214 lines
5.9 KiB
JavaScript
214 lines
5.9 KiB
JavaScript
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;
|