@zykjcommon/questions 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.env.production +2 -1
  2. package/.env.test +2 -1
  3. package/dist/zykjcommon-questions.common.js +14850 -2485
  4. package/dist/zykjcommon-questions.css +1 -1
  5. package/dist/zykjcommon-questions.umd.js +14851 -2494
  6. package/dist/zykjcommon-questions.umd.min.js +24 -1
  7. package/package.json +2 -2
  8. package/src/App.vue +2 -0
  9. package/src/assets/js/fun.js +23 -2
  10. package/src/assets/js/http.js +1 -1
  11. package/src/assets/scss/questions/index.scss +85 -22
  12. package/src/components/common/IframeComponent.vue +60 -76
  13. package/src/components/common/Loading.vue +9 -20
  14. package/src/components/common/TextAreaEditor.vue +72 -87
  15. package/src/components/exam/QuestionCard.vue +3 -3
  16. package/src/components/questions/QuestionReader.js +4 -4
  17. package/src/components/questions/Question_BriefAnswer.vue +146 -0
  18. package/src/components/questions/Question_FillBlank.vue +151 -0
  19. package/src/components/questions/Question_MultipleChoice.vue +179 -0
  20. package/src/components/questions/Question_Programming.vue +285 -0
  21. package/src/components/questions/Question_Reading.vue +173 -0
  22. package/src/components/questions/Question_SingleChoice.vue +7 -21
  23. package/src/components/questions/buildEntry.js +130 -5
  24. package/src/components/questions/const.js +15 -0
  25. package/src/components/questions/developmentEntry.js +130 -5
  26. package/src/components/questions/entry.js +2 -19
  27. package/src/components/questions/store.js +44 -0
  28. package/src/main.ts +17 -13
  29. package/src/views/exam/Analysis.vue +620 -7
  30. package/src/views/exam/Exam.vue +612 -11
  31. package/vue.config.js +8 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zykjcommon/questions",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "main": "src/components/questions/entry.js",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -12,7 +12,7 @@
12
12
  "build:lib": "vue-cli-service build --target lib src/components/questions/buildEntry.js --name zykjcommon-questions"
13
13
  },
14
14
  "dependencies": {
15
- "@zykjcommon/questions": "^0.0.11",
15
+ "@zykjcommon/questions": "^0.0.13",
16
16
  "alife-logger": "^1.8.30",
17
17
  "axios": "^0.26.0",
18
18
  "cookie": "^0.4.1",
package/src/App.vue CHANGED
@@ -27,6 +27,8 @@ export default {
27
27
  VUE_APP_VERSION:process.env.VUE_APP_VERSION
28
28
  }),
29
29
  mounted() {
30
+ let token = fun.getToken()
31
+ this.setToken(token)
30
32
  },
31
33
  watch:{
32
34
  }
@@ -3,6 +3,8 @@
3
3
  ****************************************************/
4
4
  // import {postWeb} from "./http.js";
5
5
  // import helper from "./helper";
6
+ import Vue from "vue";
7
+
6
8
  /**
7
9
  * 字典排序
8
10
  * @param <Object> dict
@@ -777,8 +779,8 @@ function closeContentDialogByUid(uid){
777
779
 
778
780
  let getToken = function() {
779
781
  // let token = getQueryVariable('a')
780
- // let token = helper.cookieUtils.getItem('token',true)
781
- // return token;
782
+ let token = '962b31f683668129f8b9f3716777c132j63rxr0z'
783
+ return token;
782
784
  };
783
785
 
784
786
  function getQueryVariable(variable)
@@ -843,7 +845,26 @@ function fbError(message, source, lineno, colno, error) {
843
845
  }
844
846
 
845
847
 
848
+ function getVueVersion(){
849
+ let version = ''
850
+ /*if(!Vue){
851
+ if(createApp){
852
+ let v = createApp({})
853
+ version = v.version
854
+ }else{
855
+ version = 'undefined'
856
+ }
857
+ }else{
858
+ version = Vue.version || 'undefined'
859
+ }*/
860
+ let Vue = require('vue')
861
+ Vue = Vue.default || Vue
862
+ version = Vue.version || 'undefined'
863
+ return version
864
+ }
865
+
846
866
  export default {
867
+ getVueVersion,
847
868
  getToken,
848
869
  getQueryVariable,
849
870
  debounce2,
@@ -27,7 +27,7 @@ let createSign = function(method, URL, param, ClientTimestamp) {
27
27
  let StringToSign =
28
28
  method +
29
29
  "\n" +
30
- "/education"+URL +
30
+ "/student-web"+URL +
31
31
  "\n" +
32
32
  ClientTimestamp +
33
33
  "\n" +
@@ -135,28 +135,6 @@
135
135
  margin-top: 10px;
136
136
  }
137
137
  }
