Explorar el Código

Merge branch 'develop3.0' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0

李思淳 hace 5 años
padre
commit
1c1486fccf

+ 2 - 0
TEAMModelOS/ClientApp/src/api/index.js

@@ -6,10 +6,12 @@ import schoolSetting from './schoolSetting'
 import totalAnalysis from './totalAnalysis'
 import stuAccount from './stuAccount'
 import syllabus from './syllabus'
+import knowledge from './knowledge'
 export default {
     ClassMgmt,
     stuAccount,
     syllabus,
+    knowledge,
     schoolSetting,
     totalAnalysis,
     talMgmt,

+ 35 - 0
TEAMModelOS/ClientApp/src/api/knowledge.js

@@ -0,0 +1,35 @@
+import { post } from '@/filters/http'
+export default {
+    // 获取标准知识点
+    GetStantardPoints: function (data) {
+        return post('/api/Knowledge/FindKnowledgePointByDict', data)
+    },
+    // 获取标准知识块
+    GetStantardBlocks: function (data) {
+        return post('/api/Knowledge/FindKnowledgeBlockAndPointByDict', data)
+    },
+    // 获取学校知识点
+    GetSchoolPoints: function (data) {
+        return post('/api/Knowledge/FindSchoolPointByDict', data)
+    },
+    // 获取学校知识块
+    GetSchoolBlocks: function (data) {
+        return post('/api/Knowledge/FindSchoolBlockAndPointByDict', data)
+    },
+    // 保存或更新学校知识块及知识点
+    SaveOrUpdateSchoolBlock: function (data) {
+        return post('/api/Knowledge/SaveOrUpdateSchoolBlock', data)
+    },
+    // 手动添加学校的私有知识点
+    SaveOrUpdateSchoolPoint: function (data) {
+        return post('/api/Knowledge/SaveOrUpdateAllSchoolPoint', data)
+    },
+    // 删除学校知识点
+    DeleteSchoolPoint: function (data) {
+        return post('/api/Knowledge/DeleteSchoolPoint', data)
+    },
+    // 手动添加学校的私有知识点
+    DeleteSchoolBlock: function (data) {
+        return post('/api/Knowledge/DeleteSchoolBlock', data)
+    },
+}

+ 12 - 0
TEAMModelOS/ClientApp/src/api/teachContent.js

@@ -0,0 +1,12 @@
+import { fetch, post } from '@/filters/http'
+export default {
+    saveOrUpdateResource: function (data) {
+        return post('/api/Resource/SaveOrUpdateSyllabusResource', data);
+    },
+    findResourceByDict: function (data) {
+        return post('/api/Resource/FindSyllabusResourceByDict', data);
+    },
+    deleteResource: function (data) {
+        return post('/api/Resource/DeleteSyllabusResource', data);
+    }
+}

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

@@ -64,7 +64,7 @@
                 <!--<MenuItem name="3-2">校本课纲管理</MenuItem>-->
                 <MenuItem name="3-3" to="/home/teachcontent">内容管理</MenuItem>
                 <MenuItem name="3-4" to="/home/evaluation/exercisesList">题目/库管理</MenuItem>
-                <MenuItem name="3-5">知识点管理</MenuItem>
+                <MenuItem name="3-5" to="/home/knowledge">知识点管理</MenuItem>
             </Submenu>
             <Submenu name="4">
                 <template slot="title">

+ 221 - 0
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.less

@@ -0,0 +1,221 @@
+@main-bgColor:rgb(20,20,20); //主背景颜色
+@borderColor: #252525;
+@primary-textColor:#e0e0e0; //文本主颜色
+@second-textColor:#a5a5a5; //文本副级颜色
+@primary-fontSize:16px;
+@second-fontSize:14px;
+@title-fontSize:18px;
+
+.new-syllabus {
+
+
+    &-container {
+        height: 100%;
+        font-family: '微軟正黑體', 'Heiti TC';
+        background: @main-bgColor;
+    }
+
+    &-header {
+        height: 70px;
+        border-top: 1px solid @borderColor;
+        box-shadow: 0px 4px 9px 0px #010101;
+        .fl-row-center;
+        justify-content: space-between;
+        padding: 0 20px;
+        z-index: 1;
+
+
+        span {
+            margin-right: 30px;
+            color: @second-textColor;
+            border-bottom: 2px solid transparent;
+            font-size: @second-fontSize;
+            font-weight: bold;
+            padding: 5px 0;
+            cursor: pointer;
+        }
+
+        .tab-active {
+            border-color: @primary-textColor;
+            color: @primary-textColor;
+            font-size: @primary-fontSize;
+        }
+    }
+
+    &-content {
+        height: calc(100% - 70px);
+        width: 100%;
+        .fl-row-center;
+
+        .ns-col {
+            position: relative;
+            height: 100%;
+            overflow: hidden;
+            border-right: 1px solid @borderColor;
+
+
+
+            .ns-header {
+                padding: 0 15px;
+                height: 50px;
+                font-size: @primary-fontSize;
+                font-weight: bold;
+                color: @primary-textColor;
+                border-bottom: 1px solid @borderColor;
+
+                &-content {
+                    height: 50px;
+                    .fl-row-center;
+                    justify-content: space-between;
+                }
+            }
+
+
+            .gl {
+                width: 100%;
+                height: 100%;
+                padding: 0 0 0 10px;
+                overflow: hidden;
+                padding-bottom: 50px;
+
+
+                &-item {
+                    position: relative;
+                    width: 100%;
+                    padding: 20px 15px;
+                    border-bottom: 1px solid #2c2c2c;
+                    cursor: pointer;
+
+
+                    &:hover {
+                        .item-active;
+                    }
+
+                    &-name {
+                        font-size: @title-fontSize;
+                        color: @primary-textColor;
+                        font-weight: bold;
+                    }
+
+                    &-info {
+                        padding: 1px 0;
+                        font-size: @second-fontSize;
+                        color: @second-textColor;
+
+                        span {
+                            display: inline-block;
+                            width: 3px;
+                            height: 10px;
+                            margin-right: 5px;
+                            background: @second-textColor;
+                        }
+                    }
+                }
+            }
+
+            .vl {
+                .gl-item {
+                    padding: 30px 15px
+                }
+
+                .gl-item-name {
+                    width:70%;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+                }
+
+                .gl-item-info {
+                    span {
+                        margin-top: 15px
+                    }
+                }
+
+                .gl-item:hover {
+                    .btn-delete, .btn-edit {
+                        display: unset;
+                    }
+                }
+
+                .btn-delete {
+                    position: absolute;
+                    right: 30px;
+                    top: 44px;
+                    display: none;
+                }
+
+                .btn-edit {
+                    position: absolute;
+                    right: 60px;
+                    top: 44px;
+                    display: none;
+                }
+            }
+        }
+
+        .ns-col {
+            width: 15%;
+            box-shadow: 6px 6px 9px 0px #000000;
+            z-index: 2;
+            background: #171717;
+            user-select: none;
+        }
+
+        .ns-col2 {
+            width: 19%;
+            background: #202020;
+            box-shadow: 6px 6px 9px 0px #000000;
+            z-index: 1;
+
+            .funnel-box {
+                .fl-col-center;
+                align-items: flex-start;
+                padding-bottom: 10px;
+
+                p {
+                    margin: 10px 5px;
+                }
+            }
+        }
+
+        .ns-col3 {
+            width: 66%;
+            background: #2c2c2cd6;
+
+            .points-wrap {
+                display: flex;
+                flex-wrap: wrap;
+
+                .point-item {
+                    margin: 10px;
+                    padding: 5px 10px;
+                    border: 1px solid #a5a5a5;
+                    border-radius: 50px;
+                    cursor: pointer;
+                }
+            }
+        }
+    }
+}
+
+.fl-row-center{
+    display:flex;
+    align-items:center;
+}
+
+.fl-col-center {
+    display: flex;
+    flex-direction:column;
+    align-items: center;
+}
+
+.item-active {
+    background-image: -webkit-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+    background-image: -o-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+    background-image: -moz-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+    background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+}
+
+
+
+

+ 500 - 0
TEAMModelOS/ClientApp/src/view/knowledge-point/index/index.vue

@@ -0,0 +1,500 @@
+<style lang="less" scoped>
+    @import './Index.less';
+</style>
+
+<template>
+    <div class="new-syllabus-container">
+        <!-- 课纲头部 切换来源以及选择学段 -->
+        <div class="new-syllabus-header">
+            <div>
+                <span :class="tabIndex == 0 ? 'tab-active' : ''" @click="handleTabClick(0)">校本知识块</span>
+                <span :class="tabIndex == 1 ? 'tab-active' : ''" @click="handleTabClick(1)">校本知识点</span>
+            </div>
+            <div class="new-syllabus-select">
+                <span>当前学段:</span>
+                <Select ref="periodSelect" v-model="currentPeriod" style="width:200px" @on-change="onPeriodChange">
+                    <Option v-for="(item,index) in periodList" :value="index" :key="index">{{ item.periodName }}</Option>
+                </Select>
+            </div>
+        </div>
+        <!-- 课纲主体内容 -->
+        <div class="new-syllabus-content">
+            <!-- 选择科目 -->
+            <div class="ns-col ns-col">
+                <Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadSubject"></Loading>
+                <div class="ns-header">
+                    <!-- 切换头部以及搜索框 -->
+                    <div class="ns-header-content" v-if="!isSearchSubject">
+                        <span>
+                            <Icon type="md-bookmark" color="#fff" size="20" />
+                            <span style="margin-left:5px">科目</span>
+                        </span>
+                        <Icon type="ios-search" color="#fff" size="18" style="cursor:pointer" @click="isSearchSubject = true" />
+                    </div>
+                    <div class="ns-header-search" v-else>
+                        <Input icon="ios-close"
+                               v-model="searchSubject"
+                               placeholder="搜索科目..."
+                               autofocus
+                               style="width: 100%"
+                               @on-click="isSearchSubject = false"
+                               @on-blur="isSearchSubject = false"
+                               @on-change="onSearchSubjectChange"
+                               @on-enter="onSearchSubjectChange" />
+                    </div>
+                </div>
+                <vuescroll>
+                    <div class="gl">
+                        <div :class='["gl-item","animated","slideInUp",index == activeSubjectIndex ? "item-active":""]'
+                             v-for="(item,index) in subjectList"
+                             :key="index"
+                             @click="hasModify ? handleConfirmSave({index},'2') : handleSubjectTap(index)"
+                             :style="{ animationDelay: ((index+1)*0.05) + 's'}">
+                            <p class="gl-item-name">{{item.subjectName}}</p>
+                            <p class="gl-item-info"><span></span>知识块数:{{index}}</p>
+                        </div>
+                    </div>
+                </vuescroll>
+            </div>
+            <!-- 选择知识块 -->
+            <div class="ns-col ns-col2">
+                <Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadVolumes"></Loading>
+                <div class="ns-header">
+                    <!-- 切换头部以及搜索框 -->
+                    <div class="ns-header-content" v-if="!isSearchBlock">
+                        <span>
+                            <Icon type="md-bookmarks" color="#fff" size="20" />
+                            <span style="margin-left:5px">知识块</span>
+                        </span>
+                        <div>
+                            <Icon type="md-add" color="#fff" size="18" style="cursor:pointer;margin-right:10px" @click="onAddVolume" />
+                            <Poptip title="筛选知识块" placement="bottom-end" @on-popper-show="onPopperShow">
+                                <Icon type="ios-funnel" color="#fff" size="18" style="cursor:pointer;margin-right:10px" />
+                                <div class="funnel-box" slot="content">
+                                    <p>年级</p>
+                                    <Select v-model="filterGrade" style="width:200px" @on-change="onFilterGrade">
+                                        <Option v-for="(item,index) in gradeList" :value="item.gradeCode" :key="index">{{ item.gradeName }}</Option>
+                                    </Select>
+                                    <p>学期</p>
+                                    <Select v-model="filterSemester" style="width:200px" @on-change="onFilterSemester">
+                                        <Option v-for="(item,index) in semesterList" :value="item.semesterCode" :key="index">{{ item.semesterName }}</Option>
+                                    </Select>
+                                </div>
+                            </Poptip>
+                            <Icon type="ios-search" color="#fff" size="18" style="cursor:pointer" @click="isSearchBlock = true" />
+                        </div>
+                    </div>
+                    <div class="ns-header-search" v-else>
+                        <!-- 搜索知识块部分 -->
+                        <Input icon="ios-close"
+                               v-model="searchBlock"
+                               placeholder="搜索知识块..."
+                               autofocus
+                               style="width: 100%"
+                               @on-click="isSearchBlock = false"
+                               @on-blur="isSearchBlock = false"
+                               @on-change="onSearchBlockChange"
+                               @on-enter="onSearchBlockChange" />
+                    </div>
+                </div>
+                <vuescroll>
+                    <!-- 知识块列表 -->
+                    <div class="vl gl">
+                        <div v-if="blockList.length === 0">
+                            <EmptyBox :top="50"></EmptyBox>
+                        </div>
+                        <div v-else>
+                            <div :class='["gl-item","animated","slideInUp",index == activeBlockIndex ? "item-active":""]'
+                                 v-for="(item,index) in blockList"
+                                 :key="index"
+                                 @click="hasModify ? handleConfirmSave({index,item},'1') : handleBlockTap(index,item)"
+                                 :style="{ animationDelay: ((index+1)*0.05) + 's'}">
+                                <p class="gl-item-name" :title="item.name">{{item.name}}</p>
+                                <p class="gl-item-info"><span></span>知识点数:{{item.points.length}}</p>
+                                <span class="btn-edit" title="编辑" @click.stop="onEditVolume(item)"><Icon type="md-create" size="20" color="#d2d2d2" /></span>
+                                <span class="btn-delete" title="删除" @click.stop="onDeleteVolume(item)"><Icon type="md-trash" size="22" color="#d2d2d2" /></span>
+                            </div>
+                        </div>
+                    </div>
+                </vuescroll>
+            </div>
+            <!-- 展示课纲树形结构部分 -->
+            <div class="ns-col ns-col3">
+                <Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadPoints"></Loading>
+                <div class="ns-header">
+                    <!-- 切换头部以及搜索框 -->
+                    <div class="ns-header-content" v-if="!isSearchPoint">
+                        <span>
+                            <Icon type="md-bookmarks" color="#fff" size="20" />
+                            <span style="margin-left:5px">知识点</span>
+                        </span>
+                        <div>
+                            <Icon type="md-add" color="#fff" size="18" style="cursor:pointer;margin-right:10px" @click="onAddVolume" />
+                            <Icon type="ios-search" color="#fff" size="18" style="cursor:pointer" @click="isSearchPoint = true" />
+                        </div>
+                    </div>
+                    <div class="ns-header-search" v-else>
+                        <!-- 搜索知识点部分 -->
+                        <Input icon="ios-close"
+                               v-model="searchPoint"
+                               placeholder="搜索知识块..."
+                               autofocus
+                               style="width: 100%"
+                               @on-click="isSearchPoint = false"
+                               @on-blur="isSearchPoint = false"
+                               @on-change="onSearchBlockChange"
+                               @on-enter="onSearchBlockChange" />
+                    </div>
+                    <div>
+                        <div v-if="pointList.length === 0">
+                            <EmptyBox :top="100"></EmptyBox>
+                        </div>
+                        <div class="points-wrap" v-else>
+                            <span class="point-item" v-for="(item,index) in pointList" :key="index">{{item.name}}</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- 新增知识块弹窗 -->
+        <Modal v-model="isAddVolume" width="560" footer-hide class="add-volume-modal">
+            <div class="modal-header" slot="header">{{ isEditVolume ? '编辑知识块' : '新增知识块'}}</div>
+            <div class="modal-content">
+                <AddBlock :originData="originSchoolData"
+                          :periodIndex="currentPeriod"
+                          :subjectIndex="currentSubject"
+                          :editVolume="editVolume"
+                          @addFinish="onFinishAddVolume">
+                </AddBlock>
+            </div>
+        </Modal>
+    </div> 
+</template>
+
+<script>
+    import Tree from '@/components/syllabus/DragTree'
+    import EmptyBox from '@/common/EmptyData'
+    import Loading from '@/common/Loading'
+    import AddBlock from './operation/addBlock'
+
+    let defaultBlock = {
+          type: 0,
+          name: "",
+          alias: "",
+          subjectCode: "",
+          schoolCode: "2151002664",
+          order: 706,
+          status: 1,
+          knowledgeId: "0aa85eec-34fd-468c-95b7-39ff3eb51e61",
+          points: [],
+          source: 1
+    }
+
+    export default {
+        data() {
+            return {
+                schoolInfo: {
+                    schoolCode: "HBCN",
+                    areaCode: "86"
+                },
+                currentParams: {
+                    schoolCode: "2151002664",
+                    subjectCode: ""
+                },
+                isLoadSubject: false,
+                isLoadVolumes: false,
+                isLoadPoints: false,
+                currentPeriod: null,
+                currentSubject: null,
+                currentBlock: null,
+                tabIndex: 0,
+                originData: {},
+                originSchoolData: {},
+                periodList: [],
+                gradeList: [],
+                semesterList: [],
+                subjectList: [],
+                originSubjectList: [],
+                blockList: [],
+                originBlockList: [],
+                pointList: [],
+                activePeriodIndex: 0,
+                activeSubjectIndex: 0,
+                activeBlockIndex: 0,
+                isSearchSubject: false,
+                isSearchBlock: false,
+                isSearchPoint: false,
+                isAddVolume: false,
+                isEditVolume: false,
+                filterGrade: 'all',
+                filterSemester: 'all',
+                searchBlock: '',
+                searchPoint: '',
+                searchSubject: '',
+                editVolume: null,
+                hasModify: false,
+                preSelectVal: null
+            }
+        },
+        components: {
+            Tree, AddBlock, EmptyBox, Loading
+        },
+        created() {
+            this.initSchoolData()
+        },
+        methods: {
+            //获取当前学校学段科目等基本信息
+            initSchoolData() {
+                this.$api.syllabus.GetSchoolInfo(this.schoolInfo).then(res => {
+                    if (!res.error && res.result.data.length) {
+                        this.originSchoolData = res.result.data[0] //默认选择第一个
+                        this.originData = res.result.data[0] //默认选择第一个
+                        this.periodList = this.originData.period
+                        //this.currentParams.schoolCode = this.originData.schoolCode
+                        //this.currentParams.periodCode = this.originData.period[0].periodCode
+                        this.currentPeriod = 0 //默认选择第一个学段
+                        this.onPeriodChange(0)
+                    } else {
+                        this.$Message.warning("暂无学段数据")
+                    }
+                })
+            },
+            //根据科目获取所有知识块信息
+            getVolumesData() {
+                let that = this
+                this.$api.knowledge.GetSchoolBlocks({ PointParams: this.currentParams }).then(res => {
+                    if (!res.error && res.result.data) {
+                        let list = res.result.data
+                        this.blockList = list
+                        this.originBlockList = list
+                        this.handleBlockTap(0, list.length ? list[0] : null)
+                        setTimeout(function () {
+                            that.isLoadVolumes = false
+                        }, 1000)
+
+                    } else {
+                        this.$Message.warning("获取数据失败")
+                    }
+                })
+            },
+
+            //根据知识块CODE来获取对应树形课纲数据
+            getTreeByVolume(volumeCode) {
+                let that = this
+                this.$api.knowledge.GetTreeByVolume({ volumeCode: volumeCode }).then(res => {
+                    if (!res.error && res.result.data) {
+                        this.treeData = res.result.data
+                        setTimeout(function () {
+                            that.isLoadPoints = false
+                        }, 1000)
+                    } else {
+                        this.$Message.warning("获取数据失败")
+                    }
+                })
+            },
+
+            //校本课纲与个人课纲切换
+            handleTabClick(index) {
+                this.tabIndex = index
+            },
+
+            //学段切换处理
+            onPeriodChange(index) {
+                this.preSelectVal = this.$refs.periodSelect.value
+                if (this.hasModify) {
+                    this.handleConfirmSave({}, '3')
+                } else {
+                    let that = this
+                    this.isLoadSubject = true
+                    this.activePeriodIndex = index
+                    //this.currentParams.periodCode = this.originData.period[index].periodCode
+                    this.subjectList = this.periodList[index].subjects //切换学段后更新 科目 列表
+                    this.originSubjectList = this.periodList[index].subjects // 筛选科目源数据
+                    this.gradeList = this.periodList[index].grades //切换学段后更新 年级 列表
+                    this.semesterList = this.periodList[index].semesters //切换学段后更新 学期 列表
+                    this.handleSubjectTap(0)
+                    setTimeout(function () {
+                        that.isLoadSubject = false
+                    }, 1000)
+                }
+            },
+
+            //科目点击事件
+            handleSubjectTap(index) {
+                if (this.hasModify) {
+                    this.$Modal.confirm({
+                        title: '修改提示',
+                        content: '<p>您有未保存的课纲,将会丢失所有更改,确认放弃修改?</p>',
+                        okText: '确认',
+                        cancelText: '取消',
+                        onOk: () => {
+                            this.hasModify = false
+                            this.isLoadVolumes = true
+                            this.currentSubject = index;
+                            this.currentParams.subjectCode = this.subjectList[index].subjectCode
+                            this.activeSubjectIndex = index
+                            this.getVolumesData()
+                        }
+                    })
+                } else {
+                    this.isLoadVolumes = true
+                    this.currentSubject = index;
+                    this.currentParams.subjectCode = this.subjectList[index].subjectCode
+                    this.activeSubjectIndex = index
+                    this.getVolumesData()
+
+                }
+            },
+
+            //知识块点击事件
+            handleBlockTap(index, item) {
+                let that = this
+                this.activeBlockIndex = index
+                this.currentBlock = item
+                this.isLoadPoints = true
+                setTimeout(function () {
+                    that.pointList = item ? item.points : []
+                    that.isLoadPoints = false
+                }, 1000)
+            },
+
+            //添加知识块完成
+            onFinishAddVolume(val) {
+                if (val) {
+                    let isExist = this.blockList.filter(item => item.id === val).length //判断列表是否已存在该学期下的知识块,有则更新,无则添加
+                    if (isExist) {
+                        this.$Message.success("知识块已存在,已为您更新数据")
+                    } else {
+                        this.$Message.success("添加新知识块成功")
+                    }
+                    this.handleSubjectTap(this.currentSubject); //获取最新知识块数据
+
+                }
+                this.isAddVolume = false  //关闭窗口
+            },
+
+            // 删除知识块事件
+            onDeleteVolume(data) {
+                data.status = 0
+                this.$Modal.confirm({
+                    title: '删除科目',
+                    content: '<p>确认删除该知识块?</p>',
+                    okText: '确认',
+                    cancelText: '取消',
+                    onOk: () => {
+                        this.$api.knowledge.DeleteVolume(data).then(res => {
+                            if (res.result.data) {
+                                this.blockList.splice(this.blockList.indexOf(data), 1)
+                                this.$Message.success('删除成功')
+                                this.handleBlockTap(0, this.blockList.length ? this.blockList[0] : null)
+                            } else {
+                                this.$Message.success('删除失败')
+                            }
+                        })
+                    }
+                })
+            },
+
+            // 编辑知识块事件
+            onEditVolume(data) {
+                this.isAddVolume = true // 打开新增窗口
+                this.isEditVolume = true //设置成编辑状态
+                this.editVolume = data
+            },
+
+            //新增知识块事件
+            onAddVolume() {
+                this.isAddVolume = true
+                this.isEditVolume = false
+                this.editVolume = null
+            },
+
+            //搜索知识块输入框onchange事件
+            onSearchBlockChange() {
+                this.blockList = this.originBlockList.filter(item => item.name.indexOf(this.searchBlock) > -1);
+            },
+
+            //搜索知识点输入框onchange事件
+            onSearchPointChange() {
+                //this.blockList = this.originBlockList.filter(item => item.volumeName.indexOf(this.searchBlock) > -1);
+            },
+
+            //搜索科目输入框onchange事件
+            onSearchSubjectChange() {
+                this.subjectList = this.originSubjectList.filter(item => item.subjectName.indexOf(this.searchSubject) > -1);
+                this.handleSubjectTap(0)
+            },
+
+
+        },
+    }
+</script>
+
+<style>
+    .new-syllabus-header .ivu-select-single .ivu-select-selection,
+    .funnel-box .ivu-select-single .ivu-select-selection {
+        background: #605f5f;
+        color: #fbfbfb;
+        border: none;
+    }
+
+    .new-syllabus-header .ivu-select-single .ivu-select-arrow,
+    .funnel-box .ivu-select-single .ivu-select-arrow {
+        color: #fbfbfb;
+    }
+
+    .ns-header .ivu-input {
+        background: #3c3c3c;
+        color: #fff;
+        border: none;
+        height: 36px;
+        margin-top: 7px;
+    }
+
+    .ns-header .ivu-input-icon {
+        font-size: 24px;
+        color: #cfc7c7;
+        line-height: 50px;
+        cursor: pointer;
+    }
+
+    /* 修改iview Modal样式 */
+
+    .add-volume-modal .ivu-modal-content {
+        background: #3c3c3c;
+        color: #fff;
+        font-family: '微軟正黑體', 'Heiti TC';
+    }
+
+    .add-volume-modal .ivu-modal-header {
+        border-bottom: none;
+        font-size: 18px;
+        font-weight: bold;
+        padding: 25px;
+    }
+
+    .add-volume-modal .modal-content {
+        padding: 10px 35px 30px 35px;
+    }
+
+    /* 修改iview popper样式 */
+
+    .ns-col .ivu-poptip-inner {
+        background: #3c3c3c;
+    }
+
+    .ns-col .ivu-poptip-title:after {
+        background: #656565;
+        left: 16px;
+        right: 20px;
+    }
+
+    .ns-col .ivu-poptip-title-inner {
+        color: #fff;
+    }
+
+    .ns-col .ivu-poptip-popper[x-placement^=bottom] .ivu-poptip-arrow:after {
+        border-bottom-color: #494949;
+    }
+</style>

+ 150 - 0
TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/addBlock.vue

@@ -0,0 +1,150 @@
+
+<template>
+    <div class="form-container">
+        <Form :model="formTop" label-position="top">
+            <FormItem label="科目">
+                <Select v-model="formTop.subject">
+                    <Option v-for="(item,index) in currentPeriod.subjects" :value="item.subjectCode" :key="index">{{ item.subjectName }}</Option>
+                </Select>
+            </FormItem>
+            <FormItem label="名称">
+                <Input v-model="formTop.name" placeholder="请输入知识块名称,必填项"></Input>
+            </FormItem>
+            <FormItem>
+                <Button @click="handleSubmit">确认</Button>
+            </FormItem>
+        </Form>
+    </div>
+</template>
+
+<script>
+    import '@/utils/Math.uuid'
+    export default {
+        props: ['originData', 'periodIndex','subjectIndex','editVolume'],
+        data() {
+            return {
+                originDatas: {},
+                currentPeriod: {},
+                editItem: {},
+                formTop: {
+                    subject: '',
+                    grade: '',
+                    semester: '',
+                    name: ''
+                }
+            }
+        },
+
+        created() {
+
+        },
+        methods: {
+            // 提交添加
+            handleSubmit() {
+                console.log("提交的ITEM")
+                console.log(this.editItem)
+                let params = {
+                    type: 0,
+                    name: this.formTop.name,
+                    alias: this.formTop.name,
+                    subjectCode: this.formTop.subject,
+                    schoolCode: "2151002664111",
+                    order: 706,
+                    status: 1,
+                    knowledgeId: Math.uuid(),
+                    points: [],
+                    source: 1
+                }
+                this.$api.knowledge.SaveOrUpdateSchoolBlock([params]).then(res => {
+                    if (!res.error && res.result.data) {
+                        this.$emit('addFinish',res.result.data.id)
+                    } else {
+                        this.$Message.warning("添加册别失败,错误代码:" + res.error.code + ",错误信息:"  + res.error.message)
+                    }
+                    this.closeModal();
+                    this.editItem = {};
+                }).catch(err => {
+                     this.$Message.warning("添加册别失败")
+                })
+            },
+
+            //添加完成 关闭窗口
+            closeModal() {
+                this.$emit('addFinish', false)
+                this.formTop.volume = ''
+            }
+        },
+        mounted() {
+        },
+        watch: {
+            originData: {
+                handler(newValue, oldValue) {
+                    this.originDatas = newValue
+                },
+            },
+            periodIndex: {
+                handler(newValue, oldValue) {
+                    this.currentPeriod = this.originDatas.period[newValue]
+                    this.formTop.subject = this.currentPeriod.subjects[0].subjectCode
+                    this.formTop.name = ""
+                },
+            },
+            subjectIndex: {
+                handler(newValue, oldValue) {
+                    this.formTop.subject = this.currentPeriod.subjects[newValue].subjectCode
+                },
+            },
+            editVolume: {
+                handler(newValue, oldValue) {
+                    if (newValue) {  // 有编辑册别传过来则为编辑状态
+                        this.editItem = newValue
+                        this.formTop.subject = newValue.subjectCode
+                        this.formTop.name = newValue.name
+                    } else { //否则为新增状态
+                        this.formTop.subject = this.currentPeriod.subjects[0].subjectCode
+                        this.formTop.name = ""
+                    }
+                    
+                },
+            }
+        },
+
+    }
+</script>
+
+<style>
+    .form-container .ivu-form .ivu-form-item-label {
+        color: #fff;
+        margin:10px 0;
+        font-size:16px;
+    }
+
+    .form-container .ivu-input {
+        background: #575757;
+        border-color: transparent;
+        height: 35px;
+        color:#fff;
+    }
+    .form-container .ivu-input::-webkit-input-placeholder {
+        color:#808080;
+    }
+
+    .form-container .ivu-select-single .ivu-select-selection {
+        background: #575757;
+        color: #fbfbfb;
+        border-color: transparent;
+        height: 35px;
+    }
+
+    .form-container .ivu-select-single .ivu-select-arrow {
+        color: #fbfbfb;
+    }
+
+    .form-container .ivu-btn {
+        width: 100%;
+        height: 40px;
+        background: rgb(11, 151, 117);
+        border: none;
+        color:#fff;
+    }
+</style>

+ 78 - 38
TEAMModelOS/ClientApp/src/view/syllabus/newSyllabus/index.vue

@@ -12,7 +12,7 @@
             </div>
             <div class="new-syllabus-select">
                 <span>当前学段:</span>
-                <Select v-model="currentPeriod" style="width:200px" @on-change="onPeriodChange">
+                <Select ref="periodSelect" v-model="currentPeriod" style="width:200px" @on-change="onPeriodChange">
                     <Option v-for="(item,index) in periodList" :value="index" :key="index">{{ item.periodName }}</Option>
                 </Select>
             </div>
@@ -48,7 +48,7 @@
                         <div :class='["gl-item","animated","slideInUp",index == activeSubjectIndex ? "item-active":""]'
                              v-for="(item,index) in subjectList"
                              :key="index"
-                             @click="handleSubjectTap(index)"
+                             @click="hasModify ? handleConfirmSave({index},'2') : handleSubjectTap(index)"
                              :style="{ animationDelay: ((index+1)*0.05) + 's'}">
                             <p class="gl-item-name">{{item.subjectName}}</p>
                             <p class="gl-item-info"><span></span>册别数:{{index}}</p>
@@ -107,7 +107,7 @@
                             <div :class='["gl-item","animated","slideInUp",index == activeVolumeIndex ? "item-active":""]'
                                  v-for="(item,index) in volumeList"
                                  :key="index"
-                                 @click="handleVolumeTap(index,item)"
+                                 @click="hasModify ? handleConfirmSave({index,item},'1') : handleVolumeTap(index,item)"
                                  :style="{ animationDelay: ((index+1)*0.05) + 's'}">
                                 <p class="gl-item-name">{{item.volumeName}}</p>
                                 <p class="gl-item-info">{{item.gradeName}}<span></span>{{item.semesterName}}</p>
@@ -205,7 +205,8 @@
                 searchVolume: '',
                 searchSubject: '',
                 editVolume: null,
-                hasModify: false
+                hasModify: false,
+                preSelectVal:null
             }
         },
         components: {
@@ -226,7 +227,6 @@
                         this.currentParams.periodCode = this.originData.period[0].periodCode
                         this.currentPeriod = 0 //默认选择第一个学段
                         this.onPeriodChange(0)
-
                     } else {
                         this.$Message.warning("暂无学段数据")
                     }
