|
@@ -7,7 +7,115 @@ const assert = require('assert');
|
|
class ZrOrderService extends CrudService {
|
|
class ZrOrderService extends CrudService {
|
|
constructor(ctx) {
|
|
constructor(ctx) {
|
|
super(ctx, 'zrorder');
|
|
super(ctx, 'zrorder');
|
|
|
|
+ this.redis = this.app.redis;
|
|
|
|
+ this.redisKey = this.app.config.redisKey;
|
|
|
|
+ this.redisTimeout = this.app.config.redisTimeout;
|
|
this.model = this.ctx.model.ZrOrder;
|
|
this.model = this.ctx.model.ZrOrder;
|
|
|
|
+ this.goodsModel = this.ctx.model.ZrGoods;
|
|
|
|
+ this.pointModel = this.ctx.model.Base.Point;
|
|
|
|
+ this.shopModel = this.ctx.model.Base.Shop;
|
|
|
|
+ }
|
|
|
|
+ // 进入订单页前,通过函数判断,存储是否可以购买 指定商品 的 指定数量
|
|
|
|
+ // 下单,走同样的函数判断.
|
|
|
|
+ // 直接生成订单,扣除积分
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ async toMakeOrder({ key }) {
|
|
|
|
+ key = `${this.redisKey.orderKeyPrefix}${key}`;
|
|
|
|
+ let data = await this.redis.get(key);
|
|
|
|
+ if (!data) throw new BusinessError(ErrorCode.SERVICE_FAULT, '请求超时,请重新进入下单页');
|
|
|
|
+ data = JSON.parse(data);
|
|
|
|
+ const { shop, goods, num: buy_num } = data;
|
|
|
|
+ const shopInfo = await this.shopModel.findById(shop);
|
|
|
|
+ // const goodsInfo = await this.
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 检查是否可以购买商品,并生成缓存
|
|
|
|
+ * @param {Object} body 参数体
|
|
|
|
+ * @param body.shop 店铺id
|
|
|
|
+ * @param body.goods 尊荣商品id
|
|
|
|
+ * @param body.num 购买数量
|
|
|
|
+ * @param {Boolean} makeCache 是否生成缓存
|
|
|
|
+ */
|
|
|
|
+ async checkCanBuy({ shop, goods, num }, makeCache = true) {
|
|
|
|
+ const result = { result: true };
|
|
|
|
+ const shopInfo = await this.shopModel.findById(shop);
|
|
|
|
+ if (!shopInfo || _.get(shopInfo, '1')) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '店铺当前不处于营业状态';
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ const goodsInfo = await this.goodsModel.findById(goods);
|
|
|
|
+ if (!goodsInfo) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '未找到尊荣商品';
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ const user = this.ctx.user;
|
|
|
|
+ const customer = _.get(user, '_id');
|
|
|
|
+ if (!customer) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '未找到用户信息';
|
|
|
|
+ }
|
|
|
|
+ // #region 库存判断
|
|
|
|
+ const knum = _.get(goodsInfo, 'num');
|
|
|
|
+ const res = this.ctx.minus(knum, num);
|
|
|
|
+ if (res <= 0) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '库存不足';
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ // #endregion
|
|
|
|
+
|
|
|
|
+ // #region 积分判断
|
|
|
|
+ const pointTotal = await this.pointComputedTotal({ customer });
|
|
|
|
+ // 计算购买所需积分
|
|
|
|
+ const cost = _.get(goodsInfo, 'cost', 0);
|
|
|
|
+ if (cost === 0) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '商品设置的尊荣有误,无法进行购买';
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ const costTotal = this.ctx.multiply(cost, num);
|
|
|
|
+ const afterCost = this.ctx.minus(pointTotal, costTotal);
|
|
|
|
+ if (afterCost < 0) {
|
|
|
|
+ result.result = false;
|
|
|
|
+ result.msg = '您的积分不足';
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ // #endregion
|
|
|
|
+
|
|
|
|
+ if (makeCache) {
|
|
|
|
+ const key = await this.makeOrderKey({ shop, goods, num });
|
|
|
|
+ result.key = key;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 生成key
|
|
|
|
+ async makeOrderKey(data) {
|
|
|
|
+ const str = this.createNonceStr();
|
|
|
|
+ const key = `${this.redisKey.orderKeyPrefix}${str}`;
|
|
|
|
+ const value = JSON.stringify(data);
|
|
|
|
+ await this.redis.set(key, value, 'EX', this.redisTimeout);
|
|
|
|
+ return str;
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 计算用户的积分
|
|
|
|
+ * @param {Object} data 数据对象
|
|
|
|
+ * @param data.customer 用户数据id
|
|
|
|
+ */
|
|
|
|
+ async pointComputedTotal({ customer }) {
|
|
|
|
+ assert(customer, '缺少用户信息');
|
|
|
|
+ const res = await this.pointModel.find({ customer });
|
|
|
|
+ const total = res.reduce((p, n) => {
|
|
|
|
+ let point = n.point;
|
|
|
|
+ if (!(n.source === '0' || n.source === '1')) point = -point;
|
|
|
|
+ return this.ctx.plus(p, point);
|
|
|
|
+ }, 0);
|
|
|
|
+ return total;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|