275 lines
7.3 KiB
JavaScript
275 lines
7.3 KiB
JavaScript
const util = require('util');
|
|
const utils = require('./utils');
|
|
const db = require("./db");
|
|
const dbhelper = require("./dbhelper");
|
|
const log = require("./log");
|
|
const bc = require('./blockchain');
|
|
const metamgr = require('./metamgr');
|
|
const C = require('./C');
|
|
|
|
class BoxOrder {
|
|
|
|
constructor(orderDb, isNewOrder) {
|
|
this.isNewOrder = isNewOrder;
|
|
this.orderDb = orderDb;
|
|
}
|
|
|
|
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()) {
|
|
//修复已支付成功订单token_id
|
|
await this.repairPaidOrder();
|
|
utils.emitEvent(C.REMOVE_PENDING_ORDER_EVENT, this.getOrderId());
|
|
} else {
|
|
if (!this.isSynced()) {
|
|
//查询
|
|
const found = await this.bcSearch();
|
|
if (!found) {
|
|
//上链
|
|
const ok = await this.bcSync();
|
|
if (!ok) {
|
|
utils.emitEvent(C.REMOVE_PENDING_ORDER_EVENT, this.getOrderId());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
//等待确认支付成功
|
|
await this.bcConfirm();
|
|
}
|
|
}
|
|
|
|
async repairPaidOrder() {
|
|
const logClass = 'repairPaidOrder';
|
|
log.info(util.format('%s begin orderDb:%s',
|
|
logClass,
|
|
JSON.stringify(this.getOrderDb()),
|
|
)
|
|
);
|
|
await this.bcMintHero();
|
|
await this.updateDb(logClass,
|
|
[
|
|
['done', 1]
|
|
]);
|
|
log.info(util.format('%s end orderDb:%s',
|
|
logClass,
|
|
JSON.stringify(this.getOrderDb()),
|
|
)
|
|
);
|
|
}
|
|
|
|
async bcSearch() {
|
|
const logClass = 'bcSearch';
|
|
const events = await bc.mallInstance.getPastEvents(
|
|
'BEBoxPaid',
|
|
{
|
|
fromBlock: 0,
|
|
toBlock: 'latest',
|
|
filter: {
|
|
boxId: this.getOrderId()
|
|
}
|
|
});
|
|
if (events.length > 0) {
|
|
while (true) {
|
|
const err = await this.updateDb(logClass,
|
|
[
|
|
['bc_synced', 1]
|
|
]);
|
|
if (!err) {
|
|
break;
|
|
}
|
|
await utils.sleep(1000 * 3);
|
|
}
|
|
this.orderDb['bc_synced'] = 1;
|
|
}
|
|
return events.length > 0;
|
|
}
|
|
|
|
async bcSync() {
|
|
const logClass = 'bcSync';
|
|
const doSync = async () => {
|
|
//log.debug(JSON.stringify(this.orderDb));
|
|
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 = await doSync();
|
|
const nowTime = utils.getUtcTime();
|
|
const blockNumber = result['blockNumber'];
|
|
const err = await this.updateDb(
|
|
logClass,
|
|
[
|
|
['state', C.ORDER_STATE_PAID],
|
|
['bc_synced', 1],
|
|
['bc_sync_count', 1],
|
|
['bc_sync_time', nowTime],
|
|
['bc_result', 1],
|
|
['bc_block_number', blockNumber],
|
|
['bc_fail_reason', ''],
|
|
]
|
|
);
|
|
this.orderDb['bc_synced'] = 1;
|
|
this.orderDb['bc_sync_count'] += 1;
|
|
this.orderDb['bc_sync_time'] = nowTime;
|
|
this.orderDb['bc_sync_number'] = blockNumber;
|
|
return true;
|
|
} 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() {
|
|
const logClass = 'bcConfirm';
|
|
|
|
while (true) {
|
|
if (bc.isComfirmed(this.getBlockNumber())) {
|
|
break;
|
|
}
|
|
await utils.sleep(1000 * 3);
|
|
}
|
|
|
|
while (true) {
|
|
const err = await this.bcMintHero();
|
|
if (!err) {
|
|
break;
|
|
}
|
|
await utils.sleep(1000 * 3);
|
|
}
|
|
|
|
while (true) {
|
|
const err = await this.updateDb(logClass,
|
|
[
|
|
['done', 1]
|
|
]);
|
|
if (!err) {
|
|
break;
|
|
}
|
|
await utils.sleep(1000 * 3);
|
|
}
|
|
|
|
utils.emitEvent(C.REMOVE_PENDING_ORDER_EVENT, this.getOrderId());
|
|
}
|
|
|
|
async bcMintHero() {
|
|
const logClass = 'bcMintHero';
|
|
const userAddress = metamgr.getUserAddress();
|
|
const tokenId = this.getOrderId();
|
|
const result = await bc.factoryInstance.methods.mintHeroTo(
|
|
userAddress,
|
|
tokenId).send({ gas: 1000000 });
|
|
{
|
|
const err = await this.updateDb(
|
|
logClass,
|
|
[
|
|
['token_id', tokenId]
|
|
]
|
|
);
|
|
}
|
|
{
|
|
const nowTime = utils.getUtcTime();
|
|
const fieldList = [
|
|
['token_id', tokenId],
|
|
['item_id', this.orderDb['item_id']],
|
|
['owner_id', ''],
|
|
['owner_address', this.orderDb['buyer_address']],
|
|
['owner_name', ''],
|
|
['createtime', nowTime],
|
|
['modifytime', nowTime],
|
|
];
|
|
const err = await dbhelper.insert(
|
|
't_nft',
|
|
fieldList);
|
|
if (err) {
|
|
log.error(util.format('%s insert nft table orderDb:%s fieldList:%s err:%s',
|
|
logClass,
|
|
JSON.stringify(this.orderDb),
|
|
JSON.stringify(fieldList),
|
|
err
|
|
)
|
|
);
|
|
} else {
|
|
log.info(util.format('%s insert nft table orderDb:%s',
|
|
logClass,
|
|
JSON.stringify(this.orderDb),
|
|
JSON.stringify(fieldList)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
async updateDb(logClass, fieldList) {
|
|
const err = await dbhelper.update(
|
|
't_box_order',
|
|
[
|
|
['order_id', this.getOrderId()]
|
|
],
|
|
fieldList);
|
|
if (err) {
|
|
log.error(util.format('%s updateDb orderDb:%s fieldList:%s err:%s',
|
|
logClass,
|
|
JSON.stringify(this.orderDb),
|
|
JSON.stringify(fieldList),
|
|
err
|
|
)
|
|
);
|
|
} else {
|
|
log.info(util.format('%s updateDb orderDb:%s',
|
|
logClass,
|
|
JSON.stringify(this.orderDb),
|
|
JSON.stringify(fieldList)
|
|
)
|
|
);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
getOrderDb() {
|
|
return this.orderDb;
|
|
}
|
|
|
|
getOrderId() {
|
|
return this.orderDb['order_id'];
|
|
}
|
|
|
|
getBlockNumber() {
|
|
return this.orderDb['bc_block_number'];
|
|
}
|
|
|
|
isPaid() {
|
|
return this.orderDb['state'] == C.ORDER_STATE_PAID;
|
|
}
|
|
|
|
isSynced() {
|
|
return this.orderDb['bc_synced'] != 0;
|
|
}
|
|
|
|
isFail() {
|
|
return this.isSynced() && this.orderDb['bc_result'] != C.BC_RESULT_OK;
|
|
}
|
|
|
|
};
|
|
|
|
exports.BoxOrder = BoxOrder;
|