@@ -277,32 +277,29 @@
 
             //学段切换处理
             onPeriodChange(index) {
-                let that = this
-                this.isLoadSubject = true
-                this.activePeriodIndex = index
-                this.currentParams.periodCode = this.originData.period[index].periodCode
-                this.subjectList = this.periodList[index].subjects //切换学段后更新 科目 列表
-                this.originSubjectList = this.periodList[index].subjects // 筛选科目源数据
-                this.gradeList = this.periodList[index].grades //切换学段后更新 年级 列表
-                this.semesterList = this.periodList[index].semesters //切换学段后更新 学期 列表
-                this.handleSubjectTap(0)
-                setTimeout(function () {
-                    that.isLoadSubject = false
-                }, 1000)
+                this.preSelectVal = this.$refs.periodSelect.value
+                if (this.hasModify) {
+                    this.handleConfirmSave({}, '3')
+                } else {
+                    let that = this
+                    this.isLoadSubject = true
+                    this.activePeriodIndex = index
+                    this.currentParams.periodCode = this.originData.period[index].periodCode
+                    this.subjectList = this.periodList[index].subjects //切换学段后更新 科目 列表
+                    this.originSubjectList = this.periodList[index].subjects // 筛选科目源数据
+                    this.gradeList = this.periodList[index].grades //切换学段后更新 年级 列表
+                    this.semesterList = this.periodList[index].semesters //切换学段后更新 学期 列表
+                    this.handleSubjectTap(0)
+                    setTimeout(function () {
+                        that.isLoadSubject = false
+                    }, 1000)
+                }
+
 
             },
 
             //科目点击事件
             handleSubjectTap(index) {
-                this.isLoadVolumes = true
-                this.currentSubject = index;
-                this.currentParams.subjectCode = this.subjectList[index].subjectCode
-                this.activeSubjectIndex = index
-                this.getVolumesData()
-            },
-
-            //册别点击事件
-            handleVolumeTap(index, volume) {
                 if (this.hasModify) {
                     this.$Modal.confirm({
                         title: '修改提示',
@@ -311,25 +308,33 @@
                         cancelText: '取消',
                         onOk: () => {
                             this.hasModify = false
-                            this.activeVolumeIndex = index
-                            this.currentVolume = volume
-                            if (volume) {
-                                this.isLoadSyllabus = true
-                                this.getTreeByVolume(volume.volumeCode)
-                            }
+                            this.isLoadVolumes = true
+                            this.currentSubject = index;
+                            this.currentParams.subjectCode = this.subjectList[index].subjectCode
+                            this.activeSubjectIndex = index
+                            this.getVolumesData()
                         }
                     })
                 } else {
-                    this.activeVolumeIndex = index
-                    this.currentVolume = volume
-                    if (volume) {
-                        this.isLoadSyllabus = true
-                        this.getTreeByVolume(volume.volumeCode)
-                    }
+                    this.isLoadVolumes = true
+                    this.currentSubject = index;
+                    this.currentParams.subjectCode = this.subjectList[index].subjectCode
+                    this.activeSubjectIndex = index
+                    this.getVolumesData()
 
                 }
             },
 
