<template>
  <div>
    <el-form :disabled="isDetail">
      <el-card shadow="hover" class="m-b-20">
        <div class="flex-between">
          <el-page-header @back="goBack" :content="isDetail ? '查看' : (form.id ? '更新' : '创建') + '考核'"></el-page-header>
          <div>
            <el-button type="primary" @click="save(0)" v-show="!isDetail">{{ form.id ? "更新" : "创建" }}</el-button>
          </div>
        </div>
      </el-card>

      <el-card shadow="hover" class="mgr20 m-b-20">
        <div>
          <p class="m-b-20">考核名称</p>
          <el-input placeholder="请输入考核名称" v-model.trim="form.experimentalName" clearable maxlength="15"
            class="inline-input"></el-input>
        </div>
      </el-card>

      <el-card shadow="hover" class="m-b-20">
        <div>
          <p class="m-b-20">发布方式</p>
          <el-radio-group v-model="form.type">
            <el-radio :label="1">手动发布</el-radio>
            <el-radio :label="2">定时发布</el-radio>
          </el-radio-group>
        </div>
      </el-card>
      <!-- 根据发布方式判断时间的显示 -->
      <el-card shadow="hover" class="m-b-20">
        <div>
          <p class="m-b-20">考核时间</p>
          <!-- 手动发布显示 -->
          <div class="date-inputs" v-if="form.type == 1">
            考核时长：
            <el-input type="number" min="0" v-model.trim="duration.day" placeholder></el-input>
            天
            <el-input type="number" min="0" v-model.trim="duration.hour" placeholder></el-input>
            小时
            <el-input type="number" min="0" v-model.trim="duration.minute" placeholder></el-input>
            分
          </div>
          <!-- 定时发布显示 -->
          <div v-if="form.type == 2" class="addAssess">
            <span class="mgr10">开始时间:</span>
            <el-date-picker size="small" v-model="date" type="datetimerange" range-separator="-"
              start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions"></el-date-picker>
          </div>
        </div>
      </el-card>
      <el-card shadow="hover" class="mgr20 m-b-20">
        <div>
          <p class="m-b-20">课程</p>
          <div class="inline-input">
            <el-select v-model="form.mallId" @change="initData">
              <el-option v-for="item in curriculumList" :key="item.mallId" :label="item.curriculumName"
                :value="item.mallId">
              </el-option>
            </el-select>
            <!-- <el-select v-model="form.curriculumId" @change="initData">
                            <el-option
                                v-for="item in systemList"
                                :key="item.id"
                                :label="item.label"
                                :value="item.id">
                            </el-option>
                        </el-select> -->
          </div>
        </div>
      </el-card>
      <!-- 实训项目模块 -->
      <el-card shadow="hover" class="m-b-20">
        <div class="flex-between m-b-20">
          <span>考核项目</span>
          <div style="display: inline-flex;">
            <div>
              <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
            </div>
            <el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button>
          </div>
        </div>
        <!-- 实训项目表格 -->
        <el-table :data="projectData" class="table" stripe header-align="center">
          <!-- 单选实训项目ID -->
          <el-table-column width="60" label="选择" align="center">
            <template slot-scope="scope">
              <el-radio v-model="form.uuid" :label="scope.row.uuid">&nbsp;</el-radio>
            </template>
          </el-table-column>
          <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
          <el-table-column prop="auth" label="项目权限" align="center">
            <template slot-scope="scope">
              {{ permissionsKeys[scope.row.permissions] }}
            </template>
          </el-table-column>
          <!-- <el-table-column prop="createUser" label="创建人" align="center"></el-table-column> -->
          <el-table-column prop="founder" label="创建人" align="center">
            <template slot-scope="scope">
              {{ scope.row.createUser }}
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
          <el-table-column label="操作" align="center">
            <template slot-scope="scope">
              <el-button type="text" @click="showProject(scope.row)">查看</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagination">
          <el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
            layout="total,prev, pager, next" :total="total"></el-pagination>
        </div>
      </el-card>
      <el-card shadow="hover" class="mgr20 m-b-20">
        <div>
          <p class="m-b-20">考核发布</p>
          <el-radio-group v-model="form.isSpecify">
            <el-radio :label="1">指定范围</el-radio>
            <el-radio :label="0">无指定范围</el-radio>
          </el-radio-group>
        </div>
        <div v-show="form.isSpecify == 1" style="padding-top: 24px;">
          <p class="m-b-20">班级名称</p>
          <el-input placeholder="请输入班级名称" v-model.trim="filterClassName" class="inline-input m-b-20" clearable>
            <el-button slot="append" icon="el-icon-search"></el-button>
          </el-input>
          <div v-show="tagList.length" class="m-b-20">
            <el-tag v-for="(tag, index) in tagList" :key="index" closable @close="handleCloseTag(tag)"
              style="margin-right: 10px">
              {{ tag.organizationName }}
            </el-tag>
          </div>
          <div class="tree-con">
            <student-tree ref="tree" node-key="id" show-checkbox highlight-current default-expand-all lazy
              :load="loadTree" :default-checked-keys="defaultCheckedKeys"
              :props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }"
              :filter-node-method="filterNode" @check="handleCheck">
            </student-tree>
          </div>
        </div>
      </el-card>
      <!-- 邀请码 -->
      <el-card v-if="form.isSpecify == 0" shadow="hover" class="m-b-20">
        <div style="margin-bottom: 10px">
          <p class="m-b-20">设置邀请码</p>
          <el-radio-group v-model="form.isEnableCode">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </div>
        <div v-if="form.isEnableCode == 1">
          <el-input style="display: inline-block;width: auto;margin-right: 10px" type="number"
            v-model.trim="form.invitationCode" maxlength="6" placeholder="请设置6个数字"></el-input>
          <el-button type="text" @click="createInv">随机</el-button>
        </div>
      </el-card>
    </el-form>
  </div>
