Compare commits

...

33 Commits

  1. 6
      src/App.vue
  2. 44
      src/assets/css/main.css
  3. BIN
      src/assets/img/ach1.png
  4. BIN
      src/assets/img/ach2.png
  5. 1
      src/assets/img/right.svg
  6. 1
      src/assets/img/shrink.svg
  7. 1
      src/assets/img/tag-active.svg
  8. 1
      src/assets/img/tag.svg
  9. 1
      src/assets/img/wrong.svg
  10. 14
      src/components/Header.vue
  11. 11
      src/components/Sidebar.vue
  12. 35
      src/components/upload/config.js
  13. 50
      src/const/ques.js
  14. 34
      src/const/testPaper.js
  15. 37
      src/libs/util.js
  16. 54
      src/router/index.js
  17. 6
      src/setting.js
  18. 21
      src/utils/api.js
  19. 2
      src/utils/editor.js
  20. 5
      src/views/Home.vue
  21. 152
      src/views/Login.vue
  22. 86
      src/views/course/AddCurriculum.vue
  23. 4
      src/views/course/contentSettings.vue
  24. 72
      src/views/customer/AddCustomer.vue
  25. 193
      src/views/devLogin.vue
  26. 21
      src/views/match/add/index.vue
  27. 271
      src/views/match/add/set.vue
  28. 60
      src/views/match/add/step1.vue
  29. 14
      src/views/match/add/step2.vue
  30. 58
      src/views/match/add/step3.vue
  31. 211
      src/views/match/add/template.vue
  32. 185
      src/views/match/list/index.vue
  33. 16
      src/views/match/manage/index.vue
  34. 95
      src/views/match/manage/matchArch.vue
  35. 728
      src/views/match/manage/matchArchList.vue
  36. 32
      src/views/match/manage/matchInfo.vue
  37. 95
      src/views/match/manage/matchRank.vue
  38. 449
      src/views/match/manage/matchReport.vue
  39. 21
      src/views/match/manage/matchSignup.vue
  40. 675
      src/views/match/manage/otherArchList.vue
  41. 1059
      src/views/match/manage/theoryReport.vue
  42. 413
      src/views/match/manage/trialReport.vue
  43. 21
      src/views/order/AddOrder.vue
  44. 113
      src/views/parner/staff.vue
  45. 50
      src/views/review/index.vue
  46. 2
      src/views/serve/Configure.vue
  47. 284
      src/views/serve/projectAdd.vue
  48. 107
      src/views/setting/info.vue
  49. 262
      src/views/system/staff.vue
  50. 2
      src/views/theoreticalCourse/contentSettings/index.vue
  51. 175
      src/views/theoreticalCourse/preview/index.vue
  52. 17
      src/views/theoryExam/index.vue

