小鸡初始化等
This commit is contained in:
parent
2ffebb8f48
commit
50556a4936
@ -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],
|
||||||
|
@ -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);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -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 { }
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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: '小鸡数据查询失败!' },
|
||||||
};
|
};
|
@ -34,4 +34,4 @@ export enum ParentReceiveStatus {
|
|||||||
RECEIVED = 'received',//售卖结束
|
RECEIVED = 'received',//售卖结束
|
||||||
UNRECEIVE = 'unreceive',//隐藏
|
UNRECEIVE = 'unreceive',//隐藏
|
||||||
WAIT_RECEIVE = 'wait_receive',//隐藏
|
WAIT_RECEIVE = 'wait_receive',//隐藏
|
||||||
}
|
}
|
||||||
|
29
src/common/utils/login.interceptor.ts
Normal file
29
src/common/utils/login.interceptor.ts
Normal 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`)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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,
|
||||||
|
@ -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: ''
|
@ -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 】小鸡游戏接口')
|
||||||
|
@ -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) {
|
||||||
|
@ -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 { }
|
||||||
|
@ -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) {
|
||||||
|
9
src/redis/keys.ts
Normal file
9
src/redis/keys.ts
Normal 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
35
src/redis/redis.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -5,5 +5,5 @@ export class CreateUserDto {
|
|||||||
token: string;
|
token: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
uid: number;
|
userid: number;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 { }
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user