浏览代码

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

Li 2 年之前
父节点
当前提交
4f88e79572

+ 1 - 1
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -304,7 +304,7 @@ export default {
         let host = srvAdr == 'Global' ? this.$store.state.config.Global.coreAPIUrl : this.$store.state
           .config.China.coreAPIUrl
         this.$api.service.getNotification(host, {
-          "sender": [],
+          "senders": ['IES'],
           "receiver": userId
         }).then(res => {
           if (res.length) {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/areaMgmt/AreaBase.vue

@@ -163,7 +163,7 @@ export default {
         let host = srvAdr == 'Global' ? this.$store.state.config.Global.coreAPIUrl : this.$store.state
           .config.China.coreAPIUrl
         this.$api.service.getNotification(host, {
-          "sender": [],
+          "senders": ['IES'],
           "receiver": userId
         }).then(res => {
           if (res.length) {

+ 12 - 12
TEAMModelOS/ClientApp/src/view/artexam/AcQuos.vue

@@ -31,16 +31,15 @@ export default {
 				return {}
 			}
 		},
-		classList: {
-			type: Array,
+		curClass: {
+			type: Object,
 			default: () => {
-				return []
+				return {}
 			}
-		}
-	},
-	computed:{
-		subjectList(){
-			return this.artInfo?.subjects || []
+		},
+		subjectId: {
+			type: String,
+			default: ''
 		}
 	},
 	data() {
@@ -105,8 +104,8 @@ export default {
 										class: ["data-wrap"],
                                         props:{
                                             taskInfo:_this.getNodeSetting(node.data.id),
-											subjectList: _this.subjectList,
-											classList: _this.classList
+											curClass: _this.curClass,
+											subjectId: _this.subjectId
                                         }
 									}
 							  )
@@ -119,8 +118,8 @@ export default {
 										class: ["data-wrap"],
                                         props:{
                                             taskInfo:_this.getNodeSetting(node.data.id),
-											subjectList: _this.subjectList,
-											classList: _this.classList
+											curClass: _this.curClass,
+											subjectId: _this.subjectId
                                         }
 									}
 							  )
@@ -139,6 +138,7 @@ export default {
 .ac-quo-tree .el-tree-node__content {
 	height: fit-content;
 	align-items: baseline;
+	padding: 8px 0px;
 }
 .data-wrap {
 	min-height: 300px;

+ 1 - 1
TEAMModelOS/ClientApp/src/view/artexam/Create.vue

@@ -153,7 +153,7 @@
 					label-position="left"
 				>
 					<h1>{{ $t("train.create.publishTitle") }}</h1>
-					<FormItem :label="$t('ae.ae3')" style="margin-top: 80px">
+					<FormItem :label="$t('ae.ae2')" style="margin-top: 80px">
 						<span>{{ artInfo.name }}</span>
 					</FormItem>
 					<FormItem :label="$t('ae.ae6')">

+ 216 - 0
TEAMModelOS/ClientApp/src/view/artexam/DataView.vue

@@ -0,0 +1,216 @@
+<template>
+    <div class="data-view-wrap">
+        <div class="table-header-wrap">
+            <!-- <span>{{$t('ae.ae6')}}:</span> -->
+            <Select v-model="classId" style="width: 200px">
+                <Option v-for="item in classList" :value="item.id" :key="item.id">{{ item.name }}</Option>
+            </Select>
+        </div>
+        <Table :columns="columns" :data="tableDataShow" border>
+            <template slot-scope="{ row , column }" v-for="s in slotList" :slot="s">
+                <div :key="s" style="padding:5px 5px">
+                    <ul>
+                        <li class="quota-score-item" v-for="task in row[s]" :key="task.taskId">
+                            {{task.quotaName}}
+                            <span class="quota-score-value" v-if="task.score >= 0">{{task.score}}分</span>
+                            <span class="quota-score-value" v-else>-</span>
+                        </li>
+                    </ul>
+                    <p v-if="!row[s].length" class="no-score-tag">
+                        未评分
+                    </p>
+                </div>
+            </template>
+        </Table>
+        <!-- 分页 -->
+        <div class="page-wrap">
+            <Page show-total size="small" :current="currentPage" :total="tableData.length" :page-size="pageSize" @on-change="pageChange" />
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        artInfo: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        quotaFirstLevel: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        classList: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        }
+    },
+    computed: {
+        curClass() {
+            if (this.classList && this.classList.length && this.classId) {
+                return this.classList.find(item => item.id == this.classId)
+            }
+            return {}
+        },
+        columns() {
+            let data = [
+                {
+                    title: '姓名',
+                    key: 'name',
+                    align: 'center',
+                    minWidth: 120,
+                    fixed: 'left',
+                },
+                {
+                    title: '总分',
+                    key: 'totalScore',
+                    align: 'center',
+                    minWidth: 80,
+                    fixed: 'right',
+                }
+            ]
+            if (this.artInfo?.subjects?.length) {
+                let stList = []
+                this.artInfo.subjects.forEach(subject => {
+                    let index = data.length - 1
+                    data.splice(index, 0, {
+                        title: subject.name,
+                        align: 'center',
+                        children: []
+                    })
+                    this.quotaFirstLevel.forEach(quo => {
+                        data[index].children.push({
+                            title: quo.name,
+                            align: 'center',
+                            minWidth: 180,
+                            slot: `${subject.id}-${quo.id}`
+                        })
+                        stList.push(`${subject.id}-${quo.id}`)
+                    })
+                })
+                this.slotList = stList
+            }
+            return data
+        }
+    },
+    data() {
+        return {
+            pageSize: 10,
+            currentPage: 1,
+            classId: '',
+            slotList: [],
+            tableData: [],
+            tableDataShow: []
+        }
+    },
+    methods: {
+        // 分页页面变化
+        pageChange(page) {
+            let start = this.pageSize * (page - 1)
+            let end = this.pageSize * page
+            this.currentPage = page
+            this.tableDataShow = this.tableData.slice(start, end)
+        },
+        findArtResult() {
+            if (!this.classId) return
+            this.$api.areaArt.findArtResults({
+                "opt": "find",
+                "artId": this.artInfo.id,
+                "subjects": [],
+                "classIds": [this.classId]
+            }).then(res => {
+                if (!res.error) {
+                    this.setTableData(res.results)
+                } else {
+                    this.$Message.error('Fail1')
+                }
+            }).catch(e => {
+                this.$Message.error('Fail2')
+            })
+        },
+        setTableData(results) {
+            let students = this.curClass.members
+            this.tableData = []
+            students.forEach(student => {
+                let row = {
+                    id: student.id,
+                    name: student.name
+                }
+                let studentRes = results.find(r => r.studentId === student.id)
+                if (studentRes) {
+                    this.slotList.forEach(st => {
+                        let arr = st.split('-')
+                        row[st] = studentRes.results.filter(res => {
+                            return res.subjectId === arr[0] && res.quotaId.includes(arr[1])
+                        })
+                    })
+                    row.totalScore = studentRes.totalScore
+                } else {
+                    this.slotList.forEach(st => {
+                        row[st] = []
+                    })
+                    row.totalScore = 0
+                }
+                this.tableData.push(row)
+            })
+            this.pageChange(1)
+        }
+    },
+    watch: {
+        classId: {
+            immediate: true,
+            deep: true,
+            handler(n, o) {
+                if (n) {
+                    this.findArtResult()
+                }
+            }
+        },
+        classList: {
+            immediate: true,
+            deep: true,
+            handler(n, o) {
+                if (n && n.length) {
+                    this.classId = n[0].id
+                } else {
+                    this.classId = ''
+                }
+            }
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.page-wrap {
+    margin-top: 15px;
+}
+.quota-score-item {
+    margin-left: 5px;
+    text-align: left;
+    list-style: square;
+    &::marker {
+        color: #085fec;
+    }
+}
+.quota-score-value {
+    color: #2d8cf0;
+    float: right;
+    font-weight: 600;
+}
+.no-score-tag {
+    color: #ed4014;
+}
+.data-view-wrap {
+    padding: 0px 5px;
+}
+.table-header-wrap {
+    margin-top: 15px;
+    margin-bottom: 5px;
+}
+</style>

+ 154 - 187
TEAMModelOS/ClientApp/src/view/artexam/ExamData.vue

@@ -1,88 +1,62 @@
 <template>
-	<div class="exam-data">
-		<!-- {{taskInfo}} -->
-		<span>{{$t('ae.ae6')}}:</span>
-		<Select v-model="classId" style="width: 200px" @on-change="getStudentAnswer">
-			<Option
-				v-for="item in classList"
-				:value="item.id"
-				:key="item.id"
-				>{{ item.name }}</Option
-			>
-		</Select>
-        <span style="margin-left:10px">{{$t('ae.ae4')}}:</span>
-		<Select v-model="subjectId" style="width: 120px" @on-change="getStudentAnswer">
-			<Option
-				v-for="item in subjectList"
-				:value="item.id"
-				:key="item.id"
-				>{{ item.name }}</Option
-			>
-		</Select>
-		<Table :height="520" stripe :columns="tableColumn" :data="tableData" border :loading="tableLoading" style="margin-top:10px">
-			<template slot-scope="{ row,index }" :slot="'qu'+qIndex" v-for="(item,qIndex) in quCount">
-				<div :key="'qu'+qIndex" style="cursor:pointer;">
-					<span v-if="row.data[qIndex] == -1 && row.status == 1">- -</span>
-					<Icon size="20" type="ios-create-outline" color="#2db7f5" v-else-if="row.data[qIndex] == -1 && row.status !== 1" />
-					<span style="color:#2db7f5;" v-else>{{row.data[qIndex]}}</span>
-				</div>
-			</template>
-			<template slot-scope="{ row }" slot="total">
-				<span style="color:#2db7f5;">{{ getTotalScore(row.data)}}</span>
-			</template>
-			<template slot-scope="{ row }" slot="name">
-				<span style="color:#2db7f5;cursor: pointer;" :title="row.id">{{ row.name}}</span>
-			</template>
-			<!-- 1: 未作答 2:未评分 3:已评分 4:缺考 5:补考中 -->
-			<template slot-scope="{ row,index }" slot="status">
-				<span class="stu-status-tag" :style="{'background':row.statusColor}">
-					{{row.statusText}}
-				</span>
-			</template>
-		</Table>
-		<!-- 分页 -->
-		<div class="page-wrap">
-			<Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" @on-change="pageChange"/>
-		</div>
-	</div>
+    <div class="exam-data">
+        <Table :height="520" :columns="tableColumn" :data="tableData" border :loading="tableLoading" style="margin-top:10px">
+            <template slot-scope="{ row,index }" :slot="'qu'+qIndex" v-for="(item,qIndex) in quCount">
+                <div :key="'qu'+qIndex" style="cursor:pointer;">
+                    <span v-if="row.data[qIndex] == -1 && row.status == 1">- -</span>
+                    <Icon size="20" type="ios-create-outline" color="#2db7f5" v-else-if="row.data[qIndex] == -1 && row.status !== 1" />
+                    <span style="color:#2db7f5;" v-else>{{row.data[qIndex]}}</span>
+                </div>
+            </template>
+            <template slot-scope="{ row }" slot="total">
+                <span style="color:#2db7f5;">{{ getTotalScore(row.data)}}</span>
+            </template>
+            <template slot-scope="{ row }" slot="name">
+                <span>{{ row.name}}</span>
+            </template>
+            <template slot-scope="{ row }" slot="id">
+                <span>{{ row.id}}</span>
+            </template>
+            <!-- 1: 未作答 2:未评分 3:已评分 4:缺考 5:补考中 -->
+            <template slot-scope="{ row,index }" slot="status">
+                <span class="stu-status-tag" :style="{'background':row.statusColor}">
+                    {{row.statusText}}
+                </span>
+            </template>
+        </Table>
+        <!-- 分页 -->
+        <div class="page-wrap">
+            <Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" @on-change="pageChange" />
+        </div>
+    </div>
 </template>
 
 <script>
 export default {
-	props: {
-		taskInfo: {
+    props: {
+        taskInfo: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        curClass: {
 			type: Object,
-			default: () => {
-				return {}
-			}
-		},
-		subjectList: {
-			type: Array,
-			default: () => {
-				return []
-			}
-		},
-        classList:{
-			type: Array,
-			default: () => {
-				return []
-			}
+            default: () => {
+                return {}
+            }
 		},
-	},
-	computed:{
-		curClass(){
-			if(this.classList && this.classList.length && this.classId){
-				return this.classList.find(item=>item.id == this.classId)
-			}
-			return undefined
+		subjectId: {
+			type: String,
+			default: ''
 		}
-	},
-	data() {
-		return {
-			currentPage:1,
-			quCount:[],
-			scoreList:[
-				{
+    },
+    data() {
+        return {
+            currentPage: 1,
+            quCount: [],
+            scoreList: [
+                {
                     title: this.$t('learnActivity.score.column1'),
                     slot: "name",
                     fixed: "left",
@@ -90,7 +64,14 @@ export default {
                     width: 150,
                 },
                 {
-                    title: this.$t('learnActivity.score.column2'),
+                    title: 'ID',
+                    slot: "id",
+                    fixed: "left",
+                    align: "center",
+                    width: 150,
+                },
+                {
+                    title: '得分',
                     slot: "total",
                     align: "center",
                     sortable: true,
@@ -104,22 +85,22 @@ export default {
                     fixed: "right",
                     width: 130,
                 }
-			],
-			tableColumn:[],
-            subjectId:'',
-            classId:'',
-			tableLoading:false,
-			studentScore:[],
-			tableData:[],
-			pageSize:10,
-			curPage:1,
-			examInfo:{
-				progress:'going'
-			}
+            ],
+            tableColumn: [],
+            // subjectId: '',
+            // classId: '',
+            tableLoading: false,
+            studentScore: [],
+            tableData: [],
+            pageSize: 10,
+            curPage: 1,
+            examInfo: {
+                progress: 'going'
+            }
         }
-	},
-	methods:{
-		getTotalScore(data) {
+    },
+    methods: {
+        getTotalScore(data) {
             let res = data.reduce((prev, curr, idx, arr) => {
                 prev = prev < 0 ? 0 : prev
                 curr = curr < 0 ? 0 : curr
@@ -130,89 +111,84 @@ export default {
             res = index > 0 ? res.substr(0, index + 2) : res
             return res
         },
-		getExamId(){
-			let task = this.taskInfo.task?.find(item=>item.subject == this.subjectId)
-			return task?.acId || ''
-		},
-		//获取学生作答详情数据
+        getExamId() {
+            let task = this.taskInfo.task?.find(item => item.subject == this.subjectId)
+            return task?.acId || ''
+        },
+        //获取学生作答详情数据
         getStudentAnswer() {
-			let examId = this.getExamId()
-			if(!examId || !this.subjectId || !this.classId) return
+            let examId = this.getExamId()
+            if (!examId || !this.subjectId || !this.curClass.id) return
             this.tableLoading = true
             let requestData = {
                 id: examId,
                 code: this.$store.state.userInfo.schoolCode,
                 subjectId: this.subjectId,
-                classId: this.classId,
+                classId: this.curClass.id,
             };
             this.$api.learnActivity.FindAllStudent(requestData).then(
                 (res) => {
                     if (res.examClassResults && res.examClassResults.length) {
                         this.setTableData(res.examClassResults[0])
-                        // this.calcOverView(res.examClassResults[0])
                         this.tableLoading = false
                     }
                 },
                 (err) => {
-                    // this.$t('learnActivity.score.dataError')
-                    // this.dataLoading = false
                 }
-            ).finally(()=>{
-				this.tableLoading = false
-			})
+            ).finally(() => {
+                this.tableLoading = false
+            })
         },
-		//初始化表单数据
+        //初始化表单数据
         setTableData(studentAns) {
-			let studentData = this.curClass?.members || []
-			this.studentScore = []
-			this.tableColumn = [...this.scoreList]
-			this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
-			for (let i = 0; i < this.quCount; i++) {
-				let data = {
-					title: "Q" + (i + 1),
-					slot: "qu" + i,
-					renderHeader: (h, params) => {
-						return h('div', {
-							style: {
-								cursor: 'pointer',
-								fontSize: '13px'
-							}
-						}, [
-							h('p', {
-								class: 'table-qu-no'
-							}, i+1)
-						])
-					},
-					align: "center",
-					minWidth: 70
-				}
-				this.tableColumn.push(data);
-			}
-			let ans = []
-			for (let i = 0; i < studentAns.studentIds.length; i++) {
-				for (let k = 0; k < studentData.length; k++) {
-					let score = {}
-					if (studentAns.studentIds[i] == studentData[k].id) {
-						score.name = studentData[k].name
-						score.type = studentData[k].type
-						score.id = studentAns.studentIds[i]
-						score.data = studentAns.studentScores[i]
-						score.total = this.getcount(score.data)
-						score.ansBlob = studentAns.studentAnswers[i]
-						score.mark = studentAns.mark[i]
-						let { status, statusText, statusColor } = this.getStatusInfo(studentAns.studentScores[i], studentAns.status[i])
-						score.status = status
-						score.statusText = statusText
-						score.statusColor = statusColor
-						this.studentScore.push(score)
-					}
-				}
-			}
-			// this.originData = this._.cloneDeep(this.studentScore)
-			// this.students = this._.cloneDeep(this.studentScore)
-			this.pageChange(1)
+            let studentData = this.curClass?.members || []
+            this.studentScore = []
+            this.tableColumn = [...this.scoreList]
+            this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
+            for (let i = 0; i < this.quCount; i++) {
+                let data = {
+                    title: "Q" + (i + 1),
+                    slot: "qu" + i,
+                    renderHeader: (h, params) => {
+                        return h('div', {
+                            style: {
+                                cursor: 'pointer',
+                                fontSize: '13px'
+                            }
+                        }, [
+                            h('p', {
+                                class: 'table-qu-no'
+                            }, i + 1)
+                        ])
+                    },
+                    align: "center",
+                    minWidth: 70
+                }
+                this.tableColumn.push(data);
+            }
+            let ans = []
+            for (let i = 0; i < studentAns.studentIds.length; i++) {
+                for (let k = 0; k < studentData.length; k++) {
+                    let score = {}
+                    if (studentAns.studentIds[i] == studentData[k].id) {
+                        score.name = studentData[k].name
+                        score.type = studentData[k].type
+                        score.id = studentAns.studentIds[i]
+                        score.data = studentAns.studentScores[i]
+                        score.total = this.getcount(score.data)
+                        score.ansBlob = studentAns.studentAnswers[i]
+                        score.mark = studentAns.mark[i]
+                        let { status, statusText, statusColor } = this.getStatusInfo(studentAns.studentScores[i], studentAns.status[i])
+                        score.status = status
+                        score.statusText = statusText
+                        score.statusColor = statusColor
+                        this.studentScore.push(score)
+                    }
+                }
+            }
+            this.pageChange(1)
         },
-		//分数求和
+        //分数求和
         getcount(arr) {
             return arr.reduce((total, item) => {
                 if (item !== -1) {
@@ -222,14 +198,14 @@ export default {
                 }
             }, 0);
         },
-		// 分页页面变化
+        // 分页页面变化
         pageChange(page) {
             let start = this.pageSize * (page - 1)
             let end = this.pageSize * page
             this.currentPage = page
             this.tableData = this.studentScore.slice(start, end)
         },
-		getStatusInfo(score, status) {
+        getStatusInfo(score, status) {
             if (status == -1) {
                 return {
                     status: -1,
@@ -263,12 +239,10 @@ export default {
                     statusColor: '#808695'
                 }
             }
-            // status:0
             //已作答,未评分
             if (score.includes(-1)) {
                 return {
                     status: 2,
-                    // statusText: this.$t('learnActivity.score.status2'),
                     statusText: this.$t('learnActivity.score.status7'),
                     statusColor: '#ff9900'
                 }
@@ -276,34 +250,27 @@ export default {
             //已作答已评分
             return {
                 status: 4,
-                statusText: this.$t('learnActivity.score.status3'),
+                statusText: this.$t('learnActivity.score.status7'),
                 statusColor: '#19be6b'
             }
         },
-	},
-    watch:{
-        subjectList:{
-            immediate:true,
-            deep:true,
-            handler(n,o){
-                if(n && n.length){
-                    this.subjectId = n[0].id
-					this.getStudentAnswer()
-                }else{
-					this.subjectId = ''
-				}
+    },
+    watch: {
+        subjectId: {
+            immediate: true,
+            handler(n, o) {
+                if (n) {
+                    this.getStudentAnswer()
+                }
             }
         },
-        classList:{
-            immediate:true,
+        curClass: {
+            immediate: true,
             deep:true,
-            handler(n,o){
-                if(n && n.length){
-                    this.classId = n[0].id
-					this.getStudentAnswer()
-                }else{
-					this.classId = ''
-				}
+            handler(n, o) {
+                if (n && n.id) {
+                    this.getStudentAnswer()
+                }
             }
         }
     }
@@ -312,7 +279,6 @@ export default {
 
 <style lang="less" scoped>
 .page-wrap {
-    float: right;
     margin-top: 15px;
 }
 
@@ -325,8 +291,9 @@ export default {
     border-radius: 4px;
     color: white;
 }
-.exam-data{
-    padding: 5px 5px;
-    background: #f9f9f9;
+.exam-data {
+    padding: 10px 10px;
+    border-radius: 6px;
+    background: #f0f0f0;
 }
 </style>

+ 311 - 210
TEAMModelOS/ClientApp/src/view/artexam/Mgt.vue

@@ -1,244 +1,345 @@
 <template>
-	<div class="art-exam-container">
-		<Split v-model="split">
-			<div class="demo-split-pane" slot="left">
-				<div class="art-mgt-top light-iview-select light-iview-input">
-					<span>{{$t('ae.ae28')}}</span>
-					<span class="to-create-art" @click="toCreate">
-						<Icon type="md-add" />
-					</span>
-					<span class="to-create-art" @click="delArt">
-						<Icon type="md-trash" />
-					</span>
-				</div>
-				<vuescroll>
-					<div :class="['art-item', curIndex == index ? 'art-item-active' : '']" v-for="(item,index) in artList" :key="item.id" @click="selectArt(index)">
-						<p class="art-name">{{item.name}}</p>
-						<p class="art-date"><Icon type="md-time" size="16"/>{{$jsFn.dateFormat(item.startTime)}}-{{$jsFn.dateFormat(item.endTime)}}</p>
-					</div>
-				</vuescroll>
-				<EmptyData v-show="!artList.length" :top="100"></EmptyData>
-			</div>
-			<div class="art-content" slot="right">
-				<vuescroll>
-					<Tabs v-model="tabName">
-						<TabPane
-							v-for="(item, index) in tabListShow"
-							:key="index"
-							:label="item.label"
-							:name="item.name"
-						>
-							<AcQuos :artInfo="artInfo" :treeData="treeData" :classList="classList"></AcQuos>
-						</TabPane>
-					</Tabs>
-				</vuescroll>
-			</div>
+    <div class="art-exam-container">
+        <Split v-model="split">
+            <div class="demo-split-pane" slot="left">
+                <div class="art-mgt-top light-iview-select light-iview-input">
+                    <span>{{$t('ae.ae28')}}</span>
+                    <span class="to-create-art" @click="toCreate">
+                        <Icon type="md-add" />
+                    </span>
+                    <span class="to-create-art" @click="delArt">
+                        <Icon type="md-trash" />
+                    </span>
+                </div>
+                <vuescroll>
+                    <div :class="['art-item', curIndex == index ? 'art-item-active' : '']" v-for="(item,index) in artList" :key="item.id" @click="selectArt(index)">
+                        <p class="art-name">{{item.name}}</p>
+                        <p class="art-date">
+                            <Icon type="md-time" size="16" />{{$jsFn.dateFormat(item.startTime)}}-{{$jsFn.dateFormat(item.endTime)}}
+                        </p>
+                    </div>
+                </vuescroll>
+                <EmptyData v-show="!artList.length" :top="100"></EmptyData>
+            </div>
+            <div class="art-content" slot="right">
+                <div class="art-exam-bar">
+                    <!-- 数据概览 -->
+                    <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>
+                <DataView :artInfo="artInfo" :quotaFirstLevel="quotaFirstLevel" :classList="classList" v-if="curBarIndex === 0"></DataView>
+                <div v-else-if="curBarIndex === 1">
+                    <vuescroll>
+                        <Tabs v-model="tabName" style="padding: 0px 10px;margin-top:15px">
+                            <template slot="extra">
+                                <div class="art-filter-wrap">
+                                    <span>{{$t('ae.ae6')}}:</span>
+                                    <Select v-model="classId" style="width: 200px">
+                                        <Option v-for="item in classList" :value="item.id" :key="item.id">{{ item.name }}</Option>
+                                    </Select>
+                                    <span style="margin-left:10px">{{$t('ae.ae4')}}:</span>
+                                    <Select v-model="subjectId" style="width: 120px">
+                                        <Option v-for="item in subjectList" :value="item.id" :key="item.id">{{ item.name }}</Option>
+                                    </Select>
+                                </div>
+                            </template>
+                            <TabPane v-for="(item, index) in tabListShow" :key="index" :label="item.label" :name="item.name">
+                                <AcQuos :artInfo="artInfo" :treeData="treeData" :curClass="curClass" :subjectId="subjectId"></AcQuos>
+                            </TabPane>
+                        </Tabs>
+                    </vuescroll>
+                </div>
+            </div>
         </Split>
-	</div>
+    </div>
 </template>
 
 <script>
 import AcQuos from "./AcQuos.vue"
+import DataView from "./DataView.vue"
 export default {
-	components:{
-		AcQuos
-	},
-	data() {
-		return {
-			tabName:'',
-			split:0.25,
-			artList: [],
-			artInfo:{},
-			curIndex:0,
-			quotas:[],
-			tabListShow:[],
-			tabList:[],
-			classList:[]
-		}
-	},
-	computed:{
-		treeData(){
-			if(this.tabName && this.quotas.length){
-				let curQuo = this.quotas.find(q=>q.id === this.tabName)
-				let _this = this
-				const filterNodes = function(nodes) {
-					nodes = nodes.filter(n=>{
-						let isShow = _this.curSettings.find(c=> (n.children.length && c.id.includes(n.id)) || (!n.children.length && c.id == n.id))
-						return !!isShow
-					})
-					nodes.forEach(node => {
-						if(node.children){
-							node.children = filterNodes(node.children)
-						}
-					})
-					console.log('---',nodes)
-					return nodes
-				}
-				let res = filterNodes(curQuo.children)
-				return res
-			}
-			return [] 
-		},
-		curSettings(){
-			if(this.tabName && this.artInfo?.settings){
-				let data = this.artInfo.settings.filter(s=>{
-					return s.id.includes(this.tabName)
+    components: {
+        AcQuos, DataView
+    },
+    data() {
+        return {
+            tabName: '',
+            split: 0.2,
+            artList: [],
+            artInfo: {},
+            curIndex: 0,
+            quotas: [],
+            tabListShow: [],
+            tabList: [],
+            classList: [],
+            classId: '',
+            subjectId: '',
+            curBarIndex: 0
+        }
+    },
+    computed: {
+		quotaFirstLevel(){
+            if(this.quotas.length && this.artInfo?.settings){
+				let levelMap = {}
+				this.artInfo.settings.forEach(setting=>{
+					let id = setting.path[0]
+					if(!levelMap[id]){
+						levelMap[id] = this.quotas.find(q=>q.id === id)?.name
+					}
 				})
-				return data || []
-			}
-			return []
-		}
-	},
-	methods: {
-		/* 获取当前区级设置数据 */
-		getAreaSetting() {
-			this.$api.areaArt.findArtSetting({
-				areaId: sessionStorage.getItem("areaId")
-			}).then((res) => {
-				if (res.setting) {
-					this.quotas = res.setting.quotas
-					this.tabList = this.quotas.map((q) => {
-						return {
-							name: q.id,
-							label: q.name,
-							children: q.children
-						}
+				let data = []
+				for (const key in levelMap) {
+					data.push({
+						id:key,
+						name:levelMap[key]
 					})
-					this.findArtList()
-				} else{
-					this.$Message.warning(this.$t('ae.ae30'))
 				}
-			})
-		},
-		delArt(){
-			this.$Modal.confirm({
-				title:this.$t('ae.ae31'),
-				content:`${this.$t('ae.ae32')}${this.artList[this.curIndex].name}?`,
-				onOk:()=>{
-					let requestData ={
-						id:this.artList[this.curIndex].id,
-						code: this.$store.state.userInfo.schoolCode
-					}
-					this.$api.areaArt.delArt(requestData).then(
-						res=>{
-							this.$Message.success(this.$t('ae.ae33'))
-							let index = this.curIndex
-							this.artList.splice(index,1)
-							this.curIndex = 0
-						},
-						err=>{
-							this.$Message.error(this.$t('ae.ae34'))
-						}
-					)
-				}
-			})
-		},
-		selectArt(index){
-			this.curIndex = index
-			this.findArtSummary()
-		},
-		toCreate() {
-			this.$router.push({
-				name: "createArtExam"
-			})
-		},
-		toDetailPage(index) {},
-		findArtList() {
-			let params = {
-				code: this.$store.state.userInfo.schoolCode
-			}
-			this.$api.areaArt.findArtList(params).then(
-				(res) => {
-					this.artList = res.arts
-					if(this.artList.length) this.findArtSummary()
-				},
-				(err) => {}
-			)
-		},
-		findArtSummary(){
-			this.classList = []
-			let params = {
-				id:this.artList[this.curIndex].id,
-				code: this.$store.state.userInfo.schoolCode
+				console.log('***',data)
+				return data
 			}
-			this.$api.areaArt.findArtSummary(params).then(
-				(res) => {
-					this.artInfo = res.art
-					this.tabListShow = this.tabList.filter(item=>{
-						return !!this.artInfo.settings.find(s=>s.id.includes(item.name))
-					})
-					if(this.tabListShow.length){
-						this.tabName = this.tabListShow[0].name
-					}
-					if(this.artInfo?.classes){
-						this.getClassList()
-					}
-				},
-				(err) => {}
-			)
-		},
-		getClassList(){
-			let req = {
+			return []
+        },
+        curClass() {
+            if (this.classList && this.classList.length && this.classId) {
+                return this.classList.find(item => item.id == this.classId)
+            }
+            return {}
+        },
+        subjectList() {
+            return this.artInfo?.subjects || []
+        },
+        treeData() {
+            if (this.tabName && this.quotas.length) {
+                let curQuo = this.quotas.find(q => q.id === this.tabName)
+                let _this = this
+                const filterNodes = function (nodes) {
+                    nodes = nodes.filter(n => {
+                        let isShow = _this.curSettings.find(c => (n.children.length && c.id.includes(n.id)) || (!n.children.length && c.id == n.id))
+                        return !!isShow
+                    })
+                    nodes.forEach(node => {
+                        if (node.children) {
+                            node.children = filterNodes(node.children)
+                        }
+                    })
+                    console.log('---', nodes)
+                    return nodes
+                }
+                let res = filterNodes(curQuo.children)
+                return res
+            }
+            return []
+        },
+        curSettings() {
+            if (this.tabName && this.artInfo?.settings) {
+                let data = this.artInfo.settings.filter(s => {
+                    return s.id.includes(this.tabName)
+                })
+                return data || []
+            }
+            return []
+        }
+    },
+    methods: {
+        selectBar(tab) {
+            this.curBarIndex = tab
+        },
+        /* 获取当前区级设置数据 */
+        getAreaSetting() {
+            this.$api.areaArt.findArtSetting({
+                areaId: sessionStorage.getItem("areaId")
+            }).then((res) => {
+                if (res.setting) {
+                    this.quotas = res.setting.quotas
+                    this.tabList = this.quotas.map((q) => {
+                        return {
+                            name: q.id,
+                            label: q.name,
+                            children: q.children
+                        }
+                    })
+                    this.findArtList()
+                } else {
+                    this.$Message.warning(this.$t('ae.ae30'))
+                }
+            })
+        },
+        delArt() {
+            this.$Modal.confirm({
+                title: this.$t('ae.ae31'),
+                content: `${this.$t('ae.ae32')}${this.artList[this.curIndex].name}?`,
+                onOk: () => {
+                    let requestData = {
+                        id: this.artList[this.curIndex].id,
+                        code: this.$store.state.userInfo.schoolCode
+                    }
+                    this.$api.areaArt.delArt(requestData).then(
+                        res => {
+                            this.$Message.success(this.$t('ae.ae33'))
+                            let index = this.curIndex
+                            this.artList.splice(index, 1)
+                            this.curIndex = 0
+                        },
+                        err => {
+                            this.$Message.error(this.$t('ae.ae34'))
+                        }
+                    )
+                }
+            })
+        },
+        selectArt(index) {
+            this.curIndex = index
+            this.findArtSummary()
+        },
+        toCreate() {
+            this.$router.push({
+                name: "createArtExam"
+            })
+        },
+        toDetailPage(index) { },
+        findArtList() {
+            let params = {
+                code: this.$store.state.userInfo.schoolCode
+            }
+            this.$api.areaArt.findArtList(params).then(
+                (res) => {
+                    this.artList = res.arts
+                    if (this.artList.length) this.findArtSummary()
+                },
+                (err) => { }
+            )
+        },
+        findArtSummary() {
+            this.classList = []
+            let params = {
+                id: this.artList[this.curIndex].id,
+                code: this.$store.state.userInfo.schoolCode
+            }
+            this.$api.areaArt.findArtSummary(params).then(
+                (res) => {
+                    this.artInfo = res.art
+                    this.tabListShow = this.tabList.filter(item => {
+                        return !!this.artInfo.settings.find(s => s.id.includes(item.name))
+                    })
+                    if (this.tabListShow.length) {
+                        this.tabName = this.tabListShow[0].name
+                    }
+                    if (this.artInfo?.classes) {
+                        this.getClassList()
+                    }
+                },
+                (err) => { }
+            )
+        },
+        getClassList() {
+            let req = {
                 ids: this.artInfo.classes,
                 schoolId: this.$store.state.userInfo.schoolCode
             }
             this.$api.common.getGroupListByIds(req).then(
-				res=>{
-					this.classList = res.groups
-				},
-				err=>{
-					this.$Message.error(this.$t('ae.ae35'))
+                res => {
+                    this.classList = res.groups
+                },
+                err => {
+                    this.$Message.error(this.$t('ae.ae35'))
+                }
+            )
+        },
+    },
+    created() {
+        this.getAreaSetting()
+    },
+	watch:{
+		classList:{
+			immediate:true,
+			deep:true,
+			handler(n,o){
+				if(n && n.length){
+					this.classId = n[0].id
 				}
-			)
+			}
 		},
-	},
-	created(){
-		this.getAreaSetting()
+		subjectList:{
+			immediate:true,
+			deep:true,
+			handler(n,o){
+				if(n && n.length){
+					this.subjectId = n[0].id
+				}
+			}
+		}
 	}
+
 }
 </script>
 
 <style lang="less" scoped>
-.art-name{
-	font-weight: 500;
-	font-size: 15px;
-	color: #17233d;
+.art-exam-bar {
+    width: 100%;
+    height: 45px;
+    line-height: 45px;
+    box-shadow: 0 2px 5px #e9e9e9;
+    padding-left: 10px;
+    color: var(--second-text-color);
+    position: relative;
+
+    .art-exam-bar-item {
+        display: inline-block;
+        cursor: pointer;
+        user-select: none;
+        line-height: 38px;
+    }
+
+    .art-exam-bar-active {
+        color: white;
+        border-bottom: 2px solid white;
+    }
 }
-.art-date{
-	margin-top: 5px;
-	color: #808695;
+.art-name {
+    font-weight: 500;
+    font-size: 15px;
+    color: #17233d;
 }
-.art-content{
-	padding-left: 10px;
+.art-date {
+    margin-top: 5px;
+    color: #808695;
 }
-.art-item-active{
-	background: var(--hover-text-color);
+.art-content {
+    padding-left: 7px;
 }
-.art-item{
-	padding: 15px 15px;
-	cursor: pointer;
-	&:hover{
-		background: var(--hover-text-color);
-	}
+.art-item-active {
+    background: var(--hover-text-color);
+}
+.art-item {
+    padding: 15px 15px;
+    cursor: pointer;
+    &:hover {
+        background: var(--hover-text-color);
+    }
 }
 .art-exam-container {
-	width: 100%;
-	height: 100%;
-	background: white;
+    width: 100%;
+    height: 100%;
+    background: white;
 }
 .art-mgt-top {
-	height: 45px;
-	box-shadow: 0px 2px 5px #e9e9e9;
-	padding-left: 15px;
-	padding-right: 20px;
-	margin-bottom: 5px;
-	line-height: 45px;
+    height: 45px;
+    box-shadow: 0px 2px 5px #e9e9e9;
+    padding-left: 15px;
+    padding-right: 20px;
+    margin-bottom: 5px;
+    line-height: 45px;
 }
 .to-create-art {
-	float: right;
-	user-select: none;
-	cursor: pointer;
-	color: #40a8f0;
-	margin-left: 10px;
+    float: right;
+    user-select: none;
+    cursor: pointer;
+    color: #40a8f0;
+    margin-left: 10px;
 }
 </style>

+ 145 - 143
TEAMModelOS/ClientApp/src/view/artexam/WorkData.vue

@@ -1,60 +1,53 @@
 <template>
-	<div class="work-data">
-        <span>{{$t('ae.ae4')}}:</span>
-		<Select v-model="subjectId" style="width: 120px" @on-change="findArtWorkData">
-			<Option
-				v-for="item in subjectList"
-				:value="item.id"
-				:key="item.id"
-				>{{ item.name }}</Option
-			>
-		</Select>
-        <span style="margin-left:10px">{{$t('ae.ae6')}}:</span>
-		<Select v-model="classId" style="width: 200px" @on-change="findArtWorkData">
-			<Option
-				v-for="item in classList"
-				:value="item.id"
-				:key="item.id"
-				>{{ item.name }}</Option
-			>
-		</Select>
-        <Table :height="520" stripe :columns="tableColumn" :data="tableData" border :loading="tableLoading" style="margin-top:10px">
-			<template slot-scope="{ row }" slot="name">
-				<span style="color:#2db7f5;cursor: pointer;" :title="row.id">{{ row.name}}</span>
-			</template>
+    <div class="work-data">
+        <Table :height="520" :columns="tableColumn" :data="tableData" border :loading="tableLoading" style="margin-top:10px">
+            <template slot-scope="{ row }" slot="name">
+                <span style="color:#2db7f5;cursor: pointer;" :title="row.id">{{ row.name}}</span>
+            </template>
+            <template slot-scope="{ row }" slot="status">
+                <span :style="{color:row.createTime ? '#19be6b' : 'red' }">{{row.createTime ? $t('td.td43') : $t('ae.ae29')}}</span>
+            </template>
+            <template slot-scope="{ row }" slot="files">
+                <div v-for="(item,index) in row.files" :key="index">
+                    <div class="file-icon">
+                        <img v-if="item.extension == 'PPT' || item.extension == 'PPTX'" src="../../assets/source/ppt.png" />
+                        <img v-else-if="item.extension == 'DOC' || item.extension == 'DOCX'" src="../../assets/source/word.png" />
+                        <img v-else-if="item.extension == 'XLS' || item.extension == 'XLSX' || item.extension == 'CSV'" src="../../assets/source/excel.png" />
+                        <img v-else-if="item.extension == 'PDF'" src="../../assets/source/pdf.png" />
+                        <img v-else-if="item.extension == 'ZIP' || item.extension == 'RAR'" src="../../assets/source/zip.png" />
+                        <img v-else-if="item.type == 'image'" src="../../assets/source/image.png" />
+                        <img v-else-if="item.type == 'video'" src="../../assets/source/video.png" />
+                        <img v-else-if="item.type == 'audio'" src="../../assets/source/audio.png" />
+                        <img v-else-if="item.type == 'res'" src="../../assets/icon/htex.png" />
+                        <img v-else src="../../assets/source/unknow.png" />
+                    </div>
+                    <p class="work-file-name" @click="handlePreviewHw(item)">
+                        {{item.name}}
+                    </p>
+                </div>
+            </template>
             <template slot-scope="{ row }" slot="createTime">
-				<span :style="{color:row.createTime ? '' : 'red' }">{{row.createTime ? $jsFn.dateFormat(row.createTime) : $t('ae.ae29')}}</span>
-			</template>
-			<!-- 1: 已提交 0 未提交 -->
-			<template slot-scope="{ row,index }" slot="action">
-				<Button type="primary" size="small" :disabled="!row.status" @click="viewHw(row)">
-                    {{$t('train.detail.hwView')}}
-                </Button>
-			</template>
-		</Table>
+                <span>{{row.createTime ? $jsFn.dateFormat(row.createTime) : '-'}}</span>
+            </template>
+        </Table>
         <!-- 分页 -->
-		<div class="page-wrap">
-			<Page show-total size="small" :current="currentPage" :total="workData.length" :page-size="pageSize" @on-change="pageChange"/>
-		</div>
+        <div class="page-wrap">
+            <Page show-total size="small" :current="currentPage" :total="workData.length" :page-size="pageSize" @on-change="pageChange" />
+        </div>
         <!-- 作业附件预览 -->
-        <Modal v-model="hwViewStatus" width="900">
+        <Modal footer-hide v-model="hwViewStatus" width="900" @on-visible-change="closeViewModal">
             <div slot="header">
-                <span>{{viewInfo ? viewInfo.name : $t('train.detail.viewHwTitle')}}{{$t('td.td66')}}{{$t('train.detail.hwFile')}}</span>
+                <span>{{$t('train.detail.hwFile')}}</span>
             </div>
-            <div v-if="viewInfo && viewInfo.files" style="min-height:150px">
-                <span :class="['hw-file-item', file.name ? 'hw-file-item-active':'']" v-for="file in viewInfo.files" :key="file.name" @click="handlePreviewHw(file)">
-                    {{file.name}}
-                </span>
-                <div v-if="hwPreviewFile.type === 'image' || hwPreviewFile.type === 'video' || hwPreviewFile.type === 'audio'" style="margin-top:20px">
-                    <video v-if="hwPreviewFile.type == 'video'" id="previewVideo" autoplay :src="hwPreviewFile.url+schoolSas.sas" width="870" controls="controls" style="max-height: 800px;">
-                        {{$t('teachContent.tips8')}}
-                    </video>
-                    <audio v-else-if="hwPreviewFile.type == 'audio'" controls>
-                        <source :src="hwPreviewFile.url+schoolSas.sas">
-                        {{$t('teachContent.notAudio')}}
-                    </audio>
-                    <img v-else-if="hwPreviewFile.type == 'image'" :src="hwPreviewFile.url+schoolSas.sas" style="border-radius: 5px;max-height: 800px;max-width:870px;" />
-                </div>
+            <div v-if="hwPreviewFile.type === 'image' || hwPreviewFile.type === 'video' || hwPreviewFile.type === 'audio'" style="margin-top:20px">
+                <video v-if="hwPreviewFile.type == 'video'" id="previewVideo" autoplay :src="hwPreviewFile.url+schoolSas.sas" width="870" controls="controls" style="max-height: 800px;">
+                    {{$t('teachContent.tips8')}}
+                </video>
+                <audio v-else-if="hwPreviewFile.type == 'audio'" controls>
+                    <source :src="hwPreviewFile.url+schoolSas.sas">
+                    {{$t('teachContent.notAudio')}}
+                </audio>
+                <img v-else-if="hwPreviewFile.type == 'image'" :src="hwPreviewFile.url+schoolSas.sas" style="border-radius: 5px;max-height: 800px;max-width:870px;" />
             </div>
         </Modal>
     </div>
@@ -62,38 +55,33 @@
 
 <script>
 export default {
-    props:{
-        taskInfo:{
+    props: {
+        taskInfo: {
             type: Object,
-            default:()=>{
+            default: () => {
                 return {}
             }
         },
-        subjectList: {
-			type: Array,
-			default: () => {
-				return []
-			}
-		},
-        classList:{
-			type: Array,
-			default: () => {
-				return []
-			}
-		},
+        curClass: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        subjectId: {
+            type: String,
+            default: ''
+        }
     },
-    data(){
+    data() {
         let _this = this
         return {
-            schoolSas:{},
-            hwPreviewFile:{},
-            hwViewStatus:false,
-            viewInfo:{},
-            pageSize:10,
-            currentPage:1,
-            subjectId:'',
-            classId:'',
-            tableColumn:[
+            schoolSas: {},
+            hwPreviewFile: {},
+            hwViewStatus: false,
+            pageSize: 10,
+            currentPage: 1,
+            tableColumn: [
                 {
                     title: this.$t('learnActivity.score.column1'),
                     key: "name",
@@ -101,32 +89,32 @@ export default {
                     width: 150,
                 },
                 {
-                    title: _this.$t('ae.ae36'),
-                    slot: "createTime",
+                    title: this.$t('td.td182'),
+                    slot: "status",
+                    align: "center",
+                },
+                {
+                    title: this.$t('cusMgt.rcd.file'),
+                    slot: "files",
                     align: "center",
                 },
                 {
-                    title: ' ',
-                    slot: "action",
+                    title: _this.$t('ae.ae36'),
+                    slot: "createTime",
                     align: "center",
-                    fixed: "right",
-                    width: 130,
                 }
             ],
-            tableData:[],
-            workData:[],
-            tableLoading:false
+            tableData: [],
+            workData: [],
+            tableLoading: false
         }
     },
-    computed:{
-		curClass(){
-			if(this.classList && this.classList.length && this.classId){
-				return this.classList.find(item=>item.id == this.classId)
-			}
-			return undefined
-		}
-	},
-    methods:{
+    methods: {
+        closeViewModal(status) {
+            if (!status) {
+                this.hwPreviewFile = {}
+            }
+        },
         /**
          * 预览/下载作业文件
          * @param {string} type video 删除研修视频 file 删除资料
@@ -134,16 +122,17 @@ export default {
         handlePreviewHw(info) {
             if (info.type === 'image' || info.type === 'video' || info.type === 'audio') {
                 this.hwPreviewFile = info
+                this.hwViewStatus = true
             } else if (info.type === 'doc') {
                 this.hwPreviewFile = info
                 if (info.extension === 'PDF') {
-                    window.open('/web/viewer.html?file=' + encodeURIComponent(info.url+this.schoolSas.sas))
+                    window.open('/web/viewer.html?file=' + encodeURIComponent(info.url + this.schoolSas.sas))
                 } else {
-                    window.open('https://view.officeapps.live.com/op/view.aspx?src=' + encodeURIComponent(info.url+this.schoolSas.sas))
+                    window.open('https://view.officeapps.live.com/op/view.aspx?src=' + encodeURIComponent(info.url + this.schoolSas.sas))
                 }
             } else {
                 this.hwPreviewFile = info
-                this.downloadTrainFile(info.url+this.schoolSas.sas, info.name)
+                this.downloadTrainFile(info.url + this.schoolSas.sas, info.name)
             }
         },
         downloadTrainFile(url, name) {
@@ -159,10 +148,6 @@ export default {
             }
             downloadRes()
         },
-        viewHw(studentInfo) {
-            this.viewInfo = studentInfo
-            this.hwViewStatus = true
-        },
         // 分页页面变化
         pageChange(page) {
             let start = this.pageSize * (page - 1)
@@ -170,46 +155,46 @@ export default {
             this.currentPage = page
             this.tableData = this.workData.slice(start, end)
         },
-        getWorkId(){
-            let task = this.taskInfo?.task?.find(item=>item.subject == this.subjectId)
-            if(task) {
+        getWorkId() {
+            let task = this.taskInfo?.task?.find(item => item.subject == this.subjectId)
+            if (task) {
                 return task.acId
-            }else{
+            } else {
                 return undefined
             }
         },
-        findArtWorkData(){
+        findArtWorkData() {
             let workId = this.getWorkId()
-            if(!workId || !this.subjectId || !this.classId) return
-            this.workData = []
+            if (!workId || !this.subjectId || !this.curClass.id) return
             let req = {
                 id: workId,
                 subject: this.subjectId,
-                classId: this.classId
+                classId: this.curClass.id
             }
             this.$api.areaArt.findArtWork(req).then(
-                res=>{
-                    if(res?.works)this.setTableData(res.works)
+                res => {
+                    if (res?.works) this.setTableData(res.works)
                 },
-                err=>{
+                err => {
 
                 }
             )
         },
-        setTableData(data){
-            if(this.curClass && this.curClass.members){
+        setTableData(data) {
+            this.workData = []
+            if (this.curClass && this.curClass.members) {
                 let students = this._.cloneDeep(this.curClass.members)
-                students.forEach(s=>{
-                    let work = data.find(w=>w.stuId === s.id)
+                students.forEach(s => {
+                    let work = data.find(w => w.stuId === s.id)
                     let hasWork = work && work.attachments?.length
                     let info = {
-                        id:s.id,
-                        name:s.name,
+                        id: s.id,
+                        name: s.name,
                     }
                     info.status = hasWork ? 1 : 0
                     info.createTime = hasWork ? work.attachments[0].createTime : 0
-                    info.count =  hasWork ? work.attachments.length : 0
-                    info.files = hasWork ? work.attachments :[]
+                    info.count = hasWork ? work.attachments.length : 0
+                    info.files = hasWork ? work.attachments : []
                     this.workData.push(info)
                 })
             }
@@ -223,38 +208,31 @@ export default {
             this.tableData = this.workData.slice(start, end)
         },
     },
-    watch:{
-        subjectList:{
-            immediate:true,
-            deep:true,
-            handler(n,o){
-                if(n && n.length){
-                    this.subjectId = n[0].id
+    watch: {
+        subjectId: {
+            immediate: true,
+            handler(n, o) {
+                if (n) {
                     this.findArtWorkData()
-                }else{
-                    this.subjectId = ''
                 }
             }
         },
-        classList:{
-            immediate:true,
-            deep:true,
-            handler(n,o){
-                if(n && n.length){
-                    this.classId = n[0].id
+        curClass: {
+            immediate: true,
+            deep: true,
+            handler(n, o) {
+                if (n && n.id) {
                     this.findArtWorkData()
-                }else{
-                    this.classId = ''
                 }
             }
         }
     },
-    created(){
+    created() {
         this.$tools.getSchoolSas().then(
-            res=>{
+            res => {
                 this.schoolSas = res
             },
-            err=>{
+            err => {
 
             }
         )
@@ -263,8 +241,32 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.work-data{
-    padding: 5px 5px;
-    background: #f9f9f9;
+.page-wrap {
+    margin-top: 15px;
+}
+
+.file-icon {
+    display: inline-block;
+    img {
+        display: inline-block;
+        margin-right: 5px;
+        vertical-align: inherit;
+        border-radius: 2px;
+        width: 15px;
+    }
+}
+.work-data {
+    padding: 10px 10px;
+    border-radius: 6px;
+    background: #f0f0f0;
+}
+</style>
+<style lang="less">
+.work-file-name {
+    display: inline-block;
+}
+.work-file-name:hover {
+    color: #2d8cf0;
+    text-decoration: underline;
 }
 </style>

+ 0 - 17
TEAMModelOS/ClientApp/src/view/learnactivity/ExamMgt.less

@@ -139,29 +139,12 @@
     color: @second-textColor;
     position: relative;
 
-    .edit-evaluation {
-        float: right;
-        margin-right: 45px;
-        display: inline-block;
-        cursor: pointer;
-        color: white;
-    }
-
-    .edit-evaluation:hover {
-        color: aqua;
-    }
-
     .evalustion-bar-item {
         display: inline-block;
         cursor: pointer;
         user-select: none;
         line-height: 38px;
     }
-
-    .evalustion-bar-item-active {
-        color: white;
-        border-bottom: 2px solid white;
-    }
 }
 .evaluation-base-info {
     width: 100%;

+ 98 - 0
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -1341,6 +1341,104 @@ namespace TEAMModelOS.Controllers.Client
             return Ok(volumes);
         }
 
+        //取得被分享的課綱
+        [ProducesDefaultResponseType]
+        [Authorize(Roles = "HiTeach")]
+        [HttpPost("get-share-syllabus")]
+        public async Task<IActionResult> GetShareSyllabusList(JsonElement request)
+        {
+            //Header驗證
+            string id_token = HttpContext.GetXAuth("IdToken");
+            if (string.IsNullOrEmpty(id_token)) return BadRequest();
+            var jwt = new JwtSecurityToken(id_token);
+            if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
+            var id = jwt.Payload.Sub;
+            //參數驗證
+            string volumeId = (request.TryGetProperty("volumeId", out JsonElement volumeIdJobj)) ? volumeIdJobj.GetString() : String.Empty;
+            string syllabusId = (request.TryGetProperty("syllabusId", out JsonElement syllabusIdJobj)) ? syllabusIdJobj.GetString() : String.Empty;
+            int display = (request.TryGetProperty("display", out JsonElement displayJobj)) ? displayJobj.GetInt32() : 0;
+            var client = _azureCosmos.GetCosmosClient();
+
+            //取得分享內容
+            List<Volume> volumeList = new List<Volume>();
+            StringBuilder queryText = new StringBuilder("SELECT value(c) FROM c WHERE c.type='share' ");
+            if (!string.IsNullOrWhiteSpace(volumeId))
+            {
+                queryText.Append($"AND c.volumeId='{volumeId}'");
+            }
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Share>(queryText: queryText.ToString(),
+            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Share-share-{id}") }))
+            {
+                
+                if(!string.IsNullOrWhiteSpace(syllabusId))
+                {
+                    if(item.id.Equals(syllabusId))
+                    {
+                        Volume volumeExist = volumeList.Where((Volume v) => v.id == item.volumeId).FirstOrDefault();
+                        if(volumeExist == null)
+                        {
+                            Volume volume = new Volume();
+                            volume.id = item.volumeId;
+                            volume.name = item.volumeName;
+                            volume.creatorId = item.issuer;
+                            volume.creatorName = item.issuerName;
+                            volume.syllabusIds.Add(item.id);
+                            volumeList.Add(volume);
+                        }
+                        else
+                        {
+                            volumeExist.syllabusIds.Add(item.id);
+                        }
+                    }
+                }
+                else
+                {
+                    Volume volumeExist = volumeList.Where((Volume v) => v.id == item.volumeId).FirstOrDefault();
+                    if (volumeExist == null)
+                    {
+                        Volume volume = new Volume();
+                        volume.id = item.volumeId;
+                        volume.name = item.volumeName;
+                        volume.creatorId = item.issuer;
+                        volume.creatorName = item.issuerName;
+                        volume.syllabusIds.Add(item.id);
+                        volumeList.Add(volume);
+                    }
+                    else
+                    {
+                        volumeExist.syllabusIds.Add(item.id);
+                    }
+                }
+            }
+
+            //取得課綱並輸出回傳值
+            List<object> result = new List<object>();
+            foreach(Volume volTmp in volumeList)
+            {
+                List<SyllabusTreeNode> treeNodes = new();
+                if (!display.Equals(1))
+                {
+                    string queryTextSyl = $"SELECT value(c) FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(volTmp.syllabusIds)}, c.id, true)";
+                    await foreach (Syllabus items in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Syllabus>(queryText: queryTextSyl, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{volTmp.creatorId}") }))
+                    {
+                        List<SyllabusTree> trees = SyllabusService.ListToTree(items.children);
+                        SyllabusTreeNode tree = new() { id = items.id, scope = items.scope, trees = trees, volumeId = items.volumeId, auth = items.auth, codeval = $"{volTmp.creatorId}" };
+                        treeNodes.Add(tree);
+                    }
+                }
+                result.Add(new
+                {
+                    id = volTmp.id,
+                    name = volTmp.name,
+                    creatorId = volTmp.creatorId,
+                    creatorName = volTmp.creatorName,
+                    syllabusIds = volTmp.syllabusIds,
+                    syllabus = treeNodes.ToList()
+                });
+            }
+            return Ok(result);
+        }
+
         //取得某班級的學生成員
         [ProducesDefaultResponseType]
         [HttpPost("get-students-list")]