|
@@ -1,9 +1,7 @@
|
|
|
-import { getNewPage } from "../elementModel";
|
|
|
import {
|
|
|
- deepCopy,
|
|
|
+ // deepCopy,
|
|
|
calcSum,
|
|
|
getElementId,
|
|
|
- numberIsOdd,
|
|
|
objAssign,
|
|
|
} from "../../card/plugins/utils";
|
|
|
|
|
@@ -66,32 +64,15 @@ const fetchElementPositionInfos = (element, topics) => {
|
|
|
return topics.findIndex((item) => item.id === element.id);
|
|
|
};
|
|
|
|
|
|
-const fetchAllRelateParentElementPositionInfos = (parentElement, topics) => {
|
|
|
- let postionInfos = [];
|
|
|
- topics.forEach((item, eindex) => {
|
|
|
- if (item["parent"] && item.parent.id === parentElement.id) {
|
|
|
- let pos = { _elementNo: eindex };
|
|
|
- postionInfos.push(pos);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- return postionInfos;
|
|
|
-};
|
|
|
-
|
|
|
const fetchSameSerialNumberChildrenPositionInfo = (
|
|
|
elementChildernElement,
|
|
|
topics
|
|
|
) => {
|
|
|
let postionInfos = [];
|
|
|
const elementId = elementChildernElement.parent.id;
|
|
|
- const serialNumber = elementChildernElement.serialNumber;
|
|
|
|
|
|
topics.forEach((item, eindex) => {
|
|
|
- if (
|
|
|
- item.parent &&
|
|
|
- item.parent.id === elementId &&
|
|
|
- item.serialNumber === serialNumber
|
|
|
- ) {
|
|
|
+ if (item.parent && item.parent.id === elementId) {
|
|
|
postionInfos.push({
|
|
|
_elementNo: eindex,
|
|
|
_elementId: item.id,
|
|
@@ -101,18 +82,6 @@ const fetchSameSerialNumberChildrenPositionInfo = (
|
|
|
return postionInfos;
|
|
|
};
|
|
|
|
|
|
-const groupByParams = (datas, paramKey) => {
|
|
|
- let elementGroupInfos = [];
|
|
|
- for (let i = 0, len = datas.length; i < len; i++) {
|
|
|
- if (i === 0 || datas[i][paramKey] !== datas[i - 1][paramKey]) {
|
|
|
- elementGroupInfos.push([datas[i]]);
|
|
|
- } else {
|
|
|
- elementGroupInfos[elementGroupInfos.length - 1].push(datas[i]);
|
|
|
- }
|
|
|
- }
|
|
|
- return elementGroupInfos;
|
|
|
-};
|
|
|
-
|
|
|
const findElementById = (id, topics) => {
|
|
|
let curElement = null;
|
|
|
topics.forEach((element) => {
|
|
@@ -134,35 +103,15 @@ const findElementById = (id, topics) => {
|
|
|
const checkElementisCovered = (id, type) => {
|
|
|
const elementDom = document.getElementById(id);
|
|
|
|
|
|
- if (type === "EXPLAIN") {
|
|
|
- const elemTitleDome = elementDom.querySelector(".elem-title");
|
|
|
- const limitHeight = elemTitleDome
|
|
|
- ? elementDom.offsetHeight - elemTitleDome.offsetHeight
|
|
|
- : elementDom.offsetHeight;
|
|
|
+ if (type === "PANE_BOX") {
|
|
|
+ const limitHeight = elementDom.offsetHeight;
|
|
|
|
|
|
let elementHeights = [];
|
|
|
elementDom
|
|
|
- .querySelector(".elem-explain-elements")
|
|
|
+ .querySelector(".elem-pane-box-elements")
|
|
|
.childNodes.forEach((node) => {
|
|
|
- if (!node.className.includes("elem-explain-element")) return;
|
|
|
- elementHeights.push(
|
|
|
- node.firstChild.offsetHeight + node.firstChild.offsetTop
|
|
|
- );
|
|
|
- });
|
|
|
- return elementHeights.some((item) => item > limitHeight);
|
|
|
- }
|
|
|
-
|
|
|
- if (type === "COMPOSITION") {
|
|
|
- const elemTitleDome = elementDom.querySelector(".elem-title");
|
|
|
- const limitHeight = elemTitleDome
|
|
|
- ? elementDom.offsetHeight - elemTitleDome.offsetHeight
|
|
|
- : elementDom.offsetHeight;
|
|
|
+ if (!node.className.includes("elem-pane-box-element")) return;
|
|
|
|
|
|
- let elementHeights = [];
|
|
|
- elementDom
|
|
|
- .querySelector(".elem-composition-elements")
|
|
|
- .childNodes.forEach((node) => {
|
|
|
- if (!node.className.includes("elem-composition-element")) return;
|
|
|
elementHeights.push(
|
|
|
node.firstChild.offsetHeight + node.firstChild.offsetTop
|
|
|
);
|
|
@@ -179,11 +128,6 @@ const actions = {
|
|
|
state.pages.forEach((page) => {
|
|
|
page.columns.forEach((column) => {
|
|
|
column.elements.forEach((element) => {
|
|
|
- if (
|
|
|
- element.type === "TOPIC_HEAD" ||
|
|
|
- (element.type === "CARD_HEAD" && element.isSimple)
|
|
|
- )
|
|
|
- return;
|
|
|
topics.push(element);
|
|
|
});
|
|
|
});
|
|
@@ -202,44 +146,9 @@ const actions = {
|
|
|
|
|
|
commit("setCurElement", curElement);
|
|
|
},
|
|
|
- resetTopicSeries({ state, commit }) {
|
|
|
- let curTopicId = "",
|
|
|
- curTopicNo = 0,
|
|
|
- topicSeries = [];
|
|
|
- state.topics.forEach((topic) => {
|
|
|
- if (!topic.parent) return;
|
|
|
- if (curTopicId !== topic.parent.id) {
|
|
|
- curTopicId = topic.parent.id;
|
|
|
- curTopicNo++;
|
|
|
- topicSeries.push({
|
|
|
- id: curTopicId,
|
|
|
- topicNo: curTopicNo,
|
|
|
- type: topic.type,
|
|
|
- sign: topic.sign,
|
|
|
- });
|
|
|
- }
|
|
|
- topic.topicNo = curTopicNo;
|
|
|
- });
|
|
|
- commit("setTopicSeries", topicSeries);
|
|
|
- },
|
|
|
// 新增试题 --------------->
|
|
|
addElement({ state, commit }, element) {
|
|
|
- let pos = null;
|
|
|
-
|
|
|
- if (state.insetTarget.id) {
|
|
|
- //
|
|
|
- } else {
|
|
|
- //
|
|
|
- }
|
|
|
-
|
|
|
- let preElements = [];
|
|
|
- preElements.forEach((preElement, index) => {
|
|
|
- if (pos && pos !== -1) {
|
|
|
- state.topics.splice(pos + index, 0, preElement);
|
|
|
- } else {
|
|
|
- state.topics.push(preElement);
|
|
|
- }
|
|
|
- });
|
|
|
+ state.topics.push(element);
|
|
|
commit("setCurElement", element);
|
|
|
},
|
|
|
addSideElement({ state, commit }, element) {
|
|
@@ -248,34 +157,10 @@ const actions = {
|
|
|
commit("setCurElement", element);
|
|
|
},
|
|
|
// 修改试题 --------------->
|
|
|
- modifyTopic({ state }, element) {
|
|
|
- // 单独编辑某个细分题
|
|
|
+ modifyElement({ state }, element) {
|
|
|
const pos = fetchElementPositionInfos(element, state.topics);
|
|
|
state.topics.splice(pos, 1, element);
|
|
|
},
|
|
|
- modifyExplain({ state }, element) {
|
|
|
- // 解答题既是拆分题,又是可复制题
|
|
|
- const positionInfos = fetchAllRelateParentElementPositionInfos(
|
|
|
- element,
|
|
|
- state.topics
|
|
|
- );
|
|
|
- const elementGroupPosInfos = groupByParams(positionInfos, "serialNumber");
|
|
|
- for (let i = 0; i < elementGroupPosInfos.length; i++) {
|
|
|
- elementGroupPosInfos[i].forEach((pos) => {
|
|
|
- let child = state.topics[pos._elementNo];
|
|
|
- child.parent = { ...element };
|
|
|
- child.topicName = element.topicName;
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- modifyElement({ dispatch }, element) {
|
|
|
- if (element.type === "EXPLAIN") {
|
|
|
- dispatch("modifyExplain", element);
|
|
|
- } else {
|
|
|
- dispatch("modifySplitTopic", element);
|
|
|
- }
|
|
|
- // commit("setCurElement", element);
|
|
|
- },
|
|
|
// 修改试题包含元素
|
|
|
modifyElementChild({ state, commit }, element) {
|
|
|
// 修改解答题小题
|
|
@@ -294,7 +179,7 @@ const actions = {
|
|
|
commit("setCurElement", element);
|
|
|
},
|
|
|
// 粘贴试题内的元素
|
|
|
- pasteExplainElementChild({ state }, { curElement, pasteElement }) {
|
|
|
+ pasteElementChild({ state }, { curElement, pasteElement }) {
|
|
|
let element = {
|
|
|
id: curElement.container ? curElement.container.id : curElement.id,
|
|
|
};
|
|
@@ -313,19 +198,13 @@ const actions = {
|
|
|
},
|
|
|
// 删除试题 --------------->
|
|
|
removeElement({ state, commit }, element) {
|
|
|
- const positionInfos = fetchAllRelateParentElementPositionInfos(
|
|
|
- element.parent,
|
|
|
- state.topics
|
|
|
- );
|
|
|
- positionInfos.reverse().forEach((pos) => {
|
|
|
- state.topics.splice(pos._elementNo, 1);
|
|
|
- });
|
|
|
+ const pos = fetchElementPositionInfos(element, state.topics);
|
|
|
+ state.topics.splice(pos, 1);
|
|
|
|
|
|
commit("setCurElement", {});
|
|
|
},
|
|
|
// 删除试题包含元素 --------------->
|
|
|
removeElementChild({ state, commit }, element) {
|
|
|
- // 删除解答题小题
|
|
|
const pos = fetchElementPositionInfos(element.container, state.topics);
|
|
|
const columnElements = state.topics[pos].elements;
|
|
|
const childIndex = columnElements.findIndex(
|
|
@@ -335,91 +214,6 @@ const actions = {
|
|
|
|
|
|
commit("setCurElement", {});
|
|
|
},
|
|
|
- // 扩展答题区操作 --------------->
|
|
|
- copyExplainChildren({ state }, element) {
|
|
|
- let curElement = {
|
|
|
- id: element.container ? element.container.id : element.id,
|
|
|
- };
|
|
|
- const pos = fetchElementPositionInfos(curElement, state.topics);
|
|
|
- curElement = state.topics[pos];
|
|
|
-
|
|
|
- let newElement = Object.assign({}, curElement, {
|
|
|
- id: getElementId(),
|
|
|
- elements: [],
|
|
|
- h: 200,
|
|
|
- isExtend: true,
|
|
|
- showTitle: false,
|
|
|
- });
|
|
|
-
|
|
|
- state.topics.splice(pos + 1, 0, newElement);
|
|
|
- // 更新小题答题区isLast
|
|
|
- let positionInfos = fetchSameSerialNumberChildrenPositionInfo(
|
|
|
- curElement,
|
|
|
- state.topics
|
|
|
- );
|
|
|
- positionInfos.forEach((pos, pindex) => {
|
|
|
- state.topics[pos._elementNo].isLast = pindex + 1 === positionInfos.length;
|
|
|
- });
|
|
|
- },
|
|
|
- deleteExplainChildren({ state }, element) {
|
|
|
- let curElement = {
|
|
|
- id: element.container ? element.container.id : element.id,
|
|
|
- };
|
|
|
- const curPos = fetchElementPositionInfos(curElement, state.topics);
|
|
|
- curElement = state.topics[curPos];
|
|
|
-
|
|
|
- let positionInfos = fetchSameSerialNumberChildrenPositionInfo(
|
|
|
- curElement,
|
|
|
- state.topics
|
|
|
- );
|
|
|
- if (positionInfos.length < 2) return;
|
|
|
- const pindex = positionInfos.findIndex(
|
|
|
- (item) => item._elementId === curElement.id
|
|
|
- );
|
|
|
- const pos = positionInfos[pindex]._elementNo;
|
|
|
- positionInfos.splice(pindex, 1);
|
|
|
- const nextPos = positionInfos[0]._elementNo;
|
|
|
- // 当删除的是非扩展区域时,则下一个答题区要被设置成非扩展区
|
|
|
- if (!curElement.isExtend) {
|
|
|
- state.topics[nextPos].isExtend = false;
|
|
|
- }
|
|
|
- // 当删除的是含有标题答题区时,则需要将下一个答题区开启显示标题。
|
|
|
- if (curElement.showTitle) {
|
|
|
- state.topics[nextPos].showTitle = true;
|
|
|
- }
|
|
|
- state.topics.splice(pos, 1);
|
|
|
- // 更新小题答题区isLast
|
|
|
- positionInfos = fetchSameSerialNumberChildrenPositionInfo(
|
|
|
- curElement,
|
|
|
- state.topics
|
|
|
- );
|
|
|
- positionInfos.forEach((pos, pindex) => {
|
|
|
- state.topics[pos._elementNo].isLast = pindex + 1 === positionInfos.length;
|
|
|
- });
|
|
|
- },
|
|
|
- // 大题顺序操作 --------------->
|
|
|
- topicMoveUp({ state, dispatch }, topicId) {
|
|
|
- const curTopicPos = state.topicSeries.findIndex(
|
|
|
- (item) => item.id === topicId
|
|
|
- );
|
|
|
- const prevTopicId = state.topicSeries[curTopicPos - 1].id;
|
|
|
- let relateTopicPos = [];
|
|
|
- state.topics.forEach((item, index) => {
|
|
|
- if (item.parent && item.parent.id === topicId) relateTopicPos.push(index);
|
|
|
- });
|
|
|
- const prevTopicFirstIndex = state.topics.findIndex(
|
|
|
- (item) => item.parent && item.parent.id === prevTopicId
|
|
|
- );
|
|
|
- const relateTopics = state.topics.splice(
|
|
|
- relateTopicPos[0],
|
|
|
- relateTopicPos.length
|
|
|
- );
|
|
|
- relateTopics.reverse().forEach((topic) => {
|
|
|
- state.topics.splice(prevTopicFirstIndex, 0, topic);
|
|
|
- });
|
|
|
-
|
|
|
- dispatch("resetTopicSeries");
|
|
|
- },
|
|
|
// 重构页面
|
|
|
resetElementProp({ state }, isResetId = false) {
|
|
|
state.topics.forEach((element) => {
|
|
@@ -434,8 +228,8 @@ const actions = {
|
|
|
});
|
|
|
},
|
|
|
rebuildPages({ state, commit }) {
|
|
|
- const columnNumber = state.cardConfig.columnNumber;
|
|
|
- const pageSize = state.cardConfig.pageSize;
|
|
|
+ const pageInfo = state.pages[0];
|
|
|
+ const { columnNumber } = pageInfo;
|
|
|
// 更新元件最新的高度信息
|
|
|
// 整理所有元件
|
|
|
state.topics.forEach((element) => {
|
|
@@ -444,19 +238,16 @@ const actions = {
|
|
|
if (elementDom) {
|
|
|
element.h = elementDom.offsetHeight;
|
|
|
element.w = elementDom.offsetWidth;
|
|
|
- // 解答题小题与其他题有些区别。
|
|
|
- // 其他题都是通过内部子元素自动撑高元件,而解答题则需要手动设置高度。
|
|
|
- const ESCAPE_ELEMENTS = ["CARD_HEAD"];
|
|
|
- element.isCovered =
|
|
|
- !ESCAPE_ELEMENTS.includes(element.type) &&
|
|
|
- checkElementisCovered(`preview-${element.id}`, element.type);
|
|
|
+ // 编辑框需要手动设置高度。
|
|
|
+ element.isCovered = checkElementisCovered(
|
|
|
+ `preview-${element.id}`,
|
|
|
+ element.type
|
|
|
+ );
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 动态计算每列可以分配的元件
|
|
|
const columnHeight = document.getElementById("topic-column").offsetHeight;
|
|
|
- let pages = [];
|
|
|
- let page = {};
|
|
|
let columns = [];
|
|
|
let curColumnElements = [];
|
|
|
let curColumnHeight = 0;
|
|
@@ -468,8 +259,6 @@ const actions = {
|
|
|
|
|
|
// 放入元素通用流程
|
|
|
const pushElement = (element) => {
|
|
|
- // 当前栏中第一个题型之前新增题型头元素(topic-head)。
|
|
|
- // 题型头和当前题要组合加入栏中,不可拆分。
|
|
|
let elementList = [element];
|
|
|
|
|
|
const elementHeight = calcSum(elementList.map((elem) => elem.h));
|
|
@@ -493,39 +282,20 @@ const actions = {
|
|
|
|
|
|
// 批量添加所有元素。
|
|
|
initCurColumnElements();
|
|
|
- state.topics.forEach((element, eindex) => {
|
|
|
- element.elementSerialNo = eindex;
|
|
|
+ state.topics.forEach((element) => {
|
|
|
pushElement(element);
|
|
|
});
|
|
|
|
|
|
// 最后一栏的处理。
|
|
|
columns.push([...curColumnElements]);
|
|
|
- // 构建pages
|
|
|
- columns.forEach((column, cindex) => {
|
|
|
- const columnNo = cindex % columnNumber;
|
|
|
- if (!columnNo) {
|
|
|
- page = getNewPage(pages.length, { pageSize, columnNumber });
|
|
|
- }
|
|
|
- page.columns[columnNo].elements = column;
|
|
|
-
|
|
|
- if (columnNo + 1 === columnNumber || cindex === columns.length - 1) {
|
|
|
- pages.push(page);
|
|
|
- }
|
|
|
- });
|
|
|
- // 保证页面总是偶数页
|
|
|
- if (numberIsOdd(pages.length)) {
|
|
|
- pages.push(getNewPage(pages.length, { pageSize, columnNumber }));
|
|
|
+ // 更新pages,只能有两页
|
|
|
+ columns = columns.slice(0, 2 * columnNumber);
|
|
|
+ for (let i = 0; i < 2 * columnNumber; i++) {
|
|
|
+ const pageNo = Math.floor(i / columnNumber);
|
|
|
+ const columnNo = i % columnNumber;
|
|
|
+ state.pages[pageNo].columns[columnNo].elements = columns[i] || [];
|
|
|
}
|
|
|
|
|
|
- pages.forEach((page, pindex) => {
|
|
|
- if (numberIsOdd(pindex + 1)) {
|
|
|
- page.sides = deepCopy(state.pageDefaultElems.sideLeft);
|
|
|
- } else {
|
|
|
- page.sides = deepCopy(state.pageDefaultElems.sideRight);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- commit("setPages", pages);
|
|
|
commit("setCurPage", state.curPageNo);
|
|
|
},
|
|
|
};
|