'未处理', self::ORDER_STATUS_CREATED => '待确认', self::ORDER_STATUS_CONFIRM => '已确认', self::ORDER_STATUS_DELIVERY => '待抢单', self::ORDER_STATUS_PICKUP => '待取货', self::ORDER_STATUS_DELIVERING => '配送中', self::ORDER_STATUS_DONE => '已完成', self::ORDER_STATUS_CANCEL => '已取消', self::ORDER_STATUS_DELETE => '已删除', self::ORDER_STATUS_EXPECT => '配送异常', ]; const DELIVERY_STATUS_PENDING = 'PENDING'; const DELIVERY_STATUS_GRABBED = 'GRABBED'; const DELIVERY_STATUS_PICKUP = 'PICKUP'; const DELIVERY_STATUS_DELIVERING = 'DELIVERING'; const DELIVERY_STATUS_DONE = 'DONE'; const DELIVERY_STATUS_CANCEL = 'CANCEL'; const DELIVERY_STATUS_BACK = 'BACK'; const DELIVERY_STATUS_TRANSFER = 'TRANSFER'; const DELIVERY_STATUS_CREATE_FAILED = 'CREATE_FAILED'; public static $delivery_status_list = [ self::DELIVERY_STATUS_PENDING => '未分配骑手', self::DELIVERY_STATUS_GRABBED => '已分配骑手', self::DELIVERY_STATUS_PICKUP => '已到店', self::DELIVERY_STATUS_DELIVERING => '配送中', self::DELIVERY_STATUS_DONE => '已完单', self::DELIVERY_STATUS_CANCEL => '配送取消', self::DELIVERY_STATUS_BACK => '配送退回', self::DELIVERY_STATUS_TRANSFER => '配送转单', self::DELIVERY_STATUS_CREATE_FAILED => '订单创建失败', ]; public static $category = [ 'xiaochi'=>'小吃美食', 'canyin'=>'正餐快餐', 'shaokao'=>'龙虾烧烤', 'dangao'=>'烘焙蛋糕', 'tianpin'=>'甜品奶茶', 'liaoli'=>'西餐料理', 'huoguo'=>'火锅串串', 'xianhua'=>'浪漫鲜花', 'shuiguo'=>'生鲜果蔬', 'yinpin'=>'酒水零售', 'chaoshi'=>'超市百货', 'chengren'=>'医药成人', ]; public static $logistic_tag_list = [ 'MEITUAN'=>'美团骑手', 'SHUNFENG'=>'顺丰', 'DADA'=>'达达', 'FENGNIAO'=>'蜂鸟跑腿', 'ELEZB'=>'饿了么众包', 'EBAIZB'=>'饿百众包', 'BINGEX'=>'闪送', 'UUPT'=>'UU跑腿', 'BANGLA'=>'帮拉', 'LINQU'=>'邻趣', 'CAOSONG'=>'曹操送', 'ZHIDONG'=>'指动跑腿', 'CAOCAO'=>'曹操跑腿', 'PAOPAO'=>'喊跑跑', 'DAXIA'=>'大侠跑腿', 'DIANWO'=>'点我达', 'IPAOTUI'=>'爱跑腿', 'XIAOBANG'=>'小帮', 'RIDER'=>'蚂蚁派', 'PINBIDA'=>'拼必达', 'JIUJIU'=>'久久跑腿', 'SAICAOCAO'=>'赛曹操', 'ZHITONG'=>'直通车', 'XIAOGE'=>'小哥快运', 'YUNDA'=>'云递配', 'HUICONG'=>'零点壹', 'SHILU'=>'时路网', 'SONGSHUWU'=>'聚合配送', 'ZBS'=>'宅帮手', 'KAOPU'=>'靠谱送', 'KUAIMA'=>'0851跑腿', 'XIANGZI'=>'祥子', 'KUAIDAO'=>'快到', 'EPAI'=>'E派速达', 'FEIKE'=>'一城飞客', 'NADUDA'=>'哪都达', 'FUWUJIA'=>'服务之家', 'BIANLI'=>'便利专送', 'HONGSU'=>'鸿速同城急送', 'GUOXIAODI'=>'裹小递', 'FUWU'=>'快服务', 'KELOOP'=>'快跑者', 'HAOJI'=>'好急跑腿', 'JDPS'=>'京东配送', 'PENGJIU'=>'鹏九跑腿', 'HUOLALA'=>'货拉拉', 'DAIBANG'=>'代帮跑腿', 'LAILA'=>'来啦跑腿', 'LANZHU'=>'懒猪跑腿', 'KUAIPAO'=>'快跑者急送', 'FEITU'=>'飞兔跑腿', 'SONGDAO'=>'送道', 'ANKEFO'=>'安克弗跑腿', 'SONGDONGXI'=>'送个东西跑腿', 'ANXUN'=>'安讯即配', 'PICKER'=>'自提', 'OTHER'=>'其他', 'ONESELF'=>'自配送', ]; public static function urlPush($store_id = 0){ $url = 'https://open-api.maiyatian.com/v1/channel/'; if(self::isTest($store_id)){ $url = 'https://open-api-test.maiyatian.com/v1/channel/'; } return $url; } public static function urlPushAuth($store_id = 0){ $url = 'https://saas.maiyatian.com/oauth/'; if(self::isTest($store_id)){ $url = 'http://saas.open.test.maiyatian.com/oauth/index/'; } return $url; } public static function setTest($store_id = 0){ self::$test[$store_id] = 1; } public static function isTest($store_id = 0){ $confTest = self::getConf($store_id, 'test'); if($confTest){ return true; } return self::$test[$store_id] ? true : false; } public static function type(){ return [ 'waimai'=>'外卖', 'shop'=>'店铺', 'other'=>'其他', ]; } public static function callbackCommandTest($command, array $data){ self::setTest(); return self::callbackCommand($command, $data); } public static function callbackCommand($command, array $data){ debug_log([__FUNCTION__, __LINE__, $command, $data], __CLASS__ . '.log'); $command = 'cb_' . $command; if($data['data']){ $data = json_decode($data['data'], true); } $res = call_user_func_array([new MaiyatianCallback(), $command], [$data]); if($res['code'] === 0){ $res['code'] = 200; } debug_log([__FUNCTION__, __LINE__, $command, $res], __CLASS__ . '.log'); return $res; } public static function access_token($store_id, $code){ $access_token = self::api($store_id, 'access_token', [ "grant_type" => "shop", //授权类型 默认:shop "code" => $code, //状态码 "shop_id" => (string)$store_id, //平台方渠道ID "category" => self::getConf($store_id, 'category'), //订单分类(麦芽田枚举) "name" => self::getConf($store_id, 'name'), //门店名称 "type" => self::getConf($store_id, 'type'), //店铺类型 ["waimai","shop","other"] "longitude" => self::getConf($store_id, 'longitude'), //经度(国测局02标准,如高德) "latitude" => self::getConf($store_id, 'latitude'), //纬度(国测局02标准,如高德) ]); return $access_token; } public static function refreshToken($store_id = 0) { if(!self::isopen($store_id)){ return; } $refreshToken = self::api($store_id, 'refresh_token', [ "token" => self::getConf($store_id, 'token'), "refresh_token" => self::getConf($store_id, 'refresh_token'), ]); if($refreshToken['code'] != 0){ return $refreshToken; } $data = $refreshToken['data']; self::saveConf($store_id, $data); return $refreshToken; } public static function authUrl($store_id){ $url = self::urlPushAuth($store_id); $saasConf = self::saasConf(); $url .= '?' . http_build_query([ 'app_key' => $saasConf['app_key'], 'response_type' => 'code', 'view' => 'web', 'state' => $store_id, 'shop_id' => (string)$store_id, 'redirect_uri' => $saasConf['url_callback_auth'], ]); return $url; } public static function signatureData(array $data, $command, $appKey, $appSecret, $token) { $signData = [ 'app_key' => $appKey, 'command' => $command, 'data' => json_encode($data), 'timestamp' => time(), 'token' => $token, ]; ksort($signData); $dataToSign = ''; foreach ($signData as $k => $v) { $dataToSign .= $k . '=' . $v . ','; } $dataToSign = substr($dataToSign, 0, -1); $hash = hash_hmac('sha256', $dataToSign, $appSecret, true); $signData['signature'] = strtr(base64_encode($hash), '+/', '-_'); unset($signData['command']); return $signData; } public static function sendRequest($type = 'POST', $baseUrl = '', $url = '', array $options = []):array { $url = $baseUrl . $url; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 10, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => strtoupper($type), CURLOPT_POSTFIELDS => json_encode($options), CURLOPT_HTTPHEADER => [ "content-type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); $res = []; if ($err) { $res = [ 'code' => 1, 'msg' => "cURL Error #:" . $err, ]; } else { $res = json_decode($response, true); } return $res; } public static function api($store_id = 0, $_a = 'shop_info', $params = [], $type = 'post') { $baseUrl = self::urlPush($store_id); $saasConf = self::saasConf(); $token = self::isopen($store_id) ? self::getConf($store_id, 'token') : $store_id; $data = self::signatureData($params, $_a, $saasConf['app_key'], $saasConf['app_secret'], $token); $data['request_id'] = md5(microtime(true)); $response = self::sendRequest($type, $baseUrl, $_a, $data); debug_log([__LINE__, $_a, $response, $store_id, $type, $data], __CLASS__ . '.log'); if(isset($response['code'])){ if($response['code'] != 200){ debug_log(['code!=200', $response, $store_id, $type, $data], __CLASS__ . '.log'); }else{ $response['code'] = 0; $response['data'] = json_decode($response['data'], true); } } return $response; } public static function saasConf($refresh = 0) { if(!empty(self::$saasConf) && !$refresh){ return self::$saasConf; } $conf = Option::get(OptionSetting::MAIYATIAN_SAAS, 0, 'saas')['value']; if($conf){ $conf = json_decode($conf, true); }else{ $conf = [ 'app_key' => '', 'app_secret' => '', 'tag' => '', ]; } $url_callback_test = \Yii::$app->request->hostInfo . '/index.php/maiyatian/test/callback/'; $url_callback = \Yii::$app->request->hostInfo . '/index.php/maiyatian/callback/'; $url_callback_auth = \Yii::$app->request->hostInfo . '/index.php/maiyatian/callback/cyy_auth'; $conf['url_callback'] = $url_callback; $conf['url_callback_test'] = $url_callback_test; $conf['url_callback_auth'] = $url_callback_auth; self::$saasConf = $conf; return $conf; } public static function saasConfSave($config = []) { $set = Option::set(OptionSetting::MAIYATIAN_SAAS, json_encode($config), 0, 'saas'); self::saasConf(1); return $set; } public static function isSaasOpen() { $conf = self::saasConf(); return empty($conf['app_key']) ? 0 : 1; } public static function conf($store_id = 0, $refresh = 0) { if(isset(self::$confs[$store_id]) && !$refresh){ return self::$confs[$store_id]; } $conf = Option::get(OptionSetting::MAIYATIAN, $store_id, 'store')['value']; if($conf){ $conf = json_decode($conf, true); }else{ $conf = [ "shop_id" => "0", //平台方渠道ID "category" => "", //订单分类(麦芽田枚举) "name" => "", //门店名称 "type" => "", //店铺类型 ["waimai","shop","other"] "longitude" => "", //经度(国测局02标准,如高德) "latitude" => "", //纬度(国测局02标准,如高德) //自定义参数 "is_open" => 0, //是否开启 "cyy_delivery_time" => "91", //配送时间(分钟) "cyy_delivery_fee" => "10", //配送费用(元) ]; } $conf['is_open'] = (int)$conf['is_open']; self::$confs[$store_id] = $conf; return $conf; } public static function saveConf($store_id = 0, $config = []) { $oldConf = self::conf($store_id, 1); if($oldConf['token'] != $config['token']){ $config['refresh_time'] = time(); } $conf = array_merge($oldConf, $config); $set = Option::set(OptionSetting::MAIYATIAN, json_encode($conf), $store_id, 'store'); self::conf($store_id, 1); return $set; } public static function getConf($store_id = 0, $key = '') { $config = self::conf($store_id); return $config[$key]; } public static function setConf($store_id = 0, $key = '', $val = '') { $config = self::conf($store_id); $config[$key] = $val; return self::saveConf($store_id, $config); } public static function isopen($store_id = 0) { $is_open = self::getConf($store_id, 'is_open'); if($is_open){ $expires_time = self::getConf($store_id, 'expire_time'); if(!isset($expires_time)){ $is_open = 0; } if($expires_time > 0 && $expires_time < time()){ $is_open = 0; } } return $is_open == 1 ? true : false; } public static function createUrl($store_id = 0) { try{ $isSaasOpen = self::isSaasOpen(); if(!$isSaasOpen){ throw new \Exception('平台未配置此功能'); } $storeName = self::getConf($store_id, 'name'); if(!$storeName){ throw new \Exception('请先提交表单信息'); } $url = self::authUrl($store_id); return [ 'code' => 0, 'data' => $url, ]; } catch (\Exception $ex) { \Yii::error([__METHOD__, __LINE__, $ex->getMessage()]); return [ 'code' => 1, 'msg' => $ex->getMessage(), ]; } } public static function getUserByStoreSaasuser($store_id = 0, $saas_user = []) { $user = User::find()->where([ 'store_id' => $store_id, 'binding' => $saas_user['mobile'], 'is_delete' => 0, ])->one(); return $user; } public static function afterOrderSave($insert, $changedAttributes, $order){ try{ $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $order->store_id, 'store')['value']; $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $order->store_id, 'pay', $local_type)['value']; \Yii::error($local_type); if($local_type != 'maiyatian'){ return; } //取消订单 if (($order->is_delivery == 1) && ($order->trade_status == Order::ORDER_FLOW_CANCEL) && ($changedAttributes['trade_status'] != Order::ORDER_FLOW_CANCEL)) { $delivery = DeliveryMaiyatian::findOne(['order_no' => $order->order_no, 'store_id' => $order->store_id]); if($delivery){ $order_canceled = self::order_canceled($order->store_id, $order->id); if($order_canceled['code'] !== 0){ throw new Exception($order_canceled['msg']); } $order_apply_refund = self::order_apply_refund($order->store_id, $order->id); if($order_apply_refund['code'] !== 0){ throw new Exception($order_apply_refund['msg']); } } } } catch (\Exception $ex) { \Yii::error($ex); debug_log([__FUNCTION__, __LINE__, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log'); } } public static function orderList($store_id, $params){ $form = new OrderListForm(); if($params['dateEnd']){ $params['dateEnd'] .= ' 23:59:59'; } $form->attributes = $params; $form->store_id = $store_id; $form->maiyatian = 1; $form->is_delivery = true; $list = $form->search(); unset($list['data']['export_list']); unset($list['data']['express_list']); foreach($list['data']['data'] as &$item){ $deliveryModel = DeliveryMaiyatian::findOne(['order_no' => $item['order_no']]); $delivery = $deliveryModel->attributes; $delivery['delivery_status_name'] = self::$delivery_status_list[$delivery['delivery_status']] ?? ''; $delivery['order_status_name'] = self::$order_status_list[$delivery['order_status']] ?? ''; $delivery['refund_status_name'] = $deliveryModel->getRefundStatusName(); $item['delivery'] = $delivery; } $list['maiyatian'] = [ 'order_status_list' => self::$order_status_list, 'delivery_status_list' => self::$delivery_status_list, 'logistic_tag_list' => self::$logistic_tag_list, ]; return $list; } public static function shop_info($store_id){ $data = self::api($store_id, 'shop_info', [ "shop_id" => (string)$store_id, //平台方渠道ID ]); return $data; } public static function order_created($store_id, $order_id = 0){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $delivery = DeliveryMaiyatian::findOne(['order_no' => $order->order_no, 'store_id' => $store_id]); if($delivery){ return [ 'code' => 1, 'msg' => '订单信息已存在', ]; } $data = self::getOrder($store_id, $order); $res = self::api($store_id, 'order_created', $data); if($res['code'] != 0){ return $res; } self::data_order_created($store_id, $order, $data); return $res; } public static function order_modified($store_id, $order_id = 0){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $data = self::getOrder($store_id, $order); $res = self::api($store_id, 'order_modified', $data); return $res; } public static function preAddOrder($store_id, $order_no, $freight) { if (!$order_no) { return [ 'code' => 1, 'msg' => '缺少订单号参数' ]; } DeliveryInfo::deleteAll(['order_no' => $order_no, 'store_id' => $store_id, 'status' => 0]); $delivery_info = new DeliveryInfo(); $delivery_info->store_id = $store_id; $delivery_info->order_no = $order_no; $delivery_info->delivery_type = ''; $delivery_info->fee = $freight; $delivery_info->created_at = time(); $save = $delivery_info->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery_info->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', 'data' => [ "resultcode" => 0, 'fee' => (float)$delivery_info->fee, ], ]; } public static function data_order_created($store_id, $order, $data){ $delivery = new DeliveryMaiyatian(); $delivery->store_id = $store_id; $delivery->order_no = $order->order_no; $delivery->delivery_status = self::DELIVERY_STATUS_PENDING; $delivery->order_status = self::ORDER_STATUS_UNPROGRESS; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } if($order->trade_status < Order::ORDER_FLOW_SEND){ $order->trade_status = Order::ORDER_FLOW_SEND; $order->send_time = time(); if (!$order->save()) { debug_log([__FUNCTION__, __LINE__, '订单发货失败', array_shift($order->getFirstErrors())], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '订单发货失败', ]; } } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function getOrder($store_id, $order) { $address_data = json_decode($order->address_data, true); $is_pre_order = false; if(!empty($order->delivery_time)){ $is_pre_order = true; $delivery_time = $order->delivery_time; }else{ $delivery_time = time() + 60 * self::getConf($store_id, 'cyy_delivery_time'); } $data = [ "order" => [ "order_id" => $order->order_no, "order_sn" => $order->id, "shop_id" => (string)$store_id, "shop_name" => self::getConf($store_id, 'name'), "category" => self::getConf($store_id, 'category'), "is_pre_order" => $is_pre_order, "total_price" => intval($order->total_price * 100), "balance_price" => intval($order->pay_price * 100), "create_time" => $order->created_at, "delivery_time" => $delivery_time, // "delivery_end" => 1657099625, "is_picker" => false, // "pick_time" => 0, "user_remark" => $order->remark, // "greeting" => "", // "pickup_code" => "", "order_fee" => [ "total_fee" => intval($order->total_price * 100), "send_fee" => 0, "package_fee" => 0, "discount_fee" => intval(($order->total_price - $order->pay_price) * 100), "shop_fee" => intval($order->pay_price * 100), "user_fee" => intval($order->pay_price * 100), "pay_type" => 2, // "need_invoice" => true, // "invoice" => [ // "type" => 1, // "title" => "麦芽田", // "taxer_id" => "123123123csd123", // "email" => "123@qq.com", // "form_type" => 2 // ], // "commission" => 0, // "activity" => [ // [ // "type" => 1, // "title" => "满30减10", // "merchant" => 3000, // "reduce" => 1000 // ] // ], // "is_first" => true, // "is_favorite" => false ], "order_goods" => [ [ "goods_id" => "1001", "goods_name" => "烧鸡", "thumb" => "https://p1.meituan.net/210.0/dpmerchantpic/f6c19b87623aead81776d86bc1f6b629335919.jpg", "sku_id" => "10001", "sku_name" => "原味", "sku_attributes" => [ [ "name" => "烧鸡200g" ] ], "unit" => "包", "weight" => 100, // "upc" => "123123123", // "shelf_no" => "123123", "number" => 2, "goods_price" => 500, "goods_total_fee" => 1000, // "package_number" => 1, // "package_price" => 100, // "package_total_fee" => 100, "reduce_fee" => 980, "discount_fee" => 20, // "discount_platform_fee" => 0, // "discount_merchant_fee" => 0, // "discount_agent_fee" => 0, // "discount_logistics_fee" => 0, "total_fee" => 980, // "goods_code" => "123123", // "sku_code" => "123123" ] ] ], "order_customer" => [ "real_name" => $order->name, "phone" => $order->mobile, "secret_phone" => substr_replace($order->mobile, '****', 3, 4), // "order_phone" => "15626476455", // "reserve_phone" => "15735039271_7095", "address" => $order->address, "longitude" => $address_data['longitude'] ?? '', "latitude" => $address_data['latitude'] ?? '', ], "update_time" => $order->pay_time, ]; $data['order']['order_goods'] = []; $ods = $order->detail; foreach($ods as $od){ $goods = $od->goods; $attrs = json_decode($od->attr, true); $item = [ "goods_id" => (string)$od->goods_id, "goods_name" => mb_substr($od->goods_name, 0, 10), "thumb" => $od->pic, "sku_id" => implode('_', array_column($attrs, 'attr_id')), "sku_name" => implode('_', array_column($attrs, 'attr_name')), "sku_attributes" => [ [ "name" => implode('_', array_column($attrs, 'attr_name')), ] ], "unit" => $goods->unit, "weight" => $goods->weight, // "upc" => "123123123", // "shelf_no" => "123123", "number" => $od->num, "goods_price" => intval($goods->price * 100), "goods_total_fee" => intval($od->total_price * 100), // "package_number" => 1, // "package_price" => 100, // "package_total_fee" => 100, "reduce_fee" => 0, "discount_fee" => 0, // "discount_platform_fee" => 0, // "discount_merchant_fee" => 0, // "discount_agent_fee" => 0, // "discount_logistics_fee" => 0, "total_fee" => intval($od->total_price * 100), // "goods_code" => "123123", // "sku_code" => "123123" ]; $data['order']['order_goods'][] = $item; } return $data; } /** * 订单申请退款 * @param type $store_id * @param type $order_id * @param type $type //退款类型 1全部 2部分 * @param type $reason //原因 */ public static function order_apply_refund($store_id, $order_id = 0, $type = 1, $reason = '申请退款'){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $params = [ 'type' => (int)$type, 'reason' => (string)$reason, ]; $res = self::api($store_id, 'order_apply_refund', array_merge( self::getOrderRefund($store_id, $order), $params, ) ); if($res['code'] != 0){ return $res; } self::data_order_refund($store_id, $order->order_no, $params); return $res; } /** * 订单退款 * @param type $store_id * @param type $order_id * @param type $status //退款状态 1确认 2驳回 3用户取消退款申请 */ public static function order_refunded($store_id, $order_id = 0, $status = 1){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $params = [ 'status' => (int)$status, ]; $res = self::api($store_id, 'order_refunded', array_merge( self::getOrderRefund($store_id, $order), $params, ) ); if($res['code'] != 0){ return $res; } self::data_order_refund($store_id, $order->order_no, $params); return $res; } /** * 订单取消 * @param type $store_id * @param type $order_id * @param type $reason * @param type $reason_code //取消类型 1用户 2商户 3客服 4系统 5其他 */ public static function order_canceled($store_id, $order_id = 0, $reason = '取消', $reason_code = 1){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $params = [ 'reason' => (string)$reason, 'reason_code' => (int)$reason_code, ]; $res = self::api($store_id, 'order_canceled', array_merge( self::getOrderRefund($store_id, $order), $params, ) ); if($res['code'] != 0){ return $res; } self::data_order_canceled($store_id, $order->order_no, $params); //取消后自动退款 self::order_apply_refund($store_id, $order_id, 1, $reason); $res = self::order_refunded($store_id, $order_id); return $res; } public static function getOrderRefund($store_id, $order) { $goods = []; $ods = $order->detail; foreach($ods as $od){ $attrs = json_decode($od->attr, true); $item = [ "goods_id" => (string)$od->goods_id, "goods_name" => mb_substr($od->goods_name, 0, 10), "sku_id" => implode('_', array_column($attrs, 'attr_id')), "upc" => "", "shelf_no" => "", "number" => $od->num, "goods_total_fee" => intval($od->total_price * 100), "package_number" => 1, "package_fee" => 0, "refund_fee" => intval($od->total_price * 100), ]; $goods[] = $item; } $res = [ 'order_id' => $order->order_no, 'shop_id' => (string)$store_id, 'goods' => $goods, 'total_price' => intval($order->total_price * 100), 'count' => count($ods), 'update_time' => time(), ]; $delivery = DeliveryMaiyatian::findOne(['order_no' => $order->order_no, 'store_id' => $store_id]); $delivery['refund_type'] && $res['type'] = $delivery['refund_type']; $delivery['refund_reason'] && $res['reason'] = $delivery['refund_reason']; return $res; } public static function order_confirmed($store_id, $order_id = 0){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $res = self::api($store_id, 'order_confirmed', [ 'order_id' => $order->order_no, 'shop_id' => (string)$store_id, 'update_time' => time(), ]); if($res['code'] != 0){ return $res; } self::data_order_confirm($store_id, $order->order_no); return $res; } public static function order_done($store_id, $order_id = 0){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $res = self::api($store_id, 'order_done', [ 'order_id' => $order->order_no, 'shop_id' => (string)$store_id, 'update_time' => time(), ]); if($res['code'] != 0){ return $res; } self::data_order_done($store_id, $order->order_no); return $res; } public static function query_order($store_id, $order_id = 0){ $order = Order::findOne($order_id); if(!$order){ return [ 'code' => 1, 'msg' => '订单信息错误', ]; } $res = self::api($store_id, 'query_order', [ 'order_id' => $order->order_no, 'shop_id' => (string)$store_id, ]); return $res; } public static function data_order_refund($store_id, $order_no = '', $params = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->is_refund = 1; $params['type'] && $delivery->refund_type = $params['type']; $params['reason'] && $delivery->refund_reason = $params['reason']; $params['status'] && $delivery->refund_status = $params['status']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_canceled($store_id, $order_no = '', $params = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->is_cancel = 1; $params['reason'] && $delivery->cancel_reason = $params['reason']; $params['reason_code'] && $delivery->cancel_reason_code = $params['reason_code']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_done($store_id, $order_no = ''){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->order_status = self::ORDER_STATUS_DONE; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_confirm($store_id, $order_no = ''){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->order_status = self::ORDER_STATUS_CONFIRM; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_change($store_id, $order_no = '', $data = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->order_status = $data['status']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_delivery_change($store_id, $order_no = '', $data = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->delivery_status = $data['status']; $delivery->rider_name = $data['rider_name']; $delivery->rider_mobile = $data['rider_phone']; $delivery->logistic_tag = $data['logistic_tag']; $delivery->logistic_no = $data['logistic_no']; $delivery->lng = $data['longitude']; $delivery->lat = $data['latitude']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } if($delivery->delivery_status == self::DELIVERY_STATUS_DONE){ debug_log([__FUNCTION__, __LINE__, '确认收货', $delivery->delivery_status], __CLASS__ . '.log'); //确认收货 $order = Order::find()->where(['order_no' => $order_no])->andWhere(['trade_status' => Order::ORDER_FLOW_SEND])->one(); if(!$order){ return [ 'code' => 1, 'msg' => '确认收货订单信息错误', ]; } $order->trade_status = Order::ORDER_FLOW_CONFIRM; $order->confirm_time = time(); if (!$order->save()) { debug_log([__FUNCTION__, __LINE__, '确认收货失败', array_shift($order->getFirstErrors())], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '确认收货失败', ]; } } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_multi_rider_location($data = []){ foreach($data['locations'] as $item){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $item['order_id'], 'store_id' => $item['shop_id']]); $delivery->logistic_tag = $item['logistic_tag']; $delivery->logistic_no = $item['logistic_no']; $delivery->lng = $item['longitude']; $delivery->lat = $item['latitude']; $save = $delivery->save(); } if(isset($save) && !$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_agree_refund($store_id, $order_no = '', $data = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->refund_status = 1; $data['refund_id'] && $delivery->refund_id = $data['refund_id']; $data['reason'] && $delivery->refund_status_reason = $data['reason']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_reject_refund($store_id, $order_no = '', $data = []){ $delivery = DeliveryMaiyatian::findOne(['order_no' => $order_no, 'store_id' => $store_id]); $delivery->refund_status = 2; $data['refund_id'] && $delivery->refund_id = $data['refund_id']; $data['reason'] && $delivery->refund_status_reason = $data['reason']; $save = $delivery->save(); if(!$save){ return [ 'code' => 1, 'msg' => array_shift($delivery->getFirstErrors()), ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function data_order_list($store_id, $data = []){ $query = DeliveryMaiyatian::find()->where(['store_id' => $store_id])->orderBy('id DESC')->asArray(); $query->andWhere(['>=', 'created_at', $data['start_time']/1000]); $query->andWhere(['<=', 'created_at', $data['end_time']/1000]); $countQuery = clone $query; $count = $countQuery->count(); $query->offset(($data['page'] - 1) * $data['page_size'])->limit($data['page_size']); $list = $query->all(); $dataList = []; foreach($list as $item){ $order = Order::findOne(['order_no' => $item['order_no']]); $dataList[] = self::getOrder($store_id, $order); } return [ 'code' => 0, 'msg' => 'ok', 'data' => json_encode([ "page" => 1, "total" => $count, "total_page" => 1, "data" => $dataList, ]), ]; } public static function data_order_detail($store_id, $order_no = ''){ $order = Order::findOne(['order_no' => $order_no]); $data = self::getOrder($store_id, $order); return [ 'code' => 0, 'msg' => 'ok', 'data' => json_encode($data), ]; } }