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:
sealday 2024-03-15 20:29:02 +08:00
commit edac378ae9
2 changed files with 64 additions and 30 deletions

View File

@ -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,

View File

@ -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,42 +19,76 @@ 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 items = {} as { [key: string]: { name: string; sort: number; out: number; in: number; total: number } }; });
records.forEach((record) => { const { sequelize } = ctx.db;
record.items.forEach((item) => { const { where, include } = filterParser.toSequelizeParams();
if (!items[item.product.name]) { const parsedFilterInclude =
items[item.product.name] = { include?.map((item) => {
name: item.product.name, if (fields.get(item.association)?.type === 'belongsToMany') {
sort: item.product.category.sort, 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 } };
records.forEach((item) => {
const product = allProducts.find((p) => p.id === item?.product_id);
if (!product) return;
if (!items[product.name]) {
items[product.name] = {
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) => ({ label: item.name,
label: item.name, value: {
value: { labels: ['出库数量', '入库数量', '小计'],
labels: ['出库数量', '入库数量', '小计'], values: [item.out, item.in, item.total],
values: [item.out, item.in, item.total], },
}, }));
})); }
} }
@Action('pdf') @Action('pdf')