Explorar o código

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10000/TEAMMODEL/TEAMModelOS into develop5.0-tmd

CrazyIter_Bin %!s(int64=4) %!d(string=hai) anos
pai
achega
8eb80e8176

+ 2 - 2
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/mission-list-card-new.css

@@ -9,7 +9,7 @@
   cursor: pointer;
 }
 .list-new-icon {
-  width: 10%;
+  width: 9%;
   margin-right: 20px;
 }
 .list-new-icon .svg-icon {
@@ -17,7 +17,7 @@
   height: 40px;
 }
 .list-new-title {
-  width: 70%;
+  width: 68%;
   font-weight: bolder;
   font-size: 14px;
   line-height: 22px;

+ 2 - 2
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/mission-list-card-new.less

@@ -10,7 +10,7 @@
     }
 
     &-icon{
-        width: 10%;
+        width: 9%;
         margin-right: 20px;
 
         .svg-icon{
@@ -20,7 +20,7 @@
     }
 
     &-title{
-        width: 70%;
+        width: 68%;
         font-weight: bolder;
         font-size: 14px;
         line-height: 22px;

+ 1 - 10
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/paper-test.css

@@ -684,21 +684,12 @@
         /* overflow-y: scroll; */
         /* font-size: 18px; */
     }
-}
-@media screen and (max-width: 767px) {
-    
-}
-@media screen and (max-width: 767px) {
-    
-}
-@media screen and (max-width: 767px) {
-    
 }
 @media screen and (max-width: 680px) {
     .lesson-test-pop .myProgressBar {
         display: none;
     }
 }
-@media screen and (max-width: 767px) {
+@media screen and (max-width: 500px) {
     
 }

+ 34 - 39
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/vote.css

@@ -1,14 +1,40 @@
+/*常用色票*/
+/*回傳的狀態文字,標題段落的方框,分頁*/
+/*標題類型的標記,編序教材附件按鈕*/
+/*各類項目的懸停與選中狀態*/
+.vote .vote-option {
+  margin-top: 15px;
+  margin-bottom: 10px;
+}
+.vote .vote-option .option-group {
+  display: flex;
+  flex-direction: column;
+}
+.vote .vote-option .option-group .option-wrapper {
+  margin-bottom: 15px;
+  display: flex;
+  align-items: center;
+}
+.vote .vote-option .option-group .option-wrapper .ivu-checkbox {
+  margin-right: 5px;
+}
+.vote .option-repeat .ivu-checkbox {
+  display: none;
+}
+.vote .option-repeat .ivu-input-number {
+  width: 50px;
+}
 .vote .checkAnswer {
-    display: inline-flex;
-    min-width:100px;
-    margin-top: 15px;
-    margin-right:20px;
+  display: block;
+  margin-top: 20px;
+  margin-left: 0px;
 }
 .vote .checkAnswer .testBtn {
-  margin: 10px 0px;
+  margin: 20px 0px;
   position: relative;
   z-index: 2;
   font-weight: bolder;
+  padding-left: 20px;
   cursor: pointer;
 }
 .vote .checkAnswer .testBtn input[type="checkbox"] {
@@ -20,10 +46,6 @@
   border: none;
 }
 .vote .checkAnswer .testBtn input[type="checkbox"]:checked ~ .testbg span {
-  color: #5e5a6e;
-  font-weight: bolder;
-}
-.vote .checkAnswer .testBtn input[type="checkbox"]:checked ~ .testbg .vote-info {
   color: #fff;
   font-weight: bolder;
 }
@@ -35,20 +57,9 @@
   top: -31px;
   padding: 10px;
   z-index: 1;
+  display: flex;
   border-radius: 4px;
   border: 1px solid #c5c5c5;
-  display:flex;
-}
-    .vote  .vote-title {
-        width: 100%;
-        /*display: flex;*/
-}
-    .vote .vote-title .title-rect-group{
-        display:flex;
-    }
-.vote .checkAnswer .testbg .vote-info{
-    width:95%;
-    display:flex;
 }
 .vote .slide-fade-enter-active {
   transition: all 0.3s ease;
@@ -61,11 +72,6 @@
   transform: translateY(-5%);
   opacity: 0;
 }
-.vote .question-box {
-    display: flex;
-    margin-top: 10px;
-    font-size: 16px;
-}
 .vote .votefinished-icon {
   font-size: 80px;
   position: relative;
@@ -74,7 +80,7 @@
 }
 .vote .voteResultsItem {
   padding: 10px 20px;
-  /*padding-left: 80px;*/
+  padding-left: 80px;
   z-index: 0 !important;
   position: relative;
 }
@@ -106,19 +112,8 @@
 .vote .vote-chart-card {
   width: 50%;
 }
