聚合供应链 * @property int|null $supplier_type 供应者类型:0:自身;1:商城;2:o2o;3:多商户 * @property string|null $clerk_code 核销码 * @property int|null $create_type 创建方式:1:线上下单;2:系统创建 */ class StoreOrder extends BaseActiveRecord { /** * {@inheritdoc} */ public static function tableName() { return '{{%addons_store_order}}'; } /** * {@inheritdoc} */ public function rules() { return [ [['mch_id', 'store_id', 'mall_id', 'user_id', 'province', 'city', 'area', 'town', 'community', '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', 'supplier_type', 'close_time', 'created_at', 'updated_at','create_type'], 'integer'], [['shipping_money', 'refund_money', 'pay_money', 'goods_price', 'original_goods_price', 'coupon_money', 'score', 'score_money'], 'number'], [['extra_info'], 'string'], [['order_no', 'out_trade_no'], 'string', 'max' => 100], [['mobile'], 'safe'], [['address', 'region_name'], 'string', 'max' => 200], [['zip', 'ip'], 'string', 'max' => 20], [['receiver_name', 'marketing_type'], 'string', 'max' => 50], [['remark', 'seller_remark', 'order_source'], 'string', 'max' => 255], [['clerk_code'], 'string', 'max' => 12], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => '订单id', 'mch_id' => '多商户id,0表示商城订单', 'store_id' => '门店id,0表示商城订单', 'mall_id' => '商城ID', 'user_id' => '用户id', 'order_no' => '订单编号', 'out_trade_no' => '系统支付流水号', 'mobile' => '收货人的手机号码', 'province' => '收货人所在省', 'city' => '收货人所在城市', 'area' => '收货人所在街道', 'town' => '镇id', 'address' => '详细地址', 'region_name' => '地区名称(省市区[乡/镇])', 'zip' => '收货人邮编', 'receiver_name' => '收货人姓名', 'remark' => '用户订单备注', 'seller_remark' => '商家订单备注', 'shipping_type' => '订单配送方式【1物流配送 2买家自提 3货到付款 4本地配送】', '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' => '更新时间', 'order_source' => '订单来源:juhe_shop=>聚合供应链', 'supplier_type' => '供应者类型:0:自身;1:商城;2:o2o;3:多商户', 'clerk_code' => '核销码', 'create_type' => '创建方式:1:线上下单;2:系统创建', ]; } public static function fieldsList($field = null) { $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' => '订单实付金额' ]; if ($field === null) return $fields; $temp = []; foreach ($field as $val) { if (isset($fields[$val])) $temp[$val] = $fields[$val]; } return $temp; } public function getBase_user() { return $this->hasOne(User::class, ['id' => 'user_id'])->select(['id', 'username', 'nickname', 'avatar_url', 'mobile']); } public function getStore() { return $this->hasOne(Store::class, ['id' => 'store_id']); } public function getDetail() { return $this->hasMany(StoreOrderDetail::class, ['order_id' => 'id']); } public function getExpress() { return $this->hasMany(OrderExpress::class, ['order_id' => 'id']); } public function getExpress_log() { return $this->hasMany(OrderExpressLog::class, ['order_id' => 'id']); } public function getReserve() { return $this->hasOne(StoreOrderReserve::class, ['order_id' => 'id']); } public function beforeSave($insert) { // 未支付/未付款 if ($this->isNewRecord || $this->order_status == OrderStatusEnum::NOT_PAY) { // 支付金额为产品金额 $this->pay_money = $this->goods_price; // 实付增加运费 $this->pay_money += $this->shipping_money; } // var_dump($this->id, $this->isNewRecord, $this->order_status, $this->oldAttributes['order_status']); // 修改订单商品状态 if (!$this->isNewRecord && isset($this->order_status)&&isset($this->oldAttributes['order_status'])&& $this->order_status != $this->oldAttributes['order_status']) { StoreOrderDetail::updateAll( ['order_status' => $this->order_status], [ 'order_status' => $this->oldAttributes['order_status'],'order_id' => $this->id] ); } return parent::beforeSave($insert); } public static function createOrder($form) { $stock_locks = []; try { if (Order::isStopOrder($form['mall_id'])) throw new Exception('站点维护中,暂时无法下单'); $group_order_goods = $form['group_order_goods']; $give_data = $form['marketing']['give']??[]; $trans = Yii::$app->db->beginTransaction(); $attr = []; $order_trade_info = []; $order_ids = []; $order_nos = []; $total_amount = 0; $data = is_array($form->data) ? $form->data : json_decode($form->data, true); $tmp_goods_ids = []; foreach ($group_order_goods as $mch_order) { $total_amount = 0; $mch_order_info = $mch_order['mch_order_info']; // 如果是预约订单且是到店服务 if ($form->type == 'reserve_now' && $form->data['service_type'] == 2) { // 替换收货地址 $mch_order_info['province'] = $mch_order_info['store']['province_id']; $mch_order_info['city'] = $mch_order_info['store']['city_id']; $mch_order_info['area'] = $mch_order_info['store']['district_id']; $mch_order_info['address'] = $mch_order_info['store']['address']; $mch_order_info['region_name'] = ""; $mch_order_info['receiver_name'] = $mch_order_info['store']['store_name']; $mch_order_info['mobile'] = $mch_order_info['store']['shop_mobile']; $mch_order_info['clerk_code'] = OrderReserve::getClerkCode($mch_order['mall_id'],ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE); }else{ if ($form->data['shipping_type'] == 2) { $mch_order_info['clerk_code'] = self::getClerkCode($mch_order_info['mall_id']); } } $order = new StoreOrder(); $order->loadDefaultValues(); $order->load($mch_order_info, ''); $order->order_status = OrderStatusEnum::NOT_PAY; empty($order->order_no) && $order->order_no = StringHelper::generateOrderNo('st'); $res = $order->save(); if ($res === false) throw new \Exception($order->getErrorMessage()); $main_order = new Order(); $main_order->loadDefaultValues(); $mch_order_info['marketing_type'] = AddonsEnum::ADDONS_NAME_STORE; $mch_order_info['marketing_id'] = $order->id; $main_order->load($mch_order_info, ''); $main_order->order_status = OrderStatusEnum::NOT_PAY; $main_order->order_no = $order->order_no; $main_order->order_source = $order->order_source == OrderSourceEnum::SOURCE_RESERVE ? OrderSourceEnum::SOURCE_STORE_RESERVE : AddonsEnum::ADDONS_NAME_STORE; if ($order->supplier_type == StoreEnum::SELF_MALL_WUZHOU && MallAddons::isInstall($mch_order_info['mall_id'], AddonsEnum::ADDONS_NAME_WUZHOU_CHAIN)) { // 如果供应链是五洲,则订单来源改为五洲 $main_order->order_source = AddonsEnum::ADDONS_NAME_WUZHOU_CHAIN; } $res = $main_order->save(); if ($res === false) throw new \Exception($main_order->getErrorMessage()); $res = StoreOrderGive::setData($give_data,$order->id,$order->store_id,$order->mall_id); if($res === false) throw new Exception(StoreOrderGive::getStaticError()); //赊账 if(!empty($data['is_use_credit'])&&!empty($mch_order_info['credit_money'])){ $params = [ 'mall_id'=>$order['mall_id'], 'user_id'=>$order['user_id'], 'order_id'=>$order['id'], 'store_id'=>$order['store_id'], 'type'=>1, 'is_repayment'=>0, 'down_payments'=>bcsub($order['pay_money'],$mch_order_info['credit_money'],2), 'credit_money'=>$mch_order_info['credit_money'], 'extra'=>!empty($mch_order_info['order_extra'])? json_encode($mch_order_info['order_extra']):json_encode([]), ]; $res = StoreOrderCredit::setData($params); if ($res === false) throw new \Exception(StoreOrderCredit::getStaticError()); $total_amount+=$params['down_payments']; }else{ $total_amount+=$order['pay_money']; } $order_id = $order->id; $main_order_id = $main_order->id; $order_ids[] = $order->id; $order_nos[] = $order->order_no; // 总商品库存维护 $goods_stock_arr = []; // 遍历商户商品 $goods_ids = array_keys($mch_order['goods']); array_push($tmp_goods_ids, ...$goods_ids); $deduct_score = 0; $score_give_data = []; $score_give_setting = \Yii::$app->services->setting->addons->get($order['mall_id'], StoreEnum::ADDONS_NAME, 'scoreGive.score_give_setting'); if(!empty($score_give_setting)){ $score_give_setting = json_decode($score_give_setting,true); } $bear = $score_give_setting['bear']??-1; $deduct_score_arr = []; 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; //操作商品库存-减 StoreGoodsAttr::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']; } // 订单详情 $main_order_detail = new OrderDetail(); $main_order_detail->loadDefaultValues(); $main_order_detail->load($goods_detail, ''); $main_order_detail->store_id = $main_order->store_id; $main_order_detail->order_id = $main_order_id; if($goods_detail['supplier_type'] == StoreEnum::SELF_MALL_WUZHOU&& isset($goods_detail['mall_goods_id'])){ //$main_order_detail->goods_id = $goods_detail['mall_goods_id'] > 0 ? $goods_detail['mall_goods_id'] : $goods_detail['goods_id']; //$main_order_detail->goods_attr_id = $goods_detail['mall_attr_id'] > 0 ? $goods_detail['mall_attr_id'] : $goods_detail['goods_attr_id']; $main_order_detail->order_source = AddonsEnum::ADDONS_NAME_WUZHOU_CHAIN; } $res = $main_order_detail->save(); $order_detail = new StoreOrderDetail(); $order_detail->loadDefaultValues(); $order_detail->load($goods_detail, ''); $order_detail->order_id = $order_id; $order_detail->main_order_detail_id = $main_order_detail->id; $res = $order_detail->save(); if ($res === false) throw new \Exception($order_detail->getErrorMessage()); if ($res === false) throw new \Exception($main_order_detail->getErrorMessage()); $attr[$goods_detail['goods_attr_id']] = $goods_detail['num']; if (!empty($goods_detail['marketing'])) { if(empty($goods_detail['marketing']['give_score'])){ $goods_detail['marketing']['give_score'] = 0; } if($bear==1 && !empty($goods_detail['marketing']['give_score'])){ //门店主承担积分赠送 $score_give_data[$order_detail['store_id']][$order_detail->id] = $goods_detail['marketing']['give_score']; } $res = StoreOrderMarketing::setData($goods_detail['marketing'],$order_detail->id,$order_detail->store_id,$order_detail->mall_id); if($res === false) throw new Exception(StoreOrderMarketing::getStaticError()); if($goods_detail['marketing']['deduct_score']>0){ $deduct_score_arr[] = [ 'order_detail_id'=> $order_detail->id, 'deduct_score'=> $goods_detail['marketing']['deduct_score'], ]; } } } } if(!empty($deduct_score_arr)){ self::subUserScore($order,$deduct_score_arr); } if($score_give_data){ self::subStoreUserScore($order,$score_give_data); } if (!empty($data['user_coupon_ids'])) { $user_coupon_id = $data['user_coupon_ids']; $res =StoreCouponUserRelate::updateAll(['is_use' => 1,'updated_at'=>time()], ['id' => $user_coupon_id]); if ($res === false) throw new \Exception($order->getErrorMessage()); } $order_trade_info[] = [ 'order_no' => $order->order_no, 'amount' => $total_amount, 'title' => StoreOrder::getOrderTitle($order), 'notify_class' => 'addons\Store\common\logic\notify\Notify', 'order_type' => 'order', ]; } if ($order->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 预约类型的订单,单独保存信息 $res = StoreOrderReserve::create($order, $form, $main_order_id ?? 0); if ($res == false) throw new Exception(StoreOrderReserve::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('生成支付流水失败'); StoreOrder::updateAll(['out_trade_no' => $res['trade_no']], ['id' => $order_ids]); Order::updateAll(['out_trade_no' => $res['trade_no']], ['order_no' => $order_nos]); // 触发订单添加事件,事务提交完成后触发 $event = new OrderCreateEvent($form['mall_id']); Yii::$app->services->events->dispatch($event, ['order_ids' => $order_ids], $event->listeners); //删除购物车 if ($form->type == 'cart') StoreCart::decreaseNumb(['user_id' => $form->user_id, 'list' => $attr]); $res['order_ids'] = implode(',', $order_ids); $arr['transaction'] = $res; // 有可能需要跳转到指定页面 $arr['is_jump'] = StatusEnum::DISABLED; 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], StoreEnum::ADDONS_NAME); if (!empty($jump_url)) { $arr['pay_success_page'] = Json::encode(['route' => $jump_url, 'open_type' => 'page', 'params' => []]); $arr['is_jump'] = StatusEnum::ENABLED; } } } // 判断是否有安装抽奖插件 if (MallAddons::isInstall($order->mall_id, AddonsEnum::ADDONS_NAME_SHOPPING_LOTTERY)) { $pay_success_page = LotteryHelper::getJumpUrl($order->mall_id, $res['trade_no'], StatusEnum::ENABLED); 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->addons->get($order->mall_id, StoreEnum::ADDONS_NAME, 'payment.pay_after_link');// 支付成功后跳转的地址 if (!empty($arr['pay_success_page'])) { $arr['is_jump'] = StatusEnum::ENABLED; } } // $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; //剩余秒数 } $arr['main_order_id'] = $main_order_id ?? 0; return $arr; } catch (\Exception $e) { // LockHelper::batchUlock($stock_locks); if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 积分抵扣-扣除下单这的积分 * @param $order * @param $deduct_score_arr * @return void * @throws Exception */ protected static function subUserScore($order,$deduct_score_arr) { foreach ($deduct_score_arr as $item){ $deduct_score = $item['deduct_score']; $desc = '用户('.$order['user_id'].'),下单('.$order['id'].')抵扣积分,数量:'.$deduct_score; $data = [ 'mall_id' => $order['mall_id'], 'user_id' => $order['user_id'], 'is_frozen' => false, 'wallet_type' => 'score', 'money' => -$deduct_score, 'desc' => $desc, 'source_table' => StoreOrderDetail::tableName(), 'source_table_id' => $item['order_detail_id'], 'from_type' => UserWalletEnum::CONSUME, 'capital_type' => 'consume_store_order', 'order_no' => $order['order_no'], ]; $res = UserWalletService::handle(0, $data); if ($res == false) throw new \Exception('抵扣积分失败'); } } /** * 订单关闭-退回积分抵扣 * @param $order * @param $deduct_score * @return void * @throws Exception */ protected static function backUserScoreDeduct($order) { $order_detail_ids = array_column($order['detail'],'id'); $score_log_list = ScoreLog::lists([ 'where'=>[ ['user_id'=>$order['user_id']], ['change_type'=>'sub'], ['source_table'=>StoreOrderDetail::tableName()], ['source_table_id'=>$order_detail_ids], ['from_type' => AddonsEnum::ADDONS_NAME_STORE], ['capital_type'=>'consume_store_order'], ] ]); if(!empty($score_log_list)){ $insert_wallet = []; foreach ($score_log_list as $item){ $deduct_score = $item['change_num']; $desc = '订单关闭,退回,用户('.$order['user_id'].'),下单('.$order['id'].')的抵扣积分,数量:'.$deduct_score; $insert_wallet[] = [ 'mall_id' => $item['mall_id'], 'user_id' => $item['user_id'], 'is_frozen' => false, 'wallet_type' => 'score', 'money' => $deduct_score, 'desc' => $desc, 'source_table' => $item['source_table'], 'source_table_id' => $item['source_table_id'], 'from_type' => UserWalletEnum::CONSUME, 'capital_type' => 'consume_store_order', 'order_no' => $order['order_no'], ]; } if($insert_wallet){ $res = UserWalletService::batchHandleByQueue($insert_wallet); } } } /** * 积分赠送-扣除门店主积分 * @param $mall_id * @param $score_give_data * @return void * @throws Exception */ protected static function subStoreUserScore($order,$score_give_data) { $prize_name = '积分赠送'; $store_ids = array_keys($score_give_data); $store_list = Store::lists(['where'=>[['id'=>$store_ids]],'index'=>'id','select'=>'id,user_id']); foreach ($score_give_data as $store_id=>$item) { $store_user_id = $store_list[$store_id]['user_id'] ?? 0; if (empty($store_user_id)) { continue; } foreach ($item as $order_detail_id => $score) { try { if ($score > 0) { $desc = '门店承担门店订单(' . $order['id'] . ')奖励,奖励类型:' . $prize_name . ',积分:' . $score; $data = [ 'mall_id' => $order['mall_id'], 'user_id' => $store_user_id, 'is_frozen' => false, 'wallet_type' => 'score', 'money' => -$score, 'desc' => $desc, 'source_table' => StoreOrderDetail::tableName(), 'source_table_id' => $order_detail_id, 'from_type' => AddonsEnum::ADDONS_NAME_STORE, 'capital_type' => UserWalletEnum::CONSUME_ORDER_GIVE, 'order_no' => $order['order_no'], ]; $res = UserWalletService::handle(0, $data); if ($res == false) throw new \Exception('积分赠送扣除门店主积分失败'); } } catch (Exception $e) { $update = ['give_score' => 0]; $condition = ['order_detail_id' => $order_detail_id]; StoreOrderMarketing::updateAll($update, $condition); Yii::error('order_detail_id:'.$order_detail_id.$e->getMessage()); } } } } /** * 订单关闭-退回积分赠送给门店主 * @param $order * @return true|void * @throws Exception */ protected static function backStoreUserScore($order) { $store = Store::findOne(['id'=>$order['store_id']]); $store_user_id = $store['user_id']??0; if($store_user_id==0){ return true; } $order_detail_ids = array_column($order['detail'],'id'); $score_log_list = ScoreLog::lists([ 'where'=>[ ['user_id'=>$store_user_id], ['change_type'=>'sub'], ['source_table'=>StoreOrderDetail::tableName()], ['source_table_id'=>$order_detail_ids], ['from_type' => AddonsEnum::ADDONS_NAME_STORE], ['capital_type'=>UserWalletEnum::CONSUME_ORDER_GIVE], ] ]); if(!empty($score_log_list)){ $prize_name = '订单关闭-退回积分赠送'; $insert_wallet = []; foreach ($score_log_list as $item){ $order_detail_id = $item['order_detail_id']; $score = $item['change_num']; $desc = '订单关闭,退回积分赠送扣除门店主的积分,门店订单(' . $order_detail_id . ')奖励,奖励类型:' . $prize_name . ',积分:' . $score; $insert_wallet[] = [ 'mall_id' => $item['mall_id'], 'user_id' => $item['user_id'], 'is_frozen' => false, 'wallet_type' => 'score', 'money' => $score, 'desc' => $desc, 'source_table' => StoreOrderDetail::tableName(), 'source_table_id' => $order_detail_id, 'from_type' => AddonsEnum::ADDONS_NAME_STORE, 'capital_type' => UserWalletEnum::CONSUME_ORDER_GIVE, 'order_no' => $order['order_no'], ]; } $res = UserWalletService::batchHandleByQueue($insert_wallet); } } public function getDeductScoreInsertWallet($mall_id,$user_id,$order_id,$order_detail_ids,$source_table,$from_type,$capital_type){ $list = StoreOrderMarketing::findAll(['order_detail_id'=>$order_detail_ids]); $deduct_score = 0; foreach ($list as $value){ $deduct_score+=$value['deduct_score']; } $desc = '用户('.$user_id.'),下单('.$order_id.')抵扣积分,数量:'.$deduct_score; if($deduct_score>0){ return ['mall_id' => $mall_id, 'user_id' => $user_id, 'is_frozen' => false, 'wallet_type' => 'score', 'money' => -$deduct_score, 'desc' => $desc, 'source_table' => $source_table, 'source_table_id' => $order_id, 'from_type' => $from_type, 'capital_type' => $capital_type, ]; }else{ return []; } } /** * 获取订单标题 * @param StoreOrder $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; } public static function getClerkCode($mall_id) { while (true) { $clerk_code = ClerkEnum::getCode(ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE); $res = Order::findOne(['mall_id' => $mall_id, 'clerk_code' => $clerk_code, 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]); if (empty($res)) break; } if (empty($clerk_code)) throw new \Exception('核销码生成失败'); return $clerk_code; } /** * 订单备注 * @Author bing * @DateTime 2021-09-14 15:43:18 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return object|bool */ public static function remark($params) { try { $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'], 'store_id' => $params['store_id'], 'status' => [StatusEnum::ENABLED]]); 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()); $order = Order::findOne(['order_no'=>$model['order_no']]); $order->remark = $model->remark; $order->seller_remark = $model->seller_remark; if (!$order->save()) throw new \Exception($order->getErrorMessage()); return $model; } catch (\Exception $e) { if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 管理员订单支付 * @Author bing * @DateTime 2021-09-10 10:43:57 * @copyright: Copyright (c) 2020 广东七件事集团 * @param StoreOrder $params 参数 * @param [type] $payment_type 支付方式 * @return boolean|object */ public static function pay($params, $peyment_type) { try { $trans = Yii::$app->db->beginTransaction(); $model = self::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED]]); if (empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理,无法进行支付'); if ($model->pay_status == StatusEnum::ENABLED) throw new Exception('订单已支付,请不要重复支付'); if($model->shipping_type==ShippingTypeEnum::PICKUP){ $model->order_status = OrderStatusEnum::TAKE; }else{ $model->order_status = OrderStatusEnum::PAY; } $model->payment_type = $peyment_type; $model->pay_status = StatusEnum::ENABLED; $model->pay_time = time(); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 预约商品支付后,改成发货状态 // 平台订单 $reserveOrder = StoreOrderReserve::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(); } StoreOrderReserve::syncOrderStatus($model); } $res = $model->save(); if ($res === false) throw new Exception('修改订单失败:' . $model->getErrorMessage()); $main_order_model = Order::findOne(['order_no' => $model['order_no'], 'status' => [StatusEnum::ENABLED]]); if($main_order_model){ $main_order_model->order_status = $model->order_status; $main_order_model->payment_type = $peyment_type; $main_order_model->pay_status = StatusEnum::ENABLED; $main_order_model->pay_time = time(); $main_order_model->out_trade_no = $model->out_trade_no; // 平台订单 if (empty($reserveOrder)) $reserveOrder = StoreOrderReserve::findOne(['order_id' => $model->id]); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE && $reserveOrder->reserve_type == StatusEnum::DISABLED) { // 预约商品支付后,改成发货状态 $main_order_model->shipping_status = StatusEnum::ENABLED; // 全部发货状态改为已发货 $main_order_model->order_status = OrderStatusEnum::SHIPMENTS; $main_order_model->consign_time = time(); } $res = $main_order_model->save(); if ($res === false) throw new Exception('修改订单失败:' . $main_order_model->getErrorMessage()); } // 增加销量 $order_detail = $model->detail; $sale_num_goods = []; foreach ($order_detail as $product) { 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 = StoreGoods::findOne($goods_id); $goods->sales_num += $sale_num; $goods->save(); } $order_no = $model['order_no']; $payment_trade_order = PaymentTradeOrder::findOne(['order_no'=>$order_no,'order_type'=>'order','is_pay'=>1]); $order_credit = StoreOrderCredit::findOne(['order_id'=>$params['id'],'type'=>1]); if(!empty($order_credit)){ $field = ['pay_time'=>time()]; if($payment_trade_order['total_fee']>$order_credit['down_payments']){ //有赊账,但没有立即支付,属于第2次付款 $field['is_repayment'] = 1; $field['down_payments'] = $payment_trade_order['total_fee']; $field['credit_money'] = 0; } StoreOrderCredit::updateAll($field,['order_id'=>$params['id'],'type'=>1]); } $trans->commit(); // 触发订单支付事件,事务提交完成后触发 $number = 0; $addons_arr = [AddonsEnum::ADDONS_NAME_AGENT,AddonsEnum::ADDONS_NAME_DISTRIBUTION,AddonsEnum::ADDONS_NAME_AREA,AddonsEnum::ADDONS_NAME_BOSS,'StoreBoss']; foreach ($addons_arr as $addons){ if(MallAddons::isInstall($model['mall_id'],$addons)){ $number++; } } if($number){ \Yii::$app->services->taskCounter->set('o2o:order_id:' . $model['id'])->incr($number); }else{ $event = new ComputeCommissionEvent($model['mall_id']); $data = []; $data['order_id'] = $model['id']; $data['operator_id'] = $params['operator_id'] ?? 0; $data['operator_name'] = $params['operator_name'] ?? ''; $data['commission_arr'] = []; //此处事件 不调用 //Yii::$app->services->events->dispatch($event, $data, $event->listeners); } $event = new OrderPaidEvent($model['mall_id']); $order['id'] = $model['id']; $order['operator_id'] = $params['operator_id'] ?? 0; $order['operator_name'] = $params['operator_name'] ?? ''; $order['mall_order_id'] = $main_order_model->id ?? 0; Yii::$app->services->events->dispatch($event, $order, $event->listeners); return $model; } catch (Exception $e) { if (isset($trans)) $trans->rollback(); 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 { $store_order = StoreOrder::findOne(['id' => $params['order_id']]); if (empty($store_order)) throw new Exception('订单不存在'); $order_comments = OrderComments::findOne(['store_id' => $store_order['store_id'], 'order_id' => $params['order_id']]); if (!empty($order_comments)) throw new Exception('订单已评价,无需再次评价'); foreach ($params['comment_data'] as $item) { $item['store_id'] = $store_order->store_id; $item['mall_id'] = $store_order->mall_id; $item['user_id'] = $store_order->user_id; $item['order_id'] = $store_order['id']; $res = self::saveComments($item); if ($res === false) throw new Exception(OrderComments::getStaticError()); } $store_order->order_status = OrderStatusEnum::ACCOMPLISH; $store_order->finish_time = time(); $store_order->is_comment = 1; $store_order->save(); $order = Order::findOne(['order_no' => $store_order['order_no']]); $params['order_id'] = $order['id']; Order::postComments($params); $t->commit(); // 订单完成触发事件 $user = User::getOne([['id'=>$order->user_id]],true,[],false,'nickname'); $event = new OrderFinishEvent($order->mall_id); $data['id'] = $order->id; $data['order_no'] = $store_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; } } // protected static function saveComments($params) { try { if (!empty($params['id'])) { $model = OrderComments::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]); if (empty($model)) throw new Exception('服务不存在或已删除'); } else { $model = new OrderComments(); $model->loadDefaultValues(); } if (isset($params['pic_url'])) $params['pic_url'] = json_encode($params['pic_url']); //后台虚拟 if (isset($params['pic_list'])) $params['pic_url'] = $params['pic_list']; //前端真实用户 if (!empty($params['virtual_time'])) $params['virtual_time'] = strtotime($params['virtual_time']); if (!$model->load($params, '') || !$model->save()) throw new Exception($model->getErrorMessage()); $res = StoreOrderDetail::setData(['id' => $params['order_detail_id'], 'mall_id' => $params['mall_id'], 'is_evaluate' => 1]); if (!$res) throw new Exception(OrderDetail::getStaticError()); return $model; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 拼装搜索参数 * @param {*} $mall_id * @param {*} $search * @return {*} */ public static function searchParams($mall_id, $search) { // 查询参数 $isReserve = $search['is_reserve']; $where[] = ['=', 'mall_id', $mall_id]; $where[] = ['>=', 'status', StatusEnum::DISABLED]; if ($isReserve) { $where[] = ['=', 'order_source', OrderSourceEnum::SOURCE_RESERVE]; } else { $where[] = ['not in', 'order_source', [OrderSourceEnum::SOURCE_SELF_MALL, OrderSourceEnum::SOURCE_RESERVE]]; } 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']]; 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']]; } } ($search['order_no'] ?? false) && $where[] = ['=', 'order_no', $search['order_no']]; ($search['start'] ?? false) && $where[] = ['>=', 'created_at', strtotime($search['start'])]; ($search['end'] ?? false) && $where[] = ['<=', 'created_at', strtotime($search['end'])]; 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]; break; case 'user_id': $where[] = ['in', 'user_id', $search['type_value']]; 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; } /** * @name: * @msg: 订单修改价格 * @param {array} $params * @return {*} */ 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()); $trans->commit(); return $model; } catch (Exception $e) { if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 关闭订单 * @param {*} $params * @param {*} $force * @return {*} */ 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']; isset($params['store_id']) && $cond['store_id'] = $params['store_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除1'); // 判断订单是否已经被关闭 if ($model->order_status == OrderStatusEnum::REPEAL) throw new Exception('订单已经关闭'); // 判断是否是未支付的订单 if ($force == false && $model->order_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理'); $order = Order::findOne(['order_no'=>$model['order_no']]); $model->close_time = time(); $model->order_status = OrderStatusEnum::REPEAL; if (!$model->save()) throw new Exception($model->getErrorMessage()); if(!empty($order)){ $order->close_time = $model->close_time; $order->order_status = $model->order_status; if (!$order->save()) throw new Exception($order->getErrorMessage()); } $goods_attr_arr = array_column($model->detail, 'num', 'goods_attr_id'); //操作规格库存-回退 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; //操作商品库存-回退 StoreGoodsAttr::handleStock($goods_attr_id, $num); } $trans->commit(); $store_order_detail_id_arr = array_column($model->detail,'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()); self::backStoreUserScore($store_order); self::backUserScoreDeduct($store_order); $res = StoreOrderReserve::updateAll(['order_status' => -4], ['main_order_id' => $order['id']]); var_dump($res); // 触发订单取消事件 // 解锁 LockHelper::batchUlock($stock_locks); return $model; } catch (Exception $e) { $trans->rollback(); // 解锁 LockHelper::batchUlock($stock_locks); self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 删除订单 * @param {*} $params * @return {*} */ public static function del($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::REPEAL) throw new Exception('只允许删除已关闭订单'); $model->status = StatusEnum::DELETE; if (!$model->save()) throw new Exception($model->getErrorMessage()); $order = Order::findOne(['order_no'=>$model['order_no']]); if(!empty($order)){ $order->status = $model->status; if (!$order->save()) throw new Exception($order->getErrorMessage()); } return $model; } catch (Exception $e) { if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 修改订单收货地址 * @param {*} $params * @return {*} */ public static function changeAddress($params) { try { $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED]]); if (empty($model)) throw new Exception('订单不存在或已删除'); if (!$model->load($params, '') || !$model->save()) throw new \Exception($model->getErrorMessage()); $order = Order::findOne(['order_no'=>$model['order_no']]); $params['id'] = $order['id']; Order::changeAddress($params); 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 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->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; } } /** * @name: * @msg: 更新订单状态 * @param {*} $order * @return {*} */ public static function autoUpdateStatus($order) { $order_details = StoreOrderDetail::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++; // 未发货的正常产品 if ($shipping_status == StatusEnum::DISABLED && in_array($is_feedback, OrderStatusEnum::getFeedbackMap())) { $no_shipping_count++; } /****判断订单是否售后完成 --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['main_order_detail_id'], 'type' => RefundTypeEnum::EXCHANGE_GOODS, 'store_id' => $order_detail['store_id'] ]) ->exists(); if ($refund_exists) { $exchange_count++; } else { // 订单完成后订单状态为已关闭(仅为退款、退货退款) $order_detail_close_ids[] = $order_detail['id']; } } /****判断订单是否售后完成--end--****/ } 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; $res = $order->save(); } // 全部售后完成 if ($normal_count === $feedback_completion) { $order->is_feedback = OrderStatusEnum::FEEDBACKED; $order->save(); } // 全部已发货 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]); } } /** * @name: * @msg: 收货 * @param {*} $params * @return {*} */ 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['store_id']) && $cond['store_id'] = $params['store_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status == OrderStatusEnum::SING) throw new Exception('订单已经签收'); if ($model->order_status != OrderStatusEnum::SHIPMENTS) throw new Exception('订单已经被处理'); $order = Order::findOne(['order_no'=>$model['order_no']]); if (OrderDetail::getAfterSaleCountByOrderId($order['id']) > 0) throw new Exception('请先处理或关闭订单售后'); if (StoreOrderDetail::getAfterSaleCountByOrderId($params['id']) > 0) throw new Exception('请先处理或关闭订单售后'); $model->order_status = OrderStatusEnum::SING; $model->sign_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); $order->order_status = OrderStatusEnum::SING; $order->sign_time = time(); if (!$order->save()) throw new Exception($order->getErrorMessage()); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 同步订单状态 StoreOrderReserve::syncOrderStatus($model, $params['tech_id'] ?? null); } // 触发订单收货事件,事务提交完成后触发 $event = new OrderTakeDeliveryEvent($params['mall_id']); $data['id'] = $order['id']; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); return $model; } catch (Exception $e) { 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']; isset($params['store_id']) && $cond['store_id'] = $params['store_id']; $model = self::findOne($cond); if (empty($model)) throw new Exception('订单不存在或已删除'); if ($model->order_status == OrderStatusEnum::ACCOMPLISH) throw new Exception('订单已经完成,无需重复处理'); if (!in_array($model->order_status,[OrderStatusEnum::SING,OrderStatusEnum::TAKE_FINISH])) throw new Exception('订单已经被处理'); $order = Order::findOne(['order_no'=>$model['order_no']]); if (OrderDetail::getAfterSaleCountByOrderId($order['id']) > 0) throw new Exception('请先处理或关闭订单售后'); if (StoreOrderDetail::getAfterSaleCountByOrderId($params['id']) > 0) throw new Exception('请先处理或关闭订单售后'); $model->order_status = OrderStatusEnum::ACCOMPLISH; $model->finish_time = time(); if (!$model->save()) throw new Exception($model->getErrorMessage()); $order->order_status = OrderStatusEnum::ACCOMPLISH; $order->finish_time = time(); if (!$order->save()) throw new Exception($order->getErrorMessage()); if ($model->order_source === OrderSourceEnum::SOURCE_RESERVE) { // 同步订单状态 StoreOrderReserve::syncOrderStatus($model); } // 触发订单过售后事件,事务提交完成后触发 $event = new OrderFinishEvent($params['mall_id']); $order_data['id'] = $order['id']; $order_data['order_no'] = $model['order_no']; $order_data['operator_id'] = $params['operator_id'] ?? 0; $order_data['operator_name'] = $params['operator_name'] ?? '系统'; Yii::$app->services->events->dispatch($event, $order_data, $event->listeners); return $model; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } /** * 发货 * @Author bing * @DateTime 2021-09-16 19:55:46 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $order_id * @param [type] $params * @param [type] $trigger_event * @return bool */ public static function OrderExpressDelivery($params,$trigger_event = true){ try{ $store_order = StoreOrder::getOne([['mall_id' => $params['mall_id'], 'id' => $params['id'],'status'=>[StatusEnum::ENABLED]]]); $order = Order::getOne([['mall_id' => $params['mall_id'], 'order_no' => $store_order['order_no'],'status'=>[StatusEnum::ENABLED]]]); if(empty($order)) throw new Exception('订单不存在或已删除'); $model = new OrderExpress(); $params['order_id'] = $order['id']; $params['buyer_id'] = $order['user_id']; $params['buyer_name'] = $order['receiver_name']; $params['operator_username'] = $params['operator_name']; $trans = Yii::$app->db->beginTransaction(); if(!$model->load($params,'') || !$model->save()) throw new \Exception($model->getErrorMessage()); //保存物流轨迹记录 $params['order_express_id'] = $model->id; $res = OrderExpressLog::saveLog($params); if ($res == false) throw new Exception(OrderExpressLog::getStaticError()); $condition['where'] = [['in', 'id', $params['order_detail_ids']],['is_feedback'=>[OrderStatusEnum::FEEDBACKING,OrderStatusEnum::FEEDBACKED]]]; $res = StoreOrderDetail::lists($condition); if(!empty($res)) throw new \Exception('订单申请售后中,请先处理售后问题'); // 订单商品的物流状态改变 StoreOrderDetail::updateAll(['shipping_status' => StatusEnum::ENABLED], ['in', 'id', $params['order_detail_ids']]); $store_order_detail_list = StoreOrderDetail::lists(['where'=>[['id'=>$params['order_detail_ids']]],'select'=>'main_order_detail_id']); $main_order_detail_id = array_column($store_order_detail_list,'main_order_detail_id'); $res = OrderDetail::updateAll(['shipping_status' => StatusEnum::ENABLED], ['in', 'id',$main_order_detail_id]); // 自动维护订单状态 $res = Order::autoUpdateStatus($order); $res = StoreOrder::autoUpdateStatus($store_order); if($res === false) throw new \Exception(Order::getStaticError()); $trans->commit(); if ($trigger_event) { // 发货成功触发事件,事务提交完成后触发 $event = new \common\events\order\OrderDeliveryEvent($params['mall_id']); $data['id'] = $model->id; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; Yii::$app->services->events->dispatch($event,$data, $event->listeners); } return true; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage().$e->getFile().$e->getLine(); return false; } } /** * 修改物流 * @Author lun * @DateTime 2021-09-24 19:55:46 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $params * @return void */ public static function OrderExpressShippingChange($params){ try{ $order_express = OrderExpress::findOne(['id' => $params['id']]); if (empty($order_express)) throw new Exception('物流不存在或已删除'); $trans = Yii::$app->db->beginTransaction(); if(!$order_express->load($params,'') || !$order_express->save()) throw new \Exception($order_express->getErrorMessage()); OrderExpressLog::saveLog($params,true); $trans->commit(); // 发货成功触发事件,事务提交完成后触发 $event = new \common\events\order\OrderDeliveryEvent($params['mall_id']); $data['id'] = $params['id']; $data['operator_id'] = $params['operator_id']; $data['operator_name'] = $params['operator_name']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); return true; }catch(Exception $e){ if(isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } //api,h5订单详情公共调用 public static function orderDetail($params){ if(empty($params['order'])){ return $params['order']; } if(empty($params['order']['order_no'])) return $params['order']; $data = $params['order']; $order_no = $params['order']['order_no']; $store_order = StoreOrder::findOne(['order_no'=>$order_no]); if(empty($store_order)) return $data; $store = Store::findOne(['id'=>$store_order['store_id']]); $region_ids = [$store['province_id'],$store['city_id'],$store['district_id']]; $region_list = Region::lists(['where'=>[['id'=>$region_ids]],'select'=>'id,name','index'=>'id']); $province = $region_list[$store['province_id']]['name']; $city = $region_list[$store['city_id']]['name']; $district = $region_list[$store['district_id']]['name']; $order = Order::findOne(['order_no'=>$order_no]); $data['user_mobile'] = $store_order['mobile']; $data['latitude'] = $store['latitude']; $data['longitude'] = $store['longitude']; $data['shop_mobile'] = $store['shop_mobile']; $data['store_name'] = $store['store_name']; $data['logo_img'] = $store['logo_img']; $data['clerk_code'] = !empty($order['clerk_code'])?$order['clerk_code']:$order['id']; $data['store_address'] = $province.$city.$district.$store['address']; $marketing = self::getMarketingInfo($store_order); $data['marketing'] = $marketing; $data['pickup'] = StoreOrderPickup::getPickupDataByOrderId($store_order->id) ?? []; $store_goods_attr_ids = $store_goods_ids = []; foreach ($order['detail'] as $v){ if(!empty($v['store_id'])){ $store_goods_attr_ids[]=$v['goods_attr_id']; $store_goods_ids[]=$v['goods_id']; } } $store_goods_attr_list = []; if(!empty($store_goods_attr_ids)){ $store_goods_attr_list = StoreGoodsAttr::lists(['where'=>[['id'=>$store_goods_attr_ids]],'select'=>'id,original_price','index'=>'id']); } if(!empty($store_goods_ids)){ $store_goods_list = StoreGoods::lists(['where'=>[['id'=>$store_goods_ids]],'select'=>'id,unit,goods_source,goods_type','index'=>'id']); } foreach ($data['detail'] as $k => $v){ if(!empty($v['store_id'])){ $data['detail'][$k]['is_show_return_btn'] = 1; $data['detail'][$k]['original_price'] = $store_goods_attr_list[$v['goods_attr_id']]['original_price']??0; $data['detail'][$k]['unit'] = $data['detail'][$k]['order_source'] = $data['detail'][$k]['goods_type'] = ''; if(isset($store_goods_list[$v['goods_id']])){ $goods = $store_goods_list[$v['goods_id']]; $data['detail'][$k]['unit'] = $goods['unit']; $data['detail'][$k]['order_source'] = $goods['goods_source']; $data['detail'][$k]['goods_type'] = $goods['goods_type']; } } } return $data; } public static function getMarketingInfo($order) { $member_price = $coupon_discount_money = $full_reduce_money = $score = $score_deduct_money = $agent_deduct = 0; if (!empty($order['detail'])) { $currency = []; $order_detail_ids = array_column($order['detail'], 'id'); $order_marketing_list = StoreOrderMarketing::lists(['where' => [['order_detail_id' => $order_detail_ids]]]); foreach ($order_marketing_list as $value) { $member_price += $value['member_price_deduct']; $coupon_discount_money += $value['coupon_discount_money']; $full_reduce_money += $value['full_reduce_money']; $deduct_currency = json_decode($value['deduct_currency'],'true'); if(!empty($deduct_currency['score'])){ $score_deduct_money += $deduct_currency['score']['money']; } $agent_deduct += $value['agent_deduct']; } } $member_price = bcmul($member_price,1,2); $coupon_discount_money = bcmul($coupon_discount_money,1,2); $agent_deduct = bcmul($agent_deduct,1,2); $marketing['deduct'] = [ 'member_price' => ['name' => '会员优惠', 'money' => -$member_price], 'coupon' => ['name' => '优惠券', 'money' => -$coupon_discount_money], 'score' => ['name' => '积分抵扣', 'money' => -$score_deduct_money], ]; !empty($currency) && $marketing['deduct'] = array_merge($marketing['deduct'], $currency); if (MallAddons::isInstall($order['mall_id'], AddonsEnum::ADDONS_NAME_AGENT)){ $marketing['deduct']['agent_deduct'] = ['name' => '经销商内购商品抵扣', 'money' => -$agent_deduct]; } return $marketing; } public static function updateCode() { $i = 1; $page_size = 1000; while ($list = StoreOrder::find() ->andWhere(['=', 'shipping_type', 2]) ->offset(($i - 1) * $page_size)->limit($page_size)->all()) { foreach ($list as $item) { $id = $item['id']; $order_no = $item['order_no']; $code = StoreOrder::getClerkCode($item['mall_id']); $sql = "update qimall_addons_store_order set clerk_code = {$code} where id = {$id}"; $res = \Yii::$app->db->createCommand($sql)->execute(); var_dump($res); $sql = "update qimall_order set clerk_code = {$code} where order_no = '{$order_no}'"; \Yii::$app->db->createCommand($sql)->execute(); var_dump($res); } $i++; } } /** * 获取门店自提订单核销信息 * @Author:hua * @Date:2024-03-07 14:27 * @Copyright:copyright(c)2024 广东七件事集团 * @param $params * @return array|mixed|void */ public static function getStoreSelfPickupOrderClerkData($params){ try { $select = 'id,mall_id,store_id,order_no,receiver_name,mobile,pay_money,shipping_money,original_goods_price,coupon_money,goods_price,order_status,pay_status, shipping_status,review_status,is_feedback,address,created_at,pay_time,region_name,remark,consign_time,finish_time,sign_time,shipping_type,payment_type,score,score_money,marketing_id,marketing_type,extra_info,order_source'; $where = []; $clerk_code = $params['clerk_code']; $mall_id = $params['mall_id']; $platform = $params['platform']; $user_id = $params['user_id']; $where[] = ['clerk_code' => $clerk_code]; $where[] = ['mall_id' => $mall_id]; $where[] = ['status' => StatusEnum::ENABLED]; $order = Order::getOne($where, true, ['detail' => function ($query) { $query->select('id,order_id,goods_id,goods_name,pic_url,num,price,is_feedback,sign_id,goods_attr_name,order_status,adjust_money,extra_info'); }], false, $select); if (empty($order))throw new Exception('该订单不存在'); $store_id = $order['store_id']; $store = Store::getOne([['id' => $store_id]], true, [], false, 'id,user_id,balance'); $store_user_id = $store['user_id']; $where = [ ['mall_id' => $mall_id], ['store_id' => $store_id], ['status' => StatusEnum::ENABLED] ]; if($user_id != $store_user_id){ $where[] = ['user_id'=>$user_id]; } $rse = StoreClerk::getOne($where); if (empty($rse)) throw new Exception('你不是核销员'); $marketing = OrderMarketing::getMarketingInfo($order); $order['order_status_text'] = OrderStatusEnum::getMap(); $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap(); $order['shipping_type_text'] = ShippingTypeEnum::getMap(); $order['payment_type_text'] = PayTypeEnum::getMap(); $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($mall_id, $platform); $adjust_money = array_sum(array_column($order['detail'], 'adjust_money'));//预留字段 if ($adjust_money) { $order['change_price'] = $adjust_money; } $order['marketing'] = $marketing; $order['marketing_type_map'] = MarketingTypeEnum::getMap(); $order_setting = Yii::$app->services->setting->mall->get($mall_id, 'order'); $order['payment_expire_time'] = $order_setting['payment_expire_time'] ?? 30; $order['auto_receiving_time'] = $order_setting['auto_receiving_time'] ?? 14; // 获取订单详情的状态文字描述 $order['status_text'] = OrderStatusEnum::getApiStatus($order['status'], $order['shipping_type']); $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc']; $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc']; // 公共调用 $order = GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $mall_id, [ 'order' => $order, 'mall_id' => $mall_id, ]) ?: $order; $order['clerk_code_pre'] = ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE; return $order; }catch (Exception $e){ throw new Exception($e->getMessage()); } } public static function getClerkLogDetail($params){ try { $clerk_log_model = \common\models\common\ClerkLog::findOne(['id'=>$params['clerk_log_id'],'mall_id'=>$params['mall_id'],'user_id'=>$params['user_id'],'type'=>$params['type']]); $extra = json_decode($clerk_log_model['extra'],true); $order_id = $extra['order_id']; $select = 'id,mall_id,store_id,order_no,receiver_name,mobile,pay_money,shipping_money,original_goods_price,coupon_money,goods_price,order_status,pay_status, shipping_status,review_status,is_feedback,address,created_at,pay_time,region_name,remark,consign_time,finish_time,sign_time,shipping_type,payment_type,score,score_money,marketing_id,marketing_type,extra_info,order_source'; $where = []; $mall_id = $params['mall_id']; $platform = $params['platform']; $user_id = $params['user_id']; $where[] = ['id' => $order_id]; $where[] = ['mall_id' => $mall_id]; $where[] = ['status' => StatusEnum::ENABLED]; $order = Order::getOne($where, true, ['detail' => function ($query) { $query->select('id,order_id,goods_id,goods_name,pic_url,num,price,is_feedback,sign_id,goods_attr_name,order_status,adjust_money,extra_info'); }], false, $select); if (empty($order)) { throw new Exception('该订单不存在'); } $store_id = $order['store_id']; $store = Store::getOne([['id' => $store_id]], true, [], false, 'id,user_id,balance'); $store_user_id = $store['user_id']; $where = [ ['mall_id' => $mall_id], ['store_id' => $store_id], ['status' => StatusEnum::ENABLED] ]; if($user_id != $store_user_id){ $where[] = ['user_id'=>$user_id]; } $marketing = OrderMarketing::getMarketingInfo($order); $order['order_status_text'] = OrderStatusEnum::getMap(); $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap(); $order['shipping_type_text'] = ShippingTypeEnum::getMap(); $order['payment_type_text'] = PayTypeEnum::getMap(); $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($mall_id, $platform); $adjust_money = array_sum(array_column($order['detail'], 'adjust_money'));//预留字段 if ($adjust_money) { $order['change_price'] = $adjust_money; } $order['marketing'] = $marketing; $order['marketing_type_map'] = MarketingTypeEnum::getMap(); $order_setting = Yii::$app->services->setting->mall->get($mall_id, 'order'); $order['payment_expire_time'] = $order_setting['payment_expire_time'] ?? 30; $order['auto_receiving_time'] = $order_setting['auto_receiving_time'] ?? 14; // 获取订单详情的状态文字描述 $order['status_text'] = OrderStatusEnum::getApiStatus($order['status'], $order['shipping_type']); $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc']; $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc']; // 公共调用 $order = GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $mall_id, [ 'order' => $order, 'mall_id' => $mall_id, ]) ?: $order; $order['clerk_code_pre'] = ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE; return $order; }catch (Exception $e){ throw new Exception($e->getMessage()); } } /** * 核销门店自提订单 * @Author:hua * @Date:2024-03-07 14:28 * @Copyright:copyright(c)2024 广东七件事集团 * @param $params * @return StoreClerkLog */ public static function storeSelfPickupOrderClerk($params){ $t = Yii::$app->db->beginTransaction(); try { $clerk_code = $params['clerk_code']; $mall_id = $params['mall_id']; $user_id = $params['user_id']; $order = Order::findOne(['mall_id'=>$mall_id,'clerk_code'=> $clerk_code,'status'=>StatusEnum::ENABLED]); if (empty($order)) throw new \Exception('自提订单不存在'); $store = Store::getOne([['id' => $order->store_id]], true, [], false, 'id,user_id,balance,logo_img,store_name'); $store_user_id = $store['user_id']; $store_id = $order['store_id']; $where = [ ['mall_id' => $mall_id], ['store_id' => $store_id], ['status' => StatusEnum::ENABLED] ]; if($user_id != $store_user_id){ $where[] = ['user_id'=>$user_id]; } $store_clerk = StoreClerk::getOne($where); if (empty($store_clerk)) throw new Exception('你不是核销员'); $params['clerk_id'] = $store_clerk['id']; $order->order_status = OrderStatusEnum::TAKE_FINISH; $order->sign_time = time(); $res = $order->save(); if($res==false) throw new \Exception($order->getErrorMessage()); $store_order = StoreOrder::getOne([['order_no' => $order['order_no']], ['mall_id' => $params['mall_id']], ['store_id' => $order['store_id']]]); if (empty($store_order)) throw new \Exception('门店自提订单不存在'); if ($store_order->order_status != OrderStatusEnum::TAKE) throw new \Exception('该订单不是待自提'); if ($store_order->order_status == OrderStatusEnum::TAKE_FINISH) throw new \Exception('已自提'); if ($store_order->shipping_type != ShippingTypeEnum::PICKUP) throw new \Exception('该订单不是自提订单'); $insert_data = $params; $insert_data['store_id'] = $store_clerk['store_id']; $insert_data['clerk_id'] = $store_clerk['id']; $insert_data['order_no'] = $store_order['order_no']; $insert_data['user_id'] = $store_order['user_id']; $insert_data['mobile'] = $store_order['mobile']; $model = new StoreClerkLog(); $model->loadDefaultValues(); if (!$model->load($insert_data, '')) throw new \Exception($model->getErrorMessage()); if (!$model->save()) throw new \Exception($model->getErrorMessage()); $store_order->order_status = OrderStatusEnum::TAKE_FINISH; $store_order->sign_time = time(); $store_order->save(); $order_detail = OrderDetail::findOne(['order_id'=>$order['id']]); if(MallAddons::isInstall($mall_id,'Clerk')){ $add_data = [ 'mall_id'=>$mall_id, 'name'=>$order_detail['goods_name'], 'clerk_code'=>$clerk_code, 'type'=>ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE, 'extra'=>json_encode(['order_no'=>$order['order_no']]) ]; ClerkLog::setData($add_data); } $store_goods = StoreGoods::findOne(['id'=>$order_detail['goods_id']]); $nums = OrderDetail::find()->where(['order_id'=>$order['id']])->sum('num'); $add_clerk_log_data = [ 'mall_id' => $params['mall_id'], 'user_id' => $user_id, 'mall_logo' => $store['logo_img'], 'mall_name' => $store['store_name'], 'name' => $order_detail['goods_name'], 'pic' => $order_detail['pic_url'], 'clerk_code' => (string)$params['clerk_code'], 'type' => ClerkEnum::O2O_SELF_PICKUP_ORDERS_CLERK_CODE_PRE, 'extra' => json_encode([ 'pay_money' => $store_order['pay_money'], 'order_money' => $store_order['pay_money'], 'clerk_nums' => $nums??0, 'subtitle' => $store_goods['subtitle']??'', 'order_id' => $order['id'] ?? 0, ]), ]; $clerk_log_model = \common\models\common\ClerkLog::setData($add_clerk_log_data); if ($clerk_log_model == false) { throw new \Exception(\common\models\common\ClerkLog::getStaticError()); } // 维护累计核销金额及累计核销订单数 StoreClerk::incrNumsAndTotalMoney($store_clerk['id'], $nums, $store_order['pay_money']); $t->commit(); // 微信小程序发货 $event = new StoreSelfPickupOrderClerkEvent($mall_id); $data['id'] = $order['id']; Yii::$app->services->events->dispatch($event, $data, $event->listeners); return $model; } catch (\Exception $e) { $t->rollBack(); throw new Exception($e->getMessage()); } } /** * 通过订单ID获取订单 * * @param integer $mall_id * @param integer $id * @param string $fields * @return static|null */ public static function getOrderByOrderId(int $mall_id, int $id, string $fields = 'id, shipping_type, store_id') { return static::find() ->select($fields) ->where(['mall_id' => $mall_id, 'id' => $id]) ->one(); } /** * 是否自提订单 * * @return boolean */ public function isPuckup() { return $this->shipping_type == ShippingTypeEnum::PICKUP; } public static function exportHandle(array $data) { date_default_timezone_set('Asia/Shanghai'); $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); if ($download) { try { $params = json_decode($download->params, true); $filename = $download->name; $type = $download->type; $order_detail_model = StoreOrderDetail::find()->alias('od'); $order_detail_model->where(['od.mall_id' => $params['mall_id']]); if (isset($params['is_reserve']) && $params['is_reserve'] == 1) { $order = StoreOrder::find()->where(['order_source' => OrderSourceEnum::SOURCE_RESERVE, 'mall_id' => $params['mall_id'], 'store_id' => $params['store_id']])->asArray()->all(); $order_detail_model->andWhere(['in', 'od.order_id', array_column($order, 'id')]); $order_detail_model->andWhere(['in', 'od.store_id', [0, $params['store_id']]]); } else { if (isset($params['store_id']) && !empty($params['store_id'])) { $order_detail_model->andWhere(['od.store_id' => $params['store_id']]); } else { $order_detail_model->andWhere(['>', 'od.store_id', 0]); } } $is_show_mch_name = 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['order_no'])) { $order = self::findOne(['order_no' => $params['order_no']]); $order_detail_model->andWhere(['=', 'od.order_id', $order->id]); } if (!empty($params['mobile'])) { $user = User::find()->where(['like', 'mobile', $params['mobile'] . '%', false])->all(); $where[] = ['in', 'user_id', array_column($user, 'id')]; $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') { $storeWhere = ['like', 'receiver_name', $params['type_value'] . '%', false]; } else { $storeWhere = ['like', 'mobile', $params['type_value'] . '%', false]; } $orderIds = StoreOrder::find() ->where(['status' => StatusEnum::ENABLED, 'mall_id' => $params['mall_id']]) ->andWhere($storeWhere)->select('id') ->column(); if (!empty($orderIds)) { $order_detail_model->andWhere(['in', 'od.order_id', array_unique($orderIds)]); } break; default: } } if (!empty($params['type'] == 'user_id') && !empty($params['type_value'])) { $order_detail_model->andWhere(['=', 'od.user_id', $params['type_value']]); } $is_left_join = false; if (!empty($params['payment_type'])) { $order_detail_model->leftJoin(self::tableName().'as o','o.id=od.order_id')->andWhere( ['=','o.payment_type',$params['payment_type']] ); $is_left_join = true; } 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['province'])) { if(!$is_left_join){ $order_detail_model->leftJoin(self::tableName().'as o','o.id=od.order_id'); } $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()]); } $order_detail_model->with(['order', 'user' => function ($query) { $query->select('id,nickname,username,mobile'); }]); $fields = $params['fields']; $fields_arr = self::fieldsList(); $fields_arr['create_type'] = '创建方式'; $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[] = '商户名称'; } } $csv = new CsvTool(); $csv->filename = $filename; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->header = $have_select_field_arr; $order_status_list = OrderStatusEnum::getMap(); $shipping_status_list = ShippingStatusEnum::getMap(); if ($params['is_reserve'] == 1) { $order_status_list = OrderStatusEnum::getReserveMap(); $shipping_status_list = [ 0 => '待预约', 1 => '上门服务', 2 => '到店服务', ]; } $payment_type_list = PayTypeEnum::getMap(); $order_ids_arr = []; foreach ($order_detail_model->batch() 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']); } $csv->data = 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', '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 (isset($order_detail['order'][$field]) && $order_detail['order'][$field] >= 0) { $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 == 'out_trade_no'): $row[] = PaymentTradeOrder::getOutTradeNoOfOrderNo($order_detail['order']['order_no'] ?? '') ?: ''; 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 == '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; default: $row[] = !empty($order_detail[$field]) ? $order_detail[$field] : ''; } } return $row; }, $order_details); $csv->export(); } $csv->updateDown($download, $params['mall_id']); return true; } catch (\Exception $e) { $download->status = 3; $res = $download->save(); var_dump($e->getMessage() . $e->getFile() . $e->getLine()); self::setStaticError($e->getMessage()); return $e->getMessage(); } } } public static function getOneData($params, $orderBy = 'id desc') { return static::find()->where($params)->orderBy($orderBy)->asArray()->one(); } /** * 修复门店预约商品的核销码 * @return void */ public static function fixReserveClerkCode(){ $offset = 1; $limit = 1000; while ($list = StoreOrder::lists([ 'where'=>[ ['order_source'=>'Reserve'] ], 'limit'=>$limit, 'offset'=>($offset - 1) * $limit],false)) { foreach ($list as $item){ if(!empty($item['clerk_code'])){ $clerk_code = $item['clerk_code']; $clerk_code_pre = $clerk_code[0] . $clerk_code[1]; if($clerk_code_pre!=ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE){ $clerk_code = OrderReserve::getClerkCode($item['mall_id'],ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE); $item->clerk_code = $clerk_code; $item->save(); Order::updateAll(['clerk_code'=>$clerk_code],['order_no'=>$item['order_no']]); $order = Order::findOne(['order_no'=>$item['order_no']]); OrderReserve::updateAll(['reserve_code'=>$clerk_code],['order_id'=>$order['id']]); StoreOrderReserve::updateAll(['reserve_code'=>$clerk_code],['order_id'=>$item['id'],'main_order_id'=>$order['id']]); } } } $offset++; } } }