appKey . $data['shop_id'] . self::RedisKey; $token = Redis::get($key); if(! empty($token)) return [true, $token]; list($bool,$msg) = $this->curlForToken($key, $data['shop_id']); if(! $bool) return [false, $msg]; return [true, $msg]; } public function curlForToken($key, $shop_id){ $param['shop_id'] = $shop_id; $param['grant_type'] = "authorization_self"; $param['code'] = ""; list($url, $paramJson) = $this->organization($param,$this->url_create); //发送请求 list($bool,$return) = $this->post_helper($url,$paramJson); if(! $bool) return [false, $return]; if($return['code'] != 10000) return [false, $return['sub_msg']]; file_put_contents('token_'. $shop_id . '.txt',json_encode($return)); $token = $return['data']['access_token']; $expires_in = $return['data']['expires_in'] - 3600; Redis::setex($key,$expires_in,$token); return [true,$token]; } //------------------获取token //------------------获取订单列表 public function getOrderList($data,$user){ list($bool,$token) = $this->getToken($data); if(! $bool) return [false, $token]; list($bool,$return) = $this->curlForOrderList($token,$data); if(! $bool) return [false, $return]; return [true, $return]; } public function curlForOrderList($token,$data){ if(empty($data['create_time'][0]) || empty($data['create_time'][0])) return [false, '下单时间不能为空']; //下单时间:开始结束,秒级时间戳 $return = $this->changeDateToTimeStampAboutRange($data['create_time']); $param['create_time_start'] = $return[0]; $param['create_time_end'] = $return[1]; if(! empty($data['product'])) { //商品,number型代表商品ID,其它代表商品名称 $param['product'] = $data['product']; } if(isset($data['b_type'])){ //【下单端】 0、站外 1、火山 2、抖音 3、头条 4、西瓜 5、微信 6、值点app 7、头条lite 8、懂车帝 9、皮皮虾 11、抖音极速版 12、TikTok 13、musically 14、穿山甲 15、火山极速版 16、服务市场 26、番茄小说 27、UG教育营销电商平台 28、Jumanji 29、电商SDK $param['b_type'] = $data['b_type']; } if(! empty($data['after_sale_status_desc'])){ //售后状态:all-全部,in_aftersale-售后中,refund-退款中,refund_success-退款成功,refund_fail-退款失败,exchange_success-换货成功 aftersale_close-售后关闭 $param['after_sale_status_desc'] = $data['after_sale_status_desc']; } if(! empty($data['tracking_no'])){ //物流单号 $param['tracking_no'] = $data['tracking_no']; } if(isset($data['presell_type'])){ //预售类型:0-普通订单;1-全款预售;2-定金预售;3-定金找货; $param['presell_type'] = $data['presell_type']; } if(isset($data['order_type'])){ //订单类型 0、普通订单 2、虚拟商品订单 4、电子券(poi核销) 5、三方核销 $param['order_type'] = $data['order_type']; } if(! empty($data['abnormal_order'])) { //异常订单,1-异常取消,2-风控审核中 $param['abnormal_order'] = $data['abnormal_order']; } if(isset($data['trade_type'])){ //交易类型:0-普通;1-拼团;2-定金预售;3-订金找货;4-拍卖;5-0元单;6-回收;7-寄卖;10-寄样;11-0元抽奖(超级福袋);12-达人买样;13-普通定制;16-大众竞拍;18-小时达;102-定金预售的赠品单;103-收款; $param['trade_type'] = $data['trade_type']; } if(! empty($data['update_time'][0]) && ! empty($data['update_time'][0])){ //更新时间:开始结束,秒级时间戳 $return = $this->changeDateToTimeStampAboutRange($data['update_time']); $param['update_time_start'] = $return[0]; $param['update_time_end'] = $return[1]; } if(empty($data['size'])) { //单页大小,限制100以内 $param['size'] = 20; }else{ if($data['size'] > 100) return [false, '单页大小,限制100以内']; $param['size'] = $data['size']; } if(! isset($data['page'])) { $param['page'] = 0; }else{ $param['page'] = $data['page']; } if(! empty($data['order_by'])){ //排序条件(create_time 订单创建时间;update_time 订单更新时间;默认create_time;) $param['order_by'] = $data['order_by']; } //排序类型,小到大或大到小,默认大到小 if(! isset($data['order_asc'])){ $param['order_asc'] = false; }else{ $param['order_asc'] = $data['order_asc']; } if(! empty($data['fulfil_status'])) { //履约状态;如小时达未接单"no_accept" $param['fulfil_status'] = $data['fulfil_status']; } //组织数据 list($url, $paramJson) = $this->organization($param,$this->url_order_list,$token); //发送请求 list($bool,$return) = $this->post_helper($url,$paramJson); if(! $bool) return [false, $return]; if($return['code'] != 10000) return [false, $return['sub_msg']]; return [true, $return['data'] ?? []]; } //------------------获取订单列表 //------------------获取订单详情 public function getOrderDetail($data,$user){ list($bool,$token) = $this->getToken($data); if(! $bool) return [false, $token]; list($bool,$return) = $this->curlForOrderDetail($token,$data); if(! $bool) return [false, $return]; return [true, $return]; } public function curlForOrderDetail($token,$data){ if(empty($data['shop_order_id'])) return [false, '店铺订单号不能为空']; $param['shop_order_id'] = $data['shop_order_id']; //组织数据 list($url, $paramJson) = $this->organization($param,$this->url_order_detail,$token); //发送请求 list($bool,$return) = $this->post_helper($url,$paramJson); if(! $bool) return [false, $return]; if($return['code'] != 10000) return [false, $return['sub_msg']]; return [true, $return['data'] ?? []]; } //------------------获取订单详情 //------------------导入线上订单 public function insertDouOrder($data,$user){ // [ // 'shop_id' => 111, // 'order_list'=>[ // [ // 'order_id' => '', // 'order_amount' => '', // 'product' => [ // [ // 'product_name' => '', // 'code' => '', // 'item_num' => '', // 'sum_amount' => '', // ] // ], // ], // [ // 'order_id' => '', // 'order_amount' => '', // 'product' => [ // [ // 'product_name' => '', // 'code' => '', // 'item_num' => '', // 'sum_amount' => '', // ] // ], // ] // ], // ]; if(empty($data['order_list'])) return [false, '订单数据不能为空']; if(empty($data['shop_id'])) return [false, '店铺ID不能为空']; $basic = BasicType::where('del_time',0) ->where('code', $data['shop_id']) ->first(); if(empty($basic->id)) return [false, '未找到店铺绑定的平台,请联系管理员进行绑定']; $plat_type = $basic->id; $customer_short_name = 0; $basic = BasicType::where('del_time',0) ->whereIn('type',[29]) ->where('title','抖音平台') ->where('top_depart_id',$user['head']['id']) ->select('id')->first(); if(! empty($basic->id)) $customer_short_name = $basic->id; $search = "" ; $order_id = []; foreach ($data['order_list'] as $value){ if(empty($value['order_id'])) return [false, '订单ID不能为空']; $order_id[] = $value['order_id']; if(! isset($value['order_amount']) || $value['order_amount'] < 0) return [false, '订单金额不能为空']; //promotion_amount 优惠金额 if(empty($value['product'])) return [false,'订单下的商品不能为空']; foreach ($value['product'] as $p){ if(empty($p['product_name'])) return [false,'商品名称不能为空']; if(empty($p['code'])) return [false, '商品:' . $p['product_name'] . '的商家编码为空,请进入抖店商家后台补充完整']; if(empty($p['item_num'])) return [false, '商品:' . $p['product_name'] . '的数量不能为空']; if(empty($p['sum_amount'])) return [false, '商品:' . $p['sum_amount'] . '的金额不能为空']; $search .= "(code = '".$p['code']."') or"; } } $search = rtrim($search,' or'); $model = Product::ProductClear($user,[]); $product = $model->whereRaw($search) ->where('del_time',0) ->select('title','id','code','cost','retail_price') ->get()->toArray(); $product_map = []; foreach ($product as $value){ $product_map[$value['code']] = [ 'id' => $value['id'], 'cost' => $value['cost'], 'retail_price' => $value['retail_price'], ]; } $sale = SalesOrder::where('del_time',0) ->whereIn('plat_order',$order_id) ->pluck('plat_order','id') ->toArray(); $head = $user['head']['id'] ?? 0; $prefix = SalesOrder::$prefix[salesOrder::Model_type_four]; $time = time(); $tmp = [ 'sales_order_type' => SalesOrder::Order_type_one, 'model_type' => SalesOrder::Model_type_four, 'order_number' => '', 'customer_short_name' => $customer_short_name, 'plat_type' => $plat_type, 'plat_order' => '', 'sign_time' => $time, 'product_total' => 0, 'contract_fee' => 0, 'discount_fee' => 0, 'cdefine29' => '',//分社施工 'cdefine32' => '',//达人昵称 'cdefine30' => '',//业务员 'rate' => 100, 'depart_id' => $head, 'top_depart_id' => $head, 'crt_id' => $user['id'], 'crt_time' => $time, 'upd_time' => $time, ]; $tmp_detail = [ 'sales_order_id' => 0, 'product_id' => 0, 'cost' => 0, 'retail_price' => 0, 'basic_type_id' => 0, 'price' => 0, 'final_amount' => 0, 'number' => '', 'crt_time' => $time, ]; $insert = $insert_detail = $insert_detail_man = []; foreach ($data['order_list'] as $value){ if(isset($sale[$value['order_id']])) return [false, '平台单号:' . $value['order_id'] . '在系统中已录入!']; $tmp['order_number'] = OrderNoService::createSalesOrderNumber($prefix); $tmp['plat_order'] = $value['order_id']; $tmp['discount_fee'] = 0; $tmp['contract_fee'] = $value['order_amount'] / 100; foreach ($value['product'] as $p){ if(! isset($product_map[$p['code']])) return [false, '产品编码:' . $p['code'] . '在系统中不存在或已被删除']; $tmp['product_total'] += $p['sum_amount'] / 100; //产品子表 $product_tmp = $product_map[$p['code']] ?? []; $tmp_detail['product_id'] = $product_tmp['id']; $tmp_detail['cost'] = $product_tmp['cost']; $tmp_detail['retail_price'] = $product_tmp['retail_price']; $tmp_detail['price'] = $product_tmp['retail_price']; $tmp_detail['final_amount'] = $p['sum_amount'] / 100; $tmp_detail['number'] = $p['item_num']; $insert_detail[$value['order_id']][] = $tmp_detail; } //主表 $insert[$value['order_id']] = $tmp; //人员子表 $insert_detail_man[$value['order_id']] = [ 'type' => SalesOrderInfo::type_one, 'data_id' => $user['id'], 'crt_time' => $time, ]; } $insert = array_values($insert); $insert_detail = array_values($insert_detail); $insert_detail_man = array_values($insert_detail_man); try{ DB::beginTransaction(); if(! empty($insert)) SalesOrder::insert($insert); $last_insert_id = SalesOrder::where('crt_time',$time) ->select('id') ->get()->toArray(); $last_insert_id = array_column($last_insert_id,'id'); if(! empty($insert_detail)){ $insert2 = []; foreach ($last_insert_id as $key => $value){ if(isset($insert_detail[$key])) { foreach ($insert_detail[$key] as $val){ $val['sales_order_id'] = $value; $insert2[] = $val; } } } SalesOrderProductInfo::insert($insert2); } if(! empty($insert_detail_man)){ $insert3 = []; foreach ($last_insert_id as $key => $value){ if(isset($insert_detail_man[$key])) { $insert_detail_man[$key]['sales_order_id'] = $value; $insert3[] = $insert_detail_man[$key]; } } SalesOrderInfo::insert($insert3); } DB::commit(); }catch (\Exception $e){ DB::rollBack(); return [false, $e->getMessage() . $e->getLine() . $e->getCode()]; } return [true, '']; } //------------------导入线上订单 //序列化排序 public function marshal($param){ if($param == null) return "{}"; $arr = $param; $this->recKSort($arr); // 对关联数组中的kv,执行排序,需要递归 $json = json_encode($arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // 重新序列化,确保所有key按字典序排序 return $json; } // 关联数组排序,递归 public function recKSort(&$arr) { $kstring = true; foreach ($arr as $k => &$v) { if (!is_string($k)) { $kstring = false; } if (is_array($v)) { $this->recKSort($v); } } if ($kstring) { ksort($arr); } } //加密 public function sign($method, $timestamp, $paramJson){ $appKey = $this->appKey; $appSecret = $this->appSecret; $paramPattern = 'app_key' . $appKey . 'method' . $method . 'param_json' . $paramJson . 'timestamp' . $timestamp . 'v2'; $signPattern = $appSecret . $paramPattern . $appSecret; return hash_hmac("sha256", $signPattern, $appSecret); } //获取方法 public function getMethod($urlPath) { if (strlen($urlPath) == 0) { return $urlPath; } $methodPath = ""; if (substr($urlPath, 0, 1) == "/") { $methodPath = substr($urlPath, 1, strlen($urlPath)); } else { $methodPath = $urlPath; } return str_replace("/", ".", $methodPath); } //组织请求参数 public function organization($param,$method,$token = ""){ $paramJson = $this->marshal($param); //时间戳 $timestamp = time(); //方法 $method_2 = $this->getMethod($method); //签名 $sign = $this->sign($method_2,$timestamp,$paramJson); //地址 $url = $this->host . $method . '?app_key='. $this->appKey.'&method='. $method_2 .'¶m_json='. $paramJson .'×tamp='. $timestamp .'&v=2&sign=' . $sign . '&access_token='. $token . '&sign_method=hmac-sha256'; return [$url, $paramJson]; } //发送请求 public function post_helper($url, $data, $timeout = 20){ $header = array("Content-type:application/json;charset='utf-8'"); Log::channel('apiLog')->info('抖店POST', ["api" => $url , "param" => $data ,"header" => $header]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $r = curl_exec($ch); if ($r === false) { // 获取错误号 $errorNumber = curl_errno($ch); // 获取错误信息 $errorMessage = curl_error($ch); $message = "cURL Error #{$errorNumber}: {$errorMessage}"; Log::channel('apiLog')->info('抖店POST结果', ["message" => $message]); return [false, "cURL Error #{$errorNumber}: {$errorMessage}"]; } curl_close($ch); Log::channel('apiLog')->info('抖店POST结果', ["message" => json_decode($r, true)]); return [true, json_decode($r, true)]; } }