Quellcode durchsuchen

feat: 根据ghID 获取wx数据

zhangyuting vor 5 Jahren
Ursprung
Commit
932585259e

+ 1 - 1
config/production.js

@@ -7,7 +7,7 @@ module.exports = {
     default: {
       dsn: 'mongodb://dds-uf6ba204086ef6b41655-pub.mongodb.rds.aliyuncs.com:3717/mini_game?authSource=admin&replicaSet=mgset-36593873&connectTimeoutMS=5000&maxPoolSize=256&readPreference=primary&authMechanism=SCRAM-SHA-1&serverSelectionTimeoutMS=5000&appname=MongoDB%20Compass&ssl=false',
       options: { authSource: 'admin', auth: { user: 'admin', password: 'YyZq6699Pi?' } }
-    },
+    }
   },
   redis: {
     default: {

+ 2 - 0
package.json

@@ -28,6 +28,7 @@
     "@types/mysql": "^2.15.15",
     "@types/node": "^14.14.2",
     "@types/random-string": "^0.0.28",
+    "@types/randomatic": "^3.1.0",
     "@types/sequelize": "^4.28.9",
     "@types/tough-cookie": "^4.0.0",
     "@types/validator": "^13.1.0",
@@ -70,6 +71,7 @@
     "nodemon": "^2.0.6",
     "npm-run-all": "^4.1.5",
     "random-string": "^0.2.0",
+    "randomatic": "^3.1.1",
     "sequelize": "^6.3.5",
     "source-map-support": "^0.5.19",
     "webpack": "^5.3.0",

+ 38 - 0
src/app/api/miniGame.ts

@@ -0,0 +1,38 @@
+import { ExtendableContext } from 'koa'
+import { Response } from '@/app/types/response'
+import { MiniGameService } from '@/app/service/miniGameService'
+import { IGetWXInfoResponse } from '@/app/types/miniGameResponse'
+
+export class MiniGame {
+  protected service: MiniGameService
+  public prefix = '/mini_game'
+
+  constructor (ctx: ExtendableContext) {
+    this.service = new MiniGameService(ctx)
+  }
+
+  async getMiniInfo (ctx: ExtendableContext): Promise<Response<IGetWXInfoResponse>> {
+    const params = ctx.request.body
+    const ret: Response<IGetWXInfoResponse> = {
+      code: 404,
+      msg: '没有数据',
+      data: null
+    }
+    try {
+      console.log(params)
+      if (!params.ghID || !params.token) {
+        throw new Error('没有参数')
+      }
+      const data = await this.service.getMiniInfo(params.ghID, params.token)
+      if (data) {
+        ret.code = 200
+        ret.msg = 'ok'
+        ret.data = data
+      }
+    } catch (e) {
+      ret.code = 500
+      ret.msg = '操作失败'
+    }
+    return ret
+  }
+}

+ 7 - 20
src/app/controller/oneLoadKey.ts → src/app/api/oneLoadKey.ts

@@ -1,21 +1,16 @@
-import { Base } from '@/app/controller/base'
-
 import { OneLoadKeyService } from '@/app/service/oneLoadKeyService'
 import { ExtendableContext } from 'koa'
 import { Response } from '@/app/types/response'
 
-export class OneLoadKey extends Base {
+export class OneLoadKey {
   protected service: OneLoadKeyService
-  public prefix = '/one_load_key'
 
   constructor () {
-    super()
     this.service = new OneLoadKeyService()
   }
 
   async get (ctx:ExtendableContext):Promise<Response<IData>> {
     const params = ctx.request.body
-
     const ret: Response<IData> = {
       code: 404,
       msg: '没有数据',
@@ -25,21 +20,13 @@ export class OneLoadKey extends Base {
       if (!params.ghID) {
         throw new Error('没有参数')
       }
-      const result = await this.service.gen(params.ghID)
-      console.log(result)
-      if (result && result.status.toLowerCase() === 'ok') {
-        ret.msg = 'ok'
-        ret.code = 200
-        let cookieAsString = ''
-        Object.entries(result.data.cookies).forEach(item => {
-          cookieAsString += `${item[0]}=${item[1]}; `
-        })
-        result.data.cookie_as_string = cookieAsString.slice(0, -2)
-        ret.data = result.data
-      } else {
-        throw new Error(result.status)
-      }
+      const data = await this.service.gen(params.ghID)
+      await this.service.setCookie2Redis(params.ghID, data)
+      ret.code = 200
+      ret.msg = 'ok'
+      ret.data = data.data
     } catch (e) {
+      console.log(e)
       ret.code = 500
       ret.msg = '操作失败'
     }

+ 0 - 42
src/app/controller/base.ts

@@ -1,42 +0,0 @@
-import { ExtendableContext } from 'koa'
-import { Response } from '@/app/types/response'
-
-export interface ICurd {
-  create (ctx:ExtendableContext): Promise<Response<unknown>>
-  update (ctx:ExtendableContext): Promise<Response<unknown>>
-  get (ctx:ExtendableContext): Promise<Response<unknown>>
-  list (ctx:ExtendableContext): Promise<Response<unknown>>
-  all (ctx:ExtendableContext): Promise<Response<unknown>>
-  destroy (ctx:ExtendableContext): Promise<Response<unknown>>
-}
-
-export class Base implements ICurd {
-  public prefix = 'base'
-  // constructor () {
-  //   this.prefix = '/' + Parser.getClassName(this).toLowerCase()
-  // }
-
-  all (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-
-  create (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-
-  destroy (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-
-  get (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-
-  list (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-
-  update (ctx: ExtendableContext): Promise<Response<unknown>> {
-    return Promise.resolve(undefined)
-  }
-}

+ 5 - 0
src/app/db/redis.ts

@@ -0,0 +1,5 @@
+import Redis from 'ioredis'
+import config from 'config'
+
+const redis = new Redis(config.get('redis.default'))
+export default redis

+ 22 - 0
src/app/middleware/cookie.ts

@@ -0,0 +1,22 @@
+import { ExtendableContext, Next } from 'koa'
+import { OneLoadKeyService } from '@/app/service/oneLoadKeyService'
+
+const miniGameService = new OneLoadKeyService()
+export class Cookie {
+  static async handle (ctx: ExtendableContext, next: Next): Promise<unknown> {
+    const ghID = ctx.request.header.ghid
+    if (!ghID || typeof ghID !== 'string') {
+      throw new Error('缺少ghID')
+    }
+    // 从redis中获取,获取不到的话,直接拉接口
+    let data:IOneLoadKeyResponse = JSON.parse(await miniGameService.getCookie4Redis(ghID))
+    if (!data) {
+      data = await miniGameService.gen(ghID)
+      await miniGameService.setCookie2Redis(ghID, data)
+    }
+    ctx.request.body.cookie = data.data.cookie_as_string
+    ctx.request.body.token = data.data.token
+    ctx.request.body.ghID = ghID
+    return next()
+  }
+}

+ 0 - 16
src/app/provider/apiMiddleware.ts

@@ -1,16 +0,0 @@
-// 对外提供格式化好的中间件
-import { Request } from '@/app/middleware/request'
-
-export class ApiMiddleware {
-  static get ():any[] {
-    return [
-      Request.handle
-    ]
-  }
-
-  static login ():any[] {
-    return [
-      Request.handle
-    ]
-  }
-}

+ 12 - 0
src/app/provider/index.ts

@@ -0,0 +1,12 @@
+// 对外提供格式化好的中间件
+import { Request } from '@/app/middleware/request'
+import { Cookie } from '@/app/middleware/cookie'
+
+export class Index {
+  static handle ():any[] {
+    return [
+      Request.handle,
+      Cookie.handle
+    ]
+  }
+}

+ 42 - 0
src/app/service/miniGameBaseService.ts

@@ -0,0 +1,42 @@
+import got, { Response, Got } from 'got'
+import { ExtendableContext } from 'koa'
+import { IApiBaseResponse } from '@/app/types/miniGameResponse'
+
+export class MiniGameBaseService {
+  protected api: Got
+  constructor (ctx:ExtendableContext) {
+    const token:string = ctx.request.body.token
+    const cookie:string = ctx.request.body.cookie
+    this.api = got.extend({
+      prefixUrl: 'https://mp.weixin.qq.com/',
+      timeout: 5000,
+      responseType: 'json',
+      hooks: {
+        beforeRequest: [
+          async options => {
+            options.headers.referer = `https://mp.weixin.qq.com/wxopen/frame?t=promotion/ad_simple_frame&hidewording=1&page=campaign/edit&token=${token}&from_pos_type=999`
+            options.headers.cookie = cookie
+            options.headers.origin = 'https://mp.weixin.qq.com'
+            options.headers.contentType = 'application/x-www-form-urlencoded; charset=UTF-8'
+            options.headers.userAgent = 'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36'
+            const { searchParams } = options.url
+            searchParams.set('token', token)
+          }
+        ],
+        afterResponse: [
+          (response: Response<IApiBaseResponse>) => {
+            const { body, requestUrl } = response
+            if (body && typeof body === 'object') {
+              if (body.ret !== 0) {
+                console.error(body)
+              }
+            } else {
+              console.error(response.statusCode, requestUrl)
+            }
+            return response
+          }
+        ]
+      }
+    })
+  }
+}

+ 20 - 0
src/app/service/miniGameService.ts

@@ -0,0 +1,20 @@
+import { IGetWXInfoResponse } from '@/app/types/miniGameResponse'
+import { MiniGameBaseService } from './miniGameBaseService'
+
+export class MiniGameService extends MiniGameBaseService {
+  async getMiniInfo (ghID: string, token: string):Promise<IGetWXInfoResponse> {
+    const params = {
+      action: 'check_weapp_id',
+      f: 'json',
+      lang: 'zh_CN',
+      ajax: 1,
+      gh_id: ghID,
+      check_type: 24,
+      token: token
+    }
+    return this.api.get<IGetWXInfoResponse>('promotion/getlinkedwxa', {
+      searchParams: params,
+      resolveBodyOnly: true
+    })
+  }
+}

+ 26 - 4
src/app/service/oneLoadKeyService.ts

@@ -1,20 +1,42 @@
-import { Random } from '@/tool/random'
+import { Random } from '@/utils/random'
 import moment from 'moment'
-import { Encrypt } from '@/tool/encrypt'
+import { Encrypt } from '@/utils/encrypt'
 import config from 'config'
 import got from 'got'
-
+import redis from '@/app/db/redis'
 const token = config.get<string>('app.one_key_load.token')
 const client = config.get<string>('app.one_key_load.client')
+const redisKey = config.get<string>('app.cache.prefix')
 
 export class OneLoadKeyService {
   // http://onekeyload.mokasz.com/v1/onekeyload/dictionary/gh_bf0ce3ecc330/cookies
   private url = 'http://onekeyload.mokasz.com/v1/onekeyload/dictionary/'
 
+  // 生成
   async gen (ghID:string):Promise<IOneLoadKeyResponse> {
     const url = `${this.url}${ghID}/cookies`
     const params = await this.getParams()
-    return await got.get<IOneLoadKeyResponse>(url, { searchParams: params }).json()
+    const result:IOneLoadKeyResponse = await got.get<IOneLoadKeyResponse>(url, { searchParams: params }).json()
+    console.log(result)
+    if (result && result?.status.toLowerCase() === 'ok') {
+      let cookieAsString = ''
+      Object.entries(result.data.cookies).forEach(item => {
+        cookieAsString += `${item[0]}=${item[1]}; `
+      })
+      result.data.cookie_as_string = cookieAsString.slice(0, -2)
+    } else {
+      throw new Error(result?.data?.err_msg)
+    }
+    return result
+  }
+
+  async setCookie2Redis (ghID:string, data:IOneLoadKeyResponse):Promise<string> {
+    // 存储到redis中
+    return await redis.set(`${redisKey}:ONE_LOAD_KEY:${ghID}`, JSON.stringify(data), 'EX', data.data.expires_in - 1000)
+  }
+
+  async getCookie4Redis (ghID:string):Promise<string> {
+    return await redis.get(`${redisKey}:ONE_LOAD_KEY:${ghID}`)
   }
 
   async getParams (): Promise<Record<string, string>> {

+ 14 - 0
src/app/types/miniGameResponse.ts

@@ -0,0 +1,14 @@
+export interface IApiBaseResponse{
+  ret?:number
+  msg?: string;
+}
+
+// 获取微信信息接口
+export interface IGetWXInfoResponse<T = Record<string, unknown>> extends IApiBaseResponse{
+  appid?: string;
+  appseivicetype?: number;
+  check_msg?: string;
+  check_ret?: number;
+  headimgurl?: string;
+  nickname?: string;
+}

+ 1 - 1
src/index.ts

@@ -5,7 +5,7 @@ import koaBody from 'koa-body'
 import cors from '@koa/cors'
 import config from 'config'
 import router from '@/router'
-import { ConsoleRouters, Debug } from '@/tool/debug'
+import { ConsoleRouters, Debug } from '@/utils/debug'
 
 const app = new Koa()
 const port = config.get<number>('app.port')

+ 12 - 5
src/router/index.ts

@@ -1,21 +1,28 @@
 import config from 'config'
 import Router from 'koa-router'
-import { OneLoadKey } from '@/app/controller/oneLoadKey'
-import { ApiMiddleware } from '@/app/provider/apiMiddleware'
+import { OneLoadKey } from '@/app/api/oneLoadKey'
+import { Index } from '@/app/provider'
+import { Request } from '@/app/middleware/request'
+import { MiniGame } from '@/app/api/miniGame'
 
 const env = config.get<number>('app.env')
 const version = config.get<number>('app.version')
 
 const router = new Router()
-const middleware = ApiMiddleware.get()
+const middleware = Index.handle()
 
-router.get('/', ...middleware, async (ctx) => {
+router.get('/', async (ctx) => {
   ctx.body = { version, env }
 })
 
-router.get('/one_load_key', ...middleware, async (ctx) => {
+router.get('/one_load_key', Request.handle, async (ctx) => {
   const oneLoadKeyController = new OneLoadKey()
   ctx.body = await oneLoadKeyController.get(ctx)
 })
 
+router.get('/get_wx_info', ...middleware, async (ctx) => {
+  const controller = new MiniGame(ctx)
+  ctx.body = await controller.getMiniInfo(ctx)
+})
+
 export default router

+ 0 - 0
src/tool/debug.ts → src/utils/debug.ts


+ 0 - 0
src/tool/encrypt.ts → src/utils/encrypt.ts


+ 0 - 0
src/tool/parser/convent2type.js → src/utils/parser/convent2type.js


+ 0 - 0
src/tool/parser/enum.js → src/utils/parser/enum.js


+ 0 - 0
src/tool/parser/interface2schema.js → src/utils/parser/interface2schema.js


+ 0 - 0
src/tool/parser/json2interface.js → src/utils/parser/json2interface.js


+ 0 - 0
src/tool/parser/mysqltable2interface.js → src/utils/parser/mysqltable2interface.js


+ 0 - 0
src/tool/parser/table2interface.ts → src/utils/parser/table2interface.ts


+ 0 - 0
src/tool/random.ts → src/utils/random.ts


+ 25 - 1
yarn.lock

@@ -409,6 +409,11 @@
   resolved "https://registry.npm.taobao.org/@types/random-string/download/@types/random-string-0.0.28.tgz#b87171d173a49332ec0e843d9c2d740ad70ef902"
   integrity sha1-uHFx0XOkkzLsDoQ9nC10CtcO+QI=
 
+"@types/randomatic@^3.1.0":
+  version "3.1.0"
+  resolved "https://registry.npm.taobao.org/@types/randomatic/download/@types/randomatic-3.1.0.tgz#b593dae46c80689be735aa826a3fa06aa9c1ac59"
+  integrity sha1-tZPa5GyAaJvnNaqCaj+gaqnBrFk=
+
 "@types/range-parser@*":
   version "1.2.3"
   resolved "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
@@ -2488,6 +2493,11 @@ is-npm@^4.0.0:
   resolved "https://registry.npm.taobao.org/is-npm/download/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
   integrity sha1-yQ3YOAaW34enptgjwg0LErvjyE0=
 
+is-number@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npm.taobao.org/is-number/download/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
+  integrity sha1-ACbjf1RU1z41bf5lZGmYZ8an8P8=
+
 is-number@^7.0.0:
   version "7.0.0"
   resolved "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
@@ -2719,7 +2729,7 @@ keyv@^4.0.0:
   dependencies:
     json-buffer "3.0.1"
 
-kind-of@^6.0.2:
+kind-of@^6.0.0, kind-of@^6.0.2:
   version "6.0.3"
   resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
   integrity sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=
@@ -3039,6 +3049,11 @@ make-error@^1.1.1:
   resolved "https://registry.npm.taobao.org/make-error/download/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
   integrity sha1-LrLjfqm2fEiR9oShOUeZr0hM96I=
 
+math-random@^1.0.1:
+  version "1.0.4"
+  resolved "https://registry.npm.taobao.org/math-random/download/math-random-1.0.4.tgz?cache=0&sync_timestamp=1596773205522&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmath-random%2Fdownload%2Fmath-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c"
+  integrity sha1-XdaUPJOFSCZwFtTjTwV1gwgMUUw=
+
 media-typer@0.3.0:
   version "0.3.0"
   resolved "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -3676,6 +3691,15 @@ random-string@^0.2.0:
   resolved "https://registry.npm.taobao.org/random-string/download/random-string-0.2.0.tgz#a46e4375352beda9a0d7b0d19ed6d321ecd1d82d"
   integrity sha1-pG5DdTUr7amg17DRntbTIezR2C0=
 
+randomatic@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.npm.taobao.org/randomatic/download/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
+  integrity sha1-t3bvxZN1mE42xTey9RofCv8Noe0=
+  dependencies:
+    is-number "^4.0.0"
+    kind-of "^6.0.0"
+    math-random "^1.0.1"
+
 randombytes@^2.1.0:
   version "2.1.0"
   resolved "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"