一些代码移至公用组件
This commit is contained in:
parent
cf5d4c659c
commit
a153eded7b
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "packages/zutils"]
|
||||||
|
path = packages/zutils
|
||||||
|
url = git@git.kingsome.cn:zhanghongliang/zutils.git
|
@ -37,7 +37,8 @@
|
|||||||
"node-schedule": "^2.1.1",
|
"node-schedule": "^2.1.1",
|
||||||
"redis": "^3.1.2",
|
"redis": "^3.1.2",
|
||||||
"tracer": "^1.1.6",
|
"tracer": "^1.1.6",
|
||||||
"verify-apple-id-token": "^3.0.0"
|
"verify-apple-id-token": "^3.0.0",
|
||||||
|
"zutils": "link:packages/zutils"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typegoose/typegoose": "^9.12.1",
|
"@typegoose/typegoose": "^9.12.1",
|
||||||
|
1
packages/zutils
Submodule
1
packages/zutils
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit b982e43cd717e09acafba79f40c63e2572dbef96
|
@ -1,7 +1,6 @@
|
|||||||
import fastify, { FastifyError, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
|
import fastify, { FastifyError, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
|
||||||
import helmet from '@fastify/helmet'
|
import helmet from '@fastify/helmet'
|
||||||
import { IncomingMessage, Server, ServerResponse } from 'http'
|
import { IncomingMessage, Server, ServerResponse } from 'http'
|
||||||
import { RouterMap } from 'decorators/router'
|
|
||||||
import { mongoose } from '@typegoose/typegoose'
|
import { mongoose } from '@typegoose/typegoose'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import config from 'config/config'
|
import config from 'config/config'
|
||||||
@ -10,6 +9,7 @@ import CodeTaskSchedule from 'schedule/codetask.schedule'
|
|||||||
import { PriceSvr } from 'service/price.svr'
|
import { PriceSvr } from 'service/price.svr'
|
||||||
import { GooglePaySvr } from 'service/googlepay.svr'
|
import { GooglePaySvr } from 'service/googlepay.svr'
|
||||||
import { GasSvr } from 'service/gas.svr'
|
import { GasSvr } from 'service/gas.svr'
|
||||||
|
import { RouterMap } from 'zutils'
|
||||||
|
|
||||||
const zReqParserPlugin = require('plugins/zReqParser')
|
const zReqParserPlugin = require('plugins/zReqParser')
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { singleton } from '../decorators/singleton'
|
import { singleton } from 'zutils'
|
||||||
import Clock from './ClockTimer'
|
import Clock from './ClockTimer'
|
||||||
import { Delayed } from './Delayed'
|
import { Delayed } from './Delayed'
|
||||||
|
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
type Callback<T> = () => Promise<T>
|
|
||||||
|
|
||||||
export type AsyncQueue<T = void> = {
|
|
||||||
push: (task: Callback<T>) => Promise<T>
|
|
||||||
flush: () => Promise<void>
|
|
||||||
size: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that each callback pushed onto the queue is executed in series.
|
|
||||||
* Such a quetie 😻
|
|
||||||
* @param opts.dedupeConcurrent If dedupeConcurrent is `true` it ensures that if multiple
|
|
||||||
* tasks are pushed onto the queue while there is an active task, only the
|
|
||||||
* last one will be executed, once the active task has completed.
|
|
||||||
* e.g. in the below example, only 0 and 3 will be executed.
|
|
||||||
* ```
|
|
||||||
* const queue = createAsyncQueue({ dedupeConcurrent: true })
|
|
||||||
* queue.push(async () => console.log(0)) // returns 0
|
|
||||||
* queue.push(async () => console.log(1)) // returns 3
|
|
||||||
* queue.push(async () => console.log(2)) // returns 3
|
|
||||||
* queue.push(async () => console.log(3)) // returns 3
|
|
||||||
* ```
|
|
||||||
* */
|
|
||||||
export function createAsyncQueue<T = void>(opts = { dedupeConcurrent: false }): AsyncQueue<T> {
|
|
||||||
const { dedupeConcurrent } = opts
|
|
||||||
let queue: Callback<T>[] = []
|
|
||||||
let running: Promise<void> | undefined
|
|
||||||
let nextPromise = new DeferredPromise<T>()
|
|
||||||
const push = (task: Callback<T>) => {
|
|
||||||
let taskPromise = new DeferredPromise<T>()
|
|
||||||
if (dedupeConcurrent) {
|
|
||||||
queue = []
|
|
||||||
if (nextPromise.started) nextPromise = new DeferredPromise<T>()
|
|
||||||
taskPromise = nextPromise
|
|
||||||
}
|
|
||||||
queue.push(() => {
|
|
||||||
taskPromise.started = true
|
|
||||||
task().then(taskPromise.resolve).catch(taskPromise.reject)
|
|
||||||
return taskPromise.promise
|
|
||||||
})
|
|
||||||
if (!running) running = start()
|
|
||||||
return taskPromise.promise
|
|
||||||
}
|
|
||||||
const start = async () => {
|
|
||||||
while (queue.length) {
|
|
||||||
const task = queue.shift()!
|
|
||||||
await task().catch(() => {})
|
|
||||||
}
|
|
||||||
running = undefined
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
push,
|
|
||||||
flush: () => running || Promise.resolve(),
|
|
||||||
get size() {
|
|
||||||
return queue.length
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createAsyncQueues = <T = void>(opts = { dedupeConcurrent: false }) => {
|
|
||||||
const queues: { [queueId: string]: AsyncQueue<T> } = {}
|
|
||||||
const push = (queueId: string, task: Callback<T>) => {
|
|
||||||
if (!queues[queueId]) queues[queueId] = createAsyncQueue<T>(opts)
|
|
||||||
return queues[queueId].push(task)
|
|
||||||
}
|
|
||||||
const flush = (queueId: string) => {
|
|
||||||
if (!queues[queueId]) queues[queueId] = createAsyncQueue<T>(opts)
|
|
||||||
return queues[queueId].flush()
|
|
||||||
}
|
|
||||||
return { push, flush }
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeferredPromise<T = void, E = any> {
|
|
||||||
started = false
|
|
||||||
resolve: (x: T | PromiseLike<T>) => void = () => {}
|
|
||||||
reject: (x: E) => void = () => {}
|
|
||||||
promise: Promise<T>
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.promise = new Promise<T>((res, rej) => {
|
|
||||||
this.resolve = res
|
|
||||||
this.reject = rej
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function main() {
|
|
||||||
// const queue = createAsyncQueue()
|
|
||||||
// queue.push(async () => {
|
|
||||||
// console.log(0)
|
|
||||||
// }) // returns 0
|
|
||||||
// queue.push(async () => {
|
|
||||||
// console.log(1)
|
|
||||||
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// setTimeout(() => {
|
|
||||||
// console.log('12')
|
|
||||||
// resolve()
|
|
||||||
// }, 1000)
|
|
||||||
// })
|
|
||||||
// }) // returns 3
|
|
||||||
// queue.push(async () => console.log(2)) // returns 3
|
|
||||||
// queue.push(async () => console.log(3)) // returns 3
|
|
||||||
// console.log('hi')
|
|
||||||
// }
|
|
||||||
|
|
||||||
// main()
|
|
@ -1,36 +0,0 @@
|
|||||||
import { singleton } from "decorators/singleton";
|
|
||||||
import { FastifyRequest } from "fastify";
|
|
||||||
import { ZError } from "./ZError";
|
|
||||||
|
|
||||||
@singleton
|
|
||||||
export class SyncLocker {
|
|
||||||
map: Map<string, boolean> = new Map();
|
|
||||||
|
|
||||||
public lock(req: FastifyRequest) {
|
|
||||||
const key = `${req.method}:${req.url}:${req.user?.id || ''}`
|
|
||||||
if (this.map.has(key)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.map.set(key, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unlock(req: FastifyRequest) {
|
|
||||||
const key = `${req.method}:${req.url}:${req.user?.id || ''}`
|
|
||||||
this.map.delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public checkLock(req: FastifyRequest) {
|
|
||||||
const key = `${req.method}:${req.url}:${req.user?.id || ''}`
|
|
||||||
if (this.map.has(key)) {
|
|
||||||
throw new ZError(100, 'request too fast');
|
|
||||||
}
|
|
||||||
this.lock(req);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isLocked(req: FastifyRequest) {
|
|
||||||
const key = `${req.method}:${req.url}:${req.user?.id || ''}`
|
|
||||||
return this.map.has(key);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { FastifyError } from 'fastify'
|
|
||||||
|
|
||||||
export class ZError implements FastifyError {
|
|
||||||
code: string
|
|
||||||
statusCode?: number
|
|
||||||
message: string
|
|
||||||
name: string
|
|
||||||
|
|
||||||
constructor(statusCode: number, message: string) {
|
|
||||||
this.statusCode = statusCode
|
|
||||||
this.message = message
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import fastify = require('fastify')
|
|
||||||
|
|
||||||
export const ROLE_ANON = 'anon'
|
|
||||||
class BaseController {
|
|
||||||
aotoRoute(req: fastify.FastifyRequest, res) {}
|
|
||||||
}
|
|
||||||
export default BaseController
|
|
@ -1,12 +1,10 @@
|
|||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import { checkPrePaySign, createOrder, queryFiat, queryPrice, refreshToken } from 'service/alchemy.svr'
|
import { checkPrePaySign, createOrder, queryFiat, queryPrice, refreshToken } from 'service/alchemy.svr'
|
||||||
import { PayRecord, PayStatus } from 'modules/PayRecord'
|
import { PayRecord, PayStatus } from 'modules/PayRecord'
|
||||||
import { PriceSvr } from 'service/price.svr'
|
import { PriceSvr } from 'service/price.svr'
|
||||||
import { reportPayResult } from 'service/game.svr'
|
import { reportPayResult } from 'service/game.svr'
|
||||||
import { GasSvr } from 'service/gas.svr'
|
import { GasSvr } from 'service/gas.svr'
|
||||||
|
import { BaseController, ROLE_ANON, ZError, role, router } from 'zutils'
|
||||||
|
|
||||||
const CALL_BACK_URL = `${process.env.ALCHEMY_PAY_CB_URL}/pay/out/alchemy/result`
|
const CALL_BACK_URL = `${process.env.ALCHEMY_PAY_CB_URL}/pay/out/alchemy/result`
|
||||||
class AlchemyController extends BaseController {
|
class AlchemyController extends BaseController {
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import { calcNetworkFee, checkPayResultSign, checkSha1Sign } from 'service/alchemy.svr'
|
import { calcNetworkFee, checkPayResultSign, checkSha1Sign } from 'service/alchemy.svr'
|
||||||
import { PayRecord, PayStatus } from 'modules/PayRecord'
|
import { PayRecord, PayStatus } from 'modules/PayRecord'
|
||||||
import { TransferQueue } from 'queue/transfer.queue'
|
import { TransferQueue } from 'queue/transfer.queue'
|
||||||
@ -9,6 +6,7 @@ import { TransferRecord } from 'modules/TransferRecord'
|
|||||||
import { reportPayResult } from 'service/game.svr'
|
import { reportPayResult } from 'service/game.svr'
|
||||||
import { PriceSvr } from 'service/price.svr'
|
import { PriceSvr } from 'service/price.svr'
|
||||||
import { OrderCacheSvr } from 'service/ordercache.svr'
|
import { OrderCacheSvr } from 'service/ordercache.svr'
|
||||||
|
import { BaseController, role, ROLE_ANON, router, ZError } from 'zutils'
|
||||||
import { fromWei, toBigWei } from 'utils/number.util'
|
import { fromWei, toBigWei } from 'utils/number.util'
|
||||||
|
|
||||||
let errorRes = function (msg: string) {
|
let errorRes = function (msg: string) {
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { ZError } from 'common/ZError'
|
|
||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { AppleInApp, ApplePayStatus } from 'modules/AppleInApp'
|
import { AppleInApp, ApplePayStatus } from 'modules/AppleInApp'
|
||||||
import { InAppRecord } from 'modules/InAppRecord'
|
import { InAppRecord } from 'modules/InAppRecord'
|
||||||
import { IPayResult, reportApplePurchaseResult } from 'service/game.svr'
|
import { IPayResult, reportApplePurchaseResult } from 'service/game.svr'
|
||||||
import { IosPaySvr } from 'service/iospay.svr'
|
import { IosPaySvr } from 'service/iospay.svr'
|
||||||
|
import { BaseController, router, ZError, role, ROLE_ANON } from 'zutils'
|
||||||
|
|
||||||
class ApplePayController extends BaseController {
|
class ApplePayController extends BaseController {
|
||||||
@router('post /pay/apple/verify')
|
@router('post /pay/apple/verify')
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import BaseController from 'common/base.controller'
|
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { router } from 'decorators/router'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { GoogleInApp, GooglePayStatus } from 'modules/GoogleInApp'
|
import { GoogleInApp, GooglePayStatus } from 'modules/GoogleInApp'
|
||||||
import { InAppRecord } from 'modules/InAppRecord'
|
import { InAppRecord } from 'modules/InAppRecord'
|
||||||
import { IPayResult, reportGooglePurchaseResult } from 'service/game.svr'
|
import { IPayResult, reportGooglePurchaseResult } from 'service/game.svr'
|
||||||
import { GooglePaySvr } from 'service/googlepay.svr'
|
import { GooglePaySvr } from 'service/googlepay.svr'
|
||||||
|
import { BaseController, router, ZError } from 'zutils'
|
||||||
|
|
||||||
class GooglePayController extends BaseController {
|
class GooglePayController extends BaseController {
|
||||||
@router('post /pay/google/verify')
|
@router('post /pay/google/verify')
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import { ZError } from 'common/ZError'
|
|
||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { PayRecord, PayRecordClass, PayStatus } from 'modules/PayRecord'
|
import { PayRecord, PayRecordClass, PayStatus } from 'modules/PayRecord'
|
||||||
import { TransferRecord, TransferRecordClass } from 'modules/TransferRecord'
|
import { TransferRecord, TransferRecordClass } from 'modules/TransferRecord'
|
||||||
import { hmacsha256 } from 'utils/security.util'
|
|
||||||
import { DocumentType } from '@typegoose/typegoose'
|
import { DocumentType } from '@typegoose/typegoose'
|
||||||
import { updateOrderStatus } from 'service/alchemy.svr'
|
import { updateOrderStatus } from 'service/alchemy.svr'
|
||||||
import { PriceSvr } from 'service/price.svr'
|
import { PriceSvr } from 'service/price.svr'
|
||||||
import { assembleGameData, checkGameSign } from 'service/game.svr'
|
import { assembleGameData, checkGameSign } from 'service/game.svr'
|
||||||
|
import { BaseController, role, ROLE_ANON, router, ZError } from 'zutils'
|
||||||
|
import { hmacSha256 } from 'zutils/utils/security.util'
|
||||||
|
|
||||||
const calcHash = function (data: any) {
|
const calcHash = function (data: any) {
|
||||||
let signStr = JSON.stringify(data)
|
let signStr = JSON.stringify(data)
|
||||||
return hmacsha256(signStr, process.env.HASH_SALT_CHAIN)
|
return hmacSha256(signStr, process.env.HASH_SALT_CHAIN).toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
const notify = async function (record: DocumentType<PayRecordClass>, subTask: DocumentType<TransferRecordClass>) {
|
const notify = async function (record: DocumentType<PayRecordClass>, subTask: DocumentType<TransferRecordClass>) {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { ZError } from 'common/ZError'
|
|
||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import { beginSell, buyOrder, submitOrder } from 'service/okxmarket.svr'
|
import { beginSell, buyOrder, submitOrder } from 'service/okxmarket.svr'
|
||||||
|
import { BaseController, ROLE_ANON, ZError, role, router } from 'zutils'
|
||||||
|
|
||||||
class OkxMarketController extends BaseController {
|
class OkxMarketController extends BaseController {
|
||||||
@role(ROLE_ANON)
|
@role(ROLE_ANON)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
|
import { BaseController, role, ROLE_ANON, router } from 'zutils'
|
||||||
|
|
||||||
class PurchaseController extends BaseController {
|
class PurchaseController extends BaseController {
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { role, router } from 'decorators/router'
|
|
||||||
import { BridgeSvr } from 'service/bridge.svr'
|
import { BridgeSvr } from 'service/bridge.svr'
|
||||||
|
import { BaseController, role, ROLE_ANON, router, ZError } from 'zutils'
|
||||||
|
|
||||||
const TOKEN_PREFIX = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'
|
const TOKEN_PREFIX = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'reflect-metadata'
|
import 'reflect-metadata'
|
||||||
import { singleton } from './singleton'
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
export class NoJsonClass {
|
export class NoJsonClass {
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
import BaseController from '../common/base.controller'
|
|
||||||
|
|
||||||
export class RouterData {
|
|
||||||
target?: any
|
|
||||||
method?: string
|
|
||||||
path?: string
|
|
||||||
fun?: Function
|
|
||||||
}
|
|
||||||
|
|
||||||
export class RouterMap {
|
|
||||||
static decoratedRouters: Map<
|
|
||||||
Function,
|
|
||||||
{
|
|
||||||
roles?: string[]
|
|
||||||
permissions?: string[][]
|
|
||||||
data?: RouterData[]
|
|
||||||
depts?: string[]
|
|
||||||
}
|
|
||||||
> = new Map()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function router(route?: string) {
|
|
||||||
return (target: BaseController, name: string, value: PropertyDescriptor) => {
|
|
||||||
if (!route) {
|
|
||||||
const controller = target.constructor.name
|
|
||||||
const controllerName = controller.toLowerCase().replace('.controller', '')
|
|
||||||
route = 'all ' + ['', controllerName, name].join('/')
|
|
||||||
}
|
|
||||||
const split = route.split(' ')
|
|
||||||
if (split.length > 2) {
|
|
||||||
throw new Error('路由中只允许一个空格')
|
|
||||||
}
|
|
||||||
const [method, path] = split
|
|
||||||
// @ts-ignore
|
|
||||||
const key = target[name]
|
|
||||||
let routerData = new RouterData()
|
|
||||||
routerData.target = target
|
|
||||||
routerData.method = method
|
|
||||||
routerData.path = path
|
|
||||||
// @ts-ignore
|
|
||||||
routerData.fun = target[name]
|
|
||||||
|
|
||||||
if (RouterMap.decoratedRouters.has(key)) {
|
|
||||||
let objCurrent = RouterMap.decoratedRouters.get(key)
|
|
||||||
if (!objCurrent.data) {
|
|
||||||
objCurrent.data = [routerData]
|
|
||||||
} else {
|
|
||||||
objCurrent.data.push(routerData)
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], objCurrent)
|
|
||||||
} else {
|
|
||||||
let routerObj = {
|
|
||||||
data: [routerData],
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], routerObj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function role(roles?: string | string[]) {
|
|
||||||
return (target: BaseController, name: string, value: PropertyDescriptor) => {
|
|
||||||
let roleList: string[] = []
|
|
||||||
if (roles) {
|
|
||||||
if (Array.isArray(roles)) {
|
|
||||||
roleList = roles
|
|
||||||
} else {
|
|
||||||
roleList = [roles]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
const key = target[name]
|
|
||||||
let roleObj = { roles: roleList }
|
|
||||||
if (RouterMap.decoratedRouters.has(key)) {
|
|
||||||
let objCurrent = RouterMap.decoratedRouters.get(key)
|
|
||||||
Object.assign(objCurrent, roleObj)
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], objCurrent)
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], roleObj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function permission(permissions?: string | string[]) {
|
|
||||||
return (target: BaseController, name: string, value: PropertyDescriptor) => {
|
|
||||||
let permissionList: string[][] = [[]]
|
|
||||||
if (permissions) {
|
|
||||||
if (Array.isArray(permissions)) {
|
|
||||||
let arr = []
|
|
||||||
for (let sub of permissions) {
|
|
||||||
arr.push(sub.split(':'))
|
|
||||||
}
|
|
||||||
permissionList = arr
|
|
||||||
} else {
|
|
||||||
permissionList = [permissions.split(':')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
const key = target[name]
|
|
||||||
let permissionObj = { permissions: permissionList }
|
|
||||||
if (RouterMap.decoratedRouters.has(key)) {
|
|
||||||
let objCurrent = RouterMap.decoratedRouters.get(key)
|
|
||||||
Object.assign(objCurrent, permissionObj)
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], objCurrent)
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], permissionObj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 有dept修饰器的, 需要验证部门id是否存在
|
|
||||||
*/
|
|
||||||
export function dept(depts?: string | string[]) {
|
|
||||||
return (target: BaseController, name: string, value: PropertyDescriptor) => {
|
|
||||||
let deptList: string[] = []
|
|
||||||
if (depts) {
|
|
||||||
if (Array.isArray(depts)) {
|
|
||||||
deptList = depts
|
|
||||||
} else {
|
|
||||||
deptList = [depts]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
const key = target[name]
|
|
||||||
let deptObj = { depts: deptList }
|
|
||||||
if (RouterMap.decoratedRouters.has(key)) {
|
|
||||||
let objCurrent = RouterMap.decoratedRouters.get(key)
|
|
||||||
Object.assign(objCurrent, deptObj)
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], objCurrent)
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
RouterMap.decoratedRouters.set(target[name], deptObj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* 单例化一个class
|
|
||||||
* 使用方法:
|
|
||||||
* @singleton
|
|
||||||
* class Test {}
|
|
||||||
* new Test() === new Test() // returns `true`
|
|
||||||
* 也可以不使用 decorator
|
|
||||||
* const TestSingleton = singleton(Test)
|
|
||||||
* new TestSingleton() === new TestSingleton() //returns 'true'
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const SINGLETON_KEY = Symbol()
|
|
||||||
|
|
||||||
export type Singleton<T extends new (...args: any[]) => any> = T & {
|
|
||||||
[SINGLETON_KEY]: T extends new (...args: any[]) => infer I ? I : never
|
|
||||||
}
|
|
||||||
export const singleton = <T extends new (...args: any[]) => any>(classTarget: T) =>
|
|
||||||
new Proxy(classTarget, {
|
|
||||||
construct(target: Singleton<T>, argumentsList, newTarget) {
|
|
||||||
// Skip proxy for children
|
|
||||||
if (target.prototype !== newTarget.prototype) {
|
|
||||||
return Reflect.construct(target, argumentsList, newTarget)
|
|
||||||
}
|
|
||||||
if (!target[SINGLETON_KEY]) {
|
|
||||||
target[SINGLETON_KEY] = Reflect.construct(target, argumentsList, newTarget)
|
|
||||||
}
|
|
||||||
return target[SINGLETON_KEY]
|
|
||||||
},
|
|
||||||
})
|
|
@ -1,16 +1,16 @@
|
|||||||
import * as dotenv from 'dotenv'
|
import * as dotenv from 'dotenv'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { RedisClient } from 'redis/RedisClient'
|
|
||||||
const envFile = process.env.NODE_ENV && process.env.NODE_ENV === 'production' ? `.env.production` : '.env.development'
|
const envFile = process.env.NODE_ENV && process.env.NODE_ENV === 'production' ? `.env.production` : '.env.development'
|
||||||
dotenv.config({ path: envFile })
|
dotenv.config({ path: envFile })
|
||||||
|
|
||||||
import 'common/Extend'
|
import 'common/Extend'
|
||||||
import { GooglePaySvr } from 'service/googlepay.svr'
|
import { GooglePaySvr } from 'service/googlepay.svr'
|
||||||
import GooglePurchaseSchedule from 'schedule/googlepurchase.schedule'
|
import GooglePurchaseSchedule from 'schedule/googlepurchase.schedule'
|
||||||
|
import { ZRedisClient } from 'zutils'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
let opts = { url: process.env.REDIS }
|
let opts = { url: process.env.REDIS }
|
||||||
new RedisClient(opts)
|
new ZRedisClient(opts)
|
||||||
logger.info('REDIS Connected')
|
logger.info('REDIS Connected')
|
||||||
await new GooglePaySvr().init()
|
await new GooglePaySvr().init()
|
||||||
logger.info('GooglePaySvr Connected')
|
logger.info('GooglePaySvr Connected')
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { AsyncQueue, createAsyncQueue } from 'common/AsyncQueue'
|
|
||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { UserLog } from 'modules/UserLog'
|
import { UserLog } from 'modules/UserLog'
|
||||||
|
import { singleton, AsyncQueue, createAsyncQueue } from 'zutils'
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
export class LoggerQueue {
|
export class LoggerQueue {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { AsyncQueue, createAsyncQueue } from 'common/AsyncQueue'
|
|
||||||
import { DocumentType } from '@typegoose/typegoose'
|
import { DocumentType } from '@typegoose/typegoose'
|
||||||
import { PayRecordClass } from 'modules/PayRecord'
|
import { PayRecordClass } from 'modules/PayRecord'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
@ -7,6 +5,7 @@ import { pushTaskToChain } from 'service/chain.svr'
|
|||||||
import { TransferRecord } from 'modules/TransferRecord'
|
import { TransferRecord } from 'modules/TransferRecord'
|
||||||
import config from 'config/config'
|
import config from 'config/config'
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
|
import { AsyncQueue, createAsyncQueue, singleton } from 'zutils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* let data = {
|
* let data = {
|
||||||
|
@ -1,306 +0,0 @@
|
|||||||
import { resolveCname } from 'dns'
|
|
||||||
import redis from 'redis'
|
|
||||||
import { promisify } from 'util'
|
|
||||||
import { singleton } from '../decorators/singleton'
|
|
||||||
|
|
||||||
type Callback = (...args: any[]) => void
|
|
||||||
|
|
||||||
@singleton
|
|
||||||
export class RedisClient {
|
|
||||||
public pub: redis.RedisClient
|
|
||||||
public sub: redis.RedisClient
|
|
||||||
|
|
||||||
protected subscribeAsync: any
|
|
||||||
protected unsubscribeAsync: any
|
|
||||||
protected publishAsync: any
|
|
||||||
|
|
||||||
protected subscriptions: { [channel: string]: Callback[] } = {}
|
|
||||||
|
|
||||||
protected smembersAsync: any
|
|
||||||
protected sismemberAsync: any
|
|
||||||
protected hgetAsync: any
|
|
||||||
protected hlenAsync: any
|
|
||||||
protected pubsubAsync: any
|
|
||||||
protected incrAsync: any
|
|
||||||
protected decrAsync: any
|
|
||||||
|
|
||||||
constructor(opts?: redis.ClientOpts) {
|
|
||||||
this.sub = redis.createClient(opts)
|
|
||||||
this.pub = redis.createClient(opts)
|
|
||||||
|
|
||||||
// no listener limit
|
|
||||||
this.sub.setMaxListeners(0)
|
|
||||||
|
|
||||||
// create promisified pub/sub methods.
|
|
||||||
this.subscribeAsync = promisify(this.sub.subscribe).bind(this.sub)
|
|
||||||
this.unsubscribeAsync = promisify(this.sub.unsubscribe).bind(this.sub)
|
|
||||||
|
|
||||||
this.publishAsync = promisify(this.pub.publish).bind(this.pub)
|
|
||||||
|
|
||||||
// create promisified redis methods.
|
|
||||||
this.smembersAsync = promisify(this.pub.smembers).bind(this.pub)
|
|
||||||
this.sismemberAsync = promisify(this.pub.sismember).bind(this.pub)
|
|
||||||
this.hlenAsync = promisify(this.pub.hlen).bind(this.pub)
|
|
||||||
this.hgetAsync = promisify(this.pub.hget).bind(this.pub)
|
|
||||||
this.pubsubAsync = promisify(this.pub.pubsub).bind(this.pub)
|
|
||||||
this.decrAsync = promisify(this.pub.decr).bind(this.pub)
|
|
||||||
this.incrAsync = promisify(this.pub.incr).bind(this.pub)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async subscribe(topic: string, callback: Callback) {
|
|
||||||
if (!this.subscriptions[topic]) {
|
|
||||||
this.subscriptions[topic] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
this.subscriptions[topic].push(callback)
|
|
||||||
|
|
||||||
if (this.sub.listeners('message').length === 0) {
|
|
||||||
this.sub.addListener('message', this.handleSubscription)
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.subscribeAsync(topic)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
public async unsubscribe(topic: string, callback?: Callback) {
|
|
||||||
if (callback) {
|
|
||||||
const index = this.subscriptions[topic].indexOf(callback)
|
|
||||||
this.subscriptions[topic].splice(index, 1)
|
|
||||||
} else {
|
|
||||||
this.subscriptions[topic] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subscriptions[topic].length === 0) {
|
|
||||||
await this.unsubscribeAsync(topic)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
public async publish(topic: string, data: any) {
|
|
||||||
if (data === undefined) {
|
|
||||||
data = false
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.publishAsync(topic, JSON.stringify(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
public async exists(roomId: string): Promise<boolean> {
|
|
||||||
return (await this.pubsubAsync('channels', roomId)).length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setex(key: string, value: string, seconds: number) {
|
|
||||||
return new Promise(resolve => this.pub.setex(key, seconds, value, resolve))
|
|
||||||
}
|
|
||||||
|
|
||||||
public async expire(key: string, seconds: number) {
|
|
||||||
return new Promise(resolve => this.pub.expire(key, seconds, resolve))
|
|
||||||
}
|
|
||||||
|
|
||||||
public async get(key: string): Promise<string | null> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.get(key, (err, data: string | null) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async set(key: string, val: string) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.set(key, val, () => {
|
|
||||||
resolve && resolve('')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async del(roomId: string) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.del(roomId, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async sadd(key: string, value: any) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.sadd(key, value, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async smembers(key: string): Promise<string[]> {
|
|
||||||
return await this.smembersAsync(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async sismember(key: string, field: string): Promise<number> {
|
|
||||||
return await this.sismemberAsync(key, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async srem(key: string, value: any) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.srem(key, value, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async scard(key: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.scard(key, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
public async srandmember(key: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.srandmember(key, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async sinter(...keys: string[]) {
|
|
||||||
return new Promise<string[]>((resolve, reject) => {
|
|
||||||
this.pub.sinter(...keys, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zadd(key: string, value: any, member: string) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.zadd(key, value, member, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
public async zrangebyscore(key: string, min: number, max: number) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zrangebyscore(key, min, max, 'withscores', (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zcard(key: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zcard(key, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zcount(key: string, min: number, max: number) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zcount(key, min, max, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zrevrank(key: string, member: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zrevrank(key, member, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zscore(key: string, member: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zscore(key, member, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async zrevrange(key: string, start: number, end: number) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.zrevrange(key, start, end, 'withscores', (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hset(key: string, field: string, value: string) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.hset(key, field, value, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hincrby(key: string, field: string, value: number) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.pub.hincrby(key, field, value, resolve)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hget(key: string, field: string) {
|
|
||||||
return await this.hgetAsync(key, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hgetall(key: string) {
|
|
||||||
return new Promise<{ [key: string]: string }>((resolve, reject) => {
|
|
||||||
this.pub.hgetall(key, (err, values) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(values)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hdel(key: string, field: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.pub.hdel(key, field, (err, ok) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
resolve(ok)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public async hlen(key: string): Promise<number> {
|
|
||||||
return await this.hlenAsync(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async incr(key: string): Promise<number> {
|
|
||||||
return await this.incrAsync(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async decr(key: string): Promise<number> {
|
|
||||||
return await this.decrAsync(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected handleSubscription = (channel: string, message: string) => {
|
|
||||||
if (this.subscriptions[channel]) {
|
|
||||||
for (let i = 0, l = this.subscriptions[channel].length; i < l; i++) {
|
|
||||||
this.subscriptions[channel][i](JSON.parse(message))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { CodeRecord, CodeStatus } from 'modules/CodeRecord'
|
import { CodeRecord, CodeStatus } from 'modules/CodeRecord'
|
||||||
import * as schedule from 'node-schedule'
|
import * as schedule from 'node-schedule'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时更新发送邮件验证码的过期状态
|
* 定时更新发送邮件验证码的过期状态
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { GoogleInApp } from 'modules/GoogleInApp'
|
import { GoogleInApp } from 'modules/GoogleInApp'
|
||||||
import * as schedule from 'node-schedule'
|
import * as schedule from 'node-schedule'
|
||||||
import { RedisClient } from 'redis/RedisClient'
|
|
||||||
import { GooglePaySvr } from 'service/googlepay.svr'
|
import { GooglePaySvr } from 'service/googlepay.svr'
|
||||||
|
import { ZRedisClient, singleton } from 'zutils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时查询 google voided purchase
|
* 定时查询 google voided purchase
|
||||||
@ -22,7 +22,7 @@ import { GooglePaySvr } from 'service/googlepay.svr'
|
|||||||
export default class GooglePurchaseSchedule {
|
export default class GooglePurchaseSchedule {
|
||||||
async parseAllRecord() {
|
async parseAllRecord() {
|
||||||
const timeKey = 'google_inapp_voided_check_time'
|
const timeKey = 'google_inapp_voided_check_time'
|
||||||
let timeStr = await new RedisClient().get(timeKey)
|
let timeStr = await new ZRedisClient().get(timeKey)
|
||||||
let startTime = timeStr ? parseInt(timeStr) : Date.now() - 24 * 60 * 60 * 1000
|
let startTime = timeStr ? parseInt(timeStr) : Date.now() - 24 * 60 * 60 * 1000
|
||||||
let endTime = Date.now()
|
let endTime = Date.now()
|
||||||
try {
|
try {
|
||||||
@ -33,7 +33,7 @@ export default class GooglePurchaseSchedule {
|
|||||||
}
|
}
|
||||||
const { data } = res
|
const { data } = res
|
||||||
await GoogleInApp.parseVoidedRecords(data.voidedPurchases)
|
await GoogleInApp.parseVoidedRecords(data.voidedPurchases)
|
||||||
await new RedisClient().set(timeKey, endTime + '')
|
await new ZRedisClient().set(timeKey, endTime + '')
|
||||||
logger.info(`success check google voided purchase:: voidedPurchases: ${data.voidedPurchases?.length || 0}`)
|
logger.info(`success check google voided purchase:: voidedPurchases: ${data.voidedPurchases?.length || 0}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.info('error check google voided purchase', err.message || err)
|
logger.info('error check google voided purchase', err.message || err)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { ReportQueue } from 'modules/ReportQueue'
|
import { ReportQueue } from 'modules/ReportQueue'
|
||||||
import * as schedule from 'node-schedule'
|
import * as schedule from 'node-schedule'
|
||||||
import { reportApplePurchaseResult, reportGooglePurchaseResult } from 'service/game.svr'
|
import { reportApplePurchaseResult, reportGooglePurchaseResult } from 'service/game.svr'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时查询加密货币购买和内购上报失败的记录, 并重试
|
* 定时查询加密货币购买和内购上报失败的记录, 并重试
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { ZError } from 'common/ZError'
|
|
||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { shortUuid, uuid } from 'utils/security.util'
|
import { shortUuid, uuid } from 'utils/security.util'
|
||||||
|
import { ZError, singleton } from 'zutils'
|
||||||
|
|
||||||
export interface IQrData {
|
export interface IQrData {
|
||||||
clientId: string
|
clientId: string
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { NetClient } from 'net/NetClient'
|
import { NetClient } from 'net/NetClient'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
export const DEFAULT_VERIFY_HTML = `
|
export const DEFAULT_VERIFY_HTML = `
|
||||||
<h1>Email Verification</h1>
|
<h1>Email Verification</h1>
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { queryPrice } from './alchemy.svr'
|
import { queryPrice } from './alchemy.svr'
|
||||||
import * as schedule from 'node-schedule'
|
import * as schedule from 'node-schedule'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
import { erc20TransferGas, ethTransferGas } from './chain.svr'
|
import { erc20TransferGas, ethTransferGas } from './chain.svr'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
export class GasSvr {
|
export class GasSvr {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { androidpublisher_v3, google } from 'googleapis'
|
import { androidpublisher_v3, google } from 'googleapis'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
const PAGEAGE_NAME = 'com.cege.games.release'
|
const PAGEAGE_NAME = 'com.cege.games.release'
|
||||||
|
|
||||||
|
@ -7,8 +7,9 @@ import {
|
|||||||
ProductTypeParameter,
|
ProductTypeParameter,
|
||||||
SortParameter,
|
SortParameter,
|
||||||
} from 'apple/Models'
|
} from 'apple/Models'
|
||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
const env = process.env.NODE_ENV || 'development'
|
const env = process.env.NODE_ENV || 'development'
|
||||||
const sandbox = env === 'development' ? true : false
|
const sandbox = env === 'development' ? true : false
|
||||||
@ -29,7 +30,7 @@ const apiSandbox = new AppStoreServerAPI(KEY, KEY_ID, ISSUER_ID, APP_BUNDLE_ID,
|
|||||||
export class IosPaySvr {
|
export class IosPaySvr {
|
||||||
public async iosPayVerify(orderId: string) {
|
public async iosPayVerify(orderId: string) {
|
||||||
logger.info('iosPayVerify: ', orderId)
|
logger.info('iosPayVerify: ', orderId)
|
||||||
let response;
|
let response
|
||||||
try {
|
try {
|
||||||
response = await apiProd.lookupOrder(orderId)
|
response = await apiProd.lookupOrder(orderId)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -78,7 +79,7 @@ export class IosPaySvr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getTransactionInfo(originalTransactionId: string) {
|
public async getTransactionInfo(originalTransactionId: string) {
|
||||||
let response;
|
let response
|
||||||
try {
|
try {
|
||||||
response = await apiProd.getTransactionInfo(originalTransactionId)
|
response = await apiProd.getTransactionInfo(originalTransactionId)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -91,8 +92,8 @@ export class IosPaySvr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!response) {
|
if (!response) {
|
||||||
throw new Error('empty transaction info')
|
throw new Error('empty transaction info')
|
||||||
}
|
}
|
||||||
const transaction = await decodeTransaction(response.signedTransactionInfo)
|
const transaction = await decodeTransaction(response.signedTransactionInfo)
|
||||||
return transaction
|
return transaction
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { singleton } from 'decorators/singleton'
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
export class OrderCacheSvr {
|
export class OrderCacheSvr {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { singleton } from 'decorators/singleton'
|
|
||||||
import { queryPrice } from './alchemy.svr'
|
import { queryPrice } from './alchemy.svr'
|
||||||
import * as schedule from 'node-schedule'
|
import * as schedule from 'node-schedule'
|
||||||
import logger from 'logger/logger'
|
import logger from 'logger/logger'
|
||||||
|
import { singleton } from 'zutils'
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
export class PriceSvr {
|
export class PriceSvr {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user