@tachybase/plugin-workflow-approval
Version:
Approval base in Workflow
319 lines (318 loc) • 12.5 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var Approval_exports = {};
__export(Approval_exports, {
default: () => ApprovalTrigger
});
module.exports = __toCommonJS(Approval_exports);
var import_module_workflow = require("@tachybase/module-workflow");
var import_server = require("@tego/server");
var import_lodash = require("lodash");
var import_sequelize = require("sequelize");
var import_status = require("../constants/status");
var import_tools = require("../tools");
var import_tools2 = require("./tools");
const _ApprovalTrigger = class _ApprovalTrigger extends import_module_workflow.Trigger {
constructor(workflow) {
super(workflow);
this.sync = false;
this.triggerHandler = async (approval, { transaction }) => {
const workflow = await approval.getWorkflow({
where: {
id: approval.get("workflowId"),
type: _ApprovalTrigger.TYPE,
enabled: true,
"config.collection": approval.collectionName
},
transaction
});
const isChangedStatus = approval.changed("status");
const isAllowStatusList = [import_status.APPROVAL_STATUS.DRAFT, import_status.APPROVAL_STATUS.SUBMITTED, import_status.APPROVAL_STATUS.RESUBMIT].includes(
approval.status
);
const previousApprovalStatus = approval.previous("status");
const currentApprovalStatus = approval.status;
const forbiddenList = [
[import_status.APPROVAL_STATUS.SUBMITTED, import_status.APPROVAL_STATUS.DRAFT]
// 撤回情况
];
const isForbiddenWhenStatusChange = forbiddenList.some(
([prev, curr]) => prev === previousApprovalStatus && curr === currentApprovalStatus
);
if (!workflow || !isChangedStatus || !isAllowStatusList || isForbiddenWhenStatusChange) {
return;
}
const [dataSourceName, collectionName] = (0, import_server.parseCollectionName)(approval.collectionName);
const { repository } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(collectionName);
const data = await repository.findOne({
filterByTk: approval.get("dataKey"),
appends: workflow.config.appends,
transaction: this.workflow.useDataSourceTransaction(dataSourceName, transaction)
});
this.workflow.trigger(
workflow,
{
data: (0, import_module_workflow.toJSON)(data),
approvalId: approval.id,
applicantRoleName: approval.applicantRoleName,
summary: (0, import_tools.getSummary)({
summaryConfig: workflow.config.summary,
data
}),
collectionName: approval.collectionName
},
{ transaction }
);
};
this.onExecutionCreate = async (execution, { transaction }) => {
const workflow = await execution.getWorkflow({ transaction });
if (workflow.type !== _ApprovalTrigger.TYPE) {
return;
}
const { approvalId, data, summary, collectionName } = execution.context;
const ApprovalExecutionRepo = this.workflow.db.getRepository("approvalExecutions");
const approvalExecution = await ApprovalExecutionRepo.create({
values: {
approvalId,
executionId: execution.id,
status: execution.status,
snapshot: data,
summary,
collectionName
},
transaction
});
const ApprovalsRepo = this.workflow.db.getRepository("approvals");
await ApprovalsRepo.update({
filterByTk: approvalId,
values: { latestExecutionId: approvalExecution.id },
transaction
});
};
this.onExecutionUpdate = async (execution, { transaction }) => {
if (!execution.workflow) {
execution.workflow = await execution.getWorkflow({ transaction });
}
if (!execution.status || execution.workflow.type !== _ApprovalTrigger.TYPE) {
return;
}
const approvalExecution = await this.workflow.db.getRepository("approvalExecutions").findOne({
filter: {
executionId: execution.id,
approvalId: execution.context.approvalId
},
appends: ["approval"],
transaction
});
const { approval } = approvalExecution;
if (![import_status.APPROVAL_STATUS.SUBMITTED, import_status.APPROVAL_STATUS.PROCESSING].includes(approval.status)) {
return;
}
let status = import_status.APPROVAL_STATUS.APPROVED;
if (execution.status === import_module_workflow.EXECUTION_STATUS.RESOLVED) {
const [approvalNodeJob] = await execution.getJobs({
where: {
status: {
[import_sequelize.Op.ne]: import_module_workflow.JOB_STATUS.PENDING
}
},
include: [
{
association: "node",
where: {
type: "approval"
},
required: true
}
],
order: [["updatedAt", "DESC"]],
limit: 1,
transaction
});
if (approvalNodeJob && import_tools2.ApprovalJobStatusMap[approvalNodeJob.result] != null) {
status = import_tools2.ApprovalJobStatusMap[approvalNodeJob.result];
}
} else {
if (import_tools2.ExecutionStatusMap[execution.status] != null) {
status = import_tools2.ExecutionStatusMap[execution.status];
}
}
await approval.update({ status }, { transaction });
await approvalExecution.update({ status: execution.status }, { transaction });
};
this.middleware = async (context, next) => {
if (!context.action) {
return;
}
const {
resourceName,
actionName,
params: { triggerWorkflows, beforeWorkflows }
} = context.action;
if (beforeWorkflows) {
this.collectionTriggerAction(context, beforeWorkflows);
}
if (resourceName === "workflows" && actionName === "trigger") {
return this.workflowTriggerAction(context, next);
}
await next();
if (!triggerWorkflows || !["create", "update"].includes(actionName)) {
return;
}
this.collectionTriggerAction(context, triggerWorkflows);
};
const { db } = workflow.app;
db.on("approvals.afterSave", this.triggerHandler);
db.on("executions.afterCreate", this.onExecutionCreate);
db.on("executions.afterUpdate", this.onExecutionUpdate);
workflow.app.use(this.middleware, { tag: "workflow-trigger", after: "dataSource" });
}
async workflowTriggerAction(context, next) {
const { triggerWorkflows, values } = context.action.params;
if (!triggerWorkflows) {
return context.throw(400);
}
const triggers = triggerWorkflows.split(",").map((trigger) => trigger.split("!"));
const workflowRepo = this.workflow.db.getRepository("workflows");
const workflows = await workflowRepo.find({
filter: {
type: _ApprovalTrigger.TYPE,
key: triggers.map((trigger) => trigger[0]),
current: true,
enabled: true
}
});
context.status = 202;
await next();
workflows.forEach(async (workflow) => {
const trigger = triggers.find((trigger2) => trigger2[0] === workflow.key);
const [dataSourceName, collectionName] = (0, import_server.parseCollectionName)(workflow.config.collection);
const collecton = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(collectionName);
const data = await collecton.repository.create({
values: {
...trigger[1] ? (0, import_lodash.get)(values, trigger[1]) : values
// createdBy: currentUser.id,
// updatedById: currentUser.id,
},
context
});
const approvalRepo = this.workflow.db.getRepository("approvals");
await approvalRepo.create({
values: {
collectionName: workflow.config.collection,
data: (0, import_module_workflow.toJSON)(data),
dataKey: data.get(collecton.filterTargetKey),
status: import_status.APPROVAL_STATUS.SUBMITTED,
// createdBy: currentUser.id,
// updatedById: currentUser.id,
workflowId: workflow.id,
workflowKey: workflow.key,
summary: (0, import_tools.getSummary)({
summaryConfig: workflow.config.summary,
data
})
},
context
});
});
}
async collectionTriggerAction(context, workflowList) {
const dataSourceHeader = context.get("x-data-source") || "main";
const approvalRepo = this.workflow.db.getRepository("approvals");
const triggers = workflowList.split(",").map((trigger) => trigger.split("!"));
const triggersKeysMap = new Map(triggers);
const workflows = Array.from(this.workflow.enabledCache.values()).filter(
(item) => item.type === _ApprovalTrigger.TYPE && triggersKeysMap.has(item.key)
);
for (const workflow of workflows) {
const [dataSourceName, collectionName] = (0, import_server.parseCollectionName)(workflow.config.collection);
const trigger = triggers.find((trigger2) => trigger2[0] === workflow.key);
const { body: data } = context;
if (!data) {
return;
}
if (dataSourceName !== dataSourceHeader) {
continue;
}
(Array.isArray(data) ? data : [data]).forEach(async (row) => {
let dataCurrent = {};
if (row.id) {
const { repository } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(collectionName);
dataCurrent = await repository.findOne({
filterByTk: data.id,
appends: [...workflow.config.appends]
});
}
let payload = row;
if (trigger[1]) {
const paths = trigger[1].split(".");
for await (const field of paths) {
if (payload.get(field)) {
payload = payload.get(field);
} else {
const association = (0, import_server.modelAssociationByKey)(payload, field);
payload = await payload[association.accessors.get]();
}
}
}
const collection = context.app.dataSourceManager.dataSources.get(dataSourceName).collectionManager.getCollection(collectionName);
if (!collection || collection.model !== payload.constructor) {
return;
}
await approvalRepo.create({
values: {
collectionName: workflow.config.collection,
data: (0, import_module_workflow.toJSON)(payload),
dataKey: payload.get(collection.filterTargetKey),
status: import_status.APPROVAL_STATUS.SUBMITTED,
// createdBy: currentUser.id,
// updatedBy: currentUser.id,
workflowId: workflow.id,
workflowKey: workflow.key,
applicantRoleName: context.state.currentRole,
summary: (0, import_tools.getSummary)({
summaryConfig: workflow.config.summary,
data: dataCurrent
})
},
context
});
});
}
}
on(workflow) {
}
off(workflow) {
}
async duplicateConfig(workflow, { transaction }) {
const { db } = this.workflow;
const uiSchemaRepo = db.getRepository("uiSchemas");
if (!workflow.config.applyForm) {
return workflow.config;
}
const result = await uiSchemaRepo.duplicate(workflow.config.applyForm, {
transaction
});
return {
...workflow.config,
applyForm: result["x-uid"]
};
}
};
_ApprovalTrigger.TYPE = "approval";
let ApprovalTrigger = _ApprovalTrigger;