+            //册别点击事件
+            handleVolumeTap(index, volume) {
+                this.activeVolumeIndex = index
+                this.currentVolume = volume
+                if (volume) {
+                    this.isLoadSyllabus = true
+                    this.getTreeByVolume(volume.volumeCode)
+                }
+            },
+
             //添加册别完成
             onFinishAddVolume(val) {
                 if (val) {
@@ -449,6 +454,41 @@
                         this.$Message.warning("获取数据失败")
                     }
                 })
+            },
+
+            // 判断用户是否放弃修改
+            handleConfirmSave(param,type) {
+                this.$Modal.confirm({
+                    title: '修改提示',
+                    content: '<p>您有未保存的课纲,将会丢失所有更改,确认放弃修改?</p>',
+                    okText: '确认',
+                    cancelText: '取消',
+                    onOk: () => {
+                        this.hasModify = false
+                        switch (type) {
+                            case '1':
+                                this.handleVolumeTap(param.index, param.item)
+                                break
+                            case '2':
+                                this.handleSubjectTap(param.index)
+                                break
+                            case '3':
+                                this.onPeriodChange(this.currentPeriod)
+                                break
+                            default:
+                                break
+                        }
+                    },
+                    onCancel: () => {
+                        switch (type) {
+                            case '3':
+                                this.currentPeriod = this.preSelectVal
+                                break
+                            default:
+                                break
+                        }
+                    }
+                })
             }
         },
     }