138
- .editor-textarea{
139
- margin-top: 15px;
140
- position: relative;
141
- display: inline-block;
142
- width: 100%;
143
- textarea{
144
- font-size: 14px;
145
- min-width: 100%;max-width: 100%;min-height: 107px;
146
- padding: 15px;
147
- outline-color: #FFBC00;
148
- border-radius: 6px;
149
- border: 1px solid #DFDFDF;
150
- color:#000;
151
- }
152
- .len{
153
- right: 10px;
154
- bottom: 10px;
155
- position: absolute;
156
- color:#999999;
157
- font-size: 12px;
158
- }
159
- }
160
138
  .question-analysis{
161
139
  position: relative;
162
140
  margin-top: 16px;
@@ -265,6 +243,91 @@
265
243
  min-width: 80px;
266
244
  margin-right:5px;
267
245
  }
246
+
247
+ .question-tabs{
248
+ margin-top: 20px;
249
+ display: flex;
250
+ flex-wrap: wrap;
251
+ width: 100%;
252
+ margin-bottom: -15px;
253
+ .question-tab-item{
254
+ cursor: pointer;
255
+ border-radius: 6px;
256
+ width: 80px;
257
+ height: 36px;
258
+ line-height: 36px;
259
+ text-align: center;
260
+ border:1px solid #999;
261
+ position: relative;
262
+ margin-right: 5px;
263
+ margin-bottom: 10px;
264
+ &:hover{
265
+ border:1px solid #FF7D30;
266
+ }
267
+ &.cur{
268
+ border:1px solid #ddd;
269
+ background: #ddd;
270
+ &:before{
271
+ content:' ';
272
+ display: inline-block;
273
+ border-top:8px solid #ddd;
274
+ border-left:8px solid transparent;
275
+ border-right:8px solid transparent;
276
+ width: 0;
277
+ height: 0;
278
+ position:absolute;
279
+ bottom: -6px;
280
+ }
281
+ &:hover{
282
+ border:1px solid #ddd;
283
+ }
284
+ }
285
+ .tab-mark{
286
+ position: absolute;
287
+ width: 20px;
288
+ height: 20px;
289
+ background:url("~@src/assets/img/tab-mark.png") no-repeat center;
290
+ background-size: 100% 100%;
291
+ right: -3px;
292
+ top: -5px;
293
+ }
294
+ }
295
+ }
296
+ .editor-textarea{
297
+ margin-top: 15px;
298
+ position: relative;
299
+ display: inline-block;
300
+ width: 100%;
301
+ textarea{
302
+ font-size: 14px;
303
+ min-width: 100%;max-width: 100%;min-height: 107px;
304
+ padding: 15px;
305
+ outline-color: #FFBC00;
306
+ border-radius: 6px;
307
+ border: 1px solid #DFDFDF;
308
+ color:#000;
309
+ }
310
+ .len{
311
+ right: 10px;
312
+ bottom: 10px;
313
+ position: absolute;
314
+ color:#999999;
315
+ font-size: 12px;
316
+ }
317
+ }
318
+
319
+ .iframeBox{
320
+ z-index:100;
321
+ width: 100%;
322
+ height: 100%;
323
+ position: fixed;
324
+ left: 0;
325
+ top: 0;
326
+ iframe{
327
+ width: 100%;
328
+ height: 100%;
329
+ }
330
+ }
268
331
  }
269
332
 
