OrderCourtesyLogic.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. namespace addons\WriteOff\common\logic;
  3. use addons\WriteOff\common\models\WriteOffMember;
  4. use addons\WriteOff\common\models\WriteOffMemberLog;
  5. use addons\WriteOff\common\models\WriteOffSetting;
  6. use addons\WriteOff\common\models\WriteOffMemberCode;
  7. use addons\WriteOff\common\helpers\QrcodeHelper;
  8. use addons\WriteOff\common\enums\WriteOffEnum;
  9. use common\enums\AddonsEnum;
  10. use common\enums\RabbitMqEnum;
  11. use common\enums\StatusEnum;
  12. use common\helpers\TaskHelper;
  13. use common\models\mall\MallAddons;
  14. use common\models\order\Order;
  15. use common\models\order\OrderDetail;
  16. use common\traits\ErrorTrait;
  17. use PhpAmqpLib\Message\AMQPMessage;
  18. use common\helpers\LockHelper;
  19. use common\enums\RedisKeyEnum;
  20. use yii\helpers\Json;
  21. use yii\db\Exception;
  22. use Yii;
  23. class OrderCourtesyLogic
  24. {
  25. use ErrorTrait;
  26. public static function giveReward($order_id, $order_status = 0)
  27. {
  28. try {
  29. // 查询订单
  30. $order = Order::findOne($order_id);
  31. $select = "id,mall_id,goods_id,user_id,goods_price,order_id,num";
  32. $order_details = OrderDetail::find()->select($select)->where(['order_id' => $order_id])->asArray()->all();
  33. if (empty($order_details)) throw new \Exception("订单id={$order_id}的订单详情数据为空");
  34. $goods_ids = array_column($order_details, 'goods_id'); // 商品ids
  35. $mall_id = $order_details[0]['mall_id'];
  36. $user_id = $order_details[0]['user_id'];
  37. $isInstall = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_WRITE_Off);
  38. if(!$isInstall) return true;
  39. // 获取配置
  40. $config = Yii::$app->services->setting->addons->get($mall_id, WriteOffEnum::ADDONS_NAME, 'basic');
  41. if(empty($config['is_enable'])) return true;
  42. // 获取设置了奖励的商品
  43. $list = WriteOffSetting::find()->where(['goods_id' => $goods_ids, 'is_enable' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED])->indexBy('goods_id')->asArray()->all();
  44. if (empty($list)) return true;
  45. $t = Yii::$app->db->beginTransaction();
  46. try {
  47. $queue_data = [];
  48. foreach ($order_details as $detail) {
  49. $goods_id = $detail['goods_id'];
  50. $setting = $list[$goods_id] ?? [];
  51. if (empty($setting)) continue;
  52. $settlement_method = $setting['settlement_method'];
  53. if ($settlement_method != $order_status) continue;
  54. $give_num = bcmul($setting['give_num'], $detail['num']);
  55. if ($give_num <= 0) continue;
  56. $writeOffMember = WriteOffMember::findOne(['user_id' => $detail['user_id'],'mall_id' => $detail['mall_id'], 'status' => StatusEnum::ENABLED]);
  57. if(empty($writeOffMember)){
  58. $writeOffMember = new WriteOffMember();
  59. $writeOffMember->mall_id = $detail['mall_id'];
  60. $writeOffMember->user_id = $detail['user_id'];
  61. }
  62. $writeOffMember->num += $give_num;
  63. $writeOffMember->total_num += $give_num;
  64. if(!$writeOffMember->save()) throw new \Exception(WriteOffMember::getStaticError());
  65. $writeOffMemberLog = WriteOffMemberLog::findOne(['source_table' => OrderDetail::tableName(), 'source_table_id' => $detail['id']]);
  66. if(!empty($writeOffMemberLog)) throw new \Exception("已存在赠送记录");
  67. $params = [
  68. 'setting_id' => $setting['id'],
  69. 'goods_id' => $goods_id,
  70. 'user_id' => $detail['user_id'],
  71. 'mall_id' => $detail['mall_id'],
  72. 'change_num' => $give_num,
  73. 'current_num' => $writeOffMember->num,
  74. 'order_no' => $order['order_no'] ?? '',
  75. 'source_table' => OrderDetail::tableName(),
  76. 'source_table_id' => $detail['id'],
  77. 'desc' => '用户购买商品(订单:'.$order_id.')获得核销数量:'.$give_num,
  78. 'change_type' => 'add',
  79. ];
  80. $model = WriteOffMemberLog::setData($params);
  81. if ($model === false) throw new \Exception(WriteOffMemberLog::getStaticError());
  82. // if(empty($writeOffMember->code_url) && empty($queue_data)){
  83. // $queue_data = [
  84. // 'id' => $writeOffMember->id,
  85. // 'mall_id' => $detail['mall_id'],
  86. // ];
  87. // }
  88. //生成核销码
  89. $code = 10000000;
  90. for($i=0;$i<$give_num;$i++){
  91. $code_params = [
  92. 'user_id' => $detail['user_id'],
  93. 'mall_id' => $detail['mall_id'],
  94. ];
  95. $codeModel = WriteOffMemberCode::setData($code_params);
  96. if ($codeModel === false) throw new \Exception(WriteOffMemberCode::getStaticError());
  97. $codeModel->code = $code + $codeModel->id;
  98. if(!$codeModel->save()){
  99. throw new \Exception("核销码生成失败,order_id:".$order_id);
  100. }
  101. }
  102. }
  103. $t->commit();
  104. // if(!empty($queue_data)){
  105. // TaskHelper::pushTaskQueue(RabbitMqEnum::ORDER_QUEUE, RabbitMqEnum::TASK_QUEUE, $queue_data, self::class, 'createQrcode', function (AMQPMessage $message) {
  106. // Yii::error('核销码发送异步任务失败');
  107. // });
  108. // }
  109. } catch (\Exception $ex) {
  110. $t->rollBack();
  111. throw new \Exception($ex->getMessage());
  112. }
  113. return true;
  114. } catch (\Exception $e) {
  115. self::setStaticError($e->getMessage());
  116. return false;
  117. }
  118. }
  119. /**
  120. * 生成核销码
  121. */
  122. public static function createCode($mall_id){
  123. $lock_key = RedisKeyEnum::suffix('lock_write_off_create_code', $mall_id);
  124. $identification = uniqid();
  125. if (!LockHelper::lock($lock_key, $identification, 100, 100)) {
  126. \Yii::error('CardCoupons give 获取锁(' . $lock_key . ')失败阻塞');
  127. return false;
  128. }
  129. try{
  130. $scalar = WriteOffMember::find()
  131. ->where(['mall_id'=>$mall_id])->orderBy('id desc')
  132. ->andWhere(['!=','code',0])
  133. ->select('code')
  134. ->scalar();
  135. if(empty($scalar)){
  136. $code = 10000000;
  137. }else{
  138. $code = $scalar + 1;
  139. }
  140. LockHelper::uLock($lock_key, $identification);
  141. return $code;
  142. }catch(\Exception $e){
  143. LockHelper::uLock($lock_key, $identification);
  144. return false;
  145. }
  146. }
  147. /**
  148. * 生成核销二维码
  149. */
  150. public static function createQrcode($params)
  151. {
  152. try {
  153. $info = WriteOffMember::findOne(['id' => $params['id']]);
  154. if (empty($info)) throw new \Exception('id错误');
  155. if(empty($info['code'])){
  156. $code = self::createCode($params['mall_id']);
  157. if(!$code) throw new \Exception('生成核销码错误');
  158. }else{
  159. $code = $info['code'];
  160. }
  161. $staticPath = \Yii::getAlias('@attachment');
  162. $qrcodeParentDir = '/download/addons/WriteOff/qrcode/' . date('Y-m-d');
  163. $qrcodeTargetDir = $staticPath . $qrcodeParentDir;
  164. if (!is_dir($qrcodeTargetDir)) {
  165. mkdir($qrcodeTargetDir, 0755, true);
  166. }
  167. $content = $code;
  168. $qrcodeFilename = $code . '.png';
  169. $qrcodePath = $qrcodeTargetDir . '/' . $qrcodeFilename;
  170. $qrcodeHelper = new QrcodeHelper($content, $code);
  171. $qrcodeHelper->save2File($qrcodePath);
  172. if (!file_exists($qrcodePath)) throw new \Exception('二维码生成失败');
  173. $attachUrl = \Yii::getAlias('@attachurl');
  174. $info->code_url = $attachUrl . $qrcodeParentDir . '/' . $qrcodeFilename;
  175. $info->code = $code;
  176. if (!$info->save()) throw new \Exception($info->getErrorMessage());
  177. } catch (\Exception $e) {
  178. $msg = self::class . '->' . __FUNCTION__ . '//errMsg:' . $e->getMessage() . '//params:' . Json::encode($params);
  179. echo $msg . PHP_EOL;
  180. \Yii::error($msg);
  181. } finally {
  182. return true;
  183. }
  184. }
  185. }