@ -1,6 +1,6 @@
<template> <template>
<div id="app"> <div id="app">
<el-radio-group v-if="Setting.isDev" v-model="ip" @change="ipChange"> <el-radio-group v-if="Setting.isDev" class="ip" v-model="ip" @change="ipChange">
<el-radio :label="0">刘榕ip</el-radio> <el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio> <el-radio :label="1">陈赓ip</el-radio>
<el-radio :label="2">测试服ip</el-radio> <el-radio :label="2">测试服ip</el-radio>
@ -20,6 +20,10 @@ export default {
}; };
}, },
created () { created () {
window.exitSystem = () => {
sessionStorage.removeItem('token')
location.reload()
}
//sessionStorage //sessionStorage
if (sessionStorage.getItem("store")) { if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store")))) this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))

@ -19,6 +19,12 @@ body {
font-size: 14px; font-size: 14px;
} }
.ip {
z-index: 1;
position: fixed;
top: 0;
left: 0;
}
a { a {
text-decoration: none; text-decoration: none;
} }
@ -458,7 +464,7 @@ li {
} }
} }
.el-tooltip__popper { .el-tooltip__popper {
max-width: 500px !important; max-width: 100% !important;
} }
.no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child { .no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child {
display: none; display: none;
@ -485,3 +491,39 @@ li {
.edui-default { .edui-default {
line-height: normal; line-height: normal;
} }
.html-parse {
table {
display: table;
margin-bottom: 10px;
border-collapse: collapse;
th,
td {
padding: 5px 10px;
border: 1px solid #DDD;
}
}
ol {
padding-left: 30px;
li {
list-style-type: decimal;
}
}
ul {
padding-left: 30px;
li {
list-style-type: disc;
}
}
}
.files-tip {
li {
line-height: 1.8;
cursor: pointer;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723792589398" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5839" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M874 150C674.09-50 349.91-50 150 150s-200 524.09 0 724 524.09 200 724 0 200-524.09 0-724zM760.57 440.57l-256 256a80 80 0 0 1-113.14 0l-128-128a80 80 0 0 1 113.14-113.14L448 526.86l199.43-199.43a80 80 0 0 1 113.14 113.14z" fill="#2abd8c" p-id="5840"></path></svg>

After

Width:  |  Height:  |  Size: 593 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723535697263" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5903" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M877.5 565.9l-367.6-340-367.6 340c-22.5 14.5-52.5 14.5-67.5 0-15-21.7-15-50.7 0-65.1L495 117.5c0-7.2 7.5-7.2 15-7.2s7.5 0 15 7.2l420.2 383.3c22.5 21.7 15 50.6 0 65.1-22.7 14.5-52.7 14.5-67.7 0zM494.8 450.1c0-7.2 7.5-7.2 15-7.2s15 0 15 7.2L945 833.4c22.5 21.7 15 50.6 0 65.1-22.5 14.4-52.5 14.4-67.5 0L509.8 558.6 142.2 905.8c-22.5 14.5-52.5 14.5-67.5 0-15-21.7-15-50.7 0-65.1l420.1-390.6z m0 0" fill="#666666" p-id="5904"></path></svg>

After

Width:  |  Height:  |  Size: 766 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723619200843" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7128" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M695.7 118.6H326.9c-58.2 0-105.4 47.2-105.4 105.4v579.6c0 58.2 47.2 105.4 105.4 105.4l184.4-184.4L695.7 909c58.2 0 105.4-47.2 105.4-105.4V224c0-58.2-47.1-105.4-105.4-105.4z" fill="#d81e06" p-id="7129"></path></svg>

After

Width:  |  Height:  |  Size: 545 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723619200843" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7128" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M695.7 118.6H326.9c-58.2 0-105.4 47.2-105.4 105.4v579.6c0 58.2 47.2 105.4 105.4 105.4l184.4-184.4L695.7 909c58.2 0 105.4-47.2 105.4-105.4V224c0-58.2-47.1-105.4-105.4-105.4z" fill="#bfbfbf" p-id="7129"></path></svg>

After

Width:  |  Height:  |  Size: 545 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723792667165" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7415" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M480 64C217.6 64 0 281.6 0 544s217.6 480 480 480 480-217.6 480-480S742.4 64 480 64z m204.8 614.4c19.2 19.2 19.2 44.8 0 64-19.2 19.2-44.8 19.2-64 0L486.4 608 345.6 748.8c-19.2 19.2-51.2 19.2-70.4 0-19.2-19.2-19.2-51.2 0-70.4L416 537.6 281.6 403.2c-19.2-19.2-19.2-44.8 0-64 19.2-19.2 44.8-19.2 64 0L480 473.6l140.8-140.8c19.2-19.2 51.2-19.2 70.4 0 19.2 19.2 19.2 51.2 0 70.4L550.4 544l134.4 134.4z" fill="#e75050" p-id="7416"></path></svg>

After

Width:  |  Height:  |  Size: 768 B

@ -10,7 +10,7 @@
<span class="user-avator">{{ userName }}</span> <span class="user-avator">{{ userName }}</span>
</div> </div>
<el-divider class="ml20" direction="vertical"></el-divider> <el-divider class="ml20" direction="vertical"></el-divider>
<el-button type="text" class="ml20" @click="loginout">退出</el-button> <el-button type="text" class="ml20" @click="logout">退出</el-button>
</div> </div>
</div> </div>
</div> </div>
@ -21,6 +21,7 @@ import Setting from '@/setting'
export default { export default {
data () { data () {
return { return {
timer: null,
Setting, Setting,
userName: '', userName: '',
}; };
@ -34,9 +35,10 @@ export default {
this.$router.push('/person') this.$router.push('/person')
} }
}, },
loginout () { async logout () {
localStorage.removeItem('ms_username'); await this.$post(this.api.logout)
localStorage.removeItem('token'); localStorage.removeItem('ms_username')
localStorage.removeItem('token')
sessionStorage.clear() sessionStorage.clear()
location.reload() location.reload()
}, },
@ -80,8 +82,8 @@ export default {
}, },
// //
heartbeatDetection () { heartbeatDetection () {
setInterval(async () => { this.timer = setInterval(async () => {
await this.$get(this.api.heartbeatDetection) sessionStorage.getItem('token') ? await this.$get(this.api.heartbeatDetection) : clearInterval(this.timer)
}, 58 * 1000) }, 58 * 1000)
}, },

@ -89,7 +89,7 @@ export default {
title: '系统配置' title: '系统配置'
}, },
{ {
icon: 'el-icon-s-check', icon: 'el-icon-box',
index: '/parner', index: '/parner',
title: '合伙管理' title: '合伙管理'
}, },
@ -99,15 +99,20 @@ export default {
title: '合伙运营' title: '合伙运营'
}, },
{ {
icon: 'el-icon-s-shop', icon: 'el-icon-shopping-cart-2',
index: '/shop', index: '/shop',
title: '商城管理' title: '商城管理'
}, },
{ {
icon: 'el-icon-s-shop', icon: 'el-icon-data-board',
index: '/theoryExam', index: '/theoryExam',
title: '考试平台' title: '考试平台'
}, },
{
icon: 'el-icon-document-copy',
index: '/review',
title: '评阅平台'
},
], ],
menus: [], menus: [],
onRoutes: this.$route.path onRoutes: this.$route.path

@ -1,31 +1,22 @@
/** /**
* 阿里云oss配置 * 阿里云oss配置
* */ * */
import { get } from '@/utils/http'
import api from '@/utils/api'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
const A = (key, encryptedData) => {
const keyHex = CryptoJS.enc.Base64.parse(key)
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
import router from '@/router/index'
import { Message } from 'element-ui'
export default async function () { export default async function () {
try { try {
const res = await get(api.encrypt) let RE = localStorage.getItem('osc')
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/') if (RE) {
RE = JSON.parse(RE)
} else {
sessionStorage.removeItem('token')
Message.error('登录过期,请重新登录!')
setTimeout(() => {
router.replace('/login')
}, 1500)
return false
}
return { return {
// oss账号信息 // oss账号信息
config: { config: {

@ -0,0 +1,50 @@
export default {
difficults: [
{
id: 'basic',
name: '基础',
coefficient: 0.2, // 难度系数,试卷里计算试卷难度专用
theme: 'success',
},
{
id: 'easy',
name: '普通',
coefficient: 0.4,
theme: '',
},
{
id: 'medium',
name: '较难',
coefficient: 0.6,
theme: 'warning',
},
{
id: 'hard',
name: '难',
coefficient: 0.8,
theme: 'danger',
},
],
questionTypes: [
{
id: 'single_choice',
name: '单选题'
},
{
id: 'multiple_choice',
name: '多选题'
},
{
id: 'judgement',
name: '判断题'
},
{
id: 'fill_blank',
name: '填空题'
},
{
id: 'essay',
name: '问答题'
},
],
}

@ -0,0 +1,34 @@
export default {
difficults: [
{
id: 1,
name: '简单'
},
{
id: 2,
name: '普通'
},
{
id: 3,
name: '较难'
},
{
id: 4,
name: '难'
},
],
paperTypes: [
{
id: 0,
name: '练习'
},
{
id: 1,
name: '考核'
},
{
id: 2,
name: '竞赛'
},
],
}

@ -172,6 +172,43 @@ const util = {
resolve(new Date(data.currentTime)) resolve(new Date(data.currentTime))
}) })
}, },
// 阿拉伯数字转化为中文数字
arabicToChinese (num) {
const arr1 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
const arr2 = ['', '十', '百', '千', '万', '亿', '点', ''];
const a = `${num}`.replace(/(^0*)/g, '').split('.');
let k = 0;
let re = '';
for (let i = a[0].length - 1; i >= 0; i--) {
switch (k) {
case 0:
re = arr2[7] + re;
break;
case 4:
if (!new RegExp(`0{4}//d{${a[0].length - i - 1}}$`).test(a[0])) re = arr2[4] + re;
break;
case 8:
re = arr2[5] + re;
arr2[7] = arr2[5];
k = 0;
break;
default:
}
if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = arr1[0] + re;
if (a[0].charAt(i) != 0) re = arr1[a[0].charAt(i)] + arr2[k % 4] + re;
k++;
}
return num > 9 && num < 20 ? re.slice(1) : re;
},
// 阿拉伯数字转化为英文字母
numToLetter (num) {
let result = ''
if (num > 26) {
result += numberToLetter((num / 26) >> 0 - 1)
}
result += String.fromCharCode(65 + (num % 26))
return result
},
} }
export default util export default util

@ -19,143 +19,123 @@ let router = new Router({
{ {
path: '/customer', path: '/customer',
component: () => import('../views/customer/customer.vue'), component: () => import('../views/customer/customer.vue'),
// meta: { title: '客户管理' }
}, },
{ {
path: '/addcustomer', path: '/addcustomer',
component: () => import('../views/customer/AddCustomer.vue'), component: () => import('../views/customer/AddCustomer.vue'),
// meta: { title: '新增客户' }
}, },
{ {
path: '/bmOrder', path: '/bmOrder',
component: () => import('../views/customer/Order.vue'), component: () => import('../views/customer/Order.vue'),
// meta: { title: '新增客户' }
}, },
{ {
path: '/user', path: '/user',
component: () => import('../views/user/User.vue'), component: () => import('../views/user/User.vue'),
// meta: { title: '用户管理' }
}, },
{ {
path: '/adduser', path: '/adduser',
component: () => import('../views/user/AddUser.vue'), component: () => import('../views/user/AddUser.vue'),
// meta: { title: '新增用户' }
}, },
{ {
path: '/info', path: '/info',
component: () => import('../views/user/Info.vue'), component: () => import('../views/user/Info.vue'),
// meta: { title: '新增用户' }
}, },
{ {
path: '/order', path: '/order',
component: () => import('../views/order/Order.vue'), component: () => import('../views/order/Order.vue'),
// meta: { title: '订单管理' }
}, },
{ {
path: '/addorder', path: '/addorder',
component: () => import('../views/order/AddOrder.vue'), component: () => import('../views/order/AddOrder.vue'),
// meta: { title: '新增订单' }
}, },
{ {
path: '/selectClient', path: '/selectClient',
component: () => import('../views/order/selectClient.vue'), component: () => import('../views/order/selectClient.vue'),
// meta: { title: '选择订单客户' }
}, },
{ {
path: '/configure', path: '/configure',
component: () => import('../views/serve/Configure.vue'), component: () => import('../views/serve/Configure.vue'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/backstage', path: '/backstage',
component: () => import('../views/serve/backstage'), component: () => import('../views/serve/backstage'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/addModel', path: '/addModel',
component: () => import('../views/serve/addModel'), component: () => import('../views/serve/addModel'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/addconfigure', path: '/addconfigure',
component: () => import('../views/serve/AddConfigure.vue'), component: () => import('../views/serve/AddConfigure.vue'),
// meta: { title: '新增配置' }
}, },
{ {
path: '/projectList', path: '/projectList',
component: () => import('../views/serve/projectList.vue'), component: () => import('../views/serve/projectList.vue'),
// meta: { title: '项目管理' }
}, },
{ {
path: '/projectAdd', path: '/projectAdd',
component: () => import('../views/serve/projectAdd.vue'), component: () => import('../views/serve/projectAdd.vue'),
// meta: { title: '项目配置' }
}, },
{ {
path: '/curriculum', path: '/curriculum',
component: () => import('../views/course/Curriculum.vue'), component: () => import('../views/course/Curriculum.vue'),
// meta: { title: '课程管理' }
}, },
{ {
path: '/addcurriculum', path: '/addcurriculum',
component: () => import('../views/course/AddCurriculum.vue'), component: () => import('../views/course/AddCurriculum.vue'),
// meta: { title: '新建课程' }
}, },
{ {
path: '/contentSettings', path: '/contentSettings',
component: () => import('../views/course/contentSettings.vue'), component: () => import('../views/course/contentSettings.vue'),
// meta: { title: '内容设置' }
}, },
{ {
path: '/addlink', path: '/addlink',
component: () => import('../views/course/AddLink.vue'), component: () => import('../views/course/AddLink.vue'),
// meta: { title: '添加环节' }
}, },
{ {
path: '/data', path: '/data',
component: () => import('../views/data/Data.vue'), component: () => import('../views/data/Data.vue'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/match', path: '/match',
component: () => import('../views/match/list'), component: () => import('../views/match/list'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/addMatch', path: '/addMatch',
component: () => import('../views/match/add'), component: () => import('../views/match/add'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchManage', path: '/matchManage',
component: () => import('../views/match/manage'), component: () => import('../views/match/manage'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/noticeDetail', path: '/noticeDetail',
component: () => import('../views/match/manage/noticeDetail'), component: () => import('../views/match/manage/noticeDetail'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchArchList', path: '/otherArchList',
component: () => import('../views/match/manage/matchArchList'), component: () => import('../views/match/manage/otherArchList'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchRank', path: '/matchRank',
component: () => import('../views/match/manage/matchRank'), component: () => import('../views/match/manage/matchRank'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchReport', path: '/trialReport',
component: () => import('../views/match/manage/matchReport'), component: () => import('../views/match/manage/trialReport'),
// meta: { title: '数据管理' } },
{
path: '/matchArchList',
component: () => import('../views/match/manage/matchArchList'),
},
{
path: '/theoryReport',
component: () => import('../views/match/manage/theoryReport'),
}, },
{ {
path: '/matchInfo', path: '/matchInfo',
component: () => import('../views/match/manage/matchInfo'), component: () => import('../views/match/manage/matchInfo'),
// meta: { title: '数据管理' }
}, },
{ {
path: `/theoreticalCourse`, path: `/theoreticalCourse`,
@ -190,32 +170,26 @@ let router = new Router({
{ {
path: '/system', path: '/system',
component: () => import('../views/system'), component: () => import('../views/system'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/manageLog', path: '/manageLog',
component: () => import('../views/system/manageLog'), component: () => import('../views/system/manageLog'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/addLog', path: '/addLog',
component: () => import('../views/system/addLog'), component: () => import('../views/system/addLog'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/permission', path: '/permission',
component: () => import('../views/customer/Permission.vue'), component: () => import('../views/customer/Permission.vue'),
// meta: { title: '应用权限', permission: true }
}, },
{ {
path: '/person', path: '/person',
component: () => import('../views/setting'), component: () => import('../views/setting'),
// meta: { title: '个人中心' }
}, },
{ {
path: '/parner', path: '/parner',
component: () => import('../views/parner'), component: () => import('../views/parner'),
// meta: { title: '个人中心' }
}, },
{ {
path: '/parnerOperation', path: '/parnerOperation',
@ -245,6 +219,10 @@ let router = new Router({
path: '/theoryExam', path: '/theoryExam',
component: () => import('../views/theoryExam'), component: () => import('../views/theoryExam'),
}, },
{
path: '/review',
component: () => import('../views/review'),
},
{ {
path: '/404', path: '/404',
component: () => import('../views/404.vue'), component: () => import('../views/404.vue'),

@ -5,7 +5,7 @@ const url = location.host;
const isDev = process.env.NODE_ENV === 'development' // 开发环境 const isDev = process.env.NODE_ENV === 'development' // 开发环境
const isPro = url.includes('huorantech.cn') //正式服 const isPro = url.includes('huorantech.cn') //正式服
let jumpPath = `${location.origin}/judgmentPoint/` let jumpPath = `${location.origin}/panfen/`
let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址 let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址
let host = `${location.origin}/` let host = `${location.origin}/`
if (isDev) { if (isDev) {
@ -18,7 +18,7 @@ if (isDev) {
host = ips[+localStorage.getItem('ip')] host = ips[+localStorage.getItem('ip')]
} else if (isPro) { } else if (isPro) {
sandPath = `https://izhixinyun.com/sandbox` sandPath = `https://izhixinyun.com/sandbox`
jumpPath = 'https://judgment.huorantech.cn/' // jumpPath = 'https://judgment.huorantech.cn/'
} }
@ -51,7 +51,7 @@ const Setting = {
isDev, isDev,
isPro, isPro,
// 是否使用动态路由 // 是否使用动态路由
dynamicRoute: false, dynamicRoute: true,
/** /**
* @description 默认密码 * @description 默认密码
*/ */

@ -13,9 +13,11 @@ export default {
refreshPageNotification: `nakadai/message/refreshPageNotification`, refreshPageNotification: `nakadai/message/refreshPageNotification`,
heartbeatDetection: `nakadai/message/heartbeatDetection`, heartbeatDetection: `nakadai/message/heartbeatDetection`,
getCurrentTime: `competition/competition/management/getCurrentTime`, getCurrentTime: `competition/competition/management/getCurrentTime`,
getToken: `users/users/user/getToken`,
logout: `users/users/user/logout`,
// 阿里云文件/视频管理 // 阿里云文件/视频管理
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证 getPlayAuth: `nakadai/nakadai/oss/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`, encrypt: `nakadai/data/encrypt`,
staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板 staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板
@ -37,6 +39,7 @@ export default {
getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`, getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`,
refreshCache: `data/data/myDate/refreshCache`, refreshCache: `data/data/myDate/refreshCache`,
getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`, getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`,
getCustomerOrderRecord: `nakadai/nakadai/order/getCustomerOrderRecord`,
// 客户管理 // 客户管理
delCustomers: `nakadai/nakadai/customer/delCustomers`, delCustomers: `nakadai/nakadai/customer/delCustomers`,
@ -103,8 +106,8 @@ export default {
editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理 editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理
copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理 copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理
// 判分点 // 判分点
getBcJudgmentPoint: `${jumpApi}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页) getBcJudgmentPoint: `${host}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页)
getLcJudgmentPoint: `${jumpApi}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页) getLcJudgmentPoint: `${host}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页)
addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表 addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表
updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新 updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新
deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除 deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除
@ -338,6 +341,14 @@ export default {
checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`, checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`,
queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`, queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`,
viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`, viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`,
getCompetitionProjectByMiddleGround: `occupationlab/occupationlab/projectManage/getCompetitionProjectByMiddleGround`,
libraryList: `exam/exam/paperLibrary/libraryList`,
examPaperList: `exam/exam/paper/examPaperList`,
copyExamPaper: `exam/exam/paper/copyExamPaper`,
getDetailedExamScores: `exam/exam/paper/getDetailedExamScores`,
exportExamPaperReport: `exam/exam/paper/exportExamPaperReport`,
exportLabReport: `occupationlab/occupationlab/achievement/exportLabReport`,
exportBankExperimentReport: `occupationlab/occupationlab/achievement/exportBankExperimentReport`,
// 赛事内容 // 赛事内容
addCompetitionContent: `competition/competition/content/addCompetitionContent`, addCompetitionContent: `competition/competition/content/addCompetitionContent`,
@ -405,9 +416,12 @@ export default {
batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`, batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`,
batchImportGrades: `${host}competition/competition/performance/batchImportGrades`, batchImportGrades: `${host}competition/competition/performance/batchImportGrades`,
exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`, exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`,
exportExamPaperReports: `${host}exam/exam/paper/exportExamPaperReports`,
batchExportReportsAsZip: `${host}occupationlab/occupationlab/achievement/batchExportReportsAsZip`,
performanceExportFailure: `${host}competition/competition/performance/exportFailure`, performanceExportFailure: `${host}competition/competition/performance/exportFailure`,
rankExportFailure: `${host}competition/competition/rank/exportFailure`, rankExportFailure: `${host}competition/competition/rank/exportFailure`,
batchImportRanking: `${host}competition/competition/rank/batchImportRanking`, batchImportRanking: `${host}competition/competition/rank/batchImportRanking`,
getPaperUploadFileZip: `${host}exam/exam/paper/question/userAnswer/getPaperUploadFileZip`,
stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`, stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`,
stageRaceRanking: `competition/competition/rank/stageRaceRanking`, stageRaceRanking: `competition/competition/rank/stageRaceRanking`,
overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`, overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`,
@ -433,6 +447,7 @@ export default {
getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`, getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`,
frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`, frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`,
cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`, cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`,
getPaperUploadFile: `exam/exam/paper/question/userAnswer/getPaperUploadFile`,
derive: `${host}competition/cCompetitionStageFile/deriveAll`, derive: `${host}competition/cCompetitionStageFile/deriveAll`,
allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`, allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`,
derivedRanking: `${host}competition/competition/rank/derivedRanking`, derivedRanking: `${host}competition/competition/rank/derivedRanking`,

@ -5,7 +5,7 @@ export default {
//skin:'oxide-dark', //skin:'oxide-dark',
language: 'zh_CN', language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js', language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize', plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autoresize',
toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em',

@ -4,8 +4,7 @@
<v-sidebar></v-sidebar> <v-sidebar></v-sidebar>
<div class="content-box"> <div class="content-box">
<div class="content"> <div class="content">
<transition name="move" <transition name="move" mode="out-in">
mode="out-in">
<!-- <keep-alive> --> <!-- <keep-alive> -->
<router-view></router-view> <router-view></router-view>
<!-- </keep-alive> --> <!-- </keep-alive> -->
@ -32,7 +31,7 @@ export default {
vSidebar, vSidebar,
}, },
created () { created () {
this.autoLogout() // this.autoLogout()
}, },
methods: { methods: {
// ,退 // ,退

@ -39,7 +39,7 @@
<el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" <el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
label-width="0px" style="margin-top: 20px"> label-width="0px" style="margin-top: 20px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input> <el-input @blur="phoneBlur" v-model="phoneOrEmail.workNumber" placeholder="请输入电话/邮箱"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password"> <el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
@ -80,6 +80,21 @@
<el-button type="primary" @click="phoneSubmit"> </el-button> <el-button type="primary" @click="phoneSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia"
width="500px">
<p class="tips">该手机号已绑定以下用户信息</p>
<ul class="users">
<li :class="{ isEnable: !user.isEnable }" v-for="(user, i) in users" :key="i" @click="chooseUser(user)">
<span>{{ user.schoolName }}{{ user.userName }}{{ user.workNumber }}{{
user.isEnable
? ''
: '(已禁用)' }}</span>
<i class="el-icon-right"></i>
</li>
</ul>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer> <v-footer class="footer" ref="footer"></v-footer>
</div> </div>
</template> </template>
@ -88,6 +103,8 @@
import vFooter from '../components/Footer' import vFooter from '../components/Footer'
import Setting from '@/setting' import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes' import addRoutes from '@/libs/route/addRoutes'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { export default {
data: function () { data: function () {
var regPhoneOrEmail = (rule, value, callback) => {// var regPhoneOrEmail = (rule, value, callback) => {//
@ -115,7 +132,6 @@ export default {
platform: 3, platform: 3,
random: '', random: '',
distinguish: 1, distinguish: 1,
type: 2
}, },
rules: { rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }], account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
@ -127,16 +143,15 @@ export default {
showPhoneVerify: true,// - showPhoneVerify: true,// -
PhoneVerificationIMG: '',// PhoneVerificationIMG: '',//
phoneOrEmail: { phoneOrEmail: {
account: '', workNumber: '',
password: '', password: '',
code: '', code: '',
platform: 3, platform: 3,
random: '', random: '',
distinguish: 2, distinguish: 1,
type: 2
}, },
phoneOrEmailrules: { phoneOrEmailrules: {
account: [{ validator: regPhoneOrEmail, trigger: 'blur' }], workNumber: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }], code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
}, },
@ -147,8 +162,11 @@ export default {
phoneDisabled: false, phoneDisabled: false,
phoneBtnText: '发送验证码', phoneBtnText: '发送验证码',
phoneTimer: '', phoneTimer: '',
phoneOpener: '' phoneOpener: '',
userVisible: false,
users: [],
}; };
}, },
components: { components: {
@ -182,23 +200,24 @@ export default {
let param = val === 'phone' ? this.phoneOrEmail : this.param let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => { this.$refs[ref].validate(valid => {
if (valid) { if (valid) {
this.$post(this.api.logins, param).then(res => { this.$post(this.api.logins, param).then(({ status, data, message }) => {
const { message } = res localStorage.removeItem('examPath')
sessionStorage.setItem('token', res.data.token) localStorage.removeItem('reviewPath')
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => { this.getOss()
const list = res.permissionMenu if (status == 200) {
addRoutes(res.permissionMenu[0].children) const accounts = data.userAccounts
this.$store.commit('setDataPer', res.dataPermissionList) //
this.$message.success(message); if (accounts instanceof Array) {
this.$router.push({ this.users = accounts
path: list[0].children[0].path this.userVisible = true
}); } else {
localStorage.setItem('ms_username', this.param.username); sessionStorage.setItem('token', data.token)
}).catch(err => { this.setLogin()
if (err.status === 500) { }
sessionStorage.clear() } else {
param.code = ''
this.$message.error(message)
} }
})
}).catch(err => { }).catch(err => {
if (err.status === 30001) { if (err.status === 30001) {
this.phoneVisible = true this.phoneVisible = true
@ -212,7 +231,54 @@ export default {
return false; return false;
} }
}); });
},
// oss
async getOss () {
const A = (key, encryptedData) => {
const keyHex = CryptoJS.enc.Base64.parse(key)
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
const res = await this.$get(this.api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
localStorage.setItem('osc', JSON.stringify(RE))
},
//
chooseUser (user) {
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => {
sessionStorage.setItem('token', data.token)
this.token = data.token
this.setLogin()
}).catch(res => { })
},
//
async setLogin () {
try {
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`)
const list = res.permissionMenu
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList)
this.$message.success('登录成功!')
this.$router.push({
path: list[0].children[0].path
});
localStorage.setItem('ms_username', this.param.username);
} catch (e) {
if (e.status === 500) {
sessionStorage.clear()
}
}
}, },
blur () { blur () {
this.param.random = Math.floor(Math.random() * 999999999) this.param.random = Math.floor(Math.random() * 999999999)
@ -437,6 +503,46 @@ img {
color: #666; color: #666;
} }
/deep/.user-dia {
.tips {
margin-bottom: 20px;
text-align: center;
color: #666;
}
.users {
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
margin-bottom: 10px;
line-height: 40px;
font-size: 14px;
background-color: #ebeef5;
cursor: pointer;
&.isEnable {
color: #c0c4cc;
background-color: #f5f7fa;
cursor: not-allowed;
}
&:last-child {
margin-bottom: 0;
}
&:hover {
background-color: #d3e0ff;
}
i {
font-size: 16px;
}
}
}
}
@media (max-width: 1600px) { @media (max-width: 1600px) {
/deep/.ms-login { /deep/.ms-login {
width: 1000px; width: 1000px;

@ -106,13 +106,13 @@
@selection-change="handleSelectionPractice"> @selection-change="handleSelectionPractice">
<el-table-column type="selection" width="55" align="center"></el-table-column> <el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="applicationName" label="系统名称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@ -156,13 +156,13 @@
@selection-change="handleSelectionAssessment"> @selection-change="handleSelectionAssessment">
<el-table-column type="selection" width="55" align="center"></el-table-column> <el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="applicationName" label="系统名称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@ -205,12 +205,12 @@
@selection-change="handleSelectionMatch"> @selection-change="handleSelectionMatch">
<el-table-column type="selection" width="55" align="center"></el-table-column> <el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column prop="applicationName" label="系统名称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@ -272,7 +272,7 @@
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox> @change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<li v-for="(item, i) in projects" :key="i" :title="item.projectName"> <li v-for="(item, i) in projects" :key="i" :title="item.projectName">
<el-checkbox v-model="item.check" <el-checkbox v-model="item.check"
:label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName" :label="item.remark ? item.remark + '(' + item.projectName + ')' : (item.projectName || item.paperName)"
@change="val => projectChange(val, item)"></el-checkbox> @change="val => projectChange(val, item)"></el-checkbox>
</li> </li>
</ul> </ul>
@ -287,18 +287,18 @@
v-model.trim="checkedKeyword" clearable></el-input> v-model.trim="checkedKeyword" clearable></el-input>
<el-table :data="checkeds" class="table" stripe header-align="center" max-height="470"> <el-table :data="checkeds" class="table" stripe header-align="center" max-height="470">
<el-table-column type="index" width="55" label="序号" align="center"></el-table-column> <el-table-column type="index" width="55" label="序号" align="center"></el-table-column>
<el-table-column prop="applicationName" label="系统名称" align="center"> <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column prop="projectName" width="80" label="系统类型" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.type === 1 ? '流程类' : scope.row.type === 3 ? '理论' : '编程类' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" width="80" label="系统类型" align="center"> <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.type ? '流程类' : '编程类' }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="55"> <el-table-column label="操作" align="center" width="55">
<template slot-scope="scope"> <template slot-scope="scope">
<i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]" <i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
@ -415,7 +415,6 @@ export default {
systemChecked: [], systemChecked: [],
curSystem: '', curSystem: '',
projects: [], projects: [],
projectAll: [],
projectKeyword: '', projectKeyword: '',
checkedKeyword: '', checkedKeyword: '',
checkeds: [], checkeds: [],
@ -442,7 +441,7 @@ export default {
projectKeyword: function (val) { projectKeyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.filterProject(); this.getProject();
}, 500); }, 500);
}, },
checkedKeyword: function (val) { checkedKeyword: function (val) {
@ -577,6 +576,7 @@ export default {
this.pageNo = 1; this.pageNo = 1;
this.getConfig(); this.getConfig();
this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData)) this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData))
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds))
}, },
// //
getConfig () { getConfig () {
@ -609,26 +609,23 @@ export default {
}).catch(err => { }) }).catch(err => { })
}, },
// //
getProject (item) { async getProject (item, fromSystemChange) {
const checked = this.checkeds const checked = this.checkeds
this.curSystem = item.systemId if (item) this.curSystem = item.systemId
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { let res
this.projectAll = JSON.parse(JSON.stringify(res)) // if (!fromSystemChange) {
res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${this.curSystem}&keyword=${this.projectKeyword}`)
}
const result = [] const result = []
res.map(e => { const projects = fromSystemChange ? this.projects : res
projects.map(e => {
// //
const include = checked.some(n => n.projectId == e.projectId && n.systemId == e.systemId) const include = checked.some(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && n.paperId == e.paperId))
e.check = include e.check = include
result.push(e) result.push(e)
}) })
this.checkAll = !result.filter(e => !e.check).length this.checkAll = !result.filter(e => !e.check).length
this.projects = result this.projects = result
}).catch(err => { })
},
//
filterProject () {
const val = this.projectKeyword
this.projects = this.projectAll.filter(e => e.projectName.includes(val))
}, },
// //
systemChange (val, item) { systemChange (val, item) {
@ -640,7 +637,7 @@ export default {
}) })
} }
this.projectKeyword = '' this.projectKeyword = ''
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
if (val) { if (val) {
// //
if (!this.mulSystem) { if (!this.mulSystem) {
@ -648,18 +645,18 @@ export default {
item.check = true item.check = true
} }
res.map(e => { res.map(e => {
if (!checkeds.find(n => n.projectId == e.projectId && n.systemId == e.systemId)) { if (!checkeds.find(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))) {
checkeds.push(e) checkeds.push(e)
} }
}) })
} else { } else {
res.map(e => { res.map(e => {
const i = checkeds.findIndex(n => n.projectId == e.projectId && n.systemId == e.systemId) const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
i === -1 || checkeds.splice(i, 1) i === -1 || checkeds.splice(i, 1)
}) })
} }
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(checkeds)) //
this.getProject(item) this.getProject(item, 1)
}).catch(err => { }) }).catch(err => { })
}, },
// //
@ -671,8 +668,8 @@ export default {
}, },
// //
projectChange (val, item) { projectChange (val, item) {
const { systemId } = item const { systemId, paperId } = item
const i = this.checkeds.findIndex(e => e.projectId == item.projectId && e.systemId == systemId) const i = this.checkeds.findIndex(e => (item.projectId && e.projectId == item.projectId && e.systemId == systemId) || (paperId && paperId == e.paperId))
// push // push
if (val) { if (val) {
this.checkeds.push(item) this.checkeds.push(item)
@ -685,12 +682,11 @@ export default {
}) })
this.checkAll = !this.projects.find(e => !e.check) // this.checkAll = !this.projects.find(e => !e.check) //
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) //
console.log("🚀 ~ file: AddCurriculum.vue ~ line 728 ~ projectChange ~ checkedAll", this.checkeds, item)
}, },
// //
filterChecked () { filterChecked () {
const val = this.checkedKeyword const val = this.checkedKeyword
this.checkeds = this.checkedAll.filter(e => e.projectName.includes(val)) this.checkeds = this.checkedAll.filter(e => (e.projectName && e.projectName.includes(val)) || (e.paperName && e.paperName.includes(val)))
}, },
// //
delProject (i, e) { delProject (i, e) {
@ -701,9 +697,9 @@ export default {
this.checkeds.splice(i, 1) this.checkeds.splice(i, 1)
// checkdisabled // checkdisabled
if (e.systemId == this.curSystem) { if (e.systemId == this.curSystem) {
const { projectId } = e const { projectId, paperId } = e
this.projects.map(n => { this.projects.map(n => {
if (n.projectId == projectId) { if ((projectId && n.projectId == projectId) || (paperId && n.paperId == paperId)) {
n.check = false n.check = false
} }
}) })
@ -822,7 +818,8 @@ export default {
form.systemIdByPractice = this.practiceData.map(i => { form.systemIdByPractice = this.practiceData.map(i => {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId || '',
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -838,6 +835,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -850,6 +848,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -864,6 +863,7 @@ export default {
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
debugger
if (form.cid) { if (form.cid) {
this.$post(this.api.modifyCourse, form).then((res) => { this.$post(this.api.modifyCourse, form).then((res) => {
this.$message.success("编辑成功"); this.$message.success("编辑成功");

@ -634,7 +634,7 @@ export default {
width: "100%", width: "100%",
autoplay: false, autoplay: false,
vid: fileId, vid: fileId,
playauth: res.data.playAuth, playauth: res.playAuth,
encryptType: 1 // encryptType: 1 //
}, player => { }, player => {
this.downloadFile(row.name, player._urls[0].Url) this.downloadFile(row.name, player._urls[0].Url)
@ -649,7 +649,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else { } else {

@ -139,7 +139,7 @@
<el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column> <el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column>
<el-table-column label="起止日期" align="center"> <el-table-column label="起止日期" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.status === '已过期' ? '' : scope.row.startAndEndTime }} {{ scope.row.status === '已过期' ? '-' : scope.row.startAndEndTime }}
<el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top"> <el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top">
<div slot="content"> <div slot="content">
还有<span v-html="scope.row.other"></span><br>的订单还未生效 还有<span v-html="scope.row.other"></span><br>的订单还未生效
@ -173,14 +173,14 @@
<ul class="filter"> <ul class="filter">
<li> <li>
<label>订单类型</label> <label>订单类型</label>
<el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="getOrder"> <el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="initOrder">
<el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name" <el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>订单状态</label> <label>订单状态</label>
<el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="getOrder"> <el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="initOrder">
<el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name" <el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name"
:value="item.id"></el-option> :value="item.id"></el-option>
</el-select> </el-select>
@ -200,7 +200,7 @@
<el-table-column prop="orderContent" label="订单内容" align="center"> <el-table-column prop="orderContent" label="订单内容" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-popover trigger="hover" placement="top" style='width: 500px' <el-popover trigger="hover" placement="top" style='width: 500px'
v-if='scope.row.orderContent.length > 14'> v-if='scope.row.orderContent && scope.row.orderContent.length > 14'>
<p> {{ scope.row.orderContent }}</p> <p> {{ scope.row.orderContent }}</p>
<div slot="reference" class="name-wrapper"> <div slot="reference" class="name-wrapper">
<el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag> <el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag>
@ -526,6 +526,7 @@ export default {
], ],
products: [], products: [],
productAll: [], productAll: [],
productAllOrigin: [],
pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1, pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1,
pageSizeProduct: 10, pageSizeProduct: 10,
totalProduct: 0, totalProduct: 0,
@ -565,7 +566,6 @@ export default {
pageSizeOrder: 10, pageSizeOrder: 10,
totalOrder: 0, totalOrder: 0,
orders: [], orders: [],
orderAll: [],
bmsKeyword: '', bmsKeyword: '',
bms: [], bms: [],
@ -625,7 +625,7 @@ export default {
this.pageOrder = 1 this.pageOrder = 1
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.handlePageOrder() this.initOrder()
}, 500) }, 500)
}, },
bmsKeyword: function (val) { bmsKeyword: function (val) {
@ -703,7 +703,7 @@ export default {
}) })
// //
// if (list[0].startTime && list[0].endTime) { // if (list[0].startTime && list[0].endTime) {
if (list[0].startTime && now < new Date(list[0].startTime).getTime()) { if (list[0].startTime && now < new Date(list[0].startTime)) {
e.startTime = list[0].startTime e.startTime = list[0].startTime
e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime
e.status = '未生效' e.status = '未生效'
@ -717,7 +717,7 @@ export default {
e.other += `<br>${j.startTime} ~ ${j.endTime}` e.other += `<br>${j.startTime} ~ ${j.endTime}`
}) })
} }
} else if (list[list.length - 1].endTime && now > new Date(list[list.length - 1].endTime).getTime()) { } else if (list[list.length - 1].endTime && now > new Date(list[list.length - 1].endTime)) {
e.status = '已过期' e.status = '已过期'
} else { } else {
// //
@ -730,7 +730,7 @@ export default {
for (const j in list) { for (const j in list) {
const i = +j const i = +j
const n = list[i] const n = list[i]
if (n.startTime && n.endTime && now >= new Date(n.startTime).getTime() && now <= new Date(n.endTime).getTime()) { if (n.startTime && n.endTime && now >= new Date(n.startTime) && now <= new Date(n.endTime)) {
// //
e.startTime = n.startTime e.startTime = n.startTime
e.endTime = n.endTime e.endTime = n.endTime
@ -745,7 +745,7 @@ export default {
}) })
} }
break break
} else if (i != 0 && list[i - 1].endTime && n.startTime && n.endTime && now > new Date(list[i - 1].endTime).getTime() && now < new Date(n.startTime).getTime()) { } else if (i != 0 && list[i - 1].endTime && n.startTime && n.endTime && now > new Date(list[i - 1].endTime) && now < new Date(n.startTime)) {
// //
e.startTime = n.startTime e.startTime = n.startTime
e.endTime = n.endTime e.endTime = n.endTime
@ -776,13 +776,14 @@ export default {
} }
}) })
this.productAll = data this.productAll = data
this.productAllOrigin = data
this.totalProduct = data.length this.totalProduct = data.length
this.handlePage() this.handlePage()
}).catch(res => { }) }).catch(res => { })
}, },
// //
getRemain (startTime, endTime) { getRemain (startTime, endTime) {
return parseInt(((new Date(endTime).getTime() - new Date(startTime).getTime()) / 86400000)) return parseInt(((new Date(endTime) - new Date(startTime)) / 86400000))
}, },
// //
handlePage () { handlePage () {
@ -793,6 +794,15 @@ export default {
this.handlePage() this.handlePage()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`) this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`)
}, },
//
filterForm2 () {
const list = this.productAllOrigin
const { productType, status, keyword } = this.form2
this.productAll = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
this.pageProduct = 1
this.totalProduct = this.productAll.length
this.handlePage()
},
// //
setCustomer () { setCustomer () {
this.initCustomer() this.initCustomer()
@ -903,12 +913,6 @@ export default {
this.productTypeList = res.classificationList this.productTypeList = res.classificationList
}).catch(err => { }) }).catch(err => { })
}, },
//
filterForm2 () {
const list = this.productAll
const { productType, status, keyword } = this.form2
this.products = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
},
// //
exportList () { exportList () {
let list = this.productAll let list = this.productAll
@ -936,36 +940,32 @@ export default {
// //
getOrder () { getOrder () {
const { orderStatus, orderType } = this.form3 const { orderStatus, orderType, keyword } = this.form3
this.$post(this.api.orderList, { this.$post(this.api.getCustomerOrderRecord, {
customerId: this.customerId,
cityId: '', cityId: '',
customerName: this.form.customerName, orderContent: keyword,
orderStatus, orderStatus,
orderType, orderType,
pageNo: 1, pageNo: this.pageOrder,
pageSize: 10000, pageSize: this.pageSizeOrder,
provinceId: '' provinceId: ''
}).then(({ orderPage }) => { }).then(({ orders }) => {
orderPage.orders.forEach(e => { orders.records.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType) e.orderType = this.orderTypeFn(e.orderType)
e.orderStatus = this.orderStatusFn(e.orderStatus) e.orderStatus = this.orderStatusFn(e.orderStatus)
e.orderNature = this.orderNatureFn(e.orderNature)
}); });
this.orderAll = orderPage.orders this.orders = orders.records
this.totalOrder = orderPage.total this.totalOrder = orders.total
this.handlePageOrder()
}).catch(res => { }) }).catch(res => { })
}, },
// initOrder () {
handlePageOrder () { this.pageOrder = 1
const { keyword } = this.form3 this.getOrder()
const list = keyword ? this.orderAll.filter(e => e.orderNumber.includes(keyword) || e.orderContent.includes(keyword)) : this.orderAll
this.totalOrder = list.length
this.orders = list.slice((this.pageOrder - 1) * this.pageSizeOrder, this.pageOrder * this.pageSizeOrder)
}, },
handleCurrentChangeOrder (val) { handleCurrentChangeOrder (val) {
this.pageOrder = val this.pageOrder = val
this.handlePageOrder() this.getOrder()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab3&page=${val}`) this.$router.push(`addcustomer?id=${this.customerId}&type=tab3&page=${val}`)
}, },
// //
@ -1014,7 +1014,7 @@ export default {
this.pageProduct = 1 this.pageProduct = 1
this.pageOrder = 1 this.pageOrder = 1
this.pageBm = 1 this.pageBm = 1
index === 'tab3' && this.handlePageOrder() index === 'tab3' && this.initOrder()
this.updateTime = this.form.customerId ? 1 : 0 this.updateTime = this.form.customerId ? 1 : 0
} }
}, },

@ -6,26 +6,19 @@
<h1>欢迎使用开发者平台</h1> <h1>欢迎使用开发者平台</h1>
<div class="form"> <div class="form">
<ul class="tab"> <ul class="tab">
<li v-for="(item, i) in tabList" :key="i" :class="{active: activeIndex == item.id}" @click="handleSelect(item.id)">{{item.label}}</li> <li v-for="(item, i) in tabList" :key="i" :class="{ active: activeIndex == item.id }"
@click="handleSelect(item.id)">{{ item.label }}</li>
</ul> </ul>
<el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px"> <el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input> <el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input type="password" placeholder="请输入密码" v-model="param.password">
type="password"
placeholder="请输入密码"
v-model="param.password"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="showVerify"> <el-form-item prop="code" v-if="showVerify">
<el-input <el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()">
placeholder="请输入验证码"
v-model="param.code"
@keyup.enter.native="submitForm()"
>
</el-input> </el-input>
<img @click="blur" :src="verificationIMG" class="verification" alt=""> <img @click="blur" :src="verificationIMG" class="verification" alt="">
</el-form-item> </el-form-item>
@ -34,24 +27,17 @@
</div> </div>
</el-form> </el-form>
<el-form v-show="activeIndex==='2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" label-width="0px"> <el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
label-width="0px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input> <el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
type="password"
placeholder="请输入密码"
v-model="phoneOrEmail.password"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify"> <el-form-item prop="code" v-if="showPhoneVerify">
<el-input <el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')">
placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')"
>
</el-input> </el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt=""> <img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item> </el-form-item>
@ -71,7 +57,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div style="display:flex;"> <div style="display:flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button> <el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText
}}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -80,6 +67,20 @@
<el-button type="primary" @click="phoneSubmit"> </el-button> <el-button type="primary" @click="phoneSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia"
width="500px">
<p class="tips">该手机号已绑定以下用户信息</p>
<ul class="users">
<li :class="{ isEnable: !user.isEnable }" v-for="(user, i) in users" :key="i" @click="chooseUser(user)">
<span>{{ user.schoolName }}{{ user.userName }}{{ user.workNumber }}{{
user.isEnable
? ''
: '(已禁用)' }}</span>
<i class="el-icon-right"></i>
</li>
</ul>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer> <v-footer class="footer" ref="footer"></v-footer>
</div> </div>
</template> </template>
@ -87,6 +88,9 @@
<script> <script>
import vFooter from '../components/Footer' import vFooter from '../components/Footer'
import Setting from '@/setting' import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { export default {
data: function () { data: function () {
var regPhoneOrEmail = (rule, value, callback) => {// var regPhoneOrEmail = (rule, value, callback) => {//
@ -155,8 +159,10 @@ export default {
phoneDisabled: false, phoneDisabled: false,
phoneBtnText: '发送验证码', phoneBtnText: '发送验证码',
phoneTimer: '', phoneTimer: '',
phoneOpener:'' phoneOpener: '',
userVisible: false,
users: [],
}; };
}, },
components: { components: {
@ -190,26 +196,29 @@ export default {
let param = val === 'phone' ? this.phoneOrEmail : this.param let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => { this.$refs[ref].validate(valid => {
if (valid) { if (valid) {
this.$post(this.api.logins,param).then(res => { this.$post(this.api.logins, param).then(({ status, data, message }) => {
const { message } = res localStorage.removeItem('examPath')
sessionStorage.setItem('token',res.data.token) localStorage.removeItem('reviewPath')
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => { this.getOss()
const list = res.permissionMenu if (status == 200) {
this.$store.commit('setDataPer', res.dataPermissionList) const accounts = data.userAccounts
this.$message.success(message); //
this.$router.push({ if (accounts instanceof Array) {
path: list[0].children[0].path this.users = accounts
}); this.userVisible = true
localStorage.setItem('ms_username', this.param.username); } else {
}).catch(err => { sessionStorage.setItem('token', data.token)
if (err.status === 500) { this.setLogin()
sessionStorage.clear() }
} else {
param.code = ''
this.$message.error(message)
} }
})
}).catch(err => { }).catch(err => {
if (err.status === 30001) { if (err.status === 30001) {
this.phoneVisible = true this.phoneVisible = true
}else if(err.status == 10004){ } else if (err.status == 10004 || err.status == 10005) {
param.code = ''
this.blur() this.blur()
} }
}); });
@ -218,7 +227,54 @@ export default {
return false; return false;
} }
}); });
},
// oss
async getOss () {
const A = (key, encryptedData) => {
const keyHex = CryptoJS.enc.Base64.parse(key)
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
const res = await this.$get(this.api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
localStorage.setItem('osc', JSON.stringify(RE))
},
//
chooseUser (user) {
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => {
sessionStorage.setItem('token', data.token)
this.token = data.token
this.setLogin()
}).catch(res => { })
},
//
async setLogin () {
try {
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`)
const list = res.permissionMenu
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList)
this.$message.success('登录成功!')
this.$router.push({
path: list[0].children[0].path
});
localStorage.setItem('ms_username', this.param.username);
} catch (e) {
if (e.status === 500) {
sessionStorage.clear()
}
}
}, },
blur () { blur () {
this.param.random = Math.floor(Math.random() * 999999999) this.param.random = Math.floor(Math.random() * 999999999)
@ -305,24 +361,28 @@ export default {
.wrap { .wrap {
min-height: 100%; min-height: 100%;
} }
.logo { .logo {
z-index: 2; z-index: 2;
position: absolute; position: absolute;
top: 50px; top: 50px;
left: 50px; left: 50px;
} }
.login { .login {
position: relative; position: relative;
height: 100%; height: 100%;
background-image: url(../assets/img/devLogin.jpg); background-image: url(../assets/img/devLogin.jpg);
background-size: 100%; background-size: 100%;
} }
.box { .box {
width: 448px; width: 448px;
position: absolute; position: absolute;
right: 20%; right: 20%;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
h1 { h1 {
margin-bottom: 20px; margin-bottom: 20px;
font-size: 34px; font-size: 34px;
@ -330,21 +390,25 @@ export default {
text-align: center; text-align: center;
} }
} }
/deep/ .form { /deep/ .form {
padding: 20px 60px 0; padding: 20px 60px 0;
background-color: rgba(255, 255, 255, .3); background-color: rgba(255, 255, 255, .3);
border-radius: 4px; border-radius: 4px;
box-sizing: border-box; box-sizing: border-box;
border: 4px solid rgba(255, 255, 255, .2); border: 4px solid rgba(255, 255, 255, .2);
.el-input__inner { .el-input__inner {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
border: 1px solid rgba(220, 220, 220, 1); border: 1px solid rgba(220, 220, 220, 1);
border-radius: 2px; border-radius: 2px;
} }
.el-form-item { .el-form-item {
margin-bottom: 25px; margin-bottom: 25px;
} }
.verification { .verification {
position: absolute; position: absolute;
top: 1px; top: 1px;
@ -354,11 +418,13 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.tab { .tab {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-bottom: 24px; margin-bottom: 24px;
li { li {
padding: 18px 5px; padding: 18px 5px;
margin: 0 20px; margin: 0 20px;
@ -367,23 +433,28 @@ export default {
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
&.active { &.active {
color: #fff; color: #fff;
border-bottom-color: #ccc; border-bottom-color: #ccc;
} }
} }
} }
.title { .title {
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
.login-btn { .login-btn {
text-align: center; text-align: center;
} }
.login-btn button { .login-btn button {
width: 100%; width: 100%;
height: 48px; height: 48px;
@ -393,13 +464,55 @@ export default {
border-radius: 4px; border-radius: 4px;
border: 0; border: 0;
} }
.forget { .forget {
margin-bottom: 28px; margin-bottom: 28px;
text-align: right; text-align: right;
color: #999; color: #999;
font-weight: bold; font-weight: bold;
&:hover { &:hover {
color: #0092FF; color: #0092FF;
} }
} }
/deep/.user-dia {
.tips {
margin-bottom: 20px;
text-align: center;
color: #666;
}
.users {
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
margin-bottom: 10px;
line-height: 40px;
font-size: 14px;
background-color: #ebeef5;
cursor: pointer;
&.isEnable {
color: #c0c4cc;
background-color: #f5f7fa;
cursor: not-allowed;
}
&:last-child {
margin-bottom: 0;
}
&:hover {
background-color: #d3e0ff;
}
i {
font-size: 16px;
}
}
}
}
</style> </style>

@ -9,8 +9,8 @@
<div class="p-title">大赛发布类型</div> <div class="p-title">大赛发布类型</div>
<el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''"> <el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''">
<el-form-item label="请选择类型"> <el-form-item label="请选择类型">
<el-radio v-model="releaseType" :label="0">仅发布信息</el-radio> <el-radio v-for="(item, i) in releaseTypes" :key="i" v-model="releaseType" :label="item.id">{{ item.name
<el-radio v-model="releaseType" :label="1">设置完整比赛</el-radio> }}</el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1" <el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1"
@ -83,6 +83,20 @@ export default {
updateTime: 0, updateTime: 0,
setupId: '', setupId: '',
releaseType: 0, releaseType: 0,
releaseTypes: [
{
id: 0,
name: '仅发布信息'
},
{
id: 1,
name: '设置完整比赛'
},
// {
// id: 2,
// name: ''
// },
],
editing: this.$route.query.id ? 0 : 1, editing: this.$route.query.id ? 0 : 1,
showBtns: true, showBtns: true,
loadIns: null loadIns: null
@ -140,9 +154,10 @@ export default {
next (next, setupId, competitionId) { next (next, setupId, competitionId) {
if (!next) { if (!next) {
if (this.step === 3 && this.$refs['step' + this.step].form[0].contentId) { if (this.step === 3 && this.$refs['step' + this.step].form[0].contentId) {
// && // &&
this.editing = 0 this.editing = 0
this.step = 1 this.step = 1
this.$parent.initTabs && this.$parent.initTabs()
} else { } else {
// //
this.$router.push(`/match`) this.$router.push(`/match`)

@ -1,103 +1,137 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛名称</p> <p class="m-b-20">比赛名称</p>
{{ form.stageName }} {{ form.stageName }}
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛时间</p> <p class="m-b-20">比赛时间</p>
<div class="date-inputs"> <div class="date-inputs">
起止时间 起止时间
<div style="display: inline-flex;align-items: center;"> <div style="display: inline-flex;align-items: center;">
<el-date-picker v-model="form.time" <el-date-picker v-model="form.time" type="datetimerange" range-separator="~" start-placeholder="开始日期"
type="datetimerange" end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@change="timeChange"> @change="timeChange">
</el-date-picker> </el-date-picker>
<el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;" <el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error" :closable="false"
type="error"
:closable="false"
effect="dark"> effect="dark">
</el-alert> </el-alert>
</div> </div>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="mgr20 m-b-20"> <!-- 理论系统 -->
<template v-if="isTheory">
<!-- 理论系统选择试卷库非理论则选择系统 -->
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<p class="m-b-20">试卷库</p>
<div class="inline-input">
<el-select v-model="libraryId" placeholder="请选择试卷库" @change="getProject">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20">
<span>理论试卷</span>
<div style="display: inline-flex;">
<div>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
</div>
</div>
</div>
<p v-if="form.paperName" style="margin-bottom: 20px">
已选试卷{{ form.paperName }}
<el-button type="primary" size="mini" @click="previewPaper(form)">预览</el-button>
</p>
<el-table :data="projects" class="table" stripe header-align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.paperId" :label="scope.row.paperId" @change="paperChange">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" min-width="140" align="center"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" min-width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" min-width="70"></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" min-width="70" sortable="custom">
<template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e =>
e.id === scope.row.difficult).name : '' }}</template>
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" min-width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" min-width="70"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" min-width="70">
<template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e =>
e.id === scope.row.paperType).name : '' }}</template>
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="170"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="110"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" @click="previewPaper(scope.row)">预览</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
</template>
<template v-else>
<el-card shadow="hover" class="mgr20 m-b-20">
<div> <div>
<p class="m-b-20">课程</p> <p class="m-b-20">课程</p>
<div class="inline-input"> <div class="inline-input">
<el-cascader ref="cur" <el-cascader ref="cur" v-model="mallIds" :options="curs" :props="{ checkStrictly: true, value: 'id' }"
v-model="mallIds" popper-class="course-cas" @expand-change="curChange" @change="curChange"></el-cascader>
:options="curs"
:props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas"
@expand-change="curChange"
@change="curChange"></el-cascader>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="m-b-20"> <el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<span>实训项目</span> <span>实训项目</span>
<div style="display: inline-flex;"> <div style="display: inline-flex;">
<div> <div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
</div> </div>
<el-button style="margin-left: 5px" <el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button>
type="primary"
round
@click="toProject">自定义实验项目</el-button>
</div> </div>
</div> </div>
<!-- 实训项目表格 --> <!-- 实训项目表格 -->
<el-table :data="projects" <el-table :data="projects" class="table" stripe header-align="center">
class="table" <el-table-column width="60" label="选择" align="center">
stripe
header-align="center">
<el-table-column width="60"
label="选择"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio v-model="form.projectId" <el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio>
:label="scope.row.projectId">&nbsp;</el-radio>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
label="项目名称" <el-table-column prop="auth" label="项目权限" align="center">
align="center"></el-table-column>
<el-table-column prop="auth"
label="项目权限"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }} {{ permissionsKeys[scope.row.permissions] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founder" <el-table-column prop="founder" label="创建人" align="center">
label="创建人"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.founder ? '老师创建' : '系统内置' }} {{ scope.row.founder ? '老师创建' : '系统内置' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
label="创建时间"
align="center"></el-table-column>
<!-- <el-table-column label="操作" align="center"> <!-- <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="showProject(scope.row)">查看</el-button> <el-button type="text" @click="showProject(scope.row)">查看</el-button>
@ -105,42 +139,54 @@
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
:page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
@current-change="handleCurrentChange"
layout="total,prev, pager, next"
:total="total"></el-pagination>
</div> </div>
</el-card> </el-card>
</template>
<div style="text-align: center"> <div style="text-align: center">
<el-button @click="back">返回</el-button> <el-button @click="back">返回</el-button>
<el-button type="primary" <el-button type="primary" @click="save">保存</el-button>
@click="save">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import util from "@/libs/util"; import util from "@/libs/util";
import { Loading } from 'element-ui' import { Loading } from 'element-ui'
import TestPaperConst from '@/const/testPaper'
export default { export default {
props: ['form', 'step1'], props: ['form', 'step1'],
data () { data () {
return { return {
difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes,
loadIns: null, loadIns: null,
mallIds: [], mallIds: [],
curs: [], curs: [],
paperLibraries: [],
testPapers: [],
keyword: '', keyword: '',
projects: [], projects: [],
page: 1, page: 1,
pageSize: 5, pageSize: 5,
total: 0, total: 0,
libraryId: '',
sysId: '', sysId: '',
paperId: '',
paperName: '',
permissionsKeys: ['练习', '考核', '竞赛'], permissionsKeys: ['练习', '考核', '竞赛'],
timeInvalid: false timeInvalid: false,
}; };
}, },
computed: {
//
isTheory () {
return this.form.method === 1
},
},
watch: { watch: {
// , // ,
form: { form: {
@ -157,7 +203,7 @@ export default {
} }
}, },
mounted () { mounted () {
this.getCourse() this.isTheory ? this.getLibrary() : this.getCourse()
}, },
methods: { methods: {
// //
@ -186,7 +232,7 @@ export default {
records.map(e => { records.map(e => {
e.id = +e.mallId e.id = +e.mallId
e.label = e.productName e.label = e.productName
e.children = serviceList.records.filter(n => e.systemId.split(',').includes(n.systemId)) // e.children = serviceList.records.filter(n => e.systemId && e.systemId.split(',').includes(n.systemId)) //
}) })
this.curs = records this.curs = records
@ -216,31 +262,65 @@ export default {
this.loadIns = Loading.service() this.loadIns = Loading.service()
this.getProject() this.getProject()
}, },
//
async getLibrary () {
try {
const res = await this.$post(this.api.libraryList, {
pageNum: 1,
pageSize: 10000,
type: 1,
isDisable: 0,
})
const { records } = res.pageList
if (records.length) {
this.paperLibraries = records
this.libraryId = records[0].libraryId
this.loadIns = Loading.service()
this.getProject()
}
} finally { }
},
// // /
getProject () { async getProject () {
this.$post(this.api.getProjectAssessmentByCompetition, { try {
//
if (this.isTheory) {
const res = await this.$post(this.api.examPaperList, {
pageNum: this.page,
pageSize: this.pageSize,
type: 1,
keyWord: this.keyword,
libraryId: this.libraryId,
isDisable: 0,
status: 1
})
this.projects = res.pageList.records
this.total = res.pageList.total
} else {
//
const { data } = await this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
cid: this.form.cid, cid: this.form.cid,
projectName: this.keyword, projectName: this.keyword,
systemId: this.sysId, systemId: this.sysId,
permissions: 2 permissions: 2,
}).then(({ data }) => { })
this.projects = data.records this.projects = data.records
this.total = data.total this.total = data.total
}
} finally {
this.loadIns.close() this.loadIns.close()
}).catch(err => { }
this.loadIns.close()
});
}, },
initData () { initData () {
this.page = 1; this.page = 1
this.getProject(); this.getProject()
}, },
handleCurrentChange (val) { handleCurrentChange (val) {
this.page = val; this.page = val
this.getProject(); this.getProject()
}, },
// //
toProject () { toProject () {
@ -277,22 +357,58 @@ export default {
} }
} }
}, },
//
previewPaper (row) {
this.$parent.previewPaper(row)
},
//
paperChange (id) {
const item = this.projects.find(e => e.paperId === id)
if (item) this.form.paperName = item.name
},
// //
save () { save () {
const { form } = this const { form } = this
if (!form.time.length) return util.warningMsg('请选择比赛时间') if (!form.time.length) return util.warningMsg('请选择比赛时间')
const { playStartTime, playEndTime } = this.step1 const { playStartTime, playEndTime } = this.step1
if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
//
if (this.isTheory) {
if (!this.libraryId) return util.warningMsg('请选择试卷库')
if (!form.paperId) return util.warningMsg('请选择试卷')
form.libraryId = this.libraryId
const curPaper = this.projects.find(e => e.paperId === form.paperId)
if (curPaper) form.paperName = curPaper.name
} else {
if (!form.cid) return util.warningMsg('请选择课程') if (!form.cid) return util.warningMsg('请选择课程')
if (!form.projectId) return util.warningMsg('请选择项目') if (!form.projectId) return util.warningMsg('请选择项目')
const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId) const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (systemId) form.systemId = systemId if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName if (projectName) form.projectName = projectName
if (systemName) form.systemName = systemName if (systemName) form.systemName = systemName
}
form.startTime = form.time[0] form.startTime = form.time[0]
form.endTime = form.time[1] form.endTime = form.time[1]
this.handlePaper()
this.$emit('hideSet', this.form) this.$emit('hideSet', this.form)
}, },
//
async handlePaper () {
const { form } = this
// id
if (form.paperName !== form.originPaperName) {
const res = await this.$post(this.api.copyExamPaper, {
associatedID: form.stageId,
paperId: form.paperId,
typeId: 1
})
if (res.examPaper) {
form.paperId = res.examPaper.paperId
}
}
},
// //
back () { back () {
this.$emit('update:form', this.$parent.curOriginForm) this.$emit('update:form', this.$parent.curOriginForm)
@ -302,5 +418,4 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

@ -37,6 +37,8 @@
<el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input> <el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input>
</div> </div>
</el-form-item> </el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="主办方"> <el-form-item class="req" label="主办方">
<div class="inline-input"> <div class="inline-input">
<div class="input-wrap" v-for="(item, index) in sponsorList" :key="index"> <div class="input-wrap" v-for="(item, index) in sponsorList" :key="index">
@ -72,6 +74,7 @@
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker> :picker-options="pickerOptions"></el-date-picker>
</el-form-item> </el-form-item>
</template>
<el-form-item class="req" label="竞赛时间"> <el-form-item class="req" label="竞赛时间">
<el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" <el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
@ -92,6 +95,7 @@
</template> </template>
</div> </div>
</el-form-item> </el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="竞赛类型"> <el-form-item class="req" label="竞赛类型">
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio> <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio>
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio> <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio>
@ -128,6 +132,7 @@
<el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button> <el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button>
</div> </div>
</el-form-item> </el-form-item>
</template>
<el-form-item class="req" label="竞赛详情"> <el-form-item class="req" label="竞赛详情">
<quill v-if="quillShow" :border="true" v-model="form.description" :height="400" <quill v-if="quillShow" :border="true" v-model="form.description" :height="400"
:readonly="!editing && form.id !== ''" /> :readonly="!editing && form.id !== ''" />
@ -136,6 +141,56 @@
<Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove" <Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove"
@onSuccess="uploadAnnexSuccess" /> @onSuccess="uploadAnnexSuccess" />
</el-form-item> </el-form-item>
<template v-if="isPractice">
<el-form-item label="比赛方式">
<el-radio-group v-model="form.type">
<el-radio :label="0">实训</el-radio>
<el-radio :label="1">理论</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="比赛内容">
<el-button style="margin-bottom: 10px;" size="small" type="primary">选择理论试卷</el-button>
<el-table :data="list" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center" min-width="100"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" width="60"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" width="100" sortable="custom">
<!-- <template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e
=>
e.id === scope.row.difficult).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" width="90"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" width="70">
<!-- <template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e
=>
e.id === scope.row.paperType).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="160"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> -->
<el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
:inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
</el-form-item>
</template>
</el-form> </el-form>
</div> </div>
</div> </div>
@ -293,6 +348,11 @@ export default {
quill, quill,
Upload Upload
}, },
computed: {
isPractice () {
return this.$parent.releaseType === 2
},
},
watch: { watch: {
editing: function (val) { editing: function (val) {
this.quillShow = false this.quillShow = false

@ -104,7 +104,7 @@
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="item.resultAnnouncementTime" type="number" min="0" <el-input v-model.number="item.resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</div> </div>
<div <div
v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined" v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined"
@ -136,13 +136,15 @@
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="rule" label="成绩公布时间"> <el-form-item label="成绩公布时间">
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0" <el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</el-form-item> </el-form-item>
<el-form-item prop="resultsDetails" label="是否公布成绩详情"> <el-form-item
v-if="form.competitionStageList[0].resultAnnouncementTime !== '' && form.competitionStageList[0].resultAnnouncementTime !== null && form.competitionStageList[0].resultAnnouncementTime !== undefined"
prop="resultsDetails" label="是否公布成绩详情">
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio>
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p> <p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
@ -320,12 +322,12 @@ export default {
// //
if (this.step1.completeCompetitionSetup.competitionType) { if (this.step1.completeCompetitionSetup.competitionType) {
const { form, originForm } = this const { form, originForm } = this
// 34 // 34
let changeLimit = 0 let changeLimit = 0
for (const i in form.competitionStageList) { for (const i in form.competitionStageList) {
const e = form.competitionStageList[i] const e = form.competitionStageList[i]
if (e.teamNumLimit !== originForm.competitionStageList[i].teamNumLimit || e.customNumber !== originForm.competitionStageList[i].customNumber) { const originStage = originForm.competitionStageList[i]
if (!originStage || e.teamNumLimit !== originStage.teamNumLimit || e.customNumber !== originStage.customNumber) {
changeLimit = 1 changeLimit = 1
break break
} }

@ -22,6 +22,7 @@
</el-alert> </el-alert>
</div> </div>
</el-form-item> </el-form-item>
<!-- 其他赛事 -->
<template v-if="item.method === 2"> <template v-if="item.method === 2">
<el-form-item class="req" label="比赛地点"> <el-form-item class="req" label="比赛地点">
<el-input v-model="item.offlineAddress" style="width: 80%"></el-input> <el-input v-model="item.offlineAddress" style="width: 80%"></el-input>
@ -70,12 +71,25 @@
</el-form-item> </el-form-item>
</template> </template>
<template v-else> <template v-else>
<template v-if="item.method === 0">
<el-form-item class="req" prop="cid" label="课程系统"> <el-form-item class="req" prop="cid" label="课程系统">
{{ item.systemName }} {{ item.systemName }}
</el-form-item> </el-form-item>
<el-form-item class="req" prop="assessmentId" label="已选择考核"> <el-form-item class="req" prop="assessmentId" label="已选择考核">
{{ item.projectName }} {{ item.projectName }}
</el-form-item> </el-form-item>
</template>
<template v-else>
<el-form-item class="req" label="已选择试卷">
<div class="flex">
{{ item.paperName }}&emsp;
<el-form>
<el-button v-if="item.paperName" type="primary" size="mini" :disabled="false"
@click="previewPaper(item)">预览</el-button>
</el-form>
</div>
</el-form-item>
</template>
<el-form-item class="req" prop="resultAnnouncementTime" label="比赛地点"> <el-form-item class="req" prop="resultAnnouncementTime" label="比赛地点">
<div class="line"> <div class="line">
<el-checkbox v-model="item.onlineButton">线上</el-checkbox> <el-checkbox v-model="item.onlineButton">线上</el-checkbox>
@ -94,8 +108,7 @@
</div> </div>
</div> </div>
<set v-if="setVisible" :form.sync="form[curStep]" :step1.sync="step1" @hideSet="hideSet" /> <Set v-if="setVisible" :form.sync="form[curStep]" :step1.sync="step1" @hideSet="hideSet" />
<el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false" <el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false"
custom-class="tips-dia"> custom-class="tips-dia">
@ -113,11 +126,13 @@
</template> </template>
<script> <script>
import Set from './set'
import Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import set from './set'
export default { export default {
props: ['setupId', 'competitionId', 'editing'], props: ['setupId', 'competitionId', 'editing'],
components: { Set },
data () { data () {
return { return {
headers: { headers: {
@ -151,6 +166,8 @@ export default {
stageId: '', stageId: '',
startTime: '', startTime: '',
systemId: '', systemId: '',
paperId: '',
paperName: '',
offlineAddress: '', offlineAddress: '',
offlineButton: 0, offlineButton: 0,
onlineAddress: '', onlineAddress: '',
@ -166,9 +183,6 @@ export default {
tipsVisible: false, tipsVisible: false,
}; };
}, },
components: {
set
},
watch: { watch: {
// , // ,
form: { form: {
@ -237,8 +251,10 @@ export default {
form.method = e.method form.method = e.method
form.stageId = e.stageId form.stageId = e.stageId
form.stageName = e.stageName form.stageName = e.stageName
if (form.paperName) form.originPaperName = form.paperName //
this.form.push(form) this.form.push(form)
}) })
this.resumeData() this.resumeData()
this.$nextTick(() => { this.$nextTick(() => {
this.updateTime = 0 this.updateTime = 0
@ -258,6 +274,19 @@ export default {
this.setVisible = false this.setVisible = false
this.$parent.showBtns = true this.$parent.showBtns = true
}, },
//
previewPaper (row) {
let url = `${location.origin}/examination`
if (Setting.isDev) {
url = `http://192.168.31.125:8098/`
} else if (Setting.isPro) {
const { host } = location
url = `https://${host === 'dev.huorantech.cn' ? host : 'www.huorantech.cn'}/examination/`
}
url += `#/testPaper/preview?id=${row.paperId}&token=${sessionStorage.getItem('token')}`
localStorage.setItem('exam_token', sessionStorage.getItem('token'))
window.open(url)
},
// //
timeChange (val) { timeChange (val) {
if (val.length) { if (val.length) {
@ -363,6 +392,7 @@ export default {
this.$confirm('团队赛发布成功,由于您设置的报名时间已结束,如需自动分配阶段参赛人员,请前往报名人员列表进行设置', '提示', { this.$confirm('团队赛发布成功,由于您设置的报名时间已结束,如需自动分配阶段参赛人员,请前往报名人员列表进行设置', '提示', {
confirmButtonText: '关闭', confirmButtonText: '关闭',
type: 'success', type: 'success',
showCancelButton: false,
closeOnClickModal: false, closeOnClickModal: false,
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
showClose: false, showClose: false,
@ -377,6 +407,10 @@ export default {
this.$emit('next', next) this.$emit('next', next)
} }
}, },
// websocket
async sendSocket () {
await this.$post(`${this.api.refreshPageNotification}?content=1`)
},
// //
save (status, next = 0) { save (status, next = 0) {
const { form } = this const { form } = this
@ -401,11 +435,16 @@ export default {
Util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') Util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
break break
} }
if (e.method !== 2 && !e.cid) { if (e.method === 0 && !e.cid) {
invalid = 1 invalid = 1
Util.errorMsg('请选择课程') Util.errorMsg('请选择课程')
break break
} }
if (e.method === 1 && !e.paperId) {
invalid = 1
Util.errorMsg('请选择试卷')
break
}
if (e.method === 2) { // 线 if (e.method === 2) { // 线
if (!e.offlineAddress) { if (!e.offlineAddress) {
invalid = 1 invalid = 1
@ -470,7 +509,10 @@ export default {
}).then(res => { }).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
// //
status && this.publish(status) if (status) {
this.publish(status)
this.sendSocket()
}
Util.successMsg((status ? '发布' : '保存') + '成功') Util.successMsg((status ? '发布' : '保存') + '成功')
this.updateTime = 0 this.updateTime = 0
if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) { if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) {

@ -0,0 +1,211 @@
<template>
<!-- 理论考试选择试卷 -->
<div>
<el-dialog title="请选择试卷" :visible.sync="listVisible" width="1200px" :close-on-click-modal="false"
@closed="closeDia">
<div class="tool">
<ul class="filter">
<li>
<label>试卷库</label>
<el-select v-model="filter.libraryId" placeholder="请选择试卷库" @change="initData">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
</li>
<li>
<label>建议用途</label>
<el-select v-model="filter.paperType" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item, i) in paperTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>试卷难度</label>
<el-select v-model="filter.difficult" clearable multiple placeholder="请选择试卷难度" @change="initData">
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>题目类型</label>
<el-select v-model="questionType" clearable multiple placeholder="请选择题目类型" @change="initData">
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.name"></el-option>
</el-select>
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="filter.keyWord"
clearable />
</li>
</ul>
<div>
<!-- <el-button type="primary" @click="add">自定义理论试卷</el-button> -->
</div>
</div>
<el-table :data="papers" class="table" stripe header-align="center" @sort-change="sortChange">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.paperId" :label="scope.row.paperId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" min-width="140" align="center"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" min-width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" min-width="70"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" min-width="70" sortable="custom">
<template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e =>
e.id === scope.row.difficult).name : '' }}</template>
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" min-width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" min-width="70"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" min-width="70">
<template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e =>
e.id === scope.row.paperType).name : '' }}</template>
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="170"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="110"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" @click="previewPaper(scope.row)">预览</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="listVisible = false">取消</el-button>
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import _ from 'lodash'
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
export default {
props: ['visible', 'form'],
data () {
return {
arabicToChinese: Util.arabicToChinese,
questionTypes: QuesConst.questionTypes,
difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes,
listVisible: false,
searchTimer: null,
questionType: [],
paperLibraries: [],
filter: {
libraryId: '',
paperType: '',
difficult: [],
keyWord: '',
},
list: [],
page: 1,
pageSize: 10,
total: 0,
paperId: '',
submiting: false,
};
},
watch: {
'filter.keyWord': function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initData, 500)
},
visible () {
this.listVisible = this.visible
this.visible && this.getList()
}
},
mounted () {
this.originForm = _.cloneDeep(this.form)
},
methods: {
//
async getList () {
try {
const res = await this.$post(this.api.examPaperList, {
...this.filter,
pageNum: this.page,
pageSize: this.pageSize,
type: 1,
keyWord: this.keyword,
libraryId: this.systemId
})
this.papers = res.pageList.records
this.total = res.pageList.total
} catch (e) { }
},
//
currentChange (val) {
this.page = val
this.getList()
},
handleCurrentChange (val) {
this.page = val
this.getList()
},
initData () {
this.page = 1
this.getList()
},
//
sortChange (column) {
if (column.prop === 'updateTime') this.filter.updateTimeOrder = column.order ? column.order === 'ascending' ? 1 : 2 : ''
this.getList()
},
//
add () {
this.form = _.cloneDeep(this.originForm)
this.detailVisible = true
},
//
previewPaper (row) {
this.$parent.previewPaper(row)
},
//
async submit () {
const { paperId } = this.form
if (!paperId) return Util.warningMsg('请选择试卷')
const curPaper = this.papers.find(e => e.paperId === paperId)
if (curPaper) this.form.paperName = curPaper.name
this.handlePaper()
},
//
async handlePaper () {
const { form } = this
// id
if (form.paperName !== form.originPaperName) {
const res = await this.$post(this.api.copyExamPaper, {
associatedID: form.stageId,
paperId: form.paperId,
typeId: 1
})
if (res.examPaper) {
form.paperId = res.examPaper.paperId
}
}
},
//
closeDia () {
this.$emit('update:visible', false)
}
}
};
</script>
<style lang="scss" scoped></style>

@ -29,17 +29,35 @@
<div class="tool mul"> <div class="tool mul">
<ul class="filter"> <ul class="filter">
<li> <li>
<label>赛来源</label> <label>赛来源</label>
<el-select v-model="form.platformSource" clearable @change="sourceChange"> <el-select v-model="form.platformSource" clearable @change="initData">
<el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>大赛范围</label> <label>发布类型</label>
<el-select v-model="form.competitionScope" clearable @change="initData"> <el-select v-model="form.releaseType" clearable @change="initData">
<el-option v-for="(item, i) in releaseTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>竞赛范围</label>
<el-select v-model="form.competitionScope" @change="initData">
<el-option v-for="(item, i) in rangeList" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in rangeList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li>
<label>竞赛类型</label>
<el-select v-model="form.competitionType" clearable @change="initData">
<el-option v-for="(item, i) in competitionTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>状态</label>
<el-select v-model="form.publishStatus" clearable @change="initData">
<el-option v-for="(item, i) in publishStatus" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
</ul> </ul>
<div> <div>
<el-button type="primary" round @click="add" v-auth>创建竞赛</el-button> <el-button type="primary" round @click="add" v-auth>创建竞赛</el-button>
@ -56,34 +74,39 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="competitionName" label="竞赛名称" align="center"></el-table-column> <el-table-column prop="competitionName" label="竞赛名称" align="center"></el-table-column>
<el-table-column prop="name" label="竞赛类型" width="90" align="center"> <el-table-column prop="name" label="竞赛来源" width="90" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} {{ sourceList.find(e => e.id === scope.row.platformSource).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founderName" label="创建人" align="center"></el-table-column> <el-table-column prop="name" label="发布类型" width="110" align="center">
<el-table-column prop="name" label="大赛来源" width="110" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ sourceList.find(e => e.id === scope.row.platformSource).name }} {{ scope.row.releaseType ? '设置完整比赛' : '练习赛' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="大赛范围" align="center"> <el-table-column prop="name" label="竞赛范围" width="100" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ rangeList.find(e => e.id === scope.row.competitionScope).name }} {{ rangeList.find(e => e.id === scope.row.competitionScope).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="竞赛类型" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }}
</template>
</el-table-column>
<el-table-column prop="applicantNum" label="报名人数" align="center" width="100"></el-table-column> <el-table-column prop="applicantNum" label="报名人数" align="center" width="100"></el-table-column>
<el-table-column prop="status" label="状态" align="center" width="80"> <el-table-column prop="status" label="状态" align="center" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.publishStatus ? '已发布' : '未发布' }} {{ scope.row.publishStatus ? '已发布' : '未发布' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="time" label="赛时间" align="center" width="290"> <el-table-column prop="time" label="赛时间" align="center" width="290">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.playStartTime }} ~ {{ scope.row.playEndTime }} {{ scope.row.playStartTime }} ~ {{ scope.row.playEndTime }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column> <el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column>
<el-table-column prop="founderName" label="创建人" width="130" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="280"> <el-table-column label="操作" align="center" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="copy(scope.row)">复制</el-button> <el-button type="text" @click="copy(scope.row)">复制</el-button>
@ -128,7 +151,7 @@
</template> </template>
<script> <script>
import util from "@/libs/util"; import Util from '@/libs/util'
import Bus from '@/libs/bus' import Bus from '@/libs/bus'
import qs from 'qs' import qs from 'qs'
export default { export default {
@ -150,11 +173,25 @@ export default {
name: "院校创建" name: "院校创建"
} }
], ],
rangeList: [ releaseTypes: [
{ {
id: '', id: '',
name: "不限" name: "不限"
}, },
{
id: 0,
name: '发布信息'
},
{
id: 1,
name: '完整比赛'
}
],
rangeList: [
{
id: null,
name: "不限"
},
{ {
id: 1, id: 1,
name: "全平台" name: "全平台"
@ -168,14 +205,45 @@ export default {
name: "校内" name: "校内"
} }
], ],
competitionTypes: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '个人赛'
},
{
id: 1,
name: '团队赛'
}
],
publishStatus: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '未发布'
},
{
id: 1,
name: '已发布'
}
],
matchData: [], matchData: [],
form: { form: {
keyWord: this.$route.query.keyWord || null, keyWord: null,
month: +this.$route.query.month || '', month: '',
startTime: this.$route.query.startTime || '', startTime: null,
endTime: this.$route.query.endTime || '', endTime: null,
platformSource: this.$route.query.platformSource === 'null' ? null : (+this.$route.query.platformSource || 0), // (01) releaseType: '',
competitionScope: this.$route.query.competitionScope ? +this.$route.query.competitionScope : '', // (0: 1: 2.) publishStatus: '',
competitionType: '',
platformSource: 0, // (01)
competitionScope: null, // (0: 1: 2.)
}, },
multipleSelection: [], multipleSelection: [],
dateList: [ dateList: [
@ -215,13 +283,14 @@ export default {
}] }]
}, },
loading: false, loading: false,
now: '',
}; };
}, },
watch: { watch: {
"form.month": function (val) { "form.month": function (val) {
if (val) { if (val) {
let unit = 24 * 60 * 60 * 1000; let unit = 24 * 60 * 60 * 1000;
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; this.date = [Util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), Util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))];
} else { } else {
this.date = []; this.date = [];
} }
@ -246,6 +315,18 @@ export default {
mounted () { mounted () {
const { query } = this.$route const { query } = this.$route
if (query.page) { if (query.page) {
const { keyWord, month, startTime, endTime, platformSource, competitionScope, competitionType, publishStatus, releaseType } = query
this.form = {
keyWord: keyWord || null,
month: +month || '',
startTime: startTime || null,
endTime: endTime || null,
competitionType: competitionType || '',
publishStatus: publishStatus || '',
releaseType: releaseType || '',
platformSource: platformSource === 'null' ? null : (+platformSource || 0), // (01)
competitionScope: competitionScope ? +competitionScope : null, // (0: 1: 2.)
}
this.$router.push('/match').catch(() => { }) this.$router.push('/match').catch(() => { })
} }
@ -260,53 +341,57 @@ export default {
}) })
}, },
methods: { methods: {
getData () { async getData () {
this.loading = true this.loading = true
try {
const { form } = this const { form } = this
this.$post(this.api.CompetitionPageConditionQueryByNakadai, { const { data } = await this.$post(this.api.CompetitionPageConditionQueryByNakadai, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
competitionScope: form.competitionScope === '' ? null : form.competitionScope, ...form
endTime: form.endTime || null, })
keyWord: form.keyWord, this.matchData = data.records
platformSource: form.platformSource,
startTime: form.startTime || null, this.now = await Util.getNow()
}).then(({ data }) => { clearInterval(this.timer)
const list = data.records this.handleBeganStage()
//
this.timer = setInterval(() => { this.timer = setInterval(() => {
const now = new Date() this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
list.map(e => { this.handleBeganStage()
}, 1000)
this.total = data.total
this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
} catch (e) {
this.loading = false
}
},
//
async handleBeganStage () {
this.matchData.map(e => {
if (!e.playingStages) { if (!e.playingStages) {
this.$set(e, 'playingStages', []) this.$set(e, 'playingStages', [])
} else { } else {
e.playingStages = [] e.playingStages = []
} }
// //
if (now >= new Date(e.playStartTime) && now <= new Date(e.playEndTime)) { if (this.now >= new Date(e.playStartTime) && this.now <= new Date(e.playEndTime)) {
// //
if (e.competitionStageList) { if (e.competitionStageList) {
for (const n of e.competitionStageList) { for (const n of e.competitionStageList) {
// //
if (now >= new Date(n.startTime) && now <= new Date(n.endTime)) { if (this.now >= new Date(n.startTime) && this.now <= new Date(n.endTime)) {
e.playingStages.push(n) e.playingStages.push(n)
} }
} }
} }
} }
}) })
}, 1000)
this.matchData = list
this.total = data.total
this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
}).catch(res => {
this.loading = false
})
}, },
initData () { initData () {
this.page = 1; this.page = 1;
@ -326,7 +411,7 @@ export default {
type: "warning" type: "warning"
}).then(async () => { }).then(async () => {
await this.$post(`${this.api.copyCompetition}?competitionId=${row.id}`) await this.$post(`${this.api.copyCompetition}?competitionId=${row.id}`)
util.successMsg('复制成功') Util.successMsg('复制成功')
this.initData() this.initData()
}).catch(() => { }) }).catch(() => { })
}, },
@ -349,7 +434,7 @@ export default {
competitionContents: data competitionContents: data
}).then(async res => { }).then(async res => {
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)
util.successMsg('修改成功') Util.successMsg('修改成功')
this.modifyVisible = false this.modifyVisible = false
this.getData() this.getData()
}).catch(err => { }) }).catch(err => { })
@ -374,7 +459,7 @@ export default {
}) })
.then(() => { .then(() => {
this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => { this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => {
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(res => { }).catch(res => {
}); });
@ -419,7 +504,7 @@ export default {
isOpen: val, isOpen: val,
type: 0 // (01) type: 0 // (01)
}).then(res => { }).then(res => {
util.successMsg(val == 1 ? '禁用成功' : '启用成功') Util.successMsg(val == 1 ? '禁用成功' : '启用成功')
}).catch(err => { }) }).catch(err => { })
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)

@ -42,7 +42,6 @@ export default {
tab3: "竞赛进展", tab3: "竞赛进展",
tab4: "公告通知", tab4: "公告通知",
tab5: "报名人员", tab5: "报名人员",
tab6: '查看异常团队'
} }
}; };
}, },
@ -55,7 +54,11 @@ export default {
AbnormalTeam AbnormalTeam
}, },
mounted () { mounted () {
Setting.dynamicRoute && this.initTabs() // if (Setting.dynamicRoute) {
this.initTabs()
// } else {
// this.active = this.$route.query.tab || 'tab1'
// }
}, },
methods: { methods: {
async initTabs () { async initTabs () {
@ -73,7 +76,12 @@ export default {
tab3 || this.$delete(this.tabs, 'tab3') tab3 || this.$delete(this.tabs, 'tab3')
tab4 || this.$delete(this.tabs, 'tab4') tab4 || this.$delete(this.tabs, 'tab4')
tab5 || this.$delete(this.tabs, 'tab5') tab5 || this.$delete(this.tabs, 'tab5')
res.competition.completeCompetitionSetup.competitionType || this.$delete(this.tabs, 'tab6')
if (res.competition.completeCompetitionSetup.competitionType) {
this.tabs.tab6 || this.$set(this.tabs, 'tab6', '查看异常团队')
} else {
this.tabs.tab6 && this.$delete(this.tabs, 'tab6')
}
const type = this.$route.query.tab const type = this.$route.query.tab
const keys = Object.keys(this.tabs) const keys = Object.keys(this.tabs)
@ -117,7 +125,7 @@ export default {
// tab // tab
tabSwitch (i) { tabSwitch (i) {
this.active = i this.active = i
this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`) this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`).catch(e => { })
}, },
// tab // tab
backOrTab (i) { backOrTab (i) {

@ -1,61 +1,57 @@
<template> <template>
<!-- 报名人员 --> <!-- 报名人员 -->
<div class="page-content" <div class="page-content" style="padding: 24px">
style="padding: 24px"> <el-table ref="table" :data="list" class="table" stripe header-align="center" row-key="stageId">
<el-table ref="table" <el-table-column type="index" width="60" label="序号" align="center">
:data="list"
class="table"
stripe
header-align="center"
row-key="stageId">
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="stageName" <el-table-column prop="stageName" label="阶段名称" align="center"></el-table-column>
label="阶段名称" <el-table-column prop="competitionContent" label="比赛内容" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="methodName" label="比赛方式" align="center"></el-table-column>
<el-table-column prop="methodName" <el-table-column label="竞赛类型" align="center">
label="比赛方式"
align="center"></el-table-column>
<el-table-column prop="founderName"
label="比赛形式"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} {{ scope.row.competitionType ? '团队赛' : '个人赛' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="ruleName" <el-table-column prop="ruleName" label="赛制" align="center"></el-table-column>
label="赛制" <el-table-column prop="status" label="大赛状态" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="reviewStatus" label="评阅情况" align="center"></el-table-column>
<el-table-column prop="status" <el-table-column label="竞赛时间" width="290" align="center">
label="状态"
align="center"></el-table-column>
<el-table-column label="竞赛起止时间"
width="290"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.startTime + ' ~ ' + scope.row.endTime }} {{ scope.row.startTime + ' ~ ' + scope.row.endTime }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="280">
align="center"
width="260">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" <el-button type="text" @click="toRank(scope.row, scope.$index)">排名</el-button>
@click="toRank(scope.row, scope.$index)">排名</el-button> <el-button type="text" @click="toArch(scope.row, scope.$index)">成绩统计</el-button>
<el-button @click="toArch(scope.row, scope.$index)">成绩管理</el-button> <!-- <el-button @click="toArch(scope.row, scope.$index)">编辑试卷</el-button> -->
<template v-if="scope.row.method === 1">
<el-button v-if="scope.row.showMyReviewTask" type="text"
@click="showReview(scope.row, '/myReview/records')">我的评阅任务</el-button>
<el-button v-auth="'/review:分配评阅任务'" type="text"
@click="showReview(scope.row, '/allocationReview')">分配评阅任务</el-button>
</template>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import Const from '@/const/match' import Const from '@/const/match'
export default { export default {
name: "matchArch", name: "matchArch",
@ -66,6 +62,8 @@ export default {
form: {}, form: {},
timer: null, timer: null,
curStep: [], curStep: [],
reviewVisible: false,
reviewUrl: '',
}; };
}, },
mounted () { mounted () {
@ -125,7 +123,16 @@ export default {
this.$store.commit('setInnerReferrer', this.$route.fullPath) this.$store.commit('setInnerReferrer', this.$route.fullPath)
const cur = this.form.competitionStage[i] const cur = this.form.competitionStage[i]
const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles) const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles)
this.$router.push(`/matchArchList?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}`) this.$router.push(`/${cur.method === 2 ? 'otherArchList' : 'matchArchList'}?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}&showMyReviewTask=${row.showMyReviewTask}`)
},
//
showReview (row, path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${row.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
} }
} }
}; };
@ -136,12 +143,26 @@ export default {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
} }
.line { .line {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
span { span {
margin-right: 30px; margin-right: 30px;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -1,277 +1,191 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20 head-card">
class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<el-page-header @back="back" <el-page-header @back="back" content="成绩管理"></el-page-header>
content="成绩管理"></el-page-header>
</div> </div>
</el-card> </el-card>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="method != 2" <el-card v-if="method != 2" shadow="hover" class="m-b-20">
shadow="hover"
class="m-b-20">
<div class="stat"> <div class="stat">
<div class="nums"> <div class="nums">
<div class="item"> <div class="item">
<p class="name">已参加/应参加人数</p> <p class="name">已参加/应参加人数</p>
<p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}</p> <p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}
</p>
</div> </div>
<div class="item"> <div class="item">
<p class="name">实验平均分</p> <p class="name">平均分</p>
<p class="val">{{ avgScore }}</p> <p class="val">{{ (+statData.avgScore).toFixed(2) }}</p>
</div> </div>
<div class="item">
<p class="name">最高分</p>
<p class="val">{{ statData.maxScore }}
</p>
</div>
<div class="item">
<p class="name">最低分</p>
<p class="val">{{ statData.minScore }}</p>
</div> </div>
<div class="chart" </div>
id="chart"></div> <div class="chart" id="chart"></div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20"> <div class="tabs m-b-20">
<div v-if="showFile" <a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: item.id === active }"
class="tabs m-b-20"> @click="tabChange(item.id)">{{ item.name }}</a>
<a class="item"
v-for="(item, i) in tabs"
:key="i"
:class="{active: i === active}"
@click="tabChange(i)">{{ item }}</a>
</div> </div>
<div class="flex-between m-b-20"> <div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li v-if="active">
<label>评阅状态</label>
<el-select v-model="filter.reviewStatus" clearable placeholder="请选择评阅状态" @change="initData">
<el-option value="待评阅"></el-option>
<el-option value="已评阅"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学生姓名、学生学号、团队名称" prefix-icon="el-icon-search" v-model="keyword"
clearable style="width: 300px"></el-input>
</li>
</ul>
<div> <div>
<el-input size="small" <template v-if="active && method === 1">
placeholder="请输入学校/学生姓名" <el-button v-auth="'/review:分配评阅任务'" type="primary" size="mini"
prefix-icon="el-icon-search" @click="showReview('/allocationReview')">分配评阅任务</el-button>
v-model="keyword" <el-button v-if="showMyReviewTask" type="primary" size="mini"
clearable @click="showReview('/myReview/records')">我的评阅任务</el-button>
style="width: 300px"></el-input> <el-button type="primary" size="mini" @click="exportFiles">导出答题文件</el-button>
</div> </template>
<div v-if="!active"> <el-button type="primary" size="mini" :loading="exportingList" @click="exportList">{{ exportingList ? '正在导出'
<el-button v-if="method == 2" :
type="primary" '导出成绩列表'
@click="batchImport">上传成绩</el-button> }}</el-button>
<el-button type="primary" <template v-if="active">
:disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)" <el-button type="primary" size="mini" :loading="exportingReport" @click="exporReport">{{ exportingReport ?
@click="delAllData">批量删除</el-button> '正在导出' :
<el-button type="primary" '导出成绩报告'
:loading="exporting" }}</el-button>
@click="exportData">{{ exporting ? '正在导出' : '批量导出' }}</el-button> <el-button type="primary" size="mini" @click="delAllData">批量删除</el-button>
</div> </template>
<div v-else>
<el-button type="primary"
:loading="exporting1"
@click="exportData1">{{ exporting1 ? '正在导出' : '批量导出' }}</el-button>
</div> </div>
</div> </div>
<template v-if="!active"> <el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
<el-table :data="list" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
class="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
:key="1" <el-table-column type="index" width="60" label="序号" align="center">
ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="schoolName" <el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
label="学生账号归属" <el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
min-width="100" <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
align="center"></el-table-column> align="center"></el-table-column>
<el-table-column prop="realSchool" <el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
label="学生所在院校" <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
min-width="100" <el-table-column prop="score" label="成绩" width="90" align="center" sortable="custom">
align="center"></el-table-column>
<el-table-column v-if="competitionType"
prop="teamName"
label="团队名称"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="userName"
label="学生姓名"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="score"
label="分数"
width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime ? scope.row.score : '--' }} {{ scope.row.submitTime ? scope.row.score : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="timeSum" <el-table-column prop="timeSum" label="用时" width="90" align="center">
label="耗时"
width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }} {{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="submitTime" <el-table-column prop="submitTime" label="提交时间" min-width="150" align="center" sortable="custom">
label="提交时间"
min-width="150"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime || '--' }} {{ scope.row.submitTime || '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" <el-table-column label="状态" width="100" align="center">
width="100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }} {{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column prop="evaluationStatus" label="评阅状态" align="center" width="90">
align="center"
width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="method != 2 && scope.row.reportId" <span v-if="scope.row.reviewStatus === '-'">-</span>
type="text" <el-tag v-else :type="scope.row.reviewStatus === '待评阅' ? 'danger' : 'success'">{{ scope.row.reviewStatus
@click="show(scope.row)">查看成绩报告</el-button> }}</el-tag>
<el-button v-if="scope.row.reportId"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> <el-table-column v-if="active" label="操作" align="center" width="300">
<div class="pagination"> <template v-if="scope.row.reportId" slot-scope="scope">
<el-pagination background <template v-if="method === 1">
layout="total, prev, pager, next" <el-popover placement="top" trigger="click" popper-class="files-tip">
:total="total" <div>
@current-change="handleCurrentChange" <ul class="match-files">
:current-page="page"> <li v-for="(file, i) in scope.row.files" :key="i" @click="preview(file.attachmentUrl)">{{
</el-pagination> file.attachmentName }}</li>
</ul>
</div> </div>
<el-button slot="reference" :disabled="!scope.row.hasFile" type="text"
@click="showFiles(scope.row)">查看答题文件</el-button>
</el-popover>
<el-button style="margin-left: 10px;" :disabled="!scope.row.hasFile" type="text"
@click="downloadFile(scope.row)">下载答题文件</el-button>
</template> </template>
<template v-else> <el-button v-if="method != 2" type="text" @click="toReport(scope.row)">查看成绩报告</el-button>
<el-table :data="list1" <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
class="table"
:key="2"
stripe
header-align="center"
@selection-change="handleSelectionChange1"
row-key="id">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="schoolName"
label="学生账号归属"
align="center"></el-table-column>
<el-table-column prop="realSchool"
label="学生所在院校"
align="center"></el-table-column>
<el-table-column v-if="competitionType"
prop="teamName"
label="团队名称"
align="center"></el-table-column>
<el-table-column prop="userName"
label="学生姓名"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
align="center"></el-table-column>
<el-table-column prop="fileName"
label="文件名"
align="center"></el-table-column>
<el-table-column prop="fileSize"
label="文件大小"
align="center"></el-table-column>
<el-table-column prop="fileType"
label="文件类型"
align="center"></el-table-column>
<el-table-column prop="fileFormat"
label="文件格式"
align="center"></el-table-column>
<el-table-column prop="createTime"
label="提交时间"
width="150"
align="center">
</el-table-column>
<el-table-column label="操作"
width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)"
type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary"
size="mini"
:loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total"
layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page">
:total="total1"
@current-change="handleCurrentChange1"
:current-page="page1">
</el-pagination> </el-pagination>
</div> </div>
</template>
</el-card> </el-card>
</div> </div>
<el-dialog title="批量导入"
:visible.sync="importVisible" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
width="24%"
:close-on-click-modal="false"
@close="cancelUpload"> @close="cancelUpload">
<div style="text-align: center"> <div style="text-align: center">
<template v-if="!uploadFaild"> <template v-if="!uploadFaild">
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<el-button type="primary" <el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
@click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div> </div>
<el-upload ref="upload" <el-upload ref="upload" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload"
name="file" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove"
accept=".xls,.xlsx" :limit="1" :on-exceed="handleExceed" :action="this.api.batchImportGrades" :file-list="uploadList"
class="import-file" :headers="headers" :disabled="uploading" :data="{
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.batchImportGrades"
:file-list="uploadList"
:headers="headers"
:disabled="uploading"
:data="{
competitionId: this.id, competitionId: this.id,
stageId: this.stageId, stageId: this.stageId,
systemId: 0 systemId: 0
}"> }">
<el-button type="primary" <el-button type="primary" :loading="uploading" class="ml20">上传文件<i
:loading="uploading" class="el-icon-upload2 el-icon--right"></i></el-button>
class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload> </el-upload>
</template> </template>
<template v-else> <template v-else>
@ -281,29 +195,58 @@
@click="showFaild">部分数据导入失败查看失败原因</p> @click="showFaild">部分数据导入失败查看失败原因</p>
</template> </template>
</div> </div>
<span v-if="uploading" <span v-if="uploading" slot="footer" class="dialog-footer">
slot="footer"
class="dialog-footer">
<el-button @click="cancelUpload">停止导入</el-button> <el-button @click="cancelUpload">停止导入</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
<el-dialog title="图片预览" :visible.sync="previewImgVisible" width="800px" :close-on-click-modal="false">
<el-image style="max-width: 100px; max-height: 100px" :src="previewImg" :preview-src-list="[previewImg]">
</el-image>
</el-dialog>
<PdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc" />
</div> </div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import Setting from '@/setting'
import PdfDia from '@/components/pdf'
import Util from '@/libs/util'
import * as echarts from "echarts"; import * as echarts from "echarts";
import axios from 'axios'; import axios from 'axios';
import Zip from '@/libs/zip'
export default { export default {
components: {
PdfDia
},
data () { data () {
return { return {
id: +this.$route.query.id, id: +this.$route.query.id,
stageId: +this.$route.query.stageId, stageId: +this.$route.query.stageId,
method: +this.$route.query.method, method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true', showMyReviewTask: +this.$route.query.showMyReviewTask,
isCompress: util.isCompress, isCompress: Util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
searchTimer: null, searchTimer: null,
list: [], list: [],
@ -326,12 +269,34 @@ export default {
headers: { headers: {
token: sessionStorage.getItem("token") token: sessionStorage.getItem("token")
}, },
statData: {}, statData: {
tabs: ['成绩列表', '文件列表'], avgScore: 0,
active: 0, maxScore: 0,
minScore: 0,
},
tabs: [
{
id: 1,
name: '已提交'
},
{
id: 0,
name: '未提交'
}
],
active: 1,
loading: false, loading: false,
exporting: false, exportingFiles: false,
exporting1: false, exportingList: false,
exportingReport: false,
previewImgVisible: false,
previewImg: '',
pdfVisible: false,
pdfSrc: '',
reviewVisible: false,
reviewUrl: '',
}; };
}, },
watch: { watch: {
@ -351,76 +316,141 @@ export default {
}, },
mounted () { mounted () {
this.getData() this.getData()
this.getProvince()
this.getSchool()
}, },
methods: { methods: {
async getData () { async getData () {
this.loading = true this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, { const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
competitionId: this.id, competitionId: this.id,
keyWord: this.keyword, keyWord: this.keyword,
stageId: this.stageId, stageId: this.stageId,
isNakadai: 1 isNakadai: 1,
participatingState: this.active,
...this.filter
}) })
this.loading = false this.loading = false
this.total = page.total this.total = page.total
this.list = page.records this.list = page.records
this.statData = data this.statData = data
this.avgScore = (+data.avgScore).toFixed(2) this.getChart()
this.method != 2 && this.getChart()
}
}, },
initData () { initData () {
this.page = 1 this.page = 1
this.getData() this.getData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
sortChange (column) {
if (column.prop === 'score') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
if (column.prop === 'submitTime') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
this.getData()
},
//
async showFiles (row) {
const { data } = await this.$get(this.api.getPaperUploadFile, {
reportId: row.reportId
})
this.$set(row, 'files', data)
},
//
async downloadFile (row) {
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: [row.reportId],
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
},
// //
show (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
},
//
showReview (path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${this.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
}, },
// () //
async exportData () { async exportFiles () {
if (this.list.length) { if (this.list.length) {
this.exporting = true this.exportingFiles = true
const list = this.multipleSelection
const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
}
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: ids,
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
this.exportingFiles = false
}
},
// ()
async exportList () {
if (this.list.length) {
this.exportingList = true
// //
if (this.multipleSelection.length) { if (this.multipleSelection.length) {
const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, { const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
} else if (this.list.length) { } else if (this.list.length) {
const res = await axios.post(this.api.allExperimentalResultsAreDerived, { const res = await axios.post(this.api.allExperimentalResultsAreDerived, {
pageNum: 1, pageNum: 1,
@ -428,40 +458,70 @@ export default {
competitionId: this.id, competitionId: this.id,
isNakadai: 1, isNakadai: 1,
stageId: this.stageId, stageId: this.stageId,
participatingState: this.active,
}, { }, {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
} }
} }
}, },
// () // ()
exportData1 () { async exporReport () {
this.exporting1 = true if (this.list.length) {
let list = this.list1 this.exportingReport = true
if (this.multipleSelection1.length) { const list = this.multipleSelection
list = this.multipleSelection1 const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
} }
Zip('批量导出', list, () => { let res
this.exporting1 = false //
if (this.method) {
res = await axios.post(this.api.exportExamPaperReports, {
ids,
stageId: list.length ? '' : this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
} else {
//
res = await axios.post(this.api.batchExportReportsAsZip, {
reportIds: ids,
stageId: this.stageId,
competitionId: this.id,
}, {
headers: this.headers,
responseType: 'blob'
}) })
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
}
}
}, },
handleDelete (row) { // async handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", { await this.$confirm(`<p>确认要删除【${row.userName}】的成绩记录吗?</p><p style="color: #f56c6c;">删除后成绩数据不可恢复,自动变为未提交</p>`, '提示', {
type: "warning" confirmButtonText: '确定',
}).then(() => { cancelButtonText: '取消',
this.$post(this.api.batchDeleteContestGrade, { type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
await this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId], ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id, competitionId: this.id,
stageId: this.stageId stageId: this.stageId
}).then(res => { })
util.successMsg("删除成功"); Util.successMsg("删除成功")
this.getData(); this.getData()
}).catch(res => {
});
}).catch(() => { });
}, },
delAllData () { // delAllData () { //
const list = this.multipleSelection const list = this.multipleSelection
@ -483,7 +543,7 @@ export default {
await this.$post(this.api.batchDeleteContestGrade, data) await this.$post(this.api.batchDeleteContestGrade, data)
this.multipleSelection = []; this.multipleSelection = [];
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(() => { }); }).catch(() => { });
}, },
@ -505,16 +565,8 @@ export default {
handleSelectionChange1 (val) { // handleSelectionChange1 (val) { //
this.multipleSelection1 = val; this.multipleSelection1 = val;
}, },
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线 getChart () { // 线
const data = [] const { fractionalSegmentCounts: data } = this.statData
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
let myChart = echarts.init(document.getElementById("chart")); let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({ myChart.setOption({
title: { text: "实验分数分布图" }, title: { text: "实验分数分布图" },
@ -524,7 +576,7 @@ export default {
type: "category", type: "category",
boundaryGap: false, boundaryGap: false,
interval: 10, interval: 10,
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"] data: data.map(e => e.range)
}, },
yAxis: { yAxis: {
name: "人数", name: "人数",
@ -532,9 +584,13 @@ export default {
minInterval: 10 minInterval: 10
}, },
series: [{ series: [{
data, data: data.map(e => e.count),
type: "line", type: "line",
areaStyle: {}, areaStyle: {},
label: {
show: true,
position: 'top'
},
color: ["#8191fd"] color: ["#8191fd"]
}] }]
}); });
@ -551,12 +607,12 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data])) Util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
// //
handleExceed (files, fileList) { handleExceed (files, fileList) {
util.warningMsg( Util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
) )
}, },
@ -566,7 +622,7 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data])) Util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
uploadSuccess (res) { uploadSuccess (res) {
@ -579,11 +635,11 @@ export default {
this.faildData = data this.faildData = data
this.uploadFaild = true this.uploadFaild = true
} else { } else {
util.successMsg(data.tip, 3000) Util.successMsg(data.tip, 3000)
this.importVisible = false this.importVisible = false
} }
} else { } else {
util.errorMsg(res.message || '上传失败,请检查数据') Util.errorMsg(res.message || '上传失败,请检查数据')
} }
}, },
uploadError (err, file, fileList) { uploadError (err, file, fileList) {
@ -613,29 +669,23 @@ export default {
}, },
// tab // tab
tabChange (i) { tabChange (i) {
this.multipleSelection = []
this.$refs.table.clearSelection()
this.active = i this.active = i
this.getData() this.initData()
}, },
// //
preview (item) { preview (url) {
window.open((util.isDoc(item.fileFormat) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath) const ext = url.split('.').pop()
}, if (Util.isDoc(ext)) {
// window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url)
exportFile (item) { } else if (Util.isImg(ext)) {
item.loading = true this.previewImgVisible = true
const url = item.filePath this.previewImg = url
var x = new XMLHttpRequest() } else if (ext === 'pdf') {
x.open("GET", url, true) this.pdfVisible = true
x.responseType = "blob" this.pdfSrc = url
x.onload = function (e) { }
var url = window.URL.createObjectURL(x.response)
var a = document.createElement("a")
a.href = url
a.download = item.userName + '-' + item.fileName
a.click()
item.loading = false
}
x.send()
}, },
back () { back () {
this.$router.push(this.$store.state.innerReferrer) this.$router.push(this.$store.state.innerReferrer)
@ -663,12 +713,31 @@ export default {
} }
} }
.tool {
align-items: flex-start;
margin-bottom: 10px;
.filter {
flex-wrap: wrap;
}
li {
margin-bottom: 10px;
}
/deep/.el-select {
width: 140px;
}
}
.stat { .stat {
display: flex; display: flex;
.nums { .nums {
display: flex; display: flex;
flex-wrap: wrap;
align-items: center; align-items: center;
width: 640px;
margin-right: 20px; margin-right: 20px;
.item:nth-child(1) { .item:nth-child(1) {
@ -679,6 +748,14 @@ export default {
background-image: url('../../../assets/img/avg.png'); background-image: url('../../../assets/img/avg.png');
} }
.item:nth-child(3) {
background-image: url('../../../assets/img/ach1.png');
}
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
}
.item { .item {
width: 300px; width: 300px;
min-height: 145px; min-height: 145px;
@ -703,10 +780,11 @@ export default {
} }
.chart { .chart {
flex: 1; width: calc(100% - 660px);
height: 300px; height: 300px;
} }
} }
/deep/.import-file { /deep/.import-file {
.el-progress__text, .el-progress__text,
.el-progress, .el-progress,
@ -714,4 +792,16 @@ export default {
display: none !important; display: none !important;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -36,15 +36,15 @@
</tr> </tr>
<tr> <tr>
<th>学校</th> <th>学校</th>
<td>{{ info.person.schoolName }}</td> <td>{{ info.person.realSchool }}</td>
</tr> </tr>
</template> </template>
<template v-if="form.completeCompetitionSetup.competitionType"> <template v-if="form.completeCompetitionSetup.competitionType">
<template> <template>
<tr> <tr>
<th>队长</th> <th>队长</th>
<td>{{ info.caption.userName }}{{ info.caption.schoolName && ',' + info.caption.schoolName }}{{ <td>{{ info.captain.userName }}{{ info.captain.realSchool && ',' + info.captain.realSchool }}{{
info.caption.workNumber && ',' + info.caption.workNumber }}</td> info.captain.workNumber && ',' + info.captain.workNumber }}</td>
</tr> </tr>
<tr> <tr>
<th>团队成员</th> <th>团队成员</th>
@ -129,7 +129,7 @@
<td colspan="6">暂无数据</td> <td colspan="6">暂无数据</td>
</tr> </tr>
</table> </table>
<el-alert v-if="form.completeCompetitionSetup.competitionType" style="margin-top: 10px;" <el-alert v-if="form.completeCompetitionSetup.competitionType && form.rule !== 2" style="margin-top: 10px;"
:title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'" :title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'"
type="warning" show-icon> type="warning" show-icon>
</el-alert> </el-alert>
@ -144,12 +144,13 @@
}}</el-tag> }}</el-tag>
</div> </div>
<div class="flex-center"> <div class="flex-center">
<p>队长{{ info.caption.userName }}</p> <p>队长{{ info.captain.userName }}</p>
<el-button type="primary" @click="transfer">转让队长</el-button> <el-button type="primary" @click="transfer">转让队长</el-button>
</div> </div>
<el-table :data="info.teamDetail" stripe header-align="center"> <el-table :data="info.teamDetail" stripe header-align="center">
<el-table-column prop="userName" label="成员姓名" min-width="100" align="center"></el-table-column> <el-table-column prop="userName" label="成员姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学校" min-width="100" align="center"></el-table-column>
<el-table-column prop="phone" label="手机号" min-width="100" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column> <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column> <el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="160"> <el-table-column label="操作" align="center" width="160">
@ -198,7 +199,7 @@
<tr v-for="(item, i) in members" :key="i"> <tr v-for="(item, i) in members" :key="i">
<td>{{ i + 1 }}</td> <td>{{ i + 1 }}</td>
<td>{{ item.userName }}</td> <td>{{ item.userName }}</td>
<td>{{ item.schoolName }}</td> <td>{{ item.realSchool }}</td>
<td>{{ item.timeSum }}min</td> <td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td> <td>{{ item.score }}</td>
<td> <td>
@ -239,7 +240,7 @@ export default {
info: { info: {
isCaption: 0, isCaption: 0,
person: {}, person: {},
caption: {}, captain: {},
team: { team: {
captain: 1, captain: 1,
invitationCode: '' invitationCode: ''
@ -314,10 +315,10 @@ export default {
info.team = {} info.team = {}
info.teamDetail = [] info.teamDetail = []
} else { } else {
info.isCaption = info.team.caption info.isCaption = info.team.captain
} }
const caption = info.teamDetail.find(e => !e.caption) const captain = info.teamDetail.find(e => !e.captain)
info.caption = caption ? caption : {} info.captain = captain ? captain : {}
info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId) info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId)
this.originInfo = JSON.parse(JSON.stringify(info)) this.originInfo = JSON.parse(JSON.stringify(info))
// accountId // accountId
@ -347,9 +348,10 @@ export default {
teamId: this.info.teamId teamId: this.info.teamId
}) })
this.teamErrors = res.teamTip.split(';').filter(e => e) this.teamErrors = res.teamTip.split(';').filter(e => e)
if (Object.keys(res.stageTip).length) { if (Object.keys(res.stageTip).length) {
this.stageTip = res.stageTip this.stageTip = res.stageTip
} else {
this.stageTip = null
} }
}, },
// //
@ -451,7 +453,7 @@ export default {
transferSubmit () { transferSubmit () {
if (!this.checkedPlayer) return Util.errorMsg('请选择成员') if (!this.checkedPlayer) return Util.errorMsg('请选择成员')
this.$post(this.api.captainOfTransfer, { this.$post(this.api.captainOfTransfer, {
captainId: this.info.caption.teamId, captainId: this.info.captain.teamId,
playerId: this.checkedPlayer playerId: this.checkedPlayer
}).then(res => { }).then(res => {
this.checkedPlayer = '' this.checkedPlayer = ''
@ -570,9 +572,9 @@ export default {
}, },
// //
show (row) { show (row) {
this.curRow = row
// //
if (this.form.completeCompetitionSetup.competitionType) { // if (this.form.completeCompetitionSetup.competitionType) { //
this.curRow = row
this.memberVisible = true this.memberVisible = true
if (this.info.teamId) { if (this.info.teamId) {
this.getMembers() this.getMembers()
@ -589,7 +591,7 @@ export default {
}, },
// //
toReport (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.curRow.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
}, },
back () { back () {
this.$router.push(this.$store.state.innerReferrer) this.$router.push(this.$store.state.innerReferrer)

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20 head-card"> <el-card shadow="hover" class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between">
<el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header> <el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header>
</div> </div>
@ -14,15 +14,41 @@
@click="tabChange(item.stageId)">{{ item.stageName }}排名</a> @click="tabChange(item.stageId)">{{ item.stageName }}排名</a>
</template> </template>
</div> </div>
<div class="flex-between" style="margin: 20px 0">
<div class="tool flex-between" style="margin-top: 20px">
<div style="display: inline-flex;align-items: center"> <div style="display: inline-flex;align-items: center">
<el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio> <el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio>
<el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio> <el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio>
<el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button> <el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button>
</div> </div>
<div style="display: inline-flex;align-items: center"> <ul class="filter" style="flex: none;">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" clearable filterable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" clearable filterable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li>
<el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'" <el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'"
prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</li>
<el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button> <el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button>
<template v-else> <template v-else>
<span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span> <span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span>
@ -31,8 +57,9 @@
<el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : <el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' :
'批量导出' '批量导出'
}}</el-button> }}</el-button>
</ul>
</div> </div>
</div>
<el-table :data="list" class="table" ref="table" stripe row-key="scoreId" <el-table :data="list" class="table" ref="table" stripe row-key="scoreId"
@selection-change="handleSelectionChange" header-align="center"> @selection-change="handleSelectionChange" header-align="center">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
@ -46,6 +73,8 @@
<el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column> <el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column>
</template> </template>
<el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column> <el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column prop="timeSum" label="用时" width="90" align="center"> <el-table-column prop="timeSum" label="用时" width="90" align="center">
@ -100,7 +129,7 @@
<template v-if="item.accountId"> <template v-if="item.accountId">
<td>{{ i + 1 }}</td> <td>{{ i + 1 }}</td>
<td>{{ item.userName }}</td> <td>{{ item.userName }}</td>
<td>{{ item.schoolName }}</td> <td>{{ item.realSchool }}</td>
<td>{{ item.timeSum }}min</td> <td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td> <td>{{ item.score }}</td>
<td> <td>
@ -178,10 +207,18 @@ export default {
id: +this.$route.query.id, id: +this.$route.query.id,
stageId: +this.$route.query.stageId, stageId: +this.$route.query.stageId,
index: +this.$route.query.index, index: +this.$route.query.index,
method: this.$route.query.method, method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
rule: +this.$route.query.rule, rule: +this.$route.query.rule,
searchTimer: null, searchTimer: null,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
teamCalculationMethods: [ teamCalculationMethods: [
{ {
@ -262,6 +299,8 @@ export default {
} }
}, },
mounted () { mounted () {
this.getProvince()
this.getSchool()
this.getStage() this.getStage()
}, },
methods: { methods: {
@ -275,6 +314,7 @@ export default {
}, },
// //
getRank () { getRank () {
const { filter } = this
this.loading = true this.loading = true
// //
if (this.type) { if (this.type) {
@ -284,7 +324,8 @@ export default {
competitionId: this.id, competitionId: this.id,
isOverallRanking: this.active ? 0 : 1, isOverallRanking: this.active ? 0 : 1,
stageId: this.active || this.stageId, stageId: this.active || this.stageId,
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ message, publishStatus }) => { }).then(({ message, publishStatus }) => {
// isRelease 01 // isRelease 01
this.published = publishStatus this.published = publishStatus
@ -307,7 +348,8 @@ export default {
publicationType: this.type, publicationType: this.type,
locationStageId: this.stageId, locationStageId: this.stageId,
stageIds: ids.splice(0, ids.length - 1), stageIds: ids.splice(0, ids.length - 1),
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ page, publishStatus, total }) => { }).then(({ page, publishStatus, total }) => {
this.published = publishStatus this.published = publishStatus
this.list = page || [] this.list = page || []
@ -319,7 +361,7 @@ export default {
}) })
} else { } else {
// //
this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}`).then(({ page, total, publishStatus }) => { this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}&provinceId=${filter.provinceId}&cityId=${filter.cityId}&realSchoolId=${filter.realSchoolId}`).then(({ page, total, publishStatus }) => {
this.published = publishStatus this.published = publishStatus
this.list = page this.list = page
this.total = total this.total = total
@ -367,6 +409,39 @@ export default {
this.active = i this.active = i
this.initData() this.initData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
// //
show (row, i) { show (row, i) {
this.teams = [] this.teams = []
@ -449,7 +524,7 @@ export default {
}, },
// //
toReport (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.method !== 1 ? 'trialReport' : 'theoryReport'}?reportId=${row.reportId}`)
}, },
handleSelectionChange (val) { // handleSelectionChange (val) { //
this.multipleSelection = val; this.multipleSelection = val;

@ -1,449 +0,0 @@
<template>
<div class="wrap">
<el-card shadow="hover"
class="m-b-20">
<el-page-header @back="$router.back()"
content="查看报告"></el-page-header>
</el-card>
<div class="content"
v-loading="loading">
<div class="text-right">
<el-button type="primary"
@click="exportPage">导出报告</el-button>
</div>
<h6 class="r-title">标准实验报告</h6>
<div class="info">
<h6 class="l-title">
<img src="@/assets/img/info1.png"
alt="">
基本信息
</h6>
<ul :class="['info-list', {edit: editing}]">
<li>
<label>学生姓名</label>
<el-input v-if="editing"
v-model="infoData.userName"
disabled></el-input>
<span v-else>{{ infoData.userName }}</span>
</li>
<li>
<label>学生学号</label>
<el-input v-if="editing"
v-model="infoData.workNumber"
disabled></el-input>
<span v-else>{{ infoData.workNumber }}</span>
</li>
<li>
<label>实验时间</label>
<el-input v-if="editing"
v-model="infoData.submitTime"
disabled></el-input>
<span v-else>{{ infoData.submitTime }}</span>
</li>
<li>
<label>实验成绩</label>
<el-input v-if="editing"
v-model="infoData.score"
disabled></el-input>
<div v-else
class="score-wrap">
<em>{{ infoData.score }}</em>
<img src="@/assets/img/point.png"
alt="">
</div>
</li>
<li>
<label>学生班级</label>
<el-input v-if="editing"
v-model="infoData.className"></el-input>
<span v-else>{{ infoData.className }}</span>
</li>
<li>
<label>指导老师</label>
<el-input v-if="editing"
v-model="infoData.instructor"></el-input>
<span v-else>{{ infoData.instructor }}</span>
</li>
<li>
<label>实验学时</label>
<el-input v-if="editing"
v-model="infoData.period"></el-input>
<span v-else>{{ infoData.period }}</span>
</li>
</ul>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report2.png"
alt="">
实验项目名称
</h6>
<el-input v-if="editing"
v-model="form.projectName"
type="textarea"></el-input>
<div v-else
class="pre-wrap"
v-html="form.projectName"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report3.png"
alt="">
实验目的
</h6>
<div :class="['pre-wrap', {edit: editing}]"
v-html="form.purpose"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report4.png"
alt="">
实验数据
</h6>
<el-table :data="expData"
class="table"
border
stripe
header-align="center">
<el-table-column type="index"
label="序号"
align="center"
width="60">
<template slot-scope="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="judgmentName"
label="判分点"
width="270"
align="center"></el-table-column>
<el-table-column v-if='project'
prop="judgmentName"
label="考核点"
align="center"
width="150">
<template slot-scope="scope">
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span>
<span>{{index+1}}. </span>{{item.name}}
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="ruleAnswer"
label="参考答案"
style='word-wrap: break-word'>
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span>
<span>{{index+1}}. </span>{{item.ruleAnswer}}
</span>
</div>
</div>
<div v-else
v-html="scope.row.referenceAnswer"></div>
</template>
</el-table-column>
<el-table-column prop="userAnswer"
label="学生答案">
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span v-if='item.userAnswer'>
<span>{{index+1}}. </span>{{item.userAnswer}}
</span>
<span v-else>
<span>{{index+1}}. </span>未填写
</span>
</div>
</div>
<div v-else
v-html='scope.row.answer'
style='white-space: pre-wrap'></div>
<template v-if="scope.row.runThePictureList">
<img v-for="(img, i) in scope.row.runThePictureList"
:key="i"
width="200"
class="result-pic"
:src="img"
alt="">
</template>
</template>
</el-table-column>
<el-table-column prop="quesScore"
label="分值"
:key="6"
width="80"
align="center"></el-table-column>
<el-table-column prop="score"
label="得分"
width="80"
align="center"></el-table-column>
</el-table>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report5.png"
alt="">
实验总结与体会
</h6>
<quill v-if="editing"
:border="true"
v-model="form.summarize"
:minHeight="150"
:height="150" />
<div v-else
class="pre-wrap"
v-html="form.summarize"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import util from "@/libs/util";
export default {
data () {
return {
reportId: this.$route.query.reportId,
title: "实验报告",
form: {
className: "",
instructor: "",
period: "",
projectName: "",
summarize: "",
},
infoData: {},
expData: [],
editing: false,
loadIns: null,
loading: false,
project: false,
userScores: []
};
},
mounted () {
this.getData()
},
methods: {
getData () { //
this.loading = true
this.$get(`${this.api.reportDetail}?reportId=${this.reportId}`).then(({ report, userScores }) => {
this.form = report
this.expData = userScores
this.project = this.expData.find(e => e.lcRuleRecords) // lcRuleRecords
let form = this.form;
this.infoData = {
workNumber: form.workNumber,
experimentalClassName: form.experimentalClassName,
instructor: form.instructor,
period: form.period,
laboratory: form.laboratory,
submitTime: form.submitTime,
score: form.score,
className: form.className,
userName: form.userName
}
const data = report.data
this.userScores = userScores
// data使
if (!data) {
this.handleList(userScores)
this.$post(this.api.editExperimentalData, {
reportId,
data: JSON.stringify(userScores)
}).then(res => { }).catch(err => { })
} else {
this.handleList(userScores.find(e => e.lcRuleRecords) ? userScores : JSON.parse(data))
}
}).catch(res => {
this.loading = false
})
},
//
handleList (list) {
this.project = list.find(e => e.lcRuleRecords) // lcRuleRecords
if (this.project) {
list.map(e => {
e.assessmentPoint = ''
e.referenceAnswer = ''
e.answer = ''
e.lcRuleRecords.map((n, i) => {
e.assessmentPoint += `${i + 1}.${n.name}`
e.referenceAnswer += `${i + 1}.${n.ruleAnswer}`
e.answer += `${i + 1}.${n.userAnswer}`
})
})
} else { // pythonuserScores
list.forEach(e => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
})
}
this.expData = list
this.loading = false
},
exportPage () {
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
list.map((e, i) => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePicture) e.runThePicture = item.runThePicture
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
e.id = i + 1
// if (e.referenceAnswer && typeof e.referenceAnswer === 'string') e.referenceAnswer = e.referenceAnswer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in form) {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.project ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
}).catch(res => { })
},
}
};
</script>
<style lang="scss" scoped>
.wrap {
padding: 12px 300px 20px;
}
.text-right {
text-align: right;
}
code,
kbd,
samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
word-wrap: break-word;
white-space: pre-wrap;
}
/deep/ pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
word-break: break-all;
overflow: hidden;
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
}
.content {
padding: 16px 40px;
background: #fff;
.r-title {
margin-bottom: 40px;
font-size: 24px;
text-align: center;
color: #333;
}
.info {
padding: 20px 16px;
border: 1px solid #e1e6f2;
}
.l-title {
display: flex;
align-items: center;
padding: 5px 8px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
}
.info-list {
display: flex;
flex-wrap: wrap;
padding: 10px 0 0 20px;
li {
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
}
&.edit {
li {
align-items: center;
}
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
span {
min-width: 150px;
padding: 0 10px 3px;
border-bottom: 1px solid #e1e6f2;
}
/deep/.el-input {
width: 174px;
}
}
.score-wrap {
position: relative;
min-width: 150px;
border-bottom: 1px solid #e1e6f2;
em {
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
}
/deep/.el-textarea .el-textarea__inner,
.pre-wrap {
min-height: 72px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
}
}
/deep/ .table th {
background-color: #e5dfff !important;
.cell {
line-height: 35px;
color: #fff;
}
}
}
.result-pic {
margin: 10px 0;
}
@media (max-width: 1650px) {
.wrap {
padding: 12px 200px 20px;
}
}
@media (max-width: 1430px) {
.wrap {
padding: 12px 100px 20px;
}
}
</style>

@ -17,9 +17,22 @@
</li> </li>
</ul> </ul>
<div> <div>
<el-button v-show="loaded && info.completeCompetitionSetup.competitionType" type="primary" round <template v-if="loaded && info.completeCompetitionSetup.competitionType">
:disabled="hasReport" :loading="allocating" @click="autoAllocationConfirm">{{ !notBeginSign && allocated ? <el-button type="primary" round :disabled="hasReport" :loading="allocating" @click="autoAllocationConfirm">{{
!notBeginSign && allocated ?
'取消' : '' }}自动分配阶段成员</el-button> '取消' : '' }}自动分配阶段成员</el-button>
<el-tooltip placement="top">
<div slot="content">
<p>报名结束前设置的自动分配将在报名结束时触发一次系统自动分配取消则不触发</p>
<p style="margin: 5px 0;">报名结束后也可以手动点击自动分配按钮来立即触发系统自动分配并且点击一次就触发一次</p>
<p></p>
<p style="margin: 5px 0;">&emsp;&emsp;1. 自动分配仅对触发时已报名的人员进行对于分配后才报名的人员如需自动分配则需手动再次触发自动分配</p>
<p>&emsp;&emsp;2. 若已有学生提交了成绩报告则无法启用自动分配功能</p>
</div>
<i class="el-icon-question"
style="margin: 0 10px 0 5px;font-size: 16px;color: #8f8f8f;cursor: pointer;"></i>
</el-tooltip>
</template>
<el-button type="primary" round @click="batchImport">导入</el-button> <el-button type="primary" round @click="batchImport">导入</el-button>
<el-button type="primary" round @click="add" v-auth="'/match:管理:报名人员:新增'">新增</el-button> <el-button type="primary" round @click="add" v-auth="'/match:管理:报名人员:新增'">新增</el-button>
<el-button type="primary" round :loading="exporting" @click="exportAll" <el-button type="primary" round :loading="exporting" @click="exportAll"
@ -69,11 +82,13 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="270"> <el-table-column label="操作" align="center" width="270">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="!scope.row.isDel">
<el-button v-auth="'/match:管理:报名人员:编辑'" type="text" @click="edit(scope.row)">编辑</el-button> <el-button v-auth="'/match:管理:报名人员:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button> <el-button type="text" @click="del(scope.row)">删除</el-button>
</template>
<template v-if="info.releaseType"> <template v-if="info.releaseType">
<el-button v-auth="'/match:管理:报名人员:参赛信息与成绩'" type="text" @click="toInfo(scope.row)">参赛信息与成绩</el-button> <el-button v-auth="'/match:管理:报名人员:参赛信息与成绩'" type="text" @click="toInfo(scope.row)">参赛信息与成绩</el-button>
<el-switch v-auth="'/match:管理:报名人员:禁用'" v-model="scope.row.isDisable" <el-switch v-if="!scope.row.isDel" v-auth="'/match:管理:报名人员:禁用'" v-model="scope.row.isDisable"
:active-text="scope.row.isDisable ? '禁用' : '启用'" :active-value="0" :inactive-value="1" :active-text="scope.row.isDisable ? '禁用' : '启用'" :active-value="0" :inactive-value="1"
style="margin: 0 10px 0 5px" @change="switchOff($event, scope.row, scope.$index)"></el-switch> style="margin: 0 10px 0 5px" @change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template> </template>

@ -0,0 +1,675 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20 head-card">
<div class="flex-between m-b-20">
<el-page-header @back="back" content="成绩管理"></el-page-header>
</div>
</el-card>
<div v-loading="loading">
<el-card v-if="method != 2" shadow="hover" class="m-b-20">
<div class="stat">
<div class="nums">
<div class="item">
<p class="name">已参加/应参加人数</p>
<p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}
</p>
</div>
<div class="item">
<p class="name">实验平均分</p>
<p class="val">{{ avgScore }}</p>
</div>
</div>
<div class="chart" id="chart"></div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div v-if="showFile" class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i === active }" @click="tabChange(i)">{{
item }}</a>
</div>
<div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable
style="width: 300px"></el-input>
</li>
</ul>
<div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@click="delAllData">批量删除</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出'
}}</el-button>
</div>
<div v-else>
<el-button type="primary" :loading="exporting1" @click="exportData1">{{ exporting1 ? '正在导出' : '批量导出'
}}</el-button>
</div>
</div>
<template v-if="!active">
<el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="score" label="分数" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.submitTime ? scope.row.score : '--' }}
</template>
</el-table-column>
<el-table-column prop="timeSum" label="耗时" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }}
</template>
</el-table-column>
<el-table-column prop="submitTime" label="提交时间" min-width="150" align="center">
<template slot-scope="scope">
{{ scope.row.submitTime || '--' }}
</template>
</el-table-column>
<el-table-column label="状态" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<el-button v-if="method != 2 && scope.row.reportId" type="text"
@click="show(scope.row)">查看成绩报告</el-button>
<el-button v-if="scope.row.reportId" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</template>
<template v-else>
<el-table :data="list1" class="table" :key="2" stripe header-align="center"
@selection-change="handleSelectionChange1" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="provinceName" label="省份" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="fileName" label="文件名" align="center"></el-table-column>
<el-table-column prop="fileSize" label="文件大小" align="center"></el-table-column>
<el-table-column prop="fileType" label="文件类型" align="center"></el-table-column>
<el-table-column prop="fileFormat" label="文件格式" align="center"></el-table-column>
<el-table-column prop="createTime" label="提交时间" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)" type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary" size="mini" :loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total1"
@current-change="handleCurrentChange1" :current-page="page1">
</el-pagination>
</div>
</template>
</el-card>
</div>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
@close="cancelUpload">
<div style="text-align: center">
<template v-if="!uploadFaild">
<div style="margin-bottom: 10px;">
<el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div>
<el-upload ref="upload" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload"
:on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove"
:limit="1" :on-exceed="handleExceed" :action="this.api.batchImportGrades" :file-list="uploadList"
:headers="headers" :disabled="uploading" :data="{
competitionId: this.id,
stageId: this.stageId,
systemId: 0
}">
<el-button type="primary" :loading="uploading" class="ml20">上传文件<i
class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload>
</template>
<template v-else>
<p style="margin: -10px 0 13px;font-size: 14px;color: #e90000;">{{ faildData.tip }}</p>
<p type="primary"
style="margin-bottom: 10px;font-size: 14px;color: #9076FF;text-decoration: underline;cursor: pointer;"
@click="showFaild">部分数据导入失败查看失败原因</p>
</template>
</div>
<span v-if="uploading" slot="footer" class="dialog-footer">
<el-button @click="cancelUpload">停止导入</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import util from "@/libs/util";
import * as echarts from "echarts";
import axios from 'axios';
import Zip from '@/libs/zip'
export default {
data () {
return {
id: +this.$route.query.id,
stageId: +this.$route.query.stageId,
method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true',
isCompress: util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '',
searchTimer: null,
list: [],
multipleSelection: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
list1: [],
multipleSelection1: [],
page1: 1,
total1: 0,
avgScore: 0, //
importVisible: false,
uploadList: [],
uploadFaild: false,
uploading: false,
faildData: null,
headers: {
token: sessionStorage.getItem("token")
},
statData: {},
tabs: ['成绩列表', '文件列表'],
active: 0,
loading: false,
exporting: false,
exporting1: false,
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.$router.push({
path: '/otherArchList',
query: {
...this.$route.query,
keyword: val
}
})
this.initData();
}, 500);
}
},
mounted () {
this.getData()
this.getProvince()
this.getSchool()
},
methods: {
async getData () {
this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
...this.filter
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page,
pageSize: this.pageSize,
competitionId: this.id,
keyWord: this.keyword,
stageId: this.stageId,
isNakadai: 1,
...this.filter
})
this.loading = false
this.total = page.total
this.list = page.records
this.statData = data
this.avgScore = (+data.avgScore).toFixed(2)
this.method != 2 && this.getChart()
}
},
initData () {
this.page = 1
this.getData()
},
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
show (row) {
this.$router.push(`/trialReport?reportId=${row.reportId}`)
},
// ()
async exportData () {
if (this.list.length) {
this.exporting = true
//
if (this.multipleSelection.length) {
const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, {
headers: this.headers,
responseType: 'blob'
})
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false
} else if (this.list.length) {
const res = await axios.post(this.api.allExperimentalResultsAreDerived, {
pageNum: 1,
pageSize: 10000,
competitionId: this.id,
isNakadai: 1,
stageId: this.stageId,
}, {
headers: this.headers,
responseType: 'blob'
})
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false
}
}
},
// ()
exportData1 () {
this.exporting1 = true
let list = this.list1
if (this.multipleSelection1.length) {
list = this.multipleSelection1
}
Zip('批量导出', list, () => {
this.exporting1 = false
})
},
handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id,
stageId: this.stageId
}).then(res => {
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
}).catch(() => { });
},
delAllData () { //
const list = this.multipleSelection
this.$confirm(list.length ? '该项目下的所有成绩报告将会删除,是否继续?' : '是否确定删除列表所有成绩数据?', "提示", {
type: "warning"
}).then(async () => {
let ids = []
if (list.length) {
ids = list.map(item => {
return this.method == 2 ? item.scoreId : item.reportId
});
ids = ids.filter(e => e)
}
const data = {
competitionId: this.id,
stageId: this.stageId
}
if (list.length) data.ids = ids
await this.$post(this.api.batchDeleteContestGrade, data)
this.multipleSelection = [];
this.$refs.table.clearSelection();
util.successMsg("删除成功");
this.getData();
}).catch(() => { });
},
handleSelectionChange (val) { //
this.multipleSelection = val;
},
handleCurrentChange (val) { //
this.$router.push({
path: '/otherArchList',
query: {
...this.$route.query,
page: val
}
})
this.page = val;
this.getData();
},
handleSelectionChange1 (val) { //
this.multipleSelection1 = val;
},
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线
const data = []
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
title: { text: "实验分数分布图" },
tooltip: {},
xAxis: {
name: "分数",
type: "category",
boundaryGap: false,
interval: 10,
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"]
},
yAxis: {
name: "人数",
type: "value",
minInterval: 10
},
series: [{
data,
type: "line",
areaStyle: {},
label: {
show: true,
position: 'top'
},
color: ["#8191fd"]
}]
});
},
//
batchImport () {
this.importVisible = true
this.uploadList = []
this.uploadFaild = false
},
//
download () {
axios.get(`${this.api.gradeDownloadExcel}?competitionId=${this.id}&stageId=${this.stageId}`, {
headers: this.headers,
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data]))
}).catch(res => { })
},
//
handleExceed (files, fileList) {
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
)
},
//
showFaild () {
axios.get(`${this.api.performanceExportFailure}?exportCode=${this.faildData.exportCode}&competitionType=${this.faildData.competitionType}`, {
headers: this.headers,
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data]))
}).catch(res => { })
},
uploadSuccess (res) {
this.uploading = false
this.uploadFaild = false
if (res.status === 200) {
this.initData()
const { data } = res
if (data.exportCode) {
this.faildData = data
this.uploadFaild = true
} else {
util.successMsg(data.tip, 3000)
this.importVisible = false
}
} else {
util.errorMsg(res.message || '上传失败,请检查数据')
}
},
uploadError (err, file, fileList) {
this.uploading = false
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
})
},
beforeUpload (file) {
this.uploading = true
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`)
},
handleRemove (file, fileList) {
this.uploadList = fileList
this.uploadFaild = false
},
cancelUpload () {
this.uploading = false
if (this.$refs.upload) this.$refs.upload.abort()
this.keyword = ''
this.initData()
this.importVisible = false
},
// tab
tabChange (i) {
this.active = i
this.getData()
},
//
preview (item) {
window.open((util.isDoc(item.fileFormat) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath)
},
//
exportFile (item) {
item.loading = true
const url = item.filePath
var x = new XMLHttpRequest()
x.open("GET", url, true)
x.responseType = "blob"
x.onload = function (e) {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement("a")
a.href = url
a.download = item.userName + '-' + item.fileName
a.click()
item.loading = false
}
x.send()
},
back () {
this.$router.push(this.$store.state.innerReferrer)
}
}
};
</script>
<style lang="scss" scoped>
/deep/ .head-card {
.el-card__body {
padding-bottom: 0px;
.el-tabs__header {
margin-bottom: 1px;
.el-tabs__nav-wrap::after {
display: none;
}
.el-tabs__item {
font-size: 18px;
}
}
}
}
.stat {
display: flex;
.nums {
display: flex;
align-items: center;
margin-right: 20px;
.item:nth-child(1) {
background-image: url('../../../assets/img/total.png');
}
.item:nth-child(2) {
background-image: url('../../../assets/img/avg.png');
}
.item {
width: 300px;
min-height: 145px;
padding: 30px 30px;
margin: 0 10px;
box-sizing: border-box;
border-radius: 8px;
background-size: 100% 100%;
background-repeat: no-repeat;
p {
font-size: 18px;
color: #ffffff;
}
.val {
margin-top: 10px;
color: #ffffff;
font-size: 36px;
}
}
}
.chart {
flex: 1;
height: 300px;
}
}
/deep/.import-file {
.el-progress__text,
.el-progress,
.el-upload-list__item-status-label {
display: none !important;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,413 @@
<template>
<div class="wrap">
<el-card shadow="hover" class="m-b-20">
<el-page-header @back="$router.back()" content="查看报告"></el-page-header>
</el-card>
<div class="content" v-loading="loading">
<div class="text-right">
<el-button type="primary" @click="exportPage">导出报告</el-button>
</div>
<h6 class="r-title">标准实验报告</h6>
<div class="info">
<h6 class="l-title">
<img src="@/assets/img/info1.png" alt="">
基本信息
</h6>
<ul :class="['info-list', { edit: editing }]">
<li>
<label>学生姓名</label>
<el-input v-if="editing" v-model="infoData.userName" disabled></el-input>
<span v-else>{{ infoData.userName }}</span>
</li>
<li>
<label>学生学号</label>
<el-input v-if="editing" v-model="infoData.workNumber" disabled></el-input>
<span v-else>{{ infoData.workNumber }}</span>
</li>
<li>
<label>实验时间</label>
<el-input v-if="editing" v-model="infoData.submitTime" disabled></el-input>
<span v-else>{{ infoData.submitTime }}</span>
</li>
<li>
<label>实验成绩</label>
<el-input v-if="editing" v-model="infoData.score" disabled></el-input>
<div v-else class="score-wrap">
<em>{{ infoData.score }}</em>
<img src="@/assets/img/point.png" alt="">
</div>
</li>
<li>
<label>学生班级</label>
<el-input v-if="editing" v-model="infoData.className"></el-input>
<span v-else>{{ infoData.className }}</span>
</li>
<li>
<label>指导老师</label>
<el-input v-if="editing" v-model="infoData.instructor"></el-input>
<span v-else>{{ infoData.instructor }}</span>
</li>
<li>
<label>实验学时</label>
<el-input v-if="editing" v-model="infoData.period"></el-input>
<span v-else>{{ infoData.period }}</span>
</li>
</ul>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report2.png" alt="">
实验项目名称
</h6>
<el-input v-if="editing" v-model="form.projectName" type="textarea"></el-input>
<div v-else class="pre-wrap" v-html="form.projectName"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report3.png" alt="">
实验目的
</h6>
<div :class="['pre-wrap', { edit: editing }]" v-html="form.purpose"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report4.png" alt="">
实验数据
</h6>
<el-table :data="expData" class="table" border stripe header-align="center">
<el-table-column type="index" label="序号" align="center" width="60">
<template slot-scope="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="judgmentName" label="判分点" width="270" align="center"></el-table-column>
<el-table-column v-if='project' prop="judgmentName" label="考核点" align="center" width="150">
<template slot-scope="scope">
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span>
<span>{{ index + 1 }}. </span>{{ item.name }}
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="ruleAnswer" label="参考答案" style='word-wrap: break-word'>
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span>
<span>{{ index + 1 }}. </span>{{ item.ruleAnswer }}
</span>
</div>
</div>
<div v-else v-html="scope.row.referenceAnswer"></div>
</template>
</el-table-column>
<el-table-column prop="userAnswer" label="学生答案">
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span v-if='item.userAnswer'>
<span>{{ index + 1 }}. </span>{{ item.userAnswer }}
</span>
<span v-else>
<span>{{ index + 1 }}. </span>未填写
</span>
</div>
</div>
<div v-else class="pre-code">{{ scope.row.answer }}</div>
<template v-if="scope.row.runThePictureList">
<img v-for="(img, i) in scope.row.runThePictureList" :key="i" width="200" class="result-pic"
:src="img" alt="">
</template>
</template>
</el-table-column>
<el-table-column prop="quesScore" label="分值" :key="6" width="80" align="center"></el-table-column>
<el-table-column prop="score" label="得分" width="80" align="center"></el-table-column>
</el-table>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report5.png" alt="">
实验总结与体会
</h6>
<quill v-if="editing" :border="true" v-model="form.summarize" :minHeight="150" :height="150" />
<div v-else class="pre-wrap" v-html="form.summarize"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import util from "@/libs/util";
export default {
data () {
return {
reportId: this.$route.query.reportId,
title: "实验报告",
form: {
className: "",
instructor: "",
period: "",
projectName: "",
summarize: "",
},
infoData: {},
expData: [],
editing: false,
loadIns: null,
loading: false,
project: false,
userScores: []
};
},
mounted () {
this.getData()
},
methods: {
getData () { //
this.loading = true
this.$get(`${this.api.reportDetail}?reportId=${this.reportId}`).then(({ report, userScores }) => {
this.form = report
this.project = this.expData.find(e => e.lcRuleRecords) // lcRuleRecords
let form = this.form;
this.infoData = {
workNumber: form.workNumber,
experimentalClassName: form.experimentalClassName,
instructor: form.instructor,
period: form.period,
laboratory: form.laboratory,
submitTime: form.submitTime,
score: form.score,
className: form.className,
userName: form.userName
}
const { data } = report
// data使
if (!data) {
this.userScores = userScores
this.handleList(userScores)
this.$post(this.api.editExperimentalData, {
reportId,
data: JSON.stringify(userScores)
}).then(res => { }).catch(err => { })
} else {
this.handleList(JSON.parse(data))
}
}).catch(res => {
this.loading = false
})
},
//
handleList (list) {
this.project = list.find(e => e.lcRuleRecords) // lcRuleRecords
if (this.project) {
list.map(e => {
e.assessmentPoint = ''
e.referenceAnswer = ''
e.answer = ''
e.lcRuleRecords && e.lcRuleRecords.map((n, i) => {
e.assessmentPoint += `${i + 1}.${n.name}`
e.referenceAnswer += `${i + 1}.${n.ruleAnswer}`
e.answer += `${i + 1}.${n.userAnswer}`
})
})
} else { // pythonuserScores
list.forEach(e => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
})
}
this.expData = list
this.loading = false
},
exportPage () {
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
list.map((e, i) => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePicture) e.runThePicture = item.runThePicture
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
e.id = i + 1
// if (e.referenceAnswer && typeof e.referenceAnswer === 'string') e.referenceAnswer = e.referenceAnswer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in form) {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.project ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
}).catch(res => { })
},
}
};
</script>
<style lang="scss" scoped>
.wrap {
padding: 12px 300px 20px;
}
.pre-code {
white-space: pre-wrap;
}
.text-right {
text-align: right;
}
code,
kbd,
samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
word-wrap: break-word;
white-space: pre-wrap;
}
/deep/ pre {
white-space: pre-wrap;
/* css-3 */
white-space: -moz-pre-wrap;
/* Mozilla, since 1999 */
white-space: pre-wrap;
/* Opera 4-6 */
white-space: -o-pre-wrap;
/* Opera 7 */
word-wrap: break-word;
/* Internet Explorer 5.5+ */
word-break: break-all;
overflow: hidden;
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
}
.content {
padding: 16px 40px;
background: #fff;
.r-title {
margin-bottom: 40px;
font-size: 24px;
text-align: center;
color: #333;
}
.info {
padding: 20px 16px;
border: 1px solid #e1e6f2;
}
.l-title {
display: flex;
align-items: center;
padding: 5px 8px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
}
.info-list {
display: flex;
flex-wrap: wrap;
padding: 10px 0 0 20px;
li {
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
}
&.edit {
li {
align-items: center;
}
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
span {
min-width: 150px;
padding: 0 10px 3px;
border-bottom: 1px solid #e1e6f2;
}
/deep/.el-input {
width: 174px;
}
}
.score-wrap {
position: relative;
min-width: 150px;
border-bottom: 1px solid #e1e6f2;
em {
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
}
/deep/.el-textarea .el-textarea__inner,
.pre-wrap {
min-height: 72px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
}
}
/deep/ .table th {
background-color: #e5dfff !important;
.cell {
line-height: 35px;
color: #fff;
}
}
}
.result-pic {
margin: 10px 0;
}
@media (max-width: 1650px) {
.wrap {
padding: 12px 200px 20px;
}
}
@media (max-width: 1430px) {
.wrap {
padding: 12px 100px 20px;
}
}
</style>

@ -1906,7 +1906,8 @@ export default {
}, },
// orderRepeatid // orderRepeatid
handleOrderRepeat (id) { handleOrderRepeat (id) {
this.orderRepeat.includes(id) && this.orderRepeat.splice(this.orderRepeat.findIndex(e => e == id), 1) const i = this.orderRepeat.findIndex(e => e == id)
i !== -1 && this.orderRepeat.splice(i, 1)
}, },
/* 处理0开头的期限 */ /* 处理0开头的期限 */
zero (e, row) { zero (e, row) {
@ -1935,6 +1936,12 @@ export default {
this.getSettlemennt() this.getSettlemennt()
}); });
this.$forceUpdate(); this.$forceUpdate();
//
this.productProps.map(e => {
this[e.name].map(n => {
this.deadLine(n.periodOfUse, n, n.options, 1)
})
})
} }
}, },
// //
@ -1965,7 +1972,7 @@ export default {
// if (this.renewDisabled && this.coursePermissions.length === 1) { // if (this.renewDisabled && this.coursePermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.coursePermissions.splice(index, 1); this.coursePermissions.splice(index, 1);
// } // }
}); });
@ -1978,7 +1985,7 @@ export default {
// if (this.renewDisabled && this.theoryCourseList.length === 1) { // if (this.renewDisabled && this.theoryCourseList.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.theoryCourseList.splice(index, 1); this.theoryCourseList.splice(index, 1);
// } // }
}); });
@ -1992,7 +1999,7 @@ export default {
// if (this.renewDisabled && this.dataPlatformPermissions.length === 1) { // if (this.renewDisabled && this.dataPlatformPermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.dataPlatformPermissions.splice(index, 1); this.dataPlatformPermissions.splice(index, 1);
// } // }
}); });
@ -2006,7 +2013,7 @@ export default {
// if (this.renewDisabled && this.valuePermissions.length === 1) { // if (this.renewDisabled && this.valuePermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.valuePermissions.splice(index, 1); this.valuePermissions.splice(index, 1);
// } // }
}); });
@ -2165,7 +2172,7 @@ export default {
// if (this.renewDisabled && this.practicalCourses.length === 1) { // if (this.renewDisabled && this.practicalCourses.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.practicalCourses.splice(index, 1); this.practicalCourses.splice(index, 1);
// } // }
}); });
@ -2179,7 +2186,7 @@ export default {
if (this.renewDisabled && this.expTools.length === 1) { if (this.renewDisabled && this.expTools.length === 1) {
return this.$message.warning("续费至少保留一条产品信息"); return this.$message.warning("续费至少保留一条产品信息");
} else { } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.expTools.splice(index, 1); this.expTools.splice(index, 1);
} }
}); });

