小鸡初始化等

This commit is contained in:
Administrator 2021-05-12 21:30:19 +08:00
parent 2ffebb8f48
commit 50556a4936
24 changed files with 254 additions and 136 deletions

View File

@ -13,6 +13,7 @@ import { ConfigurationModule } from './configuration/configuration.module';
import { AdminModule } from './admin/admin.module'; import { AdminModule } from './admin/admin.module';
import logger from './common/utils/logger'; import logger from './common/utils/logger';
import { Log4jsModule } from '@nestx-log4js/core'; import { Log4jsModule } from '@nestx-log4js/core';
import { RedisModule } from 'nestjs-redis';
@Module({ @Module({
@ -31,26 +32,18 @@ import { Log4jsModule } from '@nestx-log4js/core';
}; };
}, },
}), }),
// RedisModule.forRootAsync({ RedisModule.forRootAsync({
// imports: [ConfigModule], imports: [ConfigModule],
// useFactory: (configService: ConfigService) => { useFactory: (configService: ConfigService) => {
// const nodes = configService.get('redis.cluster.nodes'); console.log('redis普通模式');
// if (nodes) { return {
// console.log('redis集群模式'); host: configService.get('redis.host'),
// return { port: configService.get('redis.port'),
// nodes: nodes, password: configService.get('redis.password', undefined),
// }; };
// } else { }, // or use async method
// console.log('redis普通模式'); inject: [ConfigService],
// 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({ TypeOrmModule.forRootAsync({
imports: [ConfigModule], imports: [ConfigModule],
inject: [ConfigService], inject: [ConfigService],

View File

@ -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 { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CustomResult, SuccessResult } from 'src/common/utils/result-utils'; import { CustomResult, SuccessResult } from 'src/common/utils/result-utils';
import { UserService } from 'src/user/user.service'; import { UserService } from 'src/user/user.service';
@ -6,6 +6,12 @@ import { ChickensService } from './chickens.service';
import { CreateChickenDto } from './dto/create-chicken.dto'; import { CreateChickenDto } from './dto/create-chicken.dto';
import { UpdateChickenDto } from './dto/update-chicken.dto'; import { UpdateChickenDto } from './dto/update-chicken.dto';
import { CODE } from '../common/code' 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('小鸡主体数据接口') @ApiTags('小鸡主体数据接口')
@Controller('chickens') @Controller('chickens')
@ -13,42 +19,53 @@ export class ChickensController {
constructor( constructor(
private readonly chickensService: ChickensService, private readonly chickensService: ChickensService,
private readonly userService: UserService, private readonly userService: UserService,
private readonly cacheService: CacheService,
) { } ) { }
//领取小鸡 //领取小鸡
@ApiOperation({ summary: '领取小鸡' }) @ApiOperation({ summary: '领取小鸡' })
@Post() @UsePipes(new HttpValidationPipe())
async create(@Body() createChickenDto: CreateChickenDto) { @ApiImplicitQuery({
//用户数据初始化 name: 'userid',
const initUser = await this.userService.init(createChickenDto) required: true,
if (!initUser) return CustomResult(CODE.CODE_INIT_USER_ERR); description: '当前用户ID',
type: Number,
})
@Get('draw')
async create(@Query('userid') userid: number) {
//小鸡数据初始化 //小鸡数据初始化
createChickenDto.schedule = 0; let createChickenDto: CreateChickenDto = {
createChickenDto.eat_start = 0; userid: Number(userid),
createChickenDto.eat_end = 0; token: await this.cacheService.get(getUserTokenKey(userid)),
createChickenDto.eat_time = 0; schedule: 0,
const init = this.chickensService.create(createChickenDto); 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); if (!init) return CustomResult(CODE.CODE_INIT_PLAYER_ERR);
return SuccessResult(true); return SuccessResult(init);
} }
// @Get() //小鸡信息查询
// findAll() { @ApiOperation({ summary: '小鸡信息查询' })
// return this.chickensService.findAll(); @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);
// }
} }

View File

