PHP实现平台商品和京东价格做对比

xiaoxiao2021-02-28  32

我们公司最近有个需求 ,经产品部门的反应,说现在我们的商品价格和京东不同步,或者说不合理,要我们技术部的人查出原因。

那么很不幸的是,老大把这个任务交给了我。

我也没办法 只能硬着头皮上。首先我得到一个sku基础数据,查了一下   有10w多条呢。

最初的做法  我贴出代码

<?php set_time_limit(0); error_reporting(E_ALL^E_NOTICE); header("Content-type: text/html; charset=utf-8"); require("./jdapi.class.php"); require("./token.php"); date_default_timezone_set('Asia/Shanghai'); $jd = new jdapi(); $refreshToken = ''; $token = get_token($refreshToken); //读取csv文件 $csv = 'd:/sku1.csv'; $data = read_csv($csv); $col = array( 'sku'=>0, 'cost_price'=>1 ); echo '<pre>'; $res = ''; foreach ($data as $k =>$one) { $sku = $one[$col['sku']]; $cost_price = $one[$col['cost_price']]; //获取京东的售价 ,如果小于等于我们的成本价就有问题 $jd_json = $jd->getPrice($token,$sku); $arr = json_decode($jd_json,1); $hava_pro = ''; $jd_shoujia = $arr['result'][0]['price']; if($jd_shoujia<=$cost_price) { $hava_pro = '有问题'; } else { $hava_pro = '正常'; } $res[$k]['sku'] = $sku; $res[$k]['cost_price'] = $cost_price; $res[$k]['jd_price'] = $jd_shoujia; $res[$k]['pro'] = $hava_pro; } createcsv($res); function read_csv($file) { setlocale(LC_ALL,'zh_CN');//linux系统下生效 $data = null;//返回的文件数据行 if(!is_file($file)&&!file_exists($file)) { die('文件错误'); } $cvs_file = fopen($file,'r'); //开始读取csv文件数据 $i = 0;//记录cvs的行 while ($file_data = fgetcsv($cvs_file)) { $i++; if($i==1) { continue;//过滤表头 } if($file_data[0]!='') { $data[$i] = $file_data; } } fclose($cvs_file); return $data; } function createcsv($csv_body) { // 头部标题 $csv_header = array('sku','我们自己的成本价','京东自己的销售价','对比结果'); /** * 开始生成 * 1. 首先将数组拆分成以逗号(注意需要英文)分割的字符串 * 2. 然后加上每行的换行符号,这里建议直接使用PHP的预定义 * 常量PHP_EOL * 3. 最后写入文件 */ // 打开文件资源,不存在则创建 $des_file = 'd:/res.csv'; $fp = fopen( $des_file,'a'); // 处理头部标题 $header = implode(',', $csv_header) . PHP_EOL; // 处理内容 $content = ''; foreach ($csv_body as $k => $v) { $content .= implode(',', $v) . PHP_EOL; } // 拼接 $csv = $header.$content; // 写入并关闭资源 fwrite($fp, $csv); fclose($fp); } function buildOrderId() { $randStr = str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'); $rand = substr($randStr,0,6); return 'XRY_JD'.date('YmdHis',time()).$rand; } function get_token(&$refreshToken) { global $g_token; $time = isset($g_token['time'])?$g_token['time']:NULL; $expires_in = isset($g_token['expires_in'])?$g_token['expires_in']:NULL; $access_token = isset($g_token['access_token'])?$g_token['access_token']:NULL; $refreshToken = isset($g_token['refresh_token'])?$g_token['refresh_token']:NULL; if($time && $expires_in && $access_token) { $now = time(); if(($now + 3600) > ($time/1000 + $expires_in)) { get_token_in($access_token); } } else { get_token_in($access_token); } return $access_token; } function get_token_in(&$token) { global $jd; $json = $jd->getAccessToken(); $obj = json_decode($json,true); if($obj['success']) { $token = $obj['result']["access_token"]; // $text_token = '<?php $g_token = array('; foreach($obj['result'] as $key=>$value) { $text_token .= '"'.$key.'"=>"'.$value.'",'; } $text_token .= ');'; $text_token = utf8_encode($text_token); $fp=@fopen('./token.php','w'); if($fp) { fwrite($fp,$text_token); fclose($fp); } } return $json; } ?>

