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

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

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

我也没办法 只能硬着头皮上。首先我得到一个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;

然后导出



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





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章