| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 | <template>  <div class="overview">    <!-- 顶部tag -->    <div class="preview-tag">      <div class="page-tag-btn tagPage" :class="{ active: viewState === 0 }" @click="function () { viewState = 0 }">        <div class="page-tag-btn-tip">页面</div>      </div>      <div class="page-tag-btn tagElement" :class="{ active: viewState === 1 }" @click="function () { viewState = 1 }">        <div class="page-tag-btn-tip">元素</div>      </div>    </div>    <!-- 页面 -->    <div class="page-preview" style="z-index: 1;">      <ul class="list custom-scrollbar">        <li class="cover">          <img class="page_preview_tag" src="../../assets/images/page_preview_tag.png" alt="">          <div class="page_preview_tag_title">封面</div>          <div class="item-page">            <span>1</span>            <div class="page" :class="{ active: pages[0] === editingPage }"              :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"              @click="setEditingPage(pages[0],0)" @click.right="rightEvent()">              <Page :isOverView="true" class="content" :hideFoot="true"                :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"                :elements="pages[0].elements" type="see" />            </div>          </div>        </li>        <li class="cover">          <img class="page_preview_tag" src="../../assets/images/page_preview_tag.png" alt="">          <div class="page_preview_tag_title">题目</div>          <div class="item-page" v-for="(page,index) in pages" v-show="isShow(index)">            <span>{{index + 1 }}</span>            <div class="page" :class="{ active: page === editingPage }"              :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"              @click="setEditingPage(page,index)">              <Page :isOverView="true" class="content" :hideFoot="true"                :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"                :elements="page.elements" type="see" />            </div>            <el-dropdown placement="bottom" trigger="click" class="operation"              @command="command=>operationCommand(command, page, index)">              <div class="operation_img"></div>              <el-dropdown-menu slot="dropdown">                <el-dropdown-item command="del">删除</el-dropdown-item>              </el-dropdown-menu>            </el-dropdown>          </div>          <div class="item-page-add" @click="addPage">添加题目页</div>        </li>        <li class="cover">          <img class="page_preview_tag" src="../../assets/images/page_preview_tag.png" alt="">          <div class="page_preview_tag_title">结论</div>          <div class="item-page" v-for="(page,index) in pages" v-show="isShowResult(index)">            <span>{{index + 1}}</span>            <div class="page" :class="{ active: page === editingPage }"              :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"              @click="setEditingPage(page,index)">              <Page :isOverView="true" class="content" :hideFoot="true"                :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"                :elements="page.elements" type="see" />            </div>            <el-dropdown placement="bottom" trigger="click" class="operation"              @command="command=>operationCommand(command, page, index)">              <div class="operation_img"></div>              <el-dropdown-menu slot="dropdown">                <el-dropdown-item command="del">删除</el-dropdown-item>              </el-dropdown-menu>            </el-dropdown>          </div>          <div class="item-page-add" @click="addResultPage">添加结论页</div>        </li>      </ul>    </div>    <!-- 图层 -->    <div class="list custom-scrollbar" style="z-index: 2;" v-show="viewState === 1"      :class="{ dragging: dragState === 1 }">      <ul>        <li v-for="layer in layersNoBg">          <div class="layer" :class="{ active: editingLayer === layer}" @click="setEditingLayer($event, layer)"            @mousedown="moveLayer">            <span class="thumb" :style="{ backgroundImage: 'url(' + layer.imgSrc + ')' }"></span>{{ layer.type }}          </div>        </li>      </ul>      <div v-for="layer in layersBg" class="layer" :class="{ active: editingLayer === layer}"        @click="setEditingLayer($event, layer)">        <span class="thumb" :style="{ backgroundImage: 'url(' + layer.imgSrc + ')' }"></span>{{ layer.type }}      </div>    </div>    <!-- 题目 -->    <div class="topic-list" v-if="isShowQuestion">      <div class="topic-top" @click="showTopic = !showTopic">        <span>题目列表</span>        <img class="topic-top-arrow" :src="topicIcon" alt="">      </div>      <el-collapse-transition>        <div v-show="showTopic">          <div class="topic-group">            <el-checkbox v-model="item.isChecked" v-for="(item, index) in questionList" :label="item.name"              :key="item.name" @change="checked=>selectCheckbox(checked,item,index)" :disabled="isDisabled(index)">            </el-checkbox>          </div>        </div>      </el-collapse-transition>    </div>  </div></template>  <script>import Page from "./../../components/Page";import AppConst from "../../util/appConst";import editorApi from "../../api/editor";export default {  props: {    testcaseId: "",    resultCount: 0,    questions: []  },  data() {    return {      viewState: 0,      dragState: 0,      http: AppConst.BACKEND_DOMAIN,      canvasWidth: 750,      canvasHeight: 1334,      bodyBackgroundColor: "rgba(255,255,255,0)",      questionPages: [],      resultPageCount: this.resultCount,      resultPages: [],      showTopic: true,      topicIcon: "../../static/img/up-arrow.png",      questionList: [],      isShowQuestion: false,      currentPage: 0,      selectQuestions: this.questions    };  },  mounted() {    let data = {      testcaseId: this.testcaseId    };    console.log("testcaseId:", this.testcaseId);    editorApi.cncTestDetail(data).then(res => {      if (res.success) {        this.questionList = res.single.questionList;        for (var i = 0; i < this.questionList.length; i++) {          this.questionList[i].isChecked = this.isChecked(i);        }        console.log("success", this.questionList);      } else {        console.log("error");      }    });  },  computed: {    vxEditor() {      return this.$store.state["editor"];    },    pages() {      this.bodyBackgroundColor =        this.$store.state.editor.editorTheme.bodyBackgroundColor ||        "rgba(255,255,255,0)";      return this.vxEditor["editorTheme"]["pages"];    },    editingPage() {      return this.vxEditor["editorPage"];    },    layers() {      return this.editingPage["elements"];    },    layersNoBg() {      return (        this.layers && this.layers.filter(v => v["type"] !== "bg").reverse()      );    },    layersBg() {      return this.layers && this.layers.filter(v => v["type"] === "bg");    },    editingLayer() {      return this.vxEditor["editorElement"];    }  },  methods: {    operationCommand(command, page, index) {      if (command == "del") {        console.log("删除", index);        this.deletePage(page, index);      }    },    isChecked(index) {      var question = this.questionList[index].questionId;      var arrTemp = [];      this.selectQuestions.forEach(function(value, key, arr) {        arrTemp.push(...value);      });      console.log("isChecked", index, arrTemp.indexOf(question) != -1);      return arrTemp.indexOf(question) != -1;    },    isDisabled(index) {      var question = this.questionList[index].questionId;      var arrTemp = [];      this.selectQuestions.forEach(function(value, key, arr) {        arrTemp.push(...value);      });      let questions = this.selectQuestions[this.currentPage - 1] || [];      if (questions.indexOf(question) == -1) {        if (questions.length == 2) {          return true;        } else {          return arrTemp.indexOf(question) != -1;        }      } else {        return false;      }    },    selectCheckbox(checked, item, index) {      console.log("选中", checked, item, index);      let questions = this.selectQuestions[this.currentPage - 1] || [];      if (checked) {        questions.push(item.questionId);        console.log("AAAAAAAAA", questions);        this.addQuestion(item);      } else {        questions.splice(          questions.findIndex(itemTemp => itemTemp === item.questionId),          1        );        console.log("DDDDDDDDDD", questions);        this.deleteQuestion(item);      }      var selecteQuestionList = [];      for (var i = 0; i < questions.length; i++) {        var selectQID = questions[i];        for (var n = 0; n < this.questionList.length; n++) {          if (this.questionList[n].questionId == selectQID) {            selecteQuestionList.push(this.questionList[n]);          }        }      }      console.log("RRRRRRRRRR", selecteQuestionList);      this.$store.dispatch("addQuestion", selecteQuestionList);    },    addQuestion(item) {      let questions = this.selectQuestions[this.currentPage - 1] || [];      var top = 170;      if (questions.length > 1) {        var question = this.questionList.filter(          item => item.questionId == questions[0]        );        top = question[0].optionList.length * 90 + 300;      }      // 添加题目      let param = {};      param.top = top;      param.left = 100;      param.questionId = item.questionId;      param["type"] = "text";      param["text"] = item.name;      param["width"] = 300;      param["lineHeight"] = 1.5;      param["backgroundColor"] = "";      param["verticalAlign"] = "top";      param["display"] = "block";      param["textIndent"] = "0.0";      param["letterSpacing"] = "0.0";      param["allTransparent"] = "";      param["nodeId"] = "Id" + Math.random();      this.$store.dispatch("addElement", param);      // 添加选项      var itemTop = top + 50;      for (var i = 0; i < item.optionList.length; i++) {        console.log("选项", item.optionList[i].content);        let obj = {};        obj.questionId = item.questionId;        obj.optionId = item.optionList[i].optionId;        obj.type = "button";        obj.top = itemTop + i * 40 + (i + 1) * 50;        obj.left = 100;        obj["text"] = item.optionList[i].content;        obj["lineHeight"] = 1.5;        obj.width = 300;        obj.height = 40;        obj.backgroundUnselectedImg =          "https://dm.static.elab-plus.com/diaoyanbao/option_default.png";        obj.backgroundSelectedImg =          "https://dm.static.elab-plus.com/diaoyanbao/option_select.png";        obj.loop = false;        this.$store.dispatch("addElement", obj);      }    },    deleteQuestion(item) {      this.$store.dispatch("deleteElementQID", item.questionId);      // var elements = this.pages[this.currentPage].elements;      // for (var i = 0; i < elements.length; i++) {      //   if (elements[i].questionId == item.questionId) {      //     this.$store.dispatch("deleteElement", elements[i]);      //   }      // }    },    isShow: function(index) {      var result = false;      if (index > 0) {        console.log(this.pages.length, index, this.resultPageCount);        if (this.pages.length - index > this.resultPageCount) {          result = true;        }      }      return result;    },    isShowResult(index) {      var result = false;      console.log(this.pages.length, index, this.resultPageCount);      if (        this.pages.length - index <= this.resultPageCount &&        this.resultPageCount > 0      ) {        result = true;      }      return result;    },    moveLayer(downEvent) {      let height = 30;      let timer = null;      let layer = downEvent.target;      let li = layer.parentNode;      let parent = li.parentNode;      let liLen = parent.childNodes.length;      let startTop = li.offsetTop;      let startIndex = Math.round(startTop / height);      let targetIndex = null;      let placeholder = document.createElement("li");      placeholder.style = "height: " + height + "px; background-color: #d6d6d6";      let move = moveEvent => {        if (!timer) {          // 被拖动的层          let top = moveEvent.clientY - downEvent.clientY + startTop;          layer.setAttribute("data-moving", true);          layer.style.top = top + "px";          this.dragState = 1;          // 占位层          let nowIndex = Math.round(top / height);          nowIndex =            nowIndex <= 0 ? 0 : nowIndex > liLen - 1 ? liLen - 1 : nowIndex;          if (targetIndex !== nowIndex) {            (targetIndex || targetIndex === 0) &&              parent.removeChild(placeholder);            targetIndex = nowIndex;            parent.insertBefore(              placeholder,              parent.childNodes[nowIndex + (startIndex >= targetIndex ? 0 : 1)]            );          }          // timer负责减少onmousemove对客户端的负担          timer = setTimeout(() => {            timer = null;          }, 20);        }      };      let up = upEvent => {        if (layer.getAttribute("data-moving")) {          layer.removeAttribute("data-moving");          layer.style.top = "";          parent.removeChild(placeholder);          this.layersNoBg[startIndex]["zindex"] =            this.layersNoBg[targetIndex]["zindex"] +            (targetIndex > startIndex ? -0.5 : 0.5);          this.updateLayersSort();        }        document.removeEventListener("mousemove", move);        document.removeEventListener("mouseup", up);        this.dragState = 0;      };      if (liLen > 1) {        document.addEventListener("mousemove", move);        document.addEventListener("mouseup", up);      }    },    copyPage(page) {      this.bodyBackgroundColor =        this.$store.state.editor.editorTheme.bodyBackgroundColor ||        "rgba(255,255,255,0)";      this.$store.dispatch("copyPage", page);    },    deletePage(page, index) {      this.$msgbox({        title: "删除",        message: "删除后不可撤回,确定删除?",        showCancelButton: true,        confirmButtonText: "确定",        cancelButtonText: "取消",        beforeClose: (action, instance, done) => {          if (action === "confirm") {            var qusetionCount = this.pages.length - this.resultPageCount;            if (qusetionCount <= index) {              console.log("删除结论页", index, qusetionCount);              this.$store.dispatch("delPage", page);              this.resultPageCount -= 1;            } else {              console.log("删除题目", index, qusetionCount);              var pageSlelctQ = this.selectQuestions[index - 1] || [];              var deleteList = [];              for (var i = 0; i < pageSlelctQ.length; i++) {                var question = this.questionList.filter(                  item => item.questionId == pageSlelctQ[i]                );                if (question.length > 0) {                  var selectIndex = this.questionList.findIndex(                    itemTemp => itemTemp.questionId == question[0].questionId                  );                  this.questionList[selectIndex].isChecked = false;                  deleteList.push({ index: selectIndex, item: question[0] });                }              }              for (var i = 0; i < deleteList.length; i++) {                console.log("WWWWWWWWW", deleteList[i]);                this.selectCheckbox(                  false,                  deleteList[i].item,                  deleteList[i].index                );              }              this.questions.splice(index, 1);              this.$store.dispatch("delPage", page);              var editingPage = this.pages[index - 1];              this.setEditingPage(editingPage, index - 1);            }            this.$message.success("删除成功");            done();          } else {            done();          }        }      })        .then(() => {})        .catch(() => {});    },    addPage() {      this.bodyBackgroundColor =        this.$store.state.editor.editorTheme.bodyBackgroundColor ||        "rgba(255,255,255,0)";      var position = this.pages.length - this.resultPageCount;      this.$store.dispatch("addPagePosition", position);      this.isShowQuestion = true;      this.selectQuestions.push([]);      this.currentPage += 1;    },    addResultPage() {      this.bodyBackgroundColor =        this.$store.state.editor.editorTheme.bodyBackgroundColor ||        "rgba(255,255,255,0)";      this.$store.dispatch("addPage");      this.resultPageCount += 1;      this.isShowQuestion = false;    },    setEditingPage(page, index) {      this.currentPage = index;      if (index == 0 || this.isShowResult(index)) {        this.isShowQuestion = false;      } else {        this.isShowQuestion = true;      }      this.bodyBackgroundColor =        this.$store.state.editor.editorTheme.bodyBackgroundColor ||        "rgba(255,255,255,0)";      this.$store.dispatch("setEditorPage", page);    },    setEditingLayer(event, layer) {      this.$store.dispatch("setEditorElement", layer);    },    updateLayersSort() {      this.$store.dispatch("sortElementsByZindex");    }  },  components: { Page },  watch: {    showTopic: function(val) {      if (val) {        this.topicIcon = "../../static/img/up-arrow.png";      } else {        this.topicIcon = "../../static/img/down-arrow.png";      }    },    resultCount(val) {      this.resultPageCount = val;    },    questions(val) {      this.selectQuestions = val;    },    currentPage(val) {      console.log("当前页数:", val);      this.questionList = this.questionList;    }  }};</script>  <style lang="less" scoped>.overview {  position: relative;  background-color: rgb(196, 185, 185);  height: 100%;  .preview-tag {    width: 44px;    height: 100%;    background: #fff;    box-shadow: 5px 0px 10px 0px rgba(62, 67, 116, 0.1);    position: absolute;    top: 0px;    left: 226px;    z-index: 3;    padding-top: 10px;    .page-tag-btn {      margin-top: 10px;      margin-left: 5px;      width: 34px;      height: 34px;    }    .tagPage {      background: url(../../assets/images/page-tag.png) center no-repeat;      background-size: cover;      &.active {        background: url(../../assets/images/page-tag-sel.png) center no-repeat;        background-size: cover;      }    }    .tagPage:hover {      background: url(../../assets/images/page-tag-hover.png) center no-repeat;      background-size: cover;    }    .tagPage:hover div {      display: block;    }    .tagElement {      background: url(../../assets/images/element-tag.png) center no-repeat;      background-size: cover;      &.active {        background: url(../../assets/images/element-tag-sel.png) center          no-repeat;        background-size: cover;      }    }    .tagElement:hover {      background: url(../../assets/images/element-tag-hover.png) center        no-repeat;      background-size: cover;    }    .tagElement:hover div {      display: block;    }    .page-tag-btn-tip {      width: 80px;      height: 26px;      position: relative;      top: 5px;      left: -80px;      display: none;      text-align: center;      line-height: 26px;      font-size: 14px;      color: #fff;      background: url(../../assets/images/page_tag_btn_tip.png) center no-repeat;      background-size: cover;    }  }  .panel {    float: left;    line-height: 40px;    width: 50%;    text-align: center;    background-color: #d6d6d6;    cursor: pointer;    &.active {      background-color: transparent;    }  }  .list {    background-color: #fff;    position: absolute;    top: 0px;    bottom: 0px;    width: 100%;    overflow-y: auto;    overflow-x: hidden;    padding-top: 10px;    padding-bottom: 20px;    .cover {      margin-left: 16px;      width: 180px;      background: rgba(230, 237, 255, 1);      border-radius: 6px;      padding-top: 10px;      padding-bottom: 10px;      position: relative;      margin-top: 16px;      .page_preview_tag {        position: absolute;        top: 6px;        left: 0px;        width: 49px;        height: 22px;      }      .page_preview_tag_title {        position: absolute;        top: 6px;        left: 0px;        line-height: 22px;        margin-left: 10px;        font-size: 12px;        color: rgba(255, 255, 255, 1);      }      .item-page {        position: relative;        display: flex;        flex-direction: row;        justify-content: center;        margin-top: 20px;        margin-bottom: 20px;        font-size: 14px;        font-weight: 500;        color: rgba(100, 107, 129, 1);        .preview-page {          margin-left: 10px;          width: 70px;          height: 114px;          box-shadow: 0px 2px 4px 0px rgba(78, 93, 255, 1);          border: 2px solid rgba(255, 255, 255, 1);          background: #fff;        }        .operation {          position: absolute;          top: 30px;          left: 40px;          .operation_img {            width: 16px;            height: 16px;            background: url(../../assets/images/page_operation.png) center              no-repeat;            background-size: cover;          }          .operation_img:hover {            background: url(../../assets/images/page_operation_sel.png) center              no-repeat;            background-size: cover;          }        }      }      .item-page-add {        width: 70px;        height: 114px;        margin-left: 64px;        margin-bottom: 30px;        font-size: 12px;        color: rgba(100, 107, 129, 1);        line-height: 154px;        text-align: center;        background: url(../../assets/images/item-page-add.png) center no-repeat;        background-size: cover;      }      .item-page-add:hover {        color: rgba(51, 51, 51, 1);        background: url(../../assets/images/item-page-add-hover.png) center          no-repeat;        background-size: cover;      }    }  }  .dragging:before {    content: "";    position: absolute;    top: 0;    right: 0;    bottom: 0;    left: 0;    z-index: 10;  }  .page {    position: relative;    margin-left: 10px;    border: 2px solid rgba(255, 255, 255, 1);    background: #fff;    &.active {      border-color: rgba(78, 93, 255, 1);      box-shadow: 0px 2px 4px 0px rgba(78, 93, 255, 1);      .icons {        display: block;      }    }    &:before {      content: "";      position: absolute;      top: 0;      left: 0;      bottom: 0;      right: 0;      z-index: 2;    }    .content {      transform-origin: left top;      background-color: #fff;      overflow: hidden;      position: relative;    }    .icons {      position: absolute;      bottom: -1.5em;      right: 0.5em;      display: none;      width: 100%;      color: #fff;      .icon {        float: right;        margin-left: 1em;        opacity: 0.5;        cursor: pointer;        &:hover {          opacity: 1;        }      }    }  }  .layer {    padding-left: 20px;    height: 34px;    line-height: 34px;    cursor: pointer;    color: rgba(51, 51, 51, 1);    &[data-moving] {      background-color: #d6d6d6;      position: absolute;      width: 100%;    }    &:hover {      background: rgba(230, 237, 255, 1);    }    &.active {      background: rgba(78, 93, 255, 1);      color: #fff;    }    .thumb {      display: inline-block;      width: 15px;      height: 15px;      margin-right: 1em;      background: white center no-repeat;      background-size: cover;    }  }  .add {    border: none;    position: absolute;    bottom: 0;    height: 50px;    line-height: 50px;    width: 100%;    left: 0;    background-color: #373f42;    text-align: center;    color: #fff;    cursor: pointer;  }  .topic-list {    position: absolute;    top: 10px;    left: 280px;    width: 345px;    background: rgba(255, 255, 255, 1);    border-radius: 6px;    z-index: 4;    .topic-top {      width: 100%;      height: 34px;      background: rgba(78, 93, 255, 1);      color: #fff;      border-radius: 6px 6px 0px 0px;      line-height: 34px;      display: flex;      flex-direction: row;      justify-content: space-between;      align-items: center;      padding-left: 10px;      padding-right: 10px;      .topic-top-arrow {        width: 13px;        height: 12px;      }    }    .topic-group {      display: flex;      flex-direction: column;      margin-left: 24px;      .el-checkbox {        padding-top: 10px;        padding-bottom: 10px;        border-bottom: 1px solid #e2e4ee;        display: flex;        position: relative;        white-space: pre-line;        align-items: center;        font-size: 14px;        font-weight: 400;        color: rgba(51, 51, 51, 1);        line-height: 19px;      }    }  }}</style>  
 |