这个方法 我数据量少的时候 是正常运行 可以得到预期的值,。现在我真实数据10w。发现nginx报504错误。。

我就去修改代码,经过一番查资料我加上如下代码

set_time_limit(0);

nginx配置文件

依然没有作用。。。

然后我急了。急没办法啊,。

此时我再去读京东接口文档,发现 价格查询接口最多支持100个查询。多了,。就报错。。问题1这是。

第二个问题是我一次性操作10w个商品肯定会报错的,超过php单页面执行时间了。这个肯定不行,得换个思路。

然后我开始 转变  ,我把基础表的数据,导入到一个新表 用来做结果比对表

先生成比对表用sql语句

这是比对表

CREATE TABLE `difen` ( `id` int(8) NOT NULL AUTO_INCREMENT, `sku` varchar(20) NOT NULL, `cost_price` decimal(10,2) NOT NULL, `price` decimal(10,2) DEFAULT '1.00', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=131071 DEFAULT CHARSET=utf8;

price字段先留空 ,稍后做填充

创建表之后 我们执行以下sql语句

INSERT into difen(sku,price) SELECT g.sku,g.cost_price FROM goodsdb.`goods` g WHERE g.`sale_status` = 1 AND g.`status` = 1 and g.supplier_id=2;

得到一部分对比数据。。

然后我通过程序代码 把price填充进来

<?php set_time_limit(0); error_reporting(E_ALL^E_NOTICE); header("Content-type: text/html; charset=utf-8"); require("./jdapi.class.php"); require("./token.php"); date_default_timezone_set('Asia/Shanghai'); $jd = new jdapi(); $refreshToken = ''; $token = get_token($refreshToken); //读取csv文件 $mysqli = new mysqli('localhost','root','root','test'); while (true){ $sql1 = "select * from diff where price is null"; $res = $mysqli->query($sql1); $set_sku_arr = ''; while (($row = $res->fetch_assoc())==true) { if(count($set_sku_arr)<100) { $set_sku_arr[] = $row['sku']; } } $str = implode(',',$set_sku_arr); $jd_json = $jd->getPrice($token,$str); $arr = json_decode($jd_json,1); $result_list = $arr['result']; //echo '<pre>';print_r($arr); $sku_list = ''; $sql = "UPDATE diff SET price = CASE sku "; foreach ($result_list as $res) { $sku_list[] = $res['skuId']; $sql .= sprintf("WHEN \"%s\" THEN \"%.2f\" ", $res['skuId'], $res['jdPrice']); // 拼接SQL语句 } $sku_str = implode(',', array_map("change_to_quotes", $sku_list)); $sql .= "END WHERE sku IN ($sku_str)"; //执行 $mysqli->query($sql); } function change_to_quotes($str) { return sprintf("\"%s\"", $str); } function get_token(&$refreshToken) { global $g_token; $time = isset($g_token['time'])?$g_token['time']:NULL; $expires_in = isset($g_token['expires_in'])?$g_token['expires_in']:NULL; $access_token = isset($g_token['access_token'])?$g_token['access_token']:NULL; $refreshToken = isset($g_token['refresh_token'])?$g_token['refresh_token']:NULL; if($time && $expires_in && $access_token) { $now = time(); if(($now + 3600) > ($time/1000 + $expires_in)) { get_token_in($access_token); } } else { get_token_in($access_token); } return $access_token; } function get_token_in(&$token) { global $jd; $json = $jd->getAccessToken(); $obj = json_decode($json,true); if($obj['success']) { $token = $obj['result']["access_token"]; // $text_token = '<?php $g_token = array('; foreach($obj['result'] as $key=>$value) { $text_token .= '"'.$key.'"=>"'.$value.'",'; } $text_token .= ');'; $text_token = utf8_encode($text_token); $fp=@fopen('./token.php','w'); if($fp) { fwrite($fp,$text_token); fclose($fp); } } return $json; } ?>

这个执行完,就把price填充好了,。接下来用一条sql语句实现对比 再导出即可

SELECT sku 'sku',cost_price '成本价',price '京东销售价',(case when price<=cost_price then '不合格' else '合格' end) '对比结果' from difen;

然后导出

就这样给公司交了一份满意的答案。。。。

转载请注明原文地址: https://www.6miu.com/read-2621264.html

最新回复(0)