Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-exam-show
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-exam-show
Commits
cb6821b7
提交
cb6821b7
authored
7月 27, 2023
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: 优化代码
上级
80eb10b1
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
488 行增加
和
489 行删除
+488
-489
dev.ezijing.com.key
build/dev.ezijing.com.key
+27
-27
dev.ezijing.com.pem
build/dev.ezijing.com.pem
+109
-67
exam_api.js
src/api/exam_api.js
+4
-4
login_api.js
src/api/login_api.js
+1
-1
test_api.js
src/api/test_api.js
+4
-4
answerCard.vue
src/components/exam/answerCard.vue
+3
-11
question.vue
src/components/exam/question.vue
+157
-156
index.html
src/index.html
+1
-1
examAnswer.vue
src/pages/exam/examAnswer.vue
+45
-48
confirmInfo.vue
src/pages/login/confirmInfo.vue
+97
-115
index.vue
src/pages/login/index.vue
+39
-53
routes.js
src/router/routes.js
+1
-2
没有找到文件。
build/dev.ezijing.com.key
浏览文件 @
cb6821b7
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAn0EINdIXTDCzmR7J5FOjOV+PbXt7GNO6fanoCGe2O0CPRlNf
2Ea/wv6SlRtJPd0ohmnKqZdUbBpAsiV4ggOdOqeEB6utVYQWY/zhXRKYeRjN/iDu
WCRY5S+eRVkSzVOJP9DlBn6dnHSsWj55h1PrkIac8B862F/cVno/Wk5dqU55ZUoN
wHGw5Goz3R37w+Q0C9HRS5mrmPqI+Ogy8TJrIRxw9YAj5OlvuqBAeYAW1sNdEfsi
mMB0H2fbbXqEL4AsipE5ppP7Ij3vxVpxvmnl/SO7N6+Fit6r25VeFSvplK+PIV3c
UsK3PCKV2sOo0BDWtWFQh5hW3fK5RYjLpNDHCwIDAQABAoIBAEkiBDMzF5/VfaSD
jxNblUlzqNoOKqlsEehDblrtxbHQI/uXrhwT4VwarBXtQeU2+rU/P+JBrHM4Wx10
N7L9FecppmgfXqo2zlF8f8HOGFcEHRTm6o1vo6McCwKttQS1qAG2XHZvDtIagkuv
BQAwea0VJFzg+pUC8JyF5zIBauGkfk8eHTLFVuIEJoSJbPWBYzp7Vf1SCjXqs3YY
aZ5QkOqY7S81D2EULFAWiMIMdY/PVT5DSXxsjaJFkvxjDedA4jNCplyODBKdpnBb
kfoJTJ7qsSnqgJ2y2xRdRlvZalE49lr2MkW254s5GH35+hMYam0bffgLXdPz6RIs
7X0atYECgYEA1A9G+0+uYlyxddyR54QlWGK7L3wP+REMXultudT9rq4S6qkHoOgP
rhi2kvZOqA0sMR7XMVz5nw0ouUMUVfW0YzudgAK99tdIuk6dP6VqVo9T4kqa0rXi
3ZKD51qGXbF22SndEWV68QEPzMCbf0E+kXl5MGGNnFtjZ5nxTGS+uH8CgYEAwECs
0T36EnLOCXZoi3rTeHr2pSO20VuFSgljnHA6Ups9Chu6h/iZ8t0XVNb8J14q7lFi
NY6b4D3FR/vwO3nFt7dvFYNFaFGuFrkAaH002p8EYWSckhlGcucBuKivBVUbhXuM
HMGmqGhAnnGCvCj/v4n5/wv3wtFYfzYWnYPHC3UCgYBZgbFGNhW28sT8qIL1I3PX
4KR9oHHlgOqlzQVBYMNKzbKyVXIg2pJzu36kfU4p5JV4jjnqXgIGvjkoKUYWGkVv
dSQ/eejQnYHXEYOR77H4ozqW00KSGa+OMl92cWExfsxZUTA8PYcs3nPayplXlyRf
ptQeNa7eBjzo57NPuV4+5QKBgQCrJihzUlBYshmYNPBXE25FOHpwgz3SXT5orbke
4I4bUhXh9NN3DqrGmWqW3Zi2108ywALFGQLNe1AwiCnSWNLafZOHvEhC2Uw48FNb
sfMmmR/GMFJugc/EpMBUit7cyWppx5XxV7gs/jpgkz7GkV00P/ntwtK7fbDh9t3l
NhYxrQKBgDVE4HSDqOvZOaXGRoM0pJ3uYRTTSIDGVNMZ9t2C/t3uwoyFBe+Om2t+
G6w2Gr+Dck1v+zizU3khbAHvE67rYoUtrDvae41bmLuVcnYh4UsXfhB6BWOSaQ+l
l8aQwTfmV74szsEDcFkg038zQ6Q4c8iiurYp29nwEM7/mayBGOcv
-----END RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpgI5jWzjG7wmk8
V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAflET2EpILLera
I1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5ClzgnSptMenXFyhw
5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4HhCt7T7sA/UN
ahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqyrwjN3gkaa+1T
jLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABAoIBACuMmaXYz6OHmroI
HNCIH9E+F0UIUyVg4/1gj9uoqKvdAx04WPphRyRo8AXhgSOWmfb/UnCqX1fqVvj2
BfzwehsEzO9wp/aBT/3IzM6RQHPoI5DXX98prSY0SlRqr4RXi3CSOFN4duoLMOOI
mlzdXUKttVpSvJixerqQPeT7HnC18NBKOydFMYPdXsgWcMXvu2BuvRClIzsjlXKM
VP00BNRY3Oje6T9yl8N051jIZh48YD3yyEAVFKPOWaJVzUU/RRPOOdTb2Y3A1bek
IbCdurdzoEQoJxkeTuColnuL1jj2mpxIBskKYhPAMV5arYS0pZ0VAtjoGGCyn7gT
l/bkTVkCgYEA6EB15hzRD2iTTIFMtDBqw0l3vJWcuWPvwFZl6zculO8Cdsvx0cDZ
VbEXByA0+CG3q47/UrVqETRhtyuVnxuKrceKU8/zib1dvvTMNjeYLKosjyG49xO6
gDx7nVBwYHmQN/iEuWTobLg1vtSNyd99WgG4cFHvqF7kIJb2W0IaGrsCgYEAzL70
VHn9BUP3CGecoU8Fnck9/7GWhvGgFU58Q/dU3Jr8g6lroeDas9zQU2tCnJN0e7cr
13thq2kQQHTYCY4J6EUtjO89sNVx4bO83xqQhobZBwZXkE5QDWIKCbiYGRLAb1+f
AAEwIEdPBgM88YFHOU5YbPTYH8TLkJfxyvMonu0CgYEArGWE3n3PdVeT1zs3O52g
8jrrpVGNF1QmWCgJ2VKJwkW0F4iFhMRYzzH3vPNcPj+Q/cjUn4lIJWMzkWrJ0mP4
ScyPUm1PApRNLPy7RRd5XtYm40wN52F+k8fRnlFiSUqTEejoZFGR8Xm/c1qFsS6y
9ofGZ6F6ewmM3uAQGGd1xxcCgYBFhjoVTW8bkJ6b3gMTy2+Oyr0gzD7fB8FiOsp7
kcrhNke0tZz01ROuq7aZ/Pwbiv6s2+ApRZ4+xGheWs7ZP8AhfQwgpUR/fZs0FwJ1
h+G3rKaZeg/V0qHgSYA7GNGdAf8SUpf9OmoLK+urkQHqyAlVbkMcjG+vKfYt3Uqf
rb4HaQKBgQCxm1oz9QrmxWKJ4eYKHSsD9UPu4QZhltBECH1btgvTwAEmwuXaCcta
RaFNhMe609sQ+YVIxa9fK0MXBiq7DG6nSLGvnLfVEYo4nGe6EvL9nQ7IFZywJjTb
/Fw4rTMwT59VSWJdv8BPznV7Gk7p17fcXM55iJxxu65r3ZuOXjQSGA==
-----END RSA PRIVATE KEY-----
\ No newline at end of file
build/dev.ezijing.com.pem
浏览文件 @
cb6821b7
-----BEGIN CERTIFICATE-----
MIIHEDCCBfigAwIBAgIQC53CSHjB5MGsHDzx/2AxzjANBgkqhkiG9w0BAQsFADBb
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMRowGAYDVQQDExFTZWN1cmUgU2l0ZSBDQSBHMjAeFw0y
MDA2MTAwMDAwMDBaFw0yMjA5MTIxMjAwMDBaMFsxCzAJBgNVBAYTAkNOMRAwDgYD
VQQIEwdCZWlqaW5nMSIwIAYDVQQKExlUSEggWmlqaW5nIChCZWlqaW5nKSBJbmMu
MRYwFAYDVQQDDA0qLmV6aWppbmcuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAn0EINdIXTDCzmR7J5FOjOV+PbXt7GNO6fanoCGe2O0CPRlNf2Ea/
wv6SlRtJPd0ohmnKqZdUbBpAsiV4ggOdOqeEB6utVYQWY/zhXRKYeRjN/iDuWCRY
5S+eRVkSzVOJP9DlBn6dnHSsWj55h1PrkIac8B862F/cVno/Wk5dqU55ZUoNwHGw
5Goz3R37w+Q0C9HRS5mrmPqI+Ogy8TJrIRxw9YAj5OlvuqBAeYAW1sNdEfsimMB0
H2fbbXqEL4AsipE5ppP7Ij3vxVpxvmnl/SO7N6+Fit6r25VeFSvplK+PIV3cUsK3
PCKV2sOo0BDWtWFQh5hW3fK5RYjLpNDHCwIDAQABo4IDzjCCA8owHwYDVR0jBBgw
FoAUxBF+iECGwkG/ZfMa4bRTQKOr7H0wHQYDVR0OBBYEFHxjLRRYXe2jIjYECuN8
r3EnjOTFMCUGA1UdEQQeMByCDSouZXppamluZy5jb22CC2V6aWppbmcuY29tMA4G
A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwbwYD
VR0fBGgwZjAxoC+gLYYraHR0cDovL2NybDMuZGlnaWNlcnQuY29tL1NlY3VyZVNp
dGVDQUcyLmNybDAxoC+gLYYraHR0cDovL2NybDQuZGlnaWNlcnQuY29tL1NlY3Vy
ZVNpdGVDQUcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgGCCsGAQUF
BwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjBsBggr
BgEFBQcBAQRgMF4wIQYIKwYBBQUHMAGGFWh0dHA6Ly9vY3NwLmRjb2NzcC5jbjA5
BggrBgEFBQcwAoYtaHR0cDovL2NybC5kaWdpY2VydC1jbi5jb20vU2VjdXJlU2l0
ZUNBRzIuY3J0MAwGA1UdEwEB/wQCMAAwggH1BgorBgEEAdZ5AgQCBIIB5QSCAeEB
3wB2AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABcpwT21oAAAQD
AEcwRQIgWTyqiBOL3dFTJBE2Q6cgSBzk9W5iTaC2B8T1f8gFCP0CIQDhngm9WJbO
J7v14h6w+B2Li7WEAkWLSLiTKzh7na2SuQB1ACJFRQdZVSRWlj+hL/H3bYbgIyZj
rcBLf13Gg1xu4g8CAAABcpwT2zEAAAQDAEYwRAIgckmPL6WJx9Jke4AfVLmy//ye
tsmT5si8FO8p9Fd52VECICPqDvdjlN2DtfQznTGTxaL0PQ5N8eNiX3fJn6sRCfcU
AHYAUaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeUAAAFynBPbfQAABAMA
RzBFAiEAwYooscdEijXGnRdJYnz0ClmvWcxtJ169Bq+sywhPReACIDjvE5a5d7mb
n3YTgfLOtbnuDpkDRjUfdY7cs6UfderhAHYAQcjKsd8iRkoQxqE6CUKHXk4xixsD
6+tLx2jwkGKWBvYAAAFynBPa0wAABAMARzBFAiAmJVwNfWFMKrqWTvEfHk9O/5/r
Crj/W3BqjV6p0D09hgIhAIKb4drMok8s1X0Evh4Nbzd3Nv9PuwITdICztemCrk4e
MA0GCSqGSIb3DQEBCwUAA4IBAQBWSrE/pt//MKeGpf6vMISGD0LZArebPFQ7wlgv
Y13HpCY5lqwrZItsuXWS5IYMv8ueYarCm081OJOBvSUKHOtYSe6wdFqsXehokUiy
7oVNief7Li5RvLcf6z5fyjB+i017dds73Dt94mE1imV1DR1WErp1U6QCMEh+TKFa
PL52V9X5VWiYdImzdm8AWOlNBrgicmVzEEQuglejF5uaALf9iiyAjP36apqXv77T
UtxKgjONB1tnRw4XRqzwrEK+QjeOhziKCn1v2ppFX/Z11YYA7ajICVrG6wGJ+ENc
ukf5+v8r+TU7PqxQmb62zocX22jhe8HM644UJ4FWCiBh4Lb1
MIIGtjCCBZ6gAwIBAgIQDjUArTRdZ4P5wtQVmCqJGjANBgkqhkiG9w0BAQsFADBj
MQswCQYDVQQGEwJDTjE2MDQGA1UECgwtQmVpamluZyBYaW5jaGFjaGEgQ3JlZGl0
IE1hbmFnZW1lbnQgQ28uLCBMdGQuMRwwGgYDVQQDDBNYY2MgVHJ1c3QgT1YgU1NM
IENBMB4XDTIyMDgxODE0MDAzMVoXDTIzMDkxNzE0MDAzMFowgY4xCzAJBgNVBAYT
AkNOMRIwEAYDVQQIDAnljJfkuqzluIIxEjAQBgNVBAcMCeWMl+S6rOW4gjE/MD0G
A1UECgw25riF5o6n57Sr6I2G77yI5YyX5Lqs77yJ5pWZ6IKy56eR5oqA6IKh5Lu9
5pyJ6ZmQ5YWs5Y+4MRYwFAYDVQQDDA0qLmV6aWppbmcuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpg
I5jWzjG7wmk8V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAf
lET2EpILLeraI1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5Clzg
nSptMenXFyhw5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4
HhCt7T7sA/UNahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqy
rwjN3gkaa+1TjLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABo4IDODCC
AzQwDAYDVR0TAQH/BAIwADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8veGluY2hh
Y2hhMm92LmNybC5jZXJ0dW0ucGwveGluY2hhY2hhMm92LmNybDB5BggrBgEFBQcB
AQRtMGswLwYIKwYBBQUHMAGGI2h0dHA6Ly94aW5jaGFjaGEyb3Yub2NzcC1jZXJ0
dW0uY29tMDgGCCsGAQUFBzAChixodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwv
eGluY2hhY2hhMm92LmNlcjAfBgNVHSMEGDAWgBT6oMvCx12BtSCSByALtjtwOwkO
VTAdBgNVHQ4EFgQUEJufsd5nLNR+wqR2GsFWDn7qTn0wTAYDVR0gBEUwQzAIBgZn
gQwBAgIwNwYMKoRoAYb2dwIFARYCMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8vd3d3
LmNlcnR1bS5wbC9DUFMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4G
A1UdDwEB/wQEAwIFoDAlBgNVHREEHjAcgg0qLmV6aWppbmcuY29tggtlemlqaW5n
LmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYAVYHUwhaQNgFK6gubVzxT
8MDkOHhwJQgXL6OqHQcT0wwAAAGCsUFwdgAABAMARzBFAiAc51lynft4sehXTgyw
tjQ83PAVmfZ3FC55eIpIETe2hgIhANvo5ZtGQpcZQ5HSGbRLy4Y9/MbUrS8dtkwP
l7I/lRj7AHYArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooAAAGCsUFw
TwAABAMARzBFAiATnQDMw1wykBdnTIRfSSXPj7HZfDdRRq6VaiTbSpYKYQIhAMTp
V6K0W9gtdYGdeg4j6n17S1yMODYvLJxd3kAFFNDTAHYAejKMVNi3LbYg6jjgUh7p
hBZwMhOFTTvSK8E6V6NS61IAAAGCsUFwrQAABAMARzBFAiEAwWKXKxp6DcKG7R/d
rxmPUg8uNbUcdxysrpB3gOzkIlACICWpx7/+2ulDG2EC9m4RqGcXbts3VWu/yxpE
0pAYuAP8MA0GCSqGSIb3DQEBCwUAA4IBAQCf3AdKLO8EUntMjKaRa0lncwh/pBIQ
bcQfkJBfiTpo6tnRphR+DE50oYOX1TSQRm4cDgP2JURYiTK6Z2+ljqMbUx4mNLqe
+6yG+PGCUX6rX4BsJqlRP2W7WONE/I3/3S6MRfclKmakHSyrGFi8O/JJyNqm+5z9
8tnk8c1Cn7FboJZonhX0yszHkXLLeA93xm5+Etkw0+DvRcZGiEqKQivO3CnUh1gs
LZg27a8s3dtmAAHbb2icm5jloK9Jgpx/NkGL/cCoNZ8Ng2TZkRvo6GzIp43uS332
R07dQ6rNWZkPzdxKUdNcT0v3yJJyxD1H3Rk4/bxp78giw4JGHp52Df+U
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCA/6gAwIBAgIQCH4Y+4+qkn7odgoNiYL1EjANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xOTA2MjAxMjIxMzVaFw0yOTA2MjAxMjIxMzVaMFsxCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xGjAYBgNVBAMTEVNlY3VyZSBTaXRlIENBIEcyMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAx7s903fR6SgpA08UdhKEUIZHa2Ig7KPNkTtwMS1+08YS
5QSEDM4DQxy48jP8dZkyyU9J/0WCm8Nlv5ga7HOAxhdJcv+CPP4oadx8EbdrmjAH
rGOv64oHvt7Ina7uzLd3krqxd0doeuxRpTHvFAyjaUhxjSfZx0wh1f6W7prPm7V5
0VcTudj4rI+xtHXUcFAuFz4bcapTcru5aaZ1v6F2usMCMVM+xJxEZcsUM4uTxdIf
W5FUTI0dbP8NyZkr/WVzL59aGwBE4ZU0JKBlgEmtkFpLPR7JCzYunafu7nMk5YY2
6WDOmezpWDjzDxJ8xakizykWYT5gdJYE3ULlUe31WQIDAQABo4IBzjCCAcowHQYD
VR0OBBYEFMQRfohAhsJBv2XzGuG0U0Cjq+x9MB8GA1UdIwQYMBaAFAPeUDVW0Uy7
ZvCj4hsbw5eyPdFVMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAxBggrBgEFBQcBAQQlMCMwIQYI
KwYBBQUHMAGGFWh0dHA6Ly9vY3NwLmRjb2NzcC5jbjBEBgNVHR8EPTA7MDmgN6A1
hjNodHRwOi8vY3JsLmRpZ2ljZXJ0LWNuLmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
QS5jcmwwgc4GA1UdIASBxjCBwzCBwAYEVR0gADCBtzAoBggrBgEFBQcCARYcaHR0
cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBigYIKwYBBQUHAgIwfgx8QW55IHVz
ZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2Yg
dGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50IGxvY2F0ZWQgYXQgaHR0cHM6Ly93
d3cuZGlnaWNlcnQuY29tL3JwYS11YTANBgkqhkiG9w0BAQsFAAOCAQEAE+8lW5Yw
IuiRsHn4gYRRVbLmIypWwYH74lIXnQiALeUsUkWfW7KA0ARF1el3YaTAg8/r6zyX
eZTdlhndxKOKvO5N+rnHWJB6a3fJURn6e0I+rDzKV1Zacv2Vx/ZHLZmza/bp4Azi
BrDOiPlW/Ktj6ALQzAgq70Oytk9htLupBWPuplJDdyhGqb9RfQvWc1Fa1HwXdBQi
oJPibfMaYkHMY3pTbOv2rzMKEoZwHDHqyC73RI9JgqqiXHw0rIL8A1uL3IrymXEr
mycTqbSozQwiiEfb+cxzY82YaNzaLpJyIst0T2QmdDDngmyd2LEmm4NKeXRrcFRh
XDDFfpIn93B7JA==
MIIEzzCCA7egAwIBAgIRAPJECC2rqQ2ljHLp8pqTQK4wDQYJKoZIhvcNAQELBQAw
fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTAeFw0yMjA3MDEwNzQ4NDda
Fw0yNzA2MzAwNzQ4NDdaMGMxCzAJBgNVBAYTAkNOMTYwNAYDVQQKDC1CZWlqaW5n
IFhpbmNoYWNoYSBDcmVkaXQgTWFuYWdlbWVudCBDby4sIEx0ZC4xHDAaBgNVBAMM
E1hjYyBUcnVzdCBPViBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCz2nxSPEsMeRBdunf+KZ8CrJIj9DUWGVu05WWyES+QkMHzVHCZt8cB2Blp
qzHHqFsXSDHVzcMxDeXBbudmQwYbg5NpSwY9vJHPTl6vlAlK4UWN4+oPTgP9//RN
N6KLmK3kjZ2Zc9F3kFKVaziSwVNjVvneacoUnz6blwLLBc5QelQ8oDT0eEv0QBAY
I0T8pHDgcvWQqTBaRrOb80plDhYju464XbVhtOHvFCiBIkKnfUBnBfptWjGM8Kis
sq4r8YX35B/pioj9g1YX34MLt+5L3vvWXEb2aMiwwB1Z3bSeeiU3N8aMuSb9E9jp
zd0uhzRameU7jAIAr8uuunb7GUJ7AgMBAAGjggFhMIIBXTASBgNVHRMBAf8ECDAG
AQH/AgEAMB0GA1UdDgQWBBT6oMvCx12BtSCSByALtjtwOwkOVTAfBgNVHSMEGDAW
gBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0lBBYw
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9j
cmwuY2VydHVtLnBsL2N0bmNhLmNybDBrBggrBgEFBQcBAQRfMF0wKAYIKwYBBQUH
MAGGHGh0dHA6Ly9zdWJjYS5vY3NwLWNlcnR1bS5jb20wMQYIKwYBBQUHMAKGJWh0
dHA6Ly9yZXBvc2l0b3J5LmNlcnR1bS5wbC9jdG5jYS5jZXIwOgYDVR0gBDMwMTAv
BgRVHSAAMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8vd3d3LmNlcnR1bS5wbC9DUFMw
DQYJKoZIhvcNAQELBQADggEBACWzdb59JyYc/WivKUcTEZ+H8WOTuv3AiR6rPljB
QUEB/1kxIeBK+276WLJn0nFNFuT9QMUBo/iUvNvuRQqVjouuYB0Oea6zKQpeMWry
oYtbheW+5NYAbdl9tYE4MRRK9zBLMRrQz35q+XfgMInozidhNHCvuulWk38OMM51
O73z53+R1879nnoZZznoYnrnkISVDjlhe6OSMifvIJAwSYwH2z79Y6CTVgtqTDR9
793Gr7UUmk5ydoxClxnku7voTX8iJUPcuAjElxFrhSQoxm6uXXOfItEqGvLkWAcq
IC5mcyU9VpUg1YP+KkDMh+KQM7/k+2ka1em9hO+QHvJ08UQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEtDCCA5ygAwIBAgIRAJOShUABZXFflH8oj+/JmygwDQYJKoZIhvcNAQELBQAw
PjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHogby5vLjESMBAG
A1UEAxMJQ2VydHVtIENBMB4XDTA4MTAyMjEyMDczN1oXDTI3MDYxMDEwNDYzOVow
fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAOP7faNyusLwyRSH9WsBTuFuQAe6bSddf/dbLbNax1Ff
q6QypmGHtm4PhtIwApf412lXoRg5XWpkecYBWaw8MUo4fNIE0kso6CBfOweizE1z
2/OuT8dW1Vqnlon686to1COGWSfPCSe8rG5ygxwwct/gounS4XR1Gb0qnnsVVAQb
10M5rVUoxeIau/TA5K44STPMdoWfOUXSpJ7yEoxR+HzkLX/1rF/rFp+xLdG6zJFC
d0wlyZA4b9vwzPuOHpdZPtVgTuYFKO1JeRNLukjbL/ly0znK/h/YNHL1tEDPMQHD
7N4RLRddH7hQ0V4Zp2neBzMoylCV+adUy1SGUEWp+UkCAwEAAaOCAWswggFnMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAh2zcsH/yT2xc3tu5C84oQ3RnX3MFIG
A1UdIwRLMEmhQqRAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNw
LiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQYIDAQAgMA4GA1UdDwEB/wQEAwIB
BjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vY3JsLmNlcnR1bS5wbC9jYS5jcmww
aAYIKwYBBQUHAQEEXDBaMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1j
ZXJ0dW0uY29tMC4GCCsGAQUFBzAChiJodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0u
cGwvY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw
Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAI3m/UBmo0yc
p6uh2oTdHDAH5tvHLeyDoVbkHTwmoaUJK+h9Yr6ydZTdCPJ/KEHkgGcCToqPwzXQ
1aknKOrS9KsGhkOujOP5iH3g271CgYACEnWy6BdxqyGVMUZCDYgQOdNv7C9C6kBT
Yr/rynieq6LVLgXqM6vp1peUQl4E7Sztapx6lX0FKgV/CF1mrWHUdqx1lpdzY70a
QVkppV4ig8OLWfqaova9ML9yHRyZhpzyhTwd9yaWLy75ArG1qVDoOPqbCl60BMDO
TjksygtbYvBNWFA0meaaLNKQ1wmB1sCqXs7+0vehukvZ1oaOGR+mBkdCcuBWCgAc
eLmNzJkEN0k=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
src/api/exam_api.js
浏览文件 @
cb6821b7
...
...
@@ -5,13 +5,13 @@ export default class ExamAPI extends BaseAPI {
* 获取考试信息
* @param {[string]} examId resource_id
*/
getTopic
=
(
examId
)
=>
this
.
get
(
`/xexam/v1/exam/sheet/
${
examId
}
`
,
{})
getTopic
=
examId
=>
this
.
get
(
`/xexam/v1/exam/sheet/
${
examId
}
`
,
{})
/* 缓存考试 */
setCache
=
(
examId
=
{}
,
obj
=
{})
=>
this
.
post
(
`/xexam/v1/exam/cache/
${
examId
}
`
,
obj
,
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
setCache
=
(
examId
=
''
,
obj
=
{})
=>
this
.
post
(
`/xexam/v1/exam/cache/
${
examId
}
`
,
obj
,
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
/* 获取缓存 */
getCache
=
(
examId
)
=>
this
.
get
(
`/xexam/v1/exam/cache/
${
examId
}
`
,
{})
getCache
=
examId
=>
this
.
get
(
`/xexam/v1/exam/cache/
${
examId
}
`
,
{})
/* 缓存考试 */
endExam
=
(
examId
=
{}
,
obj
=
{})
=>
this
.
post
(
`/xexam/v1/exam/sheet/
${
examId
}
`
,
obj
,
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
endExam
=
(
examId
=
''
,
obj
=
{})
=>
this
.
post
(
`/xexam/v1/exam/sheet/
${
examId
}
`
,
obj
,
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
/**
* 进入考试
*/
...
...
src/api/login_api.js
浏览文件 @
cb6821b7
...
...
@@ -5,7 +5,7 @@ export default class TestAPI extends BaseAPI {
* 获取考试信息
* @param {[string]} examId resource_id
*/
getExamInfo
=
(
examId
)
=>
this
.
get
(
`/xexam/v1/exam/view/
${
examId
}
`
,
{})
getExamInfo
=
examId
=>
this
.
get
(
`/xexam/v1/exam/view/
${
examId
}
`
,
{})
/**
* 进入考试
*/
...
...
src/api/test_api.js
浏览文件 @
cb6821b7
...
...
@@ -5,14 +5,14 @@ export default class TestAPI extends BaseAPI {
* get传输方式
* @param {[string]} id resource_id
*/
getTest
=
(
id
)
=>
this
.
get
(
`/vue-client/get/
${
id
}
`
,
{})
getTest
=
id
=>
this
.
get
(
`/vue-client/get/
${
id
}
`
,
{})
/**
* post传输方式
* @param {[object]} obj
*/
postTest
=
(
obj
=
{})
=>
this
.
post
(
'/passport/rest/login'
,
obj
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
/**
* 当前登录用户,检测是否该系统有权限
*/
getInfo
=
()
=>
this
.
post
(
'/user_center/get_user_info'
,
{},
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
* 当前登录用户,检测是否该系统有权限
*/
getInfo
=
()
=>
this
.
post
(
'/user_center/get_user_info'
,
{},
{
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
}
})
}
src/components/exam/answerCard.vue
浏览文件 @
cb6821b7
...
...
@@ -3,14 +3,7 @@
<div
ref=
"wrapper"
>
<div
class=
"info"
>
<div
class=
"shape"
>
<img
:src=
"
info.id_photo
? info.id_photo
: 'https://zws-imgs-pub.ezijing.com/static/public/e0c63e4d4554f0852e1558426aad20d1.png'
"
alt=
""
/>
<img
:src=
"info.id_photo ? info.id_photo : 'https://zws-imgs-pub.ezijing.com/static/public/e0c63e4d4554f0852e1558426aad20d1.png'"
/>
</div>
<div
class=
"right"
>
<div
class=
"name"
>
{{
info
.
name
}}
</div>
...
...
@@ -132,8 +125,7 @@ export default {
info
:
{
type
:
Object
,
default
:
()
=>
{}
}
},
data
()
{
return
{
}
return
{}
},
mounted
()
{
if
(
!
this
.
isMobile
())
{
...
...
@@ -196,7 +188,7 @@ export default {
}
}
}
.order-scroll
{
.order-scroll
{
// max-height: 100px;
// overflow-y: scroll;
}
...
...
src/components/exam/question.vue
浏览文件 @
cb6821b7
...
...
@@ -7,21 +7,26 @@
<div
class=
"num"
>
{{
questionData
.
q_order
}}
/
{{
questionParams
.
question
.
total_question_count
}}
</div>
</div>
<div
class=
"title"
>
<div
class=
"num"
>
{{
questionData
.
q_order
}}
.
</div><div
class=
"des"
v-html=
"questionData.content"
></div>
<div
class=
"num"
>
{{
questionData
.
q_order
}}
.
</div>
<div
class=
"des"
v-html=
"questionData.content"
></div>
</div>
<!--
<div
class=
"describe"
></div>
-->
<ul
:class=
"questionData.question_item_type == 2 ? 'check-option' : 'radio-option'"
>
<template
v-for=
"(item, index) in questionData.options"
>
<li
:key=
"index"
:class=
"questionParams.answerRecord[questionData.question_item_id]
? questionParams.answerRecord[questionData.question_item_id][questionData.id]
? questionParams.answerRecord[questionData.question_item_id][questionData.id].answer.find(id =>
{ return id === item.id })
? 'active'
:class=
"
questionParams.answerRecord[questionData.question_item_id]
? questionParams.answerRecord[questionData.question_item_id][questionData.id]
? questionParams.answerRecord[questionData.question_item_id][questionData.id].answer.find(id =>
{
return id === item.id
})
? 'active'
: ''
: ''
: ''
: ''
"
>
"
>
<div
@
click=
"changeOptions(questionData.question_item_type, questionData.question_item_id, questionData.id, item.id)"
>
<div
class=
"icon"
></div>
<div
class=
"txt"
v-html=
"item.option"
></div>
...
...
@@ -37,9 +42,15 @@
<div
class=
"num"
>
{{
questionData
.
q_order
}}
/
{{
questionParams
.
question
.
total_question_count
}}
</div>
</div>
<div
class=
"title"
>
<div
class=
"num"
>
{{
questionData
.
q_order
}}
.
</div><div
class=
"des"
v-html=
"questionData.content"
></div>
<div
class=
"num"
>
{{
questionData
.
q_order
}}
.
</div>
<div
class=
"des"
v-html=
"questionData.content"
></div>
</div>
<el-input
@
input=
"QAChange(questionData.question_item_id, questionData.id, questionData.textContent)"
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"questionData.textContent"
></el-input>
<el-input
@
input=
"QAChange(questionData.question_item_id, questionData.id, questionData.textContent)"
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"questionData.textContent"
></el-input>
</
template
>
<!-- 复合题 -->
<
template
v-if=
"questionData.question_item_type == 5 || questionData.question_item_type == 7 || questionData.question_item_type == 8"
>
...
...
@@ -54,29 +65,35 @@
<template
v-for=
"(item, index) in questionData.list"
>
<li
:key=
"'type5' + index"
>
<div
:class=
"item.q_order === questionParams.questionIndex + 1 ? 'active title' : 'title'"
>
<div
class=
"num"
>
{{
item
.
q_order
}}
.
</div><div
class=
"des"
v-html=
"item.content"
></div>
<div
class=
"num"
>
{{
item
.
q_order
}}
.
</div>
<div
class=
"des"
v-html=
"item.content"
></div>
</div>
<div
v-if=
"item.type == 3"
@
click=
"changeIndex(item.q_order)"
>
<el-input
@
input=
"QAChildChange(questionData.question_item_id, item, item.answer)"
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"item.answer"
></el-input>
</div>
<!--
<el-input
@
input=
"QAChange(questionData.question_item_id, questionData.id)"
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"questionData.textContent"
></el-input>
-->
<ul
v-else
:class=
"item.type == 2 ? 'check-option' : 'radio-option'"
>
<!-- radio-option check-option -->
<ul
v-else
:class=
"item.type == 2 ? 'check-option' : 'radio-option'"
>
<!-- radio-option check-option -->
<template
v-if=
"item.options"
>
<template
v-for=
"(items, cIndex) in item.options"
>
<li
:id=
"items.id"
:key=
"'c' + cIndex"
:class=
"questionParams.answerRecord[questionData.question_item_id]
? questionParams.answerRecord[questionData.question_item_id][item.id]
? questionParams.answerRecord[questionData.question_item_id][item.id].answer.find(id =>
{ return id === items.id })
? 'active'
:class=
"
questionParams.answerRecord[questionData.question_item_id]
? questionParams.answerRecord[questionData.question_item_id][item.id]
? questionParams.answerRecord[questionData.question_item_id][item.id].answer.find(id =>
{
return id === items.id
})
? 'active'
: ''
: ''
: ''
: ''
"
>
"
>
<div
@
click=
"changeOptions(item.type, questionData.question_item_id, item.id, items.id, item.q_order)"
>
<div
class=
"icon"
></div>
<div
class=
"txt"
>
{{
items
.
option
}}
</div>
<div
class=
"txt"
>
{{
items
.
option
}}
</div>
</div>
</li>
</
template
>
...
...
@@ -94,8 +111,7 @@ import action from '@action'
import
Bus
from
'@/components/common/bus.js'
import
_
from
'lodash'
export
default
{
components
:
{
},
components
:
{},
props
:
{
contentHeight
:
{
type
:
Number
,
default
:
()
=>
{}
},
questionParams
:
{
type
:
Object
,
default
:
()
=>
{}
}
...
...
@@ -108,11 +124,26 @@ export default {
textarea
:
''
}
},
computed
:
{
examId
()
{
return
this
.
$route
.
params
.
examId
},
changeQuestionIndex
()
{
return
this
.
questionParams
.
questionIndex
}
},
watch
:
{
changeQuestionIndex
(
newV
,
oldV
)
{
this
.
dataCombined
()
this
.
signCallback
()
this
.
$nextTick
(()
=>
{
this
.
createTag
()
})
}
},
beforeDestroy
()
{
clearInterval
(
this
.
setCacheTime
)
},
created
()
{
},
mounted
()
{
clearInterval
(
this
.
setCacheTime
)
this
.
setCacheTime
=
setInterval
(()
=>
{
...
...
@@ -128,7 +159,9 @@ export default {
this
.
questionParams
.
question
.
question_items
.
map
((
item
,
index
)
=>
{
if
(
parseInt
(
item
.
question_item_type
)
===
5
||
parseInt
(
item
.
question_item_type
)
===
7
||
parseInt
(
item
.
question_item_type
)
===
8
)
{
item
.
question_list
.
map
(
cItem
=>
{
const
currentItem
=
cItem
.
list
.
find
(
items
=>
{
return
items
.
q_order
===
this
.
questionParams
.
questionIndex
+
1
})
const
currentItem
=
cItem
.
list
.
find
(
items
=>
{
return
items
.
q_order
===
this
.
questionParams
.
questionIndex
+
1
})
if
(
currentItem
)
{
this
.
questionData
=
{}
this
.
questionData
.
common_content
=
cItem
.
common_content
...
...
@@ -148,7 +181,7 @@ export default {
this
.
questionData
.
list
.
map
(
el
=>
{
if
(
el
.
type
===
3
)
{
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
this
.
questionParams
.
answerRecord
[
pId
][
el
.
id
]
?
el
.
answer
=
this
.
questionParams
.
answerRecord
[
pId
][
el
.
id
].
answer
[
0
]
:
el
.
answer
=
''
this
.
questionParams
.
answerRecord
[
pId
][
el
.
id
]
?
(
el
.
answer
=
this
.
questionParams
.
answerRecord
[
pId
][
el
.
id
].
answer
[
0
])
:
(
el
.
answer
=
''
)
}
else
{
el
.
answer
=
''
}
...
...
@@ -161,7 +194,9 @@ export default {
})
this
.
$forceUpdate
()
}
else
{
const
currentItem
=
item
.
question_list
.
find
(
items
=>
{
return
items
.
q_order
===
this
.
questionParams
.
questionIndex
+
1
})
const
currentItem
=
item
.
question_list
.
find
(
items
=>
{
return
items
.
q_order
===
this
.
questionParams
.
questionIndex
+
1
})
if
(
currentItem
)
{
this
.
questionData
=
currentItem
const
key
=
[
'question_item_id'
,
'question_item_title'
,
'question_item_type'
]
...
...
@@ -214,19 +249,15 @@ export default {
// 问答题回答
QAChange
(
pId
,
cId
,
length
)
{
// if (length.length
<
500
)
{
this
.
questionParams
.
answerRecord
[
pId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
=
[
this
.
questionData
.
textContent
]
:
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
this
.
questionData
.
textContent
],
sign
:
false
}
:
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
this
.
questionData
.
textContent
],
sign
:
false
}
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
cId
])
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
=
[
this
.
questionData
.
textContent
]
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
this
.
questionData
.
textContent
],
sign
:
false
}
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
this
.
questionData
.
textContent
],
sign
:
false
}
}
}
this
.
$forceUpdate
()
// } else {
// this.$message({
...
...
@@ -245,40 +276,32 @@ export default {
this
.
questionParams
.
questionIndex
=
order
-
1
}
if
(
parseInt
(
type
)
!==
2
)
{
this
.
questionParams
.
answerRecord
[
pId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
=
[
optId
]
:
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
optId
],
sign
:
false
}
:
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
optId
],
sign
:
false
}
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
cId
])
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
=
[
optId
]
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
optId
],
sign
:
false
}
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
optId
],
sign
:
false
}
}
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
?
(()
=>
{
const
optChack
=
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
findIndex
(
item
=>
{
return
item
===
optId
})
if
(
optChack
===
-
1
)
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
push
(
optId
)
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
splice
(
optChack
,
1
)
}
})()
:
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
optId
],
sign
:
false
}
:
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
optId
],
sign
:
false
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
cId
])
{
const
optCheck
=
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
findIndex
(
item
=>
{
return
item
===
optId
})
if
(
optCheck
===
-
1
)
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
push
(
optId
)
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
answer
.
splice
(
optCheck
,
1
)
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
answer
:
[
optId
],
sign
:
false
}
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
answer
:
[
optId
],
sign
:
false
}
}
}
}
Bus
.
$emit
(
'monitoringChanges'
)
this
.
$forceUpdate
()
...
...
@@ -287,27 +310,28 @@ export default {
const
param
=
{
answer
:
JSON
.
stringify
(
this
.
questionParams
.
answerRecord
)
}
action
.
Exam
.
setCache
(
this
.
$route
.
params
.
examId
,
param
).
then
(
res
=>
{
}).
catch
(
err
=>
{
// if (err.message.indexOf('error') !== -1) {
// this.$confirm('网络异常,请保持网络通畅', '提示', {
// confirmButtonText: '退出考试',
// cancelButtonText: '重新提交',
// type: 'warning'
// }).then(() => {
// this.$router.replace({
// path: `/login/${JSON.parse(window.localStorage.getItem('examInfo')).exam_id}`
// })
// }).catch(() => {
// this.endExamRequest()
// })
// } else {
// // this.$alert(err.message, {
// // callback: action => {}
// // })
// console.log(err.message)
// }
})
action
.
Exam
.
setCache
(
this
.
examId
,
param
)
.
then
(
res
=>
{})
.
catch
(
err
=>
{
// if (err.message.indexOf('error') !== -1) {
// this.$confirm('网络异常,请保持网络通畅', '提示', {
// confirmButtonText: '退出考试',
// cancelButtonText: '重新提交',
// type: 'warning'
// }).then(() => {
// this.$router.replace({
// path: `/login/${JSON.parse(window.localStorage.getItem('examInfo')).exam_id}`
// })
// }).catch(() => {
// this.endExamRequest()
// })
// } else {
// // this.$alert(err.message, {
// // callback: action => {}
// // })
// console.log(err.message)
// }
})
},
// 标记
onSignHandle
()
{
...
...
@@ -317,11 +341,7 @@ export default {
this
.
questionData
.
list
.
forEach
(
item
=>
{
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
].
sign
)
{
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
].
sign
=
false
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
].
sign
=
true
}
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
].
sign
=
!
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
].
sign
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
item
.
id
]
=
{
sign
:
true
,
answer
:
[]
}
}
...
...
@@ -330,21 +350,15 @@ export default {
}
})
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
=
false
:
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
=
true
:
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
sign
:
true
,
answer
:
[]
}
:
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
sign
:
true
,
answer
:
[]
}
if
(
this
.
questionParams
.
answerRecord
[
pId
])
{
if
(
this
.
questionParams
.
answerRecord
[
pId
][
cId
])
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
=
!
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
}
else
{
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
=
{
sign
:
true
,
answer
:
[]
}
}
}
else
{
this
.
questionParams
.
answerRecord
[
pId
]
=
{
[
cId
]:
{
sign
:
true
,
answer
:
[]
}
}
}
}
this
.
signCallback
()
},
...
...
@@ -354,9 +368,9 @@ export default {
let
isSign
=
false
this
.
questionParams
.
answerRecord
[
pId
]
?
this
.
questionParams
.
answerRecord
[
pId
][
cId
]
?
isSign
=
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
:
isSign
=
false
:
isSign
=
false
?
(
isSign
=
this
.
questionParams
.
answerRecord
[
pId
][
cId
].
sign
)
:
(
isSign
=
false
)
:
(
isSign
=
false
)
this
.
$emit
(
'isSign'
,
isSign
)
Bus
.
$emit
(
'monitoringChanges'
)
},
...
...
@@ -383,78 +397,65 @@ export default {
$
(
'body'
).
append
(
script2
)
$
(
'body'
).
append
(
script
)
}
},
computed
:
{
changeQuestionIndex
()
{
return
this
.
questionParams
.
questionIndex
}
},
watch
:
{
changeQuestionIndex
(
newV
,
oldV
)
{
this
.
dataCombined
()
this
.
signCallback
()
this
.
$nextTick
(()
=>
{
this
.
createTag
()
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
::v-deep
{
.el-textarea__inner
{
::v-deep
{
.el-textarea__inner
{
height
:
150px
;
}
}
.title-type
{
.title-type
{
width
:
100%
;
height
:
45px
;
border-bottom
:
1px
solid
#ccc
;
border-bottom
:
1px
solid
#ccc
;
display
:
flex
;
align-items
:
center
;
.type
{
.type
{
font-size
:
18px
;
color
:
#222222
;
}
.num
{
.num
{
margin-left
:
auto
;
font-size
:
18px
;
color
:
#222222
;
}
}
.title
{
.title
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
25px
;
display
:
flex
;
.num
{
.num
{
font-size
:
32px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
45px
;
margin-top
:
5px
;
}
.des
{
.des
{
margin-left
:
5px
;
padding-top
:
18px
;
&
:
:
v-deep
p
{
&
:
:
v-deep
p
{
margin
:
0
;
}
}
}
.describe
{
.describe
{
font-size
:
18px
;
color
:
#222222
;
line-height
:
25px
;
margin-top
:
20px
;
}
.radio-option
,
.check-option
{
.radio-option
,
.check-option
{
padding
:
24px
0
0
0
;
margin
:
0
;
list-style
:
none
;
li
{
li
{
// cursor: pointer;
margin-bottom
:
20px
;
// display: flex;
...
...
@@ -463,7 +464,7 @@ export default {
div
{
float
:
left
;
cursor
:
pointer
;
.icon
{
.icon
{
width
:
18px
;
height
:
18px
;
border
:
1px
solid
#999999
;
...
...
@@ -471,14 +472,14 @@ export default {
margin-top
:
3px
;
float
:
left
;
}
.txt
{
.txt
{
max-width
:
95%
;
font-size
:
18px
;
color
:
#222222
;
line-height
:
28px
;
margin-left
:
10px
;
float
:
left
;
&
:
:
v-deep
p
{
&
:
:
v-deep
p
{
margin
:
0
;
}
}
...
...
@@ -497,36 +498,36 @@ export default {
// line-height: 28px;
// margin-left: 10px;
// }
&
.active
{
.icon
{
&
.active
{
.icon
{
width
:
8px
;
height
:
8px
;
border
:
6px
solid
#
C
01540
;
border
:
6px
solid
#
c
01540
;
}
}
}
}
.check-option
{
.icon
{
.check-option
{
.icon
{
border-radius
:
3px
!
important
;
}
}
.case-que
{
::v-deep
{
img
{
.case-que
{
::v-deep
{
img
{
display
:
block
;
width
:
100%
;
width
:
100%
;
}
}
display
:
flex
;
.stem
{
.stem
{
flex
:
1
;
font-size
:
14px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
28px
;
}
.topics
{
.topics
{
flex
:
1
;
margin
:
0
;
padding
:
0
0
0
20px
;
...
...
@@ -536,19 +537,19 @@ export default {
&
:
:-
webkit-scrollbar
{
display
:
none
;
}
li
{
.title
{
li
{
.title
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
25px
;
&
.active
{
&
.active
{
color
:
#c01540
;
.num
{
.num
{
color
:
#c01540
!
important
;
}
}
span
{
span
{
font-size
:
32px
;
font-weight
:
bold
;
color
:
#222222
;
...
...
src/index.html
浏览文件 @
cb6821b7
...
...
@@ -11,7 +11,7 @@
<!-- <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> -->
<!-- <meta http-equiv="Pragma" content="no-cache" /> -->
<!-- <meta http-equiv="Expires" content="0" /> -->
<title>
标题
</title>
<title></title>
<meta
name=
"viewport"
id=
"viewport"
content=
"initial-scale=-1,maximum-scale=1,shrink-to-fit=no,user-scalable=no"
/>
</head>
<body>
...
...
src/pages/exam/examAnswer.vue
浏览文件 @
cb6821b7
...
...
@@ -25,12 +25,7 @@
</div>
</div>
<div
:class=
"isMobile() ? 'right scroll' : 'right hidden'"
ref=
"wrapper"
>
<answer-card
:questionParams=
"questionParams"
:changeTime=
"changeTime"
:info=
"sInfo.info"
@
switchQuestion=
"switchQuestion"
></answer-card>
<answer-card
:questionParams=
"questionParams"
:changeTime=
"changeTime"
:info=
"studentInfo"
@
switchQuestion=
"switchQuestion"
></answer-card>
</div>
<ul
class=
"flag-tips"
>
<li>
...
...
@@ -56,10 +51,7 @@
<div
@
click=
"changeIndex('prev')"
:class=
"this.questionParams.questionIndex !== 0 ? 'active' : ''"
>
上一题
</div>
<div
:class=
"questionParams.questionIndex + 1 !== questionParams.question.total_question_count ? 'active' : ''"
@
click=
"changeIndex('next')"
>
<div
:class=
"questionParams.questionIndex + 1 !== questionParams.question.total_question_count ? 'active' : ''"
@
click=
"changeIndex('next')"
>
下一题
</div>
</div>
...
...
@@ -91,7 +83,7 @@ import BScroll from 'better-scroll'
export
default
{
metaInfo
()
{
return
{
title
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
.
name
||
''
title
:
this
.
examInfo
.
name
||
''
}
},
components
:
{
...
...
@@ -100,14 +92,23 @@ export default {
'my-dia'
:
dialogComponent
},
data
()
{
let
studentInfo
=
{}
let
examInfo
=
{}
try
{
studentInfo
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'studentInfo'
))
examInfo
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
}
catch
(
error
)
{
console
.
log
(
error
)
}
return
{
isExamEnd
:
false
,
isExamTimeDate
:
true
,
itemSign
:
false
,
examTime
:
'00:00:00 倒计时'
,
clearTime
:
null
,
s
Info
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'studentInfo'
))
,
examInfo
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
,
s
tudentInfo
,
examInfo
,
title
:
'提示'
,
prompt
:
'确定后要结束本次考试?还有作答时间,结束考试后,将不能返回本次考试!'
,
isPopup
:
false
,
...
...
@@ -125,6 +126,20 @@ export default {
}
}
},
computed
:
{
examId
()
{
return
this
.
$route
.
params
.
examId
||
this
.
examInfo
.
exam_id
},
changeQuestionIndex
()
{
return
this
.
questionParams
.
questionIndex
}
},
watch
:
{
changeQuestionIndex
(
newV
,
oldV
)
{
this
.
refreshBscroll
()
}
},
mounted
()
{
// this.sendExamInfo(3)
this
.
setTick
()
...
...
@@ -149,8 +164,8 @@ export default {
},
sendExamInfo
(
status
)
{
const
param
=
{
student_id
:
this
.
s
Info
.
i
nfo
.
student_id
,
exam_id
:
this
.
examI
nfo
.
exam_i
d
,
student_id
:
this
.
s
tudentI
nfo
.
student_id
,
exam_id
:
this
.
examId
,
status
:
status
}
action
.
Login
.
sendExamInfo
(
param
)
...
...
@@ -160,9 +175,7 @@ export default {
})
},
countHeight
()
{
this
.
contentHeight
=
parseInt
(
document
.
body
.
clientHeight
-
(
this
.
getDom
(
'head-h'
).
offsetHeight
+
this
.
getDom
(
'foot-h'
).
offsetHeight
)
)
this
.
contentHeight
=
parseInt
(
document
.
body
.
clientHeight
-
(
this
.
getDom
(
'head-h'
).
offsetHeight
+
this
.
getDom
(
'foot-h'
).
offsetHeight
))
},
// 标记
signHandle
()
{
...
...
@@ -178,12 +191,7 @@ export default {
this
.
$alert
(
'考试时间到'
,
{
confirmButtonText
:
'确定'
,
callback
:
action
=>
{
this
.
$router
.
replace
({
path
:
'/examEnd'
,
query
:
{
id
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
)).
exam_id
}
})
this
.
$router
.
replace
({
path
:
'/examEnd'
,
query
:
{
id
:
this
.
examId
}
})
}
})
}
else
{
...
...
@@ -229,7 +237,7 @@ export default {
const
param
=
{
answer
:
JSON
.
stringify
(
this
.
questionParams
.
answerRecord
)
}
action
.
Exam
.
endExam
(
this
.
$route
.
params
.
examId
,
param
).
then
(
res
=>
{
action
.
Exam
.
endExam
(
this
.
examId
,
param
).
then
(
res
=>
{
if
(
!
n
)
{
clearInterval
(
this
.
clearTime
)
this
.
$router
.
replace
({
...
...
@@ -249,7 +257,7 @@ export default {
// })
// .then(() => {
// this.$router.replace({
// path: `/login/${
JSON.parse(window.localStorage.getItem('examInfo')).exam_i
d}`
// path: `/login/${
this.examI
d}`
// })
// })
// .catch(action => {
...
...
@@ -263,18 +271,18 @@ export default {
// })
},
countDown
(
time
)
{
const
left
t
ime
=
parseInt
(
time
/
1000
)
const
h
=
this
.
addZero
(
parseInt
((
left
t
ime
/
(
60
*
60
))
%
24
))
const
m
=
this
.
addZero
(
parseInt
((
left
t
ime
/
60
)
%
60
))
const
s
=
this
.
addZero
(
parseInt
(
left
t
ime
%
60
))
const
left
T
ime
=
parseInt
(
time
/
1000
)
const
h
=
this
.
addZero
(
parseInt
((
left
T
ime
/
(
60
*
60
))
%
24
))
const
m
=
this
.
addZero
(
parseInt
((
left
T
ime
/
60
)
%
60
))
const
s
=
this
.
addZero
(
parseInt
(
left
T
ime
%
60
))
this
.
examTime
=
`
${
h
}
:
${
m
}
:
${
s
}
倒计时`
},
setTick
()
{
let
flag
=
true
this
.
clearTime
=
setInterval
(()
=>
{
const
now
t
ime
=
new
Date
()
const
end
t
ime
=
new
Date
(
this
.
examInfo
.
end_time
.
replace
(
/-/g
,
'/'
))
const
countTime
=
end
time
.
getTime
()
-
nowt
ime
.
getTime
()
const
now
T
ime
=
new
Date
()
const
end
T
ime
=
new
Date
(
this
.
examInfo
.
end_time
.
replace
(
/-/g
,
'/'
))
const
countTime
=
end
Time
.
getTime
()
-
nowT
ime
.
getTime
()
if
(
countTime
<=
0
)
{
this
.
isExamTimeDate
=
false
clearInterval
(
this
.
clearTime
)
...
...
@@ -305,8 +313,7 @@ export default {
if
(
type
===
'prev'
)
{
this
.
questionParams
.
questionIndex
>
0
&&
this
.
questionParams
.
questionIndex
--
}
else
{
this
.
questionParams
.
questionIndex
+
1
!==
this
.
questionParams
.
question
.
total_question_count
&&
this
.
questionParams
.
questionIndex
++
this
.
questionParams
.
questionIndex
+
1
!==
this
.
questionParams
.
question
.
total_question_count
&&
this
.
questionParams
.
questionIndex
++
}
this
.
refreshBscroll
()
},
...
...
@@ -322,7 +329,7 @@ export default {
this
.
refreshBscroll
()
},
getTopic
()
{
action
.
Exam
.
getTopic
(
this
.
$route
.
params
.
examId
)
action
.
Exam
.
getTopic
(
this
.
examId
)
.
then
(
res
=>
{
this
.
questionParams
.
question
=
res
this
.
getCache
()
...
...
@@ -333,8 +340,8 @@ export default {
})
},
getCache
()
{
if
(
this
.
$route
.
params
.
examId
)
{
action
.
Exam
.
getCache
(
this
.
$route
.
params
.
examId
)
if
(
this
.
examId
)
{
action
.
Exam
.
getCache
(
this
.
examId
)
.
then
(
res
=>
{
const
data
=
JSON
.
parse
(
res
.
answer
)
if
(
data
!==
null
&&
data
!==
'null'
)
{
...
...
@@ -371,16 +378,6 @@ export default {
const
isPc
=
!
isPhone
&&
!
isAndroid
&&
!
isSymbian
return
isPc
}
},
computed
:
{
changeQuestionIndex
()
{
return
this
.
questionParams
.
questionIndex
}
},
watch
:
{
changeQuestionIndex
(
newV
,
oldV
)
{
this
.
refreshBscroll
()
}
}
}
</
script
>
...
...
src/pages/login/confirmInfo.vue
浏览文件 @
cb6821b7
...
...
@@ -17,26 +17,16 @@
<li
:key=
"index"
v-else-if=
"item.key == 'educational_background'"
>
<div
class=
"name"
>
学历
</div>
<el-select
v-model=
"form.educational_background"
placeholder=
"请选择"
style=
"width:100%"
v-if=
"item.enabled_edit"
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
<el-select
disabled
v-model=
"form.educational_background"
placeholder=
"请选择"
style=
"width:100%"
v-else
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</li>
<li
:key=
"index"
v-else
>
<div
class=
"name"
>
{{
item
.
name
}}
</div>
<input
:type=
"typeInput(item.key)"
v-model=
"form[item.key]"
@
keydown=
"keydown($event)"
v-if=
"item.enabled_edit"
>
<input
:type=
"typeInput(item.key)"
v-model=
"form[item.key]"
@
keydown=
"keydown($event)"
disabled
v-else
>
<input
:type=
"typeInput(item.key)"
v-model=
"form[item.key]"
@
keydown=
"keydown($event)"
v-if=
"item.enabled_edit"
/
>
<input
:type=
"typeInput(item.key)"
v-model=
"form[item.key]"
@
keydown=
"keydown($event)"
disabled
v-else
/
>
</li>
</
template
>
</ul>
...
...
@@ -68,13 +58,22 @@ import action from '@action'
export
default
{
metaInfo
()
{
return
{
title
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
.
name
||
''
title
:
this
.
examInfo
.
name
||
''
}
},
data
()
{
let
studentInfo
=
{}
let
examInfo
=
{}
try
{
studentInfo
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'studentInfo'
))
examInfo
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
}
catch
(
error
)
{
console
.
log
(
error
)
}
return
{
s
Info
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'studentInfo'
))
,
examInfo
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
))
||
{}
,
s
tudentInfo
,
examInfo
,
form
:
{
educational_background
:
''
},
...
...
@@ -109,18 +108,11 @@ export default {
this
.
setInput
()
this
.
defaultInto
()
},
mounted
()
{
// console.log(this.examInfo.config.info)
},
computed
:
{
typeInput
()
{
return
(
k
)
=>
{
const
type
=
k
===
'age'
||
k
===
'mobile'
?
'number'
:
'text'
return
type
}
}
},
methods
:
{
typeInput
(
k
)
{
const
type
=
k
===
'age'
||
k
===
'mobile'
?
'number'
:
'text'
return
type
},
setInput
()
{
const
key
=
Object
.
keys
(
this
.
examInfo
.
config
.
info
)
const
value
=
Object
.
values
(
this
.
examInfo
.
config
.
info
)
...
...
@@ -141,28 +133,19 @@ export default {
})
},
// 禁止input输入空格
keydown
(
event
)
{
keydown
(
event
)
{
event
.
keyCode
===
32
&&
(
event
.
returnValue
=
false
)
},
agree
()
{
// 判断考试时间开始没有
// console.log(this.isExamStatus(this.examInfo.start_time > 0))
this
.
isExamStatus
(
this
.
examInfo
.
start_time
)
>
0
?
(()
=>
{
this
.
$router
.
replace
({
path
:
'/examTime'
})
})()
:
(()
=>
{
this
.
$router
.
replace
({
path
:
`/examAnswer/
${
this
.
examInfo
.
exam_id
}
`
})
})()
if
(
this
.
isExamStatus
(
this
.
examInfo
.
start_time
)
>
0
)
{
this
.
$router
.
replace
({
path
:
'/examTime'
})
}
else
{
this
.
$router
.
replace
({
path
:
`/examAnswer/
${
this
.
examInfo
.
exam_id
}
`
})
}
},
disagree
()
{
this
.
$router
.
replace
({
path
:
`/login/
${
this
.
examInfo
.
exam_id
}
`
})
this
.
$router
.
replace
({
path
:
`/login/
${
this
.
examInfo
.
exam_id
}
`
})
},
// 判断进入考试页面还是倒计时页面
isExamStatus
(
date
)
{
...
...
@@ -183,37 +166,34 @@ export default {
defaultInto
()
{
const
key
=
Object
.
keys
(
this
.
form
)
key
.
map
(
item
=>
{
this
.
form
[
item
]
=
item
===
'age'
?
parseInt
(
this
.
sInfo
.
info
[
item
])
===
0
?
''
:
this
.
sInfo
.
info
[
item
]
:
this
.
sInfo
.
info
[
item
]
this
.
form
[
item
]
=
item
===
'age'
?
(
parseInt
(
this
.
studentInfo
[
item
])
===
0
?
''
:
this
.
studentInfo
[
item
])
:
this
.
studentInfo
[
item
]
})
},
// 确认信息
confirmInfo
()
{
if
(
this
.
verification
())
{
action
.
Login
.
confirmInfo
(
this
.
examInfo
.
exam_id
,
this
.
form
).
then
(
res
=>
{
if
(
!
res
.
code
)
{
this
.
isTreaty
=
true
window
.
localStorage
.
setItem
(
'studentInfo'
,
JSON
.
stringify
(
res
))
}
}).
catch
(
err
=>
{
if
(
parseInt
(
err
.
status
)
===
403
)
{
this
.
$alert
(
err
.
message
,
{
callback
:
action
=>
{
this
.
$router
.
replace
({
path
:
`/login/
${
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
)).
exam_id
}
`
})
}
})
}
else
{
this
.
$alert
(
err
.
message
,
{
callback
:
action
=>
{
}
})
}
})
action
.
Login
.
confirmInfo
(
this
.
examInfo
.
exam_id
,
this
.
form
)
.
then
(
res
=>
{
if
(
!
res
.
code
)
{
this
.
isTreaty
=
true
window
.
localStorage
.
setItem
(
'studentInfo'
,
JSON
.
stringify
(
res
.
info
))
}
})
.
catch
(
err
=>
{
if
(
parseInt
(
err
.
status
)
===
403
)
{
this
.
$alert
(
err
.
message
,
{
callback
:
action
=>
{
this
.
$router
.
replace
({
path
:
`/login/
${
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
)).
exam_id
}
`
})
}
})
}
else
{
this
.
$alert
(
err
.
message
,
{
callback
:
action
=>
{}
})
}
})
}
},
// 验证信息是否为空
...
...
@@ -231,13 +211,13 @@ export default {
return
false
}
else
{
if
(
this
.
allForm
[
i
].
key
===
'mobile'
)
{
if
(
!
(
/^1
[
3456789
]\d{9}
$/
.
test
(
this
.
form
.
mobile
)
))
{
if
(
!
/^1
[
3456789
]\d{9}
$/
.
test
(
this
.
form
.
mobile
))
{
this
.
$alert
(
'手机号格式不正确'
)
return
false
}
}
if
(
this
.
allForm
[
i
].
key
===
'email'
)
{
if
(
!
(
/^
([
a-zA-Z
\d])(\w)
+@
[
a-zA-Z
\d]
+
\.[
a-zA-Z
]{2,4}
$/
.
test
(
this
.
form
.
email
)
))
{
if
(
!
/^
([
a-zA-Z
\d])(\w)
+@
[
a-zA-Z
\d]
+
\.[
a-zA-Z
]{2,4}
$/
.
test
(
this
.
form
.
email
))
{
this
.
$alert
(
'邮箱格式不正确'
)
return
false
}
...
...
@@ -247,13 +227,13 @@ export default {
}
else
{
if
(
this
.
form
[
this
.
allForm
[
i
].
key
]
!==
''
)
{
if
(
this
.
allForm
[
i
].
key
===
'mobile'
)
{
if
(
!
(
/^1
[
3456789
]\d{9}
$/
.
test
(
this
.
form
.
mobile
)
))
{
if
(
!
/^1
[
3456789
]\d{9}
$/
.
test
(
this
.
form
.
mobile
))
{
this
.
$alert
(
'手机号格式不正确'
)
return
false
}
}
if
(
this
.
allForm
[
i
].
key
===
'email'
)
{
if
(
!
(
/^
([
a-zA-Z
\d])(\w)
+@
[
a-zA-Z
\d]
+
\.[
a-zA-Z
]{2,4}
$/
.
test
(
this
.
form
.
email
)
))
{
if
(
!
/^
([
a-zA-Z
\d])(\w)
+@
[
a-zA-Z
\d]
+
\.[
a-zA-Z
]{2,4}
$/
.
test
(
this
.
form
.
email
))
{
this
.
$alert
(
'邮箱格式不正确'
)
return
false
}
...
...
@@ -267,42 +247,42 @@ export default {
}
</
script
>
<
style
lang=
"scss"
scoped
>
.box
{
.box
{
display
:
flex
;
justify-content
:
center
;
background
:
url(../../assets/images/con-info-bg.png)
center
;
background-size
:
cover
;
background-attachment
:fixed
;
background-attachment
:
fixed
;
background-position
:
0
0
;
padding-bottom
:
100px
;
min-height
:
100%
;
}
.confirm-mian
{
.confirm-mian
{
width
:
100%
;
height
:
100%
;
}
.con-info
{
.con-info
{
width
:
100%
;
height
:
100%
;
.head
{
.head
{
position
:
sticky
;
top
:
0
;
height
:
80px
;
background
:
#
FFFFFF
;
background
:
#
ffffff
;
font-size
:
24px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
80px
;
padding-left
:
30px
;
}
.info-form
{
.info-form
{
height
:
max-content
;
margin-top
:
40px
;
width
:
400px
;
background
:
#
FFFFFF
;
background
:
#
ffffff
;
border-radius
:
8px
;
padding-bottom
:
30px
;
.tit
{
.tit
{
text-align
:
center
;
margin-top
:
30px
;
font-size
:
18px
;
...
...
@@ -310,48 +290,48 @@ export default {
color
:
#222222
;
line-height
:
25px
;
}
ul
{
ul
{
width
:
320px
;
margin
:
0
auto
0
auto
;
padding
:
0
;
list-style
:
none
;
li
{
li
{
margin-bottom
:
20px
;
.name
{
.name
{
font-size
:
14px
;
color
:
#222222
;
line-height
:
20px
;
margin-bottom
:
10px
;
}
input
{
input
{
width
:
310px
;
height
:
45px
;
border-radius
:
2px
;
border
:
1px
solid
#
F1F1F
1
;
border
:
1px
solid
#
f1f1f
1
;
font-size
:
14px
;
color
:
#222222
;
padding
:
0
0
0
10px
;
outline
:
none
;
}
.select-btn
{
.select-btn
{
width
:
100%
;
display
:
flex
;
div
{
div
{
width
:
150px
;
height
:
40px
;
border-radius
:
4px
;
border
:
1px
solid
#
CCCCCC
;
border
:
1px
solid
#
cccccc
;
font-size
:
14px
;
font-weight
:
bold
;
color
:
#999999
;
line-height
:
14px
;
text-align
:
center
;
line-height
:
40px
;
&
:nth-child
(
2
)
{
&
:nth-child
(
2
)
{
margin-left
:
auto
;
}
&
.active
{
background
:
#
C
01540
;
&
.active
{
background
:
#
c
01540
;
color
:
#fff
;
border
:
none
;
}
...
...
@@ -359,80 +339,82 @@ export default {
}
}
}
.confirm-btn
{
.confirm-btn
{
width
:
320px
;
height
:
40px
;
background
:
#
C
01540
;
background
:
#
c
01540
;
border-radius
:
4px
;
font-size
:
14px
;
font-weight
:
bold
;
color
:
#
FFFFFF
;
color
:
#
ffffff
;
line-height
:
14px
;
margin
:
0
auto
;
text-align
:
center
;
line-height
:
40px
;
margin-top
:
30px
;
cursor
:
pointer
;
}
}
}
.explain-box
{
.explain-box
{
width
:
100%
;
min-height
:
100%
;
background
:
#
F9F9F
9
;
.head
{
background
:
#
f9f9f
9
;
.head
{
height
:
80px
;
background
:
#
FFFFFF
;
background
:
#
ffffff
;
font-size
:
24px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
80px
;
padding-left
:
30px
;
}
.exp-text
{
.exp-text
{
width
:
900px
;
background
:
#
FFFFFF
;
background
:
#
ffffff
;
border-radius
:
8px
;
padding
:
40px
40px
80px
;
margin
:
40px
auto
0
;
margin-top
:
40px
;
.t
{
.t
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#222222
;
line-height
:
25px
;
display
:
flex
;
&
:
:
v-deep
p
{
&
:
:
v-deep
p
{
margin
:
0
;
}
}
}
.exp-btn
{
.exp-btn
{
position
:
absolute
;
bottom
:
40px
;
left
:
50%
;
-webkit-
transform
:
translateX
(
-50%
);
.tips
{
transform
:
translateX
(
-50%
);
.tips
{
font-size
:
14px
;
color
:
#222222
;
line-height
:
20px
;
}
.btn-box
{
.btn-box
{
width
:
240px
;
display
:
flex
;
margin
:
20px
auto
0
;
div
{
div
{
width
:
100px
;
height
:
40px
;
background
:
#
C
01540
;
background
:
#
c
01540
;
border-radius
:
4px
;
font-size
:
14px
;
font-weight
:
bold
;
color
:
#
FFFFFF
;
color
:
#
ffffff
;
line-height
:
40px
;
text-align
:
center
;
&
:nth-child
(
2
)
{
cursor
:
pointer
;
&
:nth-child
(
2
)
{
border-radius
:
4px
;
border
:
1px
solid
#
CCCCCC
;
border
:
1px
solid
#
cccccc
;
background
:
none
;
color
:
#999
;
margin-left
:
auto
;
...
...
@@ -441,7 +423,7 @@ export default {
}
}
}
.none
{
.none
{
display
:
none
;
}
</
style
>
src/pages/login/index.vue
浏览文件 @
cb6821b7
...
...
@@ -13,20 +13,8 @@
<div
:class=
"loginParam.is ? 'form prohibit' : 'form'"
>
<div
class=
"tips"
>
{{
tips
}}
</div>
<!-- 您登录的次数已超过最大限制 -->
<input
type=
"text"
v-model=
"examineeNumber"
placeholder=
"请输入准考证号"
v-show=
"!loginParam.is"
@
keydown=
"keydown($event)"
/>
<input
type=
"text"
placeholder=
"请输入准考证号"
readonly=
"readonly"
class=
"prohibit"
v-show=
"loginParam.is"
/>
<input
type=
"text"
v-model=
"examineeNumber"
placeholder=
"请输入准考证号"
v-show=
"!loginParam.is"
@
keydown=
"keydown($event)"
/>
<input
type=
"text"
placeholder=
"请输入准考证号"
readonly=
"readonly"
class=
"prohibit"
v-show=
"loginParam.is"
/>
<div
class=
"btn"
@
click=
"login"
>
登录
</div>
<!--
<div
class=
"btn prohibit"
>
登录
</div>
-->
<div
class=
"time-tips"
v-show=
"loginParam.is"
>
{{
loginParam
.
countTimeText
}}
</div>
...
...
@@ -34,7 +22,7 @@
</div>
</div>
</div>
<div
class=
"welcome-msg mian-cont900"
v-if=
"data"
v-html=
"data.config.welcome_message"
></div>
<div
class=
"welcome-msg mian-cont900"
v-if=
"data
&& data.config
"
v-html=
"data.config.welcome_message"
></div>
</div>
</
template
>
<
script
>
...
...
@@ -46,16 +34,16 @@ export default {
},
metaInfo
()
{
return
{
title
:
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'examInfo'
)).
name
||
''
title
:
this
.
data
.
name
}
},
data
()
{
return
{
tips
:
''
,
cl
ae
rExamTime
:
null
,
cl
ea
rExamTime
:
null
,
title
:
'提示'
,
prompt
:
'不能退出全屏'
,
data
:
''
,
data
:
{}
,
examineeNumber
:
''
,
isPopup
:
false
,
loginParam
:
{
...
...
@@ -65,6 +53,11 @@ export default {
}
}
},
computed
:
{
examId
()
{
return
this
.
$route
.
params
.
examId
}
},
mounted
()
{
this
.
getExamInfo
()
this
.
tipsMobileAngle
()
...
...
@@ -78,10 +71,7 @@ export default {
const
winWidth
=
window
.
innerWidth
||
document
.
documentElement
.
clientWidth
||
document
.
body
.
clientWidth
||
0
const
winHeight
=
window
.
innerHeight
||
document
.
documentElement
.
clientHeight
||
document
.
body
.
clientHeight
||
0
if
(
winHeight
>
winWidth
)
{
this
.
$message
({
message
:
'请横屏预览'
,
type
:
'warning'
})
this
.
$message
({
message
:
'请横屏预览'
,
type
:
'warning'
})
}
}
},
...
...
@@ -89,19 +79,19 @@ export default {
return
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
.
test
(
navigator
.
userAgent
)
},
getExamInfo
()
{
action
.
Login
.
getExamInfo
(
this
.
$route
.
params
.
examId
).
then
(
res
=>
{
action
.
Login
.
getExamInfo
(
this
.
examId
).
then
(
res
=>
{
window
.
localStorage
.
setItem
(
'examInfo'
,
JSON
.
stringify
(
res
))
this
.
data
=
res
if
(
this
.
getEnabledTime
()
<
0
)
{
this
.
examTimeInit
()
}
else
{
let
cl
a
earTimes
=
null
cl
a
earTimes
=
setInterval
(()
=>
{
let
clearTimes
=
null
clearTimes
=
setInterval
(()
=>
{
// console.log(this.getAfterTime())
if
(
this
.
getAfterTime
()
<=
0
)
{
this
.
tips
=
'超过登录时间'
this
.
loginParam
.
is
=
true
clearInterval
(
cl
a
earTimes
)
clearInterval
(
clearTimes
)
}
},
1000
)
this
.
loginParam
.
is
=
false
...
...
@@ -109,11 +99,7 @@ export default {
})
},
sendExamInfo
(
studentId
)
{
const
param
=
{
student_id
:
studentId
,
exam_id
:
this
.
data
.
exam_id
,
status
:
2
}
const
param
=
{
student_id
:
studentId
,
exam_id
:
this
.
examId
,
status
:
2
}
action
.
Login
.
sendExamInfo
(
param
)
.
then
(
res
=>
{})
.
catch
(
err
=>
{
...
...
@@ -126,25 +112,23 @@ export default {
},
getAfterTime
()
{
const
curTime
=
new
Date
()
const
end
t
Time
=
new
Date
(
this
.
data
.
end_time
)
const
countTime
=
end
t
Time
.
getTime
()
-
curTime
.
getTime
()
const
endTime
=
new
Date
(
this
.
data
.
end_time
)
const
countTime
=
endTime
.
getTime
()
-
curTime
.
getTime
()
return
countTime
},
getEnabledTime
()
{
const
curTime
=
new
Date
()
const
setCurTime
=
this
.
data
.
config
.
enabled_before
?
new
Date
(
curTime
.
setMinutes
(
curTime
.
getMinutes
()
+
this
.
data
.
config
.
before_login
))
:
curTime
const
setCurTime
=
this
.
data
.
config
.
enabled_before
?
new
Date
(
curTime
.
setMinutes
(
curTime
.
getMinutes
()
+
this
.
data
.
config
.
before_login
))
:
curTime
const
startTime
=
new
Date
(
this
.
data
.
start_time
)
const
countTime
=
setCurTime
.
getTime
()
-
startTime
.
getTime
()
return
countTime
},
examTimeInit
()
{
this
.
loginParam
.
is
=
true
this
.
cl
ae
rExamTime
=
setInterval
(()
=>
{
this
.
cl
ea
rExamTime
=
setInterval
(()
=>
{
const
date
=
this
.
getEnabledTime
()
if
(
date
>=
0
)
{
clearInterval
(
this
.
cl
ae
rExamTime
)
clearInterval
(
this
.
cl
ea
rExamTime
)
this
.
loginParam
.
is
=
false
}
else
{
this
.
countDown
(
Math
.
abs
(
date
))
...
...
@@ -156,21 +140,23 @@ export default {
},
// 倒计时
countDown
(
time
)
{
const
left
t
ime
=
parseInt
(
time
/
1000
)
const
left
T
ime
=
parseInt
(
time
/
1000
)
const
datSec
=
24
*
60
*
60
const
hourSer
=
60
*
60
const
minuteSec
=
60
const
dd
=
Math
.
floor
(
lefttime
/
datSec
)
const
hh
=
Math
.
floor
((
lefttime
%
datSec
)
/
hourSer
)
const
mm
=
Math
.
floor
((
lefttime
%
hourSer
)
/
minuteSec
)
const
ss
=
lefttime
%
minuteSec
this
.
loginParam
.
countTimeText
=
dd
>
0
?
`距离开考还有:
${
dd
}
天
${
this
.
addZero
(
hh
)}
时
${
this
.
addZero
(
mm
)}
分
${
this
.
addZero
(
ss
)}
秒`
:
`距离开考还有:
${
this
.
addZero
(
hh
)}
时
${
this
.
addZero
(
mm
)}
分
${
this
.
addZero
(
ss
)}
秒`
const
dd
=
Math
.
floor
(
leftTime
/
datSec
)
const
hh
=
Math
.
floor
((
leftTime
%
datSec
)
/
hourSer
)
const
mm
=
Math
.
floor
((
leftTime
%
hourSer
)
/
minuteSec
)
const
ss
=
leftTime
%
minuteSec
this
.
loginParam
.
countTimeText
=
dd
>
0
?
`距离开考还有:
${
dd
}
天
${
this
.
addZero
(
hh
)}
时
${
this
.
addZero
(
mm
)}
分
${
this
.
addZero
(
ss
)}
秒`
:
`距离开考还有:
${
this
.
addZero
(
hh
)}
时
${
this
.
addZero
(
mm
)}
分
${
this
.
addZero
(
ss
)}
秒`
},
// 开启全屏
fullScreen
()
{
const
el
=
document
.
documentElement
const
rfs
=
el
.
requestFullScreen
||
el
.
webkitRequestFullScreen
||
el
.
mozRequestFullScreen
||
el
.
msRequestFullscreen
const
rfs
=
el
.
requestFullScreen
||
el
.
webkitRequestFullScreen
||
el
.
mozRequestFullScreen
||
el
.
msRequestFullscreen
if
(
typeof
rfs
!==
'undefined'
&&
rfs
)
{
rfs
.
call
(
el
)
}
...
...
@@ -189,17 +175,16 @@ export default {
this
.
$alert
(
'请输入准考证号'
)
return
false
}
action
.
Login
.
userLogin
(
this
.
data
.
exam_i
d
,
{
examinee_number
:
this
.
examineeNumber
})
action
.
Login
.
userLogin
(
this
.
examI
d
,
{
examinee_number
:
this
.
examineeNumber
})
.
then
(
res
=>
{
window
.
localStorage
.
setItem
(
'studentInfo'
,
JSON
.
stringify
(
res
))
window
.
localStorage
.
setItem
(
'studentInfo'
,
JSON
.
stringify
(
res
.
info
))
const
status
=
parseInt
(
res
.
sheet_status
)
// this.sendExamInfo(res.info.student_id)
if
(
status
===
0
)
{
this
.
$router
.
replace
({
name
:
'confirmInfo'
}
)
this
.
$router
.
push
({
name
:
'confirmInfo'
,
params
:
{
examId
:
this
.
examId
}
})
}
else
if
(
status
===
1
)
{
this
.
$alert
(
'已提交考卷'
)
}
status
===
1
&&
this
.
$alert
(
'已提交考卷'
)
})
.
catch
(
err
=>
{
if
(
err
.
message
.
indexOf
(
'error'
)
!==
-
1
)
{
...
...
@@ -232,7 +217,7 @@ export default {
position
:
absolute
;
bottom
:
0
;
left
:
50%
;
-webkit-
transform
:
translateX
(
-50%
);
transform
:
translateX
(
-50%
);
margin-bottom
:
-115px
;
}
}
...
...
@@ -335,6 +320,7 @@ export default {
line-height
:
40px
;
text-align
:
center
;
font-style
:
normal
;
cursor
:
pointer
;
&
.prohibit
{
color
:
#ccc
;
background
:
#eee
;
...
...
src/router/routes.js
浏览文件 @
cb6821b7
export
default
[
{
path
:
'/'
,
redirect
:
'*'
},
/* 测试页面 */
...
...
@@ -6,7 +5,7 @@ export default [
/* 登录页面 */
{
path
:
'/login/:examId'
,
component
:
()
=>
import
(
'../pages/login/index.vue'
)
},
/* 确认信息 */
{
path
:
'/confirmInfo'
,
name
:
'confirmInfo'
,
component
:
()
=>
import
(
'../pages/login/confirmInfo.vue'
)
},
{
path
:
'/confirmInfo
/:examId
'
,
name
:
'confirmInfo'
,
component
:
()
=>
import
(
'../pages/login/confirmInfo.vue'
)
},
/* 考试倒计时 */
{
path
:
'/examTime'
,
name
:
'examTime'
,
component
:
()
=>
import
(
'../pages/exam/examTime.vue'
)
},
/* 答题 */
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论