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, | ||||
|               params: { | ||||
|                 filter: { ...filter }, | ||||
|                 collection: params.collection, | ||||
|               }, | ||||
|             }), | ||||
|             requeatItem, | ||||
|  | ||||
| @ -3,10 +3,9 @@ import { QueryTypes } from 'sequelize'; | ||||
| import { RecordPdfService } from '../services/record-pdf-service'; | ||||
| import { SystemSettingService, SqlLoader } from '@hera/plugin-core'; | ||||
| import { Action, Controller, Inject } from '@nocobase/utils'; | ||||
| import { Record } from '../../interfaces/record'; | ||||
| import { Movement } from '../../utils/constants'; | ||||
| import _ from 'lodash'; | ||||
| 
 | ||||
| import { FilterParser } from '@nocobase/database'; | ||||
| @Controller('records') | ||||
| export class RecordPreviewController { | ||||
|   @Inject(() => SqlLoader) | ||||
| @ -20,42 +19,76 @@ export class RecordPreviewController { | ||||
| 
 | ||||
|   @Action('group') | ||||
|   async group(ctx: Context) { | ||||
|     const filter = ctx.action.params.filter; | ||||
|     const records = (await ctx.db | ||||
|       .getRepository('records') | ||||
|       .find({ filter, appends: ['items', 'items.product', 'items.product.category'], limit: 10 })) as Record[]; | ||||
|     // 模拟计算
 | ||||
|     const items = {} as { [key: string]: { name: string; sort: number; out: number; in: number; total: number } }; | ||||
|     records.forEach((record) => { | ||||
|       record.items.forEach((item) => { | ||||
|         if (!items[item.product.name]) { | ||||
|           items[item.product.name] = { | ||||
|             name: item.product.name, | ||||
|             sort: item.product.category.sort, | ||||
|     const { collection: collectionName, filter } = ctx.action.params; | ||||
|     const collection = ctx.db.getCollection(collectionName); | ||||
|     const fields = collection.fields; | ||||
|     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 } }; | ||||
|       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, | ||||
|             in: 0, | ||||
|             total: 0, | ||||
|           }; | ||||
|         } | ||||
|         const count = item.product.category.convertible ? item.count * item.product.ratio : item.count; | ||||
|         if (record.movement === Movement.in) { | ||||
|           items[item.product.name].in += count; | ||||
|           items[item.product.name].total += count; | ||||
|         const count = product.category.convertible ? item.count * product.ratio : item.count; | ||||
|         if (item.movement === Movement.in) { | ||||
|           items[product.name].in += count; | ||||
|           items[product.name].total += count; | ||||
|         } else { | ||||
|           items[item.product.name].out += count; | ||||
|           items[item.product.name].total -= count; | ||||
|           items[product.name].out += count; | ||||
|           items[product.name].total -= count; | ||||
|         } | ||||
|       }); | ||||
|     }); | ||||
|     ctx.body = _.toArray(items) | ||||
|       .sort((a, b) => a.sort - b.sort) | ||||
|       .map((item) => ({ | ||||
|         label: item.name, | ||||
|         value: { | ||||
|           labels: ['出库数量', '入库数量', '小计'], | ||||
|           values: [item.out, item.in, item.total], | ||||
|         }, | ||||
|       })); | ||||
|       ctx.body = _.toArray(items) | ||||
|         .sort((a, b) => a.sort - b.sort) | ||||
|         .map((item) => ({ | ||||
|           label: item.name, | ||||
|           value: { | ||||
|             labels: ['出库数量', '入库数量', '小计'], | ||||
|             values: [item.out, item.in, item.total], | ||||
|           }, | ||||
|         })); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @Action('pdf') | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user