diff --git a/src/app.module.ts b/src/app.module.ts index 71e2281..9f2b9e8 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -13,6 +13,7 @@ import { ConfigurationModule } from './configuration/configuration.module'; import { AdminModule } from './admin/admin.module'; import logger from './common/utils/logger'; import { Log4jsModule } from '@nestx-log4js/core'; +import { RedisModule } from 'nestjs-redis'; @Module({ @@ -31,26 +32,18 @@ import { Log4jsModule } from '@nestx-log4js/core'; }; }, }), - // RedisModule.forRootAsync({ - // imports: [ConfigModule], - // useFactory: (configService: ConfigService) => { - // const nodes = configService.get('redis.cluster.nodes'); - // if (nodes) { - // console.log('redis集群模式'); - // return { - // nodes: nodes, - // }; - // } else { - // console.log('redis普通模式'); - // return { - // host: configService.get('redis.host'), - // port: configService.get('redis.port'), - // password: configService.get('redis.password', undefined), - // }; - // } - // }, // or use async method - // inject: [ConfigService], - // }), + RedisModule.forRootAsync({ + imports: [ConfigModule], + useFactory: (configService: ConfigService) => { + console.log('redis普通模式'); + return { + host: configService.get('redis.host'), + port: configService.get('redis.port'), + password: configService.get('redis.password', undefined), + }; + }, // or use async method + inject: [ConfigService], + }), TypeOrmModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], diff --git a/src/chickens/chickens.controller.ts b/src/chickens/chickens.controller.ts index 0daf46a..d5e5296 100644 --- a/src/chickens/chickens.controller.ts +++ b/src/chickens/chickens.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { Controller, Get, Post, Body, Patch, Param, Delete, UsePipes, Query, UseInterceptors } from '@nestjs/common'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { CustomResult, SuccessResult } from 'src/common/utils/result-utils'; import { UserService } from 'src/user/user.service'; @@ -6,6 +6,12 @@ import { ChickensService } from './chickens.service'; import { CreateChickenDto } from './dto/create-chicken.dto'; import { UpdateChickenDto } from './dto/update-chicken.dto'; import { CODE } from '../common/code' +import { HttpValidationPipe } from 'src/common/utils/HttpValidationPipe'; +import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator'; +import { CacheService } from 'src/redis/redis'; +import { getUserTokenKey } from 'src/redis/keys'; +import { LoggingInterceptor } from 'src/common/utils/login.interceptor'; + @ApiTags('小鸡主体数据接口') @Controller('chickens') @@ -13,42 +19,53 @@ export class ChickensController { constructor( private readonly chickensService: ChickensService, private readonly userService: UserService, + private readonly cacheService: CacheService, ) { } //领取小鸡 @ApiOperation({ summary: '领取小鸡' }) - @Post() - async create(@Body() createChickenDto: CreateChickenDto) { - //用户数据初始化 - const initUser = await this.userService.init(createChickenDto) - if (!initUser) return CustomResult(CODE.CODE_INIT_USER_ERR); + @UsePipes(new HttpValidationPipe()) + @ApiImplicitQuery({ + name: 'userid', + required: true, + description: '当前用户ID', + type: Number, + }) + @Get('draw') + async create(@Query('userid') userid: number) { //小鸡数据初始化 - createChickenDto.schedule = 0; - createChickenDto.eat_start = 0; - createChickenDto.eat_end = 0; - createChickenDto.eat_time = 0; - const init = this.chickensService.create(createChickenDto); + let createChickenDto: CreateChickenDto = { + userid: Number(userid), + token: await this.cacheService.get(getUserTokenKey(userid)), + schedule: 0, + eat_start: 0, + eat_end: 0, + eat_time: 0, + }; + //用户数据初始化,有信息则返回 + const initUser = await this.userService.initQuery(createChickenDto) + if (!initUser || initUser.code != 200) return CustomResult(CODE.CODE_INIT_USER_ERR); + + const init = await this.chickensService.create(createChickenDto); if (!init) return CustomResult(CODE.CODE_INIT_PLAYER_ERR); - return SuccessResult(true); + return SuccessResult(init); } - // @Get() - // findAll() { - // return this.chickensService.findAll(); - // } + //小鸡信息查询 + @ApiOperation({ summary: '小鸡信息查询' }) + @UsePipes(new HttpValidationPipe()) + @UseInterceptors(LoggingInterceptor) + @ApiImplicitQuery({ + name: 'userid', + required: true, + description: '当前用户ID', + type: Number, + }) + @Get() + async query(@Query('userid') userid: number) { + //小鸡数据初始化 + const res = await this.chickensService.chickensInfo(userid); + return SuccessResult(res); + } - // @Get(':id') - // findOne(@Param('id') id: string) { - // return this.chickensService.findOne(+id); - // } - - // @Patch(':id') - // update(@Param('id') id: string, @Body() updateChickenDto: UpdateChickenDto) { - // return this.chickensService.update(+id, updateChickenDto); - // } - - // @Delete(':id') - // remove(@Param('id') id: string) { - // return this.chickensService.remove(+id); - // } } diff --git a/src/chickens/chickens.module.ts b/src/chickens/chickens.module.ts index 1ec7fd7..a6e4c07 100644 --- a/src/chickens/chickens.module.ts +++ b/src/chickens/chickens.module.ts @@ -4,14 +4,17 @@ import { ChickensController } from './chickens.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ChickenEntity } from './entities/chicken.entity'; import { UserModule } from 'src/user/user.module'; +import { CacheService } from 'src/redis/redis'; +import { OrderlogService } from 'src/orderlog/orderlog.service'; +import { OrderlogEntity } from 'src/orderlog/entities/orderlog.entity'; @Module({ imports: [ - TypeOrmModule.forFeature([ChickenEntity]), + TypeOrmModule.forFeature([ChickenEntity,OrderlogEntity]), UserModule, ], controllers: [ChickensController], exports: [ChickensService], - providers: [ChickensService] + providers: [ChickensService, CacheService,OrderlogService] }) export class ChickensModule { } diff --git a/src/chickens/chickens.service.ts b/src/chickens/chickens.service.ts index 6499957..3e26900 100644 --- a/src/chickens/chickens.service.ts +++ b/src/chickens/chickens.service.ts @@ -1,29 +1,42 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import { CODE } from 'src/common/code'; +import { CustomResult } from 'src/common/utils/result-utils'; +import { OrderlogService } from 'src/orderlog/orderlog.service'; import { Repository } from 'typeorm'; import { CreateChickenDto } from './dto/create-chicken.dto'; import { UpdateChickenDto } from './dto/update-chicken.dto'; import { ChickenEntity } from './entities/chicken.entity'; +const prefix = 'chick'; @Injectable() export class ChickensService { constructor( @InjectRepository(ChickenEntity) - private readonly chickensRepository: Repository + private readonly chickensRepository: Repository, + private readonly orderService: OrderlogService ) { } /**插入数据 */ async create(createChickenDto: CreateChickenDto) { + const info = await this.chickensInfo(createChickenDto.userid); + if (info) return info; createChickenDto.create_time = new Date(); return await this.chickensRepository.save(createChickenDto); } - findAll() { - return `This action returns all chickens`; - } - - findOne(id: number) { - return `This action returns a #${id} chicken`; + /** 查询小鸡信息 */ + async chickensInfo(userid: number) { + //小鸡信息 + const info = await this.chickensRepository.createQueryBuilder(prefix) + .select().where(`userid=:userid`, { userid: userid }).getRawOne(); + console.log(info); + if (!info) return CustomResult(CODE.CODE_PLAYER_INFO_ERR); + //小鸡穿戴套装信息 + if (info.chick_ck_suitid == 0) info['suit_info'] = {}; + const suit = await this.orderService.paidGoodsInfo(info.chick_suitid, info.chick_userid); + console.log(suit); + return info; } update(id: number, updateChickenDto: UpdateChickenDto) { diff --git a/src/chickens/dto/create-chicken.dto.ts b/src/chickens/dto/create-chicken.dto.ts index 0c7895c..dbabf4f 100644 --- a/src/chickens/dto/create-chicken.dto.ts +++ b/src/chickens/dto/create-chicken.dto.ts @@ -3,7 +3,7 @@ import { IsNotEmpty, IsNumber, IsString } from "class-validator"; export class CreateChickenDto { @IsNotEmpty({ message: '用户ID不能为空' }) @IsNumber() - uid: number; + userid: number; @IsString() token: string; diff --git a/src/chickens/entities/chicken.entity.ts b/src/chickens/entities/chicken.entity.ts index 83ab259..a965d25 100644 --- a/src/chickens/entities/chicken.entity.ts +++ b/src/chickens/entities/chicken.entity.ts @@ -7,11 +7,11 @@ export class ChickenEntity { @PrimaryGeneratedColumn() id?: number; - @Column({ comment: '套装ID', type: 'int', default: 0 }) - suitid: number; + @Column({ comment: '用户ID', type: 'int', default: 0, unique: true }) + userid: number; - @Column({ comment: '背景ID', type: 'int', default: 0 }) - backdropid: number; + @Column({ comment: '套装订单ID', type: 'varchar', default: '' }) + suitid: string; @Column({ comment: '碗中剩余饲料', type: 'bigint', default: 0 }) surplus_fodder: number; diff --git a/src/common/code.ts b/src/common/code.ts index fc5eddc..bc52b99 100644 --- a/src/common/code.ts +++ b/src/common/code.ts @@ -20,6 +20,8 @@ export const CODE = { CODE_APPUSER_COIN_NOT_ENOUGHT_ERR: { code: 606, message: '用户余额不足!' }, /**扣减用户APP余额失败 */ CODE_APPUSER_SUB_COIN_ERR: { code: 606, message: '扣减用户APP余额失败!' }, + /**购买中,请稍后... */ + CODE_USER_PAY_LOCK_ERR: { code: 607, message: '购买中,请稍后...' }, /** 商品信息异常code */ @@ -36,4 +38,8 @@ export const CODE = { /** 订单信息异常code */ CODE_ORDER_INSERT_ERR: { code: 801, message: '订单创建失败!' }, + + /** 小鸡信息异常code */ + /**用户数据查询失败 */ + CODE_PLAYER_INFO_ERR: { code: 902, message: '小鸡数据查询失败!' }, }; \ No newline at end of file diff --git a/src/common/const.ts b/src/common/const.ts index 90741c1..0b81be9 100644 --- a/src/common/const.ts +++ b/src/common/const.ts @@ -34,4 +34,4 @@ export enum ParentReceiveStatus { RECEIVED = 'received',//售卖结束 UNRECEIVE = 'unreceive',//隐藏 WAIT_RECEIVE = 'wait_receive',//隐藏 -} \ No newline at end of file +} diff --git a/src/common/utils/login.interceptor.ts b/src/common/utils/login.interceptor.ts new file mode 100644 index 0000000..766afac --- /dev/null +++ b/src/common/utils/login.interceptor.ts @@ -0,0 +1,29 @@ +import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus } from '@nestjs/common'; +import { Observable, throwError } from 'rxjs'; +import { getUserTokenKey } from 'src/redis/keys'; +import { CacheService } from 'src/redis/redis'; + +@Injectable() +export class LoggingInterceptor implements NestInterceptor { + constructor( + private readonly cacheRedis: CacheService + ) { } + async intercept(context: ExecutionContext, next: CallHandler): Promise> { + const ctx = context.switchToHttp(); + const request = ctx.getRequest(); + + const userid = request.query.userid; + + const token = await this.cacheRedis.get(getUserTokenKey(userid)); + console.log(token) + const now = Date.now(); + if (!token) { + return throwError(new HttpException('登录信息错误', HttpStatus.SEE_OTHER)) + } + return next + .handle() + .pipe( + // tap(() => console.log(`After... ${Date.now() - now}ms`)), + ); + } +} diff --git a/src/common/utils/result-utils.ts b/src/common/utils/result-utils.ts index f693589..8edb3b9 100644 --- a/src/common/utils/result-utils.ts +++ b/src/common/utils/result-utils.ts @@ -26,7 +26,7 @@ export function DataListResult(data: any[], pageIndex: number, pageSize: number, * @message 错误信息 */ export function CustomResult(params: { code: number, message: string }) { - return { code: params.code, message: params.message }; + return { code: params.code, data: '', message: params.message }; // throw new HttpException({ // code: params.code, // error: params.message, diff --git a/src/config/config.yml b/src/config/config.yml index 08facbd..c6cff3b 100644 --- a/src/config/config.yml +++ b/src/config/config.yml @@ -7,4 +7,9 @@ database: drop_schema: false #启动程序时全部删除并重建数据表(生产环境严禁启用) charset: utf8mb4 #数据库编码 synchronize: true #自动同步表结构 -port: 8888 \ No newline at end of file +port: 8888 + +redis: + host: '127.0.0.1' + port: 6379 + password: '' \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 02d0b64..363349e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,10 +6,10 @@ import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); + const configService = app.get(ConfigService); const httpPort = configService.get('port'); console.log(`Linsten port http://192.168.60.11:${httpPort}`); - //swagger const options = new DocumentBuilder() .setTitle('【 API 】小鸡游戏接口') diff --git a/src/orderlog/orderlog.controller.ts b/src/orderlog/orderlog.controller.ts index 3f9bd0f..fa2ae0f 100644 --- a/src/orderlog/orderlog.controller.ts +++ b/src/orderlog/orderlog.controller.ts @@ -14,15 +14,6 @@ export class OrderlogController { return this.orderlogService.create(createOrderlogDto); } - @Get() - findAll() { - return this.orderlogService.findAll(); - } - - @Get(':id') - findOne(@Param('id') id: string) { - return this.orderlogService.findOne(+id); - } @Patch(':id') update(@Param('id') id: string, @Body() updateOrderlogDto: UpdateOrderlogDto) { diff --git a/src/orderlog/orderlog.module.ts b/src/orderlog/orderlog.module.ts index ac2ab75..69433e0 100644 --- a/src/orderlog/orderlog.module.ts +++ b/src/orderlog/orderlog.module.ts @@ -3,11 +3,13 @@ import { OrderlogService } from './orderlog.service'; import { OrderlogController } from './orderlog.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { OrderlogEntity } from './entities/orderlog.entity'; +import { ChickensService } from 'src/chickens/chickens.service'; +import { ChickenEntity } from 'src/chickens/entities/chicken.entity'; @Module({ - imports: [TypeOrmModule.forFeature([OrderlogEntity])], + imports: [TypeOrmModule.forFeature([OrderlogEntity,ChickenEntity])], controllers: [OrderlogController], exports: [OrderlogService], - providers: [OrderlogService] + providers: [OrderlogService,ChickensService] }) export class OrderlogModule { } diff --git a/src/orderlog/orderlog.service.ts b/src/orderlog/orderlog.service.ts index 01e4ceb..a7080a5 100644 --- a/src/orderlog/orderlog.service.ts +++ b/src/orderlog/orderlog.service.ts @@ -7,6 +7,7 @@ import { CreateOrderlogDto } from './dto/create-orderlog.dto'; import { UpdateOrderlogDto } from './dto/update-orderlog.dto'; import { OrderlogEntity } from './entities/orderlog.entity'; +const prefix = 'order'; @Injectable() export class OrderlogService { constructor( @@ -24,12 +25,11 @@ export class OrderlogService { return CustomResult(CODE.CODE_ORDER_INSERT_ERR); } - findAll() { - return `This action returns all orderlog`; - } - - findOne(id: number) { - return `This action returns a #${id} orderlog`; + /**API查询购买的商品订单详情信息 */ + async paidGoodsInfo(orderid: string, userid: number) { + const orderGoods = await this.orderLogRepository.createQueryBuilder(prefix) + .select().where(`orderid=:orderid AND userid=:userid`, { orderid: orderid, userid: userid }).getRawOne(); + return orderGoods; } update(id: number, updateOrderlogDto: UpdateOrderlogDto) { diff --git a/src/redis/cache.ts b/src/redis/cache.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/redis/keys.ts b/src/redis/keys.ts new file mode 100644 index 0000000..901c1ba --- /dev/null +++ b/src/redis/keys.ts @@ -0,0 +1,9 @@ +/** 获取用户token key*/ +export function getUserTokenKey(userId: number): string { + return 'ckgame:user:token:' + userId; +} + +/**用户购物锁key */ +export function getUserShoppingKey(userId: number, goodsId: number): string { + return 'ckgame:user:shopping:' + userId + '_' + goodsId; +} \ No newline at end of file diff --git a/src/redis/redis.ts b/src/redis/redis.ts new file mode 100644 index 0000000..3c24336 --- /dev/null +++ b/src/redis/redis.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@nestjs/common'; +import { RedisService } from 'nestjs-redis'; +@Injectable() +export class CacheService { + public client; + constructor(private redisService: RedisService) { + this.getClient(); + } + async getClient() { + this.client = this.redisService.getClient() + } + + //设置值的方法 + async set(key: string, value: any, seconds?: number) { + value = JSON.stringify(value); + if (!this.client) { + await this.getClient(); + } + if (!seconds) { + await this.client.set(key, value); + } else { + await this.client.set(key, value, 'EX', seconds); + } + } + + //获取值的方法 + async get(key: string) { + if (!this.client) { + await this.getClient(); + } + var data = await this.client.get(key); + if (!data) return; + return JSON.parse(data); + } +} \ No newline at end of file diff --git a/src/user/dto/buygoods-user.dto.ts b/src/user/dto/buygoods-user.dto.ts index b9abb95..a569e2c 100644 --- a/src/user/dto/buygoods-user.dto.ts +++ b/src/user/dto/buygoods-user.dto.ts @@ -5,10 +5,6 @@ export class BuyGoodsUserDto { @IsInt() userid: number; - @IsNotEmpty({ message: '用户token不能为空' }) - @IsString() - token: string; - @IsNotEmpty({ message: '用户购买商品ID不能为空' }) @IsInt() goodsid: number; diff --git a/src/user/dto/create-user.dto.ts b/src/user/dto/create-user.dto.ts index 677146d..2c8662e 100644 --- a/src/user/dto/create-user.dto.ts +++ b/src/user/dto/create-user.dto.ts @@ -5,5 +5,5 @@ export class CreateUserDto { token: string; @ApiProperty() - uid: number; + userid: number; } diff --git a/src/user/entities/user.entity.ts b/src/user/entities/user.entity.ts index fbb4cae..52f861e 100644 --- a/src/user/entities/user.entity.ts +++ b/src/user/entities/user.entity.ts @@ -29,28 +29,8 @@ export class UserEntity { }) online_status: string; - // @Column({ comment: '上级用户ID', type: 'bigint' }) - // parent_id: number; - - // @Column({ comment: '父级从中获取钻石数量', type: 'bigint' }) - // parent_gain: number; - - // @Column({ - // comment: '钻石领取状态(none-无;received-已领取;unreceive-未领取;wait_receive-n天后领取)', - // type: "enum", - // enum: ParentReceiveStatus, - // default: ParentReceiveStatus.NONE - // }) - // parent_gain_status: string; - - // @Column({ comment: '父级盈利领取时间', type: 'varchar', default: '' }) - // parent_gain_time: string; - - // @Column({ comment: '父级盈利失败原因', type: 'varchar', default: '' }) - // parent_gain_reason: string; - - // @Column({ comment: 'APP注册时间', type: 'varchar', default: '' }) - // register_time: string; + @Column({ comment: '背景订单ID', type: 'varchar', default: '' }) + backdropid: string; @CreateDateColumn({ comment: '游戏玩家信息创建时间', type: 'timestamp' }) create_time: Date; diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index 0dda135..18e4ffd 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -6,6 +6,7 @@ import { SuccessResult } from 'src/common/utils/result-utils'; import { HttpValidationPipe } from 'src/common/utils/HttpValidationPipe'; import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator'; import { BuyGoodsUserDto } from './dto/buygoods-user.dto'; +import { CreateUserDto } from './dto/create-user.dto'; @ApiTags('用户数据接口') @Controller('user') @@ -15,9 +16,23 @@ export class UserController { //查询用户信息 @ApiOperation({ summary: '用户信息查询' }) - @Get(':userid') - async findOne(@Param('userid') userid: number) { - return SuccessResult(await this.userService.findOne(userid)); + @ApiImplicitQuery({ + name: 'userid', + required: true, + description: '当前用户ID', + type: Number, + }) + @ApiImplicitQuery({ + name: 'userid', + required: true, + description: '当前用户ID', + type: Number, + }) + @Get('user_info') + async userInfoQuery( + @Query() createUserDto: CreateUserDto, + ) { + return await this.userService.initQuery(createUserDto); } //更新用户在线状态 @@ -34,11 +49,12 @@ export class UserController { return this.userService.update(+userid, updateUserDto); } - //TODO 购买商品 + //购买商品 @ApiOperation({ summary: '购买商品' }) @UsePipes(new HttpValidationPipe()) @Post('buy') async buy(@Body() buyGoodsUserDto: BuyGoodsUserDto) { return await this.userService.buy(buyGoodsUserDto); } + } diff --git a/src/user/user.module.ts b/src/user/user.module.ts index 6b0b887..1eac3bd 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -8,6 +8,7 @@ import { GoodsEntity } from 'src/goods/entities/good.entity'; import { OrderlogEntity } from 'src/orderlog/entities/orderlog.entity'; import { OrderlogService } from 'src/orderlog/orderlog.service'; import { ConfigModule } from '@nestjs/config'; +import { CacheService } from 'src/redis/redis'; @Module({ imports: [ @@ -16,6 +17,6 @@ import { ConfigModule } from '@nestjs/config'; ], controllers: [UserController], exports: [UserService], - providers: [UserService, GoodsService, OrderlogService] + providers: [UserService, GoodsService, OrderlogService,CacheService] }) export class UserModule { } diff --git a/src/user/user.service.ts b/src/user/user.service.ts index eb06c67..17ea307 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -1,12 +1,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { CODE } from 'src/common/code'; -import { GoodsStatus, UserOnlieStatus } from 'src/common/const'; +import { GoodsStatus, GoodsTypes, UserOnlieStatus } from 'src/common/const'; import { ExternalApiService } from 'src/common/utils/external-api'; -import { CustomResult, SuccessResult } from 'src/common/utils/result-utils'; +import { CustomResult, DataResultModel, SuccessResult } from 'src/common/utils/result-utils'; import { GoodsService } from 'src/goods/goods.service'; import { CreateOrderlogDto } from 'src/orderlog/dto/create-orderlog.dto'; import { OrderlogService } from 'src/orderlog/orderlog.service'; +import { getUserShoppingKey, getUserTokenKey } from 'src/redis/keys'; +import { CacheService } from 'src/redis/redis'; import { Repository } from 'typeorm'; import { BuyGoodsUserDto } from './dto/buygoods-user.dto'; import { CreateUserDto } from './dto/create-user.dto'; @@ -22,23 +24,26 @@ export class UserService { @InjectRepository(UserEntity) private readonly userRepository: Repository, private readonly goodsService: GoodsService, - private readonly orderLogService: OrderlogService + private readonly orderLogService: OrderlogService, + private readonly cacheService: CacheService, ) { } /**查询用户信息,没有则初始化 */ - async init(createUserDto: CreateUserDto) { + async initQuery(createUserDto: CreateUserDto): Promise { + //初始化token + await this.initToken(createUserDto); //查询用户信息 - const userInfo = await this.findOne(createUserDto.uid); + const userInfo = await this.findOne(createUserDto.userid); + if (userInfo) return SuccessResult(userInfo); //有信息则返回 - const appUserInfo = await ExternalApiService.getAppUserInfo(createUserDto.uid, createUserDto.token); - if (userInfo) return userInfo; + const appUserInfo = await ExternalApiService.getAppUserInfo(createUserDto.userid, createUserDto.token); //用户信息异常处理 - if (!appUserInfo || appUserInfo.code != 200) return CustomResult(CODE.CODE_USER_INFO_ERR); + if (!appUserInfo || appUserInfo.code != 200) return appUserInfo; //没有信息则初始化 - const initRes = await this.initUser(appUserInfo); + const initRes = await this.initUser(appUserInfo.data); if (!initRes) return CustomResult(CODE.CODE_INIT_USER_ERR); - return initRes; + return SuccessResult(initRes); } /**用户信息初始化 */ private async initUser(appUser: AppUserModel) { @@ -56,6 +61,7 @@ export class UserService { return await this.userRepository.save(entity); } + /**查询用户信息 */ async findOne(userid: number) { const info = await this.userRepository.createQueryBuilder(prefix) @@ -65,6 +71,17 @@ export class UserService { return info; } + /**用户token初始化 */ + async initToken(createUserDto: CreateUserDto) { + const tokenKey = getUserTokenKey(createUserDto.userid); + //查询Redis token 信息 + const tokenInfo = await this.cacheService.get(tokenKey); + if (tokenInfo) return SuccessResult(tokenInfo); + //存储Redis + await this.cacheService.set(tokenKey, createUserDto.token); + return SuccessResult(createUserDto.token); + } + /**更新用户数据 */ async update(userid: number, updateUserDto: UpdateUserDto) { updateUserDto.update_time = new Date(); @@ -80,7 +97,8 @@ export class UserService { /** 用户购买商品逻辑 */ async buy(buyGoodsUserDto: BuyGoodsUserDto) { //查询APP用户信息 - const appUserInfo = await ExternalApiService.getAppUserInfo(buyGoodsUserDto.userid, buyGoodsUserDto.token); + const token = await this.cacheService.get(getUserTokenKey(buyGoodsUserDto.userid)); + const appUserInfo = await ExternalApiService.getAppUserInfo(buyGoodsUserDto.userid, token); if (appUserInfo?.code != 200) return appUserInfo; const user = appUserInfo.data; @@ -93,11 +111,16 @@ export class UserService { const payCoin = goods.goods_price * buyGoodsUserDto.goods_count;//应支付价格 if (user.coin < payCoin) return CustomResult(CODE.CODE_APPUSER_COIN_NOT_ENOUGHT_ERR); - //TODO 扣减加锁 锁几秒 + //扣减加锁 锁几秒 + const locKeys = getUserShoppingKey(buyGoodsUserDto.userid, buyGoodsUserDto.goodsid); + const queryLock = await this.cacheService.get(locKeys); + if (queryLock) return CustomResult(CODE.CODE_USER_PAY_LOCK_ERR); + await this.cacheService.set(locKeys, true, 5); //用户金额扣减 - const subUserInfo = await ExternalApiService.subAppUserCoin(buyGoodsUserDto.userid, buyGoodsUserDto.token, payCoin); - console.log('扣减后用户信息',subUserInfo); + const subUserInfo = await ExternalApiService.subAppUserCoin(buyGoodsUserDto.userid, token, payCoin); + + if (subUserInfo?.code != 200) return CustomResult(CODE.CODE_APPUSER_SUB_COIN_ERR); //发放完成记录日志 const orderInfo: CreateOrderlogDto = { @@ -107,12 +130,11 @@ export class UserService { goods_price: goods.goods_price, goods_attribute: goods.goods_attribute } - // const orderRes = await this.orderLogService.create(orderInfo); - // logger.debug(`购买订单日志结果: ${JSON.stringify(orderRes)}`); - // if (orderRes.code != 200) return CustomResult(CODE.CODE_GOODS_DEAL_ERR); + const orderRes = await this.orderLogService.create(orderInfo); + logger.debug(`购买订单日志结果: ${JSON.stringify(orderRes)}`); + if (orderRes.code != 200) return CustomResult(CODE.CODE_GOODS_DEAL_ERR); - return appUserInfo; - return SuccessResult(); + return SuccessResult(orderRes.data); }