增加小游戏码的生成
This commit is contained in:
parent
dfbe89f10b
commit
2884da21a8
@ -1,9 +1,20 @@
|
||||
import BaseController from '../../common/base.controller'
|
||||
import { permission, router } from '../../decorators/router'
|
||||
import { permission, role, router } from '../../decorators/router'
|
||||
import { ZError } from '../../common/ZError'
|
||||
import { Game } from '../../models/content/Game'
|
||||
import { generateQrFile } from '../../services/File'
|
||||
|
||||
|
||||
class GameController extends BaseController{
|
||||
@role('anon')
|
||||
@router('get /api/test')
|
||||
async test(req) {
|
||||
let gameId= '60810dd156af0e8550832a44'
|
||||
let version = '608117912ff0238a3e607d33'
|
||||
let shop = 'sa6xtgbmj7'
|
||||
const { file, url } = await generateQrFile({gameId, version, shop})
|
||||
return {file, url}
|
||||
}
|
||||
@permission(['game:read', 'shop:game_setting'])
|
||||
@router('post /games')
|
||||
async list(req, res) {
|
||||
|
@ -3,6 +3,7 @@ import { permission, router } from '../../decorators/router'
|
||||
import { Shop } from '../../models/shop/Shop'
|
||||
import { ZError } from '../../common/ZError'
|
||||
import { Game } from '../../models/content/Game'
|
||||
import { generateQrFile } from '../../services/File'
|
||||
|
||||
class ShopController extends BaseController {
|
||||
|
||||
@ -149,6 +150,15 @@ class ShopController extends BaseController {
|
||||
versionid: shop.gameInfo.versionid
|
||||
}
|
||||
}
|
||||
|
||||
@permission('shop:edit')
|
||||
@router('post /shop/gameqr')
|
||||
async getGameQr(req: any) {
|
||||
let { shop, gameId, version } = req.params
|
||||
const { url } = await generateQrFile({gameId, version, shop})
|
||||
return { url }
|
||||
}
|
||||
|
||||
@permission('shop:edit')
|
||||
@router('post /shop/save_qtype')
|
||||
async updateQTypes(req) {
|
||||
|
@ -25,6 +25,9 @@ export class GameVersion extends Base{
|
||||
@prop()
|
||||
public appid: string
|
||||
|
||||
@prop()
|
||||
public appsecret: string
|
||||
|
||||
@prop()
|
||||
public image: string
|
||||
|
||||
@ -61,26 +64,14 @@ class GameClass extends BaseModule {
|
||||
public createdBy: string
|
||||
|
||||
public static parseQueryParam(params) {
|
||||
let {key, timeBegin, timeEnd, shop, hasVersion} = params
|
||||
let opt: any = {deleted: false}
|
||||
if (key) {
|
||||
opt.name = {$regex: key, $options: 'i'}
|
||||
}
|
||||
if (shop) {
|
||||
opt.shop = shop
|
||||
}
|
||||
if (timeBegin && !timeEnd) {
|
||||
opt.createdAt = {$gte: timeBegin};
|
||||
} else if (timeBegin && timeEnd) {
|
||||
opt['$and'] = [{createdAt: {$gte: timeBegin}}, {createdAt: {$lte: timeEnd}}];
|
||||
} else if (!timeBegin && timeEnd) {
|
||||
opt.createdAt = {$lte: timeEnd};
|
||||
let options: any = {
|
||||
matchKey: 'name'
|
||||
}
|
||||
let { opt, sort } = super.parseQueryParam(params, options)
|
||||
let { hasVersion } = params
|
||||
if (hasVersion) {
|
||||
Object.assign(opt, {'versions.0': {$exists: true}})
|
||||
}
|
||||
|
||||
let sort = {_id: 1}
|
||||
return { opt, sort }
|
||||
}
|
||||
|
||||
@ -88,6 +79,14 @@ class GameClass extends BaseModule {
|
||||
return this.findOne({deleted: false, 'versions.0': {$exists: true} }).exec()
|
||||
}
|
||||
|
||||
public static async fetchVersionInfo(gameId: string, version: string) {
|
||||
let game = await Game.findById(gameId)
|
||||
if (!game) {
|
||||
return null
|
||||
}
|
||||
return game.versions.find( o => o._id.toHexString() === version)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const Game = getModelForClass(GameClass, { existingConnection: GameClass.db })
|
||||
|
53
src/services/File.ts
Normal file
53
src/services/File.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import config from '../config/config'
|
||||
import * as jetpack from 'fs-jetpack'
|
||||
import { Game } from '../models/content/Game'
|
||||
import { ZError } from '../common/ZError'
|
||||
import { generateQr } from './Wechat'
|
||||
|
||||
export function generateUploadPath(subPath: string) {
|
||||
const base = config.file.upload_location
|
||||
const path = `${base}${subPath}`
|
||||
jetpack.dir(path)
|
||||
return path
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成包含该店铺信息的小程序码
|
||||
* @param {string} gameId
|
||||
* @param {string} version
|
||||
* @param {string} shop
|
||||
* @return {{file: string, url: string}}
|
||||
*/
|
||||
export async function generateQrFile({gameId, version, shop } : {gameId: string, version: string, shop: string}) {
|
||||
let subPath = `/qr/${gameId}/${version}`
|
||||
let path = generateUploadPath(subPath)
|
||||
let file = `${path}/${shop}.png`
|
||||
let url = `${config.file.show_url}${subPath}/${shop}.png`
|
||||
if ( jetpack.exists(file) !== 'file' ) {
|
||||
let versionData = await Game.fetchVersionInfo(gameId, version)
|
||||
if (!versionData || !versionData.appid || !versionData.appsecret) {
|
||||
throw new ZError(20, 'game version not found')
|
||||
}
|
||||
await generateQr({
|
||||
appId: versionData.appid,
|
||||
appSecret: versionData.appsecret,
|
||||
scene: shop,
|
||||
file
|
||||
})
|
||||
}
|
||||
return {file, url}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查该游戏包含该店铺信息的小程序码是否存在
|
||||
* @param {string} gameId
|
||||
* @param {string} version
|
||||
* @param {string} shop
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function checkQrExists(gameId: string, version: string, shop: string) {
|
||||
let subPath = `/qr/${gameId}/${version}`
|
||||
let path = generateUploadPath(subPath)
|
||||
let file = `${path}/${shop}.png`
|
||||
return jetpack.exists(file) === 'file'
|
||||
}
|
@ -1,5 +1,40 @@
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
import fs from 'fs'
|
||||
|
||||
export async function generateQr({appId, appSecret, scene, filePath}) {
|
||||
|
||||
export async function generateQr({appId, appSecret, scene, file }) {
|
||||
const stream = fs.createWriteStream(file);
|
||||
const token = await refreshToken(appId, appSecret)
|
||||
const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token}`
|
||||
const reqParams = {
|
||||
scene: scene,
|
||||
width: 430,
|
||||
auto_color: false,
|
||||
line_color: {'r': '0', 'g': '0', 'b': '0'},
|
||||
}
|
||||
let reqConfig: AxiosRequestConfig = {
|
||||
method: 'post',
|
||||
url,
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
responseType: 'stream',
|
||||
data: reqParams
|
||||
}
|
||||
const { data } = await axios(reqConfig)
|
||||
data.pipe(stream)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
export async function refreshToken(appId: string, appSecret: string) {
|
||||
const link =
|
||||
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`
|
||||
const { data } = await axios.get(link)
|
||||
if (!data.errcode) {
|
||||
return data.access_token
|
||||
} else {
|
||||
throw new Error(data.errmsg)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user