Sfoglia il codice sorgente

Merge branch 'develop4.0-tmd' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop4.0-tmd

zhouj1203@hotmail.com 4 anni fa
parent
commit
7fd47b75ef

+ 9 - 2
TEAMModelOS/ClientApp/src/api/courseMgmt.js

@@ -8,6 +8,7 @@ export default {
     findCusInfo: function (data) {
         return post('/school/course/find-summary', data)
     },
+    //更新或者新增课程
     saveOrUpdateCourse: function (data) {
         return post('/school/course/upsert', data)
     },
@@ -69,7 +70,13 @@ export default {
     //更新保存标准课程公告
     upsertNotice: function (data) {
         return post('/school/course/upsert-notice', data)
+    },
+    //查询stulist
+    findStulist: function (data) {
+        return post('/school/course/find-list', data)
+    },
+    //添加或修改stulist
+    upsertStulist: function (data) {
+        return post('/school/course/upsert-list', data)
     }
-
-
 }

+ 3 - 0
TEAMModelOS/ClientApp/src/components/coursemgt/StudentList.less

@@ -14,6 +14,9 @@
 
 .student-filter-wrap{
     margin-bottom:10px;
+    display: flex;
+    justify-content: flex-end;
+    color: #a5a5a5;
 }
 .name-header {
     background: white;

+ 217 - 213
TEAMModelOS/ClientApp/src/components/coursemgt/StudentList.vue

@@ -1,18 +1,17 @@
 <template>
     <div class="dark-iview-table student-list">
         <div class="student-filter-wrap dark-iview-select dark-iview-input">
+            <span style="margin-top:6px">筛选条件:</span>
             <!-- 學制Select -->
             <Select v-model="searchPeriod" style="width:120px;" :placeholder="$t('stuAccount.periodHolder')" clearable @on-change="filterData" not-found-text="暂未归属学校">
                 <Option v-for="(item,index) in periods" :value="item.id" :key="index">{{ item.name }}</Option>
             </Select>
             <!-- 學級Select -->
-            <Select v-model="searchGrade" style="width:120px;margin-left:5px;" :placeholder="$t('stuAccount.gradeHolder')"
-                    not-found-text="请先选择学段" clearable @on-change="filterData">
+            <Select v-model="searchGrade" style="width:120px;margin-left:5px;" :placeholder="$t('stuAccount.gradeHolder')" not-found-text="请先选择学段" clearable @on-change="filterData">
                 <Option v-for="(item,index) in filterGrades" :value="item.id" :key="index">{{ item.name }}</Option>
             </Select>
             <!-- 教室Select -->
-            <Select v-model="searchClassroom" ref="classroom" style="width:150px;margin-left:5px;" :placeholder="$t('stuAccount.classroomHolder')"
-                    clearable @on-change="filterData" :not-found-text="searchGrade ? '此年级暂无教室':'请先选择年级'">
+            <Select v-model="searchClassroom" ref="classroom" style="width:150px;margin-left:5px;" :placeholder="$t('stuAccount.classroomHolder')" clearable @on-change="filterData" :not-found-text="searchGrade ? '此年级暂无教室':'请先选择年级'">
                 <Option v-for="(item,index) in filterClasses" :value="item.id" :key="index">{{ item.name }}</Option>
             </Select>
             <!-- 字串模糊搜尋 -->
@@ -25,7 +24,8 @@
                         <Icon custom="iconfont icon-auth-key" size="25" color="#565656" />
                     </template>
                     <template slot-scope="{ row,index }" slot="header">
-                        <span class="name-header" :style="{background:bgColor[index % 12]}">{{getFirstChart(row.name)}}</span>
+                        <!-- <span class="name-header" :style="{background:bgColor[index % 12]}">{{getFirstChart(row.name)}}</span> -->
+                        <PersonalPhoto :name="row.name" :picture="row.picture"></PersonalPhoto>
                     </template>
                     <template slot-scope="{ row }" slot="gradeId">
                         <span>{{ getGradeName(row.gradeId) }}</span>
@@ -53,235 +53,239 @@
     </div>
 </template>
 <script>
-    import { mapGetters } from 'vuex'
-    export default {
-        data() {
-            return {
-                bgColor: ['#4ECDC4', '#F99406', '#075CD0', '#F7CA17', '#F2774B', '#67809F', '#BF55ED', '#00B169', '#F72459', '#F15A22', '#03C9A8', '#9A1294'],
-                searchText: '',
-                searchPeriod: '',
-                searchGrade: '',
-                searchClassroom: '',
-                selections: [],
-                currentPage: 1,
-                pageSize: 20,
-                tableShowData: [],
-                tableColumns: [],
-                totalNum: 0,
-                tableLoading: false,
-                schoolData: {},
-                tableFilterData: [],
-                basicCount: 99,
-            }
-        },
-        methods: {
-            initData() {
-                this.tableColumns = [
-                    {
-                        type: 'selection',
-                        width: 80,
-                        align: 'center'
-                    },
-                    {
-                        slot: 'header',
-                        title: ' ',
-                        align: 'center',
-                        width: 150
-                    },
-                    {
-                        key: 'id',
-                        title: this.$t('stuAccount.account'),
-                        align: 'center',
-                        sortable: true,
-                        sortMethod: (a, b, type) => {
-                            if (type == 'asc') {
-                                return a.localeCompare(b)
-                            } else {
-                                return b.localeCompare(a)
-                            }
-                        }
-                    },
-                    {
-                        key: 'no',
-                        title: this.$t('stuAccount.seatNo'),
-                        align: 'center',
-                        width: 120,
-                        sortable: true,
-                        sortMethod: (a, b, type) => {
-                            if (type == 'desc') {
-                                return parseInt(a) > parseInt(b) ? -1 : 1
-                            } else {
-                                return parseInt(a) < parseInt(b) ? -1 : 1
-                            }
+import PersonalPhoto from '@/components/public/personalPhoto/Index.vue'
+import { mapGetters } from 'vuex'
+export default {
+    components: {
+        PersonalPhoto
+    },
+    data() {
+        return {
+            bgColor: ['#4ECDC4', '#F99406', '#075CD0', '#F7CA17', '#F2774B', '#67809F', '#BF55ED', '#00B169', '#F72459', '#F15A22', '#03C9A8', '#9A1294'],
+            searchText: '',
+            searchPeriod: '',
+            searchGrade: '',
+            searchClassroom: '',
+            selections: [],
+            currentPage: 1,
+            pageSize: 20,
+            tableShowData: [],
+            tableColumns: [],
+            totalNum: 0,
+            tableLoading: false,
+            schoolData: {},
+            tableFilterData: [],
+            basicCount: 99,
+        }
+    },
+    methods: {
+        initData() {
+            this.tableColumns = [
+                {
+                    type: 'selection',
+                    width: 80,
+                    align: 'center'
+                },
+                {
+                    slot: 'header',
+                    title: ' ',
+                    align: 'center',
+                    width: 150
+                },
+                {
+                    key: 'id',
+                    title: this.$t('stuAccount.account'),
+                    align: 'center',
+                    sortable: true,
+                    sortMethod: (a, b, type) => {
+                        if (type == 'asc') {
+                            return a.localeCompare(b)
+                        } else {
+                            return b.localeCompare(a)
                         }
-                    },
-                    {
-                        key: 'name',
-                        title: this.$t('stuAccount.stuName'),
-                        align: 'center'
-                    },
-                    {
-                        slot: 'gradeId',
-                        title: this.$t('stuAccount.grade'),
-                        align: 'center',
-                        width: 140
-                    },
-                    {
-                        slot: 'classId',
-                        title: this.$t('stuAccount.classroomName'),
-                        align: 'center'
                     }
-                ]
-            },
-            /**基础查询数据 */
-            baseFindStudent(params) {
-                this.$api.stuAccount.findStudent(this.$store.state.user.schoolCode).then(
-                    (res) => {
-                        this.tableLoading = false
-                        // 給一個 PW 讓AddStudent.vue 的Watch 可以動作
-                        let newStudents = res.students.map(function (item) {
-                            let temp = item
-                            temp.pw = '******'
-                            return temp
-                        })
-                        this.$store.dispatch('schoolBaseInfo/setStudentsToState', newStudents)
-                        this.filterData()
-                    },
-                    (err) => {
-                        this.tableLoading = false
+                },
+                {
+                    key: 'no',
+                    title: this.$t('stuAccount.seatNo'),
+                    align: 'center',
+                    width: 120,
+                    sortable: true,
+                    sortMethod: (a, b, type) => {
+                        if (type == 'desc') {
+                            return parseInt(a) > parseInt(b) ? -1 : 1
+                        } else {
+                            return parseInt(a) < parseInt(b) ? -1 : 1
+                        }
                     }
-                )
-            },
-            /**根据学段、年级、班级搜索 */
-            filterData: function () {
-                let data = this.students
-                // 帳號資訊搜尋
-                if (this.searchText) {
-                    let text = this.searchText
-                    data = data.filter(function (item) {
-                        return (item.name.indexOf(text) >= 0) || (item.id.indexOf(text) >= 0)
-                    })
+                },
+                {
+                    key: 'name',
+                    title: this.$t('stuAccount.stuName'),
+                    align: 'center'
+                },
+                {
+                    slot: 'gradeId',
+                    title: this.$t('stuAccount.grade'),
+                    align: 'center',
+                    width: 140
+                },
+                {
+                    slot: 'classId',
+                    title: this.$t('stuAccount.classroomName'),
+                    align: 'center'
                 }
-
-                // 學制篩選
-                if (this.searchPeriod) {
-                    let id = this.searchPeriod
-                    data = data.filter(function (item) {
-                        return item.periodId == id
+            ]
+        },
+        /**基础查询数据 */
+        baseFindStudent(params) {
+            this.$api.stuAccount.findStudent(this.$store.state.user.schoolCode).then(
+                (res) => {
+                    this.tableLoading = false
+                    // 給一個 PW 讓AddStudent.vue 的Watch 可以動作
+                    let newStudents = res.students.map(function (item) {
+                        let temp = item
+                        temp.pw = '******'
+                        return temp
                     })
+                    this.$store.dispatch('schoolBaseInfo/setStudentsToState', newStudents)
+                    this.filterData()
+                },
+                (err) => {
+                    this.tableLoading = false
                 }
+            )
+        },
+        /**根据学段、年级、班级搜索 */
+        filterData: function () {
+            let data = this.students
+            // 帳號資訊搜尋
+            if (this.searchText) {
+                let text = this.searchText
+                data = data.filter(function (item) {
+                    return (item.name.indexOf(text) >= 0) || (item.id.indexOf(text) >= 0)
+                })
+            }
 
-                // 年級篩選
-                if (this.searchGrade) {
-                    let id = this.searchGrade
-                    data = data.filter(function (item) {
-                        return item.gradeId == id
-                    })
-                }
+            // 學制篩選
+            if (this.searchPeriod) {
+                let id = this.searchPeriod
+                data = data.filter(function (item) {
+                    return item.periodId == id
+                })
+            }
 
-                // 教室篩選
-                if (this.searchClassroom) {
-                    let id = this.searchClassroom
-                    data = data.filter(function (item) {
-                        return item.classId == id
-                    })
-                }
+            // 年級篩選
+            if (this.searchGrade) {
+                let id = this.searchGrade
+                data = data.filter(function (item) {
+                    return item.gradeId == id
+                })
+            }
 
-                this.tableFilterData = data
-                this.pointNum = this.basicCount
-                this.tableShowData = data.slice(0, this.basicCount)
-            },
+            // 教室篩選
+            if (this.searchClassroom) {
+                let id = this.searchClassroom
+                data = data.filter(function (item) {
+                    return item.classId == id
+                })
+            }
 
-            getSelectInfo(selction, row) {
-                this.selections = selction
-                this.selectRow = row
-                this.$emit('getSelectInfo', selction)
-            },
+            this.tableFilterData = data
+            this.pointNum = this.basicCount
+            this.tableShowData = data.slice(0, this.basicCount)
+        },
 
-            scrollLoad: function () {
-                setTimeout(() => {
-                    let maxLength = this.tableShowData.length
-                    let temp = this.tableFilterData.slice(this.pointNum + 1, this.pointNum + this.basicCount)
-                    this.pointNum += this.basicCount
-                    if (temp.length == 0) {
-                        this.$Message.info('已經到底了')
-                        //多语系后面统一处理
-                        //this.$Message.info(this.$t('已經到底了'))
-                    } else {
-                        this.tableShowData.push(...temp)
-                    }
-                }, 1500);
-            },
-            /** 取得年級Name */
-            getGradeName: function (gradeId) {
-                if (gradeId != null) {
-                    let gradeData = this.grades.filter(function (item) {
-                        return item.id == gradeId
-                    })
-                    return gradeData[0].name
-                } else {
-                    return ''
-                }
-            },
-            /** 取得教室Name */
-            getClassName: function (classId) {
-                if (classId != null) {
-                    let classesData = this.classes.filter(function (item) {
-                        return item.id == classId
-                    })
-                    return classesData[0].name
-                }
+        getSelectInfo(selction, row) {
+            this.selections = selction
+            this.selectRow = row
+            this.$emit('getSelectInfo', selction)
+        },
 
-            },
-            getFirstChart(name) {
-                if (name) {
-                    return name.substr(0, 1)
+        scrollLoad: function () {
+            setTimeout(() => {
+                let maxLength = this.tableShowData.length
+                let temp = this.tableFilterData.slice(this.pointNum + 1, this.pointNum + this.basicCount)
+                this.pointNum += this.basicCount
+                if (temp.length == 0) {
+                    this.$Message.info('已經到底了')
+                    //多语系后面统一处理
+                    //this.$Message.info(this.$t('已經到底了'))
                 } else {
-                    return '--'
+                    this.tableShowData.push(...temp)
                 }
-            },
+            }, 1500);
         },
-        created() {
-            this.initData()
-            this.baseFindStudent()
+        /** 取得年級Name */
+        getGradeName: function (gradeId) {
+            if (gradeId != null) {
+                let gradeData = this.grades.filter(function (item) {
+                    return item.id == gradeId
+                })
+                return gradeData[0].name
+            } else {
+                return ''
+            }
         },
-        computed: {
-            ...mapGetters({
-                periods: 'user/getPeriods', // 學制s
-                grades: 'user/getGrades', // 年級
-                classes: 'user/getClasses', // 教室ID
-                students: 'schoolBaseInfo/getStudent', // 學生List
-            }),
-            filterGrades: function () {
-                var data = this.grades
-                if (this.searchPeriod) {
-                    let periodId = this.searchPeriod
-                    data = data.filter(function (item) {
-                        return item.periodId == periodId
-                    })
-                    return data
-                } else {
-                    return []
-                }
-            },
-            filterClasses: function () {
-                var data = this.classes
-                if (this.searchGrade) {
-                    let gradeId = this.searchGrade
-                    data = data.filter(function (item) {
-                        return item.gradeId == gradeId
-                    })
-                    return data
-                } else {
-                    return []
-                }
+        /** 取得教室Name */
+        getClassName: function (classId) {
+            if (classId != null) {
+                let classesData = this.classes.filter(function (item) {
+                    return item.id == classId
+                })
+                return classesData[0].name
             }
-        }
 
+        },
+        getFirstChart(name) {
+            if (name) {
+                return name.substr(0, 1)
+            } else {
+                return '--'
+            }
+        },
+    },
+    created() {
+        this.initData()
+        this.baseFindStudent()
+    },
+    computed: {
+        ...mapGetters({
+            periods: 'user/getPeriods', // 學制s
+            grades: 'user/getGrades', // 年級
+            classes: 'user/getClasses', // 教室ID
+            students: 'schoolBaseInfo/getStudent', // 學生List
+        }),
+        filterGrades: function () {
+            var data = this.grades
+            if (this.searchPeriod) {
+                let periodId = this.searchPeriod
+                data = data.filter(function (item) {
+                    return item.periodId == periodId
+                })
+                return data
+            } else {
+                return []
+            }
+        },
+        filterClasses: function () {
+            var data = this.classes
+            if (this.searchGrade) {
+                let gradeId = this.searchGrade
+                data = data.filter(function (item) {
+                    return item.gradeId == gradeId
+                })
+                return data
+            } else {
+                return []
+            }
+        }
     }
+
+}
 </script>
 <style lang="less" scoped>
-    @import "./StudentList.less";
+@import "./StudentList.less";
 </style>
 <style>
 </style>

+ 7 - 0
TEAMModelOS/ClientApp/src/view/newcourse/MgtStuList.less

@@ -86,4 +86,11 @@
             display: none;
         }
     }
+}
+.list-name-box{
+    color: #a5a5a5;
+    margin-bottom: -30px;
+}
+.item-tools{
+    display:none;
 }

+ 113 - 26
TEAMModelOS/ClientApp/src/view/newcourse/MgtStuList.vue

@@ -7,23 +7,23 @@
                     <div v-if="!isSearch" style="float:right;">
                         <Icon class="action-btn-icon" type="md-trash" />
                         <Icon class="action-btn-icon" type="md-create" />
-                        <Icon class="action-btn-icon" type="md-add" />
+                        <Icon class="action-btn-icon" type="md-add" @click="addStuStatus = true" />
                         <Icon class="action-btn-icon" type="ios-search" @click="isSearch = true" />
                     </div>
-                    <Input v-else icon="ios-close" v-model="keyWord" placeholder="搜索" @on-click="isSearch = false" size="small" style="float:right;width: 150px;margin-top:10px;margin-right:10px" />
+                    <Input v-else icon="ios-close" v-model="keyWord" placeholder="搜索" @on-click="isSearch = false" size="small" style="float:right;width: 180px;margin-top:10px;margin-right:10px" />
                 </div>
                 <div class="list-content">
                     <vuescroll>
                         <div v-for="(item,index) in stuList" @click="curIndex = index" :key="index" :class="['list-item','block-bg',curIndex == index ? 'block-bg-active':'']">
                             <p class="list-name">
-                                选修名单{{index+1}}
+                                {{item.name}}
                             </p>
                             <p>
                                 <span class="attr-label">
                                     学生人数:
                                 </span>
                                 <span class="stu-count">
-                                    51
+                                    {{item.count}}
                                 </span>
                             </p>
                         </div>
@@ -65,18 +65,22 @@
                                 <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
                             </div>
                         </template>
-                        <template slot-scope="{ row, index }" slot="groupId">
-                            <span>{{row.groupId ? row.groupId : '- -'}}</span>
-                        </template>
-                        <template slot-scope="{ row, index }" slot="groupName">
-                            <span>{{row.groupName ? row.groupName : '未分组'}}</span>
+                        <template slot-scope="{ row, index }" slot="action">
+                            <!-- <Icon type="md-trash" color="white"/> -->
+                            <div class="item-tools">
+                                <Icon type="md-remove-circle" color="white" size="18" title="移除学生" />
+                            </div>
                         </template>
                     </Table>
                 </div>
             </div>
         </Split>
         <!-- 创建名单 -->
-        <Modal v-model="addStuStatus" :title="$t('cusMgt.addStu')" width="1200" @on-ok="confirmAddStu" class-name="dark-iview-modal">
+        <Modal v-model="addStuStatus" :title="$t('cusMgt.addStu')" width="1200" @on-ok="confirmAddStu" class-name="dark-iview-modal" :loading="modalLoading">
+            <div class="dark-iview-input list-name-box">
+                <span>名称:</span>
+                <Input v-model="listName" placeholder="请输入名单名称..." style="width: 300px" />
+            </div>
             <StudentList @getSelectInfo="(selction)=>{selections = selction}"></StudentList>
         </Modal>
     </div>
@@ -90,28 +94,36 @@ export default {
     },
     data() {
         return {
+            modalLoading: true,
+            selections: '',//选中的学生了列表
+            listName: '',
             keyWord: '',
-            addStuStatus:false,
+            addStuStatus: false,
             isSearch: false,
             split1: 0.2,
             stuList: [],
             curIndex: 0,
-            tableLoading:false,
-            students:[
+            tableLoading: false,
+            students: [
                 {
-                    name:'李白',
-                    id:'hbcn001',
-                    source:'校内账号',
-                    class:'一年级一班'
+                    name: '李白',
+                    id: 'hbcn001',
+                    source: '校内账号',
+                    class: '一年级一班'
                 },
                 {
-                    name:'杜甫',
-                    id:'16055862215',
-                    source:'醍摩豆账号',
-                    class:'- -'
+                    name: '杜甫',
+                    id: '16055862215',
+                    source: '醍摩豆账号',
+                    class: '- -'
                 }
             ],
             listColumn: [
+                {
+                    type: 'selection',
+                    width: 60,
+                    align: 'center'
+                },
                 {
                     title: '头像',
                     slot: 'picture',
@@ -138,26 +150,101 @@ export default {
                     title: '班级',
                     key: 'class',
                     align: 'center'
+                },
+                {
+                    title: ' ',
+                    slot: 'action',
+                    align: 'center'
                 }
             ],
         }
     },
     methods: {
-        confirmAddStu(){
-
+        confirmAddStu() {
+            console.log(this.selections)
+            if (!this.listName) {
+                this.$Message.warning('请输入名单名称')
+                this.modalLoading = false
+                setTimeout(() => {
+                    this.modalLoading = true
+                }, 0)
+            } else {
+                let stuList = {
+                    name: this.listName,
+                    id: this.$tools.guid(),
+                    code: this.$store.state.userInfo.schoolCode,
+                    students: this.selections.map(item => { //这里没有学生名字, 需要先查看id集合再查学生信息?
+                        return {
+                            id: item.id,
+                            code: item.code
+                        }
+                    }),
+                    tmids: [],
+                    course: null
+                }
+                this.saveStuList(stuList)
+            }
         },
         goBack() {
             this.$router.push({
                 name: 'NewCusMgt'
             })
-        }
+        },
+        findStuList() {
+            let params = {
+                code: this.$store.state.userInfo.schoolCode,
+                scope: 'school'
+            }
+            this.$api.courseMgmt.findStulist(params).then(
+                res => {
+                    this.stuList = res.stuList
+                },
+                err => {
+
+                }
+            )
+        },
+        saveStuList(stuList) {
+            let params = {
+                stuList,
+                scope: "school"
+            }
+            this.$api.courseMgmt.upsertStulist(params).then(
+                res => {
+                    this.$Message.success('添加成功')
+                    this.addStuStatus = false
+                    this.stuList.unshift(params.stuList)
+                },
+                err => {
+                    this.modalLoading = false
+                    setTimeout(() => {
+                        this.modalLoading = true
+                    }, 0)
+                }
+            )
+        },
+        upsertStuList() {
+            this.$api.courseMgmt.upsertStulist(params).then(
+                res => {
+
+                },
+                err => {
+
+                }
+            )
+        },
     },
     created() {
-        this.stuList = Array.from(new Array(5).keys())
-        console.log(this.stuList)
+        this.findStuList()
     }
 }
 </script>
 <style scoped lang="less">
 @import "./MgtStuList.less";
+</style>
+<style>
+.mgt-stu-list .ivu-table-row-hover .item-tools {
+    display: inline-block;
+    cursor: pointer;
+}
 </style>

+ 265 - 96
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue

@@ -62,16 +62,74 @@
                 </div>
             </div>
             <div slot="right" class="cus-schd-box">
-                <Split v-model="split2">
+                <!-- 添加名单UI -->
+                <div slot="right" class="class-setting dark-el-cascader dark-iview-select dark-iview-table" v-show="isAddStuList">
+                    <div class="add-list-header">
+                        <span class="add-list-label">教师:</span>
+                        <Select ref="sltStuList" clearable label-in-value v-model="schedule.teacher.id" style="width:200px;margin-right:30px" size="small" @on-change="setTeaName">
+                            <Option v-for="(item,index) in $store.state.teachers.teacherList" :value="item.id" :key="index">{{ item.name }}</Option>
+                        </Select>
+                        <span class="add-list-label">教室:</span>
+                        <el-cascader size="small" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="schedule.classInfo.id" :options="csOptions" :props="props" @change="setClassName" style="width:180px;">
+                        </el-cascader>
+                        <span v-show="teaClass" class="attr-label" style="margin-left:20px">默认名单</span>
+                        <Tooltip v-show="teaClass" content="默认名单为教室对应的名单,否则需要指定自定义名单。" max-width="200">
+                            <Icon type="ios-information-circle-outline" style="margin-left:2px;margin-right:5px" />
+                        </Tooltip>
+                        <span v-show="teaClass">
+                            <i-switch v-model="isDefault" size="small" />
+                        </span>
+                        <span class="add-list-label" v-show="!isDefault || !teaClass" style="margin-left:40px">名单:</span>
+                        <Select ref="sltStuList" v-show="!isDefault || !teaClass" clearable v-model="schedule.stulist" style="width:200px;margin-right:5px" size="small" @on-change="checkCreate">
+                            <Option v-for="(item,index) in stuList" :value="item" :key="index">{{ item }}</Option>
+                        </Select>
+                        <Icon type="md-add-circle" v-show="!isDefault || !teaClass" class="create-list-icon" @click="goMgtStuList" />
+                        <div class="action-btn-wrap">
+                            <span class="action-btn" style="margin-right:40px" @click="confirmAddSchd">
+                                <Icon type="md-add" size="16" />
+                                <span>确认添加</span>
+                            </span>
+                            <span class="action-btn" @click="cancelAddSchd">
+                                <Icon type="md-close" size="16" />
+                                <span>取消添加</span>
+                            </span>
+                        </div>
+                    </div>
+                    <Table v-if="schdList[curClassIndex]" :columns="schdList[curClassIndex].stulist ? listColumn : classColumn" :data="students" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
+                        <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
+                        <template slot-scope="{ row }" slot="picture">
+                            <PersonalPhoto :name="row.name" :picture="row.picture" />
+                        </template>
+                        <template slot-scope="{ row,index }" slot="no">
+                            <span v-show="editIndex !== index">{{row.no}}</span>
+                            <Input v-model="students[index].no" v-show="editIndex == index" style="width: 60px;" type="number" />
+                            <Icon type="md-checkmark" v-show="editIndex == index" @click="confirmSetNo()" class="reset-no-btn" />
+                            <Icon type="md-close" v-show="editIndex == index" @click="cancelSetNo()" class="reset-no-btn" />
+                        </template>
+                        <template slot-scope="{ row ,index}" slot="action">
+                            <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
+                                <Icon type="md-create" size="18" color="white" @click="resetNo(index)" :title="$t('schoolBaseInfo.editSeat')" />
+                                <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
+                            </div>
+                        </template>
+                        <template slot-scope="{ row, index }" slot="groupId">
+                            <span>{{row.groupId ? row.groupId : '- -'}}</span>
+                        </template>
+                        <template slot-scope="{ row, index }" slot="groupName">
+                            <span>{{row.groupName ? row.groupName : '未分组'}}</span>
+                        </template>
+                    </Table>
+                </div>
+                <Split v-model="split2" v-show="!isAddStuList">
                     <!-- 授课教师列表 -->
                     <div slot="left" class="teacher-list">
                         <div class="teacher-list-header">
                             <span>教师</span>
-                            <Icon type="md-add" size="16" class="tea-action-icon" @click="addTeaStatus = true" />
+                            <Icon type="md-add" size="16" class="tea-action-icon" @click="isAddStuList = true" />
                             <Icon type="md-trash" size="16" class="tea-action-icon" @click="delTeacher" />
                         </div>
-                        <div class="tea-list-content" v-if="courseListShow && courseListShow[curCusIndex]">
-                            <div v-for="(item,index) in courseListShow[curCusIndex].teachers" :key="index" @click="curTeaIndex = index" :class="['block-bg','tea-item',curTeaIndex == index ? 'block-bg-active':'']">
+                        <div class="tea-list-content">
+                            <div v-for="(item,index) in teaList" :key="index" @click="selectTea(index)" :class="['block-bg','tea-item',curTeaIndex == index ? 'block-bg-active':'']">
                                 <PersonalPhoto :name="item.name" />
                                 <div class="tea-info">
                                     <p class="tea-name">{{item.name}}</p>
@@ -81,7 +139,7 @@
                         </div>
                     </div>
                     <!-- 上课名单、上课时段设置 -->
-                    <div slot="right" class="class-setting" v-show="!isAddStuList">
+                    <div slot="right" class="class-setting">
                         <div class="teacher-list-header">
                             <span @click="curTab = 0" :class="curTab == 0 ? 'tab-label line-bottom line-bottom-active':'tab-label line-bottom'">
                                 课程名单
@@ -104,45 +162,44 @@
                         <div class="cus-time-setting">
                             <!-- 设置授课教室名单 -->
                             <div class="set-cus-class" v-show="curTab == 0">
-                                <Split v-model="split3">
+                                <Split v-model="split3" v-show="schdList.length > 0">
                                     <!-- 教室列表 -->
                                     <div slot="left" class="class-list">
-                                        <div v-for="(item,index) in testClassList" :key="index" @click="curClassIndex = index" :class="['block-bg','tea-class-item',curClassIndex == index ? 'block-bg-active':'']">
+                                        <div v-for="(item,index) in schdList" :key="index" @click="selectClass(index)" :class="['block-bg','tea-class-item',curClassIndex == index ? 'block-bg-active':'']">
                                             <p class="class-attr-item">
                                                 <span class="attr-label">教室:</span>
-                                                <span class="class-name">{{item.name}}</span>
-                                                <span class="class-label" :style="{color:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900',borderColor:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900'}">
+                                                <span class="class-name">{{item.classInfo.id ? item.classInfo.name:'未设置'}}</span>
+                                                <!-- <span class="class-label" :style="{color:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900',borderColor:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900'}">
                                                     {{item.type}}
-                                                </span>
+                                                </span> -->
                                             </p>
                                             <p class="class-attr-item">
                                                 <span class="attr-label">名单:</span>
-                                                <span class="class-name">默认名单</span>
+                                                <span class="class-name">{{item.stulist ? '自定义名单':'默认名单'}}</span>
                                             </p>
                                         </div>
                                     </div>
                                     <!-- 设置教室名单 -->
-                                    <div slot="right" class="set-stu-list dark-iview-table dark-el-cascader ">
+                                    <div slot="right" class="set-stu-list dark-iview-table dark-el-cascader" v-if="schdList[curClassIndex]">
                                         <div class="stu-list-header dark-iview-select">
                                             <span class="attr-label">教室:</span>
                                             <!-- <span>{{testClassList[curClassIndex].name }}</span> -->
-                                            <el-cascader size="mini" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="teaClass" :options="csOptions" :props="props" @change="treeChange" style="width:180px;">
+                                            <el-cascader size="mini" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="schdList[curClassIndex].classInfo.id" :options="csOptions" :props="props" @change="setClassName" style="width:180px;">
                                             </el-cascader>
                                             <span class="attr-label" style="margin-left:50px">默认名单</span>
                                             <Tooltip content="默认名单为教室对应的名单,否则需要指定自定义名单。" max-width="200">
                                                 <Icon type="ios-information-circle-outline" style="margin-left:2px;margin-right:5px" />
                                             </Tooltip>
                                             <span>
-                                                <i-switch v-model="isDefault" size="small" @on-change="setIsDefList" />
-
+                                                <i-switch v-model="isDefault" size="small" :before-change="handleSwitch"/>
                                             </span>
                                             <span v-show="!isDefault" class="attr-label" style="margin-left:50px">名单:</span>
-                                            <Select ref="sltStuList" v-show="!isDefault" clearable v-model="dyStu" style="width:200px;margin-right:5px" size="small" @on-change="checkCreate">
+                                            <Select ref="sltStuList" v-show="!isDefault" clearable v-model="schdList[curClassIndex].stulist" style="width:200px;margin-right:5px" size="small" @on-change="checkCreate">
                                                 <Option v-for="(item,index) in stuList" :value="item" :key="index">{{ item }}</Option>
                                             </Select>
                                             <Icon type="md-add-circle" v-show="!isDefault" style="cursor:pointer" @click="goMgtStuList" />
                                         </div>
-                                        <Table :columns="dyStu ? listColumn : classColumn" :data="students" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
+                                        <Table v-if="schdList[curClassIndex]" :columns="schdList[curClassIndex].stulist ? listColumn : classColumn" :data="students" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
                                             <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
                                             <template slot-scope="{ row }" slot="picture">
                                                 <PersonalPhoto :name="row.name" :picture="row.picture" />
@@ -168,6 +225,7 @@
                                         </Table>
                                     </div>
                                 </Split>
+                                <EmptyData v-show="schdList.length == 0" textContent="暂无课程名单,请先前往添加名单"></EmptyData>
                             </div>
                             <!-- 教师课表 -->
                             <vuescroll v-show="curTab == 1">
@@ -182,60 +240,7 @@
                             </vuescroll>
                         </div>
                     </div>
-                    <!-- 添加名单UI -->
-                    <div slot="right" class="class-setting dark-el-cascader dark-iview-select dark-iview-table" v-show="isAddStuList">
-                        <div class="add-list-header">
-                            <span class="add-list-label">教室:</span>
-                            <el-cascader size="small" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="teaClass" :options="csOptions" :props="props" @change="treeChange" style="width:180px;">
-                            </el-cascader>
-                            <span v-show="teaClass" class="attr-label" style="margin-left:20px">默认名单</span>
-                            <Tooltip v-show="teaClass" content="默认名单为教室对应的名单,否则需要指定自定义名单。" max-width="200">
-                                <Icon type="ios-information-circle-outline" style="margin-left:2px;margin-right:5px" />
-                            </Tooltip>
-                            <span v-show="teaClass">
-                                <i-switch v-model="isDefault" size="small" @on-change="setIsDefList" />
-                            </span>
-                            <span class="add-list-label" v-show="!isDefault || !teaClass" style="margin-left:40px">名单:</span>
-                            <Select ref="sltStuList" v-show="!isDefault || !teaClass" clearable v-model="dyStu" style="width:200px;margin-right:5px" size="small" @on-change="checkCreate">
-                                <Option v-for="(item,index) in stuList" :value="item" :key="index">{{ item }}</Option>
-                            </Select>
-                            <Icon type="md-add-circle" v-show="!isDefault || !teaClass" class="create-list-icon" @click="goMgtStuList" />
-                            <div class="action-btn-wrap">
-                                <span class="action-btn" style="margin-right:40px" @click="isAddStuList = false">
-                                    <Icon type="md-add" size="16" />
-                                    <span>确认添加</span>
-                                </span>
-                                <span class="action-btn" @click="isAddStuList = false">
-                                    <Icon type="md-close" size="16" />
-                                    <span>取消添加</span>
-                                </span>
-                            </div>
-                        </div>
-                        <Table :columns="dyStu ? listColumn : classColumn" :data="students" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
-                            <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
-                            <template slot-scope="{ row }" slot="picture">
-                                <PersonalPhoto :name="row.name" :picture="row.picture" />
-                            </template>
-                            <template slot-scope="{ row,index }" slot="no">
-                                <span v-show="editIndex !== index">{{row.no}}</span>
-                                <Input v-model="students[index].no" v-show="editIndex == index" style="width: 60px;" type="number" />
-                                <Icon type="md-checkmark" v-show="editIndex == index" @click="confirmSetNo()" class="reset-no-btn" />
-                                <Icon type="md-close" v-show="editIndex == index" @click="cancelSetNo()" class="reset-no-btn" />
-                            </template>
-                            <template slot-scope="{ row ,index}" slot="action">
-                                <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
-                                    <Icon type="md-create" size="18" color="white" @click="resetNo(index)" :title="$t('schoolBaseInfo.editSeat')" />
-                                    <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
-                                </div>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupId">
-                                <span>{{row.groupId ? row.groupId : '- -'}}</span>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupName">
-                                <span>{{row.groupName ? row.groupName : '未分组'}}</span>
-                            </template>
-                        </Table>
-                    </div>
+
                 </Split>
             </div>
         </Split>
@@ -270,8 +275,11 @@
             </Form>
         </Modal>
         <!-- 添加授课教师 -->
-        <Modal v-model="addTeaStatus" title="添加教师" class-name="dark-iview-modal dark-iview-select">
-            <Select label-in-value multiple v-model="teacherId" :placeholder="$t('cusMgt.teacherHolder')" :max-tag-count="3" filterable @on-change="getTeahcers">
+        <Modal v-model="addTeaStatus" title="添加教师" class-name="dark-iview-modal dark-iview-select" @on-ok="confirmAddTea">
+            <!-- <div style="margin-bottom:20px;">
+                <Tag closable v-for="(item,index) in courseListShow[curCusIndex].teachers" :key="index">{{item.name}}</Tag>
+            </div> -->
+            <Select ref="addTea" label-in-value multiple clearable :placeholder="$t('cusMgt.teacherHolder')" :max-tag-count="3" filterable @on-change="seltChange">
                 <Option v-for="(item,index) in $store.state.teachers.teacherList" :value="item.id" :key="index">{{ item.name }}</Option>
             </Select>
         </Modal>
@@ -309,7 +317,6 @@ export default {
         }
         return {
             props: {
-                // multiple: true,
                 value: 'id',
                 label: 'name',
                 emitPath: false
@@ -320,7 +327,6 @@ export default {
             isSearch: false,
             stuLoading: false,
             students: [],
-            dyStu: '',
             stuList: ['选修名单1', '选修名单2', '选修名单3', '选修名单4', '选修名单5', '选修名单6'],
             isDefault: true,
             testClassList: [
@@ -401,6 +407,7 @@ export default {
                     align: 'center'
                 },
             ],
+            addTeachers: [],
             curClassIndex: 0,
             hasTimeTable: false,
             selections: [],
@@ -450,10 +457,149 @@ export default {
             addCourseStatus: false,
             keyWord: '',
             courseList: [],
-            courseListShow: []
+            courseListShow: [],
+            schedule: {
+                classInfo: {
+                    id: '',
+                    name: ''
+                },
+                teacher: {
+                    id: '',
+                    name: ''
+                },
+                stulist: '',
+                time: [
+                    // {
+                    //     week: "Mon",
+                    //     start: "8:00",
+                    //     end: "8:40"
+                    // }
+                ],
+                notice: ''
+            }
         }
     },
     methods: {
+        //教室列表
+        selectClass(index){
+            this.curClassIndex = index
+            this.setIsDefault()
+        },
+        //教师列表选择事件
+        selectTea(index) {
+            this.curClassIndex = 0
+            this.curTeaIndex = index
+            this.setIsDefault()
+        },
+        //默认名单切换判断
+        handleSwitch() {
+            return new Promise((resolve, reject) => {
+                if (!this.isDefault) {
+                    this.$Modal.confirm({
+                        title: '默认名单',
+                        content: '如果使用默认名单将会移除当前自定义名单,您确认要使用默认名单吗?',
+                        onOk: () => {
+                            this.schdList[this.curClassIndex].stulist = ''
+                            resolve()
+                        },
+                        onCancel: () => {
+                            reject()
+                        }
+                    })
+                } else {
+                    resolve()
+                }
+            })
+        },
+        //下拉选择授课教师,并设置教师名称
+        setTeaName(data) {
+            this.schedule.teacher.name = data.label
+            console.log(this.schedule)
+        },
+        //设置教室名称
+        setClassName(data) {
+            console.log(data)
+            let curClass = this.classList.find(item => {
+                return item.id == data
+            })
+            if (curClass) {
+                this.schedule.classInfo.name = curClass.name
+            }
+        },
+        //确认添加名单
+        confirmAddSchd() {
+            if (!this.schedule.teacher.id) {
+                this.$Message.warning('请设置授课老师')
+                return
+            }
+            if (!(this.schedule.classInfo.id || this.schedule.stulist)) {
+                this.$Message.warning('请设置教室或者名单')
+                return
+            }
+            this.courseListShow[this.curCusIndex].schedule.push(this.schedule)
+            console.log(this.courseListShow[this.curCusIndex])
+            this.isAddStuList = false
+            this.updCusInfo()
+            this.initSchedule()
+        },
+        //取消添加Schd
+        cancelAddSchd() {
+            this.isAddStuList = false
+            this.initSchedule()
+        },
+        //确认或取消添加后初始化数据
+        initSchedule() {
+            this.schedule = {
+                classInfo: {
+                    id: '',
+                    name: ''
+                },
+                teacher: {
+                    id: '',
+                    name: ''
+                },
+                stulist: '',
+                time: [],
+                notice: ''
+            }
+        },
+        // (废弃)
+        seltChange(data) {
+            this.addTeachers = data
+        },
+        //确认添加教师 (废弃)
+        confirmAddTea() {
+            let teachers = this.addTeachers.map(item => {
+                return {
+                    id: item.value,
+                    name: item.label
+                }
+            })
+            let ids = this.courseListShow[this.curCusIndex].teachers.map(item => {
+                return item.id
+            })
+            let isUpd = false
+            teachers.forEach(item => {
+                if (ids.indexOf(item.id) == -1) {
+                    this.courseListShow[this.curCusIndex].teachers.push(item)
+                    isUpd = true
+                }
+            })
+            this.addTeachers = []
+            this.$refs['addTea'].clearSingleSelect()
+            if (isUpd) this.updCusInfo()
+        },
+        // 更新课程数据
+        updCusInfo() {
+            this.courseListShow[this.curCusIndex].code = this.courseListShow[this.curCusIndex].code.replace('Course-', '')
+            this.$api.courseMgmt.saveOrUpdateCourse({
+                course: this.courseListShow[this.curCusIndex],
+                option: 'update',
+                scope: this.courseListShow[this.curCusIndex].scope
+            }).then().catch(() => {
+                this.$Message.error('更新失败')
+            })
+        },
         //删除授课教师
         delTeacher() {
             this.$Modal.confirm({
@@ -485,16 +631,6 @@ export default {
                 name: 'MgtStuList'
             })
         },
-        //设置是否为默认名单
-        setIsDefList(status) {
-            if (status) {
-                this.dyStu = ''
-            }
-        },
-        treeChange(data) {
-            console.log(data)
-            console.log('modal', this.teaClass)
-        },
         //跳转名单管理页面
         mgtStuList() {
             this.$Message.warning("名单管理开发中.......")
@@ -591,10 +727,10 @@ export default {
                     (res) => {
                         if (!res.error) {
                             // [this.curCusIndex] = res.courses[0]
-                            if(res.courses &&  res.courses.length > 0){
+                            if (res.courses && res.courses.length > 0) {
                                 res.courses[0].schedule = res.courses[0].schedule ? res.courses[0].schedule : []
                             }
-                            this.$set(this.courseListShow,this.curCusIndex,res.courses[0])
+                            this.$set(this.courseListShow, this.curCusIndex, res.courses[0])
                         }
                     }
                 ).finally(() => {
@@ -744,6 +880,11 @@ export default {
                 }
             })
         },
+        setIsDefault() {
+            if (this.schdList.length) {
+                this.isDefault = !this.schdList[this.curClassIndex].stulist
+            }
+        }
     },
     created() {
         //直接读取登录成功拿到得学校基础信息
@@ -806,20 +947,44 @@ export default {
             return name
         },
         //当前老师的课程安排
-        teaSchd(){
-            if(this.courseListShow && this.courseListShow[this.curCusIndex] && this.courseListShow[this.curCusIndex].teachers){
-                return this.courseListShow[this.curCusIndex].schedule.filter(item=>{
-                    return item.teacher.id == this.courseListShow[this.curCusIndex].teachers[this.curTeaIndex].id
+        schdList() {
+            if (this.courseListShow && this.courseListShow[this.curCusIndex] && this.courseListShow[this.curCusIndex] && this.teaList.length) {
+                let schds = this.courseListShow[this.curCusIndex].schedule.filter(item => {
+                    return item.teacher.id == this.teaList[this.curTeaIndex].id
                 })
-            }else{
+                return schds
+            } else {
+                return []
+            }
+        },
+        //当前课程的授课老师列表
+        teaList() {
+            if (this.courseListShow && this.courseListShow[this.curCusIndex] && this.courseListShow[this.curCusIndex].schedule) {
+                let all = this.courseListShow[this.curCusIndex].schedule.map(item => {
+                    return item.teacher
+                })
+                const res = new Map()
+                let removeRep = all.filter((a) => !res.has(a.id) && res.set(a.id, 1))
+
+                console.log(removeRep)
+                return removeRep
+            } else {
                 return []
             }
         }
     },
-    watch:{
-        curCusIndex(){
+    watch: {
+        curCusIndex() {
             this.getCusInfo()
-        }
+        },
+        // schdList:{
+        //     handler(){
+        //         console.log('watch',this.isDefault)
+        //         this.setIsDefault()
+        //         console.log('watch',this.isDefault)
+        //     },
+        //     deep:true
+        // }
     }
 }
 </script>
@@ -830,4 +995,8 @@ export default {
 .class-setting thead {
     background: #505050;
 }
+.add-list-header .el-input--small .el-input__inner {
+    height: 26px;
+    line-height: 26px;
+}
 </style>

+ 4 - 2
TEAMModelOS/Controllers/School/CourseController.cs

@@ -182,16 +182,18 @@ namespace TEAMModelOS.Controllers
         {
             try
             {
+                
                 StuList stuList = new StuList();
                 if (!requert.TryGetProperty("stuList", out JsonElement student)) return BadRequest();
-                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
+                //if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                 if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
                 stuList = student.ToObject<StuList>();
                 var client = _azureCosmos.GetCosmosClient();
+                string originCode = stuList.code;
                 stuList.code = stuList.pk + "-" + stuList.code;
                 if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                 {
-                    stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{code}"));
+                    stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{originCode}"));
                 }
                 else
                 {