-.vote .select-voteTime{
-    margin-top:15px;
-}
-.vote .select-voteTime h3{
-   display:inline-flex;
-   width:100%;
-}
-.vote .select-voteBox{
-    float:right;
-    margin-top:-25px;
-}
 @media screen and (max-width: 1200px) {
-    .vote .vote-chart-card {
+  .vote .vote-chart-card {
     width: 70%;
   }
 }

+ 29 - 0
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/vote.less

@@ -1,6 +1,35 @@
 @import 'color.less';
 .vote {
     //投票區按鈕
+    .vote-option{
+        margin-top: 15px;
+        margin-bottom: 10px;
+
+        .option-group{
+            display: flex;
+            flex-direction: column;
+
+            .option-wrapper{
+                margin-bottom: 15px;
+                display: flex;
+                align-items: center;
+                // font-weight: 600;
+
+                .ivu-checkbox{
+                    margin-right: 5px;
+                }
+            }
+        }
+    }
+    .option-repeat{
+        .ivu-checkbox{
+            display: none;
+        }
+        .ivu-input-number{
+            width: 50px;
+        }
+    }
+
     .checkAnswer {
         display: block;
         margin-top: 20px;

+ 84 - 83
TEAMModelOS/ClientApp/src/components/student-web/EventBasicInfo.vue

@@ -1,97 +1,98 @@
 <template>
-  <Row :gutter="30">
-    <i-col :xs="24" :sm="24" :md="24" :lg="getCurrentLang()=='tw'?12:24" class="title-part">
-      <h2 class="event-title">
-        <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'exam'" >{{$t("studentWeb.home.exam")}}</span>
-        <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'vote'" >{{$t("studentWeb.home.vote")}}</span>
-        <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'survey'" >{{$t("studentWeb.home.survey")}}</span>
-        {{ this.$store.getters.getItemTitle.name }}
-      </h2>
-    </i-col>
-    <i-col :xs="24" :sm="24" :md="24" :lg="getCurrentLang()=='tw'?12:24" class="info-part">
-      <ul class="base-info" :class="{'base-infoEn':getCurrentLang()=='en'}">
-        <li
-          v-if="this.$store.getters.getItemTitle.eventType == 'exam' && paper.length !== 0 "
-        >
-          <svg-icon icon-class="subject" class="base-info-icon" />{{ $t('studentWeb.baseInfo.subject')}}
-        <span class="base-info-text">{{paper.length > 1? $t('studentWeb.event.allSubject'):paper[0].subject.name }}</span>
-          <!--<span class="base-info-text" v-if="getCurrentLang()=='en'">{{ transSubjecttoEn(this.$store.getters.getItemTitle.eventSubject) }}</span>-->
-        </li>
-        <!--<li>
-          <svg-icon icon-class="teacher" class="base-info-icon" />投票类型:
-          <span class="base-info-text">{{ this.$store.getters.getItemTitle.times }}</span>
-        </li>-->
-        <li>
-          <svg-icon icon-class="time" class="base-info-icon" />
-          <span>{{ !eventType ?  $t('studentWeb.baseInfo.period') :  $t('studentWeb.baseInfo.postTime') }}</span>
-          <span class="base-info-text" v-if="from != '通知'&&from != 'hiteach'">
-              <span>
-                  {{ !eventType ? dateFormat(this.$store.getters.getItemTitle.startTime) + "~" : ""}}
-              </span>
-              {{ dateFormat(this.$store.getters.getItemTitle.endTime) }}
-          </span>
-          <!--<span
-            class="base-info-text"
-            v-if="from == '通知'||from == 'hiteach'"
-          >{{ this.$store.getters.getItemTitle.endTime + " 14:20" }}54345</span>-->
-        </li>
-        <!--<li v-if=" from == 'hiteach'">
-           <svg-icon icon-class="time" class="base-info-icon" />{{$t('studentWeb.baseInfo.classTime')}}:
-          <span class="base-info-text">{{ this.$store.getters.getItemTitle.endTime }}</span>
-        </li>-->
-        <!--<li v-if="finishedCondition && !eventType && from != '通知'&&from!='hiteach'">
-           <svg-icon icon-class="done" class="base-info-icon" />
-          <span class="base-info-text">{{ $t('studentWeb.baseInfo.Fineshed')}}</span>
-        </li>
-        <li v-if="unfinishedCondition && !eventType && from != '通知'&&from!='hiteach'">
-           <svg-icon icon-class="undone" class="base-info-icon" />
-          <span class="base-info-text">{{ $t('studentWeb.baseInfo.unFinished')}}</span>
-        </li>-->
-      </ul>
-    </i-col>
-  </Row>
+    <Row :gutter="30">
+        <i-col :xs="24" :sm="24" :md="24" :lg="getCurrentLang() == 'tw' ? 12 : 24" class="title-part">
+            <h2 class="event-title">
+                <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'exam'" >{{$t("studentWeb.home.exam")}}</span>
+                <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'vote'" >{{$t("studentWeb.home.vote")}}</span>
+                <span class="title-mark" v-show="this.$store.getters.getItemTitle.eventType == 'survey'" >{{$t("studentWeb.home.survey")}}</span>
+                {{ this.$store.getters.getItemTitle.name }}
+            </h2>
+        </i-col>
+        <i-col :xs="24" :sm="24" :md="24" :lg="getCurrentLang() == 'tw' ? 12 : 24" class="info-part">
+            <ul class="base-info" :class="{'base-infoEn': getCurrentLang() == 'en'}">
+                <li
+                  v-if="this.$store.getters.getItemTitle.eventType == 'exam' && paper.length !== 0 "
+                >
+                    <svg-icon icon-class="subject" class="base-info-icon" />{{ $t('studentWeb.baseInfo.subject')}}
+                    <span class="base-info-text">{{paper.length > 1 ? $t('studentWeb.event.allSubject') : paper[0].subject.name }}</span>
+                    <!-- <span class="base-info-text" v-if="getCurrentLang()=='en'">{{ transSubjecttoEn(this.$store.getters.getItemTitle.eventSubject) }}</span> -->
+                </li>
+                <!--<li>
+                    <svg-icon icon-class="teacher" class="base-info-icon" />投票类型:
+                    <span class="base-info-text">{{ this.$store.getters.getItemTitle.times }}</span>
+                </li>-->
+                <li>
+                    <svg-icon icon-class="time" class="base-info-icon" />
+                    <span>{{ !eventType ? $t('studentWeb.baseInfo.period') : $t('studentWeb.baseInfo.postTime') }}</span>
+                    <span class="base-info-text" v-if="from != '通知' && from != 'hiteach'">
+                        <span>
+                            {{ !eventType ? dateFormat(this.$store.getters.getItemTitle.startTime) + "~" : ""}}
+                        </span>
+                        {{ dateFormat(this.$store.getters.getItemTitle.endTime) }}
+                    </span>
+                    <!--<span
+                      class="base-info-text"
+                      v-if="from == '通知'||from == 'hiteach'"
+                    >{{ this.$store.getters.getItemTitle.endTime + " 14:20" }}54345</span>-->
+                </li>
+                <!--<li v-if=" from == 'hiteach'">
+                    <svg-icon icon-class="time" class="base-info-icon" />{{$t('studentWeb.baseInfo.classTime')}}:
+                    <span class="base-info-text">{{ this.$store.getters.getItemTitle.endTime }}</span>
+                </li>-->
+                <!--<li v-if="finishedCondition && !eventType && from != '通知'&&from!='hiteach'">
+                    <svg-icon icon-class="done" class="base-info-icon" />
+                    <span class="base-info-text">{{ $t('studentWeb.baseInfo.Fineshed')}}</span>
+                </li>
+                <li v-if="unfinishedCondition && !eventType && from != '通知'&&from!='hiteach'">
+                    <svg-icon icon-class="undone" class="base-info-icon" />
+                    <span class="base-info-text">{{ $t('studentWeb.baseInfo.unFinished')}}</span>
+                </li>-->
+            </ul>
+        </i-col>
+    </Row>
 </template>
 
 <script>
 export default {
-  name: "EventBasicInfo",
-        props: [
-            "eventType", "from",
-            "paper"
-        ],
+    name: "EventBasicInfo",
+    props: [
+        "eventType",
+        "from",
+        "paper"
+    ],
 
-  computed: {
-    finishedCondition: function () {
-      return (
-        this.$store.getters.getItemTitle.isDone ||
-        this.$store.getters.getFinishedItem.includes(
-          this.$store.getters.getItemTitle.eventID
-        ) == true
-      );
+    computed: {
+        finishedCondition: function () {
+            return (
+                this.$store.getters.getItemTitle.isDone ||
+                this.$store.getters.getFinishedItem.includes(
+                  this.$store.getters.getItemTitle.eventID
+                ) == true
+            );
+        },
+        unfinishedCondition: function () {
+            return (
+                !this.$store.getters.getItemTitle.isDone &&
+                this.$store.getters.getFinishedItem.includes(
+                  this.$store.getters.getItemTitle.eventID
+                ) == false
+            );
+        },
     },
-    unfinishedCondition: function () {
-      return (
-        !this.$store.getters.getItemTitle.isDone &&
-        this.$store.getters.getFinishedItem.includes(
-          this.$store.getters.getItemTitle.eventID
-        ) == false
-      );
+    mounted() {
     },
+    methods: {
+        dateFormat(timestamp) {
+            var date = new Date(timestamp)
+            var Y = date.getFullYear() + '-'
+            var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+            var D = date.getDate() + ' '
+            return Y + M + D;
         },
-        mounted() {
+        getCurrentLang() {
+            return localStorage.getItem('lang');
         },
-        methods: {
-            dateFormat(timestamp) {
-                var date = new Date(timestamp)
-                var Y = date.getFullYear() + '-'
-                var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
-                var D = date.getDate() + ' '
-                return Y + M + D;
-            },
-    getCurrentLang() {
-      return localStorage.getItem('lang');
     },
-  },
 };
 </script>
 

+ 1 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue

@@ -594,6 +594,7 @@
                             if (this.examInfo.stuScore[i] == -1) {
                                 info.noAns++
                             } else if (this.examInfo.stuScore[i] == this.paperData[i].score && this.examInfo.stuScore[i] != -1) {
+                                // 得了满分才算做对
                                 info.right++
                             } else {
                                 info.wrong++

+ 14 - 13
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue

@@ -168,19 +168,6 @@
                 }
                 this.isLoad = false
             },
-            dateFormat(timestamp) {
-                var date = new Date(timestamp)
-                var Y = date.getFullYear() + '-'
-                var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
-                var D = date.getDate() + ' '
-                return Y + M + D;
-            },
-            hidehint() {
-                this.ishideHint = !this.ishideHint;
-            },
-            opentest: function () {
-                this.$store.commit("ToggleLessonTestPop");
-            },
             opentestWithSubject(item) {
                 if (item !== undefined) {
                     this.getPaper(item)
@@ -232,6 +219,20 @@
                     }
                 }
             },
+            /* =====未调用===== */
+            dateFormat(timestamp) {
+                var date = new Date(timestamp)
+                var Y = date.getFullYear() + '-'
+                var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+                var D = date.getDate() + ' '
+                return Y + M + D;
+            },
+            hidehint() {
+                this.ishideHint = !this.ishideHint;
+            },
+            opentest: function () {
+                this.$store.commit("ToggleLessonTestPop");
+            },
         },
         computed: {
             listData() {

+ 33 - 4
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue

@@ -33,14 +33,43 @@
                         <h2 class="title-rect-name">{{ $t("studentWeb.vote.bollotbox") }}</h2>
                         <p v-if="voteInfo.repeat" style="margin-left:15px;margin-top:2px">{{ $t("studentWeb.vote.surplusTickets")}} <span style="font-size:16px">{{voteCount}}</span><span> {{ $t("studentWeb.vote.tickets")}} </span></p>
                     </div>
-                    <Button v-show="isResult" style="float:right;margin-top:-30px" size="small" type="success" @click="showRes">
+                    <Button v-show="isResult"
+                            style="float:right;margin-top:-30px"
+                            size="small" type="success"
+                            @click="showRes"
+                    >
                         <span style="margin-left:5px">{{$t("studentWeb.vote.voteRes")}}</span>
                     </Button>
                 </div>
                 <!-- 投票内容 -->
-                <div class="question-box"><span v-html="voteInfo.description"></span></div>
-                <div>
-                    <div class="checkAnswer" v-for="(item, index) in voteInfo.options" :key="index">
+                <!-- <div class="question-box">
+                    <span v-html="voteInfo.description"></span>
+                </div> -->
+                <div class="vote-option">
+                    <!-- 1票
+                    <RadioGroup v-model="voteChecked" v-if="voteInfo.voteNum == 1" class="option-group">
+                        <Radio :label="item.code" v-for="(item, index) in voteInfo.options" :key="index" class="option-wrapper">
+                            <span v-html="item.value"></span>
+                        </Radio>
+                    </RadioGroup>
+                    多票  不重复
+                    <CheckboxGroup v-model="voteChecked" v-if="voteInfo.voteNum > 1 && !voteInfo.repeat" class="option-group">
+                        <Checkbox :label="item.code" v-for="(item, index) in voteInfo.options" :key="index" class="option-wrapper">
+                            <span v-html="item.value"></span>
+                        </Checkbox>
+                    </CheckboxGroup>
+                    多票  重复
+                    <CheckboxGroup v-model="voteChecked" v-if="voteInfo.voteNum > 1 && voteInfo.repeat" class="option-group option-repeat">
+                        <Checkbox :label="item.code" v-for="(item, index) in voteInfo.options" :key="index" class="option-wrapper">
+                            <InputNumber v-model="item.count"
+                                         :min="0"
+                                         size="small"
+                                         :formatter="value => `${value}` +$t('studentWeb.vote.tickets')"
+                            ></InputNumber>
+                            <span v-html="item.value"></span>
+                        </Checkbox>
+                    </CheckboxGroup> -->
+                    <div class="checkAnswer" v-for="(item, index) in voteInfo.options" :key="index">  
                         <label class="testBtn">
                             <input type="checkbox" :value="item" v-model="voteChecked" @click="getVote(item)" />
                             <div class="testbg">

+ 38 - 25
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -212,13 +212,14 @@
 </template>
 
 <script>
+import { mapGetters, mapState } from 'vuex';
     import PreviewProgressPie from "../EventView/PreviewProgressPie";
     export default {
         name: "EventList",
         mounted() { 
             this.getActivityInfo()
-            this.selectedCondition(this.$store.getters.getItemTitle);
-            if (this.$store.getters.getIsSelectedNow == false) {
+            this.selectedCondition(this.getItemTitle);
+            if (this.getIsSelectedNow == false) {
                 this.predealMockdatafirstItem();
             }
             this.scrollList();
@@ -299,22 +300,37 @@
                 } else this.isListNoItem = false;
             },
         },
+        computed: {
+            ...mapState({
+                studentProfile: state => state.user.studentProfile,
+                schoolCode: state => state.user.schoolCode,
+                userInfo: state => state.userInfo,
+            }),
+            ...mapGetters([
+                "getItemTitle",
+                "getIsSelectedNow",
+                "getisFromInfoPoptoScroll",
+                "getFilterType",
+                "getFinishedItem",
+                "getFinishedItemTime"
+            ])
+        },
         methods: {
             //获取活动信息数据
             getActivityInfo() {
                 this.eventList.length = 0
                 this.isListNoItem = true;
-                if (this.$store.state.user.studentProfile.classinfo.id !== "") {
-                    let classInfo = [this.$store.state.user.studentProfile.classinfo.id]
-                    if (this.$store.state.user.studentProfile.courses.length) {
-                        for (let item of this.$store.state.user.studentProfile.courses) {
+                if (this.studentProfile.classinfo.id !== "") {
+                    let classInfo = [this.studentProfile.classinfo.id]
+                    if (this.studentProfile.courses.length) {
+                        for (let item of this.studentProfile.courses) {
                             classInfo.push(item.id)
                         }
                     }
                     let params = {
-                        userid: this.$store.state.userInfo.sub,
+                        userid: this.userInfo.sub,
                         userType: "schoolid",
-                        school: this.$store.state.user.schoolCode
+                        school: this.schoolCode
                     }
                     this.$api.studentWeb.getActivityInfo(params).then(res => {
                         if (res) {
@@ -441,7 +457,7 @@
                     return true;
                 }
             },
-            //选择所有
+            // 选择所有
             selectAllType() {
                 this.eventTypeCheckers = '';
                 this.predealMockdatafirstItem();
@@ -474,12 +490,12 @@
                 this.$store.commit("SetTrytestCount", [0, 0, 0]);
             },
             scrollListfromInfoPop() {
-                if (this.$store.getters.getisFromInfoPoptoScroll == true) {
+                if (this.getisFromInfoPoptoScroll == true) {
                     //當從通知操作進行捲動時,將篩選條件清空
                     this.selectedEventStatusNow = this.$t('studentWeb.event.allStatus');
                     this.eventTypeCheckers = "";
                     let targetItem = document.getElementById(
-                        `event${this.$store.getters.getItemTitle.eventID}`
+                        `event${this.getItemTitle.eventID}`
                     );
                     let scrollList = document.querySelectorAll(
                         ".event-list .list-block"
@@ -502,8 +518,8 @@
             },
             selectedCondition(item) {
                 if (
-                    this.$store.getters.getIsSelectedNow == true &&
-                    this.$store.getters.getItemTitle.id == item.id
+                    this.getIsSelectedNow == true &&
+                    this.getItemTitle.id == item.id
                 ) {
                     return true;
                 } else return false;
@@ -550,7 +566,7 @@
             },
             sentEvenType(eventype) {
                 this.$store.commit("ChangeFilterType", eventype);
-                if (this.$store.getters.getFilterType == "all") {
+                if (this.getFilterType == "all") {
                     let filterListFinished = [],
                         filterListUnFinished = [];
                     for (let i = 0; i < this.mockdata.length; i++) {
@@ -571,7 +587,7 @@
                     }
                     this.defaultFirstItem = filterListUnFinished[0];
                     if (
-                        this.$store.getters.getIsSelectedNow == false &&
+                        this.getIsSelectedNow == false &&
                         this.defaultFirstItem != ""
                     ) {
                         this.sentSelectedEventTitle(this.defaultFirstItem);
@@ -581,34 +597,31 @@
                 }
             },
             eventypeSelected: function (type) {
-                if (this.$store.getters.getFilterType == type) return true;
+                if (this.getFilterType == type) return true;
                 else return false;
             },
             scrollList() {
             },
             showTheCurrentTab() {
                 if (
-                    (this.finishedListNoItem == false &&
-                        this.$store.getters.getItemTitle.isDone == true) ||
-                    this.$store.getters.getFinishedItem.includes(
-                        this.$store.getters.getItemTitle.eventID
-                    )
+                    (this.finishedListNoItem == false && this.getItemTitle.isDone == true)
+                    || this.getFinishedItem.includes(this.getItemTitle.eventID)
                 )
                     return "tab2";
                 else return "tab1";
             },
             finishedcondition(item) {
-                if (this.$store.getters.getFinishedItem.includes(item.eventID) == true) {
+                if (this.getFinishedItem.includes(item.eventID) == true) {
                     this.havejustfinishedItem = true;
                     return true;
                 } else return false;
             },
             finishedItemtime(item) {
-                if (this.$store.getters.getFinishedItem.includes(item.eventID) == true) {
-                    let timeIndex = this.$store.getters.getFinishedItem.indexOf(
+                if (this.getFinishedItem.includes(item.eventID) == true) {
+                    let timeIndex = this.getFinishedItem.indexOf(
                         item.eventID
                     );
-                    return this.$store.getters.getFinishedItemTime[timeIndex];
+                    return this.getFinishedItemTime[timeIndex];
                 }
             },
         },

+ 25 - 4
TEAMModelOS/ClientApp/src/components/syllabus/DragTree.vue

@@ -10,11 +10,11 @@
 						<!-- {{data.id}} -->
 						<Icon type="md-cube" :title="$t('syllabus.tree.hasResource')" v-if="data.rnodes && data.rnodes.length" />
 					</span>
-					<span class="custom-tree-tools" v-if="editable">
+					<span class="custom-tree-tools" v-if="(hasEditAuth(data) || $access.can('admin.*|Syllabus_Edit'))">
 						<Icon type="md-create" size="16" :title="$t('syllabus.tree.edit')" @click="onEditItem(node,data,$event)" />
 						<Icon type="md-add" size="16" :title="$t('syllabus.tree.add')" @click="onAddNode(node,data,$event)" />
-						<Icon type="md-remove" size="16" :title="$t('syllabus.tree.remove')" @click="remove(node,data)" />
-						<Icon type="md-share" v-if="isFirstLevel(data)" :title="isSchool ? $t('syllabus.tree.coEdit') : $t('syllabus.tree.share')"
+						<Icon type="md-remove" size="16" :title="$t('syllabus.tree.remove')" @click="remove(node,data)" v-if="!isFirstLevel(data) ||  (canDeleteChapter(data) && isFirstLevel(data))"/>
+						<Icon type="md-share" v-if="isFirstLevel(data) && canDeleteChapter(data)" :title="isSchool ? $t('syllabus.tree.coEdit') : $t('syllabus.tree.share')"
 							@click="doShare(data)" />
 					</span>
 				</span>
@@ -79,6 +79,7 @@
 					version: '',
 					type: '1',
 					children: [],
+					creatorId: this.$store.state.userInfo.TEAMModelId,
 					remark: '',
 					nodeKey: '',
 					pid: '',
@@ -233,6 +234,7 @@
 					newChild.nodeKey = newChild.id
 					newChild.pid = parentNode.id
 					newChild.code = parentNode.code
+					newChild.creatorId = this.$store.state.userInfo.TEAMModelId
 					newChild.children = []
 					newChild.resources = []
 					newChild.knowledges = []
@@ -286,11 +288,29 @@
 
 		},
 		computed: {
+			// 判断是否为一级节点
 			isFirstLevel() {
 				return data => {
 					return data.pid === this.volume.id
 				}
 			},
+			// 判断当前用户是否有当前节点的编辑权限(如果父节点有权限则下面的子节点相应都有操作权限)
+			hasEditAuth(){
+				return nodeData => {
+					let userId = this.$store.state.userInfo.TEAMModelId
+					// 判断是否为一级节点,如果是二级节点则需要拿对应的一级节点去做判断
+					let chapterId = nodeData.pid === this.volume.id ? nodeData.id : this.getChapterIdById(nodeData.id)
+					let chapterNode = this.treeDatas.find(i => i.id === chapterId)
+					console.log(this.volume);
+					return this.volume.creatorId === userId || (chapterNode.auth && chapterNode.auth.length && chapterNode.auth.map(i => i.tmdid).includes(userId))
+				}
+			},
+			// 判断当前用户是否可以删除当前章节
+			canDeleteChapter(){
+				return nodeData => {
+					return nodeData.creatorId === this.$store.state.userInfo.TEAMModelId
+				}
+			}
 		},
 		watch: {
 			// 监听课纲数据变化
@@ -307,7 +327,8 @@
 						firstNode.click();
 					})
 				},
-				immediate: true
+				immediate: true,
+				deep:true
 			},
 			// 监听课纲数据变化
 			volume: {

+ 95 - 28
TEAMModelOS/ClientApp/src/components/syllabus/InviteTeacher.vue

@@ -3,6 +3,14 @@
 		<div class="node-info">
 			<span>当前选择章节:</span>
 			<span class="node-name">{{ nodeInfo.title }}</span>
+			<br>
+			<br>
+			<div style="display: inline-block;" v-if="!isSchool">
+				<span>当前章节已分享教师:</span>
+				<!-- <span v-for="(item,index) in nodeInfo.auth" :key="item.tmdid" class="share-item">{{ item.tmdname }}( {{ item.tmdid }})</span> -->
+				<span v-if="!nodeInfo.auth || !nodeInfo.auth.length" style="color: #dacaca;">暂无数据</span>
+				<Tag closable color="success" v-for="(item,index) in nodeInfo.auth" :key="item.tmdid" @on-close="doDelShare(item,index)">{{ item.tmdname }}( {{ item.tmdid }})</Tag>
+			</div>
 		</div>
 		<div class="search-wrap" v-if="isSchool">
 			<Input v-model="searchVal"  placeholder="输入教师名字或ID查询..."
@@ -34,7 +42,7 @@
 					</div>
 					<p v-if="!curTeacher && hasSearchResult" class="search-none">暂未查询到相关结果</p>
 					<p v-if="hasSearchResult" class="re-search" @click="onReSearch">重新搜索</p>
-					<Button type="success" v-if="hasSearchResult"  @click="doShare">确认分享</Button>
+					<Button type="success" :laading="isShareLoading" v-if="hasSearchResult"  @click="doShare">确认分享</Button>
 				</div>
 			</div>
 		</div>
@@ -60,6 +68,7 @@
 		data() {
 			return {
 				isSchool:false,
+				isShareLoading:false,
 				hasSearchResult:false,
 				searchVal:'',
 				searchIdVal:'',
@@ -166,49 +175,100 @@
 				});
 			},
 			/* 修改共编权限 */
-			onSwitchChange(val,e){
-				let curVolume = this.$parent.$parent.curVolume
-				this.$api.syllabus.ShareTree({
-					"school": curVolume.school,
-					"scope": curVolume.scope,
-					"tmdInfo": [
-						{
-							"tmdid": val.id,
-							"tmdname": val.name
-						}
-					],
-					"coedit": true,
-					"share": false,
-					"issuer": this.$store.state.userInfo.TEAMModelId,
-					"opt": e ? 'add' : 'del',
-					"syllabusId": this.nodeInfo.id,
-					"syllabusName": this.nodeInfo.title,
-					"volumeId": curVolume.id,
-					"volumeName": curVolume.name
-				}).then(res => {
-					if(res.code === 200){
-						this.$Message.success('操作成功!')
+			onSwitchChange(val,isAdd){
+				this.sendShareApi(val.id,val.name,false,isAdd).then(res => {
+					this.$Message.success(isAdd ? '授权成功!' : '取消授权成功!')
+					if(isAdd){
+						this.nodeInfo.auth.push({
+							tmdid:val.id,
+							tmdname:val.name,
+							share:false,
+							coedit:true
+						})
+					}else{
+						this.nodeInfo.auth.splice(this.nodeInfo.auth.map(i => i.tmdid).indexOf(val.id),1)
 					}
-				}).catch(err => {
-					this.$Message.error(err)
 				})
 			},
 			/* 分享课纲操作 */
 			doShare(){
-				console.log(this.curTeacher);
-			}
+				let val = this.curTeacher
+				this.isShareLoading = true
+				this.sendShareApi(val.id,val.name,true,true).then(res => {
+					setTimeout(() => {
+						this.$Message.success('分享成功!')
+						this.nodeInfo.auth.push({
+							tmdid:val.id,
+							tmdname:val.name,
+							share:true,
+							coedit:false
+						})
+						this.isShareLoading = false
+						this.curTeacher = null
+						this.hasSearchResult = false
+						this.searchIdVal = ''
+					},500)
+				})
+			},
+			/* 取消分享操作 */
+			doDelShare(val,index){
+				this.$Modal.confirm({
+					title: '取消分享',
+					content: '确认取消对' + val.tmdname + '的分享?',
+					onOk: () => {
+						this.sendShareApi(val.tmdid,val.tmdname,true,false).then(res => {
+							this.nodeInfo.auth.splice(index,1)
+							this.$Message.success('取消分享成功!')
+							this.$forceUpdate()
+						})
+					}
+				});
+			},
+			/* 发送共编或者分享API请求 */
+			sendShareApi(toId,toName,isShare,isAdd){
+				return new Promise((r,j) => {
+					let curVolume = this.$parent.$parent.curVolume
+					this.$api.syllabus.ShareTree({
+						"school": curVolume.school,
+						"scope": curVolume.scope,
+						"tmdInfo": [
+							{
+								"tmdid": toId,
+								"tmdname": toName
+							}
+						],
+						"coedit": !isShare,
+						"share": isShare,
+						"issuer": this.$store.state.userInfo.TEAMModelId,
+						"opt": isAdd ? 'add' : 'del',
+						"syllabusId": this.nodeInfo.id,
+						"syllabusName": this.nodeInfo.title,
+						"volumeId": curVolume.id,
+						"volumeName": curVolume.name
+					}).then(res => {
+						if(res.code === 200){
+							r(200)
+						}
+					}).catch(err => {
+						this.$Message.error(err)
+						j(err)
+					})
+				})
+				
+			},
+			
 		},
 		mounted() {
 			this.isSchool && this.getAllTeacher()
 		},
 		computed:{
+			/* 判断当前用户是否已被授权 */
 			hasAuth(){
 				return id => {
 					if(!this.nodeInfo.auth){
 						return false
 					}else{
 						let matchItem = this.nodeInfo.auth.filter(i => i.tmdid === id)
-						console.log(matchItem)
 						if(matchItem.length && matchItem[0].coedit){
 							return true
 						}else{
@@ -241,6 +301,13 @@
 			}
 		}
 		
+		.share-item{
+			display: inline-block;
+			margin-left: 10px;
+			padding: 2px 5px;
+			background-color: #005C5F;
+		}
+		
 		.search-wrap{
 			.ivu-input-wrapper{
 				width: 300px;

+ 81 - 13
TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js

@@ -19,17 +19,8 @@ export default {
         privateVote: 'Personal vote',
         schoolSurvey: 'School Level Questionnaire',
         privateSurvey: 'Personal Questionnaire',
-        search: 'Please enter the query content...'
-    },
-    event: {
-        allStatus: 'All activity status',
-        unFinished: 'Unfinished',
-        Fineshed: 'Completed',
-        Timeout: 'Timeout',
-        makeupExam: 'Can make up the exam',
-        makeupHw: 'Can make up',
-        selectActivity: 'Please select an activity from the list',
-        allSubject: 'Comprehensive subjects'
+        search: 'Please enter the query content...',
+        notice: '此功能暂未开放!'
     },
     state: [
         {
@@ -45,6 +36,16 @@ export default {
             status: 'Completed'
         }
     ],
+    event: {
+        allStatus: 'All activity status',
+        unFinished: 'Unfinished',
+        Fineshed: 'Completed',
+        Timeout: 'Timeout',
+        makeupExam: 'Can make up the exam',
+        makeupHw: 'Can make up',
+        selectActivity: 'Please select an activity from the list',
+        allSubject: 'Comprehensive subjects'
+    },
     'settingView-title': 'Personal settings',
     'teammodel-account-management': {
         'page-title': 'TeamModel account management',
@@ -159,6 +160,52 @@ export default {
     },
     latestNotification: 'Latest notification',
     postAt: 'Posted on',
+    '______________': '______________',
+    'eventView-title': '活动任务',
+    nextTask: '下个活动',
+    allStatus: '所有活动状态',
+    unFinished: '未完成',
+    Fineshed: '已完成',
+    Timeout: '已逾时',
+    makeupExam: '可补考',
+    makeupHW: '可补交',
+    empty: '目前无资料 ~',
+    baseInfo: {
+        subject: '科目:',
+        teacher: '教师:',
+        period: '活动期限:',
+        postTime: '发布时间:',
+        classTime: '上课时间',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Closed: '已结束'
+    },
+    billboard: {
+        description: '描述',
+        referlink: '连结资料',
+        attachment: '附件',
+        reference: '参考资料'
+    },
+    preview: {
+        checkpoint: '活动任务',
+        tutorial: '编序教材',
+        multiQues: '多题闯关模组',
+        previewContent: {
+            tutorial: '教材',
+            Des: '内容',
+            Unit: '单元',
+            quiz: '随堂考'
+        },
+        previous: '上一题',
+        next: '下一题',
+        sentAns: '送出答案',
+        tryAgain: '详读教材,再试一次',
+        nextUnit: '下一单元',
+        goHome: '回到首页',
+        quizRetries: '测验重试次数',
+        crossUnitHint: '上个单元测验尚未完成,请先完成方可进行本单元测验',
+        timeoutHint: '课前预习活动时间已结束,仍可进行教材阅读与练习,如于结束时间前未完成,相关成绩可能受到影响。'
+    },
     vote: {
         bollotbox: 'Voting area',
         submit: 'OK to submit',
@@ -175,7 +222,10 @@ export default {
         warning: 'Voting failed, please check the voting information! ',
         warning2: 'The maximum number of votes has been exceeded! ',
         voteRes: 'Voting results',
-        voteRecord: 'Vote Record'
+        voteRecord: 'Vote Record',
+        voteTime: '投票时间',
+        noData: '暂无投票结果数据',
+        option: '选项',
     },
     homework: {
         homeworkUpload: 'Job upload area',
@@ -234,6 +284,7 @@ export default {
             onlywrong: 'Only practice the wrong answer',
             questions: 'The question',
             submitted: 'Submission of paper',
+            submitted1: "结束练习",
             finish: 'Completed',
             showAns: 'Show answers',
             hideAns: 'Hide the answer',
@@ -254,6 +305,13 @@ export default {
             conAnswer2: ', please complete the question first! ',
             conAnswer: 'Continue to answer',
             okSubmit: 'Confirm to submit the paper',
+            exitWrong: "离开错题练习提示",
+            exitWrongDe: "系统检测您尚未「结束练习」,如您选择「确定」,",
+            exitWrongDes: "则目前作答将不保存,下次需重新练习",
+            endPractice: "结束练习提示",
+            endPracticeDe: "是否继续练习?",
+            endPracticeBtn1: "继续练习",
+            endPracticeBtn2: "结束练习",
             qNo: 'Question number:',
             correction: 'right',
             queNo: 'Title:',
@@ -302,6 +360,7 @@ export default {
             student: 'person',
             keyPointPerformance: 'Knowledge point performance radar chart',
             me: 'personal',
+            participantClass: '全班',
             participantAverage: 'The whole school',
             recognizePerformance: 'Cognitive Level Radar Chart'
         },
@@ -347,7 +406,16 @@ export default {
         solution: 'Solution',
         analysis: 'Analysis',
         correctRate: 'correct answer rate',
-        relatedAQues: 'Related Questions'
+        relatedAQues: 'Related Questions',
+        answer: '作答',
+        inputAnswers: '请输入作答结果',
+        emput: '空'
+    },
+    queNaire: {
+        submitSuccess: '提交成功',
+        overTime: '不在作答时间范围内!',
+        answerErr: '作答数据错误!',
+        fileErr: '问卷获取失败!'
     },
     'informview-title': 'Notification overview',
     view: 'Go to view',

+ 0 - 2
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/studentWeb.js

@@ -226,8 +226,6 @@ export default {
         voteTime: '投票时间',
         noData: '暂无投票结果数据',
         option: '选项',
-
-
     },
     homework: {
         homeworkUpload: '作业上传区',

+ 22 - 12
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/studentWeb.js

@@ -20,17 +20,7 @@ export default {
         schoolSurvey: '校級問卷',
         privateSurvey: '個人問卷',
         search: '請輸入查詢內容...',
-        noitice: '此功能暫未開放!'
-    },
-    event: {
-        allStatus: '所有活動狀態',
-        unFinished: '未完成',
-        Fineshed: '已完成',
-        Timeout: '已逾時',
-        makeupExam: '可補考',
-        makeupHw: '可補交',
-        selectActivity: '請從列表中挑選一個活動',
-        allSubject: '所有學科'
+        notice: '此功能暫未開放!'
     },
     state: [
         {
@@ -46,6 +36,16 @@ export default {
             status: '已完成'
         }
     ],
+    event: {
+        allStatus: '所有活動狀態',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Timeout: '已逾時',
+        makeupExam: '可補考',
+        makeupHw: '可補交',
+        selectActivity: '請從列表中挑選一個活動',
+        allSubject: '所有學科'
+    },
     'settingView-title': '個人設定',
     'teammodel-account-management': {
         'page-title': 'TeamModel 帳號管理',
@@ -223,7 +223,9 @@ export default {
         warning2: '已超出最大投票數! ',
         voteRes: '投票結果',
         voteRecord: '投票記錄',
-        voteTime: '投票時間'
+        voteTime: '投票時間',
+        noData: '暫無投票結果數據',
+        option: '選項',
     },
     homework: {
         homeworkUpload: '作業上傳區',
@@ -282,6 +284,7 @@ export default {
             onlywrong: '只練習答錯',
             questions: '的題目',
             submitted: '交卷',
+            submitted1: "結束練習",
             finish: '已完成',
             showAns: '顯示答案',
             hideAns: '隱藏答案',
@@ -302,6 +305,13 @@ export default {
             conAnswer2: ',請先完成題目作答! ',
             conAnswer: '繼續作答',
             okSubmit: '確定交卷',
+            exitWrong: "離開錯題練習提示",
+            exitWrongDe: "系統檢測您尚未「結束練習」,如您選擇「確定」,",
+            exitWrongDes: "則現時作答將不保存,下次需重新練習",
+            endPractice: "結束練習提示",
+            endPracticeDe: "是否繼續練習?",
+            endPracticeBtn1: "繼續練習",
+            endPracticeBtn2: "結束練習",
             qNo: '題號:',
             correction: '正解',
             queNo: '題目:',

+ 3 - 2
TEAMModelOS/ClientApp/src/view/student-web/App.vue

@@ -132,7 +132,8 @@
         computed: {
             getRoleName() {
                 return val => {
-                    return val === 'student' ? '学生' : '教师'
+                    // return val === 'student' ? '学生' : '教师'
+                    return val === 'student' ? this.$t("studentWeb.home.student") : this.$t("studentWeb.home.teacher")
                 }
             },
             //判断用户权限
@@ -197,7 +198,7 @@
                 }
             },
             noData() {
-                this.$Message.warning('此功能暂未开放!')
+                this.$Message.warning(this.$t("studentWeb.public.notice"))
             },
             reload() {
                 this.isRouterAlive = false;

+ 73 - 9
TEAMModelOS/ClientApp/src/view/syllabus/Syllabus.vue

@@ -17,7 +17,7 @@
 				<span style="color: #F0F0F0;font-size: 18px;font-weight: bolder;">个人课纲</span>
 			</div>
 			<Button @click="onSaveSyllabus" class="btn-save-modify" icon="md-folder"
-				v-if="$access.can('admin.*|Syllabus_Edit') && hasModify">存储变更</Button>
+				v-if="(hasSyllabusAuth || hasEditAuth(curNode)) && hasModify">存储变更</Button>
 		</div>
 		<div class="syllabus-content">
 			<div class="syllabus-left">
@@ -26,9 +26,9 @@
 						<span>册别清单</span>
 						<span class="syllabus-content-header-tools">
 							<Icon type="md-search" @click="doSearchVolume" />
-							<Icon type="md-create" @click="doEditVolume" v-if="$access.can('admin.*|Syllabus_Edit')"/>
-							<Icon type="md-trash" @click="doDeleteVolume" v-if="$access.can('admin.*|Syllabus_Edit')"/>
-							<Icon type="md-add" @click="doAddVolume" v-if="$access.can('admin.*|Syllabus_Edit')"/>
+							<Icon type="md-create" @click="doEditVolume" v-if="hasSyllabusAuth"/>
+							<Icon type="md-trash" @click="doDeleteVolume" v-if="hasSyllabusAuth"/>
+							<Icon type="md-add" @click="doAddVolume" v-if="hasSyllabusAuth"/>
 						</span>
 					</div>
 					<div style="width: 90%;" v-else>
@@ -56,13 +56,13 @@
 				<div class="syllabus-content-header">
 					<span>课纲目录</span>
 					<span class="syllabus-content-header-tools">
-						<Icon type="md-add" @click="isAddTreeModal = true" v-if="$access.can('admin.*|Syllabus_Edit')"/>
+						<Icon type="md-add" @click="isAddTreeModal = true" v-if="hasSyllabusAuth"/>
 					</span>
 				</div>
 				<div class="syllabus-tree-box">
 					<EmptyData :top="-240" v-if="!treeOrigin.length"></EmptyData>
 					<Tree ref="treeRef" :treeData="treeOrigin" :volume="curVolume"
-						:editable="$access.can('admin.*|Syllabus_Edit')" @onNodeClick="onNodeClick" @doShare="doShare" @addModifyId="addModifyId"v-else></Tree>
+						:editable="hasSyllabusAuth || hasEditAuth(curNode)" @onNodeClick="onNodeClick" @doShare="doShare" @addModifyId="addModifyId"v-else></Tree>
 				</div>
 			</div>
 			<div class="syllabus-right">
@@ -70,7 +70,7 @@
 					<span>关联资源</span>
 					<span class="syllabus-content-header-tools">
 						<!-- <Icon type="md-add" @click="onAddResource" v-if="curNode.id"/> -->
-						<Dropdown @on-click="onAddResource" v-if="curNode.id">
+						<Dropdown @on-click="onAddResource" v-if="curNode.id && (hasSyllabusAuth || hasEditAuth(curNode))">
 							<a href="javascript:void(0)" style="color: #ddd;">
 								添加资源
 								<Icon type="ios-arrow-down"></Icon>
@@ -312,11 +312,13 @@
 					"id": "",
 					"pid": "",
 					"title": "",
+					"creatorId": this.$store.state.userInfo.TEAMModelId,
 					"type": 1,
 					"children": [],
 					"rnodes": []
 				},
-				modifyIdArr:[]
+				modifyIdArr:[],
+				flatArr:[]
 			}
 		},
 		created() {
@@ -452,6 +454,9 @@
 						}).then((res) => {
 							if (res) {
 								this.volumeList.splice(this.activeVolumeIndex, 1);
+								this.treeOrigin = []
+								this.curNode.rnodes = []
+								this.curNode.id = ''
 								this.$Message.success("删除成功");
 								this.onVolumeClick(this.volumeList.length ? this.volumeList[this
 									.activeVolumeIndex] : null, this.activeVolumeIndex)
@@ -474,6 +479,10 @@
 				}).then(res => {
 					if (!res.error) {
 						this.treeOrigin = res.tree
+						this.getAllChild(this.treeOrigin.map(i => {
+							i.trees[0].auth = i.auth
+							return i.trees[0]
+						}))
 					} else {
 						this.$Message.warning(res.error);
 						this.treeOrigin = []
@@ -488,6 +497,7 @@
 			onAddTreeNode() {
 				this.nodeInfo.id = this.$tools.guid()
 				this.nodeInfo.pid = this.curVolume.id
+				this.nodeInfo.creatorId = this.$store.state.userInfo.TEAMModelId
 				// 统一传给树形组件的数据结构
 				this.treeOrigin.push({
 					auth:null,
@@ -846,7 +856,7 @@
 						"status": 1,
 						"name": this.addVolumeForm.name || this.getDefaultVolumeName,
 						"creatorId": this.$store.state.userInfo.TEAMModelId,
-						"school": this.$store.state.userInfo.schoolCode,
+						"school": this.isSchool ? this.$store.state.userInfo.schoolCode : '',
 						"scope": this.curScope,
 						"syllabusIds":[]
 					}
@@ -854,6 +864,7 @@
 						addVolumeParams.id = this.curVolume.id
 						addVolumeParams.name = this.curVolume.name
 						addVolumeParams.syllabusIds = this.allChapterIds || []
+						addVolumeParams.creatorId = this.curVolume.creatorId
 					}
 					// 发送新增或者编辑册别请求
 					this.$api.syllabus.SaveOrUpdateVolume(addVolumeParams).then(res => {
@@ -872,6 +883,45 @@
 					})
 				})
 				
+			},
+			
+			/* 获取整个树的章节与子节点归属 */
+			getAllChild(arr){
+				let result = []
+				arr.forEach(item => {
+					result.push({
+						chapterId:item.id,
+						children:this.flatChildren(item.children)
+					})
+				})
+				this.flatArr = result
+			},
+			
+			/* 递归拉平所有children */
+			flatChildren(children){
+				let result = []
+				const fn = (source)=>{
+				    source.forEach(i => {
+				    	result.push(i.id)
+				    	if(i.children.length){
+				    		fn(i.children)
+				    	}
+				    })
+				}
+				fn(children)
+				return result
+			},
+			
+			/* 根据某个节点ID换取它对应的章节ID */
+			getChapterIdById(id){
+				if(this.flatArr.map(i => i.chapterId).includes(id)){
+					return id
+				}else{
+					console.log(this.flatArr)
+					console.log(id);
+					let targetChapter = this.flatArr.find(i => i.children.includes(id))
+					return targetChapter.chapterId
+				}
 			}
 		},
 		computed: {
@@ -906,6 +956,20 @@
 				return item => {
 					return item.type !== 'item' && item.type !== 'paper' && item.type !== 'link'
 				}
+			},
+			hasEditAuth(){
+				return nodeData => {
+					if(!nodeData.id) return false
+					let userId = this.$store.state.userInfo.TEAMModelId
+					// 判断是否为一级节点,如果是二级节点则需要拿对应的一级节点去做判断
+					let chapterId = nodeData.pid === this.curVolume.id ? nodeData.id : this.getChapterIdById(nodeData.id)
+					let chapterNode = this.treeOrigin.find(i => i.id === chapterId)
+					return this.curVolume.creatorId === userId || (chapterNode.auth && chapterNode.auth.length && chapterNode.auth.map(i => i.tmdid).includes(userId))
+				}
+			},
+			// 是否可以操作课纲模块(个人课纲或者管理员或者有课纲权限)
+			hasSyllabusAuth(){
+				return !this.isSchool || this.$access.can('admin.*|Syllabus_Edit')
 			}
 		},
 	}