select($select)->where(['order_id' => $order_id])->asArray()->all(); if (empty($order_details)) throw new \Exception("订单id={$order_id}的订单详情数据为空"); $goods_ids = array_column($order_details, 'goods_id'); // 商品ids $mall_id = $order_details[0]['mall_id']; $user_id = $order_details[0]['user_id']; $isInstall = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_WRITE_Off); if(!$isInstall) return true; // 获取配置 $config = Yii::$app->services->setting->addons->get($mall_id, WriteOffEnum::ADDONS_NAME, 'basic'); if(empty($config['is_enable'])) return true; // 获取设置了奖励的商品 $list = WriteOffSetting::find()->where(['goods_id' => $goods_ids, 'is_enable' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED])->indexBy('goods_id')->asArray()->all(); if (empty($list)) return true; $t = Yii::$app->db->beginTransaction(); try { $queue_data = []; foreach ($order_details as $detail) { $goods_id = $detail['goods_id']; $setting = $list[$goods_id] ?? []; if (empty($setting)) continue; $settlement_method = $setting['settlement_method']; if ($settlement_method != $order_status) continue; $give_num = bcmul($setting['give_num'], $detail['num']); if ($give_num <= 0) continue; $writeOffMember = WriteOffMember::findOne(['user_id' => $detail['user_id'],'mall_id' => $detail['mall_id'], 'status' => StatusEnum::ENABLED]); if(empty($writeOffMember)){ $writeOffMember = new WriteOffMember(); $writeOffMember->mall_id = $detail['mall_id']; $writeOffMember->user_id = $detail['user_id']; } $writeOffMember->num += $give_num; $writeOffMember->total_num += $give_num; if(!$writeOffMember->save()) throw new \Exception(WriteOffMember::getStaticError()); $writeOffMemberLog = WriteOffMemberLog::findOne(['source_table' => OrderDetail::tableName(), 'source_table_id' => $detail['id']]); if(!empty($writeOffMemberLog)) throw new \Exception("已存在赠送记录"); $params = [ 'setting_id' => $setting['id'], 'goods_id' => $goods_id, 'user_id' => $detail['user_id'], 'mall_id' => $detail['mall_id'], 'change_num' => $give_num, 'current_num' => $writeOffMember->num, 'order_no' => $order['order_no'] ?? '', 'source_table' => OrderDetail::tableName(), 'source_table_id' => $detail['id'], 'desc' => '用户购买商品(订单:'.$order_id.')获得核销数量:'.$give_num, 'change_type' => 'add', ]; $model = WriteOffMemberLog::setData($params); if ($model === false) throw new \Exception(WriteOffMemberLog::getStaticError()); // if(empty($writeOffMember->code_url) && empty($queue_data)){ // $queue_data = [ // 'id' => $writeOffMember->id, // 'mall_id' => $detail['mall_id'], // ]; // } //生成核销码 $code = 10000000; for($i=0;$i<$give_num;$i++){ $code_params = [ 'user_id' => $detail['user_id'], 'mall_id' => $detail['mall_id'], ]; $codeModel = WriteOffMemberCode::setData($code_params); if ($codeModel === false) throw new \Exception(WriteOffMemberCode::getStaticError()); $codeModel->code = $code + $codeModel->id; if(!$codeModel->save()){ throw new \Exception("核销码生成失败,order_id:".$order_id); } } } $t->commit(); // if(!empty($queue_data)){ // TaskHelper::pushTaskQueue(RabbitMqEnum::ORDER_QUEUE, RabbitMqEnum::TASK_QUEUE, $queue_data, self::class, 'createQrcode', function (AMQPMessage $message) { // Yii::error('核销码发送异步任务失败'); // }); // } } catch (\Exception $ex) { $t->rollBack(); throw new \Exception($ex->getMessage()); } return true; } catch (\Exception $e) { self::setStaticError($e->getMessage()); return false; } } /** * 生成核销码 */ public static function createCode($mall_id){ $lock_key = RedisKeyEnum::suffix('lock_write_off_create_code', $mall_id); $identification = uniqid(); if (!LockHelper::lock($lock_key, $identification, 100, 100)) { \Yii::error('CardCoupons give 获取锁(' . $lock_key . ')失败阻塞'); return false; } try{ $scalar = WriteOffMember::find() ->where(['mall_id'=>$mall_id])->orderBy('id desc') ->andWhere(['!=','code',0]) ->select('code') ->scalar(); if(empty($scalar)){ $code = 10000000; }else{ $code = $scalar + 1; } LockHelper::uLock($lock_key, $identification); return $code; }catch(\Exception $e){ LockHelper::uLock($lock_key, $identification); return false; } } /** * 生成核销二维码 */ public static function createQrcode($params) { try { $info = WriteOffMember::findOne(['id' => $params['id']]); if (empty($info)) throw new \Exception('id错误'); if(empty($info['code'])){ $code = self::createCode($params['mall_id']); if(!$code) throw new \Exception('生成核销码错误'); }else{ $code = $info['code']; } $staticPath = \Yii::getAlias('@attachment'); $qrcodeParentDir = '/download/addons/WriteOff/qrcode/' . date('Y-m-d'); $qrcodeTargetDir = $staticPath . $qrcodeParentDir; if (!is_dir($qrcodeTargetDir)) { mkdir($qrcodeTargetDir, 0755, true); } $content = $code; $qrcodeFilename = $code . '.png'; $qrcodePath = $qrcodeTargetDir . '/' . $qrcodeFilename; $qrcodeHelper = new QrcodeHelper($content, $code); $qrcodeHelper->save2File($qrcodePath); if (!file_exists($qrcodePath)) throw new \Exception('二维码生成失败'); $attachUrl = \Yii::getAlias('@attachurl'); $info->code_url = $attachUrl . $qrcodeParentDir . '/' . $qrcodeFilename; $info->code = $code; if (!$info->save()) throw new \Exception($info->getErrorMessage()); } catch (\Exception $e) { $msg = self::class . '->' . __FUNCTION__ . '//errMsg:' . $e->getMessage() . '//params:' . Json::encode($params); echo $msg . PHP_EOL; \Yii::error($msg); } finally { return true; } } }