270
333
  .imgLookerDialog{
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <teleport to="#app">
2
+ <!-- <teleport to="#app">
3
3
  <div class="iframeBox">
4
4
  <iframe :src ="iframeUrl"
5
5
  id="codeIframe"
@@ -10,92 +10,76 @@
10
10
  <p>Your browser does not support iframes.</p>
11
11
  </iframe>
12
12
  </div>
13
- </teleport>
14
- <Loading :loading="loading"></Loading>
13
+ </teleport>-->
14
+ <div>
15
+ <div class="iframeBox">
16
+ <iframe :src ="iframeUrl"
17
+ id="codeIframe"
18
+ loop
19
+ allow="microphone;camera;midi;encrypted-media;unsized-media;vr;xr-spatial-tracking;autoplay"
20
+ frameborder="0"
21
+ >
22
+ <p>Your browser does not support iframes.</p>
23
+ </iframe>
24
+ </div>
25
+ <Loading :loading="loading"></Loading>
26
+ </div>
15
27
  </template>
16
28
 
17
- <script lang="ts">
18
- import {defineComponent, toRefs, reactive, onMounted, onUnmounted} from 'vue'
19
- interface dataInterface{
20
- loading:boolean
21
- }
22
- export default defineComponent({
29
+ <script>
30
+ import Loading from "./Loading.vue";
31
+ export default {
23
32
  props: {
24
33
  iframeUrl:{
25
34
  type:String,
26
35
  default:''
27
36
  }
28
37
  },
29
- emits:['uploadCodingFileSuccess','close','closeAndSave','iframeLoaded','getQuestionInfo','saveCodeOnly'],
30
- setup(props, context) {
31
- let iframe:any = null
32
- let data:dataInterface = reactive({
33
- loading:true
34
- })
35
-
36
-
37
-
38
- function iframeLoadEvent(){
39
- data.loading = false
40
- context.emit('iframeLoaded',iframe)
41
- }
42
-
43
- function messageEvent(data:any){
44
- // let iframeOrigin = ''+window.location.protocol+'//'+props.iframeUrl.replace(/^(http|https):\/\//g,'').split('/')[0];
45
- // if(data.origin===iframeOrigin){
46
- //判断是否json字符串
47
- if(typeof(data.data)==='string'){
48
- try {
49
- let obj = JSON.parse(data.data)
50
- context.emit(obj.type,obj.data)
51
- } catch(e) {
52
- let res = data.data
53
- context.emit(res,data)
54
- }
38
+ data() {
39
+ return {
40
+ loading:true,
41
+ iframe:null
42
+ };
43
+ },
44
+ mounted() {
45
+ this.iframe = document.getElementById('codeIframe')
46
+ this.iframe.addEventListener('load',this.iframeLoadEvent)
47
+ window.addEventListener('message',this.messageEvent)
48
+ },
49
+ unmounted() {
50
+ this.removeIframeEvents()
51
+ },
52
+ destroyed() {
53
+ this.removeIframeEvents()
54
+ },
55
+ methods:{
56
+ iframeLoadEvent(){
57
+ this.loading = false
58
+ this.$emit('iframeLoaded',this.iframe)
59
+ },
60
+ messageEvent(data){
61
+ if(typeof(data.data)==='string'){
62
+ try {
63
+ let obj = JSON.parse(data.data)
64
+ this.$emit(obj.type,obj.data)
65
+ } catch(e) {
66
+ let res = data.data
67
+ this.$emit(res,data)
55
68
  }
56
- // }
57
- }
58
-
59
-
60
-
61
- function removeIframeEvents(){
62
- iframe && iframe.removeEventListener('load',iframeLoadEvent)
63
- window.removeEventListener('message',messageEvent)
64
- }
65
-
66
-
67
- onMounted(()=>{
68
- iframe = document.getElementById('codeIframe')
69
- iframe.addEventListener('load',iframeLoadEvent)
70
- window.addEventListener('message',messageEvent)
71
- })
72
-
73
- onUnmounted(()=>{
74
- removeIframeEvents()
75
- })
76
-
69
+ }
70
+ },
71
+ removeIframeEvents(){
72
+ this.iframe && this.iframe.removeEventListener('load',this.iframeLoadEvent)
73
+ window.removeEventListener('message',this.messageEvent)
74
+ },
77
75
 
78
-
79
-
80
-
81
- return {
82
- ...toRefs(data)
83
- }
76
+ },
77
+ components:{
78
+ Loading
84
79
  }
85
- })
80
+ }
86
81
  </script>
87
82
 
88
- <style scoped lang="scss">
89
- .iframeBox{
90
- z-index:100;
91
- width: 100%;
92
- height: 100%;
93
- position: fixed;
94
- left: 0;
95
- top: 0;
96
- iframe{
97
- width: 100%;
98
- height: 100%;
99
- }
100
- }
83
+ <style scoped>
84
+
101
85
  </style>
@@ -1,36 +1,25 @@
1
1
  <template>
2
- <teleport to="body">
3
- <img class="loading" src="~@src/assets/img/loading.gif" alt="" v-if="loading">
4
- </teleport>
2
+ <div class="loading-box">
3
+ <img class="loading" src="../../assets/img/loading.gif" alt="" v-if="loading">
4
+ </div>
5
5
  </template>
6
6
 
7
- <script lang="ts">
8
- import {defineComponent, toRefs, reactive, onMounted, onUnmounted} from 'vue'
9
- interface dataInterface{
10
-
11
- }
12
- export default defineComponent({
7
+ <script>
8
+ export default {
13
9
  props: {
14
10
  loading:{
15
11
  type:Boolean,
16
12
  default:false
17
13
  }
18
14
  },
19
- setup(props, context) {
20
- let data:dataInterface = reactive({
21
-
22
- })
23
-
24
-
25
-
15
+ data() {
26
16
  return {
27
- ...toRefs(data)
28
- }
17
+ };
29
18
  }
30
- })
19
+ }
31
20
  </script>
32
21
 
33
- <style scoped lang="scss">
22
+ <style scoped>
34
23
  .loading{
35
24
  width: 50px;
36
25
  height: 50px;
@@ -8,25 +8,9 @@
8
8
  <div class="len">{{textareaStr.length}}/5000</div>
9
9
  </div>
10
10
  </template>
11
+ <script>
11
12
 
12
- <script lang="ts">
13
- import {
14
- defineComponent,
15
- onMounted,
16
- onUnmounted,
17
- reactive,
18
- ref,
19
- toRef,
20
- toRefs,
21
- watch,
22
- onActivated,
23
- onDeactivated,
24
- getCurrentInstance
25
- } from 'vue'
26
- interface dataInterface{
27
- textareaStr:string
28
- }
29
- export default defineComponent({
13
+ export default {
30
14
  props: {
31
15
  placeHolder:{
32
16
  type:String,
@@ -41,81 +25,82 @@ export default defineComponent({
41
25
  default:false
42
26
  }
43
27
  },
44
- setup(props, context) {
45
- let data:dataInterface = reactive({
46
- textareaStr:'',
47
- })
48
- const currentInstance:any = getCurrentInstance()
49
- let _this = currentInstance.proxy
50
- let observer:any
51
- onMounted(()=>{
52
- let textareaComponent = _this.$el.querySelector('.textareaComponent')
53
- let ele = textareaComponent as HTMLElement
54
- let textareaInitH = textareaComponent.clientHeight
55
- const MutationObserver = window.MutationObserver|| window.WebKitMutationObserver || window.MozMutationObserver
56
- const config = { attributes: true, childList: false, subtree: true, attributeFilter:['style'],attributeOldValue:true };
57
- observer = new MutationObserver( (mutationsList, observer) => {
58
- let appNode = document.querySelector('.content-outter')
59
- if(appNode){
60
- let height = parseInt(getComputedStyle(ele).getPropertyValue('height'))
61
- let scrollDistance = height - textareaInitH
62
- // console.log(scrollDistance,appNode.scrollTop);
63
- appNode.scrollTop = appNode.scrollTop + scrollDistance
64
- // if(scrollDistance > 0){
65
- // console.log(scrollDistance,appNode.scrollTop);
66
- // appNode.scrollTop = appNode.scrollTop + scrollDistance
67
- // }
68
- textareaInitH = height
69
- }
70
- });
71
- observer.observe(ele, config);
72
- })
73
-
74
- onUnmounted(()=>{
75
- observer && observer.disconnect()
76
- })
77
-
78
- watch(() => data.textareaStr, (nv) => {
79
- context.emit("getTextareaStr", nv);
80
- })
28
+ mounted() {
29
+ let textareaComponent = this.$el.querySelector('.textareaComponent')
30
+ let initTextAreaWidth = parseInt(getComputedStyle(textareaComponent).getPropertyValue('width'))
31
+ // console.log(initTextAreaWidth,2211);
32
+ let ele = textareaComponent
33
+ let textareaInitH = textareaComponent.clientHeight
34
+ const MutationObserver = window.MutationObserver|| window.WebKitMutationObserver || window.MozMutationObserver
35
+ const config = { attributes: true, childList: false, subtree: true, attributeFilter:['style'],attributeOldValue:true };
36
+ this.observer = new MutationObserver( (mutationsList, observer) => {
37
+ let appNode = document.querySelector('.content-outter')
38
+ if(appNode){
39
+ let height = parseInt(getComputedStyle(ele).getPropertyValue('height'))
40
+ let scrollDistance = height - textareaInitH
41
+ appNode.scrollTop = appNode.scrollTop + scrollDistance
42
+ textareaInitH = height
43
+ }
81
44
 
82
- watch(() => props.value, (nv) => {
83
- if(nv){
84
- data.textareaStr = nv
45
+ let curTextAreaWidth = parseInt(getComputedStyle(textareaComponent).getPropertyValue('width'))
46
+ // console.log(initTextAreaWidth,curTextAreaWidth,2233);
47
+ //自定义拉伸到宽度比容器还长后,把宽度固定到容器宽度
48
+ if(curTextAreaWidth > initTextAreaWidth){
49
+ textareaComponent.style.width = initTextAreaWidth + 'px'
85
50
  }
51
+ });
52
+ this.observer.observe(ele, config);
53
+
54
+ this.$watch('textareaStr',(nv)=>{
55
+ this.$emit("getTextareaStr", nv);
86
56
  },{
87
57
  immediate:true
88
58
  })
89
-
90
-
91
-
59
+ },
60
+ unmounted() {
61
+ this.observer && this.observer.disconnect()
62
+ },
63
+ destroyed() {
64
+ this.observer && this.observer.disconnect()
65
+ },
66
+ data() {
92
67
  return {
93
- ...toRefs(data)
68
+ observer:null,
69
+ textareaStr:''
70
+ };
71
+ },
72
+ watch: {
73
+ value:{
74
+ handler(nv,ov){
75
+ if(nv){
76
+ this.textareaStr = nv
77
+ }
78
+ },
79
+ immediate:true
80
+ }
81
+ },
82
+ computed:{
83
+ },
84
+ methods: {
85
+ getAnswer(){
86
+ let self = this
87
+ return {multiple_index_set:self.checkboxList}
88
+ },
89
+ isAnswered(){
90
+ let answerd = this.checkboxList.length !== 0
91
+ return answerd
92
+ },
93
+ isCorrect(){
94
+ let correct = this.questionInfo.answerMap.is_correct === '1' ? true : false
95
+ return correct
96
+ },
97
+ getCorrectStr(correct_multiple_index_set){
98
+ let str = ''
99
+ correct_multiple_index_set.forEach((item,index)=>{
100
+ str += `${fun.indexToEnIndex(item)}${index === correct_multiple_index_set.length -1?'':'、'}`
101
+ })
102
+ return str
94
103
  }
95
104
  }
96
- })
105
+ };
97
106
  </script>
98
-
99
- <!-- Add "scoped" attribute to limit CSS to this component only -->
100
- <style lang="scss" scoped>
101
- .editor-textarea{
102
- margin-top: 15px;
103
- position: relative;
104
- display: inline-block;
105
- textarea{
106
- font-size: 18px;min-width: 800px;max-width: 1600px;min-height: 300px;
107
- padding: 10px 15px 15px 15px;
108
- outline-color: deepskyblue;
109
- }
110
- .len{
111
- right: 15px;
112
- bottom: 4px;
113
- position: absolute;
114
- color:blue;
115
- font-weight: bold;
116
-
117
- }
118
- }
119
-
120
-
121
- </style>
@@ -280,9 +280,9 @@ export default defineComponent({
280
280
  let t = 1000 * 60
281
281
  // let t = 1000 * 2
282
282
  clearAutoTimer()
283
- data.autoSubmitTimer = setInterval(()=>{
284
- submitQuestion(0)
285
- },t)
283
+ // data.autoSubmitTimer = setInterval(()=>{
284
+ // submitQuestion(0)
285
+ // },t)
286
286
  }
287
287
 
288
288
  function btnQuit(){
@@ -3,19 +3,19 @@
3
3
  */
4
4
  import '../../assets/scss/questions/index.scss';
5
5
  import Question_SingleChoice from './Question_SingleChoice.vue'
6
- // import Question_MultipleChoice from '@src/components/questions/Question_MultipleChoice.vue'
6
+ import Question_MultipleChoice from './Question_MultipleChoice.vue'
7
7
  // import Question_Programming from '@src/components/questions/Question_Programming.vue'
8
8
  // import Question_BriefAnswer from '@src/components/questions/Question_BriefAnswer.vue'
9
- // import Question_Reading from '@src/components/questions/Question_Reading.vue'
9
+ import Question_Reading from './Question_Reading.vue'
10
10
  // import Question_FillBlank from '@src/components/questions/Question_FillBlank.vue'
11
11
 
12
12
 
13
13
 
14
14
  export default {
15
15
  Question_SingleChoice,
16
- // Question_MultipleChoice,
16
+ Question_MultipleChoice,
17
17
  // Question_Programming,
18
18
  // Question_BriefAnswer,
19
- // Question_Reading,
19
+ Question_Reading,
20
20
  // Question_FillBlank
21
21
  }