Merge pull request 'feat: 汇总后端计算' (#395) from feat_group_backend into @hera/dev
Reviewed-on: daoyoucloud/tachycode#395 Reviewed-by: sealday <zhanglin@daoyoucloud.com>
This commit is contained in:
commit
edac378ae9
@ -47,6 +47,7 @@ export const GroupBlock = (props) => {
|
|||||||
url: requeatItem.fieldFormat.requestUrl,
|
url: requeatItem.fieldFormat.requestUrl,
|
||||||
params: {
|
params: {
|
||||||
filter: { ...filter },
|
filter: { ...filter },
|
||||||
|
collection: params.collection,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
requeatItem,
|
requeatItem,
|
||||||
|
@ -3,10 +3,9 @@ import { QueryTypes } from 'sequelize';
|
|||||||
import { RecordPdfService } from '../services/record-pdf-service';
|
import { RecordPdfService } from '../services/record-pdf-service';
|
||||||
import { SystemSettingService, SqlLoader } from '@hera/plugin-core';
|
import { SystemSettingService, SqlLoader } from '@hera/plugin-core';
|
||||||
import { Action, Controller, Inject } from '@nocobase/utils';
|
import { Action, Controller, Inject } from '@nocobase/utils';
|
||||||
import { Record } from '../../interfaces/record';
|
|
||||||
import { Movement } from '../../utils/constants';
|
import { Movement } from '../../utils/constants';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { FilterParser } from '@nocobase/database';
|
||||||
@Controller('records')
|
@Controller('records')
|
||||||
export class RecordPreviewController {
|
export class RecordPreviewController {
|
||||||
@Inject(() => SqlLoader)
|
@Inject(() => SqlLoader)
|
||||||
@ -20,33 +19,66 @@ export class RecordPreviewController {
|
|||||||
|
|
||||||
@Action('group')
|
@Action('group')
|
||||||
async group(ctx: Context) {
|
async group(ctx: Context) {
|
||||||
const filter = ctx.action.params.filter;
|
const { collection: collectionName, filter } = ctx.action.params;
|
||||||
const records = (await ctx.db
|
const collection = ctx.db.getCollection(collectionName);
|
||||||
.getRepository('records')
|
const fields = collection.fields;
|
||||||
.find({ filter, appends: ['items', 'items.product', 'items.product.category'], limit: 10 })) as Record[];
|
const filterParser = new FilterParser(filter, {
|
||||||
// 模拟计算
|
collection,
|
||||||
|
});
|
||||||
|
const { sequelize } = ctx.db;
|
||||||
|
const { where, include } = filterParser.toSequelizeParams();
|
||||||
|
const parsedFilterInclude =
|
||||||
|
include?.map((item) => {
|
||||||
|
if (fields.get(item.association)?.type === 'belongsToMany') {
|
||||||
|
item.through = { attributes: [] };
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}) || [];
|
||||||
|
const query = {
|
||||||
|
where: where || {},
|
||||||
|
attributes: [
|
||||||
|
[sequelize.fn('sum', sequelize.col('items.count')), 'count'],
|
||||||
|
[sequelize.col('items.product_id'), 'product_id'],
|
||||||
|
[sequelize.col('records.movement'), 'movement'],
|
||||||
|
],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'items',
|
||||||
|
attributes: [],
|
||||||
|
},
|
||||||
|
...parsedFilterInclude,
|
||||||
|
],
|
||||||
|
group: [sequelize.col('items.product_id'), sequelize.col('records.movement')],
|
||||||
|
order: [],
|
||||||
|
subQuery: false,
|
||||||
|
raw: true,
|
||||||
|
} as any;
|
||||||
|
const records = await ctx.db.getModel('records').findAll(query);
|
||||||
|
if (records) {
|
||||||
|
const allProducts = await ctx.db.getRepository('product').find({ appends: ['category'] });
|
||||||
|
if (!allProducts) return;
|
||||||
const items = {} as { [key: string]: { name: string; sort: number; out: number; in: number; total: number } };
|
const items = {} as { [key: string]: { name: string; sort: number; out: number; in: number; total: number } };
|
||||||
records.forEach((record) => {
|
records.forEach((item) => {
|
||||||
record.items.forEach((item) => {
|
const product = allProducts.find((p) => p.id === item?.product_id);
|
||||||
if (!items[item.product.name]) {
|
if (!product) return;
|
||||||
items[item.product.name] = {
|
if (!items[product.name]) {
|
||||||
name: item.product.name,
|
items[product.name] = {
|
||||||
sort: item.product.category.sort,
|
name: product.name,
|
||||||
|
sort: product.category.sort,
|
||||||
out: 0,
|
out: 0,
|
||||||
in: 0,
|
in: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const count = item.product.category.convertible ? item.count * item.product.ratio : item.count;
|
const count = product.category.convertible ? item.count * product.ratio : item.count;
|
||||||
if (record.movement === Movement.in) {
|
if (item.movement === Movement.in) {
|
||||||
items[item.product.name].in += count;
|
items[product.name].in += count;
|
||||||
items[item.product.name].total += count;
|
items[product.name].total += count;
|
||||||
} else {
|
} else {
|
||||||
items[item.product.name].out += count;
|
items[product.name].out += count;
|
||||||
items[item.product.name].total -= count;
|
items[product.name].total -= count;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
ctx.body = _.toArray(items)
|
ctx.body = _.toArray(items)
|
||||||
.sort((a, b) => a.sort - b.sort)
|
.sort((a, b) => a.sort - b.sort)
|
||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
@ -57,6 +89,7 @@ export class RecordPreviewController {
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Action('pdf')
|
@Action('pdf')
|
||||||
async printPreview(ctx: Context) {
|
async printPreview(ctx: Context) {
|
||||||
|
Loading…
Reference in New Issue
Block a user