qrcode-framework
Version:
474 lines • 35.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const sequelize_1 = require("sequelize");
const Common_1 = require("../common/Common");
const ErrorCode_1 = require("../common/ErrorCode");
const BaseService_1 = require("../core/BaseService");
const model_1 = require("../model");
const NumberUtil_1 = require("../util/NumberUtil");
const Order_1 = require("../util/Order");
class OrderService extends BaseService_1.default {
async createOrder(id, order, platform) {
const products = order.products || [];
// 检查产品状态
await this.checkProducts(id, products);
const code = Order_1.generateOrderId();
return await global.sequelize.transaction(async (t) => {
const coreOrder = await model_1.CoreOrder.create({
uid: id,
code,
meta: order.meta,
}, {
transaction: t,
});
const orderProducts = await model_1.CoreOrderProduct.bulkCreate(products.map((item) => {
return {
orderCode: code,
productType: item.type,
productId: item.id,
meta: item.meta,
};
}), {
transaction: t,
});
// 计算结算价格
const prices = await this.getProductsPrice(orderProducts, platform);
await model_1.CoreOrderPayment.bulkCreate(prices.map((item) => {
return {
orderCode: code,
payType: item.type,
payment: item.price,
meta: {
payType: item.type,
price: item.price,
payments: item.payments,
products: orderProducts,
},
};
}), {
transaction: t,
});
return coreOrder;
});
}
async changeStatus(code, status) {
const order = await model_1.CoreOrder.update({
status,
}, {
where: {
code,
},
});
return order;
}
async payOrder(code, payType, pays, extra = null) {
const order = await model_1.CoreOrder.findOne({
where: {
code,
},
});
if (!order) {
throw new ErrorCode_1.HttpError({
status: 400,
errorCode: ErrorCode_1.ERROR_CODE.COMMON.NOT_FOUND,
message: '订单不存在',
});
}
if (order.status === model_1.CORE_ORDER_STATUS.SUCCESS) {
throw new ErrorCode_1.HttpError({
status: 400,
errorCode: ErrorCode_1.ERROR_CODE.ORDER.ORDER_HAD_SUCCESS,
message: '订单已完成',
});
}
const user = await this.ctx.service.userService.getInfo(order.uid);
if (!user) {
throw new ErrorCode_1.HttpError({
status: 400,
errorCode: ErrorCode_1.ERROR_CODE.USER.NOT_FOUND,
message: '用户不存在',
});
}
const payment = await model_1.CoreOrderPayment.findOne({
where: {
payType,
orderCode: order.code,
},
});
if (!payment) {
throw new ErrorCode_1.HttpError({
message: '订单结算信息无效',
errorCode: ErrorCode_1.ERROR_CODE.ORDER.ORDER_INVALID_PAYMENT,
});
}
if (!this.canPay(user, payment)) {
throw new ErrorCode_1.HttpError({
message: '账户余额不足',
errorCode: ErrorCode_1.ERROR_CODE.COMMON.DEFAULT,
});
}
// if (payType === PAY_TYPE.MONEY && payment.payment !== this.calcTotalPayment(pays, payType)) {
// throw new HttpError({
// message: '订单校验错误,金额对账有误',
// errorCode: ERROR_CODE.ORDER.ORDER_VALIDATE_ERROR,
// });
// }
const payInfos = pays && pays.length ? pays : [{ type: payment.payType, payment: payment.payment }];
const products = await model_1.CoreOrderProduct.findAll({
where: {
orderCode: code,
deleted: false,
},
});
const divideId = this.ctx.state.qrcodeAgent ? this.ctx.state.qrcodeAgent.divideId : null;
return await global.sequelize.transaction(async (t) => {
// 更改订单状态
order.set('status', model_1.CORE_ORDER_STATUS.SUCCESS);
await order.save({
transaction: t,
});
// 如果存在三方ID,并且支付方式是金钱
if (payType === Common_1.PAY_TYPE.MONEY && divideId) {
await model_1.CoreOrderDivideId.create({
code: order.code,
divideid: divideId,
}, {
transaction: t,
});
}
// 修改结算状态
payment.set('status', model_1.CORE_ORDER_PAYMENT_STATUS.DONE);
await payment.save({
transaction: t,
});
await Promise.all([
// 创建支付记录
model_1.CoreOrderPayRecord.bulkCreate(payInfos.map((p) => {
return {
orderCode: order.code,
payType: p.type,
userPayment: p.payment,
outType: p.outType,
outId: p.outId,
meta: {
payInfo: p,
payment,
extra,
},
};
}), {
transaction: t,
}),
// 删除未使用到的结算记录
model_1.CoreOrderPayment.update({
deleted: true,
}, {
where: {
orderCode: order.code,
payType: {
[sequelize_1.Op.ne]: payType,
},
},
transaction: t,
}),
// 交付产品
this.payProduct(order.uid, products, { order }, t),
]);
await this.payPrice(user, payment, order, t);
return order;
});
}
async getOrder(code) {
const order = await model_1.CoreOrder.findOne({
where: {
code,
deleted: false,
},
include: [
{
model: model_1.CoreOrderProduct,
as: 'products',
required: false,
where: {
deleted: false,
},
},
{
model: model_1.CoreOrderPayment,
as: 'payments',
required: false,
attributes: ['payType', 'payment', 'status'],
where: {
deleted: false,
},
},
{
model: model_1.CoreOrderPayRecord,
as: 'payRecords',
required: false,
attributes: ['payType', 'userPayment', 'outType', 'outId', 'createdAt'],
},
],
});
return order;
}
async getOrders() {
const list = await model_1.CoreOrder.findAll({
where: {
deleted: false,
},
include: [
{
model: model_1.CoreOrderProduct,
as: 'products',
where: {
deleted: false,
},
},
],
});
return list;
}
async payPrice(user, payment, order, t) {
// 如果消耗的是积分,添加积分消耗记录,更改用户积分值
if (payment.payType === Common_1.PAY_TYPE.INTEGRAL && payment) {
return await Promise.all([
model_1.UserIntegralRecord.create({
uid: user.id,
value: -payment.payment,
latestValue: user.integral.value,
type: model_1.INTEGRAL_TYPE.BUY_EXPEND,
description: '支付订单消耗',
meta: {
order,
},
}, {
transaction: t,
}),
user.integral.decrement({
value: payment.payment,
}, {
transaction: t,
}),
]);
}
// 如果消耗的是马币,添加马币消耗记录,更改用户马币值
if (payment.payType === Common_1.PAY_TYPE.MABI && payment) {
return await Promise.all([
model_1.UserMabiRecord.create({
uid: user.id,
value: -payment.payment,
latestValue: user.mabi.value,
type: model_1.MABI_RECORD_TYPE.BUY_EXPEND,
description: '支付订单消耗',
meta: {
order,
},
}, {
transaction: t,
}),
user.mabi.decrement({
value: payment.payment,
}, {
transaction: t,
}),
]);
}
}
/**
* 获取订单支付信息
* @param products
*/
async getProductsPrice(products, platform) {
const prices = await Promise.all(products.map((p) => {
return new Promise(async (resolve) => {
const productType = parseInt(p.productType + '', 10);
let price = [];
switch (productType) {
case model_1.PRODUCT_TYPE.MATERIAL:
price = await this.ctx.service.materialService.getPrice(p.productId);
break;
case model_1.PRODUCT_TYPE.DYNAMIC_CODE:
price = await this.ctx.service.codeService.getDCodePrice(p.productId, p.meta.code, platform);
break;
case model_1.PRODUCT_TYPE.MABI:
price = await this.ctx.service.mabiService.getPrice(p.productId, platform);
break;
case model_1.PRODUCT_TYPE.CHANGE_DYNAMIC_CODE_TO:
price = await this.ctx.service.codeService.getDCodeChangeToPrice(p.productId, platform);
break;
case model_1.PRODUCT_TYPE.REWARD:
price = [{
payType: Common_1.PAY_TYPE.MONEY,
price: p.meta.price,
payment: {},
}];
break;
default:
break;
}
resolve(price);
});
}));
if (!prices || prices.length < 1) {
return [];
}
const result = [];
// 如果所有价格信息都具有金钱,就计算用金钱结算的总额是多少
const everyHasMoney = _.every(prices, (p) => {
return _.some(p, (item) => item.payType === Common_1.PAY_TYPE.MONEY);
});
if (everyHasMoney) {
let sumPrice = 0;
const payments = [];
prices.forEach((p) => {
// 查找用钱付款的价格条目
const price = _.find(p, (item) => item.payType === Common_1.PAY_TYPE.MONEY);
sumPrice += price.price;
payments.push(price.payment);
});
result.push({
type: Common_1.PAY_TYPE.MONEY,
price: sumPrice,
payments,
});
}
// 如果所有价格信息都具有积分,就计算用积分结算的总额是多少
const everyHasIntegral = _.every(prices, (p) => {
return _.some(p, (item) => item.payType === Common_1.PAY_TYPE.INTEGRAL);
});
if (everyHasIntegral) {
let sumPrice = 0;
const payments = [];
prices.forEach((p) => {
// 查找用钱付款的价格条目
const price = _.find(p, (item) => item.payType === Common_1.PAY_TYPE.INTEGRAL);
sumPrice += price.price;
payments.push(price.payment);
});
result.push({
type: Common_1.PAY_TYPE.INTEGRAL,
price: sumPrice,
payments,
});
}
// 如果所有价格信息都具有马币,就计算用马币结算的总额是多少
const everyHasMabi = _.every(prices, (p) => {
return _.some(p, (item) => item.payType === Common_1.PAY_TYPE.MABI);
});
if (everyHasMabi) {
let sumPrice = 0;
const payments = [];
prices.forEach((p) => {
// 查找用马币付款的价格条目
const price = _.find(p, (item) => item.payType === Common_1.PAY_TYPE.MABI);
sumPrice += price.price;
payments.push(price.payment);
});
result.push({
type: Common_1.PAY_TYPE.MABI,
price: sumPrice,
payments,
});
}
if (!everyHasMoney && !everyHasIntegral && !everyHasMabi) {
throw new ErrorCode_1.HttpError({
message: '无法获取订单价格信息,订单内产品结算冲突,请取消订单重新下单',
errorCode: ErrorCode_1.ERROR_CODE.ORDER.ORDER_PRICE_ERROR,
});
}
return result;
}
// private calcTotalPayment(pays: any[], type: number) {
// return _.sumBy(pays.filter((p) => p.type === type), 'payment');
// }
/**
* 交付产品
* @param uid
* @param products
* @param meta
* @param t
*/
async payProduct(uid, products, meta, t) {
await Promise.all(products.map((p) => {
return new Promise(async (resolve, reject) => {
try {
if (p.productType === model_1.PRODUCT_TYPE.MATERIAL) {
const m = await model_1.UserToMaterial.create({
uid,
mid: p.productId,
meta,
}, {
transaction: t,
});
resolve(m);
}
else if (p.productType === model_1.PRODUCT_TYPE.DYNAMIC_CODE) {
const dynamicCode = await this.ctx.service.codeService.activeDCodePrice(p.productId, p.meta.code, t);
resolve(dynamicCode);
}
else if (p.productType === model_1.PRODUCT_TYPE.MABI) {
const mabi = await this.ctx.service.mabiService.addMabi(uid, p.productId, t);
resolve(mabi);
}
else if (p.productType === model_1.PRODUCT_TYPE.CHANGE_DYNAMIC_CODE_TO) {
const mabi = await this.ctx.service.codeService.updateDynamicCodeTo(uid, p.productId, p.meta.code, t);
resolve(mabi);
}
else {
resolve();
}
}
catch (e) {
reject(e);
}
});
}));
}
canPay(user, payment) {
if (payment.payType === Common_1.PAY_TYPE.INTEGRAL) {
return user.integral.value >= payment.payment;
}
if (payment.payType === Common_1.PAY_TYPE.MABI) {
return user.mabi.value >= payment.payment;
}
return true;
}
async checkProducts(uid, products) {
// 检查用户是否购买过素材
const materials = products.filter((p) => NumberUtil_1.isEqual(p.type, model_1.PRODUCT_TYPE.MATERIAL));
if (materials && materials.length) {
const mArray = await model_1.UserToMaterial.findAll({
where: {
uid,
mid: {
[sequelize_1.Op.in]: materials.map((m) => m.id),
},
},
});
if (mArray && mArray.length > 0) {
throw new ErrorCode_1.HttpError({
message: `素材已购买,无法创建订单`,
errorCode: ErrorCode_1.ERROR_CODE.USER.HAS_MATERIAL,
status: 400,
});
}
}
// 检查用户更新的动态码是不是过期
const updateDCodes = products.filter((p) => NumberUtil_1.isEqual(p.type, model_1.PRODUCT_TYPE.CHANGE_DYNAMIC_CODE_TO));
if (updateDCodes && updateDCodes.length) {
const valid = await this.ctx.service.codeService.isValidCodes(uid, updateDCodes.map((i) => i.id));
if (!valid) {
throw new ErrorCode_1.HttpError({
message: `个性码当前状态无法进行此操作`,
errorCode: ErrorCode_1.ERROR_CODE.CODE.INVALID,
status: 400,
});
}
}
return true;
}
}
exports.default = OrderService;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3JkZXJTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiT3JkZXJTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNEJBQTRCO0FBQzVCLHlDQUE2QjtBQUM3Qiw2Q0FBMEM7QUFDMUMsbURBQTBEO0FBQzFELHFEQUE4QztBQUM5QyxvQ0FTa0I7QUFFbEIsbURBQTJDO0FBQzNDLHlDQUE4QztBQUU5QyxNQUFxQixZQUFhLFNBQVEscUJBQVc7SUFFMUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFVLEVBQUUsS0FFcEMsRUFBRSxRQUFpQjtRQUNoQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUN0QyxTQUFTO1FBQ1QsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2QyxNQUFNLElBQUksR0FBRyx1QkFBZSxFQUFFLENBQUM7UUFFL0IsT0FBTyxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNsRCxNQUFNLFNBQVMsR0FBRyxNQUFNLGlCQUFTLENBQUMsTUFBTSxDQUFDO2dCQUNyQyxHQUFHLEVBQUUsRUFBRTtnQkFDUCxJQUFJO2dCQUNKLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTthQUNuQixFQUFFO2dCQUNDLFdBQVcsRUFBRSxDQUFDO2FBQ2pCLENBQUMsQ0FBQztZQUVILE1BQU0sYUFBYSxHQUFHLE1BQU0sd0JBQWdCLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDMUUsT0FBTztvQkFDSCxTQUFTLEVBQUUsSUFBSTtvQkFDZixXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUk7b0JBQ3RCLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRTtvQkFDbEIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO2lCQUNsQixD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