OnePsycho před 5 roky
rodič
revize
1d37d51631

+ 1 - 0
.gitignore

@@ -252,3 +252,4 @@ _Pvt_Extensions
 
 .vscode/
 /.idea
+/TEAMModelOS/wwwroot/dist

+ 522 - 0
TEAMModelOS/ClientApp/src/components/syllabus/newTree.vue

@@ -0,0 +1,522 @@
+<template>
+  <div class="tree-main">
+
+    <Tree :data="treeData" :render="renderContent" ref="tree"></Tree>
+    <Modal v-model="modalFlag" title="添加新节点" ok-text="确认" cancel-text="取消" @on-ok="handleAddNode">
+      <Row class="modelRow">
+        <span>
+          当前章节:
+          <span style="margin-left:10px;">{{currentNode.title}}</span>
+        </span>
+      </Row>
+      <Row class="modelRow">
+        <span>节点名称:</span>
+        <Input v-model="inputValue" placeholder="输入新节点名称" style="width: 100%" />
+      </Row>
+    </Modal>
+    <Modal v-model="editFlag" title="修改节点" ok-text="确认" cancel-text="取消" @on-ok="handleUpdateNode">
+      <Row class="modelRow">
+        <span>
+          当前名称:
+          <span style="margin-left:10px;">{{currentNode.title}}</span>
+        </span>
+      </Row>
+      <Row class="modelRow">
+        <span>修改名称:</span>
+        <Input v-model="editValue" placeholder="输入节点新名称" style="width: 100%" />
+      </Row>
+    </Modal>
+  </div>
+</template>
+<script>
+  export default {
+    props: ["treeDatas", "volumeCode"],
+    data() {
+      return {
+        treeData: [],
+        inputValue: "",
+        editValue: "",
+        modalFlag: false,
+        editFlag: false,
+        addBookFlag: false,
+        nodeType: "章节",
+        currentNode: "",
+        currentLiNode: "",
+      };
+    },
+    created() {
+      this.treeData = this.treeDatas;
+    },
+    watch:{
+      treeDatas: {
+        handler(newValue, oldValue) {
+          this.treeData = newValue;
+    },
+    deep: true
+  }
+    },
+    methods: {
+      renderContent(h, { root, node, data }) {
+        let that = this;
+        return h(
+          "span",
+          {
+            domProps: {
+              className: "singleClass"
+            },
+            on: {
+              click: () => {
+                this.titleClick(data);
+              },
+              mouseover: e => {
+                e.stopPropagation();
+                this.handleLiOver(event);
+              },
+              mouseleave: e => {
+                e.stopPropagation();
+                this.handleLiLeave(node, event);
+              }
+            }
+          },
+          [
+            h("span", [
+              h("Icon", {
+                props: {
+                  type:
+                    data.children && data.children.length > 0
+                      ? "md-albums"
+                      : "ios-paper-outline"
+                },
+                style: {
+                  marginRight: "5px",
+                  display: "none",
+                }
+              }),
+              h("span", data.title)
+            ]),
+            h(
+              "span",
+              {
+                style: {
+                  float: "right",
+                  top: "14px",
+                  display: "none"
+                },
+                on: {
+                  mouseleave: e => {
+                    e.stopPropagation();
+                    //this.hideTools(event);
+                  },
+                },
+                domProps: {
+                  className: "tools"
+                }
+              },
+              [
+                h(
+                  "Icon",
+                  {
+                    props: {
+                      type: "md-add",
+                      title: "添加"
+                    },
+                    on: {
+                      click: e => {
+                        e.stopPropagation();
+                        this.appendClick(data);
+                      }
+                    }
+                  },
+                ),
+                h(
+                  "Icon",
+                  {
+                    props: {
+                      type: "md-remove"
+                    },
+                    on: {
+                      click: e => {
+                        e.stopPropagation();
+                        this.remove(root, node, data);
+                      }
+                    }
+                  },
+                ),
+                h(
+                  "Icon",
+                  {
+                    props: {
+                      type: "md-arrow-round-up"
+                    },
+                    on: {
+                      click: e => {
+                        e.stopPropagation();
+                        this.moveUp(root, node, data);
+                      }
+                    }
+                  },
+                ),
+                h(
+                  "Icon",
+                  {
+                    props: {
+                      type: "md-arrow-round-down"
+                    },
+                    on: {
+                      click: e => {
+                        e.stopPropagation();
+                        this.moveDown(root, node, data);
+                      }
+                    }
+                  },
+                ),
+                h(
+                  "Icon",
+                  {
+                    props: {
+                      type: "md-create"
+                    },
+                    on: {
+                      click: e => {
+                        e.stopPropagation();
+                        this.editClick(node, data);
+                      }
+                    }
+                  },
+                )
+              ]
+            )
+          ]
+        );
+      },
+      // 添加节点
+      append(data, value) {
+        const children = data.children || [];
+        let newChild = {
+          title: value,
+          order: children.length,
+          pid: data.rowKey,
+          children: [],
+          expand: true,
+          type: data.type,
+          volumeCode: this.volumeCode,
+          remark: "备注",
+        }
+        children.push(newChild);
+        this.$set(data, "children", children);
+        this.$api.SaveOrUpdateSingleNode(newChild).then(res => {
+          this.$Message.success("添加成功");
+          this.$api.FindSyllabusByVolumeCode({ VolumeCode: this.volumeCode, Status: 1 }).then(res => {
+            this.treeData = res.result.data;
+          })
+        })
+      },
+      // 删除节点
+      remove(root, node, data) {
+        data.status = 0;
+        this.$api.SaveOrUpdateSingleNode(data).then(res => {
+          this.$Message.success("删除成功");
+          this.$api.FindSyllabusByVolumeCode({ VolumeCode: this.volumeCode, Status: 1 }).then(res => {
+            this.treeData = res.result.data;
+          })
+        })
+      },
+      // 点击编辑
+      editClick(node, data) {
+        this.currentNode = data;
+        this.editFlag = true;
+        this.editValue = "";
+      },
+      //添加节点 弹出输入框
+      appendClick(data) {
+        this.currentNode = data;
+        this.modalFlag = true;
+        this.inputValue = "";
+      },
+      // 确认添加节点
+      handleAddNode() {
+        if (this.inputValue != "") {
+          this.append(this.currentNode, this.inputValue);
+        } else {
+          this.modalFlag = false;
+        }
+      },
+      // 修改节点
+      handleUpdateNode() {
+        if (this.editValue != "") {
+          this.$api.SaveOrUpdateSingleNode(this.currentNode).then(res => {
+            this.$Message.success("修改成功");
+            this.currentNode.title = this.editValue;
+          })
+        } else {
+          this.editFlag = false;
+        }
+      },
+      // 标题点击收缩展开
+      titleClick(data) {
+        data.expand = !data.expand;
+      },
+      // 根目录点击事件
+      rootClick(data) {
+        data.expand = !data.expand;
+      },
+      // 上移章节操作
+      moveUp(root, node, data) {
+        let that = this;
+        let list = [];
+        const parentKey = root.find(el => el === node).parent;
+
+        //判断是否存在父级
+        if (parentKey == null || parentKey == undefined) {
+          list = that.treeData;
+        } else {
+          list = root.find(el => el.nodeKey === parentKey).node.children;
+        }
+        const index = list.indexOf(data);
+        let currentOrder = data.order;
+
+        //第一个元素无法上移
+        if (index != 0) {
+          let preData = list[index - 1];
+          if (data.order == preData.order) {
+            data.order = data.order - 1;
+          } else {
+            data.order = preData.order;
+            preData.order = currentOrder;
+          }
+          //更新两条数据
+          that.$api.SaveOrUpdateSingleNode(data);
+          that.$api.SaveOrUpdateSingleNode(preData);
+
+          //移动后刷新数据
+          setTimeout(function () {
+            that.$api.FindSyllabusByVolumeCode({ VolumeCode: that.volumeCode, Status: 1 }).then(res => {
+              that.treeData = res.result.data;
+            })
+          }, 500)
+        }
+      },
+      // 下移章节操作
+      moveDown(root, node, data) {
+        let that = this;
+        let list = [];
+        const parentKey = root.find(el => el === node).parent;
+
+        //判断是否存在父级
+        if (parentKey == null || parentKey == undefined) {
+          list = that.treeData;
+        } else {
+          list = root.find(el => el.nodeKey === parentKey).node.children;
+        }
+        const index = list.indexOf(data);
+        let currentOrder = data.order;
+        //最后一个元素无法下移
+        if (index != (list.length - 1)) {
+           let nextData = list[index + 1];
+          if (data.order == nextData.order) {
+            data.order = data.order + 1;
+          } else {
+            data.order = nextData.order;
+            nextData.order = currentOrder;
+          }
+          //更新两条数据
+          that.$api.SaveOrUpdateSingleNode(data);
+          that.$api.SaveOrUpdateSingleNode(nextData);
+
+          //移动后刷新数据
+          setTimeout(function () {
+            that.$api.FindSyllabusByVolumeCode({ VolumeCode: that.volumeCode, Status: 1 }).then(res => {
+              that.treeData = res.result.data;
+            })
+          }, 500)
+        }
+      },
+      // 更多操作
+      handleTools(root, node, data, event) {
+        let toolsDom = event.currentTarget.nextElementSibling;
+        const parentKey = root.find(el => el === node).parent;
+        const parent = root.find(el => el.nodeKey === parentKey).node;
+        const index = parent.children.indexOf(data);
+        let list = document.getElementsByClassName("tools");
+        let cFlag = toolsDom.style.display;
+        for (let i = 0; i < list.length; i++) {
+          list[i].style.display = "none";
+        }
+        // 判断TOOL显示与隐藏
+        if (cFlag == "none") {
+          toolsDom.style.display = "inline-flex";
+          toolsDom.classList.add("animated");
+          toolsDom.classList.add("slideInDown");
+        } else {
+          toolsDom.style.display = "none";
+        }
+      },
+      // 鼠标从工具条移开的时候隐藏
+      hideTools(event) {
+        event.currentTarget.style.display = "none";
+      },
+      handleLiOver(event) {
+        event.currentTarget.lastElementChild.style.display = "block";
+        event.currentTarget.style.backgroundColor = "rgba(55, 55, 55, 0.68)";
+        event.currentTarget.style.border = "1px solid #000";
+      },
+      handleLiLeave(node, event) {
+        event.currentTarget.lastElementChild.style.display = "none";
+        if (this.currentLiNode.nodeKey != node.nodeKey) {
+          event.currentTarget.style.backgroundColor = "transparent";
+          event.currentTarget.style.border = "0";
+        }
+      },
+     
+    },
+  };
+</script>
+<style scoped>
+  .tree-main {
+    margin-left: 5%;
+    width: 90%;
+    user-select:none;
+  }
+
+    .tree-main /deep/ .ivu-icon-ios-paper-outline {
+      font-size: 14px;
+    }
+
+    .tree-main /deep/ .ivu-select {
+      width: 80% !important;
+    }
+
+  .slideSelect .ivu-select-selection {
+    height: 40px;
+    background: #d8d8d870;
+    border: 1px solid #808080;
+  }
+
+  .slideSelect, .slideSelect .ivu-icon {
+    color: rgba(255,255,255,.8);
+  }
+
+  .tree-main /deep/ .ivu-select-single .ivu-select-selection .ivu-select-selected-value {
+    height: 40px;
+    line-height: 40px;
+    font-size: 14px;
+  }
+  /* .ivu-tree ul li {
+    margin: 18px 0;
+  } */
+  .tree-main /deep/ .ivu-tree ul {
+    font-size: 14px;
+    position:relative;
+  }
+  
+  /*.tree-main /deep/ .ivu-tree ul::after {
+        content: " ";
+    position: absolute;
+    width: 0;
+    height: 100%;
+    border-left: 1px dashed #fff;
+    left: 5px;
+    top: -11px;
+  }*/
+
+    .tree-main /deep/ .ivu-tree ul li {
+      margin: 8px 0;
+    }
+
+  .ivu-tree .ivu-tree-arrow {
+    width: 2%;
+  }
+  .ivu-tree /deep/ .ivu-tree-arrow i{
+    color:#fff;
+  }
+
+  .ivu-input-wrapper {
+    width: 80% !important;
+  }
+
+  .modelRow {
+    margin: 20px;
+    font-size: 14px;
+  }
+
+  .tree-main /deep/ .tools {
+    position: absolute;
+    right: 60px;
+    bottom: 5px;
+    display: inline-flex;
+    z-index: 999;
+  }
+
+    .tree-main /deep/ .tools .ivu-icon {
+      margin-right: 15px;
+      font-size: 16px;
+      font-weight: 200;
+      color: rgba(255,255,255,.8);
+    }
+
+  .btn_more {
+    background: #fff;
+    border: 1px solid rgb(248,248,248);
+  }
+
+  .animated {
+    animation-duration: 0.5s;
+  }
+
+  @-webkit-keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0,-10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  @keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0, -10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  .slideInDown {
+    -webkit-animation-name: slideInDown;
+    animation-name: slideInDown;
+  }
+
+  .tree-main /deep/ .singleClass {
+    display: inline-flex !important;
+    position:relative;
+    flex-direction: row;
+    align-items: center;
+    width:100%;
+    font-size:14px;
+    height: 50px;
+    padding-left:10px;
+    color:#fff;
+    user-select:none;
+    cursor:pointer;
+  }
+    
+   /*.tree-main /deep/ .singleClass:before {
+            content: " ";
+    position: absolute;
+    width: 100px;
+    height: 0;
+    left: 5px;
+    top: 20px;
+    border-top: 1px dashed #fff;
+    }*/
+
+
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/filters/http.js