</template>
<script>
import util from "@/libs/util";
import { mapState, mapActions } from "vuex";
import StudentTree from "@/components/student-tree/src/tree";
import qs from 'qs'
export default {
  components: { StudentTree },
  data () {
    return {
      founderKeys: {
        0: "系统",
        1: "老师"
      },
      cidList: [],
      permissionsKeys: {
        0: "练习",
        1: "考核",
        2: "竞赛"
      },
      isDetail: Boolean(this.$route.query.show),
      form: {
        id: this.$route.query.id ? this.$route.query.id : "",
        experimentalName: "",
        type: 1, // 发布类型(1、手动发布 2、定时发布)
        experimentDuration: "0d0h0m",
        curriculumId: "",
        mallId: '',
        projectId: '',
        paperId: '',
        isSpecify: 1, // 考核发布(1、指定范围 0、无指定范围)
        isEnableCode: 0, //是否设置邀请码
        invitationCode: "",
        status: 0, // 状态(0、待开始 1、进行中 2、已结束)
        classId: "",
        stuInfo: []
      },
      date: "", // 实验时间
      duration: {
        day: "",
        hour: "",
        minute: ""
      }, // 实验时长
      startTime: "0000-00-00 00:00:00", //开始时间
      stopTime: "0000-00-00 00:00:00", //结束时间
      expNameRepeat: false, // 考核名称是否重复
      curriculumList: [], // 课程列表
      filterClassName: "", // 班级名称搜索
      tagList: [], // 班级名称标签
      defaultCheckedKeys: [], // 默认选中
      allCheckedNodes: [], // 当前选中和半选节点
      keyword: "", // 项目名称搜索
      searchTimer: null,
      surplusTime: "",
      projectDataAll: [],
      projectData: [],
      pickerOptions: {
        disabledDate: time => {
          return time.getTime() < new Date().getTime() - 86400000;
        }
      },
      page: 1,
      pageSize: 5,
      total: 0,
      isToProject: false,
      systemList: [],
      submiting: false, // 新增编辑防抖标识
      updateTime: 0
    };
  },
  computed: {
    ...mapState("project", [
      "assFields"
    ])
  },
  // 离开的时候判断是否有保存更改的信息,没有则拦截并提示
  beforeRouteLeave (to, from, next) {
    if (!this.isToProject && this.updateTime) {
      this.$confirm(`您所更改的内容未更新，是否更新？`, '提示', {
        type: 'warning',
        closeOnClickModal: false
      }).then(() => {
        this.save(next)
      }).catch(() => {
        next()
      })
    } else {
      next()
    }
  },
  beforeDestroy () {
    if (!this.isToProject) this.setAss({});
  },
  mounted () {
    this.date = [util.formatDate("yyyy-MM-dd hh:mm:ss", new Date(new Date().getTime() + 300000)), util.formatDate("yyyy-MM-dd hh:mm:ss", new Date(new Date().getTime() + 300000))];
    this.form.id && this.getData();
    this.recoveryData();
    this.getschoolCourse();
  },
  watch: {
    // 监听信息是否有更改,有的话页面离开的时候要询问是否要保存
    form: {
      handler (val) {
        this.updateTime++
      },
      deep: true
    },
    date: function (val) {
      if (val[0] != "0000-00-00 00:00:00") {
        this.startTime = util.formatDate("yyyy-MM-dd hh:mm:ss", new Date(val[0]));
        this.stopTime = util.formatDate("yyyy-MM-dd hh:mm:ss", new Date(val[1]));
        this.updateTime++
      }
    },
    duration: {
      handler (n, o) {
        this.form.experimentDuration = `${n.day ? n.day : 0}d${n.hour ? n.hour : 0}h${n.minute ? n.minute : 0}m`;
        this.updateTime++
      },
      deep: true
    },
    keyword: function (val) {
      clearTimeout(this.searchTimer);
      this.searchTimer = setTimeout(() => {
        this.initData();
      }, 500);
    },
    filterClassName (val) {
      this.$refs.tree.filter(val);
    }
  },
  methods: {
    ...mapActions("project", [
      "setAss"
    ]),
    handleCloseTag (tag) { // 关闭班级标签
      this.allCheckedNodes = this.$refs.tree.getCheckedNodes().concat(this.$refs.tree.getHalfCheckedNodes());
      let tagIndex = this.tagList.findIndex(i => i.id === tag.id);
      this.tagList.splice(tagIndex, 1);
      // 设置选中
      let setKeys = [];
      this.allCheckedNodes.forEach(i => {
        if (i.level === 4 && i.parentId !== tag.id) setKeys.push(i.nodeKey);
      });
      this.$refs.tree.setCheckedKeys(setKeys);
      this.allCheckedNodes = this.allCheckedNodes.filter(i => (i.level === 3 && i.id !== tag.id) || (i.level === 4 && i.parentId !== tag.id));
    },
    handleCheck (data, checked) { // 当复选框被点击的时候触发
      // 全选和半选状态下的班级都显示在标签
      let checkedClass = checked.checkedNodes.filter(i => i.level === 3);
      let halfCheckedClass = checked.halfCheckedNodes.filter(i => i.level === 3);
      this.tagList = [...checkedClass, ...halfCheckedClass].map(i => {
        return { id: i.id, organizationName: i.organizationName };
      });
      // 缓存全选和半选状态下的所有节点
      this.allCheckedNodes = [...checked.checkedNodes, ...checked.halfCheckedNodes];
    },
    filterNode (value, data) { // 对树节点进行过滤
      if (!value) return true;
      return data.organizationName.indexOf(value) !== -1;
    },
    loadTree (node, resolve) { // 懒加载所在班级树结构
      let level = 1;
      let parentId = "";
      if (node.level === 0) {
        this.treeNode = node;
        this.treeResolve = resolve;
        this.getTreeData(resolve, level, parentId);
      } else if (node.level > 3) {
        return resolve([]);
      } else {
        if (node.data && node.data.level && node.data.id) {
          this.getTreeData(resolve, node.data.level + 1, node.data.id);
        }
      }
    },
    async getTreeData (resolve, level, parentId) { // 获取组织架构树数据
      let { status, treeList } = await this.$post(`${this.api.stuOrganizationTree}?level=${level}&parentId=${parentId}`);
      if (status === 200 && treeList.length) {
        let result = [];
        treeList.forEach(i => {
          if (i.level === 4) {
            i.nodeKey = `${i.parentId}-${i.id}`;
            i.leaf = true;
          } else {
            i.nodeKey = `${i.id}-${new Date().getTime()}`;
            i.leaf = false;
          }
          result.push(i);
        });
        this.$nextTick(() => {
          // 编辑时，设置默认勾选
          if (this.form.classInfo && this.form.classInfo.length) {
            let keys = this.form.classInfo.map(i => {
              return i.id;
            });
            this.defaultCheckedKeys = keys;
          }
          // 获取树结构选中和半选中状态下的数据
          let nodes = this.$refs.tree.getCheckedNodes().concat(this.$refs.tree.getHalfCheckedNodes());
          this.allCheckedNodes = nodes;
          this.tagList = nodes.filter(i => i.level === 3);
        });
        return resolve(result);
      } else {
        return resolve([]);
      }
    },
    getschoolCourse () { // 获取课程
      this.$get(this.api.getSchoolEffectiveCourse).then(({ data }) => {
        this.curriculumList = data;
        if (this.curriculumList.length) {
          if (!this.form.mallId) this.form.mallId = data[0].mallId
          this.getProjectData()
        }
        this.$nextTick(() => {
          this.updateTime = 0
        })
      }).catch(err => { });
    },
    getProjectData () {
      const curItem = this.curriculumList.find(e => e.mallId === this.form.mallId)
      let data = {
        pageNum: this.page,
        pageSize: this.pageSize,
        cid: curItem.cid,
        projectName: this.keyword,
        systemId: curItem ? curItem.systemId : 1,
        permissions: 1,
        mallId: this.form.mallId
      }
      this.$post(this.api.getProjectOrExamPaperByAssessment, data).then(({ data }) => {
        const list = data.records
        list.forEach(e => {
          e.uuid = e.projectId || e.paperId // 唯一标识
        })
        this.projectData = list
        this.total = data.total
      }).catch(err => { })
    },
    handlePage () {
      let result = this.projectDataAll.slice((this.page - 1) * this.pageSize, this.page * this.pageSize);
      this.projectData = result;
    },
    initData () {
      this.page = 1;
      this.getProjectData();
    },
    save (cb) { // 提交
      if (this.submiting) return false
      const { form } = this
      if (!this.form.experimentalName) return util.warningMsg("请填写考核名称");
      if (this.expNameRepeat) return util.warningMsg("考核名称重复，请重新输入");
      if (this.form.type !== 1) {
        if (new Date().getTime() > new Date(this.startTime).getTime()) return util.warningMsg("开始时间不能早于当前时间");
        let timestamp = new Date(new Date(this.stopTime).getTime() - new Date(this.startTime).getTime());
        let minute = 1000 * 60;
        let hour = minute * 60;
        let day = hour * 24;
        this.form.experimentDuration = `${Math.floor(timestamp / day)}d${Math.floor(timestamp % day / hour)}h${Math.floor(timestamp % day % hour / minute)}m`;
      }
      if (this.form.type == 1 && this.form.experimentDuration == "0d0h0m") return util.warningMsg("请填写考核时长");
      if (this.form.type == 2 && this.startTime == "0000-00-00 00:00:00") return util.warningMsg("请填写考核时间");
      if (this.form.type == 1) {
        const { day, hour, minute } = this.duration
        if (String(day).includes('.')) return util.warningMsg('考核天数请填写整数')
        if (day < 0) return util.warningMsg('考核天数请勿填写负数')
        if (String(hour).includes('.')) return util.warningMsg('考核小时请填写整数')
        if (hour < 0) return util.warningMsg('考核小时请勿填写负数')
        if (String(minute).includes('.')) return util.warningMsg('考核分钟请填写整数')
        if (minute < 0) return util.warningMsg('考核分钟请勿填写负数')
      }
      if (!form.uuid) return util.warningMsg("请选择考核项目");
      const item = this.projectData.find(e => form.uuid === e.projectId || form.uuid === e.paperId)
      if (item) form[item.projectId ? 'projectId' : 'paperId'] = form.uuid
      if (this.form.isSpecify == 0 && this.form.isEnableCode == 1) {
        if (!this.form.invitationCode) return util.warningMsg("请设置邀请码");
        if (!this.form.invitationCode || String(this.form.invitationCode).length < 6 || isNaN(this.form.invitationCode)) return util.warningMsg("请输入6位纯数字邀请码");
      }
      this.form.startTime = this.form.type == 2 ? this.startTime : ''
      this.form.stopTime = this.form.type == 2 ? this.stopTime : ''
      let classId = [];
      let stuInfo = [];
      this.allCheckedNodes.forEach(i => {
        if (i.level === 3) {
          classId.push(i.id);
        } else if (i.level === 4) {
          stuInfo.push({ classId: i.parentId, stuAccountId: i.id });
        }
      });
      if (this.isSpecify == 1 && !stuInfo.length) {
        util.warningMsg("请选择学生");
        return;
      } else {
        this.form.classId = classId.toString();
        this.form.stuInfo = stuInfo;
      }

      const curItem = this.curriculumList.find(e => e.mallId === this.form.mallId)
      this.form.curriculumId = curItem.cid
      this.submiting = true
      if (this.form.id) {
        this.$post(this.api.modifyAssessment, this.form).then(async res => {
          this.updateTime = 0
          util.successMsg("修改成功");
          cb ? cb() : this.backPage()
        }).catch(err => {
          this.submiting = false
        });
      } else {
        this.$post(this.api.saveAssessment, this.form).then(res => {
          this.updateTime = 0
          util.successMsg("创建成功");
          cb ? cb() : this.$router.push('list')
        }).catch(err => {
          this.submiting = false
        });
      }
    },
    getData () { // 获取详情
      this.$get(`${this.api.getDetailById}?id=${this.form.id}`).then(({ data }) => {
        this.form = data;
        this.startTime = data.startTime
        this.stopTime = data.stopTime
        this.formatDuration();
        this.getschoolCourse();
      }).catch(err => {
      });
    },
    formatDuration () { // 格式化实验时长
      let duration = this.form.experimentDuration.replace(/\D+/g, ",").split(",");
      this.duration = {
        day: duration[0],
        hour: duration[1],
        minute: duration[2]
      };
      this.date = [this.startTime, this.stopTime];
      this.$nextTick(() => {
        this.updateTime = 0
      })
    },
    recoveryData () { // 恢复数据
      if (JSON.stringify(this.assFields) != "{}") {
        let info = this.assFields;
        this.form = info.form;
        this.duration = info.duration; // 实验时长
        this.startTime = info.startTime; //开始时间
        this.stopTime = info.startTime; //结束时间
        this.expNameRepeat = info.expNameRepeat; // 考核名称是否重复
        this.allCheckedNodes = info.allCheckedNodes; // 选中的树节点
        this.formatDuration();
      }
    },
    handleCacheData () { // 缓存数据,用于从项目管理页面返回时,数据回显
      this.allCheckedNodes.forEach(i => {
        if (i.level === 4) {
          this.form.stuInfo.push({ classId: i.parentId, stuAccountId: i.id });
        }
      });
      let data = {
        form: this.form,
        date: this.date, // 实验时间
        duration: this.duration, // 实验时长
        startTime: this.startTime, //开始时间
        stopTime: this.startTime, //结束时间
        expNameRepeat: this.expNameRepeat, // 考核名称是否重复
        allCheckedNodes: this.allCheckedNodes // 选中的树节点
      };
      this.setAss(data)
      this.isToProject = true
    },
    toProject () {
      this.handleCacheData()
      this.$router.push("/project/list?show=1")
    },
    showProject (row) {
      this.handleCacheData()
      this.$router.push(`/project/add?projectId=${row.projectId}&show=1&ass=1`)
    },
    createInv () {
      let result = "";
      for (let i = 0; i < 6; i++) {
        result += Math.floor(Math.random() * 10);
      }
      this.form.invitationCode = result;
    },
    handleCurrentChange (val) {
      this.page = val;
      this.getProjectData();
    },
    // 返回上一页
    backPage () {
      this.$router.push(this.$store.state.achievement.referrer)
    },
    goBack () {
      // 更改了信息才需要提示
      if (this.updateTime) {
        this.$confirm(`编辑的内容未保存，是否保存？`, '提示', {
          type: 'warning',
          closeOnClickModal: false
        }).then(() => {
          this.save()
        }).catch(() => {
          this.updateTime = 0
          this.backPage()
        })
      } else {
        this.updateTime = 0
        this.backPage()
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.inline-input {
  width: 500px;
}

.date-inputs {
  .el-input {
    width: 100px;
  }
}

.tree-con {
  height: 400px;
  max-height: 400px;
  width: 100%;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px 10px 10px 40px;
  overflow: auto;

  /deep/ .el-tree-node__content {
    height: 30px;

    .el-tree-node__expand-icon {
      padding: 2px;
      color: #fff;
      background-color: $main-color;
      border-radius: 30px;
      margin: 0 10px;
    }

    .el-tree-node__expand-icon.is-leaf {
      background-color: transparent;
    }

    .el-icon-caret-right:before {
      font-size: 14px;
    }

    .el-checkbox__inner {
      width: 18px;
      height: 18px;
      border: 1px solid $main-color$main-color;
      border-radius: 20px;
    }

    .el-checkbox__inner::after {
      position: absolute;
      top: 3px;
      left: 6px;
    }

    .el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
      position: absolute;
      top: 7px;
    }
  }
}
</style>