聚合供应链 * @property int|null $created_at 创建时间 * @property int|null $updated_at 更新时间 * @property string|null $clerk_code 核销码 * @property array|null $extra_data 额外信息 * @property int $goods_subtype 订单商品子类型 (0:普通商品 其他:根据商品的goods_subtype而定) */ class Order extends \common\models\base\BaseActiveRecord { const DEFAULT = 'order'; public static $getRefundId; /** * {@inheritdoc} */ public static function tableName() { return '{{%order}}'; } /** * {@inheritdoc} */ public function rules() { return [ [['mch_id','store_id', 'mall_id','user_id', 'province', 'city', 'area','town', 'shipping_type', 'coupon_id', 'order_status', 'pay_status', 'shipping_status', 'review_status', 'is_feedback', 'payment_type', 'marketing_id', 'invoice_id', 'status', 'is_comment', 'is_recycle', 'is_virtual', 'is_new_user', 'pay_time', 'shipping_time', 'sign_time', 'consign_time', 'finish_time', 'close_time', 'created_at', 'updated_at', 'community','is_bill','bill_time', 'goods_subtype'], 'integer'], [['shipping_money', 'reduce_shipping_money', 'refund_money', 'pay_money', 'score', 'goods_price', 'original_goods_price', 'coupon_money', 'score_money'], 'number'], [['order_no', 'out_trade_no'], 'string', 'max' => 100], [['mobile', 'extra_data'], 'safe'], [['address', 'region_name'], 'string', 'max' => 200], [['zip', 'ip'], 'string', 'max' => 20], [['receiver_name', 'marketing_type', 'order_source'], 'string', 'max' => 50], [['remark', 'seller_remark'], 'string', 'max' => 255], [['extra_info'], 'string'], [['clerk_code'], 'string', 'max' => 12], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => '订单id', 'mall_id' => '商城ID', 'mch_id' => '多商户id,0表示商城订单', 'store_id' => '门店i', 'user_id' => '用户id', 'order_no' => '订单编号', 'out_trade_no' => '外部交易号', 'mobile' => '收货人的手机号码', 'province' => '收货人所在省', 'city' => '收货人所在城市', 'area' => '收货人所在街道', 'town' => '收货人所在镇', 'address' => '收货详细地址', 'region_name' => '收货地区名称(省市区[乡/镇])', 'zip' => '收货人邮编', 'receiver_name' => '收货人姓名', 'remark' => '用户订单备注', 'seller_remark' => '商家订单备注', 'shipping_type' => '订单配送方式', 'shipping_money' => '订单运费', 'reduce_shipping_money' => '满邮减免', 'refund_money' => '订单退款金额', 'pay_money' => '订单实付金额', 'goods_price' => '商品优惠后总价', 'original_goods_price' => '商品原本总价', 'ip' => '买家ip', 'coupon_id' => '优惠券券id', 'coupon_money' => '优惠券券支付金额', 'score' => '订单消耗积分', 'score_money' => '订单消耗积分抵多少钱', 'order_status' => '订单状态', 'pay_status' => '订单付款状态', 'shipping_status' => '订单配送状态', 'review_status' => '订单评价状态', 'is_feedback' => '订单售后状态:0:未售后;1:售后中;2:售后完成', 'payment_type' => '支付类型', 'marketing_id' => '营销活动id', 'marketing_type' => '营销活动类型', 'invoice_id' => '发票id', 'status' => '状态[-1:删除;0:禁用;1启用]', 'is_comment' => '是否评价 0为未评价 1为已评价 2为已追评', 'is_recycle' => '是否加入回收站【1是 0否】', 'is_virtual' => '是否包含虚拟商品【1是 0否】', 'is_new_user' => '是否新顾客', 'pay_time' => '订单付款时间', 'shipping_time' => '买家要求配送时间', 'sign_time' => '买家签收时间', 'consign_time' => '卖家发货时间', 'finish_time' => '订单完成时间', 'close_time' => '关闭的时间', 'extra_info' => '额外信息', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'clerk_code' => '核销码', 'goods_subtype' => '订单商品子类型 (0:普通商品 其他:根据商品的goods_subtype而定)', ]; } // 关联模型 public function getUser() { return $this->hasOne(User::class, ['id' => 'user_id']); } public function getBase_user() { return $this->hasOne(User::class, ['id' => 'user_id'])->select(['id', 'username','nickname', 'avatar_url','mobile']); } public function getDetail() { return $this->hasMany(OrderDetail::class, ['order_id' => 'id']); } public function getExpress() { return $this->hasMany(OrderExpress::class, ['order_id' => 'id'])->where(['status' => StatusEnum::ENABLED]); } public function getExpress_log() { return $this->hasMany(OrderExpressLog::class, ['order_id' => 'id'])->where(['status' => StatusEnum::ENABLED]); } public function getReserve() { return $this->hasOne(OrderReserve::class, ['order_id' => 'id']); } public function getMch() { return $this->hasOne(\addons\Mch\common\models\Mch::class, ['id' => 'mch_id'])->select('id,store_name,shop_mobile,logo_img,user_id'); } /** * @return ActiveQueryInterface */ public function getTrade() { return $this->hasOne(PaymentTrade::class, ['out_trade_no' => 'out_trade_no']); } public function getExtra() { return $this->hasOne(OrderExtra::class,['order_id' => 'id']); } public function getOrderPrescriptionDetails() { return $this->hasOne(OrderPrescriptionDetails::class,['order_id' => 'id']); } /** * 畅捷通请求 * * @return \yii\db\ActiveQuery */ public function getAddonsChanjetRequest() { return $this ->hasOne(AddonsChanjetRequest::class, ['table_id' => 'id']) ->orderBy('updated_at desc') ->select('id, table_id, request_status, updated_at') ->where([ 'table' => self::tableName(), 'path' => [Request::PATHS['SALE_DELIVERY_CREATE_BATCH']] ]) ->andWhere(['>', 'request_status', 0]); } /** * @Author bing * @DateTime 2021-09-14 11:24:22 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $insert * @return void */ public function beforeSave($insert) { // 未支付/未付款 if ($this->isNewRecord || $this->order_status == OrderStatusEnum::NOT_PAY) { // 支付金额为产品金额 if (isset($this->goods_price)) { $this->pay_money = $this->goods_price; } // 实付增加运费 if (isset($this->pay_money) && isset($this->shipping_money)) { $this->pay_money += $this->shipping_money - $this->reduce_shipping_money; } // 随机减金额计算,因为未支付前无法更改实付金额,所以只能在此处进行修改 if (MallAddons::isInstall($this->mall_id, 'RandFee')) { $this->pay_money && $this->pay_money = RandFeeService::getRandFee($this->pay_money, $this->order_no); if(MallAddons::isInstall($this->mall_id,'Store')){ $this->pay_money && StoreOrder::updateAll(['pay_money'=>$this->pay_money,'extra_info'=>$this->extra_info],['order_no'=> $this->order_no]); } } } // var_dump($this->id, $this->isNewRecord, $this->order_status, $this->oldAttributes['order_status']); // 修改订单商品状态 if (!$this->isNewRecord && $this->order_status != $this->oldAttributes['order_status']) { OrderDetail::updateAll( ['order_status' => $this->order_status], [ 'order_status' => $this->oldAttributes['order_status'],'order_id' => $this->id] ); } // self::orderStastics($orderStatis); return parent::beforeSave($insert); } public static function generateOrderNo($prefix = ''){ // 优化唯一性保证:使用random_int()代替rand(),并结合微调以生成更唯一的ID $randInt = random_int(100000, 999999); // 日期时间戳处理 $dateTimeStr = date('YmdHis'); // 保证前缀不为空字符串且不超过一定长度(例如20个字符) $prefix = trim($prefix, '0'); if (strlen($prefix) > 20) { $prefix = substr($prefix, 0, 20); } // 生成订单号,保证总长度为17(前缀+日期时间戳+随机数) $orderNo = $prefix . $dateTimeStr . str_pad($randInt, 6, '0', STR_PAD_LEFT); return $orderNo; } public static function createOrder( $form){ $stock_locks = []; try{ if (self::isStopOrder($form['mall_id'])) throw new Exception('站点维护中,暂时无法下单'); $group_order_goods = $form['group_order_goods']; $trans = Yii::$app->db->beginTransaction(); $attr = []; $order_trade_info = []; $order_ids = []; $tmp_goods_ids = []; foreach($group_order_goods as $mch_order){ $mch_order_info = $mch_order['mch_order_info']; $mch_order_info['mch_id'] = intval($mch_order_info['mch_id']); $order = new Order(); $order->loadDefaultValues(); $order->load($mch_order_info,''); $order->order_status = OrderStatusEnum::NOT_PAY; empty($order->order_no) && $order->order_no = self::generateOrderNo('s'); $res = $order->save(); if($res === false) throw new Exception($order->getErrorMessage()); $order_id = $order->id; $order_ids[] = $order->id; //$region_statistics[] = ['mall_id' => $order->mall_id, 'province_id' => $order->province, 'city_id' => $order->city, 'order' => $order->pay_money]; // 总商品库存维护 $goods_stock_arr = []; // 积分扣除数据 $wallet_deduct_score = [ 'mall_id' => $mch_order_info['mall_id'], 'user_id' => $mch_order_info['user_id'], 'is_frozen' => false, 'wallet_type' => 'score', 'source_table' => 'order', 'money' => 0, 'source_table_id' => $order_id, 'from_type' => UserWalletEnum::CONSUME, 'capital_type' => UserWalletEnum::CONSUMPTION_ORDER, ]; // 遍历商户商品 $goods_ids = array_keys($mch_order['goods']); array_push($tmp_goods_ids, ...$goods_ids); foreach($mch_order['goods'] as $goods_id =>$goods){ !isset($goods_name) && $goods_name = $goods['goods_name']; foreach($goods['goods_details'] as $goods_detail){ $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_GOODS_ATTR , $goods_detail['goods_attr_id']); $identification = uniqid(); if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多'); $stock_locks[$lock_key] = $identification; //操作商品库存-减 GoodsAttr::handleStock($goods_detail['goods_attr_id'],$goods_detail['num']*-1); if(!isset($goods_stock_arr[$goods_id])){ $goods_stock_arr[$goods_id] = $goods_detail['num']; }else{ $goods_stock_arr[$goods_id] += $goods_detail['num']; } // 订单详情 $order_detail = new OrderDetail(); $order_detail->loadDefaultValues(); $goods_detail['mch_id'] = intval($goods_detail['mch_id']); $order_detail->load($goods_detail,''); $order_detail->order_id = $order_id; // $goods_statistics[] = ['goods_id' => $goods_detail['goods_id'], 'order_num' => 1, 'sales_num' => $goods_detail['num']]; $res = $order_detail->save(); if($res === false) throw new Exception($order_detail->getErrorMessage()); $attr[$goods_detail['goods_attr_id']] = $goods_detail['num']; $goods_detail['marketing'] = $goods_detail['marketing'] ?? []; $goods_detail['marketing'] = OrderMarketing::handleGiveScore($order_detail->mall_id, $goods_detail['marketing'], $order_detail->goods_price - $order_detail->cost_price + $order_detail->adjust_money, $order_detail->num, $order_detail->mch_id); // 订单营销 if (!empty($goods_detail['marketing'])) { $order_marketing = new OrderMarketing(); $order_marketing->loadDefaultValues(); $order_marketing->load($goods_detail['marketing'],''); $order_marketing->order_detail_id = $order_detail->id; $res = $order_marketing->save(); if($res === false) throw new Exception($order_marketing->getErrorMessage()); } // 积分扣除 if (isset($goods_detail['marketing']['deduct_score']) && ($deduct_score = $goods_detail['marketing']['deduct_score'])) { $wallet_deduct_score['money'] = bcmul(bcadd(abs($wallet_deduct_score['money']), $deduct_score, 2), -1, 2); $wallet_deduct_score['desc'] = sprintf( '用户(%s),下单(%s)抵扣积分,数量:%s', $wallet_deduct_score['user_id'], $wallet_deduct_score['source_table_id'], abs($wallet_deduct_score['money']) ); } } } // 存在扣除积分 if ($wallet_deduct_score['money']) UserWalletService::handle(0, $wallet_deduct_score, false); $form_data = self::findFormDataByKey($form, 'data'); $data = is_array($form_data)?$form_data:Json::decode($form_data,true); if(!empty($data['user_coupon_ids'])){ $user_coupon_id = $data['user_coupon_ids']; $res = AddonsCouponUserRelate::updateAll(['is_use'=>1, 'updated_at'=>time()], ['id' => $user_coupon_id]); if($res === false) throw new Exception($order->getErrorMessage()); } $order_trade_info[] = [ 'order_id' => $order->id, 'order_type' => Order::DEFAULT, 'order_no' => $order->order_no, 'amount' => $order->goods_price + ($order->shipping_money - $order->reduce_shipping_money), 'title' => Order::getOrderTitle($order), 'notify_class' => 'common\logic\notify\Notify', ]; // 处方商品,记录处方药登记信息 if ($order['goods_subtype'] == GoodsTypeEnum::GOODS_SUBTYPE_PRESCRIPTION) { OrderPrescriptionDetails::setData([ 'user_id' => $form->user_id, 'mall_id' => $form->mall_id, 'order_id' => $order_id, 'symptom' => $form['data']['symptom'] ?? [], 'medication_recipient' => $form->process_extra_data['medication_recipient'] ?? [], ]); } } $form_data = self::findFormDataByKey($form, 'data'); $data = is_array($form_data)?$form_data:Json::decode($form_data,true); if(isset($data['is_agree']) && !empty($data['is_agree'])){ UserSignAgreement::setData([ 'mall_id' => self::findFormDataByKey($form, 'mall_id'), 'user_id' => self::findFormDataByKey($form, 'user_id'), 'source' => UserSignAgreement::SOURCE_GOODS, 'source_id' => json_encode($tmp_goods_ids), ]); } if ($order->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 预约类型的订单,单独保存信息 $res = OrderReserve::create($order, $form); if ($res == false) throw new Exception(OrderReserve::getStaticError()); } // $trans->commit(); LockHelper::batchUlock($stock_locks); //生成支付流水 $res = \Yii::$app->services->pay->createTrade($form['mall_id'],$form['user_id'],$order_trade_info); if($res==false) throw new Exception('生成支付流水失败'); Order::updateAll(['out_trade_no'=>$res['trade_no']],['id'=>$order_ids]); // 触发订单添加事件,事务提交完成后触发 $event = new OrderCreateEvent($form['mall_id']); $form['data']['share_user_id'] = $form['data']['share_user_id']??0; Yii::$app->services->events->dispatch($event, ['order_ids' => $order_ids,'share_user_id'=>$form['data']['share_user_id']], $event->listeners); //删除购物车 if (self::findFormDataByKey($form, 'type') == 'cart' && empty($form->process_extra_data['is_not_del_cart'])) Cart::decreaseNumb(['user_id' => self::findFormDataByKey($form, 'user_id'), 'list' => $attr]); $res['order_ids'] = implode(',', $order_ids); $arr['transaction'] = $res; $arr['cart_list'] = $attr;//社安消防插件--该方法的删除购物车无法删除数据,返回购物车数据回插件方法,进行删除 $trade=PaymentTrade::getOne([['out_trade_no'=>$res['trade_no']]]); $trade->limit_payment=''; //限制支付方式 foreach ($form['sku'] as $key => $oldGoods) { $ogood=$oldGoods['goods']; if($ogood['is_pay_limit']) { $trade->limit_payment=$ogood['pay_limit']; continue; } } $trade->save(); // 有可能需要跳转到指定页面 if (count($tmp_goods_ids) == 1 && MallAddons::isInstall($order->mall_id, AddonsEnum::ADDONS_NAME_PAY_SUCCESS_JUMP)) { // 判断是否有开启 $jump_url_config = \Yii::$app->services->setting->addons->get($order->mall_id, AddonsEnum::ADDONS_NAME_PAY_SUCCESS_JUMP, 'basic'); // 两个都开启的情况下 if (intval($jump_url_config['is_enable_jump']) && intval($jump_url_config['is_enable'])) { $jump_url = (new JumpUrlService())->getJumpUrl($order->mall_id, $tmp_goods_ids[0], ''); if (!empty($jump_url)) { $arr['pay_success_page'] = Json::encode(['route' => $jump_url, 'open_type' => 'page', 'params' => []]); } } } // 判断是否有安装抽奖插件 if (MallAddons::isInstall($order->mall_id, AddonsEnum::ADDONS_NAME_SHOPPING_LOTTERY)) { $pay_success_page = LotteryHelper::getJumpUrl($order->mall_id, $res['trade_no']); if (!empty($pay_success_page)) { $arr['pay_success_page'] = $pay_success_page; $arr['is_jump'] = StatusEnum::ENABLED; } } if (empty($arr['pay_success_page'])) { $arr['pay_success_page'] = Yii::$app->services->setting->mall->get($form['mall_id'], 'order.pay_after_link');// 支付成功后跳转的地址 } $payment_expire_time = Yii::$app->services->setting->mall->get($form['mall_id'], 'order.payment_expire_time'); $arr['surplus_second'] = 30*60;//剩余秒数 if($payment_expire_time){ $arr['surplus_second'] = intval($payment_expire_time) * 60;//剩余秒数 } return $arr; }catch(Exception $e){ LockHelper::batchUlock($stock_locks); if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } private static function findFormDataByKey($form, $key) { if (is_array($form)) return $form[$key] ?? null; return $form->{$key} ?? null; } /** * 订单改价 * @Author bing * @DateTime 2021-09-10 19:10:45 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @param [type] $peyment_type * @return void */ public static function changePrice(array $params){ try{ $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]); if(empty($model)) throw new Exception('订单不存在或已删除'); $model->shipping_money = $params['shipping_money']; $trans = Yii::$app->db->beginTransaction(); // 修改订单详情调价 $all_goods_price = OrderDetail::priceAdjustment($params['detail']); if($all_goods_price === false) throw new Exception('调整订单商品价格失败:'. $model->getErrorMessage()); $model->goods_price = $all_goods_price; $res = $model->save(); if($res === false) throw new Exception('修改订单运费失败:'. $model->getErrorMessage()); // 订单金额修复后 self::changeOrderMarketingScore($model->id); $trans->commit(); return $model; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 更新订单营销积分 * @return void * @throws Exception */ public static function changeOrderMarketingScore(int $order_id) { try { $orderInfo = self::find() ->select('id, order_no, user_id') ->where(['status' => StatusEnum::ENABLED, 'id' => $order_id]) ->with(['detail' => function($query){ $query->select('id, goods_id, order_id, original_goods_price, goods_price, adjust_money'); } ])->asArray()->one(); foreach ($orderInfo['detail'] as $item) { // 查询当前订单是否生成营销积分 $marketing_score = OrderMarketing::find() ->where(['order_detail_id' => $item['id'], 'status' => StatusEnum::ENABLED]) ->asArray() ->one(); if (empty($marketing_score)) continue; // 没有生成营销积分 $scoreNum = self::getGoodsGiveScore($item['goods_id'], $item); if (!$scoreNum) continue; // 没有设置积分赠送规则 $res = OrderMarketing::updateAll(['give_score' => $scoreNum], ['id' => $marketing_score['id']]); if (!$res) { throw new Exception('修改订单营销积分失败'); } } } catch (Exception $e) { Yii::$app->custom->logs("修改订单营销积分失败:" . $e->getMessage(), $order_id); } } public static function getGoodsGiveScore($goods_id, $orderDetail) { $goodsExtra = GoodsExtra::find()->where(['status' => StatusEnum::ENABLED, 'goods_id' => $goods_id]) ->select('id, goods_id, score_give_setting') ->one(); if (!$goodsExtra) return false; $give_setting = Json::decode($goodsExtra['score_give_setting'], true); if (empty($give_setting['enable_give_score'])) return false; if (!empty($give_setting['give_type']) && $give_setting['give_type'] == 2) { if (!empty($give_setting['calculation_value']) && $give_setting['calculation_value'] == 1) { // 订单支付金额 $goods_price = $orderDetail['goods_price'] + $orderDetail['adjust_money']; // 订单金额等于原来总金额加上调整金额 $money = bcmul($goods_price, $give_setting['give_num'] / 100, 2); } else { // 订单商品总价 $money = bcmul($orderDetail['original_goods_price'], $give_setting['give_num'] / 100, 2); } } else { // 固定赠送值 $money = $give_setting['give_num'] ?? 0; } return $money ?? 0; } /** * 管理员订单支付 * @Author bing * @DateTime 2021-09-10 10:43:57 * @copyright: Copyright (c) 2020 广东七件事集团 * @param Order $params 参数 * @param [type] $payment_type 支付方式 * @param string 支付流水号 * @return boolean|object */ public static function pay($params, $peyment_type,$out_trade_no = '') { $stock_locks = []; try{ // $model = self::findOne(['id' => $params['id'],'status'=>[StatusEnum::ENABLED]]); $model = self::findOne(['id' => $params['id']]); if(empty($model)) throw new Exception('订单不存在或已删除'); // if ($model->order_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理,无法进行支付'); if (in_array($model->order_status ,[OrderStatusEnum::PAY,OrderStatusEnum::SHIPMENTS,OrderStatusEnum::ACCOMPLISH])) throw new Exception('订单已经被处理,无法进行支付'); if ($model->pay_status == StatusEnum::ENABLED) throw new Exception('订单已支付,请不要重复支付'); $order_status = $model->order_status; $model->order_status = OrderStatusEnum::PAY; if ($model->order_source == 'Aiyunuo' && $model->shipping_type == ShippingTypeEnum::PICKUP) { $model->order_status = OrderStatusEnum::TAKE; } if ($model->shipping_type == ShippingTypeEnum::PICKUP) { if (MallAddons::isInstall($model->mall_id, AddonsEnum::ADDONS_NAME_YUNMENG)) { //查找订单是否在云盟店订单 $yunmeng_order = \addons\Yunmeng\common\models\YunmengOrder::getOne([ ['mall_id' => $model->mall_id], ['order_id' => $model->id], ]); if (!empty($yunmeng_order)) $model->order_status = OrderStatusEnum::TAKE; } } $model->payment_type = $peyment_type; $model->pay_status = StatusEnum::ENABLED; $model->pay_time = time(); $model->out_trade_no = $out_trade_no ?? ''; $trans = Yii::$app->db->beginTransaction(); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 平台订单 $reserveOrder = OrderReserve::findOne(['order_id' => $model->id]); if ($reserveOrder->reserve_type == StatusEnum::DISABLED) { // 家政才需要修改为发货状态 // 预约商品支付后,改成发货状态 $model->shipping_status = StatusEnum::ENABLED; // 全部发货状态改为已发货 // 如果是技师,那么就为已支付 $model->order_status = OrderStatusEnum::SHIPMENTS; $model->consign_time = time(); } OrderReserve::syncOrderStatus($model); } $res = $model->save(); if($res === false) throw new Exception('修改订单失败:'. $model->getErrorMessage()); // 增加销量 $order_detail = $model->detail; $sale_num_goods = []; foreach($order_detail as $product){ if($order_status==OrderStatusEnum::REPEAL) { if ($model->order_source !== OrderSourceEnum::SOURCE_RESERVE) { $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_GOODS_ATTR, $product['goods_attr_id']); $identification = uniqid(); if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多'); $stock_locks[$lock_key] = $identification; //操作商品库存-减 GoodsAttr::handleStock($product['goods_attr_id'], $product['num'] * -1); $stock = GoodsAttr::find()->where(['goods_id' => $product['goods_id'], 'status' => StatusEnum::ENABLED])->sum('stock'); $stock = $stock ?? 0; Goods::updateAll(['stock' => $stock], ['id' => $product['goods_id']]); } } if(isset($sale_num_goods[$product['goods_id']])){ $sale_num_goods[$product['goods_id']] += $product['num']; }else{ $sale_num_goods[$product['goods_id']] = $product['num']; } } foreach($sale_num_goods as $goods_id => $sale_num){ $goods = Goods::findOne($goods_id); $goods->sales_num += $sale_num; $goods->save(); } $trans->commit(); LockHelper::batchUlock($stock_locks); // 触发订单支付事件,事务提交完成后触发 if(!empty($model['mch_id'])){ $number = 0; $addons_arr = [AddonsEnum::ADDONS_NAME_AGENT,AddonsEnum::ADDONS_NAME_DISTRIBUTION,AddonsEnum::ADDONS_NAME_AREA, AddonsEnum::ADDONS_NAME_BOSS]; foreach ($addons_arr as $addons){ if(MallAddons::isInstall($model['mall_id'],$addons)){ $number++; } } //多商户事件触发 \Yii::$app->services->taskCounter->set('mch:order_id:' . $model['id'])->incr($number); if (MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_MCH)){ $data = []; $event = new \addons\Mch\common\events\order\OrderPaidEvent($model['mall_id']); $data['id'] = $model['id']; $data['operator_id'] = $params['operator_id'] ?? 0; $data['operator_name'] = $params['operator_name'] ?? ''; \Yii::$app->services->events->dispatch($event, $data, $event->listeners); } }else{ $number = 0; $addons_arr = [AddonsEnum::ADDONS_NAME_AGENT,AddonsEnum::ADDONS_NAME_DISTRIBUTION,AddonsEnum::ADDONS_NAME_AREA,AddonsEnum::ADDONS_NAME_DOUBLE_COPY]; foreach ($addons_arr as $addons){ if(MallAddons::isInstall($model['mall_id'],$addons)){ $number++; } } //云库存商品-先等经销、分销、区域分佣完 \Yii::$app->services->taskCounter->set($model['id'])->incr($number); $event = new OrderPaidEvent($model['mall_id']); $order['id'] = $model['id']; $order['operator_id'] = $params['operator_id'] ?? 0; $order['operator_name'] = $params['operator_name'] ?? ''; $order['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $order, $event->listeners); } return $model; }catch(Exception $e){ LockHelper::batchUlock($stock_locks); if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 取消订单 * @Author bing * @DateTime 2021-09-14 15:43:18 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return order */ public static function close($params,$force = false){ $trans = Yii::$app->db->beginTransaction(); $stock_locks = []; $close_lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_GOODS , $params['id']); try{ // 加锁 $close_identification = uniqid(); $stock_locks[$close_lock_key] = $close_identification; if (!LockHelper::lock($close_lock_key, $close_identification, 30, 60)) throw new \Exception('正在关闭订单'); $cond = ['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]; isset($params['user_id']) && $cond['user_id'] = $params['user_id']; $model = self::findOne($cond); if(empty($model)) throw new Exception('订单不存在或已删除'); if($model['order_source']=='Aiyunuo') { $extra_info = $model['extra_info']; if(!empty($extra_info)){ $extra_info = json_decode($extra_info,true); if(!empty($extra_info['aiyunuo_rp_order_rp_id'])){ throw new Exception('爱优诺处方订单不允许取消'); } } } // 判断订单是否已经被关闭 if ($model->order_status == OrderStatusEnum::REPEAL) throw new Exception('订单已经关闭'); // 判断是否是未支付的订单 if ($force == false && $model->order_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理'); $model->close_time = time(); $model->order_status = OrderStatusEnum::REPEAL; if (!$model->save()) throw new Exception($model->getErrorMessage()); $goods_attr_arr = array_column($model->detail,'num','goods_attr_id'); //操作规格库存-回退 if ($model->order_source !== OrderSourceEnum::SOURCE_RESERVE) { // 非预约商品处理库存 foreach ($goods_attr_arr as $goods_attr_id => $num) { $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_GOODS_ATTR, $goods_attr_id); $identification = uniqid(); if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多'); $stock_locks[$lock_key] = $identification; //操作商品库存-回退 GoodsAttr::handleStock($goods_attr_id, $num); } } // 订单营销扣减返还 $order_detail_id_arr = array_column($model->detail, 'id'); if (empty($model['store_id'])) { $res = OrderMarketing::deductBack($model->id, $order_detail_id_arr, $order_detail_id_arr, $model->mall_id, $model->user_id, '交易关闭返还'); if ($res == false) throw new Exception(OrderMarketing::getStaticError()); } // liuzhantao,这里注释的原因是:订单支付用积分抵扣,那么取消订单时,就会返回两次积分,这里的代码返回一次积分,下面监听的代码也返回一次积分,所以把这里的注释了。 // else { // if (MallAddons::isInstall($model->mall_id, AddonsEnum::ADDONS_NAME_STORE)) { // $store_order_detail_list = StoreOrderDetail::lists(['where' => [['main_order_detail_id' => $order_detail_id_arr]]]); // $store_order_detail_id_arr = array_column($store_order_detail_list, 'id'); // $store_order = StoreOrder::findOne(['order_no' => $model['order_no']]); // $res = StoreOrderMarketing::deductBack($store_order, $store_order_detail_id_arr, $store_order_detail_id_arr, $model['mall_id'], $model['user_id'], '交易关闭返还'); // if ($res == false) throw new Exception(StoreOrderMarketing::getStaticError()); // } // } if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 同步订单状态 OrderReserve::syncOrderStatus($model); } $trans->commit(); // 触发订单取消事件 if (!empty($model['store_id'])) { if (($model->order_source == AddonsEnum::ADDONS_NAME_STORE || $model->order_source == AddonsEnum::ADDONS_NAME_RESERVERE) && MallAddons::isInstall($model->mall_id, AddonsEnum::ADDONS_NAME_STORE)) { $event = new \addons\Store\common\events\order\OrderCloseEvent($model->mall_id); $order_data['id'] = $model->id; $order_data['operator_id'] = $params['operator_id'] ?? 0; $order_data['operator_name'] = $params['operator_name'] ?? '系统'; $order_data['is_store'] = 1; Yii::$app->services->events->dispatch($event, $order_data, $event->listeners); } elseif ($model->marketing_type == AddonsEnum::ADDONS_NAME_LAO_DA_FU) { $event = new \addons\LaoDaFu\common\events\order\OrderCloseEvent($model->mall_id); $order_data['id'] = $model->id; $order_data['operator_id'] = $params['operator_id'] ?? 0; $order_data['operator_name'] = $params['operator_name'] ?? '系统'; $order_data['is_store'] = 1; Yii::$app->services->events->dispatch($event, $order_data, $event->listeners); } } else { $event = new OrderCloseEvent($model->mall_id); $order_data['id'] = $model->id; $order_data['operator_id'] = $params['operator_id'] ?? 0; $order_data['operator_name'] = $params['operator_name'] ?? '系统'; $order_data['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $order_data, $event->listeners); } // 解锁 LockHelper::batchUlock($stock_locks); return $model; } catch (Exception $e) { $trans->rollback(); // 解锁 LockHelper::batchUlock($stock_locks); self::$static_error = $e->getMessage(); return false; } } /** * 订单备注 * @Author bing * @DateTime 2021-09-14 15:43:18 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function remark($params){ try{ $where = ['mall_id' => $params['mall_id'], 'id' => $params['id']]; if(!empty($params['mch_id']))$where['mch_id'] = $params['mch_id']; $model = self::findOne($where); if(empty($model)) throw new Exception('订单不存在或已删除'); $model->remark = $params['remark'] ?? $model->remark; $model->seller_remark = $params['seller_remark'] ?? $model->seller_remark; if (!$model->save()) throw new Exception($model->getErrorMessage()); return $model; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * @desc:删除订单 * @Author: hua * @Date: 2021/12/3 * @Time: 19:05 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return Order|false */ public static function del($params){ try{ $where = ['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED, StatusEnum::DISABLED]]; if(!empty($params['mch_id']))$where['mch_id'] = $params['mch_id']; $model = self::findOne($where); if(empty($model)) throw new Exception('订单不存在或已删除'); if(!empty($model->pay_time))throw new Exception('只允许删除未支付订单'); if($model->order_status!=OrderStatusEnum::REPEAL)throw new Exception('只允许删除关闭订单'); $model->status = StatusEnum::DELETE; if (!$model->save()) throw new Exception($model->getErrorMessage()); OrderDetail::updateAll(['status'=>StatusEnum::DELETE],['order_id'=>$params['id']]); $event = new OrderDelEvent($model->mall_id); $order_data['id'] = $params['id']; $order_data['order_no'] = $model->order_no; $order_data['operator_id'] = $params['operator_id'] ?? 0; $order_data['operator_name'] = $params['operator_name'] ?? '系统'; $order_data['is_admin'] = $params['is_admin'] ?? 0; $order_data['is_store'] = $params['is_store'] ?? 0; $order_data['is_mch'] = $params['is_mch'] ?? 0; $order_data['is_aiyunuo'] = $params['is_aiyunuo'] ?? 0; Yii::$app->services->events->dispatch($event,$order_data,$event->listeners); return $model; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } public static function delByh5($params){ try{ $where = ['mall_id' => $params['mall_id'],'user_id'=>$params['user_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]; if(!empty($params['mch_id']))$where['mch_id'] = $params['mch_id']; $model = self::findOne($where); if(empty($model)) throw new Exception('订单不存在或已删除'); if(!in_array($model->order_status,[OrderStatusEnum::REPEAL,OrderStatusEnum::ACCOMPLISH]))throw new Exception('只允许删除关闭订单或者已完成订单'); $model->status = StatusEnum::DISABLED; if (!$model->save()) throw new Exception($model->getErrorMessage()); OrderDetail::updateAll(['status'=>StatusEnum::DISABLED],['order_id'=>$params['id']]); // 用户删除订单 OrderAction::create("用户删除订单", $model->id, $model->order_status, $params['user_id'], $model->user->nickname); return $model; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 修改收货地址 * @Author bing * @DateTime 2021-09-14 15:43:18 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function changeAddress($params){ try{ $where = ['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]; if(!empty($params['mch_id']))$where['mch_id'] = $params['mch_id']; $model = self::findOne($where); if(empty($model)) throw new Exception('订单不存在或已删除'); // 记录原地址 $params['old_receiver_name'] = $model['receiver_name']; $params['old_mobile'] = $model['mobile']; $params['old_region_name'] = $model['region_name']; $params['old_address'] = $model['address']; $params['old_province'] = $model['province']; $params['old_city'] = $model['city']; $params['old_area'] = $model['area']; $params['old_town'] = $model['town']; $params['old_community'] = $model['community']; self::isAllowChangeAddress($params['mall_id'], $model->order_source); if(!$model->load($params,'') || !$model->save()) throw new \Exception($model->getErrorMessage()); // 事件 $event = new OrderChangeAddressEvent($params['mall_id']); Yii::$app->services->events->dispatch($event,$params,$event->listeners); return $model; }catch(Exception $e){ self::$static_error = $e->getMessage(); return false; } } /** * 只有主商城订单和聚水潭订单允许修改订单地址 * * @param int $mallId * @param string $orderSource * * @throws Exception */ public static function isAllowChangeAddress(int $mallId, string $orderSource) { $needCheckIsAllowModifyAddressAddons = [ AddonsEnum::ADDONS_NAME_JSTAN_ERP, AddonsEnum::ADDONS_NAME_QI_JUHE, AddonsEnum::ADDONS_NAME_JUHE_SHOP, 'StarChain' ]; if (!in_array($orderSource, $needCheckIsAllowModifyAddressAddons)) { return; } // 获取插件的配置 $event = new \common\events\mall\GetSpecifyAdsCfgEvent($mallId); Yii::$app->services->events->dispatch($event, ['mall_id' => $mallId, 'addons_name' => $orderSource], $event->listeners); if (!empty($event->getConfig()['is_allow_modify_address'])) { return; } throw new \RuntimeException('当前订单不允许修改地址'); } /** * 发货 * @Author bing * @DateTime 2021-09-16 17:35:05 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function delivery($params){ try{ $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]); if(empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status == OrderStatusEnum::SHIPMENTS) throw new Exception('订单已经发货'); if ($model->order_status != OrderStatusEnum::PAY) throw new Exception('订单已经被处理'); $model->shipping_status = StatusEnum::ENABLED;// 全部发货状态改为已发货 $model->order_status = OrderStatusEnum::SHIPMENTS; $model->consign_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); return $model; }catch(Exception $e){ self::$static_error = $e->getMessage(); return false; } } /** * 收货 * @Author bing * @DateTime 2021-09-16 17:35:05 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function takeDelivery($params){ try{ $cond = ['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]; isset($params['user_id']) && $cond['user_id'] = $params['user_id']; isset($params['mch_id']) && $cond['mch_id'] = $params['mch_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除'); $actionText = ($params['from'] ?? '') == OrderSourceEnum::SOURCE_RESERVE ? '核销' : '签收'; if ($model->order_status == OrderStatusEnum::SING) throw new Exception('订单已经' . $actionText); if ($model->order_status != OrderStatusEnum::SHIPMENTS) throw new Exception('订单已经被处理'); $orderDetailRefund = OrderDetail::find()->alias('or') ->join('inner join', OrderRefund::tableName() . 'as refund', 'refund.order_detail_id=or.id') ->where(['or.order_id' => $params['id'], 'or.is_feedback' => OrderStatusEnum::FEEDBACKING, 'or.status' => StatusEnum::ENABLED, 'refund.status' => StatusEnum::ENABLED, ]) ->andWhere(['!=', 'refund.refund_status', RefundStatusEnum::FINISH]) ->select('or.id, refund.id as refund_id, or.is_feedback, refund.type') ->orderBy('refund.type desc') ->asArray()->all(); if (!empty($orderDetailRefund)) { $refundTypes = array_column($orderDetailRefund, 'type'); if (in_array(RefundTypeEnum::EXCHANGE_GOODS, $refundTypes)) { $refund_id = array_filter($orderDetailRefund, function ($item) { return $item['type'] == RefundTypeEnum::EXCHANGE_GOODS; }); self::$getRefundId = reset($refund_id)['refund_id']; // 获取第一个换货商品id throw new Exception('该订单包含换货中商品,请先前往售后详情确认收货。'); } else if (in_array(RefundTypeEnum::MONEY_AND_PRODUCT, $refundTypes) && !in_array(RefundTypeEnum::MONEY, $refundTypes)) { throw new Exception('该订单包含退货退款商品,确认收货后其售后流程将继续进行。'); } else if (in_array(RefundTypeEnum::MONEY, $refundTypes) && !in_array(RefundTypeEnum::MONEY_AND_PRODUCT, $refundTypes)) { throw new Exception('该订单包含退款中商品,确认收货将关闭退款。'); } else if (in_array(RefundTypeEnum::MONEY_AND_PRODUCT, $refundTypes) && in_array(RefundTypeEnum::MONEY, $refundTypes)) { throw new Exception('该订单包含退款中及退货退款中商品,确认收货将关闭退款;退货退款商品售后继续,不受影响。'); } } $model->order_status = OrderStatusEnum::SING; $model->shipping_status = ShippingStatusEnum::RECEIVED; $model->sign_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); OrderDetail::updateAll(['shipping_status' => ShippingStatusEnum::RECEIVED], ['order_id' => $model['id'],'is_feedback'=>0]); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 同步订单状态 OrderReserve::syncOrderStatus($model, $params['tech_id'] ?? null); } if (!empty($model['store_id'])) { if ($model->order_source === AddonsEnum::ADDONS_NAME_STORE) { $is_install = MallAddons::isInstall($params['mall_id'], AddonsEnum::ADDONS_NAME_STORE); if ($is_install) { $store_order = StoreOrder::findOne(['order_no' => $model['order_no']]); if ($store_order) { $store_order->order_status = OrderStatusEnum::SING; $store_order->sign_time = time(); if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); } } } elseif ($model->marketing_type == AddonsEnum::ADDONS_NAME_LAO_DA_FU) { $store_order = \addons\LaoDaFu\common\models\StoreOrder::findOne(['order_no' => $model['order_no']]); if ($store_order) { $store_order->order_status = OrderStatusEnum::SING; $store_order->sign_time = time(); if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); } } } // 触发订单收货事件,事务提交完成后触发 $event = new OrderTakeDeliveryEvent($params['mall_id']); $data['id'] = $model->id; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; $data['is_admin'] = (int)!empty($params['is_admin']); Yii::$app->services->events->dispatch($event, $data, $event->listeners); return $model; }catch(Exception $e){ self::$static_error = $e->getMessage(); return false; } } /** * @notes:取消发货 * @param $params * @return bool * @author: lun * @Time: 2022/10/27 10:21 */ public static function cancelShipment($params) { try { $order_details = OrderDetail::find()->where(['id' => $params['order_detail_ids']])->all(); foreach ($order_details as $detail) { if (!$detail->shipped_num) throw new Exception('订单处于非发货状态'); if (OrderDetail::getAfterSaleCountByOrderId($detail->order_id) > 0) throw new Exception('请先处理或关闭订单售后'); $detail->order_status = OrderStatusEnum::PAY; $detail->shipping_status = StatusEnum::DISABLED; if (!$detail->save()) throw new Exception($detail->getErrorMessage()); OrderDetail::updateAllCounters(['shipped_num' => -min($params['nums'][$detail->id] ?? $detail->shipped_num, $detail->shipped_num)], ['id' => $detail->id]); } // 统计订单详情数量 if ($order_details) { /*$order = Order::findOne(['id' => $params['order_id']]); $order->order_status = OrderStatusEnum::PAY; // 已发货改为待发货状态 $order->consign_time = 0; // 发货时间改为0 if (!$order->save()) throw new Exception($order->getErrorMessage());*/ Yii::$app->db->createCommand() ->update(Order::tableName(), ['order_status' => OrderStatusEnum::PAY,'consign_time' => 0,'updated_at' => time()], ['id' => $params['order_id']]) ->execute(); } return true; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } /** * 自动维护订单状态 * @Author bing * @DateTime 2021-09-17 11:43:41 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $order_id * @return void */ public static function autoUpdateStatus($order) { $order_details = OrderDetail::getOrderDetails([['order_id' => $order->id]]); // 正常订单详情数 $normal_count = count($order_details); // 退款状态数 $refund_count = 0; $not_refunding_count = 0; $refunding_count = 0; $feedback_completion = 0; // 已发货状态数 $shipping_count = 0; // 未发货状态数 $no_shipping_count = 0; // 换货状态数 $exchange_count = 0; // 订单完成需要关闭的订单详情数 $order_detail_close_ids = []; foreach ($order_details as $order_detail) { $shipping_status = $order_detail['shipping_status']; $is_feedback = $order_detail['is_feedback']; $shipping_status == StatusEnum::ENABLED && $shipping_count++; $is_feedback == OrderStatusEnum::FEEDBACKED && $refund_count++; $is_feedback == OrderStatusEnum::NOT_FEEDBACK && $not_refunding_count++; $is_feedback == OrderStatusEnum::FEEDBACKING && $refunding_count++; $is_feedback == OrderStatusEnum::FEEDBACKED && $feedback_completion++; /****判断订单是否售后完成 --start-- ****/ if ($is_feedback == OrderStatusEnum::FEEDBACKED) { // 订单售后完成(判断完成订单中是否存在换货数据) $refund_exists = OrderRefund::find() ->where(['mall_id' => $order_detail['mall_id'], 'status' => StatusEnum::ENABLED, 'order_detail_id' => $order_detail['id'], 'type' => RefundTypeEnum::EXCHANGE_GOODS, 'store_id' => 0, 'mch_id' => 0 ])->exists(); if ($refund_exists) { $exchange_count++; } else { // 订单完成后订单状态为已关闭(仅为退款、退货退款) $order_detail_close_ids[] = $order_detail['id']; } } /****判断订单是否售后完成--end--****/ // 未发货的正常产品 if ($shipping_status == StatusEnum::DISABLED && in_array($is_feedback, OrderStatusEnum::getFeedbackMap())) { $no_shipping_count++; } } if (!empty($order_detail_close_ids)) { // 关闭订单详情 OrderDetail::updateAll(['order_status' => OrderStatusEnum::REPEAL], ['id' => $order_detail_close_ids]); } // 全部已退款直接关闭 if ($normal_count === $refund_count) { $order->close_time = time(); // 只有当退货订单中没有换货订单时,才对主订单进行关闭 if ($exchange_count == 0) { $order->order_status = OrderStatusEnum::REPEAL; } if (!$order->save()) throw new Exception($order->getErrorMessage()); // return self::close(['mall_id'=>$order->mall_id,'id'=>$order->id], true); } //未售后(当售后完成中有拒绝时也更改主订单状态) if (!empty($not_refunding_count)) { $order->is_feedback = OrderStatusEnum::NOT_FEEDBACK; $order->save(); } // 全部售后中 if ($normal_count === $refunding_count) { $order->is_feedback = OrderStatusEnum::FEEDBACKING; $order->save(); } // 全部售后完成 if ($normal_count === $feedback_completion) { $order->is_feedback = OrderStatusEnum::FEEDBACKED; $order->save(); } if($order->order_source === OrderSourceEnum::SOURCE_RESERVE){ // 预约订单处理 try{ OrderReserve::syncOrderStatus($order); }catch(Exception $e){ throw $e; } } // 全部已发货 if ($normal_count === $shipping_count) { return self::delivery(['mall_id' => $order->mall_id, 'id' => $order->id]); } // 校验发货状态如果其他货物已发就改变订单状态 $refund_shipping_count = $refund_count + $shipping_count; if ($normal_count == $refund_shipping_count && $order->order_status == OrderStatusEnum::PAY && $no_shipping_count == 0) { return self::delivery(['mall_id' => $order->mall_id, 'id' => $order->id]); } } public function export(array $data) { foreach ($data as &$val) { $val['created_at'] = date('Y-m-d H:i:s', $val['created_at']); } return $data; } /** * 导出字段数组 * @Author: hua * @DateTime: 2021/10/11 18:06 * @Copyright: copyright (c) 2021 广东七件事集团 * @return \string[][] */ public static function fieldsLists($field = null) { $fields = [ 'o.order_id' => '订单ID', 'o.user_id' => '用户ID', 'o.order_no' => '订单编号', 'o.out_trade_no' => '外部交易号', 'o.mobile' => '收货人的手机号码', 'o.receiver_name' => '收货人姓名', 'o.region_name' => '地区名称(省市区[乡/镇]', 'o.address' => '详细地址', 'd.goods_name' => '商品名', //detail 'd.goods_attr_name' => '规格', //detail 'd.num' => '购买数量', //detail 'd.cost_price' => '商品成本价', //detail 'd.original_goods_price' => '商品原本总价', //detail 'd.goods_price' => '商品优惠后总价', //detail 'o.shipping_money' => '订单运费', 'o.created_at' => '下单时间', 'o.payment_type' => '支付方式', //- 'o.order_status' => '订单状态', //- 'o.pay_status' => '订单付款状态', //- 'o.pay_time' => '订单付款时间', 'd.shipping_status' => '订单配送状态', //- detail 'o.consign_time' => '卖家发货时间', // 'o.sign_time' => '买家签收时间', 'd.remark' => '用户订单备注', //detail 'o.seller_remark' => '商家订单备注', 'o.pay_money' => '订单实付金额' ]; if ($field === null) return $fields; $temp = []; foreach ($field as $val) { if (isset($fields[$val])) $temp[$val] = $fields[$val]; } return $temp; } /** * 获取订单标题 * @param Order $order * @return string */ public static function getOrderTitle($order) { $details = $order->getDetail()->all(); if (empty($details) || !is_array($details) || count($details) < 1) { return ''; } $titles = []; foreach ($details as $detail) { $titles[] = $detail->goods_name; } $title = implode(';', $titles); return mb_strlen($title) > 32 ? mb_substr($title, 0, 32) : $title; } /** * @desc:去支付 * @Author: hua * @Date: 2021/10/19 * @Time: 14:13 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false|int */ public static function toPay($params) { try { $id = json_decode($params['id'], true); $orderUserId = $params['order_user_id'] ?? $params['user_id']; $where = ['id' => $id, 'user_id' => $orderUserId, 'mall_id' => $params['mall_id'], 'pay_status' => 0]; if (!empty($params['mch_id'])) $where['mch_id'] = $params['mch_id']; $list = Order::findAll($where); $orders = []; $payment_expire_time = Yii::$app->services->setting->mall->get($params['mall_id'], 'order.payment_expire_time'); if (empty($payment_expire_time)) $payment_expire_time = 30; $order_nos = []; $goods_price = 0; // 最终支付金额 $store_order_nos = []; foreach ($list as $k => $order) { self::toPayBeforeCheck($order, $k); // 获取插件内容 $event = new OrderToPayEvent($order['mall_id'], $order); Yii::$app->services->events->dispatch($event); $orders[] = [ 'order_id' => $order->id, 'order_no' => $order->order_no, 'amount' => $order->goods_price + ($order->shipping_money - $order->reduce_shipping_money), 'title' => self::getOrderTitle($order), 'notify_class' => empty($order['store_id']) ? 'common\logic\notify\Notify' : (!empty($params['notify_class']) ? $params['notify_class'] : 'addons\Store\common\logic\notify\Notify'), 'order_type' => Order::DEFAULT, ]; //如果是o2o门店订单,记录订单号 if (!empty($order['store_id'])) { $store_order_nos[] = $order->order_no; } $order_time = $order['created_at'] + $payment_expire_time * 60; $order_ids[] = $order->id; $order_nos[] = $order->order_no; $goods_price += $order->goods_price + ($order->shipping_money - $order->reduce_shipping_money); } if(empty($list)) throw new Exception('查无订单'); // 判断是否已有组合待支付订单 $group_trade_ids = PaymentTradeOrder::find()->where(['order_no'=>$order_nos])->select('trade_id')->column(); if(!empty($group_trade_ids)) { // 组合支付查询 /** * @var PaymentTrade|null */ $mixed_trade = PaymentTrade::getMixedTradeByIds($group_trade_ids); !empty($mixed_trade) && $res = [ 'trade_id' => $mixed_trade->id, 'trade_no' => $mixed_trade->out_trade_no, 'pay_fee' => $mixed_trade->getOnlinePayFee(), 'is_pay' => $mixed_trade->is_pay, 'pay_type' => PayTypeEnum::MIXED, ]; // 选择重新支付 if (isset($params['re_pay']) && $params['re_pay'] && !empty($mixed_trade)) { $mixed_trade->rePay(reset($list), 2); $res = null; } } if (empty($res)) { //查询上一个订单是否有限制支付方式 $orderNo=$list[0]->order_no; $tradeOrder=PaymentTradeOrder::find()->where(['order_no'=>$orderNo])->orderBy('id DESC')->one(); $trade=PaymentTrade::find()->where(['id'=>$tradeOrder->trade_id])->one(); $res = \Yii::$app->services->pay->createTrade($params['mall_id'], $params['user_id'], $orders); if ($res == false) throw new Exception('生成支付流水失败'); Order::updateAll(['out_trade_no'=>$res['trade_no']],['id'=>$order_ids]); //如果门店订单号不为空,修改门店订单的外部单号 if (!empty($store_order_nos)) { StoreOrder::updateAll(['out_trade_no'=>$res['trade_no']],['order_no'=>$store_order_nos]); } //限制支付方式 if(!empty($trade) && !empty($trade->limit_payment)){ $newTrade=PaymentTrade::findOne($res['trade_id']); $newTrade->limit_payment = $trade->limit_payment; $newTrade->save(); } } $res['surplus_second'] = 30*60;//剩余秒数 $res['main_order_id'] = reset($id); $res['goods_price'] = $goods_price;//剩余秒数 if(!empty($order_time)) $res['surplus_second'] = ($order_time - time())>0?$order_time - time():0; return $res; }catch (Exception $e){ self::$static_error = $e->getMessage(); return false; } } /** * 检查是否允许支付 * * @param $order * @param $k * * @return void * @throws Exception */ protected static function toPayBeforeCheck($order, $k) { // 查询是否是处方药订单,如果是则需要开方后才能支付 if ($order['goods_subtype'] == GoodsTypeEnum::GOODS_SUBTYPE_PRESCRIPTION) { // 验证是否启用插件 if (!$k) { if ( !MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_CLOUD_PRESCRIPTION) || !((new \addons\CloudPrescription\common\services\SettingService(['mall_id' => $order['mall_id']]))->isEnable()) ) { throw new Exception('暂不支持购买处方药'); } } if ( !OrderPrescriptionDetails::find() ->where([ 'mall_id' => $order['mall_id'], 'user_id' => $order['user_id'], 'status' => StatusEnum::ENABLED, 'order_id' => $order['id'], 'prescription_status' => OrderPrescriptionDetails::PRESCRIPTION_STATUS_OPENED ]) ->exists() ) { throw new Exception('开方失败订单不允许支付'); } } } /** * @desc:提醒发货 * @Author: hua * @Date: 2021/10/20 * @Time: 9:06 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false|int */ public static function remindSend($params){ try { $where = ['id'=>$params['order_id'],'user_id'=>$params['user_id'],'mall_id'=>$params['mall_id']]; if(!empty($params['mch_id'])) $where['mch_id'] = $params['mch_id']; $order = self::findOne($where); if(empty($order)) throw new Exception('查无订单'); if($order['pay_status']!=1) throw new Exception('该订单未支付'); if($order['order_status']!=OrderStatusEnum::PAY) throw new Exception('该订单已发货'); $key = RedisKeyEnum::suffix(RedisKeyEnum::REMIND_SEND,$params['order_id']); $res = \Yii::$app->redis->get($key); if($res)throw new Exception('您已提醒过发货,请24小时后再来'); \Yii::$app->redis->set($key,1,'NX','EX',24*3600); //todo 调用发送短信接口 OrderAction::create('发货提醒',$order['id'], $order['order_status'], $params['user_id'], $params['user']['nickname']??''); // 提醒发货事件 $event = new OrderReminderShipmentEvent($params['mall_id']); $data['order_id'] = $params['order_id']; $data['operator_id'] = $params['user_id']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); return true; }catch (Exception $e){ self::$static_error = $e->getMessage(); return false; } } /** * @desc:提交订单评价 * @Author: hua * @Date: 2021/10/19 * @Time: 18:28 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return bool */ public static function postComments($params){ $t = Yii::$app->db->beginTransaction(); try{ $order = Order::findOne($params['order_id']); if (empty($order)) throw new Exception('订单不存在'); if ($order->order_status == OrderStatusEnum::ACCOMPLISH && !in_array($order['order_source'], [OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_STORE_RESERVE])) { // 如果订单已被后台管理员设置为完成。则用户不能再评论 throw new Exception('订单已完成,不能再评价'); } $goods_ids = array_column($params['comment_data'], 'goods_id'); if(!empty($order['store_id'])){ $class = \addons\Store\common\models\StoreGoods::class; }else{ $class = Goods::class; } $goods_list = $class::lists([ 'where'=>[ ['id'=>$goods_ids] ], 'index'=>'id', 'select'=>'id,goods_type' ]); foreach ($params['comment_data'] as $item) { $item['mch_id'] = $order->mch_id; $item['store_id'] = $order->store_id; $item['mall_id'] = $order->mall_id; $item['user_id'] = $order->user_id; $item['order_id'] = $params['order_id']; if (in_array($order->marketing_type, [AddonsEnum::ADDONS_NAME_LAO_DA_FU])) { $item['source'] = $order->marketing_type; } else { $item['source'] = ''; } $item['goods_type'] = $goods_list[$item['goods_id']]['goods_type']??1; $res = OrderComments::setData($item); if ($res === false) throw new Exception(OrderComments::getStaticError()); //注释下面的代码,原因是:不是首评,也能记录数据 // $is_first_comment = OrderComments::find()->where(['mall_id' => $item['mall_id'], 'store_id' => $item['store_id'], 'mch_id' => $item['mch_id'], 'user_id' => $item['user_id'], 'goods_id' => $item['goods_id']])->count(); // if ($is_first_comment == 1) { //如果为首评,记录数据 $order_comments_extra_data = OrderCommentsExtra::find()->where(['mall_id' => $item['mall_id'], 'store_id' => $item['store_id'], 'mch_id' => $item['mch_id'], 'goods_id' => $item['goods_id']])->asArray()->one(); if (!empty($order_comments_extra_data)) { // $order_comments_extra_data['num'] += 1; OrderCommentsExtra::updateAllCounters(['num' => 1], ['mall_id' => $item['mall_id'], 'store_id' => $item['store_id'], 'mch_id' => $item['mch_id'], 'goods_id' => $item['goods_id']]); } else { $order_comments_extra_data = [ 'mall_id' => $item['mall_id'], 'store_id' => $item['store_id'], 'mch_id' => $item['mch_id'], 'goods_id' => $item['goods_id'], 'num' => 1, ]; OrderCommentsExtra::setData($order_comments_extra_data); } // } if (in_array($order->order_source, [OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_STORE_RESERVE])) { if (empty($item['reserve']) && !is_array($item['reserve'])) throw new Exception('对技师/师傅的评价不能为空'); $res = OrderReserveComments::setData([ 'store_id' => $order->store_id, 'mch_id' => $order->mch_id, 'id' => $res->id, 'aging_score' => $item['reserve']['aging_score'], 'attitude_score'=> $item['reserve']['attitude_score'], 'major_score' => $item['reserve']['major_score'], 'staff_score' => !empty($item['reserve']['staff_score']) ? $item['reserve']['staff_score'] : 0, 'environment_score' => !empty($item['reserve']['environment_score']) ? $item['reserve']['environment_score'] : 0, 'service_score' => !empty($item['reserve']['service_score']) ? $item['reserve']['service_score'] : 0, 'tags' => $item['reserve']['tags'], 'goods_id' => $item['goods_id'], 'order_id' => $order->id, 'order_detail_id' => $item['order_detail_id'], 'user_id' => $order->user_id, 'score' => $item['score'], 'show_tech' => isset($item['show_tech']) ? $item['show_tech'] : 0, // 确保有默认值 ]); if ($res === false) throw new Exception(OrderComments::getStaticError()); } // 记录评分 $scores = OrderComments::getOne([ ['goods_id' => $item['goods_id']], ['status' => StatusEnum::ENABLED], ], true, [], '', "SUM(score) as score, COUNT(*) AS total" ); if (!empty($scores['score'])) { $scores['score'] = $item['score']; } else { $scores['score'] += $item['score']; } Goods::updateAll(['comment_score' => bcdiv($scores['score'], $scores['total'] + 1, 2)], ['id' => $item['goods_id']]); } $order->order_status = OrderStatusEnum::ACCOMPLISH; $order->finish_time = time(); $order->is_comment = 1; $order->save(); if(!empty($order['store_id'])){ $is_install = MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_STORE); if($is_install && $order->order_source == AddonsEnum::ADDONS_NAME_STORE){ $store_order = StoreOrder::findOne(['order_no'=>$order['order_no']]); if($store_order){ $store_order->order_status = OrderStatusEnum::ACCOMPLISH; $store_order->finish_time = time(); $store_order->is_comment = 1; if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); } } if ($order->marketing_type == AddonsEnum::ADDONS_NAME_LAO_DA_FU) { $store_order = \addons\LaoDaFu\common\models\StoreOrder::findOne(['order_no' => $order['order_no']]); if($store_order){ $store_order->order_status = OrderStatusEnum::ACCOMPLISH; $store_order->finish_time = time(); $store_order->is_comment = 1; if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); if ($store_order->order_source == OrderSourceEnum::SOURCE_LAODAFU_RESERVE) { LaoDaFuStoreOrderService::updateAll(['order_id' => $store_order->id], ['order_status' => $store_order->order_status]); } } } } $t->commit(); // 订单完成触发事件 $user = User::getOne([['id' => $order->user_id]], true, [], false, 'nickname'); if(empty($order['mch_id'])&&empty($order['store_id'])){ $user = User::getOne([['id' => $order->user_id]], true, [], false, 'nickname'); $event = new OrderFinishEvent($order->mall_id); $data['id'] = $order->id; $data['order_no'] = $order->order_no; $data['operator_id'] = $order->user_id; $data['operator_name'] = $user['nickname']; $data['is_comment'] = 1; Yii::$app->services->events->dispatch($event, $data, $event->listeners); }else { if (!empty($order['mch_id'])) { if (MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_MCH)) { $user = User::getOne([['id' => $order->user_id]], true, [], false, 'nickname'); $event = new \addons\Mch\common\events\order\OrderFinishEvent($order->mall_id); $data['id'] = $order->id; $data['order_no'] = $order->order_no; $data['operator_id'] = $order->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } } elseif ($order['store_id']) { // 之前门店订单来源为预约的订单,不会触发到门店订单完成事件。这里添加到门店订单完成事件中 if (($order->order_source == AddonsEnum::ADDONS_NAME_STORE || in_array($order->order_source, [OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_STORE_RESERVE])) && MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_STORE)) { $user = User::getOne([['id' => $order->user_id]], true, [], false, 'nickname'); $event = new \addons\Store\common\events\order\OrderFinishEvent($order->mall_id); $data['id'] = $order->id; $data['order_no'] = $order->order_no; $data['operator_id'] = $order->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } elseif ($order->order_source == AddonsEnum::ADDONS_NAME_LAO_DA_FU) { $user = User::getOne([['id' => $order->user_id]], true, [], false, 'nickname'); $event = new \addons\LaoDaFu\common\events\order\OrderFinishEvent($order->mall_id); $data['id'] = $order->id; $data['order_no'] = $order->order_no; $data['operator_id'] = $order->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } } } return true; }catch(Exception $e){ $t->rollBack(); self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 处理订单完成(过售后) * @param {array} $params * @return {*} */ public static function complete(array $params) { try { $cond = ['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED]]; isset($params['user_id']) && $cond['user_id'] = $params['user_id']; if(!empty($params['mch_id'])) $cond['mch_id'] = $params['mch_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status == OrderStatusEnum::ACCOMPLISH) throw new Exception('订单已经完成,无需重复处理'); if ($model->order_status != OrderStatusEnum::SING && $model->order_status != OrderStatusEnum::TAKE_FINISH) throw new Exception('订单已经被处理'); if (OrderDetail::getAfterSaleCountByOrderId($params['id']) > 0) throw new Exception('请先处理或关闭订单售后'); $model->order_status = OrderStatusEnum::ACCOMPLISH; $model->finish_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); if (in_array($model->order_source, [OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_STORE_RESERVE])) { // 同步订单状态 OrderReserve::syncOrderStatus($model); } if (!empty($model['store_id'])) { $is_install = MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_STORE); if ($is_install) { $store_order = StoreOrder::findOne(['order_no' => $model['order_no']]); if ($store_order) { $store_order->order_status = OrderStatusEnum::ACCOMPLISH; $store_order->finish_time = time(); if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); } } } if (empty($model['mch_id']) && empty($model['store_id'])) { $user = User::getOne([['id' => $model->user_id]], true, [], false, 'nickname'); $event = new OrderFinishEvent($model->mall_id); $data['id'] = $model->id; $data['operator_id'] = !empty($params['operator_id']) ? $params['operator_id'] : $model->user_id; $data['operator_name'] = !empty($params['operator_name']) ? $params['operator_name'] : $user['nickname']; $data['is_admin'] = (int)!empty($params['is_admin']); $data['is_system_auto'] = (int)!empty($params['is_system_auto']); Yii::$app->services->events->dispatch($event, $data, $event->listeners); } else { if (!empty($model['mch_id'])) { if (MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_MCH)) { $user = User::getOne([['id' => $model->user_id]], true, [], false, 'nickname'); $event = new \addons\Mch\common\events\order\OrderFinishEvent($model->mall_id); $data['id'] = $model->id; $data['operator_id'] = $model->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } } elseif ($model['store_id']) { if ($model->order_source == AddonsEnum::ADDONS_NAME_STORE && MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_STORE)) { $user = User::getOne([['id' => $model->user_id]], true, [], false, 'nickname'); $event = new \addons\Store\common\events\order\OrderFinishEvent($model->mall_id); $data['id'] = $model->id; $data['order_no'] = $model->order_no; $data['operator_id'] = $model->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } elseif ($model->marketing_type == AddonsEnum::ADDONS_NAME_LAO_DA_FU) { $user = User::getOne([['id' => $model->user_id]], true, [], false, 'nickname'); $event = new \addons\LaoDaFu\common\events\order\OrderFinishEvent($model->mall_id); $data['id'] = $model->id; $data['order_no'] = $model->order_no; $data['operator_id'] = $model->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } } } return $model; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } public static function completes(array $params) { try { $cond = ['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED]]; isset($params['user_id']) && $cond['user_id'] = $params['user_id']; if (!empty($params['mch_id'])) $cond['mch_id'] = $params['mch_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status == OrderStatusEnum::ACCOMPLISH) throw new Exception('订单已经完成,无需重复处理'); if ($model->order_status != OrderStatusEnum::SING && $model->order_status != OrderStatusEnum::TAKE_FINISH) throw new Exception('订单已经被处理'); if (OrderDetail::getAfterSaleCountByOrderId($params['id']) > 0) throw new Exception('请先处理或关闭订单售后'); $model->order_status = OrderStatusEnum::ACCOMPLISH; $model->finish_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); if (in_array($model->order_source, [OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_STORE_RESERVE])) { // 同步订单状态 OrderReserve::syncOrderStatus($model); } if (!empty($model['store_id'])) { $is_install = MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_STORE); if ($is_install) { $store_order = StoreOrder::findOne(['order_no' => $model['order_no']]); if ($store_order) { $store_order->order_status = OrderStatusEnum::ACCOMPLISH; $store_order->finish_time = time(); if (!$store_order->save()) throw new Exception($store_order->getErrorMessage()); if (MallAddons::isInstall($model['mall_id'], AddonsEnum::ADDONS_NAME_STORE)) { $user = User::getOne([['id' => $model->user_id]], true, [], false, 'nickname'); $event = new \addons\Store\common\events\order\OrderFinishEvent($model->mall_id); $data['id'] = $model->id; $data['order_no'] = $model->order_no; $data['operator_id'] = $model->user_id; $data['operator_name'] = $user['nickname']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); } } } } return $model; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } public static function exportHandle(array $data) { set_time_limit(3600); // 设置一个小时 ini_set('memory_limit', '1024M'); //设置内存 date_default_timezone_set('Asia/Shanghai'); $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); if ($download) { // 因为当数据过大时会创建多个文件所以开启事务 $transaction = \Yii::$app->db->beginTransaction(); try { $params = json_decode($download->params, true); $isChanjetExport = !empty($params['is_chanjet_addons']); $filename = $download->name; $type = $download->type; $order_detail_model = OrderDetail::find()->alias('od'); $order_detail_model->leftJoin(self::tableName() . 'as o', 'o.id=od.order_id'); $order_detail_model->where(['od.mall_id' => $params['mall_id'], 'o.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]); if (isset($params['store_id']) && $params['store_id'] !==''){ $order_detail_model->andWhere(['=', 'od.store_id', $params['store_id']])->andWhere(['=', 'o.store_id', $params['store_id']]); }else{ $order_detail_model->andWhere(['=', 'od.store_id', 0])->andWhere(['=', 'o.store_id', 0]); } $is_show_mch_name = 0; if (isset($params['mch_id'])) { if ($params['mch_id'] == -1) { $is_show_mch_name = 1; $order_detail_model->andWhere(['<>', 'od.mch_id', 0]); } else { $order_detail_model->andWhere(['=', 'od.mch_id', $params['mch_id']]); } }else{ $order_detail_model->andWhere(['=', 'od.mch_id', 0]); } $order_detail_model->andWhere(['>=', 'od.status', StatusEnum::DISABLED]); if (!empty($params['ids'])) { $order_detail_model->andWhere(['od.order_id' => $params['ids']]); } if (!empty($params['start_date'])) { $order_detail_model->andWhere(['>=','od.created_at',strtotime($params['start_date'])]); } if (!empty($params['end_date'])) { $order_detail_model->andWhere(['<=','od.created_at',strtotime($params['start_date'])]); } if(!empty($params['keyword'])){ $order_detail_model->andWhere(['like','od.goods_name',$params['keyword']]); } if(!empty($params['user_id'])){ if (!empty($params['child_orders'])) { $u_ids = UserPartitionRelationship::getChildIdArr($params['user_id']); $u_ids[] = $params['user_id']; $order_detail_model->andWhere(['in','od.user_id',$u_ids]); } else { $order_detail_model->andWhere(['=','od.user_id',$params['user_id']]); } } if (!empty($params['order_no'])) { $params['order_no'] = explode(',', $params['order_no']); $orderIds = self::find()->where(['order_no' => $params['order_no']])->select('id')->column(); $order_detail_model->andWhere(['in', 'od.order_id', $orderIds]); } if (!empty($params['mobile'])) { $user = User::find()->where(['like', 'mobile', $params['mobile'] . '%', false])->all(); $order_detail_model->andWhere(['in', 'od.user_id', array_column($user, 'id')]); } if (!empty($params['start'])) { $order_detail_model->andWhere(['>=', 'od.created_at', strtotime($params['start'])]); } if (!empty($params['end'])) { $order_detail_model->andWhere(['<=', 'od.created_at', strtotime($params['end'])]); } if (isset($params['order_status']) && $params['order_status'] !== '' && $params['order_status'] != 999) { $order_detail_model->andWhere(['=', 'od.order_status', $params['order_status']]); } if (!empty($params['type']) && !empty($params['type_value'])) { switch ($params['type']) { case 'mobile': $uids = User::find()->select('id') ->where(['mall_id' => $params['mall_id']]) ->andWhere(['like', 'mobile', $params['type_value'] . '%', false])->column(); !empty($uids) && $order_detail_model->andWhere(['od.user_id' => $uids]); break; case 'username': $uids = User::find()->select('id') ->where(['mall_id' => $params['mall_id']]) ->andWhere(['username' => $params['type_value']])->column(); !empty($uids) && $order_detail_model->andWhere(['od.user_id' => $uids]); break; case 'user_id': $order_detail_model->andWhere(['od.user_id' => $params['type_value']]); break; case 'order_id': $order_detail_model->andWhere(['od.order_id' => $params['type_value']]); break; case 'goods_name': $order_detail_model->andWhere(['like', 'od.goods_name', '%' . $params['type_value'] . '%', false]); break; case 'consignee': case 'consignee_mobile': if ($params['type'] == 'consignee') { $order_detail_model->andWhere(['like', 'o.receiver_name', $params['type_value'] . '%', false]); } else { $order_detail_model->andWhere(['like', 'o.mobile', $params['type_value'] . '%', false]); } break; default: } } if (!empty($params['type'] == 'user_id') && !empty($params['type_value'])) { $order_detail_model->andWhere(['=', 'od.user_id', $params['type_value']]); } if (!empty($params['payment_type'])) { $order_detail_model ->andWhere(['=', 'o.payment_type', $params['payment_type']]); } if (!empty($params['shipping_type'])) { $order_detail_model->andWhere(['=', 'o.shipping_type', $params['shipping_type']]); } if(!empty($params['marketing_type'])){ if($params['marketing_type'] != 'order_user_handle_finish'){ $order_detail_model->andWhere(['=', 'o.marketing_type', $params['marketing_type']]); }else{ $order_user_handle = OrderUserHandle::lists(['where' => [['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED]], 'select' => 'order_id']); $order_detail_model->andWhere(['in', 'o.id', array_column($order_user_handle, 'order_id')]); } } //标识排除 if(!empty($params['not_marketing_type'])){ if($params['not_marketing_type'] != 'order_user_handle_finish'){ $order_detail_model->andWhere(['!=', 'o.marketing_type', $params['not_marketing_type']]); }else{ $order_user_handle = OrderUserHandle::lists(['where' => [['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED]], 'select' => 'order_id']); $order_detail_model->andWhere(['not in', 'o.id', array_column($order_user_handle, 'order_id')]); } } if (!empty($params['province'])) { $order_detail_model->andWhere(['IN', 'o.id', (array)self::find()->where(['mall_id' => $params['mall_id']]) ->andWhere(['OR',['province' => $params['province']], ['city' => $params['province']], ['area' => $params['province']]]) ->select('id') ->asArray() ->column()]); } if(!empty($params['cate_id'])){ $goods_cate_ids = GoodsCate::getAllCate($params['mall_id'], [$params['cate_id']]); $order_detail_model->andWhere(['IN', 'goods_id', (array)GoodsCateRelate::find() ->select('goods_id')->andWhere(['IN', 'cate_id' , $goods_cate_ids]) ->column()]); } $order_detail_model->with(['order' => function ($query) use ($isChanjetExport) { if ($isChanjetExport) { $query->with('addonsChanjetRequest'); } }, 'user' => function ($query) { $query->select('id,nickname,username,mobile'); }]); $fields = $params['fields']; $fields_arr = self::fieldsList(null, $isChanjetExport); $have_select_field_arr = []; $is_attr = 0; foreach ($fields as $value) { if ($value == 'goods_attr_name') { $is_attr = 1; } if (isset($fields_arr[$value])) $have_select_field_arr[] = $fields_arr[$value]; if ($value == 'mch_id') { $have_select_field_arr[] = '商户名称'; } } $order_status_list = OrderStatusEnum::getMap(); $payment_type_list = PayTypeEnum::getMap(); $shipping_status_list = ShippingStatusEnum::getMap(); $batchSize = 10000; // 设置订单批量导出数量 $i = 0; //循环次数 $orderCount = $order_detail_model->count(); // 查询订单总条数 $is_order_page = $orderCount > $batchSize; // 判断是否需要分页 foreach ($order_detail_model->batch($batchSize) as $order_details) { $goods_attr_arr = []; if ($is_attr) { $goods_attr_ids = array_column($order_details, 'goods_attr_id'); $goods_attr_arr = GoodsAttr::lists(['where' => [['id' => $goods_attr_ids]], 'select' => 'id,goods_no', 'index' => 'id']); } $mch_list = []; if (!empty($is_show_mch_name)) { $mch_ids = array_unique(array_column($order_details, 'mch_id')); $mch_list = Mch::lists(['where' => [['id' => $mch_ids]], 'select' => 'id,store_name', 'index' => 'id']); } $order_ids_arr = []; $exportList = array_map(function ($order_detail) use ($fields, $payment_type_list, $order_status_list, $shipping_status_list, $goods_attr_arr, $mch_list,&$order_ids_arr) { $row = []; foreach ($fields as $field) { // 收货人地址切割 if (!empty($order_detail['order']['region_name'])) { $region_name = explode(' ', $order_detail['order']['region_name']); } // 判断是否安装社区团购 $is_install = MallAddons::isInstall($order_detail['mall_id'], AddonsEnum::ADDONS_NAME_COMMUNITY); if ($is_install && $order_detail['order']['shipping_type'] == 2 && !empty($order_detail['order']['extra_info'])) { $extra_info = json_decode($order_detail['order']['extra_info'], true); if (!empty($extra_info['head_id'])) { $headInfo = (new HeadService())->getHeadInfo($order_detail['mall_id'], $extra_info['head_id']); if (!empty($headInfo)) { $region_name = [ $headInfo['province'] ?? '', $headInfo['city'] ?? '', $headInfo['district'] ?? '' ]; $order_detail['order']['address'] = $headInfo['address']; } } } switch (true) { case (in_array($field, ['created_at'])): $row[] = !empty($order_detail[$field]) ? date('Y-m-d H:i:s', $order_detail[$field]) : ''; break; case (in_array($field, ['pay_time', 'consign_time', 'sign_time'])): $row[] = !empty($order_detail['order'][$field]) ? date('Y-m-d H:i:s', $order_detail['order'][$field]) : ''; break; case (in_array($field, ['order_no','out_trade_no', 'mobile', 'receiver_name', 'region_name', 'address', 'shipping_money', 'seller_remark', 'remark'])): $row[] = !empty($order_detail['order'][$field]) ? $order_detail['order'][$field] : ''; break; case ($field == 'pay_money'): if (!isset($order_ids_arr[$field]) || !in_array($order_detail['order_id'],$order_ids_arr[$field])) { $row[] = !empty($order_detail['order'][$field]) ? $order_detail['order'][$field] : ''; $order_ids_arr[$field][]=$order_detail['order_id']; } else { $row[] = ''; } break; case (in_array($field, ['order_id'])): $row[] = !empty($order_detail['order']['id']) ? $order_detail['order']['id'] : ''; break; case ($field == 'payment_type'): if (!empty($order_detail['order'][$field])) { $row[] = !empty($payment_type_list[$order_detail['order'][$field]]) ? $payment_type_list[$order_detail['order'][$field]] : ''; } else { $row[] = ''; } break; case ($field == 'order_status'): $row[] = !empty($order_status_list[$order_detail[$field]]) ? $order_status_list[$order_detail[$field]] : ''; break; case ($field == 'order_type'): if ($order_detail['order']['is_feedback'] != StatusEnum::DISABLED) { if ($order_detail['order']['is_feedback'] == StatusEnum::ENABLED) { $row[] = '售后订单维权中'; } else { $row[] = '售后订单维权完成'; } } else { $row[] = ''; } //var_dump($order_detail['order']['is_feedback'],$row); break; case ($field == 'shipping_status'): $row[] = !empty($shipping_status_list[$order_detail[$field]]) ? $shipping_status_list[$order_detail[$field]] : ''; break; case ($field == 'pay_status'): $row[] = !empty($order_detail['order'][$field]) ? '已付款' : '未付款'; break; case ($field == 'user_mobile'): $row[] = $order_detail['user']['mobile'] ?? ''; break; case ($field == 'username'): $row[] = $order_detail['user']['username'] ?? ''; break; case ($field == 'nickname'): $row[] = $order_detail['user']['nickname'] ?? ''; break; case ($field == 'detail_address'): $str = ''; if (!empty($region_name[0])) $str .= $region_name[0]; if (!empty($region_name[1])) $str .= $region_name[1]; if (!empty($region_name[2])) $str .= $region_name[2]; if (!empty($region_name[3])) $str .= $region_name[3]; $str .= $order_detail['order']['address']; $row[] = $str; break; case ($field == 'province'): $row[] = $region_name[0] ?? ''; break; case ($field == 'city'): $row[] = $region_name[1] ?? ''; break; case ($field == 'area'): $row[] = $region_name[2] ?? ''; break; case ($field == 'town'): $row[] = $region_name[3] ?? ''; break; case ($field == 'goods_attr_name'): $str = !empty($order_detail[$field]) ? $order_detail[$field] : ''; if (!empty($goods_attr_arr[$order_detail['goods_attr_id']]['goods_no'])) { if (!empty($str)) { $str .= ';'; } $str .= '货号:' . $goods_attr_arr[$order_detail['goods_attr_id']]['goods_no']; } $row[] = $str; break; case ($field == 'mch_id'): if (isset($mch_list) && isset($mch_list[$order_detail[$field]])) { $row[] = $mch_list[$order_detail[$field]]['store_name']; } break; case ($field == 'user_id'): $row[] = !empty($order_detail[$field]) ? $order_detail[$field] : ''; break; case ($field == 'chanjet_updated_at'): if (isset($order_detail['order']['addonsChanjetRequest']['updated_at'])) { $row[] = date('Y-m-d H:i:s', $order_detail['order']['addonsChanjetRequest']['updated_at']); }else { $row[] = ''; } break; case ($field == 'chanjet_request_status'): if (isset($order_detail['order']['addonsChanjetRequest']['request_status'])) { $row[] = AddonsChanjetRequestEnum::getMap()[$order_detail['order']['addonsChanjetRequest']['request_status']] ?? ''; }else { $row[] = ''; } break; case ($field == 'cost_total_price'): if (isset($order_detail['cost_price']) && isset($order_detail['num'])) { $row[] = bcmul($order_detail['num'], $order_detail['cost_price'], 2); }else { $row[] = ''; } break; case ($field == 'parent_id'): // 获取用户上级名称 $parentId = User::find()->where(['id' => $order_detail['user_id']])->select('parent_id')->scalar(); $parentName = User::find()->where(['id' => $parentId])->select('nickname')->scalar(); $row[] = $parentName ?? ''; break; default: $row[] = !empty($order_detail[$field]) ? $order_detail[$field] : ''; } } return $row; }, $order_details); if (!empty($exportList)) { $csv = new CsvTool(); $csv->filename = $is_order_page ? $filename . "_1" : $filename; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->header = $have_select_field_arr; $csv->data = $exportList; if ($is_order_page && $i == 0) { // 因为订单页需要分页,所以需要设置文件名 $download->name = $filename . '_1'; $download->save(); } if ($i >= 1) { $newFileName = $filename . '_' . ($i + 1); $csv->filename = $newFileName; $downloadData = array( 'mall_id' => $download->mall_id, 'mch_id' => $download->mch_id, 'store_id' => $download->store_id, 'name' => $newFileName, 'type' => $download->type, 'handler_class' => $download->handler_class, 'method' => $download->method, 'params' => $download->params, 'data' => $exportList ); $downloadModel = Download::setData($downloadData); if ($downloadModel === false) { Yii::$app->custom->logs('创建下载任务失败:' . $downloadData['name'], Download::getStaticError()); throw new Exception('创建新下载任务失败'); }; $download = $downloadModel; } $csv->export(); $csv->updateDown($download, $params['mall_id']); $i++; unset($exportList); } } $transaction->commit(); return true; } catch (\Exception $e) { $transaction->rollBack(); $download->status = 3; $res = $download->save(); var_dump($e->getMessage() . $e->getFile() . $e->getLine()); self::setStaticError($e->getMessage()); return $e->getMessage(); } } } public static function fieldsList($field = null, $isChanjet = false) { $fields = [ 'order_id' => '订单ID', 'user_id' => '用户ID', 'username' => '真实姓名', 'nickname' => '用户昵称', 'user_mobile' => '用户手机号', 'order_no' => '订单编号', 'out_trade_no' => '外部交易号', 'mobile' => '收货人的手机号码', 'detail_address' => '收货人地址全称', 'receiver_name' => '收货人姓名', 'province' => '收货人省份', 'city' => '收货人城市', 'area' => '收货人地区/街道', 'town' => '收货人乡/镇', // 'region_name' => '地区名称(省市区[乡/镇]', 'address' => '详细地址', 'goods_name' => '商品名', //detail 'goods_attr_name' => '规格', //detail 'num' => '购买数量', //detail 'cost_price' => '商品成本单价', //detail 'cost_total_price' => '商品成本总价', //detail 'original_goods_price' => '商品原本总价', //detail 'goods_price' => '商品优惠后总价', //detail 'shipping_money' => '订单运费', 'created_at' => '下单时间', 'payment_type' => '支付方式', //- 'order_type' => '订单情况', //- 'order_status' => '订单状态', //- 'pay_status' => '订单付款状态', //- 'pay_time' => '订单付款时间', 'shipping_status' => '订单配送状态', //- detail 'consign_time' => '卖家发货时间', // 'sign_time' => '买家签收时间', 'remark' => '用户订单备注', 'seller_remark' => '商家订单备注', 'pay_money' => '订单实付金额', 'parent_id' => '直推上级', ]; if ($isChanjet) { $fields['chanjet_updated_at'] = '最后推送时间'; $fields['chanjet_request_status'] = '推送状态'; } if ($field === null) return $fields; $temp = []; foreach ($field as $val) { if (isset($fields[$val])) $temp[$val] = $fields[$val]; } return $temp; } /** * 拼装搜索参数 * @Author bing * @DateTime 2021-11-29 14:52:23 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $mall_id * @param [type] $search * @return array */ public static function searchParams($mall_id, $search) { date_default_timezone_set('PRC'); // 查询参数 $isReserve = $search['is_reserve']; $where[] = ['=', 'mall_id', $mall_id]; $where[] = ['>=', 'status', StatusEnum::DISABLED]; if ($isReserve) { $where[] = ['not in', 'order_source', [OrderSourceEnum::SOURCE_SELF_MALL]]; $where[] = ['=', 'order_source', OrderSourceEnum::SOURCE_RESERVE]; } else { $where[] = ['not in', 'order_source', [OrderSourceEnum::SOURCE_SELF_MALL, OrderSourceEnum::SOURCE_RESERVE, OrderSourceEnum::SOURCE_WUZHOU_CHAIN]]; } $where[] = ['store_id' => 0]; if (!empty($search['mch_id'])) { $where[] = ['mch_id' => $search['mch_id']]; } else { $where[] = ['mch_id' => 0]; } //配送类型搜索 if (!empty($search['shipping_type'])) $where[] = ['shipping_type'=>$search['shipping_type']]; if (isset($search['order_id'])) $where[] = ['in', 'id', explode(',', $search['order_id'])]; ($search['payment_type'] ?? false) && $where[] = ['=', 'payment_type', $search['payment_type']]; ($search['shipping_type'] ?? false) && $where[] = ['=', 'shipping_type', $search['shipping_type']]; isset($search['receiver_name']) && $search['receiver_name'] !== '' && $where[] = ['=', 'receiver_name', $search['receiver_name']]; if($search['marketing_type'] ?? false){ if($search['marketing_type'] == 'order_user_handle_finish'){ $order_user_handle = OrderUserHandle::lists(['where' => [['mall_id' => $mall_id], ['status' => StatusEnum::ENABLED]], 'select' => 'order_id']); $where[] = ['id' => array_column($order_user_handle, 'order_id')]; } elseif ($search['marketing_type'] == OrderSourceEnum::SOURCE_CLOUD_PRESCRIPTION) { $where[] = ['=', 'goods_subtype', GoodsTypeEnum::GOODS_SUBTYPE_PRESCRIPTION]; } else{ $where[] = ['=', 'marketing_type', $search['marketing_type']]; } } //标识排除 if($search['not_marketing_type'] ?? false){ if($search['not_marketing_type'] == 'order_user_handle_finish'){ $order_user_handle = OrderUserHandle::lists(['where' => [['mall_id' => $mall_id], ['status' => StatusEnum::ENABLED]], 'select' => 'order_id']); $where[] = ['not in', 'id', array_column($order_user_handle, 'order_id')]; } elseif ($search['marketing_type'] == OrderSourceEnum::SOURCE_CLOUD_PRESCRIPTION) { $where[] = ['=', 'goods_subtype', GoodsTypeEnum::GOODS_SUBTYPE_PRESCRIPTION]; } else{ $where[] = ['!=', 'marketing_type', $search['not_marketing_type']]; } } if (isset($search['order_status']) && $search['order_status'] != 999) { if ($isReserve && $search['order_status'] == OrderStatusEnum::SING) { // 以前端栏目配置服务中即待验收其状态包括已提货 $where[] = ['in', 'order_status', [OrderStatusEnum::SING, OrderStatusEnum::TAKE_FINISH]]; } else { $where[] = ['=', 'order_status', $search['order_status']]; } } if (isset($search['is_use_coupon'])) { if ($search['is_use_coupon'] == 1) { $where[] = ['>', 'coupon_money', 0]; } else { $where[] = ['=', 'coupon_money', 0]; } } // ($search['order_status'] ?? false) && $search['order_status'] != 999 && $where[] = ['=', 'order_status', $search['order_status']]; ($search['order_no'] ?? false) && $where[] = ['in', 'order_no', explode(',',$search['order_no'])]; ($search['start'] ?? false) && $where[] = ['>=', 'created_at', strtotime($search['start'])]; ($search['end'] ?? false) && $where[] = ['<=', 'created_at', strtotime($search['end'])]; if($search['province'] ?? false) { $where[] =['IN', 'id', (array)self::find()->where(['mall_id' => $mall_id]) ->andWhere(['OR',['province' => $search['province']],['city' => $search['province']], ['area' => $search['province']]]) ->select('id') ->asArray() ->column()]; } if($search['cate_id'] ?? false){ $goods_cate_ids = GoodsCate::getAllCate($mall_id, [$search['cate_id']]); $order_ids = (array)OrderDetail::find()->where(['mall_id' => $mall_id])->andWhere(['IN', 'goods_id', (array)GoodsCateRelate::find() ->select('goods_id')->andWhere(['IN', 'cate_id' ,$goods_cate_ids]) ->column()])->select('order_id')->column(); $where[] = ['id'=> $order_ids]; } if ($search['type_value'] ?? false) { switch ($search['type']) { case 'mobile': $uids = User::find()->select('id')->where(['like', 'mobile', $search['type_value'] . '%', false])->column(); !empty($uids) ? $where[] = ['in', 'user_id', $uids] : $where[] = ['=', 'user_id', 0]; break; case 'username': $uids = User::find()->select('id')->where(['username' => $search['type_value']])->column(); !empty($uids) && $where[] = ['in', 'user_id', $uids]; break; case 'user_id': $where[] = ['in', 'user_id', $search['type_value']]; break; case 'order_id': $where[] = ['=', 'id', $search['type_value']]; break; case 'goods_name': $order_detail_list = OrderDetail::lists([ 'where' => [ ['mall_id' => $mall_id], ['store_id' => 0], ['mch_id' => 0], ['like', 'goods_name', '%' . $search['type_value'] . '%', false] ], 'select' => 'order_id' ]); $orderIds = array_column($order_detail_list, 'order_id'); $where[] = ['id' => $orderIds]; break; // 查询交易单号 case 'trade_no': $ids = PaymentTrade::find()->where(['mall_id' => $mall_id, 'out_trade_no' => $search['type_value']])->select('id')->column(); $order_nos = PaymentTradeOrder::find()->where(['trade_id' => $ids])->select('order_no')->column(); $where[] = ['order_no' => $order_nos]; break; case 'consignee': case 'consignee_mobile': if ($search['type'] == 'consignee') { $where[] = ['like', 'receiver_name', $search['type_value'] . '%', false]; } else { $where[] = ['like', 'mobile', $search['type_value'] . '%', false]; } break; default: } } return $where; } public static function updateOrderPayMoney($rand_fee_arr) { foreach ($rand_fee_arr as $order_no => $rand_fee) { $order_model = Order::getOne([['order_no' => $order_no]], false, ['detail']); if ($order_model) { $extra_arr = json_decode($order_model->extra_info, true); if (!is_array($extra_arr)) { $extra_arr[] = $order_model->extra_info; } // $order_model->pay_money -= $rand_fee; // $order_model->goods_price -= $rand_fee;// 随机减的金额不能减去商品实际售价金额 $order_detail_list = $order_model['detail']; $total_goods_price = array_sum(array_column($order_detail_list, 'goods_price')); $temp_rand_fee = 0; $extra_arr['rand_fee']['order'] = ['desc' => '随机减', 'order_no' => $order_no, 'money' => $rand_fee]; $order_detail_extra_info = []; foreach ($order_detail_list as $k => $order_detail) { if (!isset($order_detail_list[$k + 1])) { $order_detail_rand_fee = bcsub($rand_fee, $temp_rand_fee, 2); } else { $rate = bcdiv($order_detail['goods_price'], $total_goods_price, 2); $order_detail_rand_fee = bcmul($rate, $rand_fee, 2); $temp_rand_fee = bcadd($order_detail_rand_fee, $temp_rand_fee, 2); } // 商品优惠后的金额不包括随机减金额 // $order_detail->goods_price-=$order_detail_rand_fee; // $order_detail->save(); $order_detail_extra_info = ['desc' => '随机减', 'order_detail_id' => $order_detail['id'], 'money' => $order_detail_rand_fee]; } $extra_arr['rand_fee']['order_detail'] = $order_detail_extra_info; $order_model->extra_info = json_encode($extra_arr); $order_model->save(); } } } public static function checkScoreMallIsCommission($marketing_type) { $join_commission = isset(\Yii::$app->params['is_score_mall_join_commission']) ? \Yii::$app->params['is_score_mall_join_commission'] : true; return $marketing_type == AddonsEnum::ADDONS_NAME_SCORE_MALL && !$join_commission; } public static function userInitiativeComplete($params) { try{ $order = self::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]); if(empty($order)) throw new \Exception('订单参数错误'); if(!in_array($order->order_status ,[OrderStatusEnum::PAY,OrderStatusEnum::SHIPMENTS,OrderStatusEnum::SING])){ throw new \Exception('该订单不支持此操作'); } if($order->order_status == OrderStatusEnum::PAY){ $new_params = $params; $new_params['order_detail_ids'] = []; $new_params['shipping_type'] = 0; $new_params['express_id'] = $new_params['express_name'] = $new_params['customer_name']= $new_params['express_no'] = $new_params['memo']= ''; $details = ArrayHelper::toArray($order->detail); foreach($details as $detail){ $new_params['order_detail_ids'][] = $detail['id']; } if(OrderExpress::delivery($new_params) == false){ throw new \Exception(OrderExpress::getStaticError()); } $order->order_status = OrderStatusEnum::SHIPMENTS; if(self::takeDelivery($params) == false){ throw new \Exception(self::getStaticError()); } } if(self::complete($params) == false){ throw new \Exception(self::getStaticError()); } OrderUserHandle::setData([ 'mall_id' => $params['mall_id'], 'user_id' => $params['user_id'], 'order_id' => $params['id'], 'order_status' => OrderStatusEnum::ACCOMPLISH ]); return true; }catch(\Exception $e){ self::setStaticError($e->getMessage()); return false; } } public static function handleVerifyOrder($params) { try{ $order = self::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]); if(empty($order)) throw new \Exception('订单参数错误'); if(!in_array($order->order_status ,[OrderStatusEnum::PAY,OrderStatusEnum::SHIPMENTS,OrderStatusEnum::SING])){ throw new \Exception('该订单不支持此操作'); } if($order->order_status == OrderStatusEnum::PAY){ $new_params = $params; $new_params['order_detail_ids'] = []; $new_params['shipping_type'] = 0; $new_params['express_id'] = $new_params['express_name'] = $new_params['customer_name']= $new_params['express_no'] = $new_params['memo']= ''; $details = ArrayHelper::toArray($order->detail); foreach($details as $detail){ $new_params['order_detail_ids'][] = $detail['id']; } if(OrderExpress::delivery($new_params) == false){ throw new \Exception(OrderExpress::getStaticError()); } $order->order_status = OrderStatusEnum::SHIPMENTS; } if($order->order_status == OrderStatusEnum::SHIPMENTS){ if(self::takeDelivery($params) == false){ throw new \Exception(self::getStaticError()); } } if(self::complete($params) == false){ throw new \Exception(self::getStaticError()); } return true; }catch(\Exception $e){ self::setStaticError($e->getMessage()); return false; } } /** * 获取会员支付总金额 * * @param integer $user_id * @param integer $pay_status * @return float */ public static function getUserPayMoney(int $user_id, int $pay_status = StatusEnum::ENABLED) { return static::find() ->where(['user_id' => $user_id, 'pay_status' => $pay_status, 'status' => StatusEnum::DISABLED]) ->sum('pay_money'); } /** * 批量添加备注 * @param $params * @return bool */ public static function batchRemark(array $params): bool { try { $orderIds = explode(',', $params['order_ids']); $res = self::updateAll(['seller_remark' => $params['content']], ['id' => $orderIds]); if (!$res) { throw new Exception('批量备注失败!'); } return true; } catch (Exception $e) { if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 国内手机号验证 * @param $number * @return bool */ public static function isMobileNumber($number): bool { // 手机号正则表达式 $pattern = '/^1[3-9]\d{9}$/'; if (preg_match($pattern, $number)) { return true; } else { return false; } } public static function getOrderByNo($params) { try { $info = self::getOne([ ['mall_id' => $params['mall_id']], ['order_no' => $params['order_no']] ], true, ['detail', 'user']); $data = [ 'user' => [ 'id' => $info['user']['id'], 'nickname' => $info['user']['nickname'], 'avatar_url' => $info['user']['avatar_url'], 'mobile' => $info['user']['mobile'], 'parent_id' => $info['user']['parent_id'], ], 'pay_money' => $info['pay_money'], 'order_no' => $info['order_no'], 'id' => $info['id'], ]; foreach ($info['detail'] as $key => $value) { $data['product'][] = [ 'pic_url' => $value['pic_url'], 'goods_name' => $value['goods_name'], 'goods_attr_name' => $value['goods_attr_name'], 'price' => $value['price'], 'num' => $value['num'], ]; } return $data; } catch (\Exception $e) { throw new Exception($e->getMessage()); } } /** * 判断会员是否支付 * * @param $user_id * @return bool */ public static function userIsPay($user_id) { return Order::find()->andWhere(['user_id'=>$user_id,'pay_status'=>1,'store_id'=>0,'mch_id'=>0])->exists(); } /** * 判断会员是否创建订单 * * @param $user_id * @return bool */ public static function userIsCreated($user_id) { return Order::find()->andWhere(['user_id'=>$user_id,'store_id'=>0,'mch_id'=>0])->exists(); } public static function isStopOrder($mall_id) { $is_stop_order = MallSetting::conf($mall_id,'order.is_stop_order'); if ($is_stop_order) return true; return false; } }