mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat(plugin-workflow-aggregate): add precision option (#6491)
This commit is contained in:
parent
30c612cb08
commit
7da1c200ed
@ -22,7 +22,7 @@ export class BelongsToManyRepository extends MultipleRelationRepository {
|
||||
async aggregate(options: AggregateOptions) {
|
||||
const targetRepository = this.targetCollection.repository;
|
||||
|
||||
const sourceModel = await this.getSourceModel();
|
||||
const sourceModel = await this.getSourceModel(await this.getTransaction(options));
|
||||
|
||||
const association = this.association as any;
|
||||
|
||||
|
@ -387,6 +387,21 @@ export default class extends Instruction {
|
||||
},
|
||||
},
|
||||
},
|
||||
precision: {
|
||||
type: 'number',
|
||||
title: `{{t("Result precision", { ns: "${NAMESPACE}" })}}`,
|
||||
description: `{{t("Number of decimal places for query result.", { ns: "${NAMESPACE}" })}}`,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'InputNumber',
|
||||
'x-component-props': {
|
||||
min: 0,
|
||||
max: 14,
|
||||
step: 1,
|
||||
precision: 0,
|
||||
className: 'auto-width',
|
||||
},
|
||||
default: 2,
|
||||
},
|
||||
};
|
||||
scope = {
|
||||
useCollectionDataSource,
|
||||
|
@ -8,5 +8,7 @@
|
||||
"Data of associated collection": "关联数据表数据",
|
||||
"Field to aggregate": "聚合字段",
|
||||
"Distinct": "去重",
|
||||
"Query result": "查询结果"
|
||||
"Query result": "查询结果",
|
||||
"Result precision": "结果精度",
|
||||
"Number of decimal places for query result.": "查询结果小数位数"
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const aggregators = {
|
||||
|
||||
export default class extends Instruction {
|
||||
async run(node: FlowNodeModel, input, processor: Processor) {
|
||||
const { aggregator, associated, collection, association = {}, params = {} } = node.config;
|
||||
const { aggregator, associated, collection, association = {}, params = {}, precision = 2 } = node.config;
|
||||
const options = processor.getParsedValue(params, node.id);
|
||||
const [dataSourceName, collectionName] = parseCollectionName(collection);
|
||||
const { collectionManager } = this.workflow.app.dataSourceManager.dataSources.get(dataSourceName);
|
||||
@ -49,7 +49,10 @@ export default class extends Instruction {
|
||||
});
|
||||
|
||||
return {
|
||||
result: round((options.dataType === DataTypes.DOUBLE ? Number(result) : result) || 0, 14),
|
||||
result: round(
|
||||
(options.dataType === DataTypes.DOUBLE ? Number(result) : result) || 0,
|
||||
Math.max(0, Math.min(precision, 14)),
|
||||
),
|
||||
status: JOB_STATUS.RESOLVED,
|
||||
};
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ describe('workflow > instructions > aggregate', () => {
|
||||
TagRepo = db.getCollection('tags').repository;
|
||||
|
||||
workflow = await WorkflowModel.create({
|
||||
sync: true,
|
||||
enabled: true,
|
||||
type: 'collection',
|
||||
config: {
|
||||
@ -62,8 +63,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const post = await PostRepo.create({ values: { title: 't1' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [execution] = await workflow.getExecutions();
|
||||
const [job] = await execution.getJobs();
|
||||
expect(job.result).toBe(1);
|
||||
@ -86,8 +85,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const post = await PostRepo.create({ values: { title: 't1' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [execution] = await workflow.getExecutions();
|
||||
const [job] = await execution.getJobs();
|
||||
expect(job.result).toBe(0);
|
||||
@ -107,16 +104,12 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', read: 1 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(1);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', read: 2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(3);
|
||||
@ -136,22 +129,18 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', score: 0.1 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(0.1);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', score: 0.2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(0.3);
|
||||
});
|
||||
|
||||
it('sum number will be rounded', async () => {
|
||||
it('sum number will be rounded to 2 decimal places by default', async () => {
|
||||
const n1 = await workflow.createNode({
|
||||
type: 'aggregate',
|
||||
config: {
|
||||
@ -163,9 +152,59 @@ describe('workflow > instructions > aggregate', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', score: 0.100000000000001 } });
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', score: 0.123 } });
|
||||
|
||||
await sleep(500);
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(0.12);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', score: 0.456 } });
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(0.58);
|
||||
});
|
||||
|
||||
it('sum precision configured -1 as 0', async () => {
|
||||
const n1 = await workflow.createNode({
|
||||
type: 'aggregate',
|
||||
config: {
|
||||
aggregator: 'sum',
|
||||
collection: 'posts',
|
||||
params: {
|
||||
field: 'score',
|
||||
},
|
||||
precision: -1,
|
||||
},
|
||||
});
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', score: 0.123 } });
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(0);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', score: 0.456 } });
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(1);
|
||||
});
|
||||
|
||||
it('sum precision configured over 14 as 14', async () => {
|
||||
const n1 = await workflow.createNode({
|
||||
type: 'aggregate',
|
||||
config: {
|
||||
aggregator: 'sum',
|
||||
collection: 'posts',
|
||||
params: {
|
||||
field: 'score',
|
||||
},
|
||||
precision: 15,
|
||||
},
|
||||
});
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', score: 0.100000000000001 } });
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
@ -173,8 +212,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', score: 0.200000000000001 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(0.3);
|
||||
@ -194,8 +231,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(0);
|
||||
@ -215,16 +250,12 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', read: 1 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(1);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', read: 2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(1.5);
|
||||
@ -244,16 +275,12 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', read: 1 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(1);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', read: 2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(1);
|
||||
@ -273,16 +300,12 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', read: 1 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1] = await e1.getJobs();
|
||||
expect(j1.result).toBe(1);
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', read: 2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e2] = await workflow.getExecutions({ order: [['id', 'desc']] });
|
||||
const [j2] = await e2.getJobs();
|
||||
expect(j2.result).toBe(2);
|
||||
@ -333,8 +356,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1', comments: [{}, { status: 1 }] } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1, j2] = await e1.getJobs({ order: [['id', 'ASC']] });
|
||||
expect(j1.result).toBe(2);
|
||||
@ -343,7 +364,7 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
it('sum', async () => {
|
||||
const PostModel = db.getCollection('posts').model;
|
||||
const p1 = await PostModel.create({ title: 't1', read: 1 });
|
||||
const p1 = await PostModel.create({ title: 't1', read: 1 }, { hooks: false });
|
||||
|
||||
const n1 = await workflow.createNode({
|
||||
type: 'create',
|
||||
@ -400,8 +421,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
const p2 = await PostRepo.create({ values: { title: 't2', read: 2 } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [e1] = await workflow.getExecutions();
|
||||
const [j1, j2, j3] = await e1.getJobs({ order: [['id', 'ASC']] });
|
||||
expect(j2.result).toBe(3);
|
||||
@ -429,8 +448,6 @@ describe('workflow > instructions > aggregate', () => {
|
||||
|
||||
await PostRepo.create({ values: { title: 't1' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const [execution] = await workflow.getExecutions();
|
||||
expect(execution.status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
const [job] = await execution.getJobs();
|
||||
|
Loading…
x
Reference in New Issue
Block a user