import { Inject, Provide } from '@midwayjs/core'; import { InjectSaasCrud, SaasAction, SaasActionContext, SaasBusinessReject, SaasCrudCaller, SaasCrudService, SaasCrudServiceBase, } from '@cool-midway/module-runtime'; import { Actions, Crud, Events, type GoodsBatchInfoInput, type GoodsBatchInfoOutput, type GoodsInfoOutput, type GoodsReleaseStockInput, type GoodsReleaseStockOutput, type GoodsReserveStockInput, type GoodsReserveStockOutput, } from '../saas/generated'; @Provide() @SaasCrudService(Crud.Goods) export class GoodsService extends SaasCrudServiceBase { @InjectSaasCrud(Crud.Goods) private readonly goods!: SaasCrudCaller; @Inject() private readonly saasActionContext!: SaasActionContext; @SaasAction(Actions.GoodsBatchInfo) async batchInfo( input: GoodsBatchInfoInput ): Promise { const list: GoodsInfoOutput[] = []; for (const id of input.ids) { const goods = await this.findGoods(id); if (goods) list.push(goods); } return { list }; } @SaasAction(Actions.GoodsReserveStock) async reserveStock( input: GoodsReserveStockInput ): Promise { const goods = await this.requireGoods(input.goodsId); if (goods.status !== 1) { throw new SaasBusinessReject( 'GOODS_UNAVAILABLE', `商品 ${input.goodsId} 当前不可售` ); } if (goods.stock < input.quantity) { throw new SaasBusinessReject( 'INSUFFICIENT_STOCK', `商品 ${input.goodsId} 库存不足`, { available: goods.stock, requested: input.quantity } ); } const remainingStock = goods.stock - input.quantity; this.saasActionContext.raise(Events.DemoGoodsStockReserved, { goodsId: input.goodsId, quantity: input.quantity, remainingStock, }); await this.updateStock(input.goodsId, remainingStock); return { goodsId: input.goodsId, remainingStock }; } @SaasAction(Actions.GoodsReleaseStock) async releaseStock( input: GoodsReleaseStockInput ): Promise { const goods = await this.requireGoods(input.goodsId); const currentStock = goods.stock + input.quantity; this.saasActionContext.raise(Events.DemoGoodsStockReserved, { goodsId: input.goodsId, quantity: input.quantity, remainingStock: currentStock, }); await this.updateStock(input.goodsId, currentStock); return { goodsId: input.goodsId, currentStock }; } private async findGoods(goodsId: number): Promise { const rows = await this.goods.list({ where: { id: String(goodsId) }, take: 1, }); return rows[0] || null; } private async requireGoods(goodsId: number): Promise { const goods = await this.findGoods(goodsId); if (!goods) { throw new SaasBusinessReject( 'GOODS_NOT_FOUND', `商品 ${goodsId} 不存在` ); } return goods; } private async updateStock(goodsId: number, stock: number): Promise { const result = await this.goods.update({ id: String(goodsId), stock }); if (result.affected !== 1) { throw new SaasBusinessReject( 'GOODS_STOCK_UPDATE_FAILED', `商品 ${goodsId} 库存更新失败` ); } } }