const util = require('util'); const utils = require('./utils'); const db = require("./db"); const log = require("./log"); const ordermgr = require('./ordermgr'); const boxrepairer = require('./boxrepairer'); const bc = require('./blockchain'); const C = require('./C'); class BoxOrder { constructor(orderDb, isNewOrder) { this.isNewOrder = isNewOrder; this.orderDb = orderDb; this.repairer = new boxrepairer.BoxRepairer(this); } init () { if (this.isNewOrder) { setTimeout(this.start.bind(this), 1000 * 0.1 + Math.floor(Math.random() * 100)); } else { setTimeout(this.start.bind(this), 1000 * 1 + Math.floor(Math.random() * 1000 * 3)); } } async start() { if (this.isPaid()) { //修复已经支付成功订单的t_box表关系 await this.repairer.repairPaidOrder(); return; } if (this.isExpired()) { //修复已过期订单的t_box表关系 await this.repairer.repairExpiredOrder(); return; } if (this.isFail()) { //修复支付失败的订单 await this.repairFailOrder(); return; } if (!this.isSynced()) { //查询 let found = await this.bcSearch(); if (!found) { //上链 let ok = await this.bcSync(); if (!ok) { ordermgr.removePendingOrder(this.getOrderId()); return; } } } //等待确认支付成功 await this.bcConfirm(); ordermgr.removePendingOrder(this.getOrderId()); } async bcSearch() { return true; } async bcSync() { const logClass = 'bcSync'; let doSync = async () => { const result = await bc.mallInstance.methods.buyBoxWithSignature( this.orderDb['order_id'], this.orderDb['item_id'], this.orderDb['buyer_address'], this.orderDb['price'], this.orderDb['payment_token_address'], this.orderDb['nonce'], this.orderDb['signature']).send({gas: 1000000}); return result; }; while (true) { try { const result = doSync(); } catch (e) { log.warning(util.format('%s end orderDb:%s err:s', logClass, JSON.stringify(this.orderDb), e ) ); } await utils.sleep(1000 * 3 + Math.random() * 1000); } } async bcConfirm() { while (true) { await utils.sleep(1000 * 3); } } async getBoxDb(logClass) { let {err, row} = await db.execOneQuery('SELECT * FROM t_box where order_id=?', [ this.getOrderId() ]); if (!row) { log.warning(util.format('%s box not found orderDb:%s', logClass, JSON.stringify(this.orderDb), ) ); } return { 'err': err, 'boxDb': row }; } async setDone(logClass) { let err = await db.execScript('UPDATE t_box_order SET done=1 WHERE order_id=?', [ this.getOrderId() ]); if (err) { log.error(util.format('%s setDoneErr orderDb:%s err:%s', logClass, JSON.stringify(this.orderDb), err ) ); } else { log.error(util.format('%s setDoneOk orderDb:%s', logClass, JSON.stringify(this.orderDb) ) ); } return err; } async setBoxPaidState(logClass, boxDb) { let err = await db.execScript('UPDATE t_box SET state=? WHERE idx=?', [ BOX_STATE_PAID, boxDb['idx'] ]); if (err) { log.error(util.format('%s setBoxPaidState orderDb:%s boxDb:%s err:%s', logClass, JSON.stringify(this.orderDb), JSON.stringify(boxDb), err ) ); } else { log.error(util.format('%s setBoxPaidState orderDb:%s boxDb:%s', logClass, JSON.stringify(this.orderDb), JSON.stringify(boxDb), ) ); } return err; } async setBoxOrderInvalid(logClass, boxDb) { let err = await db.execScript('UPDATE t_box SET order_valid=0 WHERE idx=?', [ boxDb['idx'] ]); if (err) { log.error(util.format('%s setBoxOrderInvalid orderDb:%s boxDb:%s err:%s', logClass, JSON.stringify(this.orderDb), JSON.stringify(boxDb), err ) ); } else { log.error(util.format('%s setBoxOrderInvalid orderDb:%s boxDb:%s', logClass, JSON.stringify(this.orderDb), JSON.stringify(boxDb), ) ); } return err; } getOrderDb() { return this.orderDb; } getOrderId() { return this.orderDb['order_id']; } isExpired() { return this.orderDb['expired']; } isPaid() { return this.orderDb['state'] == ORDER_STATE_PAID; } isSynced() { return this.orderDb['bc_synced'] != 0; } isFail() { return this.isSynced() && this.orderDb['bc_result'] != BC_RESULT_OK; } }; exports.BoxOrder = BoxOrder;