+ 1 - 1
TEAMModelOS/ClientApp/src/view/teachcontent/index.less

@@ -174,7 +174,7 @@
         width: ~'calc(100% - 220px)';
         float: right;
         height: 100%;
-        margin-top:-8px;
+        /*margin-top:-8px;*/
         .content-file-filter {
             height: 50px;
             /*line-height: 50px;*/

+ 67 - 8
TEAMModelOS/ClientApp/src/view/teachcontent/index.vue

@@ -2,8 +2,8 @@
     <div class="teach-content">
         <div class="teach-content-top">
             <div class="tab-box">
-                <span :class="tabIndex == 1 ? 'tab-active' : ''" @click="handleTabClick(1)">私有资源</span>
-                <span :class="tabIndex == 0 ? 'tab-active' : ''" @click="handleTabClick(0)">校本资源</span>
+                <span :class="rangeType == 1 ? 'tab-active' : ''" @click="handleTabClick(1)">私有资源</span>
+                <span :class="rangeType == 0 ? 'tab-active' : ''" @click="handleTabClick(0)">校本资源</span>
             </div>
             <div class="upload-box" @click="toggleUpload">
 
@@ -18,7 +18,7 @@
                     <Icon :type="item.icon" color="white" size="28" />
                     <span class="content-type-label">{{item.label}}</span>
                 </div>
-                <div :class="tabIndex === 1 ? 'space-box animated fadeIn fast' : 'space-box animated fadeOut fast'">
+                <div :class="rangeType === 1 ? 'space-box animated fadeIn fast' : 'space-box animated fadeOut fast'">
                     <Progress hide-info :percent="48" :stroke-width="15" style="width:100%;" />
                     <p>
                         <span>空间:1020M/2G</span>
@@ -88,7 +88,7 @@
             </div>
         </div>
         <Modal v-model="uploadStatus"
-               title="上传教学资源" class="upload-modal">
+               title="上传教学资源" class="upload-modal" @on-ok="confirmUpload">
             <Upload type="drag" :action="uploadUrl" multiple :on-success="getFileUrl">
                 <p style="margin:20px 0px;font-size:20px;">点击或者拖拽上传</p>
                 <Icon type="ios-cloud-upload" size="50" style="margin-bottom:30px;"/>
@@ -100,7 +100,8 @@
     export default {
         data() {
             return {
-                uploadStatus:false,
+                uploadStatus: false,
+                uploadFileList:[],
                 uploadUrl:'',
                 keyWord: '',
                 demoLoginInfo: {
@@ -475,7 +476,12 @@
                         url:"XXXXXXXXXX"
                     }
                 ],
-                tabIndex: 1,
+                rangeType: 1,
+                contentTypes: [
+                    'JPG,JPEG,PNG,GIF',
+                    'AVI,MP4',
+                    'PPT,PPTX,DOC,DOCX,PDF,XLS,XLSX'
+                ],
                 contentTypeList: [
                     {
                         label: '全部',
@@ -506,13 +512,66 @@
             }
         },
         methods: {
+            confirmUpload() {
+                console.log(this.uploadFileList)
+                this.$api.teachContent.saveOrUpdateResource(this.uploadFileList).then(
+                    (res) => {
+                        console.log(res)
+                    },
+                    (err) => {
+                        alert('API error!')
+                    }
+                )
+            },
             toggleUpload() {
                 this.uploadStatus = !this.uploadStatus
             },
             getFileUrl(response) {  //获取文件地址
                 console.log(response)
                 if (response.error == null) {
-                    
+                    let resData = response.result.data
+                    if (resData.length > 0) {
+                        let type = 'other';
+                        for (let item in this.contentTypes) {
+                            if (this.contentTypes[item].indexOf(resData[0].extension.toUpperCase()) !== -1) {
+                                switch (true) {
+                                    case item == 0:
+                                        type = 'picture'
+                                        console.log(type)
+                                        break
+                                    case item == 1:
+                                        type = 'video'
+                                        console.log(type)
+                                        break
+                                    case item == 2:
+                                        type = 'document'
+                                        console.log(type)
+                                        break
+                                    default:
+                                        break
+                                        
+                                }
+                                break
+                            }
+                            
+                        }
+                        this.uploadFileList.push({
+                            teamModelId: this.demoLoginInfo.teamModelId,
+                            fileName: resData[0].fileName,
+                            extension: resData[0].extension,
+                            contentType: resData[0].contentType,
+                            type: type,
+                            size: resData[0].length,
+                            createTime: resData[0].uploadTime,
+                            relationNum: 0,
+                            blobUrl: resData[0].blobUrl,
+                            range: this.rangeType === 1 ? 'private':'shcool',
+                            sha1Code: resData[0].sha1Code
+                        })
+                    }
+
+                } else {
+                    alert('API error!')
                 }
             },
             setOrderWay(value) {
@@ -530,7 +589,7 @@
                 }
             },
             handleTabClick(index) {
-                this.tabIndex = index
+                this.rangeType = index
             },
             selectFileType(index) {
                 this.activeTypeIndex = index