322 lines
11 KiB
JavaScript
322 lines
11 KiB
JavaScript
import { assert } from 'oak-domain/lib/utils/assert';
|
||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||
import { OakPreConditionUnsetException } from 'oak-domain/lib/types';
|
||
import { uniq } from 'oak-domain/lib/utils/lodash';
|
||
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
|
||
const triggers = [
|
||
{
|
||
name: '在创建文章分类时,查询文章分类是否重名',
|
||
entity: 'articleMenu',
|
||
action: 'create',
|
||
when: 'before',
|
||
fn: async (event, context) => {
|
||
const { operation: { data }, } = event;
|
||
assert(!(data instanceof Array)); // 不可能是成组创建
|
||
if (data.name) {
|
||
const { entity, entityId } = data;
|
||
const [articleMenu] = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
name: 1,
|
||
parentId: 1,
|
||
},
|
||
filter: {
|
||
entity,
|
||
entityId,
|
||
name: data.name,
|
||
parentId: data.parentId
|
||
? data.parentId
|
||
: {
|
||
$exists: false,
|
||
},
|
||
},
|
||
}, {});
|
||
if (articleMenu) {
|
||
throw new OakPreConditionUnsetException(`父分类的同一子集中存在同名分类【${data.name}】,请重新输入`);
|
||
}
|
||
}
|
||
return 0;
|
||
},
|
||
},
|
||
{
|
||
name: '在创建文章分类时,文章分类的父节点的【isLeaf】置为【true】',
|
||
entity: 'articleMenu',
|
||
action: 'create',
|
||
when: 'after',
|
||
fn: async (event, context) => {
|
||
const { operation: { data, filter }, } = event;
|
||
assert(!(data instanceof Array));
|
||
const { id } = data;
|
||
const [articleMenu] = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
name: 1,
|
||
parentId: 1,
|
||
parent: {
|
||
id: 1,
|
||
isLeaf: 1,
|
||
},
|
||
},
|
||
filter: {
|
||
id,
|
||
},
|
||
}, {});
|
||
if (articleMenu &&
|
||
articleMenu.parent &&
|
||
!articleMenu.parent.isLeaf) {
|
||
await context.operate('articleMenu', {
|
||
id: await generateNewIdAsync(),
|
||
action: 'update',
|
||
data: {
|
||
isLeaf: true,
|
||
},
|
||
filter: {
|
||
id: articleMenu.parentId,
|
||
},
|
||
}, {
|
||
blockTrigger: true,
|
||
});
|
||
}
|
||
return 0;
|
||
},
|
||
},
|
||
{
|
||
name: '在删除文章分类前,将文章分类的父节点的【isLeaf】置为【false】',
|
||
entity: 'articleMenu',
|
||
action: 'remove',
|
||
when: 'before',
|
||
fn: async (event, context) => {
|
||
const { operation: { data, filter }, } = event;
|
||
const [articleMenu] = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
name: 1,
|
||
parentId: 1,
|
||
parent: {
|
||
id: 1,
|
||
isLeaf: 1,
|
||
},
|
||
},
|
||
filter,
|
||
}, {});
|
||
if (articleMenu && articleMenu.parentId) {
|
||
const articleMenus = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
},
|
||
filter: {
|
||
parentId: articleMenu.parentId,
|
||
id: {
|
||
$ne: articleMenu.id,
|
||
},
|
||
},
|
||
}, {});
|
||
if (articleMenus.length === 0) {
|
||
await context.operate('articleMenu', {
|
||
id: await generateNewIdAsync(),
|
||
action: 'update',
|
||
data: {
|
||
isLeaf: false,
|
||
},
|
||
filter: {
|
||
id: articleMenu.parentId,
|
||
},
|
||
}, {});
|
||
}
|
||
}
|
||
return 0;
|
||
},
|
||
},
|
||
{
|
||
name: '在更新文章分类时,查询文章分类是否重名',
|
||
entity: 'articleMenu',
|
||
action: 'update',
|
||
when: 'before',
|
||
fn: async (event, context) => {
|
||
const { operation: { data, filter }, } = event;
|
||
assert(!(data instanceof Array)); // 不可能是成组创建
|
||
if (data.name) {
|
||
const [articleMenu] = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
name: 1,
|
||
parentId: 1,
|
||
entity: 1,
|
||
entityId: 1,
|
||
},
|
||
filter,
|
||
}, {});
|
||
if (articleMenu) {
|
||
const [articleMenu2] = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
name: 1,
|
||
parentId: 1,
|
||
},
|
||
filter: {
|
||
entity: articleMenu.entity,
|
||
entityId: articleMenu.entityId,
|
||
name: data.name,
|
||
parentId: articleMenu.parentId
|
||
? articleMenu.parentId
|
||
: {
|
||
$exists: false,
|
||
},
|
||
id: {
|
||
$ne: articleMenu.id
|
||
}
|
||
},
|
||
}, {});
|
||
if (articleMenu2) {
|
||
throw new OakPreConditionUnsetException(`父分类的同一子集中存在同名分类【${data.name}】,请重新输入`);
|
||
}
|
||
}
|
||
}
|
||
return 1;
|
||
},
|
||
},
|
||
{
|
||
name: '文章分类创建时,更新其最近编辑时间',
|
||
entity: 'articleMenu',
|
||
action: 'create',
|
||
when: 'before',
|
||
priority: 99,
|
||
fn: async ({ operation }, context, option) => {
|
||
const { id, data } = operation;
|
||
data.latestAt = Date.now();
|
||
return 1;
|
||
},
|
||
},
|
||
{
|
||
name: '文章分类更新时,更新其最近编辑时间',
|
||
entity: 'articleMenu',
|
||
action: 'update',
|
||
when: 'before',
|
||
attributes: ['$$updateAt$$'],
|
||
check: (operation) => {
|
||
const { data } = operation;
|
||
return typeof data.$$updateAt$$ === 'number' && data.$$updateAt$$ > 0;
|
||
},
|
||
priority: 99,
|
||
asRoot: true,
|
||
fn: async ({ operation }, context, option) => {
|
||
const { data, filter } = operation;
|
||
data.latestAt = data.$$updateAt$$;
|
||
return 1;
|
||
},
|
||
},
|
||
{
|
||
name: '文章分类的最近编辑时间更新时,更新其parent的最近编辑时间',
|
||
entity: 'articleMenu',
|
||
action: 'update',
|
||
when: 'after',
|
||
attributes: ['latestAt'],
|
||
check: (operation) => {
|
||
const { data } = operation;
|
||
return typeof data.latestAt === 'number' && data.latestAt > 0;
|
||
},
|
||
priority: 99,
|
||
asRoot: true,
|
||
fn: async ({ operation }, context, option) => {
|
||
const { data, filter } = operation;
|
||
const articleMenus = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
parentId: 1,
|
||
},
|
||
filter,
|
||
}, { forUpdate: true });
|
||
let count = 0;
|
||
if (articleMenus && articleMenus.length > 0) {
|
||
const parentIds = uniq(articleMenus.map((ele) => ele.parentId));
|
||
for (const parentId of parentIds) {
|
||
if (parentId) {
|
||
await context.operate('articleMenu', {
|
||
id: await generateNewIdAsync(),
|
||
action: 'update',
|
||
data: {
|
||
latestAt: data.latestAt,
|
||
},
|
||
filter: {
|
||
id: parentId,
|
||
},
|
||
}, {});
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
return count;
|
||
},
|
||
},
|
||
{
|
||
name: '在删除文章分类前,更新其parent的最近编辑时间',
|
||
entity: 'articleMenu',
|
||
action: 'remove',
|
||
when: 'before',
|
||
priority: 99,
|
||
asRoot: true,
|
||
fn: async ({ operation }, context, option) => {
|
||
const { data, filter } = operation;
|
||
const articleMenus = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
parentId: 1,
|
||
},
|
||
filter,
|
||
}, { forUpdate: true });
|
||
let count = 0;
|
||
if (articleMenus && articleMenus.length > 0) {
|
||
const now = Date.now();
|
||
const parentIds = uniq(articleMenus.map((ele) => ele.parentId));
|
||
for (const parentId of parentIds) {
|
||
if (parentId) {
|
||
await context.operate('articleMenu', {
|
||
id: await generateNewIdAsync(),
|
||
action: 'update',
|
||
data: {
|
||
latestAt: now,
|
||
},
|
||
filter: {
|
||
id: parentId,
|
||
},
|
||
}, {});
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
},
|
||
{
|
||
name: '当articleMenu的isArticle更新时,通知相应的事件订阅',
|
||
entity: 'articleMenu',
|
||
action: 'update',
|
||
when: 'before',
|
||
attributes: ['isArticle'],
|
||
check: (operation) => {
|
||
const { data } = operation;
|
||
return typeof data.isArticle === 'boolean';
|
||
},
|
||
fn: async ({ operation }, context, option) => {
|
||
const { id, filter } = operation;
|
||
const articleMenus = await context.select('articleMenu', {
|
||
data: {
|
||
id: 1,
|
||
entityId: 1,
|
||
},
|
||
filter,
|
||
}, { forUpdate: true });
|
||
const entityIds = articleMenus.map((ele) => ele.entityId);
|
||
let count = 0;
|
||
if (entityIds && entityIds.length) {
|
||
for (const entityId of entityIds) {
|
||
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.articleMenuUpdate}-${entityId}`);
|
||
count++;
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
},
|
||
];
|
||
export default triggers;
|