You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
8.3 KiB
218 lines
8.3 KiB
'use strict';
|
|
|
|
const { TEMP_POSITION_BASE } = require('./constants');
|
|
const { toInt, normalizeInsertPosition } = require('./helpers');
|
|
|
|
const reorderPositions = async (Model, orderedIds, transaction = null) => {
|
|
if (!orderedIds.length) return;
|
|
let tempPosition = TEMP_POSITION_BASE;
|
|
for (const id of orderedIds) {
|
|
await Model.update({ position: tempPosition++ }, { where: { id }, transaction });
|
|
}
|
|
let finalPosition = 1;
|
|
for (const id of orderedIds) {
|
|
await Model.update({ position: finalPosition++ }, { where: { id }, transaction });
|
|
}
|
|
};
|
|
|
|
const findChapterSiblings = async (ctx, instanceId, parentId, excludeChapterId = null, transaction = null) => {
|
|
const { models, ORM: { Op } } = ctx.app.fs.dc;
|
|
const where = {
|
|
instanceId: toInt(instanceId),
|
|
parentId: parentId === null ? null : toInt(parentId),
|
|
};
|
|
if (excludeChapterId) {
|
|
where.id = { [Op.ne]: toInt(excludeChapterId) };
|
|
}
|
|
return models.ReportChapter.findAll({
|
|
where,
|
|
attributes: ['id', 'position'],
|
|
order: [['position', 'ASC'], ['id', 'ASC']],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
};
|
|
|
|
const findTemplateChapterSiblings = async (ctx, templateId, parentId, excludeChapterId = null, transaction = null) => {
|
|
const { models, ORM: { Op } } = ctx.app.fs.dc;
|
|
const where = {
|
|
templateId: toInt(templateId),
|
|
parentId: parentId === null ? null : toInt(parentId),
|
|
};
|
|
if (excludeChapterId) {
|
|
where.id = { [Op.ne]: toInt(excludeChapterId) };
|
|
}
|
|
return models.ReportTemplateChapter.findAll({
|
|
where,
|
|
attributes: ['id', 'position'],
|
|
order: [['position', 'ASC'], ['id', 'ASC']],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
};
|
|
|
|
const findBlockSiblings = async (ctx, chapterId, excludeBlockId = null, transaction = null) => {
|
|
const { models, ORM: { Op } } = ctx.app.fs.dc;
|
|
const where = {
|
|
chapterId: toInt(chapterId),
|
|
};
|
|
if (excludeBlockId) {
|
|
where.id = { [Op.ne]: toInt(excludeBlockId) };
|
|
}
|
|
return models.ReportBlock.findAll({
|
|
where,
|
|
attributes: ['id', 'position'],
|
|
order: [['position', 'ASC'], ['id', 'ASC']],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
};
|
|
|
|
const findTemplateBlockSiblings = async (ctx, chapterId, excludeBlockId = null, transaction = null) => {
|
|
const { models, ORM: { Op } } = ctx.app.fs.dc;
|
|
const where = {
|
|
chapterId: toInt(chapterId),
|
|
};
|
|
if (excludeBlockId) {
|
|
where.id = { [Op.ne]: toInt(excludeBlockId) };
|
|
}
|
|
return models.ReportTemplateBlock.findAll({
|
|
where,
|
|
attributes: ['id', 'position'],
|
|
order: [['position', 'ASC'], ['id', 'ASC']],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
};
|
|
|
|
const reorderChapterSiblingsWithInsert = async (ctx, instanceId, parentId, chapterId, targetPosition, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findChapterSiblings(ctx, instanceId, parentId, chapterId, transaction);
|
|
const insertPosition = normalizeInsertPosition(targetPosition, siblings.length + 1);
|
|
const orderedIds = siblings.map(item => item.id);
|
|
orderedIds.splice(insertPosition - 1, 0, toInt(chapterId));
|
|
await reorderPositions(models.ReportChapter, orderedIds, transaction);
|
|
return insertPosition;
|
|
};
|
|
|
|
const reorderBlockSiblingsWithInsert = async (ctx, chapterId, blockId, targetPosition, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findBlockSiblings(ctx, chapterId, blockId, transaction);
|
|
const insertPosition = normalizeInsertPosition(targetPosition, siblings.length + 1);
|
|
const orderedIds = siblings.map(item => item.id);
|
|
orderedIds.splice(insertPosition - 1, 0, toInt(blockId));
|
|
await reorderPositions(models.ReportBlock, orderedIds, transaction);
|
|
return insertPosition;
|
|
};
|
|
|
|
const reorderChapterSiblings = async (ctx, instanceId, parentId, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findChapterSiblings(ctx, instanceId, parentId, null, transaction);
|
|
await reorderPositions(models.ReportChapter, siblings.map(item => item.id), transaction);
|
|
};
|
|
|
|
const reorderTemplateChapterSiblingsWithInsert = async (ctx, templateId, parentId, chapterId, targetPosition, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findTemplateChapterSiblings(ctx, templateId, parentId, chapterId, transaction);
|
|
const insertPosition = normalizeInsertPosition(targetPosition, siblings.length + 1);
|
|
const orderedIds = siblings.map(item => item.id);
|
|
orderedIds.splice(insertPosition - 1, 0, toInt(chapterId));
|
|
await reorderPositions(models.ReportTemplateChapter, orderedIds, transaction);
|
|
return insertPosition;
|
|
};
|
|
|
|
const reorderTemplateBlockSiblingsWithInsert = async (ctx, chapterId, blockId, targetPosition, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findTemplateBlockSiblings(ctx, chapterId, blockId, transaction);
|
|
const insertPosition = normalizeInsertPosition(targetPosition, siblings.length + 1);
|
|
const orderedIds = siblings.map(item => item.id);
|
|
orderedIds.splice(insertPosition - 1, 0, toInt(blockId));
|
|
await reorderPositions(models.ReportTemplateBlock, orderedIds, transaction);
|
|
return insertPosition;
|
|
};
|
|
|
|
const reorderTemplateChapterSiblings = async (ctx, templateId, parentId, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findTemplateChapterSiblings(ctx, templateId, parentId, null, transaction);
|
|
await reorderPositions(models.ReportTemplateChapter, siblings.map(item => item.id), transaction);
|
|
};
|
|
|
|
const reorderBlockSiblings = async (ctx, chapterId, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findBlockSiblings(ctx, chapterId, null, transaction);
|
|
await reorderPositions(models.ReportBlock, siblings.map(item => item.id), transaction);
|
|
};
|
|
|
|
const reorderTemplateBlockSiblings = async (ctx, chapterId, transaction = null) => {
|
|
const { models } = ctx.app.fs.dc;
|
|
const siblings = await findTemplateBlockSiblings(ctx, chapterId, null, transaction);
|
|
await reorderPositions(models.ReportTemplateBlock, siblings.map(item => item.id), transaction);
|
|
};
|
|
|
|
const ensureNoChapterCycle = async (ctx, instanceId, chapterId, parentId, transaction = null) => {
|
|
if (parentId === null) return;
|
|
const { models } = ctx.app.fs.dc;
|
|
if (toInt(chapterId) === toInt(parentId)) throw '父章节不能是自身';
|
|
let current = await models.ReportChapter.findOne({
|
|
where: { id: toInt(parentId), instanceId: toInt(instanceId) },
|
|
attributes: ['id', 'parentId'],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
if (!current) throw '父章节不存在';
|
|
while (current) {
|
|
if (toInt(current.id) === toInt(chapterId)) {
|
|
throw '不允许将章节移动到自己的子节点';
|
|
}
|
|
if (!current.parentId) break;
|
|
current = await models.ReportChapter.findOne({
|
|
where: { id: current.parentId, instanceId: toInt(instanceId) },
|
|
attributes: ['id', 'parentId'],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
}
|
|
};
|
|
|
|
const ensureNoTemplateChapterCycle = async (ctx, templateId, chapterId, parentId, transaction = null) => {
|
|
if (parentId === null) return;
|
|
const { models } = ctx.app.fs.dc;
|
|
if (toInt(chapterId) === toInt(parentId)) throw '父章节不能是自身';
|
|
let current = await models.ReportTemplateChapter.findOne({
|
|
where: { id: toInt(parentId), templateId: toInt(templateId) },
|
|
attributes: ['id', 'parentId'],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
if (!current) throw '父章节不存在';
|
|
while (current) {
|
|
if (toInt(current.id) === toInt(chapterId)) {
|
|
throw '不允许将章节移动到自己的子节点';
|
|
}
|
|
if (!current.parentId) break;
|
|
current = await models.ReportTemplateChapter.findOne({
|
|
where: { id: current.parentId, templateId: toInt(templateId) },
|
|
attributes: ['id', 'parentId'],
|
|
raw: true,
|
|
transaction,
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
reorderPositions,
|
|
findChapterSiblings,
|
|
findTemplateChapterSiblings,
|
|
findBlockSiblings,
|
|
findTemplateBlockSiblings,
|
|
reorderChapterSiblingsWithInsert,
|
|
reorderBlockSiblingsWithInsert,
|
|
reorderChapterSiblings,
|
|
reorderTemplateChapterSiblingsWithInsert,
|
|
reorderTemplateBlockSiblingsWithInsert,
|
|
reorderTemplateChapterSiblings,
|
|
reorderBlockSiblings,
|
|
reorderTemplateBlockSiblings,
|
|
ensureNoChapterCycle,
|
|
ensureNoTemplateChapterCycle,
|
|
};
|
|
|