mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 11:12:20 +08:00
fix(plugin-workflow): fix stats cascade deleted (#7103)
This commit is contained in:
parent
aa1070ad0f
commit
2c8934bd9a
@ -204,11 +204,9 @@ export function WorkflowTasks() {
|
|||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { setTitle } = useDocumentTitle();
|
const { setTitle } = useDocumentTitle();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const apiClient = useAPIClient();
|
|
||||||
const { taskType, status = TASK_STATUS.PENDING, popupId } = useParams();
|
const { taskType, status = TASK_STATUS.PENDING, popupId } = useParams();
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
const [currentRecord, setCurrentRecord] = useState<any>(null);
|
const [currentRecord, setCurrentRecord] = useState<any>(null);
|
||||||
|
|
||||||
const items = useTaskTypeItems();
|
const items = useTaskTypeItems();
|
||||||
|
|
||||||
const { title, collection, action = 'list', useActionParams, Item, Detail } = useCurrentTaskType();
|
const { title, collection, action = 'list', useActionParams, Item, Detail } = useCurrentTaskType();
|
||||||
@ -227,21 +225,9 @@ export function WorkflowTasks() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (popupId && !currentRecord) {
|
if (popupId && !currentRecord) {
|
||||||
apiClient
|
setCurrentRecord({ id: popupId });
|
||||||
.resource(collection)
|
|
||||||
.get({
|
|
||||||
filterByTk: popupId,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data?.data) {
|
|
||||||
setCurrentRecord(res.data.data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [popupId, collection, currentRecord, apiClient]);
|
}, [popupId, currentRecord]);
|
||||||
|
|
||||||
const typeKey = taskType ?? items[0].key;
|
const typeKey = taskType ?? items[0].key;
|
||||||
|
|
||||||
|
@ -150,7 +150,6 @@ export default {
|
|||||||
foreignKey: 'key',
|
foreignKey: 'key',
|
||||||
sourceKey: 'key',
|
sourceKey: 'key',
|
||||||
constraints: false,
|
constraints: false,
|
||||||
onDelete: 'CASCADE',
|
|
||||||
// interface: 'oho',
|
// interface: 'oho',
|
||||||
// uiSchema: {
|
// uiSchema: {
|
||||||
// type: 'object',
|
// type: 'object',
|
||||||
|
@ -251,6 +251,60 @@ describe('workflow > actions > workflows', () => {
|
|||||||
const versionStatsCount = await WorkflowVersionStatsRepo.count();
|
const versionStatsCount = await WorkflowVersionStatsRepo.count();
|
||||||
expect(versionStatsCount).toBe(0);
|
expect(versionStatsCount).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('destroy current version should delete stats record too', async () => {
|
||||||
|
const w1 = await WorkflowModel.create({
|
||||||
|
enabled: true,
|
||||||
|
type: 'collection',
|
||||||
|
config: {
|
||||||
|
mode: 1,
|
||||||
|
collection: 'posts',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const s1 = await WorkflowStatsRepo.find();
|
||||||
|
expect(s1.length).toBe(1);
|
||||||
|
expect(s1[0].key).toBe(w1.key);
|
||||||
|
|
||||||
|
await agent.resource(`workflows`).destroy({
|
||||||
|
filterByTk: w1.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const statsCount = await WorkflowStatsRepo.count();
|
||||||
|
expect(statsCount).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('destroy non-current version should not delete stats record', async () => {
|
||||||
|
const w1 = await WorkflowModel.create({
|
||||||
|
enabled: true,
|
||||||
|
type: 'collection',
|
||||||
|
config: {
|
||||||
|
mode: 1,
|
||||||
|
collection: 'posts',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const s1 = await WorkflowStatsRepo.find();
|
||||||
|
expect(s1.length).toBe(1);
|
||||||
|
expect(s1[0].key).toBe(w1.key);
|
||||||
|
|
||||||
|
const w2 = await WorkflowRepo.revision({
|
||||||
|
filterByTk: w1.id,
|
||||||
|
filter: {
|
||||||
|
key: w1.key,
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
app,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await agent.resource(`workflows`).destroy({
|
||||||
|
filterByTk: w2.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const statsCount = await WorkflowStatsRepo.count();
|
||||||
|
expect(statsCount).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('revision', () => {
|
describe('revision', () => {
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, test } from 'vitest';
|
||||||
|
|
||||||
|
import { MockServer } from '@nocobase/test';
|
||||||
|
import { getApp } from '@nocobase/plugin-workflow-test';
|
||||||
|
|
||||||
|
import Migration from '../../migrations/20250619213102-add-missed-stats';
|
||||||
|
import PluginWorkflowServer from '../..';
|
||||||
|
import { EXECUTION_STATUS } from '../../constants';
|
||||||
|
|
||||||
|
describe('20250619213102-add-missed-stats', () => {
|
||||||
|
let app: MockServer;
|
||||||
|
let plugin: PluginWorkflowServer;
|
||||||
|
let WorkflowRepo;
|
||||||
|
let WorkflowStatsRepo;
|
||||||
|
|
||||||
|
describe('missed stats should be added', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = await getApp();
|
||||||
|
await app.version.update('1.7.0');
|
||||||
|
plugin = app.pm.get(PluginWorkflowServer) as PluginWorkflowServer;
|
||||||
|
WorkflowRepo = app.db.getRepository('workflows');
|
||||||
|
WorkflowStatsRepo = app.db.getRepository('workflowStats');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => app.destroy());
|
||||||
|
|
||||||
|
test('current workflow stats missing', async () => {
|
||||||
|
const workflow = await WorkflowRepo.create({
|
||||||
|
values: {
|
||||||
|
type: 'syncTrigger',
|
||||||
|
key: 'abc',
|
||||||
|
current: true,
|
||||||
|
},
|
||||||
|
hooks: false,
|
||||||
|
});
|
||||||
|
const e1 = await workflow.createExecution({
|
||||||
|
key: workflow.get('key'),
|
||||||
|
eventKey: '1',
|
||||||
|
context: {},
|
||||||
|
status: EXECUTION_STATUS.RESOLVED,
|
||||||
|
});
|
||||||
|
|
||||||
|
const s1 = await WorkflowStatsRepo.findOne({
|
||||||
|
filterByTk: workflow.get('key'),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(s1).toBeNull();
|
||||||
|
|
||||||
|
const migration = new Migration({ app, db: app.db } as any);
|
||||||
|
await migration.up();
|
||||||
|
|
||||||
|
const s2 = await WorkflowStatsRepo.findOne({
|
||||||
|
filterByTk: workflow.get('key'),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(s2).not.toBeNull();
|
||||||
|
expect(s2.get('executed')).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -57,11 +57,20 @@ export async function destroy(context: Context, next) {
|
|||||||
|
|
||||||
revisions.forEach((item) => ids.add(item.id));
|
revisions.forEach((item) => ids.add(item.id));
|
||||||
|
|
||||||
context.body = await repository.destroy({
|
const deleted = await repository.destroy({
|
||||||
filterByTk: Array.from(ids),
|
filterByTk: Array.from(ids),
|
||||||
individualHooks: true,
|
individualHooks: true,
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
const StatsRepo = context.db.getRepository('workflowStats');
|
||||||
|
await StatsRepo.destroy({
|
||||||
|
filter: {
|
||||||
|
key: Array.from(keysSet),
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
context.body = deleted;
|
||||||
});
|
});
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Migration } from '@nocobase/server';
|
||||||
|
|
||||||
|
export default class extends Migration {
|
||||||
|
appVersion = '<1.8.0';
|
||||||
|
on = 'afterLoad';
|
||||||
|
async up() {
|
||||||
|
const { db } = this.context;
|
||||||
|
|
||||||
|
const WorkflowRepo = db.getRepository('workflows');
|
||||||
|
const ExecutionRepo = db.getRepository('executions');
|
||||||
|
await db.sequelize.transaction(async (transaction) => {
|
||||||
|
const workflows = await WorkflowRepo.find({
|
||||||
|
filter: {
|
||||||
|
current: true,
|
||||||
|
},
|
||||||
|
appends: ['stats'],
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const workflow of workflows) {
|
||||||
|
if (!workflow.stats) {
|
||||||
|
const executed =
|
||||||
|
(await ExecutionRepo.count({
|
||||||
|
filter: {
|
||||||
|
key: workflow.key,
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
})) ||
|
||||||
|
workflow.allExecuted ||
|
||||||
|
0;
|
||||||
|
await workflow.createStats({ executed }, { transaction });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user