npm package: @lantsang/nestjs-mp-cluster
Description: NestJS 多小程序插件
Author: Iric
Latest version: 0.0.5

# nestjs 小程序插件-支持多个小程序

注意：<font color="#dd0000">仍在开发中，目前仅在内部使用</font><br /> 

## 使用说明

* 外部人员仅供参考，请不要用于生产环境，因此导致的事故后果请自行承担。
* TS target es2019

### 安装

`$ npm i @lantsang/nestjs-mp-cluster` <br />
or <br />
`$ yarn add @lantsang/nestjs-mp-cluster` <br />
推荐使用yarn

### 引入

在模块注册的时候，支持传入内置小程序配置列表，并可以通过 `syncAccessToken` 参数配置是否在初始化的时候同步 `Access Token` 。

* 无内置小程序

``` typescript
import { MpModule } from '@lantsang/nestjs-mp-cluster'

@Module({
  imports: [
    MpModule.forRoot()  
  ]
})
export class AppModule { }
```

* 有内置小程序

``` typescript
import { MpModule } from '@lantsang/nestjs-mp-cluster'

@Module({
  imports: [
    MpModule.forRoot({
      mpList:[
        {
          appId: 'appid 1',
          appSecret: 'app secret 1'
        },
        {
          appId: 'appid 2',
          appSecret: 'app secret 2'
        }
      ],
      syncAccessToken:true //true表示在插件初始化的时候获取mpList中的小程序列表的 Access Token，默认为false
    })  
  ]
})
export class AppModule { }
```

### 注册小程序

推荐在引入时不内置小程序，在程序生命周期 `onModuleInit()` 方法中统一注册，后期页面中添加小程序时，只需要重新调用注册方法即可。(**增量注册**，不必全量注册)

``` typescript
import { Injectable, OnModuleInit } from "@nestjs/common";
import { MpService } from "@lantsang/nestjs-mp-cluster";

@Injectable()
export class TestService implements OnModuleInit {
  constructor(
    private readonly mpService: MpService
  ) { }

  async onModuleInit() {
    await this.mpService.register([
      {
        appId: 'appid 1',
        appSecret: 'app secret 1'
      },
      {
        appId: 'appid 2',
        appSecret: 'app secret 2'
      }
    ])
  }
}
```

### 删除注册

``` typescript
this.mpService.unregister('appid'); //此方法不用await，为同步方法
```

### 小程序登录

``` typescript
import { Body, Controller, HttpStatus, Post, HttpStatus, HttpException } from "@nestjs/common";
import { ApiOkResponse, ApiOperation, ApiTags } from "@nestjs/swagger";
import { LantUtil } from "../../../utils/lant.util";
import { SystemLogAppender } from "../../log/constants/log.constant";
import { LogService } from "../../log/services/log.service";
import { LoginMpReqDto } from "../dtos/mp/login.mp.req.dto";
import { LoginMpResDto } from "../dtos/mp/login.mp.res.dto";
import { MpService } from "@lantsang/nestjs-mp-cluster";

@ApiTags('user')
@Controller('mp/users')
export class UserMpController {
  constructor(
    private readonly mpService: MpService,
    private readonly logService: LogService,
    private readonly lantUtil: LantUtil
  ) { }

  @ApiOperation({ summary: '小程序用户登录' })
  @ApiOkResponse({ description: '用户token信息', type: LoginMpResDto })
  @Post('login')
  async login(@Body() body: LoginMpReqDto):Promise<LoginMpResDto> {
    try {
      const { success, userInfo, errorMessage } = await this.mpService.login(body.appid, body.temp_code, body.raw_data, body.signature, body.encrypted_data, body.iv);

      console.log(success, userInfo, errorMessage)
      return null;
    } catch (error) {
      if (error instanceof HttpException) throw error;
      this.logService.fatal(SystemLogAppender.user, `Mp user login by ${JSON.stringify(body)} failed and error is ${error}` , this.lantUtil.parseError(error));
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
```

### 特殊说明

* 登录时，小程序模拟器第一次调用会出现签名校验失败的错误，之后都是正常的，因此在调用login的接口中最后一个参数为默认参数，默认检查签名，可设置为false不去校验。