@ -21,37 +21,20 @@
</div> </div>
<div style="height: 504px; max-height: 504px; overflow: auto"> <div style="height: 504px; max-height: 504px; overflow: auto">
<el-tree <el-tree :data="orgList" default-expand-all ref="orgTree" node-key="id" highlight-current
:data="orgList" :expand-on-click-node="false" @node-click="handleNodeClick"
default-expand-all :props="{ children: 'children', label: 'partnerClassificationName', isLeaf: 'leaf' }">
ref="orgTree"
node-key="id"
highlight-current
:expand-on-click-node="false"
@node-click="handleNodeClick"
:props="{children: 'children', label: 'partnerClassificationName', isLeaf: 'leaf'}"
>
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span class="org-name">{{ node.label }}</span> <span class="org-name">{{ node.label }}</span>
<span> <span>
<!-- isTeam 0: 分类1: 团队 --> <!-- isTeam 0: 分类1: 团队 -->
<el-button <el-button v-auth="'/parner:账号管理:添加分类'" v-if="!data.isTeam" type="text"
v-auth="'/parner:账号管理:添加分类'" icon="el-icon-circle-plus-outline" @click="() => addOrg(node, data)">
v-if="!data.isTeam"
type="text"
icon="el-icon-circle-plus-outline"
@click="() => addOrg(node, data)">
</el-button> </el-button>
<el-button <el-button v-auth="'/parner:账号管理:编辑分类'" type="text" icon="el-icon-edit-outline"
v-auth="'/parner:账号管理:编辑分类'"
type="text"
icon="el-icon-edit-outline"
@click="() => editOrg(node, data)"> @click="() => editOrg(node, data)">
</el-button> </el-button>
<el-button <el-button v-auth="'/parner:账号管理:删除分类'" type="text" icon="el-icon-delete"
v-auth="'/parner:账号管理:删除分类'"
type="text"
icon="el-icon-delete"
@click="() => delOrg(node, data)"> @click="() => delOrg(node, data)">
</el-button> </el-button>
</span> </span>
@ -60,27 +43,16 @@
</div> </div>
</div> </div>
<el-dialog <el-dialog :title="typeForm.id ? '编辑' : '新增' + '分类'" :visible.sync="orgVisible" :close-on-click-modal="false"
:title="typeForm.id ? '编辑' : '新增' + '分类'" width="50%" @close="closeType">
:visible.sync="orgVisible"
:close-on-click-modal="false"
width="50%"
@close="closeType"
>
<el-form v-if="orgVisible" ref="typeForm" :model="typeForm" :rules="orgRules" label-width="100px"> <el-form v-if="orgVisible" ref="typeForm" :model="typeForm" :rules="orgRules" label-width="100px">
<el-form-item label="分类名称" prop="partnerClassificationName"> <el-form-item label="分类名称" prop="partnerClassificationName">
<el-input v-model.trim="typeForm.partnerClassificationName" placeholder="请输入"></el-input> <el-input v-model.trim="typeForm.partnerClassificationName" placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="上级部门"> <el-form-item label="上级部门">
<span v-if="typeForm.parentName">{{ typeForm.parentName }}</span> <span v-if="typeForm.parentName">{{ typeForm.parentName }}</span>
<el-cascader <el-cascader v-else :options="orgListDia" v-model="cascaderValue" :props="cascaderProps" clearable
v-else style="width: 100%">
:options="orgListDia"
v-model="cascaderValue"
:props="cascaderProps"
clearable
style="width: 100%"
>
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -96,7 +68,8 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord" clearable></el-input> <el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord"
clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
@ -104,18 +77,21 @@
</div> </div>
</div> </div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> <el-table :data="listData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" align="center" min-width="100"></el-table-column> <el-table-column prop="userName" label="姓名" align="center" min-width="100"></el-table-column>
<el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column> <el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column>
<el-table-column prop="phone" label="手机号" align="center" min-width="120"></el-table-column> <el-table-column prop="phone" label="手机号" align="center" min-width="120"></el-table-column>
<el-table-column prop="invitationAccount" label="邀请人" align="center" min-width="120"></el-table-column> <el-table-column prop="invitationAccount" label="邀请人" align="center" min-width="120"></el-table-column>
<el-table-column prop="partnerClassificationName" label="团队名称" align="center" min-width="120" show-overflow-tooltip></el-table-column> <el-table-column prop="partnerClassificationName" label="团队名称" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<template v-if="!type"> <template v-if="!type">
<el-table-column prop="provinceName" label="省份" align="center" min-width="80"></el-table-column> <el-table-column prop="provinceName" label="省份" align="center" min-width="80"></el-table-column>
<el-table-column prop="cityName" label="城市" align="center" min-width="80"></el-table-column> <el-table-column prop="cityName" label="城市" align="center" min-width="80"></el-table-column>
<el-table-column prop="roleName" label="授权角色" align="center" min-width="120" show-overflow-tooltip></el-table-column> <el-table-column prop="roleName" label="授权角色" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<el-table-column prop="phone" label="费率" align="center" min-width="120"> <el-table-column prop="phone" label="费率" align="center" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="scope.row.annualTeamFee">团队年费{{ scope.row.annualTeamFee }}w</p> <p v-if="scope.row.annualTeamFee">团队年费{{ scope.row.annualTeamFee }}w</p>
@ -130,16 +106,20 @@
<el-button v-if="!type" type="text" v-auth="'/parner:账号管理:重置密码'" @click="edit(scope.row)">编辑</el-button> <el-button v-if="!type" type="text" v-auth="'/parner:账号管理:重置密码'" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" v-auth="'/parner:账号管理:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button> <el-button type="text" v-auth="'/parner:账号管理:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button v-if="type" type="text" v-auth="'/parner:账号管理:删除合伙人'" @click="del(scope.row)">删除</el-button> <el-button v-if="type" type="text" v-auth="'/parner:账号管理:删除合伙人'" @click="del(scope.row)">删除</el-button>
<el-button v-else-if="scope.row.isTeam == 1" type="text" v-auth="'/parner:账号管理:转让超管'" @click="transfer(scope.row)">转让超管</el-button> <el-button v-else-if="scope.row.isTeam == 1" type="text" v-auth="'/parner:账号管理:转让超管'"
<el-button v-if="scope.row.isTeam == 0" type="text" v-auth="'/parner:账号管理:移除'" @click="remove(scope.row)">移除</el-button> @click="transfer(scope.row)">转让超管</el-button>
<el-button v-if="scope.row.isTeam == 0" type="text" v-auth="'/parner:账号管理:移除'"
@click="remove(scope.row)">移除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination> <el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next"
:total="total"></el-pagination>
</div> </div>
<el-dialog title="添加城市合伙人" :visible.sync="parnerVisible" width="580px" custom-class="add-dia" :close-on-click-modal="false" @close="closeAdd"> <el-dialog title="添加城市合伙人" :visible.sync="parnerVisible" width="580px" custom-class="add-dia"
:close-on-click-modal="false" @close="closeAdd">
<p class="tips">链接/二维码失效时间{{ expireTime }}</p> <p class="tips">链接/二维码失效时间{{ expireTime }}</p>
<p class="title">城市合伙人 <em>邀请链接</em></p> <p class="title">城市合伙人 <em>邀请链接</em></p>
<p class="des">加盟商合作伙伴可以通过这个链接加入 <em>城市合伙人计划</em></p> <p class="des">加盟商合作伙伴可以通过这个链接加入 <em>城市合伙人计划</em></p>
@ -152,21 +132,24 @@
<img width="250" :src="qrcode" alt=""> <img width="250" :src="qrcode" alt="">
</el-dialog> </el-dialog>
<el-dialog title="转让管理员" :visible.sync="transferVisible" width="350px" custom-class="transfer-dia" :close-on-click-modal="false"> <el-dialog title="转让管理员" :visible.sync="transferVisible" width="350px" custom-class="transfer-dia"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<el-button type="primary" @click="showChoose">转给团队成员</el-button> <el-button type="primary" @click="showChoose">转给团队成员</el-button>
<el-button @click="add(1)">邀请外部人员</el-button> <el-button @click="add(1)">邀请外部人员</el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog title="请选择要转让的团队成员" :visible.sync="chooseVisible" width="300px" custom-class="choose-dia" :close-on-click-modal="false"> <el-dialog title="请选择要转让的团队成员" :visible.sync="chooseVisible" width="300px" custom-class="choose-dia"
:close-on-click-modal="false">
<ul class="member-list"> <ul class="member-list">
<li v-for="(item, i) in members" :key="i"> <li v-for="(item, i) in members" :key="i">
<div class="info"> <div class="info">
<img src="@/assets/img/avatar.png" alt=""> <img src="@/assets/img/avatar.png" alt="">
<span class="name">{{ item.userName }}</span> <span class="name">{{ item.userName }}</span>
</div> </div>
<el-radio v-model="choosePartnerId" :label="item.partnerId" :disabled="curRow.accountId === item.accountId"></el-radio> <el-radio v-model="choosePartnerId" :label="item.partnerId"
:disabled="curRow.accountId === item.accountId"></el-radio>
</li> </li>
</ul> </ul>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -184,22 +167,22 @@
<el-select class="w-100" v-model="form.roleList" multiple> <el-select class="w-100" v-model="form.roleList" multiple>
<template v-for="item in roleList"> <template v-for="item in roleList">
<!-- 不显示超管 --> <!-- 不显示超管 -->
<el-option <el-option :key="item.id" :label="item.roleName" :value="item.id">
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option> </el-option>
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="provinceId" label="省份"> <el-form-item prop="provinceId" label="省份">
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择省份" @change="getCity"> <el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择省份" @change="getCity">
<el-option v-for="(item,index) in provinces" :key="index" :label="item.provinceName" :value="item.provinceId"></el-option> <el-option v-for="(item, index) in provinces" :key="index" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="cityId" label="城市"> <el-form-item prop="cityId" label="城市">
<el-select style="width: 100%" v-model="form.cityId" placeholder="请选择城市" :disabled="form.provinceId ? false : true"> <el-select style="width: 100%" v-model="form.cityId" placeholder="请选择城市"
<el-option v-for="(item,index) in cities" :key="index" :label="item.cityName" :value="item.cityId"></el-option> :disabled="form.provinceId ? false : true">
<el-option v-for="(item, index) in cities" :key="index" :label="item.cityName"
:value="item.cityId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -665,47 +648,58 @@ export default {
.m-b-20 { .m-b-20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.org-name { .org-name {
margin-right: 20px; margin-right: 20px;
} }
.w-100 { .w-100 {
width: 100%; width: 100%;
} }
.wrap { .wrap {
display: flex; display: flex;
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 324px); width: calc(100% - 324px);
padding: 24px 0; padding: 24px 0;
} }
} }
.add-dia { .add-dia {
.tips { .tips {
font-size: 12px; font-size: 12px;
color: #f00; color: #f00;
} }
.title { .title {
margin: 10px 0; margin: 10px 0;
font-size: 14px; font-size: 14px;
em { em {
font-style: normal; font-style: normal;
} }
} }
.des { .des {
font-size: 13px; font-size: 13px;
color: #7a7a7a; color: #7a7a7a;
} }
.link-wrap { .link-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 10px 0 20px; margin: 10px 0 20px;
} }
.link { .link {
padding: 10px; padding: 10px;
margin-right: 15px; margin-right: 15px;
@ -713,6 +707,7 @@ export default {
border-radius: 4px; border-radius: 4px;
} }
} }
/deep/.choose-dia { /deep/.choose-dia {
.member-list { .member-list {
li { li {
@ -721,17 +716,21 @@ export default {
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
} }
.info { .info {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
img { img {
width: 40px; width: 40px;
height: 40px; height: 40px;
} }
.name { .name {
margin-left: 10px; margin-left: 10px;
} }
.el-radio__label { .el-radio__label {
display: none; display: none;
} }

@ -0,0 +1,50 @@
<template>
<div>
<iframe :src="url" frameborder="0" width="100%"></iframe>
</div>
</template>
<script>
import Setting from '@/setting'
export default {
data () {
return {
url: ''
};
},
mounted () {
const token = sessionStorage.getItem('token')
const cache = localStorage.getItem('reviewPath') // localStorage
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
if (cache) {
url += '#' + this.replaceParam(cache, Date.now())
} else {
url += `#/myReview?nakadai=1${Setting.isDev ? `&token=${token}` : ''}&v=${Date.now()}`
}
console.log("🚀 ~ mounted ~ url:", url)
localStorage.setItem('review_token', token)
this.url = url
},
methods: {
replaceParam (url, newVValue) {
const vParamRegex = /v=[^&]+/g
let newUrl = url.replace(vParamRegex, `v=${newVValue}`)
const [baseUrl, hash] = newUrl.split('#');
if (hash) {
newUrl = `${baseUrl}#${hash.replace(vParamRegex, `v=${newVValue}`)}`
}
return newUrl
}
}
};
</script>
<style lang="scss" scoped>
iframe {
height: calc(100vh - 167px);
}
</style>

@ -161,7 +161,7 @@ export default {
// //
toBackstage (row) { toBackstage (row) {
this.setReferrer() this.setReferrer()
if (row.systemId == 19) { if (row.systemId == 19 || row.systemId == 30) {
location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}` location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}`
} else { } else {
this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`) this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`)

@ -1,28 +1,20 @@
<template> <template>
<div ref="main" <div ref="main" class="main" v-loading="loading">
class="main"
v-loading="loading">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" content="项目配置"></el-page-header>
content="项目配置"></el-page-header>
<div v-if="!isDetail"> <div v-if="!isDetail">
<el-button type="success" <el-button type="success" :loading="submiting === 0"
:loading="submiting === 0"
@click="handleSubmit(0, projectManage.isOpen = 1, projectManage.ztOpen = 1)">保存为草稿 @click="handleSubmit(0, projectManage.isOpen = 1, projectManage.ztOpen = 1)">保存为草稿
</el-button> </el-button>
<el-button type="primary" <el-button type="primary" :loading="submiting === 1" @click="handleSubmit(1)">确定并发布</el-button>
:loading="submiting === 1"
@click="handleSubmit(1)">确定并发布</el-button>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>课程信息</span> <span>课程信息</span>
@ -33,26 +25,18 @@
<el-form label-width="80px"> <el-form label-width="80px">
<div style="display: flex"> <div style="display: flex">
<el-form-item label="项目名称"> <el-form-item label="项目名称">
<el-input :disabled="isDetail" <el-input :disabled="isDetail" v-model.trim="projectManage.projectName" placeholder="20个字符以内"
v-model.trim="projectManage.projectName"
placeholder="20个字符以内"
@blur="projectNameExistis"></el-input> @blur="projectNameExistis"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model.trim="projectManage.remark" <el-input v-model.trim="projectManage.remark" placeholder="20个字符以内"></el-input>
placeholder="20个字符以内"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目用途"> <el-form-item label="项目用途">
<el-select :disabled="isDetail" <el-select :disabled="isDetail" v-model="projectManage.permissions" placeholder="请选择"
v-model="projectManage.permissions"
placeholder="请选择"
@change="permissionChange"> @change="permissionChange">
<el-option label="练习" <el-option label="练习" :value="0"></el-option>
:value="0"></el-option> <el-option label="考核" :value="1"></el-option>
<el-option label="考核" <el-option label="竞赛" :value="2"></el-option>
:value="1"></el-option>
<el-option label="竞赛"
:value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
@ -60,8 +44,7 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>实验目标</span> <span>实验目标</span>
@ -70,20 +53,14 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentTarget"
:readonly="isDetail" :type.sync="projectManage.experimentTargetType" radio :minHeight="150" :height="150" />
v-model="projectManage.experimentTarget"
:type.sync="projectManage.experimentTargetType"
radio
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>项目背景</span> <span>项目背景</span>
@ -92,30 +69,22 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentDescription"
:readonly="isDetail" :type.sync="projectManage.experimentDescriptionType" radio :minHeight="150" :height="150"
v-model="projectManage.experimentDescription"
:type.sync="projectManage.experimentDescriptionType"
radio
:minHeight="150"
:height="150"
:index="1" /> :index="1" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between mgb20"> <div class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>实验任务</span> <span>实验任务</span>
</div> </div>
<div> <div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" @click="toJudgePoint('home')">进入判分点
type="primary"
@click="toJudgePoint('home')">进入判分点
</el-button> </el-button>
</div> </div>
</div> </div>
@ -123,120 +92,67 @@
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center"> <div class="flex-center">
<div class="m-r-20" <div class="m-r-20" style="color: #f00">项目总分值100</div>
style="color: #f00">项目总分值100</div>
<!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> --> <!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> -->
</div> </div>
<div> <div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" class="m-r-20" type="text" @click="avgDistributionScore">
class="m-r-20"
type="text"
@click="avgDistributionScore">
平均分配分值 平均分配分值
</el-button> </el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" class="m-r-20" type="text" @click="manualDistributionScore">
class="m-r-20"
type="text"
@click="manualDistributionScore">
手动分配分值 手动分配分值
</el-button> </el-button>
<span>(待分配分值: {{ handDistributionScore }}/100)</span> <span>(待分配分值: {{ handDistributionScore }}/100)</span>
</div> </div>
</div> </div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" icon="el-icon-plus" round @click="handleAddJudgment"
type="primary"
icon="el-icon-plus"
round
@click="handleAddJudgment"
style="margin-bottom: 10px">判分点 style="margin-bottom: 10px">判分点
</el-button> </el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" icon="el-icon-delete" round @click="batchDeleteProjectJudgment"
type="primary"
icon="el-icon-delete"
round
@click="batchDeleteProjectJudgment"
style="margin-bottom: 10px">批量删除 style="margin-bottom: 10px">批量删除
</el-button> </el-button>
<div class="draggable"> <div class="draggable">
<u-table ref="projectJudgementTable" <el-table ref="projectJudgementTable" :data="projectJudgmentData" class="table" stripe header-align="center"
:data="projectJudgmentData" :use-virtual="isLc" :max-height="600" :row-height="60" :border="false"
class="table" @selection-change="handleSelectionProjectJudgment" row-key="judgmentId" v-loading="listLoading">
stripe <el-table-column type="selection" width="55" align="center"></el-table-column>
header-align="center" <el-table-column prop="sort" label="序号" width="80" align="center">
:use-virtual="isLc"
:max-height="600"
:row-height="60"
:border="false"
@selection-change="handleSelectionProjectJudgment"
row-key="judgmentId"
v-loading="listLoading">
<u-table-column type="selection"
width="55"
align="center"></u-table-column>
<u-table-column prop="sort"
label="序号"
width="80"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.sort }} {{ scope.row.sort }}
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="name" <el-table-column prop="name" label="判分指标" align="center" show-overflow-tooltip
label="判分指标" min-width="140"></el-table-column>
align="center" <el-table-column prop="name" label="判分点名称" align="center" show-overflow-tooltip
show-overflow-tooltip min-width="140"></el-table-column>
min-width="140"></u-table-column> <el-table-column label="实验要求" align="center" width="600">
<u-table-column prop="name"
label="判分点名称"
align="center"
show-overflow-tooltip
min-width="140"></u-table-column>
<u-table-column label="实验要求"
align="center"
width="600">
<template slot-scope="scope"> <template slot-scope="scope">
<quill :readonly="true" <quill :readonly="true" elseRead="true" v-model="scope.row.experimentalRequirements" :index="2" />
elseRead="true"
v-model="scope.row.experimentalRequirements"
:index="2" />
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="score" <el-table-column prop="score" label="分数" align="center" width="120">
label="分数"
align="center"
width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input :disabled="isDetail" <el-input :disabled="isDetail" :key="scope.$index" type="number" step="0.1"
:key="scope.$index"
type="number"
step="0.1"
v-model.trim="scope.row.score"></el-input> v-model.trim="scope.row.score"></el-input>
<!-- <!--
@input="scoreChange(scope.row, scope.$index)" --> @input="scoreChange(scope.row, scope.$index)" -->
</template> </template>
</u-table-column> </el-table-column>
<u-table-column label="操作" <el-table-column label="操作" width="140" align="center">
width="140"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="text" style="margin-right: 10px"
type="text"
style="margin-right: 10px"
@click="toJudgePoint('edit', scope.row)">自定义</el-button> @click="toJudgePoint('edit', scope.row)">自定义</el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="text" @click="delJudgePoint(scope.$index)">
type="text"
@click="delJudgePoint(scope.$index)">
删除 删除
</el-button> </el-button>
</template> </template>
</u-table-column> </el-table-column>
</u-table> </el-table>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between mgb20"> <div class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -244,25 +160,16 @@
</div> </div>
<div> <div>
启用 启用
<el-switch :disabled="isDetail" <el-switch :disabled="isDetail" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
v-model="projectManage.hintOpen"></el-switch> v-model="projectManage.hintOpen"></el-switch>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item prop="tips" <el-form-item prop="tips" label="">
label=""> <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentHint"
<quill :border="true" :type.sync="projectManage.experimentHintType" radio :minHeight="150" :height="400" :index="3" />
:readonly="isDetail"
v-model="projectManage.experimentHint"
:type.sync="projectManage.experimentHintType"
radio
:minHeight="150"
:height="400"
:index="3" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -271,62 +178,34 @@
</el-row> </el-row>
<!--选择判分点对话框--> <!--选择判分点对话框-->
<el-dialog title="添加判分点" <el-dialog title="添加判分点" :visible.sync="dialogVisible" width="40%" :close-on-click-modal="false"
:visible.sync="dialogVisible"
width="40%"
:close-on-click-modal="false"
@close="closeJudgment"> @close="closeJudgment">
<div class="text-right mgb10"> <div class="text-right mgb10">
<div> <div>
<el-input placeholder="请输入需要查找的判分点" <el-input placeholder="请输入需要查找的判分点" prefix-icon="el-icon-search" v-model.trim="judgementpointsquery"
prefix-icon="el-icon-search"
v-model.trim="judgementpointsquery"
clearable></el-input> clearable></el-input>
</div> </div>
</div> </div>
<u-table v-loading="visibleLoading" <el-table v-loading="visibleLoading" :data="judgementData" ref="judgementTable" class="table" stripe
:data="judgementData" header-align="center" use-virtual :row-height="45" :max-height="400" :border="false"
ref="judgementTable" @selection-change="handleSelectionJudgment" :row-key="rowKey">
class="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column prop="id" label="序号" align="center" width="100">
header-align="center"
use-virtual
:row-height="45"
:max-height="400"
:border="false"
@selection-change="handleSelectionJudgment"
:row-key="rowKey">
<u-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></u-table-column>
<u-table-column prop="id"
label="序号"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="name" <el-table-column prop="name" label="判分点名称" align="center"></el-table-column>
label="判分点名称" <el-table-column label="操作" align="center" width="100">
align="center"></u-table-column>
<u-table-column label="操作"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" <el-button size="mini" @click="toJudgePoint('view', scope.row)">查看</el-button>
@click="toJudgePoint('view', scope.row)">查看</el-button>
</template> </template>
</u-table-column> </el-table-column>
</u-table> </el-table>
<div slot="footer" <div slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="closeJudgment"> </el-button> <el-button @click="closeJudgment"> </el-button>
<el-button type="primary" <el-button type="primary" :loading="savingJud" @click="saveJudgment"> </el-button>
:loading="savingJud"
@click="saveJudgment"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
@ -440,6 +319,8 @@ export default {
if (this.$route.query.projectId) { if (this.$route.query.projectId) {
this.projectId = this.$route.query.projectId; this.projectId = this.$route.query.projectId;
this.getInfoData(); this.getInfoData();
} else {
this.rowDrop()
} }
// //
if (JSON.stringify(this.projectFields) != "{}") { if (JSON.stringify(this.projectFields) != "{}") {
@ -447,7 +328,6 @@ export default {
this.projectManage = projectManage; this.projectManage = projectManage;
this.projectJudgmentData = projectJudgmentData; this.projectJudgmentData = projectJudgmentData;
} }
this.rowDrop();
this.$refs.main.scrollTop = 0; this.$refs.main.scrollTop = 0;
}, },
beforeDestroy () { beforeDestroy () {
@ -482,6 +362,7 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateTime = 0 this.updateTime = 0
this.$refs.main.scrollTop = 0; this.$refs.main.scrollTop = 0;
this.rowDrop();
}); });
}).catch(err => { }).catch(err => {
this.loading = false this.loading = false
@ -785,24 +666,16 @@ export default {
// //
rowDrop () { rowDrop () {
// //
const tbody = document.querySelector(".draggable .el-table__body-wrapper tbody"); const tbody = document.querySelector(".el-table__body tbody");
const _this = this; const that = this;
Sortable.create(tbody, { this.$refs.projectJudgementTable && Sortable.create(tbody, {
// //
draggable: ".draggable .el-table__row", // draggable: ".draggable .el-table__row",
onEnd ({ newIndex, oldIndex }) { onUpdate ({ newIndex, oldIndex }) {
// : vue$nextTick console.log("🚀 ~ onEnd ~ newIndex, oldIndex:", newIndex, oldIndex)
_this.projectJudgmentData.splice(newIndex, 0, _this.projectJudgmentData.splice(oldIndex, 1)[0]); if (newIndex == oldIndex) return false
let newArray = _this.projectJudgmentData.slice(0); const currentRow = that.projectJudgmentData.splice(oldIndex, 1)[0]
_this.projectJudgmentData = []; that.projectJudgmentData.splice(newIndex, 0, currentRow)
_this.$nextTick(function () {
newArray.forEach((e, i) => {
_this.$set(e, "sort", i + 1);//
_this.$set(e, "name", e.name + "?");
_this.$set(e, "name", e.name.slice(0, e.name.length - 1)); //
});
_this.projectJudgmentData = newArray;
});
} }
}); });
}, },
@ -915,6 +788,7 @@ export default {
padding: 0; padding: 0;
border-bottom: 0; border-bottom: 0;
} }
.main { .main {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;

@ -13,7 +13,8 @@
<li> <li>
<label>所在国家</label> <label>所在国家</label>
<el-select size="small" v-model="form.countries"> <el-select size="small" v-model="form.countries">
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label"></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -21,7 +22,8 @@
<li> <li>
<label>性别</label> <label>性别</label>
<el-select size="small" v-model="form.sex"> <el-select size="small" v-model="form.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"></el-option> <el-option v-for="item in sexList" :key="item.value" :label="item.name"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li class="selects"> <li class="selects">
@ -29,17 +31,21 @@
<div class="mul"> <div class="mul">
<div class="child"> <div class="child">
<el-select size="small" v-model="form.countries" placeholder> <el-select size="small" v-model="form.countries" placeholder>
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label"></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</div> </div>
<div class="child"> <div class="child">
<el-select size="small" v-model="form.provinceId" placeholder @change="id => getCity(id, 1)"> <el-select size="small" v-model="form.provinceId" placeholder @change="id => getCity(id, 1)">
<el-option v-for="item in provinceList" :key="item.provinceId" :label="item.provinceName" :value="item.provinceId"></el-option> <el-option v-for="item in provinceList" :key="item.provinceId" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select> </el-select>
</div> </div>
<div class="child"> <div class="child">
<el-select size="small" v-model="form.cityId" placeholder :disabled="form.provinceId ? false : true"> <el-select size="small" v-model="form.cityId" placeholder
<el-option v-for="item in cityList" :key="item.cityId" :label="item.cityName" :value="item.cityId"></el-option> :disabled="form.provinceId ? false : true">
<el-option v-for="item in cityList" :key="item.cityId" :label="item.cityName"
:value="item.cityId"></el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
@ -48,7 +54,8 @@
<div class="line info"> <div class="line info">
<li> <li>
<label>出生年月</label> <label>出生年月</label>
<el-date-picker size="small" placeholder="请选择时间" v-model="form.dateBirth" :clearable="false" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd"></el-date-picker> <el-date-picker size="small" placeholder="请选择时间" v-model="form.dateBirth" :clearable="false" type="date"
format="yyyy-MM-dd" value-format="yyyy-MM-dd"></el-date-picker>
</li> </li>
<li> <li>
<label>身份证</label> <label>身份证</label>
@ -59,7 +66,8 @@
<li> <li>
<label>教育程度</label> <label>教育程度</label>
<el-select size="small" v-model="form.educationDegree" placeholder="请选择教育程度"> <el-select size="small" v-model="form.educationDegree" placeholder="请选择教育程度">
<el-option v-for="(item,index) in educationDegreeList" :key="index" :label="item.name" :value="item.value"></el-option> <el-option v-for="(item, index) in educationDegreeList" :key="index" :label="item.name"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -76,41 +84,52 @@
<li> <li>
<label>职业</label> <label>职业</label>
<el-select size="small" v-model="archive.personalCareerId" placeholder="选择职业"> <el-select size="small" v-model="archive.personalCareerId" placeholder="选择职业">
<el-option v-for="item in occupationList" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in occupationList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>所在国家</label> <label>所在国家</label>
<el-select size="small" v-model="form.countries" placeholder> <el-select size="small" v-model="form.countries" placeholder>
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label" ></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
<div class="line"> <div class="line">
<li> <li>
<label>学校名称</label> <label>学校名称</label>
<el-select size="small" v-model="archive.schoolId" filterable placeholder="选择学校" @change="id => getSchoolName(id,index)"> <el-select size="small" v-model="archive.schoolId" filterable placeholder="选择学校"
<el-option v-for="item in schoolList" :key="item.value" :label="item.schoolName" :value="item.schoolId"></el-option> @change="id => getSchoolName(id, index)">
<el-option v-for="item in schoolList" :key="item.value" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>专业学科</label> <label>专业学科</label>
<el-select size="small" v-model="archive.disciplineId" placeholder="选择专业学科" @change="id => getItemProfessionalClass(id,index)" @clear="() => clearItemClass(index)"> <el-select size="small" v-model="archive.disciplineId" placeholder="选择专业学科"
<el-option v-for="item in subjectList" :key="item.value" :label="item.disciplineName" :value="item.disciplineId"></el-option> @change="id => getItemProfessionalClass(id, index)" @clear="() => clearItemClass(index)">
<el-option v-for="item in subjectList" :key="item.value" :label="item.disciplineName"
:value="item.disciplineId"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
<div class="line" style="margin-bottom: 0"> <div class="line" style="margin-bottom: 0">
<li> <li>
<label>专业类</label> <label>专业类</label>
<el-select size="small" v-model="archive.professionalClassId" placeholder="选择专业类" :disabled="archive.disciplineId ? false : true" @change="id => getItemProfessional(id,index)" @clear="() => clearItemProfess(index)"> <el-select size="small" v-model="archive.professionalClassId" placeholder="选择专业类"
<el-option v-for="item in archive.ProfessionalClassList" :key="item.professionalClassId" :label="item.professionalClassName" :value="item.professionalClassId"></el-option> :disabled="archive.disciplineId ? false : true" @change="id => getItemProfessional(id, index)"
@clear="() => clearItemProfess(index)">
<el-option v-for="item in archive.ProfessionalClassList" :key="item.professionalClassId"
:label="item.professionalClassName" :value="item.professionalClassId"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>专业</label> <label>专业</label>
<el-select size="small" v-model="archive.professionalId" placeholder="选择专业" :disabled="archive.professionalClassId ? false : true" @change="getItemStuGrade"> <el-select size="small" v-model="archive.professionalId" placeholder="选择专业"
<el-option v-for="item in archive.ProfessionalList" :key="item.professionalId" :label="item.professionalName" :value="item.professionalId"></el-option> :disabled="archive.professionalClassId ? false : true" @change="getItemStuGrade">
<el-option v-for="item in archive.ProfessionalList" :key="item.professionalId"
:label="item.professionalName" :value="item.professionalId"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -163,7 +182,8 @@
<el-button type="primary" size="small" @click="save">更新</el-button> <el-button type="primary" size="small" @click="save">更新</el-button>
</div> </div>
<el-dialog :title="form.email ? '更换邮箱' : '绑定邮箱'" :visible.sync="emailVisible" :close-on-click-modal="false" @close="closeEmail" width="30%"> <el-dialog :title="form.email ? '更换邮箱' : '绑定邮箱'" :visible.sync="emailVisible" :close-on-click-modal="false"
@close="closeEmail" width="30%">
<el-form ref="form" :model="form" label-width="60px"> <el-form ref="form" :model="form" label-width="60px">
<el-form-item label="邮箱"> <el-form-item label="邮箱">
<el-input style="width: 394px;" placeholder="请输入邮箱" v-model="email"></el-input> <el-input style="width: 394px;" placeholder="请输入邮箱" v-model="email"></el-input>
@ -171,7 +191,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div class="flex"> <div class="flex">
<el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{emailBtnText}}</el-button> <el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{
emailBtnText }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -181,7 +202,8 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog :title="form.phone ? '更换手机号' : '绑定手机号'" :visible.sync="phoneVisible" :close-on-click-modal="false" @close="closePhone" width="30%"> <el-dialog :title="form.phone ? '更换手机号' : '绑定手机号'" :visible.sync="phoneVisible" :close-on-click-modal="false"
@close="closePhone" width="30%">
<el-form ref="form" :model="form" label-width="60px"> <el-form ref="form" :model="form" label-width="60px">
<el-form-item label="手机号"> <el-form-item label="手机号">
<el-input style="width: 404px;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input> <el-input style="width: 404px;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
@ -189,7 +211,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div class="flex"> <div class="flex">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button> <el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{
phoneBtnText }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -199,16 +222,19 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="更换密码" :visible.sync="passwordVisible" :close-on-click-modal="false" @close="closePassword" width="30%"> <el-dialog title="更换密码" :visible.sync="passwordVisible" :close-on-click-modal="false" @close="closePassword"
width="30%">
<el-form ref="passwordForm" :model="form" label-width="82px"> <el-form ref="passwordForm" :model="form" label-width="82px">
<el-form-item label="原密码"> <el-form-item label="原密码">
<el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input> <el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="新密码"> <el-form-item label="新密码">
<el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码" @keyup.enter.native="editPassword"></el-input> <el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="确认新密码"> <el-form-item label="确认新密码">
<el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码" @keyup.enter.native="editPassword"></el-input> <el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -835,37 +861,46 @@ export default {
.flex { .flex {
display: flex; display: flex;
} }
.m-r-10 { .m-r-10 {
margin-right: 10px; margin-right: 10px;
} }
.l-title { .l-title {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 12px; margin-bottom: 12px;
font-size: 14px; font-size: 14px;
color: #333; color: #333;
img { img {
margin-right: 5px; margin-right: 5px;
} }
} }
.scroll { .scroll {
max-height: calc(100vh - 218px); max-height: calc(100vh - 218px);
overflow: auto; overflow: auto;
} }
.page { .page {
margin-bottom: 12px; margin-bottom: 12px;
/deep/.el-input__inner { /deep/.el-input__inner {
border-color: #CACFDB; border-color: #CACFDB;
} }
.list { .list {
.line { .line {
display: flex; display: flex;
margin-bottom: 24px; margin-bottom: 24px;
&.info li:not(.selects) { &.info li:not(.selects) {
.el-input { .el-input {
flex: 1; flex: 1;
} }
} }
&.imp li { &.imp li {
&:nth-child(odd) { &:nth-child(odd) {
width: 360px; width: 360px;
@ -873,15 +908,20 @@ export default {
} }
} }
} }
.el-input, .el-select{
.el-input,
.el-select {
width: 220px; width: 220px;
.el-input__inner { .el-input__inner {
border-color: #CACFDB; border-color: #CACFDB;
} }
} }
li { li {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
&>label { &>label {
width: 100px; width: 100px;
margin-right: 5px; margin-right: 5px;
@ -889,23 +929,29 @@ export default {
font-size: 14px; font-size: 14px;
color: #4c4c4c; color: #4c4c4c;
} }
.el-select { .el-select {
flex: 1; flex: 1;
} }
.el-select .el-input.is-disabled .el-input__inner { .el-select .el-input.is-disabled .el-input__inner {
border-color: #ddd; border-color: #ddd;
} }
.val { .val {
margin-right: 15px; margin-right: 15px;
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
} }
.mul { .mul {
display: inline-flex; display: inline-flex;
.child { .child {
display: inline-flex; display: inline-flex;
width: 132px; width: 132px;
margin-right: 10px; margin-right: 10px;
&>span { &>span {
margin-bottom: 5px; margin-bottom: 5px;
font-size: 14px; font-size: 14px;
@ -913,12 +959,14 @@ export default {
} }
} }
} }
&:nth-child(odd) { &:nth-child(odd) {
width: 325px; width: 325px;
margin-right: 100px; margin-right: 100px;
} }
} }
} }
.archives { .archives {
position: relative; position: relative;
width: 862px; width: 862px;
@ -926,6 +974,7 @@ export default {
margin-bottom: 6px; margin-bottom: 6px;
border-radius: 4px; border-radius: 4px;
background-color: #FAFAFA; background-color: #FAFAFA;
.del { .del {
position: absolute; position: absolute;
top: 80px; top: 80px;
@ -933,28 +982,34 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.fold { .fold {
margin-top: 20px; margin-top: 20px;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
color: #006EFF; color: #006EFF;
span { span {
cursor: pointer; cursor: pointer;
i { i {
transition: .5s; transition: .5s;
} }
&.active i { &.active i {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
} }
} }
.btns { .btns {
width: 100%; width: 100%;
padding: 12px 0; padding: 12px 0;
text-align: center; text-align: center;
background-color: #fff; background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(188, 201, 218, 0.4); box-shadow: 0px 0px 10px 0px rgba(188, 201, 218, 0.4);
.el-button { .el-button {
width: 80px; width: 80px;
} }

@ -4,8 +4,7 @@
<div class="side"> <div class="side">
<div class="m-b-20"> <div class="m-b-20">
<h6 class="p-title">后台员工账号</h6> <h6 class="p-title">后台员工账号</h6>
<el-radio-group v-model="studentType" <el-radio-group v-model="studentType" @change="changeType">
@change="changeType">
<div class="m-b-20"> <div class="m-b-20">
<el-radio :label="1">所有员工</el-radio> <el-radio :label="1">所有员工</el-radio>
</div> </div>
@ -17,39 +16,24 @@
<el-divider></el-divider> <el-divider></el-divider>
<div> <div>
<div class="flex-between"> <div class="flex-between">
<h6 class="p-title" <h6 class="p-title" style="margin-bottom: 0">组织架构</h6>
style="margin-bottom: 0">组织架构</h6> <el-button type="text" @click="addOrg" v-auth="'/system:后台账号:新增部门'">添加</el-button>
<el-button type="text"
@click="addOrg"
v-auth="'/system:后台账号:新增部门'">添加</el-button>
</div> </div>
<div style="overflow: auto"> <div style="overflow: auto">
<el-tree :data="orgList" <el-tree :data="orgList" default-expand-all ref="orgTree" node-key="id" highlight-current
default-expand-all :expand-on-click-node="false" @node-click="handleNodeClick"
ref="orgTree"
node-key="id"
highlight-current
:expand-on-click-node="false"
@node-click="handleNodeClick"
:props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }"> :props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }">
<span class="custom-tree-node" <span class="custom-tree-node" slot-scope="{ node, data }">
slot-scope="{ node, data }">
<span class="org-name">{{ node.label }}</span> <span class="org-name">{{ node.label }}</span>
<span> <span>
<el-button v-auth="'/system:后台账号:新增部门'" <el-button v-auth="'/system:后台账号:新增部门'" type="text" icon="el-icon-circle-plus-outline"
type="text"
icon="el-icon-circle-plus-outline"
@click="() => addOrg(node, data)"> @click="() => addOrg(node, data)">
</el-button> </el-button>
<el-button v-auth="'/system:后台账号:编辑部门'" <el-button v-auth="'/system:后台账号:编辑部门'" type="text" icon="el-icon-edit-outline"
type="text"
icon="el-icon-edit-outline"
@click="() => editOrg(node, data)"> @click="() => editOrg(node, data)">
</el-button> </el-button>
<el-button v-auth="'/system:后台账号:删除部门'" <el-button v-auth="'/system:后台账号:删除部门'" type="text" icon="el-icon-delete"
type="text"
icon="el-icon-delete"
@click="() => delOrg(node, data)"> @click="() => delOrg(node, data)">
</el-button> </el-button>
</span> </span>
@ -58,36 +42,22 @@
</div> </div>
</div> </div>
<el-dialog :title="orgForm.id ? '编辑' : '新增' + '部门'" <el-dialog :title="orgForm.id ? '编辑' : '新增' + '部门'" :visible.sync="orgVisible" :close-on-click-modal="false"
:visible.sync="orgVisible"
:close-on-click-modal="false"
width="50%"> width="50%">
<el-form v-if="orgVisible" <el-form v-if="orgVisible" ref="orgForm" :model="orgForm" :rules="orgRules" label-width="100px">
ref="orgForm" <el-form-item label="部门名称" prop="organizationName">
:model="orgForm" <el-input v-model.trim="orgForm.organizationName" placeholder="请输入"></el-input>
:rules="orgRules"
label-width="100px">
<el-form-item label="部门名称"
prop="organizationName">
<el-input v-model.trim="orgForm.organizationName"
placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="上级部门"> <el-form-item label="上级部门">
<span v-if="orgForm.parentName">{{ orgForm.parentName }}</span> <span v-if="orgForm.parentName">{{ orgForm.parentName }}</span>
<el-cascader v-else <el-cascader v-else :options="orgListDia" v-model="cascaderValue" :props="cascaderProps" clearable
:options="orgListDia"
v-model="cascaderValue"
:props="cascaderProps"
clearable
style="width: 100%"> style="width: 100%">
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="closeOrg"> </el-button> <el-button @click="closeOrg"> </el-button>
<el-button type="primary" <el-button type="primary" @click="orgSubmit"> </el-button>
@click="orgSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -97,195 +67,96 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input style="width: 250px;" <el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord"
placeholder="请输入员工姓名/手机号"
prefix-icon="el-icon-search"
v-model="keyWord"
clearable></el-input> clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
<el-button type="primary" <el-button type="primary" @click="addStaff" v-auth="'/system:后台账号:新增员工'">新增员工</el-button>
@click="addStaff" <el-button type="primary" @click="batchImport" v-auth="'/system:后台账号:批量导入'">批量导入</el-button>
v-auth="'/system:后台账号:新增员工'">新增员工</el-button>
<el-button type="primary"
@click="batchImport"
v-auth="'/system:后台账号:批量导入'">批量导入</el-button>
</div> </div>
</div> </div>
<el-table :data="listData" <el-table :data="listData" class="table" ref="table" stripe header-align="center"
class="table" @selection-change="handleSelectionChange" row-key="accountId">
ref="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
header-align="center" <el-table-column prop="userName" label="员工姓名" align="center" min-width="100"></el-table-column>
@selection-change="handleSelectionChange" <el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column>
row-key="accountId"> <el-table-column prop="phone" label="手机号" align="center" width="120"></el-table-column>
<el-table-column type="selection" <el-table-column prop="staffArchitectureName" label="所在部门" align="center" min-width="200"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index"
width="60"
label="序号"
align="center"></el-table-column>
<el-table-column prop="userName"
label="员工姓名"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="account"
label="账号"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="phone"
label="手机号"
align="center"
width="120"></el-table-column>
<el-table-column prop="staffArchitectureName"
label="所在部门"
align="center"
min-width="200"
show-overflow-tooltip></el-table-column> show-overflow-tooltip></el-table-column>
<el-table-column prop="roleName" <el-table-column prop="roleName" label="授权角色" align="center" min-width="200"
label="授权角色"
align="center"
min-width="200"
show-overflow-tooltip></el-table-column> show-overflow-tooltip></el-table-column>
<el-table-column prop="lastLoginTime" <el-table-column prop="lastLoginTime" label="最后登录时间" align="center" width="130"></el-table-column>
label="最后登录时间" <el-table-column label="操作" align="center" width="300">
align="center"
width="130"></el-table-column>
<el-table-column label="操作"
align="center"
width="300">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" v-auth="'/system:后台账号:查看'" @click="queryStaff(scope.row, true)">查看</el-button>
v-auth="'/system:后台账号:查看'" <el-button type="text" v-auth="'/system:后台账号:编辑'" @click="queryStaff(scope.row, false)">编辑</el-button>
@click="queryStaff(scope.row,true)">查看</el-button> <el-button type="text" v-auth="'/system:后台账号:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button type="text" <el-button type="text" v-auth="'/system:后台账号:删除'" @click="delStaff(scope.row)">删除</el-button>
v-auth="'/system:后台账号:编辑'"
@click="queryStaff(scope.row,false)">编辑</el-button>
<el-button type="text"
v-auth="'/system:后台账号:重置密码'"
@click="resetPassword(scope.row)">重置密码</el-button>
<el-button type="text"
v-auth="'/system:后台账号:删除'"
@click="delStaff(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next"
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination> :total="total"></el-pagination>
</div> </div>
<el-dialog :title="isDetail ? '查看' : (form.accountId ? '编辑' : '新增') + '员工'" <el-dialog :title="isDetail ? '查看' : (form.accountId ? '编辑' : '新增') + '员工'" :visible.sync="staffVisible"
:visible.sync="staffVisible" width="580px" class="dialog" :close-on-click-modal="false" @close="closeStaff">
width="580px" <el-form ref="form" :model="form" :rules="rules" label-width="150px" :disabled="isDetail"
class="dialog"
:close-on-click-modal="false"
@close="closeStaff">
<el-form ref="form"
:model="form"
:rules="rules"
label-width="150px"
:disabled="isDetail"
style='margin-right: 80px;'> style='margin-right: 80px;'>
<el-form-item prop="workNumber" <el-form-item prop="workNumber" label="工号">
label="工号"> <el-input v-model.trim="form.workNumber" placeholder="请输入工号"></el-input>
<el-input v-model.trim="form.workNumber"
placeholder="请输入工号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="userName" <el-form-item prop="userName" label="姓名">
label="姓名"> <el-input v-model.trim="form.userName" placeholder="请输入姓名"></el-input>
<el-input v-model.trim="form.userName"
placeholder="请输入姓名"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="account" <el-form-item prop="account" label="账号">
label="账号"> <el-input v-model.trim="form.account" placeholder="请输入账号"></el-input>
<el-input v-model.trim="form.account"
placeholder="请输入账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="roleList" <el-form-item prop="roleList" label="授权角色">
label="授权角色"> <el-select class="w-100" v-model="form.roleList" multiple>
<el-select class="w-100"
v-model="form.roleList"
multiple>
<template v-for="item in roleList"> <template v-for="item in roleList">
<!-- 不显示超管 --> <!-- 不显示超管 -->
<el-option v-if="item.roleName !== '超级管理员'" <el-option v-if="item.roleName !== '超级管理员'" :key="item.id" :label="item.roleName" :value="item.id">
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option> </el-option>
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="所在部门"> <el-form-item label="所在部门">
<el-cascader class="w-100" <el-cascader class="w-100" v-model="form.staffArchitectureId" :options="orgList"
v-model="form.staffArchitectureId"
:options="orgList"
:props="casProps"></el-cascader> :props="casProps"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item prop="phone" <el-form-item prop="phone" label="手机号">
label="手机号"> <el-input v-model.trim="form.phone" placeholder="请输入手机号" maxlength="11"></el-input>
<el-input v-model.trim="form.phone"
placeholder="请输入手机号"
maxlength="11"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="email" <el-form-item prop="email" label="邮箱">
label="邮箱"> <el-input v-model.trim="form.email" placeholder="请输入邮箱"></el-input>
<el-input v-model.trim="form.email"
placeholder="请输入邮箱"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer" v-if="!isDetail">
class="dialog-footer"
v-if="!isDetail">
<el-button @click="staffVisible = false">取消</el-button> <el-button @click="staffVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="submitStaff">确定</el-button>
@click="submitStaff">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="批量导入" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false">
:visible.sync="importVisible"
width="24%"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<el-button type="primary" <el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
@click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div> </div>
<el-upload ref="importStaff" <el-upload ref="importStaff" name="file" accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError"
name="file" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed"
accept=".xls,.xlsx" :action="this.api.importStaff" :file-list="uploadList" :headers="headers">
:on-remove="handleRemove" <el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.importStaff"
:file-list="uploadList"
:headers="headers">
<el-button type="primary"
class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload> </el-upload>
<el-link v-if="uploadFaild" <el-link v-if="uploadFaild" type="primary" @click="showFaild">部分数据导入失败查看失败原因</el-link>
type="primary"
@click="showFaild">部分数据导入失败查看失败原因</el-link>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer"> <el-button size="small" @click="importVisible = false"> </el-button>
<el-button size="small" <el-button size="small" type="primary" @click="uploadSure"> </el-button>
@click="importVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -870,22 +741,27 @@ export default {
.m-b-20 { .m-b-20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.org-name { .org-name {
margin-right: 20px; margin-right: 20px;
} }
.w-100 { .w-100 {
width: 100%; width: 100%;
} }
.wrap { .wrap {
display: flex; display: flex;
min-height: 100%; min-height: 100%;
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 374px); width: calc(100% - 374px);
padding: 24px 0; padding: 24px 0;

@ -705,7 +705,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else { } else {

@ -1,78 +1,46 @@
<template> <template>
<!-- 课程预览 --> <!-- 课程预览 -->
<div class="wrap"> <div class="wrap">
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" :content="'课程预览'"></el-page-header>
:content="'课程预览'"></el-page-header>
</div> </div>
</el-card> </el-card>
<div class="flex"> <div class="flex">
<div class="cover" <div class="cover" :class="{ 'is-word': showMask1 }">
:class="{'is-word': showMask1}"> <img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%">
<img v-if="coverUrl"
:src="coverUrl"
alt=""
width="100%"
height="100%">
<template v-else-if="iframeSrc"> <template v-else-if="iframeSrc">
<iframe class="inner fileIframe" <iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
id="fileIframe"
:src="iframeSrc"
frameborder="0"></iframe>
<template v-if="showMask"> <template v-if="showMask">
<div class="mask" <div class="mask" style="width: 500px;height: 30px;top: 53px;right: 320px"></div>
style="width: 500px;height: 30px;top: 53px;right: 320px"></div> <div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
<div class="mask"
style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
</template> </template>
<template v-if="showMask1"> <template v-if="showMask1">
<div class="word-mask" <div class="word-mask" style="height: 40px;"></div>
style="height: 40px;"></div> <div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
<div class="word-mask2"
style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template> </template>
<template v-if="showMask2"> <template v-if="showMask2">
<div class="excel-mask1" <div class="excel-mask1" style="height: 48px;"></div>
style="height: 48px;"></div>
</template> </template>
</template> </template>
<div class="pdf inner" <div class="pdf inner" v-else-if="pdfSrc">
v-else-if="pdfSrc">
<p class="arrow"> <p class="arrow">
<span @click="changePdfPage(0)" <span @click="changePdfPage(0)" class="turn el-icon-arrow-left" :class="{ grey: currentPage == 1 }"></span>
class="turn el-icon-arrow-left"
:class="{grey: currentPage==1}"></span>
{{ currentPage }} / {{ pageCount }} {{ currentPage }} / {{ pageCount }}
<span @click="changePdfPage(1)" <span @click="changePdfPage(1)" class="turn el-icon-arrow-right"
class="turn el-icon-arrow-right"
:class="{ grey: currentPage == pageCount }"></span> :class="{ grey: currentPage == pageCount }"></span>
</p> </p>
<pdf class="pdf-wrap" <pdf class="pdf-wrap" :src="pdfSrc" :page="currentPage" @num-pages="pageCount = $event"
:src="pdfSrc" @page-loaded="currentPage = $event" @loaded="loadPdfHandler">
:page="currentPage"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
@loaded="loadPdfHandler">
</pdf> </pdf>
</div> </div>
<div class="inner" <div class="inner" v-else-if="playAuth">
v-else-if="playAuth"> <div class="video_wid" id="player"></div>
<div class="video_wid"
id="player"></div>
</div> </div>
<div class="inner" <div class="inner" v-else-if="videoSrc">
v-else-if="videoSrc"> <video class="video" :key="videoSrc" width="100%" height="100%" autoplay controls>
<video class="video" <source :src="videoSrc" type="video/mp4">
:key="videoSrc"
width="100%"
height="100%"
autoplay
controls>
<source :src="videoSrc"
type="video/mp4">
您的浏览器不支持 video 标签 您的浏览器不支持 video 标签
</video> </video>
</div> </div>
@ -81,49 +49,26 @@
<div class="list"> <div class="list">
<h4 class="title">{{ courseName }}</h4> <h4 class="title">{{ courseName }}</h4>
<div class="desc-wrap"> <div class="desc-wrap">
<div class="desc" <div class="desc" :class="{ active: desShrink }" v-html="description"></div>
:class="{active: desShrink}" <i class="arrow" :class="{ active: desShrink }" v-if="description.length > 40">
v-html="description"></div>
<i class="arrow"
:class="{active: desShrink}"
v-if="description.length > 40">
<span>...</span> <span>...</span>
<img src="@/assets/img/arrow-down.png" <img src="@/assets/img/arrow-down.png" alt="" @click="desShrink = !desShrink">
alt=""
@click="desShrink = !desShrink">
</i> </i>
</div> </div>
<div class="chapters"> <div class="chapters">
<template v-if="videoList.length"> <template v-if="videoList.length">
<div class="chapter" <div class="chapter" v-for="(item, index) in videoList" :key="index">
v-for="(item,index) in videoList"
:key="index">
<div class="chapterName">{{ item.name }}</div> <div class="chapterName">{{ item.name }}</div>
<div class="section" <div class="section" v-if="item.subsectionList.length">
v-if="item.subsectionList.length"> <div v-for="(section, i) in item.subsectionList" :key="i" @click="preview(section, item.name)">
<div v-for="(section,i) in item.subsectionList" <p class="sectionName ellipsis" :class="{ active: curLink === `${item.name}${section.name}` }">
:key="i" <img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
@click="preview(section, item.name)"> <img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<p class="sectionName ellipsis"
:class="{active: curLink === `${item.name}${section.name}`}">
<img v-if="section.fileType === 'pptx'"
src="@/assets/img/exts/ppt.png"
alt="">
<img v-else-if="section.fileType === 'mp4'"
src="@/assets/img/exts/video.png"
alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" <img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png" src="@/assets/img/exts/word.png" alt="">
alt=""> <img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'txt'" <img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
src="@/assets/img/exts/txt.png" <img v-else src="@/assets/img/exts/pic.png" alt="">
alt="">
<img v-else-if="section.fileType === 'pdf'"
src="@/assets/img/exts/pdf.png"
alt="">
<img v-else
src="@/assets/img/exts/pic.png"
alt="">
{{ section.name }} {{ section.name }}
</p> </p>
</div> </div>
@ -222,7 +167,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
this.$nextTick(() => { this.$nextTick(() => {
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
@ -322,7 +267,9 @@ export default {
.wrap { .wrap {
padding: 0 200px; padding: 0 200px;
} }
$height: 700px; $height: 700px;
.video_wid, .video_wid,
.cover { .cover {
position: relative; position: relative;
@ -330,9 +277,11 @@ $height: 700px;
height: $height !important; height: $height !important;
border: 0; border: 0;
} }
.page { .page {
/deep/.des { /deep/.des {
overflow: auto; overflow: auto;
div, div,
p, p,
span { span {
@ -340,21 +289,27 @@ $height: 700px;
} }
} }
} }
.l-title { .l-title {
font-size: 17px; font-size: 17px;
} }
.cover { .cover {
background-color: #252528; background-color: #252528;
img { img {
border-radius: 8px; border-radius: 8px;
} }
&.is-word { &.is-word {
overflow: hidden; overflow: hidden;
} }
} }
.fileIframe { .fileIframe {
height: $height !important; height: $height !important;
} }
.video_wid, .video_wid,
.inner { .inner {
width: 100%; width: 100%;
@ -362,42 +317,52 @@ $height: 700px;
border: 0; border: 0;
overflow: auto; overflow: auto;
} }
.cover.is-word { .cover.is-word {
.inner { .inner {
height: calc(100% + 38px) !important; height: calc(100% + 38px) !important;
margin-top: -38px; margin-top: -38px;
} }
} }
.video_wid:focus { .video_wid:focus {
outline: none; outline: none;
} }
.catalog { .catalog {
width: 296px; width: 296px;
padding: 16px; padding: 16px;
margin-left: 12px; margin-left: 12px;
background-color: #252528; background-color: #252528;
} }
.list { .list {
height: calc(700px - 82px); height: calc(700px - 82px);
overflow-y: auto; overflow-y: auto;
.title { .title {
margin-bottom: 11px; margin-bottom: 11px;
color: #fff; color: #fff;
font-size: 16px; font-size: 16px;
} }
.pro-title { .pro-title {
margin-bottom: 5px; margin-bottom: 5px;
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
} }
/deep/.el-progress-bar { /deep/.el-progress-bar {
width: 92%; width: 92%;
} }
/deep/.el-progress__text { /deep/.el-progress__text {
color: #fff; color: #fff;
} }
.desc-wrap { .desc-wrap {
position: relative; position: relative;
.desc { .desc {
font-size: 12px; font-size: 12px;
color: #fff; color: #fff;
@ -407,11 +372,13 @@ $height: 700px;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
&.active { &.active {
display: block; display: block;
overflow: visible; overflow: visible;
} }
} }
.arrow { .arrow {
position: absolute; position: absolute;
bottom: 2px; bottom: 2px;
@ -420,41 +387,50 @@ $height: 700px;
justify-content: space-between; justify-content: space-between;
width: 46px; width: 46px;
background-color: #fff; background-color: #fff;
span { span {
font-size: 14px; font-size: 14px;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
} }
img { img {
width: 16px; width: 16px;
cursor: pointer; cursor: pointer;
} }
&.active { &.active {
span { span {
opacity: 0; opacity: 0;
} }
img { img {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
} }
} }
.chapters { .chapters {
margin-top: 16px; margin-top: 16px;
max-height: calc(100% - 53px); max-height: calc(100% - 53px);
overflow: auto; overflow: auto;
} }
.chapter { .chapter {
margin-bottom: 20px; margin-bottom: 20px;
} }
.chapterName { .chapterName {
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
} }
.section { .section {
padding: 5px 15px; padding: 5px 15px;
margin-top: 12px; margin-top: 12px;
background-color: #121214; background-color: #121214;
} }
.sectionName { .sectionName {
position: relative; position: relative;
display: flex; display: flex;
@ -464,36 +440,44 @@ $height: 700px;
font-size: 12px; font-size: 12px;
color: #999; color: #999;
cursor: pointer; cursor: pointer;
img { img {
margin-right: 8px; margin-right: 8px;
} }
.icon { .icon {
position: absolute; position: absolute;
right: 0; right: 0;
font-size: 14px; font-size: 14px;
color: #00c935; color: #00c935;
} }
.circle { .circle {
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 50%; border-radius: 50%;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
&.active { &.active {
color: #fff; color: #fff;
} }
} }
} }
.buy { .buy {
text-align: center; text-align: center;
.tips { .tips {
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
} }
img { img {
width: 85%; width: 85%;
} }
} }
.el-image-viewer__wrapper { .el-image-viewer__wrapper {
transform: translateY(-10px); transform: translateY(-10px);
transition: transform 0.5s; transition: transform 0.5s;
@ -502,19 +486,23 @@ $height: 700px;
transform: translateY(0); transform: translateY(0);
} }
} }
.el-image-viewer__close { .el-image-viewer__close {
z-index: 2000; z-index: 2000;
top: 15px; top: 15px;
right: 15px; right: 15px;
&.doc-close { &.doc-close {
i { i {
color: #000 !important; color: #000 !important;
} }
} }
} }
.list::-webkit-scrollbar { .list::-webkit-scrollbar {
width: 4px; width: 4px;
} }
.list::-webkit-scrollbar-thumb { .list::-webkit-scrollbar-thumb {
border-radius: 10px; border-radius: 10px;
background: rgba(0, 0, 0, 0.06); background: rgba(0, 0, 0, 0.06);
@ -525,6 +513,7 @@ $height: 700px;
position: absolute; position: absolute;
background-color: rgb(57, 58, 61); background-color: rgb(57, 58, 61);
} }
.word-mask { .word-mask {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -533,6 +522,7 @@ $height: 700px;
width: 100%; width: 100%;
background-color: rgb(243, 242, 241); background-color: rgb(243, 242, 241);
} }
.word-mask1 { .word-mask1 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -541,11 +531,13 @@ $height: 700px;
width: 100%; width: 100%;
background-color: #185abd; background-color: #185abd;
} }
.word-mask2 { .word-mask2 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
background-color: transparent; background-color: transparent;
} }
.excel-mask1 { .excel-mask1 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -554,14 +546,17 @@ $height: 700px;
width: 60%; width: 60%;
background-color: #107c41; background-color: #107c41;
} }
.pdf { .pdf {
position: relative; position: relative;
.full { .full {
position: absolute; position: absolute;
top: 7px; top: 7px;
right: 10px; right: 10px;
cursor: pointer; cursor: pointer;
} }
.arrow { .arrow {
padding: 10px 0; padding: 10px 0;
display: flex; display: flex;
@ -570,12 +565,14 @@ $height: 700px;
font-size: 16px; font-size: 16px;
color: #fff; color: #fff;
background-color: #333; background-color: #333;
.turn { .turn {
margin: 0 10px; margin: 0 10px;
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
} }
} }
.pdf-wrap { .pdf-wrap {
width: 80%; width: 80%;
margin: 0 auto; margin: 0 auto;

@ -6,14 +6,25 @@
<script> <script>
import Util from '@/libs/util' import Util from '@/libs/util'
import Setting from '@/setting'
export default { export default {
data () { data () {
return { return {
url: `http://121.37.12.51/exam/#/quesBankType?token=${sessionStorage.getItem('token')}` url: ''
}; };
}, },
mounted () { mounted () {
const cache = localStorage.getItem('examPath') // localStorage
let url = `${location.origin}/examination/`
if (Setting.isDev) url = `http://192.168.31.125:8098/`
if (cache) {
url += `#${cache}${cache.includes('?') ? `&` : '?'}token=${sessionStorage.getItem('token')}`
} else {
url += `#/quesBankType?token=${sessionStorage.getItem('token')}`
}
url += `&v=${Date.now()}`
localStorage.setItem('exam_token', sessionStorage.getItem('token'))
this.url = url
}, },
methods: { methods: {
@ -23,6 +34,6 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
iframe { iframe {
height: calc(100vh - 173px); height: calc(100vh - 167px);
} }
</style> </style>

Loading…
Cancel
Save