@@ -98,7 +98,7 @@ export function post(url, params) {
     axios.post(url,data)
       .then(response => {
         resolve(response.data);
-       // this.$Message.success('数据访问成功!');
+        //this.$Message.success('数据访问成功!');
       },err => {
         reject(err);
         //this.$Message.error('数据访问错误!');

+ 1 - 0
TEAMModelOS/ClientApp/src/view/syllabus/newSyllabus/Index.less

@@ -151,6 +151,7 @@
 
         .ns-col4 {
             width: 50%;
+            padding-top:20px;
         }
     }
 }

+ 183 - 90
TEAMModelOS/ClientApp/src/view/syllabus/newSyllabus/index.vue

@@ -1,109 +1,202 @@
 <style lang="less" scoped>
-  @import './Index.less';
+    @import './Index.less';
 </style>
 
 <template>
-  <div class="new-syllabus-container">
-    <div class="new-syllabus-header">
-      <div>
-        <span>课纲管理</span>
-      </div>
-      <div>
-        <!--<Input search placeholder="Enter something..." />-->
-      </div>
-    </div>
-    <div class="new-syllabus-content">
-      <div class="ns-col ns-col1" slot="left">
-        <div class="ns-header">
-          <span>选择学段</span>
-        </div>
-        <vuescroll>
-          <div class="pl">
-            <div class="pl-item" v-for="(item,index) in periodList" :key="index" @click="handlePeriodTap(index)" :class="index == activePeriodIndex ? 'item-active':''">
-              <p class="pl-item-name">{{item.name}}</p>
-              <p class="pl-item-info"><span></span>年级数:{{item.gradeCount}}</p>
-              <p class="pl-item-info"><span></span>学期数:{{item.semesterCount}}</p>
-              <p class="pl-item-info"><span></span>科目数:{{item.subjectCount}}</p>
+    <div class="new-syllabus-container">
+        <div class="new-syllabus-header">
+            <div>
+                <span>课纲管理</span>
             </div>
-          </div>
-        </vuescroll>
-      </div>
-      <div class="ns-col ns-col2" slot="right">
-        <div class="ns-header">
-          <span>选择科目</span>
-        </div>
-        <vuescroll>
-          <div class="gl">
-            <div class="gl-item" v-for="(item,index) in subjectList" :key="index" @click="handleSubjectTap(index)" :class="index == activeGradeIndex ? 'item-active':''">
-              <p class="gl-item-name">{{item.name}}</p>
-              <p class="gl-item-info"><span></span>册别数:{{index}}</p>
+            <div>
+                <!--<Input search placeholder="Enter something..." />-->
             </div>
-          </div>
-        </vuescroll>
-      </div>
-      <div class="ns-col ns-col3" slot="trigger">
-        <div class="ns-header">
-          <span>选择册别</span>
         </div>
-        <vuescroll>
-          <div class="gl">
-            <div class="gl-item" v-for="(item,index) in subjectList" :key="index" @click="handleVolumnTap(index)" :class="index == activeVolumnIndex ? 'item-active':''">
-              <p class="gl-item-name">小学二年级语文上册</p>
-              <p class="gl-item-info"><span></span>册别数:{{index}}</p>
+        <div class="new-syllabus-content">
+            <div class="ns-col ns-col1" slot="left">
+                <div class="ns-header">
+                    <span>选择学段</span>
+                </div>
+                <vuescroll>
+                    <div class="pl">
+                        <div class="pl-item" v-for="(item,index) in periodList" :key="index" @click="handlePeriodTap(index)" :class="index == activePeriodIndex ? 'item-active':''">
+                            <p class="pl-item-name">{{item.name}}</p>
+                            <p class="pl-item-info"><span></span>年级数:{{item.gradeCount}}</p>
+                            <p class="pl-item-info"><span></span>学期数:{{item.semesterCount}}</p>
+                            <p class="pl-item-info"><span></span>科目数:{{item.subjectCount}}</p>
+                        </div>
+                    </div>
+                </vuescroll>
+            </div>
+            <div class="ns-col ns-col2" slot="right">
+                <div class="ns-header">
+                    <span>选择科目</span>
+                </div>
+                <vuescroll>
+                    <div class="gl">
+                        <div class="gl-item" v-for="(item,index) in subjectList" :key="index" @click="handleSubjectTap(index)" :class="index == activeGradeIndex ? 'item-active':''">
+                            <p class="gl-item-name">{{item.name}}</p>
+                            <p class="gl-item-info"><span></span>册别数:{{index}}</p>
+                        </div>
+                    </div>
+                </vuescroll>
             </div>
-          </div>
-        </vuescroll>
-      </div>
-      <div class="ns-col ns-col4" slot="trigger"></div>
+            <div class="ns-col ns-col3" slot="trigger">
+                <div class="ns-header">
+                    <span>选择册别</span>
+                </div>
+                <vuescroll>
+                    <div class="gl">
+                        <div class="gl-item" v-for="(item,index) in subjectList" :key="index" @click="handleVolumnTap(index)" :class="index == activeVolumnIndex ? 'item-active':''">
+                            <p class="gl-item-name">小学二年级语文上册</p>
+                            <p class="gl-item-info"><span></span>册别数:{{index}}</p>
+                        </div>
+                    </div>
+                </vuescroll>
+            </div>
+            <div class="ns-col ns-col4" slot="trigger">
+                <div>
+                    <vuescroll>
+                        <Tree :treeDatas="treeDatas"></Tree>
+                    </vuescroll>
+                </div>
+            </div>
+        </div>
     </div>
-  </div>
 </template>
 
 <script>
-  export default {
-    data() {
-      return {
-        originData: {},
-        periodList: [],
-        gradeList: [],
-        semesterList: [],
-        subjectList:[],
-        activePeriodIndex: 0,
-        activeGradeIndex: 0,
-        activeVolumnIndex: 0,
-        split1:1
-      }
-    },
-    created() {
-      console.log(this.getData());
-      this.originData = this.getData();
-      this.periodList = this.originData.period;
+    import Tree from '@/components/syllabus/newTree'
+    export default {
+        data() {
+            return {
+                originData: {},
+                periodList: [],
+                gradeList: [],
+                semesterList: [],
+                subjectList: [],
+                treeDatas: [{
+                    title: '小学二年级语文上册',
+                    expand: true,
+                    children: [
+                        {
+                            title: '第一章 基础知识',
+                            expand: true,
+                            children: [
+                                {
+                                    title: '第一节 拼音'
+                                },
+                                {
+                                    title: '第二节 汉字'
+                                },
+                                {
+                                    title: '第三节 词语'
+                                }
+                            ]
+                        },
+                        {
+                            title: '第二章 句法实践',
+                            expand: true,
+                            children: [
+                                {
+                                    title: '第一节 句子结构'
+                                },
+                                {
+                                    title: '第二节 基本句型'
+                                }
+                            ]
+                        },
+                        {
+                            title: '第三章 基础知识',
+                            expand: true,
+                            children: [
+                                {
+                                    title: '第一节 拼音'
+                                },
+                                {
+                                    title: '第二节 汉字'
+                                },
+                                {
+                                    title: '第三节 词语'
+                                }
+                            ]
+                        },
+                        {
+                            title: '第四章 基础知识',
+                            expand: true,
+                            children: [
+                                {
+                                    title: '第一节 拼音'
+                                },
+                                {
+                                    title: '第二节 汉字'
+                                },
+                                {
+                                    title: '第三节 词语'
+                                }
+                            ]
+                        },
+                        {
+                            title: '第五章 基础知识',
+                            expand: true,
+                            children: [
+                                {
+                                    title: '第一节 拼音'
+                                },
+                                {
+                                    title: '第二节 汉字'
+                                },
+                                {
+                                    title: '第三节 词语'
+                                }
+                            ]
+                        },
+                    ]
+                }],//课纲数据
+                activePeriodIndex: 0,
+                activeGradeIndex: 0,
+                activeVolumnIndex: 0,
+                split1: 1
+            }
+        },
+        components: {
+            Tree
+        },
+        created() {
+            console.log(this.getData());
+            this.originData = this.getData();
+            this.periodList = this.originData.period;
+
+            this.handlePeriodTap(0);
+        },
+        methods: {
+            getData() {
+                let res = require('./syllabus.json');
+                return res;
+            },
 
-      this.handlePeriodTap(0);
-    },
-    methods: {
-      getData() {
-        let res = require('./syllabus.json');
-        return res;
-      },
+            getTreeData() {
+                let res = require('./syllabus.json');
+                return res;
+            },
 
-      handlePeriodTap(index) {
-        this.activePeriodIndex = index;
-        this.subjectList = this.periodList[index].subject;
-        this.handleSubjectTap(0);
-      },
+            handlePeriodTap(index) {
+                this.activePeriodIndex = index;
+                this.subjectList = this.periodList[index].subject;
+                this.handleSubjectTap(0);
+            },
 
-      handleSubjectTap(index) {
-        this.activeGradeIndex = index;
-        //this.gradeList = this.periodList[index].grade;
-      },
+            handleSubjectTap(index) {
+                this.activeGradeIndex = index;
+                //this.gradeList = this.periodList[index].grade;
+            },
 
-      handleVolumnTap(index) {
-        this.activeVolumnIndex = index;
-        //this.gradeList = this.periodList[index].grade;
-      }
-    },
+            handleVolumnTap(index) {
+                this.activeVolumnIndex = index;
+                //this.gradeList = this.periodList[index].grade;
+            }
+        },
 
 
-  }
+    }
 </script>