@ -4,14 +4,17 @@ import { ChickensController } from './chickens.controller';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { ChickenEntity } from './entities/chicken.entity'; import { ChickenEntity } from './entities/chicken.entity';
import { UserModule } from 'src/user/user.module'; 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({ @Module({
imports: [ imports: [
TypeOrmModule.forFeature([ChickenEntity]), TypeOrmModule.forFeature([ChickenEntity,OrderlogEntity]),
UserModule, UserModule,
], ],
controllers: [ChickensController], controllers: [ChickensController],
exports: [ChickensService], exports: [ChickensService],
providers: [ChickensService] providers: [ChickensService, CacheService,OrderlogService]
}) })
export class ChickensModule { } export class ChickensModule { }

View File

@ -1,29 +1,42 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; 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 { Repository } from 'typeorm';
import { CreateChickenDto } from './dto/create-chicken.dto'; import { CreateChickenDto } from './dto/create-chicken.dto';
import { UpdateChickenDto } from './dto/update-chicken.dto'; import { UpdateChickenDto } from './dto/update-chicken.dto';
import { ChickenEntity } from './entities/chicken.entity'; import { ChickenEntity } from './entities/chicken.entity';
const prefix = 'chick';
@Injectable() @Injectable()
export class ChickensService { export class ChickensService {
constructor( constructor(
@InjectRepository(ChickenEntity) @InjectRepository(ChickenEntity)
private readonly chickensRepository: Repository<ChickenEntity> private readonly chickensRepository: Repository<ChickenEntity>,
private readonly orderService: OrderlogService
) { } ) { }
/**插入数据 */ /**插入数据 */
async create(createChickenDto: CreateChickenDto) { async create(createChickenDto: CreateChickenDto) {
const info = await this.chickensInfo(createChickenDto.userid);
if (info) return info;
createChickenDto.create_time = new Date(); createChickenDto.create_time = new Date();
return await this.chickensRepository.save(createChickenDto); return await this.chickensRepository.save(createChickenDto);
} }
findAll() { /** 查询小鸡信息 */
return `This action returns all chickens`; async chickensInfo(userid: number) {
} //小鸡信息
const info = await this.chickensRepository.createQueryBuilder(prefix)
findOne(id: number) { .select().where(`userid=:userid`, { userid: userid }).getRawOne();
return `This action returns a #${id} chicken`; 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) { update(id: number, updateChickenDto: UpdateChickenDto) {

View File

@ -3,7 +3,7 @@ import { IsNotEmpty, IsNumber, IsString } from "class-validator";
export class CreateChickenDto { export class CreateChickenDto {
@IsNotEmpty({ message: '用户ID不能为空' }) @IsNotEmpty({ message: '用户ID不能为空' })
@IsNumber() @IsNumber()
uid: number; userid: number;
@IsString() @IsString()
token: string; token: string;

View File

@ -7,11 +7,11 @@ export class ChickenEntity {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id?: number; id?: number;
@Column({ comment: '套装ID', type: 'int', default: 0 }) @Column({ comment: '用户ID', type: 'int', default: 0, unique: true })
suitid: number; userid: number;
@Column({ comment: '背景ID', type: 'int', default: 0 }) @Column({ comment: '套装订单ID', type: 'varchar', default: '' })
backdropid: number; suitid: string;
@Column({ comment: '碗中剩余饲料', type: 'bigint', default: 0 }) @Column({ comment: '碗中剩余饲料', type: 'bigint', default: 0 })
surplus_fodder: number; surplus_fodder: number;

View File

@ -20,6 +20,8 @@ export const CODE = {
CODE_APPUSER_COIN_NOT_ENOUGHT_ERR: { code: 606, message: '用户余额不足!' }, CODE_APPUSER_COIN_NOT_ENOUGHT_ERR: { code: 606, message: '用户余额不足!' },
/**扣减用户APP余额失败 */ /**扣减用户APP余额失败 */
CODE_APPUSER_SUB_COIN_ERR: { code: 606, message: '扣减用户APP余额失败!' }, CODE_APPUSER_SUB_COIN_ERR: { code: 606, message: '扣减用户APP余额失败!' },
/**购买中,请稍后... */
CODE_USER_PAY_LOCK_ERR: { code: 607, message: '购买中,请稍后...' },
/** 商品信息异常code */ /** 商品信息异常code */
@ -36,4 +38,8 @@ export const CODE = {
/** 订单信息异常code */ /** 订单信息异常code */
CODE_ORDER_INSERT_ERR: { code: 801, message: '订单创建失败!' }, CODE_ORDER_INSERT_ERR: { code: 801, message: '订单创建失败!' },
/** 小鸡信息异常code */
/**用户数据查询失败 */
CODE_PLAYER_INFO_ERR: { code: 902, message: '小鸡数据查询失败!' },
}; };

View File

@ -34,4 +34,4 @@ export enum ParentReceiveStatus {
RECEIVED = 'received',//售卖结束 RECEIVED = 'received',//售卖结束
UNRECEIVE = 'unreceive',//隐藏 UNRECEIVE = 'unreceive',//隐藏
WAIT_RECEIVE = 'wait_receive',//隐藏 WAIT_RECEIVE = 'wait_receive',//隐藏
} }

View File

@ -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<Observable<any>> {
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`)),
);
}
}

View File

@ -26,7 +26,7 @@ export function DataListResult(data: any[], pageIndex: number, pageSize: number,
* @message * @message
*/ */
export function CustomResult(params: { code: number, message: string }) { 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({ // throw new HttpException({
// code: params.code, // code: params.code,
// error: params.message, // error: params.message,

View File

@ -7,4 +7,9 @@ database:
drop_schema: false #启动程序时全部删除并重建数据表(生产环境严禁启用) drop_schema: false #启动程序时全部删除并重建数据表(生产环境严禁启用)
charset: utf8mb4 #数据库编码 charset: utf8mb4 #数据库编码
synchronize: true #自动同步表结构 synchronize: true #自动同步表结构
port: 8888 port: 8888
redis:
host: '127.0.0.1'
port: 6379
password: ''

View File

@ -6,10 +6,10 @@ import { AppModule } from './app.module';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
const configService = app.get(ConfigService); const configService = app.get(ConfigService);
const httpPort = configService.get<string>('port'); const httpPort = configService.get<string>('port');
console.log(`Linsten port http://192.168.60.11:${httpPort}`); console.log(`Linsten port http://192.168.60.11:${httpPort}`);
//swagger //swagger
const options = new DocumentBuilder() const options = new DocumentBuilder()
.setTitle('【 API 】小鸡游戏接口') .setTitle('【 API 】小鸡游戏接口')

View File

@ -14,15 +14,6 @@ export class OrderlogController {
return this.orderlogService.create(createOrderlogDto); 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') @Patch(':id')
update(@Param('id') id: string, @Body() updateOrderlogDto: UpdateOrderlogDto) { update(@Param('id') id: string, @Body() updateOrderlogDto: UpdateOrderlogDto) {

View File

@ -3,11 +3,13 @@ import { OrderlogService } from './orderlog.service';
import { OrderlogController } from './orderlog.controller'; import { OrderlogController } from './orderlog.controller';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { OrderlogEntity } from './entities/orderlog.entity'; import { OrderlogEntity } from './entities/orderlog.entity';
import { ChickensService } from 'src/chickens/chickens.service';
import { ChickenEntity } from 'src/chickens/entities/chicken.entity';
@Module({ @Module({
imports: [TypeOrmModule.forFeature([OrderlogEntity])], imports: [TypeOrmModule.forFeature([OrderlogEntity,ChickenEntity])],
controllers: [OrderlogController], controllers: [OrderlogController],
exports: [OrderlogService], exports: [OrderlogService],
providers: [OrderlogService] providers: [OrderlogService,ChickensService]
}) })
export class OrderlogModule { } export class OrderlogModule { }

View File

@ -7,6 +7,7 @@ import { CreateOrderlogDto } from './dto/create-orderlog.dto';
import { UpdateOrderlogDto } from './dto/update-orderlog.dto'; import { UpdateOrderlogDto } from './dto/update-orderlog.dto';
import { OrderlogEntity } from './entities/orderlog.entity'; import { OrderlogEntity } from './entities/orderlog.entity';
const prefix = 'order';
@Injectable() @Injectable()
export class OrderlogService { export class OrderlogService {
constructor( constructor(
@ -24,12 +25,11 @@ export class OrderlogService {
return CustomResult(CODE.CODE_ORDER_INSERT_ERR); return CustomResult(CODE.CODE_ORDER_INSERT_ERR);
} }
findAll() { /**API查询购买的商品订单详情信息 */
return `This action returns all orderlog`; 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();
findOne(id: number) { return orderGoods;
return `This action returns a #${id} orderlog`;
} }
update(id: number, updateOrderlogDto: UpdateOrderlogDto) { update(id: number, updateOrderlogDto: UpdateOrderlogDto) {

View File

9
src/redis/keys.ts Normal file
View File

@ -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;
}

35
src/redis/redis.ts Normal file
View File

@ -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);
}
}

View File

@ -5,10 +5,6 @@ export class BuyGoodsUserDto {
@IsInt() @IsInt()
userid: number; userid: number;
@IsNotEmpty({ message: '用户token不能为空' })
@IsString()
token: string;
@IsNotEmpty({ message: '用户购买商品ID不能为空' }) @IsNotEmpty({ message: '用户购买商品ID不能为空' })
@IsInt() @IsInt()
goodsid: number; goodsid: number;

View File

@ -5,5 +5,5 @@ export class CreateUserDto {
token: string; token: string;
@ApiProperty() @ApiProperty()
uid: number; userid: number;
} }

View File

@ -29,28 +29,8 @@ export class UserEntity {
}) })
online_status: string; online_status: string;
// @Column({ comment: '上级用户ID', type: 'bigint' }) @Column({ comment: '背景订单ID', type: 'varchar', default: '' })
// parent_id: number; backdropid: string;
// @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;
@CreateDateColumn({ comment: '游戏玩家信息创建时间', type: 'timestamp' }) @CreateDateColumn({ comment: '游戏玩家信息创建时间', type: 'timestamp' })
create_time: Date; create_time: Date;

View File

@ -6,6 +6,7 @@ import { SuccessResult } from 'src/common/utils/result-utils';
import { HttpValidationPipe } from 'src/common/utils/HttpValidationPipe'; import { HttpValidationPipe } from 'src/common/utils/HttpValidationPipe';
import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator'; import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator';
import { BuyGoodsUserDto } from './dto/buygoods-user.dto'; import { BuyGoodsUserDto } from './dto/buygoods-user.dto';
import { CreateUserDto } from './dto/create-user.dto';
@ApiTags('用户数据接口') @ApiTags('用户数据接口')
@Controller('user') @Controller('user')
@ -15,9 +16,23 @@ export class UserController {
//查询用户信息 //查询用户信息
@ApiOperation({ summary: '用户信息查询' }) @ApiOperation({ summary: '用户信息查询' })
@Get(':userid') @ApiImplicitQuery({
async findOne(@Param('userid') userid: number) { name: 'userid',
return SuccessResult(await this.userService.findOne(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); return this.userService.update(+userid, updateUserDto);
} }
//TODO 购买商品 //购买商品
@ApiOperation({ summary: '购买商品' }) @ApiOperation({ summary: '购买商品' })
@UsePipes(new HttpValidationPipe()) @UsePipes(new HttpValidationPipe())
@Post('buy') @Post('buy')
async buy(@Body() buyGoodsUserDto: BuyGoodsUserDto) { async buy(@Body() buyGoodsUserDto: BuyGoodsUserDto) {
return await this.userService.buy(buyGoodsUserDto); return await this.userService.buy(buyGoodsUserDto);
} }
} }

View File

@ -8,6 +8,7 @@ import { GoodsEntity } from 'src/goods/entities/good.entity';
import { OrderlogEntity } from 'src/orderlog/entities/orderlog.entity'; import { OrderlogEntity } from 'src/orderlog/entities/orderlog.entity';
import { OrderlogService } from 'src/orderlog/orderlog.service'; import { OrderlogService } from 'src/orderlog/orderlog.service';
import { ConfigModule } from '@nestjs/config'; import { ConfigModule } from '@nestjs/config';
import { CacheService } from 'src/redis/redis';
@Module({ @Module({
imports: [ imports: [
@ -16,6 +17,6 @@ import { ConfigModule } from '@nestjs/config';
], ],
controllers: [UserController], controllers: [UserController],
exports: [UserService], exports: [UserService],
providers: [UserService, GoodsService, OrderlogService] providers: [UserService, GoodsService, OrderlogService,CacheService]
}) })
export class UserModule { } export class UserModule { }

View File

@ -1,12 +1,14 @@
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { CODE } from 'src/common/code'; 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 { 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 { GoodsService } from 'src/goods/goods.service';
import { CreateOrderlogDto } from 'src/orderlog/dto/create-orderlog.dto'; import { CreateOrderlogDto } from 'src/orderlog/dto/create-orderlog.dto';
import { OrderlogService } from 'src/orderlog/orderlog.service'; 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 { Repository } from 'typeorm';
import { BuyGoodsUserDto } from './dto/buygoods-user.dto'; import { BuyGoodsUserDto } from './dto/buygoods-user.dto';
import { CreateUserDto } from './dto/create-user.dto'; import { CreateUserDto } from './dto/create-user.dto';
@ -22,23 +24,26 @@ export class UserService {
@InjectRepository(UserEntity) @InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>, private readonly userRepository: Repository<UserEntity>,
private readonly goodsService: GoodsService, 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<DataResultModel> {
//初始化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); const appUserInfo = await ExternalApiService.getAppUserInfo(createUserDto.userid, createUserDto.token);
if (userInfo) return userInfo;
//用户信息异常处理 //用户信息异常处理
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); if (!initRes) return CustomResult(CODE.CODE_INIT_USER_ERR);
return initRes; return SuccessResult(initRes);
} }
/**用户信息初始化 */ /**用户信息初始化 */
private async initUser(appUser: AppUserModel) { private async initUser(appUser: AppUserModel) {
@ -56,6 +61,7 @@ export class UserService {
return await this.userRepository.save(entity); return await this.userRepository.save(entity);
} }
/**查询用户信息 */ /**查询用户信息 */
async findOne(userid: number) { async findOne(userid: number) {
const info = await this.userRepository.createQueryBuilder(prefix) const info = await this.userRepository.createQueryBuilder(prefix)
@ -65,6 +71,17 @@ export class UserService {
return info; 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) { async update(userid: number, updateUserDto: UpdateUserDto) {
updateUserDto.update_time = new Date(); updateUserDto.update_time = new Date();
@ -80,7 +97,8 @@ export class UserService {
/** 用户购买商品逻辑 */ /** 用户购买商品逻辑 */
async buy(buyGoodsUserDto: BuyGoodsUserDto) { async buy(buyGoodsUserDto: BuyGoodsUserDto) {
//查询APP用户信息 //查询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; if (appUserInfo?.code != 200) return appUserInfo;
const user = appUserInfo.data; const user = appUserInfo.data;
@ -93,11 +111,16 @@ export class UserService {
const payCoin = goods.goods_price * buyGoodsUserDto.goods_count;//应支付价格 const payCoin = goods.goods_price * buyGoodsUserDto.goods_count;//应支付价格
if (user.coin < payCoin) return CustomResult(CODE.CODE_APPUSER_COIN_NOT_ENOUGHT_ERR); 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); const subUserInfo = await ExternalApiService.subAppUserCoin(buyGoodsUserDto.userid, token, payCoin);
console.log('扣减后用户信息',subUserInfo);
if (subUserInfo?.code != 200) return CustomResult(CODE.CODE_APPUSER_SUB_COIN_ERR);
//发放完成记录日志 //发放完成记录日志
const orderInfo: CreateOrderlogDto = { const orderInfo: CreateOrderlogDto = {
@ -107,12 +130,11 @@ export class UserService {
goods_price: goods.goods_price, goods_price: goods.goods_price,
goods_attribute: goods.goods_attribute goods_attribute: goods.goods_attribute
} }
// const orderRes = await this.orderLogService.create(orderInfo); const orderRes = await this.orderLogService.create(orderInfo);
// logger.debug(`购买订单日志结果: ${JSON.stringify(orderRes)}`); logger.debug(`购买订单日志结果: ${JSON.stringify(orderRes)}`);
// if (orderRes.code != 200) return CustomResult(CODE.CODE_GOODS_DEAL_ERR); if (orderRes.code != 200) return CustomResult(CODE.CODE_GOODS_DEAL_ERR);
return appUserInfo; return SuccessResult(orderRes.data);
return SuccessResult();
} }