Explorar el Código

Merge branch 'develop' of http://163.228.141.122:3000/TEAMMODEL/TEAMModelOS into develop

jeff hace 3 meses
padre
commit
89fa4c059d

+ 5 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamViews/src/view/admin/ActivityManage.less

@@ -239,6 +239,7 @@
         position: absolute;
         top: 70px;
         right: 20px;
+        width: 20%;
 
         .info-box {
             display: flex;
@@ -248,6 +249,10 @@
 
             p {
                 margin-right: 20px;
+                overflow: hidden;
+                display: block;
+                white-space: nowrap;
+                text-overflow: ellipsis;
             }
 
             .el-icon-close {

+ 1 - 1
TEAMModelOS.Extension/IES.Exam/IES.ExamViews/src/view/admin/ActivityManage.vue

@@ -242,7 +242,7 @@
         </el-dialog>
         <div class="open-evaluation" v-if="showErrorMsgs">
             <div class="info-box error-info" v-for="(item, index) in openErrorMsgs" :key="index">
-                <p>
+                <p :title="item">
                     <i class="el-icon-error"></i>
                     {{ item }}
                 </p>

+ 3 - 4
TEAMModelOS.Extension/IES.Exam/IES.ExamViews/src/view/student/ActivityAnswer.vue

@@ -568,11 +568,10 @@ export default {
                 clearInterval(this.interval)
             }
             if (this.checkers.length) {
-                this.loading = this.$loading({
+                this.loading = Loading.service({
                     lock: true,
-                    text: 'Loading',
-                    spinner: 'el-icon-loading',
-                    background: 'rgba(0, 0, 0, 0.8)'
+                    text: '加载中',
+                    background: 'rgba(0, 0, 0, 0.7)'
                 })
                 let answer = []
                 // 是否乱序作答

+ 3 - 4
TEAMModelOS.Extension/IES.Exam/IES.ExamViews/src/view/student/ActivityInfo.vue

@@ -141,11 +141,10 @@ export default {
         }
     },
     async created() {
-        this.loading = this.$loading({
+        this.loading = Loading.service({
             lock: true,
-            text: '加载中...',
-            spinner: 'el-icon-loading',
-            background: 'rgba(0, 0, 0, 0.8)'
+            text: '加载中',
+            background: 'rgba(0, 0, 0, 0.7)'
         })
         this.nowtime = await this.getNowTime()
         this.userInfo = jwtDecode(localStorage.getItem('stu_auth_token'))

+ 3 - 0
TEAMModelOS/ClientApp/src/api/areaArt.js

@@ -73,4 +73,7 @@ export default {
     packageExam: function(data) {
         return post('/evaluation-sync/package', data)
     },
+    loadPackage: function(data) {
+        return post('/evaluation-sync/load-package', data)
+    },
 }

+ 6 - 2
TEAMModelOS/ClientApp/src/utils/excel.js

@@ -85,7 +85,7 @@ export const export_json_to_excel = ({ data, key, title, filename, autoWidth })
     XLSX.writeFile(wb, filename + '.xlsx');
 }
 
-export const export_array_to_excel = ({ key, data, title, filename, autoWidth, setTitle }) => {
+export const export_array_to_excel = ({ key, data, title, filename, autoWidth, setTitle, returnFile }) => {
     const wb = XLSX.utils.book_new();
     const arr = json_to_array(key, data);
     arr.unshift(title)
@@ -117,7 +117,11 @@ export const export_array_to_excel = ({ key, data, title, filename, autoWidth, s
         bookSST: true,
         type: 'array'
     });
-    XLSX.writeFile(wb, filename + '.xlsx');
+    if(returnFile) {
+        return new Blob([wbout], { type: 'application/octet-stream' })
+    } else {
+        XLSX.writeFile(wb, filename + '.xlsx');
+    }
 }
 
 /**

+ 177 - 0
TEAMModelOS/ClientApp/src/view/areaArtExam/Mgt.vue

@@ -36,6 +36,10 @@
                     <!-- 评价指标 -->
                     <span :class="curBarIndex == 1 ? 'art-exam-bar-item line-bottom-active line-bottom':'art-exam-bar-item line-bottom'" @click="selectBar(1)">
                         评价指标
+                    </span>
+					<!-- 打包信息 -->
+					<span :class="curBarIndex == 3 ? 'art-exam-bar-item line-bottom-active line-bottom' : 'art-exam-bar-item line-bottom'" @click="selectBar(3)">
+                        打包信息
                     </span>
                     <div style="position: absolute; right: 20px; top: 0;" v-if="artInfo.progress !== 'finish'">
 						<Button @click="packageExam()">打包评测</Button>
@@ -65,6 +69,38 @@
                         </Tabs>
                     </vuescroll>
                 </div>
+				<div v-else-if="curBarIndex === 3" style="width: 100%; height: calc(100% - 50px); padding: 10px 10px; background: #f6f6f6;">
+					<div v-if="packageInfo.length" style="background: #fff; height: 100%; padding: 10px; font-size: 18px; position: relative;">
+						<Button style="float: right; margin-bottom: 10px;" @click="uploadPackage()">下载打包信息</Button>
+                        <vuescroll>
+                            <Table :columns="columns" :data="packageInfo" border>
+                                <template slot-scope="{ row, index }" slot="grouplist">
+                                    <Tag color="blue" v-for="(group, gIndex) in row.grouplist" :key="gIndex">{{ group }}</Tag>
+                                </template>
+                                <template slot-scope="{ row, index }" slot="subject">
+                                    <Tag color="orange" v-for="(sub, sIndex) in row.subject" :key="sIndex">{{ sub }}</Tag>
+                                </template>
+                            </Table>
+                        </vuescroll>
+						<!-- <vuescroll>
+                            <div v-for="(item, index) in packageInfo" :key="index" style="border-bottom: 1px dashed #ccc; margin-bottom: 20px; padding-left: 10px;">
+                                <p style="margin-bottom: 10px;"><span>{{ item.ownerName }}({{ item.ownerId }})</span></p>
+                                <p style="margin-bottom: 10px;">科目: 
+                                    <Tag color="orange" v-for="(sub, sIndex) in item.subject" :key="sIndex">{{ sub }}</Tag>
+                                </p>
+                                <p style="margin-bottom: 10px;">学生总数:<span>{{ item.studentCount }}</span></p>
+                                <p style="margin-bottom: 10px;">参考班级:
+                                    <Tag color="blue" v-for="(group, gIndex) in item.grouplist" :key="gIndex">{{ group }}</Tag>
+                                </p>
+                                <p style="margin-bottom: 10px;">试卷数量:<span>{{ item.paperCount }}</span>份</p>
+                                <p style="margin-bottom: 10px;">文件大小:<span>{{ item.size }}</span>MB</p>
+                                <p style="margin: 20px 0; font-size: 20px;">提取码:<span style="color: #33a30e;">{{ item.shortCode }}</span></p>
+                                <p style="margin: 20px 0; font-size: 20px;">开卷码:<span style="color: #33a30e;">{{ item.openCode }}</span></p>
+                            </div>
+                        </vuescroll> -->
+					</div>
+					<div v-else style="text-align: center; margin-top: 20%; font-size: 30px;">暂未打包</div>
+				</div>
             </div>
         </Split>
     </div>
@@ -73,6 +109,9 @@
 <script>
 import AcQuos from "./AcQuos.vue"
 import DataView from "./DataView.vue"
+import excel from "@/utils/excel.js";
+import JsZip from 'jszip';
+import FileSaver from 'file-saver';
 export default {
     components: {
         AcQuos, DataView
@@ -96,6 +135,57 @@ export default {
             subjectId: '',
             curBarIndex: 0,
             tabTree: {},
+            packageInfo: [],
+            columns: [
+                {
+                    title: "学校名称",
+                    key: "ownerName",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "学校简码",
+                    key: "ownerId",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "参考学生总数",
+                    key: "studentCount",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "参考班级",
+                    slot: "grouplist",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "科目",
+                    slot: "subject",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "下载文件大小(MB)",
+                    key: "size",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "提取码",
+                    key: "shortCode",
+                    align: "center",
+                    minWidth: 120,
+                },
+                {
+                    title: "开卷码",
+                    key: "openCode",
+                    align: "center",
+                    minWidth: 120,
+                },
+            ]
         }
     },
     computed: {
@@ -256,6 +346,7 @@ export default {
                     } else {
                         this.hasPublish = false
                     }
+                    this.loadPackage()
                 },
                 (err) => { }
             )
@@ -318,7 +409,93 @@ export default {
                     this.$Message.error('打包失败')
                 } else if(res.code === 200) {
                     this.$Message.success('打包成功')
+                    this.packageInfo = res.infos.map(item => {
+                        let obj = {
+                            ownerName: item.ownerName,
+                            ownerId: item.ownerId,
+                            studentCount: item.studentCount,
+                            grouplist: item.grouplist.map(group => group.name),
+                            subject: item.subjects.map(group => group.subjectName),
+                            size: ((item.blobSize + item.dataSize) / 1024 / 1024).toFixed(2),
+                            paperCount: item.paperCount,
+                            shortCode: item.shortCode,
+                            openCode: item.openCode,
+                        }
+                        return obj
+                    })
+                }
+            })
+        },
+        loadPackage() {
+            this.packageInfo = []
+            let params = {
+                pid: this.artInfo.pId,
+            }
+            this.$api.areaArt.loadPackage(params).then(res => {
+                if(res.code === 200) {
+                    if(res.infos.length) {
+                        this.packageInfo = res.infos.map(item => {
+                            let obj = {
+                                ownerName: item.ownerName,
+                                ownerId: item.ownerId,
+                                studentCount: item.studentCount,
+                                grouplist: item.grouplist.map(group => group.name),
+                                subject: item.subjects.map(group => group.subjectName),
+                                size: ((item.blobSize + item.dataSize) / 1024 / 1024).toFixed(2),
+                                paperCount: item.paperCount,
+                                shortCode: item.shortCode,
+                                openCode: item.openCode,
+                            }
+                            obj.groupShow = obj.grouplist.join(',')
+                            obj.subShow = obj.subject.join(',')
+                            return obj
+                        })
+                    }
+                }
+            })
+        },
+        uploadPackage() {
+            const zip = new JsZip()
+            const params = {
+                title: [
+                    '学校名称',
+                    '学校简码',
+                    '参考学生总数',
+                    '参考班级',
+                    '科目',
+                    '下载文件大小(MB)',
+                ],
+                key: ['ownerName', 'ownerId', 'studentCount', 'groupShow', 'subShow', 'size'],
+                data: this.packageInfo,
+                autoWidth: true,
+                filename: `${this.artInfo.name}总表`,
+                returnFile: true
+            }
+            zip.file(`${this.artInfo.name}总表.xlsx`, excel.export_array_to_excel(params))
+            for (let i = 0; i < this.packageInfo.length; i++) {
+                const params = {
+                    title: [
+                        '学校名称',
+                        '学校简码',
+                        '参考学生总数',
+                        '参考班级',
+                        '科目',
+                        '下载文件大小(MB)',
+                        '提取码',
+                        '开卷码',
+                    ],
+                    key: ['ownerName', 'ownerId', 'studentCount', 'groupShow', 'subShow', 'size', 'shortCode', 'openCode'],
+                    data: [this.packageInfo[i]],
+                    autoWidth: true,
+                    filename: `${this.artInfo.name}-${this.packageInfo[i].ownerName}`,
+                    returnFile: true
                 }
+                zip.file(`${this.artInfo.name}-${this.packageInfo[i].ownerName}.xlsx`, excel.export_array_to_excel(params))
+            }
+            zip.generateAsync({type: 'blob'}).then(content => {
+                FileSaver.saveAs(content, `${this.artInfo.name}.zip`)
+            }).catch(err => {
+                console.log('文件压缩失败——', err);
             })
         },
     },

+ 95 - 2
TEAMModelOS/ClientApp/src/view/artexam/Mgt.vue

@@ -35,7 +35,9 @@
 					<span :class="curBarIndex == 0 ? 'art-exam-bar-item line-bottom-active line-bottom' : 'art-exam-bar-item line-bottom'" @click="selectBar(0)"> 数据概览 </span>
 					<!-- 评价指标 -->
 					<span :class="curBarIndex == 1 ? 'art-exam-bar-item line-bottom-active line-bottom' : 'art-exam-bar-item line-bottom'" @click="selectBar(1)"> 评价指标 </span>
-					<div style="position: absolute; right: 20px; top: 0;">
+					<!-- 打包信息 -->
+					<span :class="curBarIndex == 3 ? 'art-exam-bar-item line-bottom-active line-bottom' : 'art-exam-bar-item line-bottom'" @click="selectBar(3)"> 打包信息 </span>
+					<div v-if="artList[curIndex].endTime > serverTime" style="position: absolute; right: 20px; top: 0;">
 						<Button @click="packageExam()">打包评测</Button>
 					</div>
 				</div>
@@ -72,6 +74,26 @@
 						<Button type="primary" long style="margin-top: 15px" @click="publish" :loading="btnLoading">确认发布</Button>
 					</div>
 				</div>
+				<div v-else-if="curBarIndex === 3" style="width: calc(100% - 20px); font-size: 18px; height: calc(100% - 70px); margin: 10px; padding: 20px; background: white;">
+					<template v-if="packageInfo.length">
+						<Button style="float: right;" @click="uploadPackage()">下载打包信息</Button>
+						<div v-for="(item, index) in packageInfo" :key="index">
+							<!-- <p style="margin-bottom: 10px;">学校:<span>{{ item.ownerName }}({{ item.ownerId }})</span></p> -->
+							<p style="margin-bottom: 10px;">科目:
+								<Tag color="orange" v-for="(sub, sIndex) in item.subject" :key="sIndex">{{ sub }}</Tag>
+							</p>
+							<p style="margin-bottom: 10px;">学生总数:<span>{{ item.studentCount }}</span></p>
+							<p style="margin-bottom: 10px;">参考班级:
+								<Tag color="blue" v-for="(group, gIndex) in item.grouplist" :key="gIndex">{{ group }}</Tag>
+							</p>
+							<p style="margin-bottom: 10px;" v-show="artInfo.owner === 'school'">试卷数量:<span>{{ item.paperCount }}</span>份</p>
+							<p style="margin-bottom: 10px;">文件大小:<span>{{ item.size }}</span>MB</p>
+							<p style="margin: 20px 0; font-size: 20px;">提取码:<span style="color: #33a30e;">{{ item.shortCode }}</span></p>
+							<p style="margin: 20px 0; font-size: 20px;" v-show="artInfo.owner === 'school'">开卷码:<span style="color: #33a30e;">{{ item.openCode }}</span></p>
+						</div>
+					</template>
+					<div v-else style="text-align: center; margin-top: 20%; font-size: 30px;">暂未打包</div>
+				</div>
 			</div>
 		</Split>
 	</div>
@@ -82,6 +104,7 @@
 	import { mapGetters } from "vuex";
 	import AcQuos from "./AcQuos.vue";
 	import DataView from "./DataView.vue";
+	import excel from "@/utils/excel.js";
 	export default {
 		components: {
 			AcQuos,
@@ -111,7 +134,8 @@
 				classId: "",
 				subjectId: "",
 				curBarIndex: 0,
-				tabTree: {}
+				tabTree: {},
+				packageInfo: []
 			};
 		},
 		computed: {
@@ -558,6 +582,7 @@
 						if (this.artInfo?.classes?.length) {
 							this.getClassList();
 						}
+						this.loadPackage()
 					},
 					(err) => {}
 				);
@@ -628,6 +653,74 @@
 					}
 				})
 			},
+			loadPackage() {
+				this.packageInfo = []
+				let params = {
+					evaluation: {
+						id: this.artInfo.id,
+						scope: this.artInfo.scope,
+						owner: this.artInfo.school,
+						type: this.artInfo.pk,
+					},
+				}
+				this.$api.areaArt.loadPackage(params).then(res => {
+					if(res.code === 200) {
+						if(res.infos.length) {
+							this.packageInfo = res.infos.map(item => {
+								let obj = {
+									ownerName: item.ownerName,
+									ownerId: item.ownerId,
+									studentCount: item.studentCount,
+									grouplist: item.grouplist.map(group => group.name),
+									subject: item.subjects.map(group => group.subjectName),
+									size: ((item.blobSize + item.dataSize) / 1024 / 1024).toFixed(2),
+									paperCount: item.paperCount,
+									shortCode: item.shortCode,
+									openCode: item.openCode,
+								}
+								obj.groupShow = obj.grouplist.join(',')
+								obj.subShow = obj.subject.join(',')
+								return obj
+							})
+						}
+					}
+				})
+			},
+			uploadPackage() {
+				const params = {
+					title: [
+						'学校名称',
+						'学校简码',
+						'参考学生总数',
+						'参考班级',
+						'科目',
+						'下载文件大小',
+						'提取码',
+					],
+					key: ['ownerName', 'ownerId', 'studentCount', 'groupShow', 'subShow', 'size', 'shortCode'],
+					data: this.packageInfo,
+					autoWidth: true,
+					filename: `${this.artInfo.name}总表`,
+					/* setTitle: {
+						title: `${this.artInfo.name}总表`,
+						rules: [{//合并第一行数据
+							s: {//s为开始
+								c: 0,//开始列
+								r: 0//开始取值范围
+							},
+							e: {//e结束
+								c: 4,//结束列
+								r: 0//结束范围
+							}
+						}]
+					} */
+				}
+				if(this.artInfo.owner === 'school') {
+					params.title.push('开卷码')
+					params.key.push('openCode')
+				}
+				excel.export_array_to_excel(params)
+			},
 		},
 		created() {
 			this.serverTime = localStorage.getItem("serverTime") || new Date().getTime();