Browse Source

授权 同步历史订单 同步增量订单 定时更新订单状态 导出待发货订单 最近30天订单统计 待发货订单统计 退款订单统计

pull/1/head
liuyu 3 years ago
parent
commit
24e0e47b4f
  1. 28
      config/define.php
  2. 25
      control/callback.php
  3. 83
      control/index.php
  4. 26
      data/dBase.php
  5. 2
      data/dGoods.php
  6. 1
      data/dUser.php
  7. 194
      index.php
  8. 300
      library/pinduoduo/pdd_api.php
  9. 17
      model/mGoods.php
  10. 137
      model/mOrder.php
  11. 86
      model/mPage.php
  12. 260
      model/mPdd.php
  13. 28
      model/mRedis.php
  14. 77
      model/mShop.php
  15. 8
      model/mUser.php
  16. 14
      project_vhost.conf
  17. 45
      queue/base/cronBase.php
  18. 141
      queue/base/dealBase.php
  19. 19
      queue/config/daemonconf.php
  20. 43
      queue/deal/sync_historical_orders.php
  21. 43
      queue/deal/sync_increment_orders.php
  22. 43
      queue/deal/sync_orders_status.php

28
config/define.php

@ -14,4 +14,32 @@
define('LOG_PATH_BASE', DATACENTER_ROOT.'/logs/');
define('LOG_TRACK_SAVE_PATH', LOG_PATH_BASE.'track/%s/%s.log'); // 监控日志的路径,如2014-02-14/1(检测类型).log
define('APP_TMEPPATH', DATACENTER_ROOT.'/temp/');
define('APP_TMEPPATH_WAIT_DELIVER_GOODS_CSV', APP_TMEPPATH.'/wait_deliver_goods_csv/');
# 拼多多
define('PDD_CLIENT_ID', '565558eab28242c7a9fa47fa080a06db');
define('PDD_CLIENT_SECRET', 'bf3dfd836648d0d53657030d17b10e2dfa7056a0');
define('PDD_REDIRECT_URI', 'http://www.kuailelunwen.com/callback/pdd');
define('PDD_AUTH_STATE', 'pddauth');
define('PDD_APPLICATION_BUY_URL', '');
# order_status 1:待发货,2:已发货待签收,3:已签收 5:全部
define('ORDER_STATUS_WAIT_DELIVER_GOODS', 1);
define('ORDER_STATUS_DELIVERED', 2);
define('ORDER_STATUS_SIGNED_FOR', 3);
define('ORDER_STATUS_FULL', 5);
# refund_status 售后状态 1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功 5:全部
define('REFUND_STATUS_NO_AFTER_SALES', 1);
define('REFUND_STATUS_AFTER_SALE_ING', 2);
define('REFUND_STATUS_ING', 3);
define('REFUND_STATUS_SUCC', 4);
define('REFUND_STATUS_FULL', 5);
# 同步历史订单
define('_RQ_SYNC_HISTORICAL_ORDERS', 'rq_sync_historical_orders');
define('_RQ_SYNC_INCREMENT_ORDERS', 'rq_sync_increment_orders');
define('USER_STATUS_VALID', 1);

25
control/callback.php

@ -8,6 +8,31 @@ include_once(dirname(dirname(__FILE__))."/library/publicBase.php");
class callback extends publicBase {
public function pdd() {
$obj = new mPdd();
$info = $obj->getPddAccessToken($this->get('code'));
$obj->writeLog('application', 'pdd_auth.log', json_encode($info)."\n");
// if($info['expires_at']==0) $this->show_message('对不起,服务已到期,请续费后再使用。', PDD_APPLICATION_BUY_URL);
$access_token = $info['access_token'];
// if(empty($access_token)) $this->show_message('授权信息token不存在');
$name = urldecode($info['owner_name']);
$expire_time = date("Y-m-d H:i:s", $info['expires_at']);
$uid = $_SESSION['app_uid'] ? $_SESSION['app_uid'] : 0;
$sobj = new mShop();
$shopinfo = $sobj->addShop($name, $access_token, $expire_time, $uid);
var_dump($shopinfo);
$_SESSION['app_uid'] = $shopinfo['uid'];
$_SESSION['app_name'] = $shopinfo['name'];
var_dump($_SESSION);
exit();
header('Location: /');
exit;
}
}

83
control/index.php

@ -1,13 +1,90 @@
<?php
/**
*
*/
include_once(dirname(dirname(__FILE__))."/library/publicBase.php");
class index extends publicBase {
public function home() {
$shopinfo = $this->get_shopinfo();
$uid = $shopinfo['uid'];
$shop_id = $shopinfo['id'];
$obj = new mOrder();
$this->view['date2count'] = $date2count = $obj->getLastThirtyDaysOrderNum($uid, $shop_id);
$this->view['wait_deliver_goods_count'] = $obj->getOrdersCount($uid, $shop_id, ORDER_STATUS_WAIT_DELIVER_GOODS, REFUND_STATUS_NO_AFTER_SALES);
$this->view['refund_count'] = $obj->getOrdersCount($uid, $shop_id, 0, REFUND_STATUS_SUCC);
}
public function order_list() {
$url = '/index/order_list';
$shopinfo = $this->get_shopinfo();
$uid = $shopinfo['uid'];
$shop_id = $shopinfo['id'];
$order_status = $this->get('order_status')+0;
$refund_status = $this->get('refund_status')+0;
$url .= '/order_status/'.$order_status;
$url .= '/refund_status/'.$refund_status;
$obj = new mOrder();
$count = $obj->getOrdersCount($uid, $shop_id, $order_status, $refund_status);
// 分页
$page = new Page();
$page->setTotalnum($count);
$page->setUrl($url.'/page/');
$curpage = $this->get('page')>0 ? $this->get('page') : 1;
$page->setPage($curpage);
$pagesize = $page->pagesize = 50;
$this->view['page_list'] = $page->getPageList();
$this->view['curpage'] = $curpage;
if ($curpage > 1) $this->view['prev_page'] = $page->url . ($curpage - 1); //上一页连接
if ($curpage < $page->totalpage) $this->view['post_page'] = $page->url . ($curpage + 1); //下一页连接
//只取出当前页显示
$list = $obj->getOrderList($uid, $shop_id, $order_status, $refund_status, $curpage, $pagesize);
$this->view['list'] = $list ? $list : array();
}
public function export_wait_deliver_goods_tids() {
$shopinfo = $this->get_shopinfo();
$uid = $shopinfo['uid'];
$shop_id = $shopinfo['id'];
$obj = new mOrder();
$filedir = APP_TMEPPATH_WAIT_DELIVER_GOODS_CSV;
if(!is_dir($filedir)) {
mkdir($filedir, 0755, true);
chown($filedir, 'nobody');
chgrp($filedir, 'nobody');
}
$filepath = $filedir."{$uid}_{$shop_id}_".date("YmdHis").".csv";
$file = fopen($filepath, 'w');
fwrite($file, "订单号\t\n");
fwrite($file, "order_sn\t\n");
for ($page=1;;$page++) {
$list = $obj->getOrderList($uid, $shop_id, ORDER_STATUS_WAIT_DELIVER_GOODS, REFUND_STATUS_NO_AFTER_SALES, $page, 1000);
if (empty($list)) break;
foreach ($list as $info) {
fwrite($file, $info['order_sn']."\t\n");
}
}
fclose($file);
$obj->downFileChunk($filepath, $shopinfo['name'].'_待发货订单.csv');
exit();
}
}

26
data/dBase.php

@ -819,6 +819,32 @@ class dBase extends publicBase {
}
}
public function array2whereSql($array) {
if(empty($array)) return array();
$fields = array_keys($array);
$where['vals'] = array_values($array);
foreach ($fields as $field) {
// 支持非等号比较符号
$allow_symbols = array('!=', '>=', '<=', '>', '<', '=');
$i=0;
foreach ($allow_symbols as $symbol) {
$pos=strpos($field, $symbol);
if($pos!==false) {
$field = substr($field, 0, $pos);
$i++;
break;
}
}
if($i==0) $symbol = '=';
$where['sql'] .= " AND `{$field}`{$symbol}?";
}
$where['sql'] = substr($where['sql'], 4);
return $where;
}
/**
* 解析数据库配置信息

2
data/dGoods.php

@ -12,6 +12,8 @@ class dGoods extends dBase {
'goods_name',
'goods_price',
'shop_id',
'sku_id',
'sku_name',
'uid'
),
);

1
data/dUser.php

@ -8,6 +8,7 @@ class dUser extends dBase {
protected $fieldlist = array(
'user_list' => array(
'id',
'status',
),
);

194
index.php

@ -1,117 +1,133 @@
<?php
include_once(dirname(__FILE__)."/library/publicBase.php");
class run extends publicBase {
public $control_name;
public $control_func;
include_once(dirname(__FILE__)."/library/publicBase.php");
public function __construct() {
$this->beforecheckpara();
$this->checkpara();
$this->action();
$this->display();
}
class run extends publicBase {
public $control_name;
public $control_func;
private function beforecheckpara() {
$url = trim(trim($_GET['argv']), '/');
public function __construct() {
session_start();
$this->checkpara();
$this->aftercheckpara();
$this->action();
$this->display();
}
$func_uri = explode('/', $url);
private function checkpara() {
$argv = trim(trim($_GET['argv']),'/');
if(empty($argv)) {
$this->control_name = 'agent';
$this->control_func = 'demand_list';
} else {
$array = explode('/', $argv);
$this->control_name = $array[0] == '' ? 'agent' : $array[0];
$this->control_func = $array[1] == '' ? 'demand_list' : $array[1];
}
$_GET['argv'] = 'api/_api_' . $url;
// 还原GET
if(!empty($array)) {
unset($_GET['argv']);
unset($array[0]);
unset($array[1]);
$this->para['viewFormat'] = 'json';
$count = count($array);
for($i=1;$i<=$count/2;$i++) {
$_GET[$array[$i*2]] = $array[$i*2+1];
}
}
private function checkpara() {
$argv = trim(trim($_GET['argv']),'/');
if(empty($argv)) {
$this->control_name = 'index';
$this->control_func = 'home';
} else {
$array = explode('/', $argv);
$this->control_name = $array[0];
$this->control_func = $array[1]=='' ? 'home' : $array[1];
// 如果URI带有常规传参形式,并入$_GET
$pos = strpos($_SERVER['REQUEST_URI'], '?');
if($pos!==false) {
$new_uri = substr($_SERVER['REQUEST_URI'], $pos+1);
$new_uri_arr = explode("&", $new_uri);
foreach($new_uri_arr as $v) {
$new_para = explode("=", $v);
$_GET[$new_para[0]] = $new_para[1];
}
}
}
// 还原GET
if(!empty($array)) {
unset($_GET['argv']);
unset($array[0]);
unset($array[1]);
private function aftercheckpara() {
$no_login_list = array('callback');
$is_need_login = in_array($this->control_name, $no_login_list) ? false : true;
$count = count($array);
for($i=1;$i<=$count/2;$i++) {
$_GET[$array[$i*2]] = $array[$i*2+1];
}
}
if (!$is_need_login) return true;
// 如果URI带有常规传参形式,并入$_GET
$pos = strpos($_SERVER['REQUEST_URI'], '?');
if($pos!==false) {
$new_uri = substr($_SERVER['REQUEST_URI'], $pos+1);
$new_uri_arr = explode("&", $new_uri);
foreach($new_uri_arr as $v) {
$new_para = explode("=", $v);
$_GET[$new_para[0]] = $new_para[1];
}
}
$app_uid = $_SESSION['app_uid'];
$app_name = $_SESSION['app_name'];
//代理登陆检查
if (empty($app_uid) || empty($app_name)) {
header('Location:/login/login');
exit;
}
private function action() {
$control_func = empty($this->control_func) ? 'home' : $this->control_func;
$sobj = new mShop();
$shopinfo = $sobj->getShopByName($app_name);
if (empty($shopinfo)) {
header('Location:/login/login');
exit;
}
// 判断控制层文件是否存在
$control_path = dirname(__FILE__).'/control/'.$this->control_name.'.php';
if(!file_exists($control_path)) {
die('/'.$this->control_name.'.php not exist.');
}
include_once ($control_path);
// 判断控制层方法是否存在
$obj = new $this->control_name;
##如下根据情况传递公共变量值##################
if (is_array($this->para)) {
foreach ($this->para as $k=>$v) {
$func = 'set' . $k;
$obj->$func($v);
}
}
##如上根据情况传递公共变量值##################
if (method_exists($obj, $control_func)) {
$res = $obj->$control_func();
} else {
die('method '.$this->control_func.' not exist.');
}
$this->view['_shopinfo'] = $this->para['_shopinfo'] = $shopinfo;
}
if($obj->getViewFormat()=='json' && $res===false) {
echo urldecode($obj->getError());
exit;
}
private function action() {
$control_func = empty($this->control_func) ? 'admin' : $this->control_func;
$this->view = array_merge($this->view, $obj->getView());
$this->viewFormat = $obj->getViewFormat();
$this->viewTpl = $obj->getViewTpl();
// 判断控制层文件是否存在
$control_path = dirname(__FILE__).'/control/'.$this->control_name.'.php';
if(!file_exists($control_path)) {
die('class '.$this->control_name.' not exist.');
}
include_once ($control_path);
// 判断控制层方法是否存在
$obj = new $this->control_name;
private function display() {
if($this->viewFormat=='json') {
$display = new DisplayJson();
} elseif($this->viewFormat=='string') {
$display = new DisplayNone();
} else {
$tpl_path = $this->viewTpl=='' ? $this->control_name.'/'.$this->control_func.'.html' : $this->viewTpl;
if(!file_exists(dirname(__FILE__) . '/view/templates/'.$tpl_path)) { // 判断模板是否存在
die("{$tpl_path} not exist.");
}
$display = new DisplaySmarty($tpl_path);
##如下根据情况传递公共变量值##################
if (is_array($this->para)) {
foreach ($this->para as $k=>$v) {
$func = 'set' . $k;
$obj->$func($v);
}
}
##如上根据情况传递公共变量值##################
if (method_exists($obj, $control_func)) {
$res = $obj->$control_func();
} else {
die('method '.$this->control_func.' not exist.');
}
$display->setView($this->view);
$display->execute();
if($obj->getViewFormat()=='json' && $res===false) {
echo urldecode($obj->getError());
exit;
}
$this->view = array_merge($this->view, $obj->getView());
$this->viewFormat = $obj->getViewFormat();
$this->viewTpl = $obj->getViewTpl();
}
new run();
private function display() {
if($this->viewFormat=='json') {
$display = new DisplayJson();
} elseif($this->viewFormat=='string') {
$display = new DisplayNone();
} else {
$tpl_path = $this->viewTpl=='' ? $this->control_name.'/'.$this->control_func.'.html' : $this->viewTpl;
if(!file_exists(dirname(__FILE__) . '/view/templates/'.$tpl_path)) { // 判断模板是否存在
echo dirname(__FILE__) . '/view/templates/'.$tpl_path;
die("{$tpl_path} not exist.");
}
$display = new DisplaySmarty($tpl_path);
}
$display->setView($this->view);
$display->execute();
}
}
new run();

300
library/pinduoduo/pdd_api.php

@ -0,0 +1,300 @@
<?php
/**
* https://mobile.yangkeduo.com/goods1.html?goods_id=256762212601
*
* @author GavinLau
*
*/
class PDD {
private $request_url = 'https://gw-api.pinduoduo.com/api/router';
private $request_headers = array('content-type: application/json');
private $request_timeout = 60;
private $sign = ''; // 必填参数 API入参参数签名,签名值根据如下算法给出计算过程
private $version = 'V1'; // 非必填参数 API版本,默认为V1,无要求不传此参数
public $data_type = 'JSON'; // 非必填参数 请求返回的数据格式,可选参数为XML或JSON,默认为JSON
public $client_id = ''; // 必填参数 已创建成功的应用标志client_id,可在应用详情和中查看
public $client_secret;
public $access_token = ''; // 非必填参数 用户授权令牌access_token,通过pdd.pop.auth.token.create获取
public function __construct($client_id, $client_secret, $access_token=null) {
$this->client_id = $client_id;
$this->client_secret = $client_secret;
if ($access_token !== null) $this->access_token = $access_token;
}
/**
* 获取授权url
*
* 授权说明 https://open.pinduoduo.com/application/document/browse?idStr=BD3A776A4D41D5F5
* @param unknown $redirect_uri
* @param unknown $state
*/
public function getWebAuthUrl($redirect_uri, $state) {
return "https://fuwu.pinduoduo.com/service-market/auth?response_type=code&client_id=".$this->client_id."&redirect_uri={$redirect_uri}&state={$state}";
}
public function getAccessToken($code) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.pop.auth.token.create';
$params['code'] = $code;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
* 订单详情
* https://open.pinduoduo.com/application/document/api?id=pdd.order.information.get
*
* 查询单个订单详情(只能获取到成交时间三个月以内的交易信息)
* {"order_info_get_response":{"request_id":"16547568855546893","order_info":{"support_nationwide_warranty":0,"country":"中国","group_status":1,"free_sf":0,"discount_amount":0.0,"platform_discount":0.0,"return_freight_payer":0,"order_status":1,"id_card_num":"","risk_control_status":0,"province":"","town_id":0,"item_list":[{"goods_name":"checkpass论文查重无限次数低价免注册查重","outer_goods_id":"","goods_price":1.0,"goods_id":329073007863,"sku_id":1115504481445,"goods_count":1,"goods_spec":"千字符","outer_id":"","goods_img":"https://img.pddpic.com/mms-material-img/2022-03-28/0c075d33-b036-46f7-a0bf-d40774f68190.png.a.jpeg"}],"pay_no":"","last_ship_time":"2022-06-11 14:37:23","delivery_one_day":0,"created_time":"2022-06-09 14:37:14","card_info_list":[],"refund_status":1,"town":"","is_stock_out":0,"receiver_address_mask":"","receive_time":"","pay_time":"2022-06-09 14:37:23","gift_list":[],"capital_free_discount":0.0,"receiver_phone_mask":"13*******67","country_id":0,"city_id":0,"invoice_status":0,"service_fee_detail":[],"city":"","order_tag_list":[{"name":"delivery_one_day","value":0},{"name":"no_trace_delivery","value":0},{"name":"self_contained","value":0},{"name":"return_freight_payer","value":0},{"name":"free_sf","value":0},{"name":"duoduo_wholesale","value":0},{"name":"support_nationwide_warranty","value":0},{"name":"only_support_replace","value":0},{"name":"oversea_tracing","value":0},{"name":"distributional_sale","value":0},{"name":"open_in_festival","value":0},{"name":"same_city_distribution","value":0},{"name":"region_black_delay_shipping","value":0},{"name":"has_subsidy_postage","value":0},{"name":"has_sf_express_service","value":0},{"name":"community_group","value":0},{"name":"has_ship_additional","value":0},{"name":"ship_additional_order","value":0}],"is_lucky_flag":1,"yyps_time":"","mkt_biz_type":0,"shipping_type":0,"remark":"","pre_sale_time":"","inner_transaction_id":"","order_change_amount":0.0,"only_support_replace":0,"logistics_id":0,"updated_at":"2022-06-09 14:37:33","street":"","receiver_name_mask":"","receiver_name":"","tracking_number":"","pay_type":"","duoduo_wholesale":0,"buyer_memo":"","is_pre_sale":0,"shipping_time":"","home_delivery_type":0,"after_sales_status":0,"address":"","id_card_name":"","self_contained":0,"goods_amount":1.0,"pay_amount":1.0,"seller_discount":0.0,"address_mask":"","yyps_date":"","confirm_status":1,"confirm_time":"2022-06-09 14:37:23","stock_out_handle_status":-1,"postage":0.0,"province_id":0,"cat_id_3":9056,"cat_id_4":0,"cat_id_1":8726,"receiver_address":"","cat_id_2":8786,"trade_type":0,"urge_shipping_time":"","receiver_phone":"$3MpaxbKBnse9$AgAAAAF2+qYGan7+ggANYOk6e6B2tcD3m4NUAgu6bY4=$0$$","order_sn":"220609-635730697112661"}}}
*
* 注:虚拟订单充值手机号信息无法通过此接口获取,请联系虚拟类目运营人员。
* @param unknown $order_sn
* @return boolean|mixed
*/
public function getOrderInformation($order_sn) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.order.information.get';
$params['order_sn'] = $order_sn;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
// /**
// * 商品明细
// * https://open.pinduoduo.com/application/document/api?id=pdd.goods.detail.get
// *
// * @param unknown $goods_id 商品id
// *
// */
// public function getGoodsDetailInfo($goods_id) {
// $params = $this->getPublicParams();
// $params['type'] = 'pdd.goods.detail.get';
// $params['goods_id'] = $goods_id;
// $params['sign'] = $this->getSignature($params);
// return $this->postRequest(json_encode($params));
// }
/**
* 商品详情接口
* https://open.pinduoduo.com/application/document/api?id=pdd.goods.information.get
*
* @param unknown $goods_id
*
* {"goods_info_get_response":{"goods_info":{"goods_name":"万方查重万方数据官网本科硕士博士毕业论文查重论文检测系统2.0","last_category":"论文检测与查询","image_url":"","shipment_limit_second":"172800","goods_quantity":422621,"goods_id":"329073140054","goods_sn":"329073140054","goods_category":"教育培训","is_onsale":"1","is_refundable":"0","second_hand":0,"sku_list":[{"single_price":"3.35","sku_img":"https://img.pddpic.com/mms-material-img/2022-02-27/3622095f-10d0-4a3f-9a2c-51aaa811e08c.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1106921187393","group_price":"2.35","outer_id":"","spec":"保证正品支持真伪验证","sku_quantity":"0"},{"single_price":"30.00","sku_img":"https://img.pddpic.com/mms-material-img/2022-02-27/12c136b0-e0be-4508-91c6-cb2ded66aa5f.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1115835177591","group_price":"25.00","outer_id":"","spec":"万方本科版(高校大学生毕业论文检测)","sku_quantity":"21509"},{"single_price":"30.00","sku_img":"https://img.pddpic.com/mms-material-img/2022-02-27/549d0277-1835-41f9-b9f7-320f6591b9ea.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1115835177592","group_price":"25.00","outer_id":"","spec":"万方硕博版(高校硕博研究生论文检测)","sku_quantity":"21538"},{"single_price":"3.60","sku_img":"https://img.pddpic.com/mms-material-img/2022-02-27/45e5a82b-4921-4686-98c6-2badf65a2789.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1119777051922","group_price":"2.60","outer_id":"","spec":"万方通用版(期刊作业报告等)","sku_quantity":"54166"},{"single_price":"6.00","sku_img":"https://img.pddpic.com/mms-material-img/2022-02-27/d21eb099-7318-432e-9303-fdb861b6e2ba.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1119949041761","group_price":"5.00","outer_id":"","spec":"万方职称版(已发表职称评定检测)","sku_quantity":"325408"}],"goods_type":"1","group_required_customer_num":"2"},"request_id":"16547602950483034"}}
*/
public function getGoodsInformation($goods_id) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.goods.information.get';
$params['goods_id'] = $goods_id;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
*
* 商品名称模糊查询
*
* 商品列表接口
* https://open.pinduoduo.com/application/document/api?id=pdd.goods.list.get
* {"goods_list_get_response":{"goods_list":[{"is_more_sku":1,"goods_name":"checkpass论文查重无限次数低价免注册查重","thumb_url":"https://img.pddpic.com/gaudit-image/2022-03-28/edac0af376a509b227714488bd5dfa37.jpeg","goods_reserve_quantity":0,"image_url":"","sku_list":[{"outer_goods_id":"","is_sku_onsale":1,"reserve_quantity":0,"sku_id":1115504481445,"outer_id":"","spec":"千字符","sku_quantity":1277},{"outer_goods_id":"","is_sku_onsale":1,"reserve_quantity":0,"sku_id":1115476736663,"outer_id":"","spec":"无限次数","sku_quantity":1495}],"goods_quantity":2772,"goods_id":329073007863,"is_onsale":1}],"total_count":1,"request_id":"16551061312578732"}}
*
* @param unknown $goods_name
* @param number $page 返回页码 默认 1,页码从 1 开始PS:当前采用分页返回,数量和页数会一起传,如果不传,则采用 默认值
* @param number $page_size 返回数量,默认 100,最大100。
* @return boolean|mixed
*/
public function getGoodsList($goods_name, $page=1, $page_size=100) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.goods.list.get';
$params['goods_name'] = $goods_name;
$params['page'] = $page;
$params['page_size'] = $page_size;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
* 批量获取订单状态
*
*
* 订单状态
* https://open.pinduoduo.com/application/document/api?id=pdd.order.status.get
* {"order_status_get_response":{"request_id":"16552754937789430","order_status_list":[{"order_status":2,"refund_status":4,"orderSn":"220614-336705627082662"},{"order_status":1,"refund_status":4,"orderSn":"220614-170641387082662"},{"order_status":1,"refund_status":4,"orderSn":"220614-321700576842662"}]}}
*
* @param unknown $order_sns 0150909-452750051,20150909-452750134 用逗号分开
* @return boolean|mixed
*/
public function getOrderStatus($order_sns) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.order.status.get';
$params['order_sns'] = $order_sns;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
* 订单列表查询接口(根据成交时间)
* https://open.pinduoduo.com/application/document/api?id=pdd.order.list.get
*
* @param unknown $start_confirm_at 必填,成交时间开始时间的时间戳,指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数
* @param unknown $end_confirm_at 必填,成交时间结束时间的时间戳,指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数 PS:开始时间结束时间间距不超过 24 小时
* @param unknown $order_status 发货状态,1:待发货,2:已发货待签收,3:已签收 5:全部
* @param unknown $page 返回页码 默认 1,页码从 1 开始 PS:当前采用分页返回,数量和页数会一起传,如果不传,则采用 默认值
* @param unknown $page_size 返回数量,默认 100。最大 100
* @param unknown $refund_status 售后状态 1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功 5:全部
* @param unknown $trade_type 非必填 订单类型 0-普通订单 ,1- 定金订单
* @param unknown $use_has_next 非必填 是否启用has_next的分页方式,如果指定true,则返回的结果中不包含总记录数,但是会新增一个是否存在下一页的的字段,通过此种方式获取增量交易,效率在原有的基础上有80%的提升
* @return boolean|mixed
*
* {"error_response":{"error_msg":"access_token已过期","sub_msg":"access_token已过期","sub_code":"10019","error_code":10019,"request_id":"16570185181360686"}}
* {"order_list_get_response":{"total_count":1,"has_next":false,"order_list":[{"support_nationwide_warranty":0,"country":"中国","group_status":1,"free_sf":0,"discount_amount":0.0,"platform_discount":0.0,"return_freight_payer":0,"order_status":1,"id_card_num":"","risk_control_status":0,"province":"","town_id":0,"item_list":[{"goods_name":"checkpass论文查重无限次数低价免注册查重","outer_goods_id":"","goods_price":2.0,"goods_id":329073007863,"sku_id":1115504481445,"goods_count":1,"goods_spec":"千字符","outer_id":"","goods_img":"https://img.pddpic.com/mms-material-img/2022-03-28/0c075d33-b036-46f7-a0bf-d40774f68190.png.a.jpeg"}],"pay_no":"","last_ship_time":"2022-07-07 18:59:01","delivery_one_day":0,"created_time":"2022-07-05 18:58:41","card_info_list":[],"refund_status":1,"town":"","is_stock_out":0,"receiver_address_mask":"","receive_time":"","pay_time":"2022-07-05 18:59:01","gift_list":[],"capital_free_discount":0.0,"receiver_phone_mask":"13*******67","country_id":0,"city_id":0,"invoice_status":0,"service_fee_detail":[],"city":"","order_tag_list":[{"name":"delivery_one_day","value":0},{"name":"no_trace_delivery","value":0},{"name":"self_contained","value":0},{"name":"return_freight_payer","value":0},{"name":"free_sf","value":0},{"name":"duoduo_wholesale","value":0},{"name":"support_nationwide_warranty","value":0},{"name":"only_support_replace","value":0},{"name":"oversea_tracing","value":0},{"name":"distributional_sale","value":0},{"name":"open_in_festival","value":0},{"name":"same_city_distribution","value":0},{"name":"region_black_delay_shipping","value":0},{"name":"has_subsidy_postage","value":0},{"name":"has_sf_express_service","value":0},{"name":"community_group","value":0},{"name":"has_ship_additional","value":0},{"name":"ship_additional_order","value":0},{"name":"conso_order","value":0}],"is_lucky_flag":1,"yyps_time":"","mkt_biz_type":0,"shipping_type":0,"remark":"","pre_sale_time":"","inner_transaction_id":"","order_change_amount":0.0,"only_support_replace":0,"logistics_id":0,"updated_at":"2022-07-05 18:59:11","street":"","receiver_name_mask":"","receiver_name":"","tracking_number":"","pay_type":"","duoduo_wholesale":0,"buyer_memo":"","is_pre_sale":0,"shipping_time":"","home_delivery_type":0,"after_sales_status":0,"address":"","id_card_name":"","self_contained":0,"goods_amount":2.0,"pay_amount":2.0,"seller_discount":0.0,"address_mask":"","yyps_date":"","confirm_status":1,"confirm_time":"2022-07-05 18:59:01","stock_out_handle_status":-1,"postage":0.0,"province_id":0,"cat_id_3":9056,"cat_id_4":0,"cat_id_1":8726,"receiver_address":"","cat_id_2":8786,"trade_type":0,"urge_shipping_time":"","receiver_phone":"$u9upNmQ5775n$AgAAAAGFtKUGQpF/UwCIGc9XLGYcE0AFeoGvJNLo1wk=$0$$","order_sn":"220705-189933833112661"}],"request_id":"16570188342965892"}}
*/
public function getOrderList($start_confirm_at, $end_confirm_at, $order_status, $refund_status, $page, $page_size, $trade_type=-1, $use_has_next=true) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.order.list.get';
$params['start_confirm_at'] = $start_confirm_at;
$params['end_confirm_at'] = $end_confirm_at;
$params['order_status'] = $order_status;
$params['refund_status'] = $refund_status;
$params['page'] = $page;
$params['page_size'] = $page_size;
$params['use_has_next'] = $use_has_next;
if ($trade_type > -1) $params['trade_type'] = $trade_type;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
* 订单增量接口
* https://open.pinduoduo.com/application/document/api?id=pdd.order.number.list.increment.get
*
* @param unknown $start_updated_at 必填,最后更新时间开始时间的时间戳,指格林威治时间 1970 年01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数
* @param unknown $end_updated_at 必填,最后更新时间结束时间的时间戳,指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数 PS:开始时间结束时间间距不超过 30 分钟
* @param unknown $order_status 发货状态,1:待发货,2:已发货待签收,3:已签收 5:全部
* @param unknown $page 返回页码,默认 1,页码从 1 开始 PS:当前采用分页返回,数量和页数会一起传,如果不传,则采用 默认值;注:必须采用倒序的分页方式(从最后一页往回取)才能避免漏单问题。
* @param unknown $page_size 返回数量,默认 100。最大 100
* @param unknown $refund_status 售后状态 1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功 5:全部
* @param unknown $is_lucky_flag 订单类型(是否抽奖订单),0-全部,1-非抽奖订单,2-抽奖订单
* @param unknown $trade_type 非必填 订单类型 0-普通订单 ,1- 定金订单
* @param unknown $use_has_next 非必填 是否启用has_next的分页方式,如果指定true,则返回的结果中不包含总记录数,但是会新增一个是否存在下一页的的字段,通过此种方式获取增量交易,效率在原有的基础上有80%的提升
* @return boolean|mixed
*
* {"error_response":{"error_msg":"access_token已过期","sub_msg":"access_token已过期","sub_code":"10019","error_code":10019,"request_id":"16570185181360686"}}
* {"order_list_get_response":{"total_count":1,"has_next":false,"order_list":[{"support_nationwide_warranty":0,"country":"中国","group_status":1,"free_sf":0,"discount_amount":0.0,"platform_discount":0.0,"return_freight_payer":0,"order_status":1,"id_card_num":"","risk_control_status":0,"province":"","town_id":0,"item_list":[{"goods_name":"checkpass论文查重无限次数低价免注册查重","outer_goods_id":"","goods_price":2.0,"goods_id":329073007863,"sku_id":1115504481445,"goods_count":1,"goods_spec":"千字符","outer_id":"","goods_img":"https://img.pddpic.com/mms-material-img/2022-03-28/0c075d33-b036-46f7-a0bf-d40774f68190.png.a.jpeg"}],"pay_no":"","last_ship_time":"2022-07-07 18:59:01","delivery_one_day":0,"created_time":"2022-07-05 18:58:41","card_info_list":[],"refund_status":1,"town":"","is_stock_out":0,"receiver_address_mask":"","receive_time":"","pay_time":"2022-07-05 18:59:01","gift_list":[],"capital_free_discount":0.0,"receiver_phone_mask":"13*******67","country_id":0,"city_id":0,"invoice_status":0,"service_fee_detail":[],"city":"","order_tag_list":[{"name":"delivery_one_day","value":0},{"name":"no_trace_delivery","value":0},{"name":"self_contained","value":0},{"name":"return_freight_payer","value":0},{"name":"free_sf","value":0},{"name":"duoduo_wholesale","value":0},{"name":"support_nationwide_warranty","value":0},{"name":"only_support_replace","value":0},{"name":"oversea_tracing","value":0},{"name":"distributional_sale","value":0},{"name":"open_in_festival","value":0},{"name":"same_city_distribution","value":0},{"name":"region_black_delay_shipping","value":0},{"name":"has_subsidy_postage","value":0},{"name":"has_sf_express_service","value":0},{"name":"community_group","value":0},{"name":"has_ship_additional","value":0},{"name":"ship_additional_order","value":0},{"name":"conso_order","value":0}],"is_lucky_flag":1,"yyps_time":"","mkt_biz_type":0,"shipping_type":0,"remark":"","pre_sale_time":"","inner_transaction_id":"","order_change_amount":0.0,"only_support_replace":0,"logistics_id":0,"updated_at":"2022-07-05 18:59:11","street":"","receiver_name_mask":"","receiver_name":"","tracking_number":"","pay_type":"","duoduo_wholesale":0,"buyer_memo":"","is_pre_sale":0,"shipping_time":"","home_delivery_type":0,"after_sales_status":0,"address":"","id_card_name":"","self_contained":0,"goods_amount":2.0,"pay_amount":2.0,"seller_discount":0.0,"address_mask":"","yyps_date":"","confirm_status":1,"confirm_time":"2022-07-05 18:59:01","stock_out_handle_status":-1,"postage":0.0,"province_id":0,"cat_id_3":9056,"cat_id_4":0,"cat_id_1":8726,"receiver_address":"","cat_id_2":8786,"trade_type":0,"urge_shipping_time":"","receiver_phone":"$u9upNmQ5775n$AgAAAAGFtKUGQpF/UwCIGc9XLGYcE0AFeoGvJNLo1wk=$0$$","order_sn":"220705-189933833112661"}],"request_id":"16570188342965892"}}
*/
public function getIncrementOrderNumberList($start_updated_at, $end_updated_at, $order_status, $refund_status, $page, $page_size, $is_lucky_flag=0, $trade_type=-1, $use_has_next=true) {
$params = $this->getPublicParams();
$params['type'] = 'pdd.order.number.list.increment.get';
$params['start_updated_at'] = $start_updated_at;
$params['end_updated_at'] = $end_updated_at;
$params['order_status'] = $order_status;
$params['refund_status'] = $refund_status;
$params['page'] = $page;
$params['page_size'] = $page_size;
$params['use_has_next'] = $use_has_next;
$params['is_lucky_flag'] = $is_lucky_flag;
if ($trade_type > -1) $params['trade_type'] = $trade_type;
$params['sign'] = $this->getSignature($params);
return $this->postRequest(json_encode($params));
}
/**
* 公共参数
*/
public function getPublicParams() {
$pub_params = array(
'client_id' => $this->client_id,
'timestamp' => time(),
'data_type' => $this->data_type,
'version' => $this->version,
);
if ($this->access_token) $pub_params['access_token'] = $this->access_token;
return $pub_params;
}
/**
* 签名
* https://open.pinduoduo.com/application/document/browse?idStr=8EC06C399636041E
* @param unknown $params
*/
public function getSignature($params) {
ksort($params);
$signstr = '';
foreach($params as $key => $val) {
$signstr .= "{$key}{$val}";
}
$signstr = $this->client_secret.$signstr.$this->client_secret;
$sign = strtoupper(md5($signstr));
return $sign;
}
/**
* POST REQUEST
* @param unknown $url
* @param unknown $data
* @param array $headers
* @param number $timeout
*/
public function postRequest($data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->request_headers);
//分析是否开启SSL加密
$ssl = substr($this->request_url, 0, 8) == 'https://' ? true : false;
if ($ssl) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
}
curl_setopt($ch, CURLOPT_URL, $this->request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->request_timeout);
$res = curl_exec($ch);
if(curl_error($ch)=='') {
curl_close($ch);
return $res;
}
curl_close($ch);
return false;
}
}

17
model/mGoods.php

@ -6,9 +6,26 @@ include_once(SERVER_ROOT."/model/mBase.php");
class mGoods extends mBase {
private $obj;
private $dataoods;
public function __construct() {
$this->obj = new dGoods();
$this->goods = 'goods_list';
}
public function addGoods($goods_id, $goods_name, $goods_price, $sku_id, $sku_name, $shop_id, $uid) {
$data = array();
$data['goods_id'] = $goods_id;
$data['goods_name'] = $goods_name;
$data['goods_price'] = $goods_price;
$data['sku_id'] = $sku_id;
$data['sku_name'] = $sku_name;
$data['shop_id'] = $shop_id;
$data['uid'] = $uid;
return $this->obj->insert($this->goods, $data);
}
}

137
model/mOrder.php

@ -6,9 +6,146 @@ include_once(SERVER_ROOT."/model/mBase.php");
class mOrder extends mBase {
private $obj;
private $order;
public function __construct() {
$this->obj = new dOrder();
$this->order = 'order_list';
}
public function addOrder($order_sn, $order_status, $refund_status, $pay_amount, $pay_time, $shop_id, $goods_id, $sku_id, $uid) {
$data = array();
$data['order_status'] = $order_status;
$data['refund_status'] = $refund_status;
$data['pay_amount'] = $pay_amount;
$data['pay_time'] = $pay_time;
$data['shop_id'] = $shop_id;
$data['goods_id'] = $goods_id;
$data['sku_id'] = $sku_id;
$data['uid'] = $uid;
$info = $this->getOrderBySn($order_sn);
if ($info) {
$res = $this->updateOrderBySn($order_sn, $data);
if (!$res) {
$this->setError('更新订单信息失败');
return false;
}
return $info['id'];
}
$data['order_sn'] = $order_sn;
return $this->obj->insert($this->order, $data);
}
public function getOrderBySn($order_sn) {
return $this->obj->select($this->order, array('sql'=>'`order_sn`=?', 'vals'=>array($order_sn)));
}
public function updateOrderBySn($order_sn, $data) {
return $this->obj->update($this->order, $data, array('sql'=>'`order_sn`=?', 'vals'=>array($order_sn)));
}
public function getOrdersCount($uid, $shop_id, $order_status=0, $refund_status=0) {
$where = array('sql'=>'1=1');
if ($uid) {
$where['sql'] .= ' and `uid`=?';
$where['vals'][] = $uid;
}
if ($shop_id) {
$where['sql'] .= ' and `shop_id`=?';
$where['vals'][] = $shop_id;
}
if ($order_status) {
$where['sql'] .= ' and `order_status`=?';
$where['vals'][] = $order_status;
}
if ($refund_status) {
$where['sql'] .= ' and `refund_status`=?';
$where['vals'][] = $refund_status;
}
return $this->obj->count($this->order, $where);
}
public function getOrderList($uid, $shop_id, $order_status=0, $refund_status=0, $page=1, $pagesize=100) {
$where = array('sql'=>'1=1');
if ($uid) {
$where['sql'] .= ' and `uid`=?';
$where['vals'][] = $uid;
}
if ($shop_id) {
$where['sql'] .= ' and `shop_id`=?';
$where['vals'][] = $shop_id;
}
if ($order_status) {
$where['sql'] .= ' and `order_status`=?';
$where['vals'][] = $order_status;
}
if ($refund_status) {
$where['sql'] .= ' and `refund_status`=?';
$where['vals'][] = $refund_status;
}
$start = ($page - 1) * $pagesize;
return $this->obj->selectAll($this->order, $where, 'pay_time desc', array($start, $pagesize));
}
public function getNotFinishedOrders() {
return $this->obj->selectAll($this->order, array('sql'=>'`order_status`!=? and `refund_status`!=?', 'vals'=>array(ORDER_STATUS_SIGNED_FOR, REFUND_STATUS_SUCC)));
}
public function getLastThirtyDaysOrderNum($uid, $shop_id) {
$start_date = date("Y-m-d", strtotime("-30 day"));
$sql = "select DATE_FORMAT(`pay_time`,'%Y-%m-%d') sale_day, count(*) as count from {$this->order} where `uid`={$uid} and `shop_id`={$shop_id} and `pay_time`>={$start_date}";
$list = $this->obj->execute($sql, true, true);
if (!$list) return array();
$date2count = array();
foreach ($list as $info) {
$date2count[$info['sale_day']] = $info['count'];
}
unset($list);
return $date2count;
}
public function addOrders($order_list, $shop_id, $uid) {
$goods_list = array();
foreach ($order_list as $order) {
$this->addOrder($order['order_sn'], $order['order_status'], $order['refund_status'], $order['pay_amount'], $order['pay_time'], $shop_id, $order['item_list'][0]['goods_id'], $order['item_list'][0]['sku_id'], $uid);
$g = array();
$g['goods_id'] = $order['item_list'][0]['goods_id'];
$g['goods_name'] = $order['item_list'][0]['goods_name'];
$g['goods_price'] = $order['item_list'][0]['goods_price'];
$g['sku_id'] = $order['item_list'][0]['sku_id'];
$g['sku_name'] = $order['item_list'][0]['goods_spec'];
$g['shop_id'] = $shop_id;
$g['uid'] = $uid;
$goods_list[] = $g;
}
$gobj = new mGoods();
foreach ($goods_list as $goods) {
$gobj->addGoods($goods['goods_id'], $goods['goods_name'], $goods['goods_price'], $goods['sku_id'], $goods['sku_name'], $goods['shop_id'], $goods['uid']);
}
return true;
}
}

86
model/mPage.php

@ -0,0 +1,86 @@
<?php
//include_once(dirname(dirname(__FILE__))."/publicBase.php");
class Page extends publicBase {
public $totalnum; // 总记录数[必填],例:$page->setTotalnum(100);
public $page; // 当前页码[必填]
public $url; // 分页URL[必填]
public $pagesize=100; // 每页记录数
public $viewpagenum=7; // 每页看到的页码数
public $virtualpage='...'; // 省略或跨越页码
public $totalpage;
//mysql表中数据量过多时采用的分页改造
public $first_page_url; //点击”首页“跳转链接
public $end_page_url; //点击”尾页“跳转链接
public $prev_page_url; //点击”上一页“跳转链接
public $next_page_url; //点击”下一页“跳转链接
public $endpage=false; //跳转到尾页标识
public $jump_to_page_url; //跳转到某一页链接
public $maxid; //点击上一页时 当前页面最大id
public $minid; //点击下一页时 当前页面最小id
/*
* $pageobj = new Page();
$pageobj->setTotalnum($totalnum);
$pageobj->setPage($page);
$pageobj->setPagesize($pagesize);
$pageobj->setUrl('/comment/black/page/');
$plist = $pageobj->getPageList();
*/
/*
listnum 显示页码数, 默认展示7页
*/
public function getPageList() {
$pagelist = array(); // 构造的翻页数据
$begin = $last = array(); // 开始,结尾数据
$totalpage = ceil($this->totalnum/$this->pagesize); // 总页数
$this->totalpage = $totalpage;
$middle_page = ceil($this->viewpagenum/2); // 每页中间页码值
if($this->page > $middle_page && $totalpage > $this->viewpagenum) { // 开头有...时
$begin[] = array('page' => 1, 'url' => $this->url . '1');
$begin[] = array('page' => $this->virtualpage, 'url' => '');
$firstpage = $totalpage-$this->viewpagenum+2;
$endpage = $totalpage;
if($totalpage-$this->page > $middle_page) { // 结尾也有...时
$last[$totalpage-1] = array('page' => $this->virtualpage, 'url'=>'');
$last[$totalpage] = array('page' => $totalpage, 'url' => $this->url . $totalpage);
$firstpage = $this->page-$middle_page+2;
$endpage = $this->page+$middle_page-2;
}
} elseif($totalpage-$this->page > $middle_page && $totalpage > $this->viewpagenum) { // 只有结尾的...时
$last[$totalpage-1] = array('page' => $this->virtualpage, 'url' => '');
$last[$totalpage] = array('page' => $totalpage, 'url' => $this->url . $totalpage);
$firstpage = 1;
$endpage = $this->viewpagenum-1;
} else { // 没有...时
$firstpage = 1;
$endpage = $totalpage;
}
// 中间页码数据
for ($i=$firstpage; $i<=$endpage; $i++) {
$pagelist[$i-1]['page'] = $i;
$pagelist[$i-1]['url'] = $this->url . $i;
}
return $begin + $pagelist + $last;
}
public function getLimitInfo() {
$this->first_page_url = $this->url."/page/1"; //首页链接
$this->end_page_url = $this->url."/end_page/1"; //尾页链接
$this->jump_to_page_url = $this->url."/jump_to_page"; //跳转到某一页
if($this->totalnum>0) $this->page = ceil($this->totalnum/$this->pagesize);
if ($this->page > 1 || $this->endpage) $this->prev_page_url = $this->url.'/page/'.($this->page-1).'/maxid/'.$this->maxid; //上一页连接
if (!$this->endpage) $this->next_page_url = $this->url.'/page/'.($this->page+1).'/minid/'.$this->minid; //下一页连接
}
}

260
model/mPdd.php

@ -0,0 +1,260 @@
<?php
/**
* 支付模型层
* @package model
*/
include_once(SERVER_ROOT."/model/mBase.php");
// 拼多多
include_once (SERVER_ROOT."/library/pinduoduo/pdd_api.php");
class mPdd extends mBase {
public function __construct() {
}
public function getPddAuthUrl() {
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET);
return $obj->getWebAuthUrl(PDD_REDIRECT_URI, PDD_AUTH_STATE);
}
public function getPddAccessToken($code) {
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET);
$res = $obj->getAccessToken($code);
$res = json_decode($res, true);
return $res['pop_auth_token_create_response'];
}
private function getPddToken($name='', $shop_id=0) {
if (empty($name) && empty($shop_id)) {
$this->setError('店铺id或店铺名称不能为空');
return false;
}
$obj = new mShop();
if ($name) {
$shopinfo = $obj->getShopByName($name);
} elseif ($shop_id) {
$shopinfo = $obj->getShopById($shop_id);
}
if (!$shopinfo) {
$this->setError('店铺信息不存在');
return false;
}
if (strtotime($shopinfo['expire_time']) < time()) {
$this->setError(false, '授权已过期');
return false;
}
return $shopinfo['access_token'];
}
/**
* 获取拼多多订单信息
* @param unknown $tid
* @param unknown $pay_id
*/
public function getPddOrderInfo($tid, $name) {
$access_token = $this->getPddToken($name);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$res = $obj->getOrderInformation($tid);
// {"order_info_get_response":{"request_id":"16547568855546893","order_info":{"support_nationwide_warranty":0,"country":"中国","group_status":1,"free_sf":0,"discount_amount":0.0,"platform_discount":0.0,"return_freight_payer":0,"order_status":1,"id_card_num":"","risk_control_status":0,"province":"","town_id":0,"item_list":[{"goods_name":"checkpass论文查重无限次数低价免注册查重","outer_goods_id":"","goods_price":1.0,"goods_id":329073007863,"sku_id":1115504481445,"goods_count":1,"goods_spec":"千字符","outer_id":"","goods_img":"https://img.pddpic.com/mms-material-img/2022-03-28/0c075d33-b036-46f7-a0bf-d40774f68190.png.a.jpeg"}],"pay_no":"","last_ship_time":"2022-06-11 14:37:23","delivery_one_day":0,"created_time":"2022-06-09 14:37:14","card_info_list":[],"refund_status":1,"town":"","is_stock_out":0,"receiver_address_mask":"","receive_time":"","pay_time":"2022-06-09 14:37:23","gift_list":[],"capital_free_discount":0.0,"receiver_phone_mask":"13*******67","country_id":0,"city_id":0,"invoice_status":0,"service_fee_detail":[],"city":"","order_tag_list":[{"name":"delivery_one_day","value":0},{"name":"no_trace_delivery","value":0},{"name":"self_contained","value":0},{"name":"return_freight_payer","value":0},{"name":"free_sf","value":0},{"name":"duoduo_wholesale","value":0},{"name":"support_nationwide_warranty","value":0},{"name":"only_support_replace","value":0},{"name":"oversea_tracing","value":0},{"name":"distributional_sale","value":0},{"name":"open_in_festival","value":0},{"name":"same_city_distribution","value":0},{"name":"region_black_delay_shipping","value":0},{"name":"has_subsidy_postage","value":0},{"name":"has_sf_express_service","value":0},{"name":"community_group","value":0},{"name":"has_ship_additional","value":0},{"name":"ship_additional_order","value":0}],"is_lucky_flag":1,"yyps_time":"","mkt_biz_type":0,"shipping_type":0,"remark":"","pre_sale_time":"","inner_transaction_id":"","order_change_amount":0.0,"only_support_replace":0,"logistics_id":0,"updated_at":"2022-06-09 14:37:33","street":"","receiver_name_mask":"","receiver_name":"","tracking_number":"","pay_type":"","duoduo_wholesale":0,"buyer_memo":"","is_pre_sale":0,"shipping_time":"","home_delivery_type":0,"after_sales_status":0,"address":"","id_card_name":"","self_contained":0,"goods_amount":1.0,"pay_amount":1.0,"seller_discount":0.0,"address_mask":"","yyps_date":"","confirm_status":1,"confirm_time":"2022-06-09 14:37:23","stock_out_handle_status":-1,"postage":0.0,"province_id":0,"cat_id_3":9056,"cat_id_4":0,"cat_id_1":8726,"receiver_address":"","cat_id_2":8786,"trade_type":0,"urge_shipping_time":"","receiver_phone":"$3MpaxbKBnse9$AgAAAAF2+qYGan7+ggANYOk6e6B2tcD3m4NUAgu6bY4=$0$$","order_sn":"220609-635730697112661"}}}
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
$order_info = $res['order_info_get_response']['order_info'];
// 成交状态:0:未成交、1:已成交、2:已取消
if ($order_info['confirm_status'] != 1) {
$confirm_status_desc = '';
if ($order_info['order_status'] == 0) $confirm_status_desc = '未成交';
if ($order_info['order_status'] == 2) $confirm_status_desc = '已取消';
$this->setError('当前订单 '.$tid.' 成交状态为'.$confirm_status_desc.',无法使用');
return false;
}
// 退款状态,枚举值:1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功
if ($order_info['refund_status'] != 1) {
$order_refund_status_desc = '';
if ($order_info['refund_status'] == 2) $order_refund_status_desc = '售后处理中';
if ($order_info['refund_status'] == 3) $order_refund_status_desc = '退款中';
if ($order_info['refund_status'] == 4) $order_refund_status_desc = '退款成功';
$this->setError('当前订单 '.$tid.' 售后('.$order_refund_status_desc.')状态,无法使用');
return false;
}
// 发货状态,枚举值:1:待发货,2:已发货待签收,3:已签收
if ($order_info['order_status'] != 1) {
$order_status_desc = '';
if ($order_info['order_status'] == 2) $order_status_desc = '已发货待签收';
if ($order_info['order_status'] == 3) $order_status_desc = '已签收';
$this->setError('当前订单 '.$tid.' 非待发货('.$order_status_desc.')状态,无法使用');
return false;
}
// 成团状态:0:拼团中、1:已成团、2:团失败
if ($order_info['group_status'] != 1) {
$group_status_desc = '';
if ($order_info['group_status'] == 0) $group_status_desc = '拼团中';
if ($order_info['group_status'] == 2) $group_status_desc = '团失败';
$this->setError('当前订单 '.$tid.' 成团状态为'.$group_status_desc.',无法使用');
return false;
}
// 售后状态 0:无售后 2:买家申请退款,待商家处理 3:退货退款,待商家处理 4:商家同意退款,退款中 5:平台同意退款,退款中 6:驳回退款,待买家处理 7:已同意退货退款,待用户发货 8:平台处理中 9:平台拒绝退款,退款关闭 10:退款成功 11:买家撤销 12:买家逾期未处理,退款失败 13:买家逾期,超过有效期 14:换货补寄待商家处理 15:换货补寄待用户处理 16:换货补寄成功 17:换货补寄失败 18:换货补寄待用户确认完成 21:待商家同意维修 22:待用户确认发货 24:维修关闭 25:维修成功 27:待用户确认收货 31:已同意拒收退款,待用户拒收 32:补寄待商家发货
if ($order_info['after_sales_status'] != 0) {
$this->setError('当前订单 '.$tid.' 售后中,无法使用');
return false;
}
// 是否为预售商品 1表示是 0表示否
if ($order_info['is_pre_sale'] == 1) {
$this->setError('当前订单 '.$tid.' 为预售商品,无法使用');
return false;
}
// goods_amount 商品金额(元)商品金额=商品销售价格*商品数量-订单改价折扣金额
// seller_discount 店铺优惠金额
// discount_amount 折扣金额(元)折扣金额=平台优惠+商家优惠+团长免单优惠金额
// pay_amount 支付金额(元)支付金额=商品金额-折扣金额+邮费+服务费
$payment = 0;
foreach($order_info['item_list'] as $item){
if($item['goods_price']+0 == 0) continue;
if($item['goods_count']+0 == 0) continue;
$payment = $item['goods_price'] * $item['goods_count'];
$order_info['numiid2num'][$item['goods_id']] = $item['goods_count'];
$order_info['numiid2skuid'][$item['goods_id']] = $item['sku_id'];
}
$order_info['payment'] = $order_info['goods_amount'];
$order_info['total_payment'] = $payment;
$order_info['num'] = $order_info['item_list'][0]['goods_count'];
return $order_info;
}
public function getPddGoodsList($goods_name, $name) {
$access_token = $this->getPddToken($name);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$res = $obj->getGoodsList($goods_name);
// {"goods_list_get_response":{"goods_list":[{"is_more_sku":1,"goods_name":"checkpass论文查重无限次数低价免注册查重","thumb_url":"https://img.pddpic.com/gaudit-image/2022-03-28/edac0af376a509b227714488bd5dfa37.jpeg","goods_reserve_quantity":0,"image_url":"","sku_list":[{"outer_goods_id":"","is_sku_onsale":1,"reserve_quantity":0,"sku_id":1115504481445,"outer_id":"","spec":"千字符","sku_quantity":1277},{"outer_goods_id":"","is_sku_onsale":1,"reserve_quantity":0,"sku_id":1115476736663,"outer_id":"","spec":"无限次数","sku_quantity":1495}],"goods_quantity":2772,"goods_id":329073007863,"is_onsale":1}],"total_count":1,"request_id":"16551061312578732"}}
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
return $res['goods_list_get_response']['goods_list'];
}
public function getPddGoodsInformation($goods_id, $name) {
$access_token = $this->getPddToken($name);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$res = $obj->getGoodsInformation($goods_id);
// {"goods_info_get_response":{"goods_info":{"goods_name":"checkpass论文查重无限次数低价免注册查重","last_category":"论文检测与查询","image_url":"","shipment_limit_second":"172800","goods_quantity":2772,"goods_id":"329073007863","goods_sn":"329073007863","goods_category":"教育培训","is_onsale":"1","is_refundable":"0","second_hand":0,"sku_list":[{"single_price":"12.00","sku_img":"https://img.pddpic.com/mms-material-img/2022-03-28/3cd06438-b959-42ac-936a-93c273367355.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1115476736663","group_price":"10.00","outer_id":"","spec":"无限次数","sku_quantity":"1495"},{"single_price":"2.00","sku_img":"https://img.pddpic.com/mms-material-img/2022-03-28/0c075d33-b036-46f7-a0bf-d40774f68190.png.a.jpeg","outer_goods_id":"","is_sku_onsale":"1","sku_id":"1115504481445","group_price":"1.00","outer_id":"","spec":"千字符","sku_quantity":"1277"}],"goods_type":"1","group_required_customer_num":"2"},"request_id":"16551080285427607"}}
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
return $res['goods_info_get_response']['goods_info'];
}
public function getPddOrderStatus($tids, $name='', $shopid=0) {
$access_token = $this->getPddToken($name, $shopid);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$res = $obj->getOrderStatus(implode(',', $tids));
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
return $res['order_status_get_response']['order_status_list'];
}
public function getPddOrderList($name, $start_date, $end_date, $order_status, $refund_status, $page=1, $page_size=100) {
$access_token = $this->getPddToken($name);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$start_confirm_at = strtotime($start_date);
$end_confirm_at = strtotime($end_date);
$res = $obj->getOrderList($start_confirm_at, $end_confirm_at, $order_status, $refund_status, $page, $page_size);
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
return $res['order_list_get_response'];
}
public function getPddIncrOrderList($name, $start_date, $end_date, $order_status, $refund_status, $page=1, $page_size=100) {
$access_token = $this->getPddToken($name);
if (!$access_token) {
$this->setError($this->getError());
return false;
}
$obj = new PDD(PDD_CLIENT_ID, PDD_CLIENT_SECRET, $access_token);
$start_updated_at = strtotime($start_date);
$end_updated_at = strtotime($end_date);
$res = $obj->getIncrementOrderNumberList($start_updated_at, $end_updated_at, $order_status, $refund_status, $page, $page_size);
$res = json_decode($res, true);
if (isset($res['error_response'])) {
$this->setError($res['error_response']['error_msg'].' '.$res['error_response']['sub_msg']);
return false;
}
return $res['order_sn_increment_get_response'];
}
}

28
model/mRedis.php

@ -0,0 +1,28 @@
<?php
/**
* redis模型层
* @package model
*/
class mRedis extends Redis{
// 实例
protected static $_instance = null;
/**
* Singleton instance(获取自己的实例)
*
* @return RedisOperate
*/
public static function getInstance($cnf) {
if (null === self::$_instance) {
self::$_instance = new self();
$res = self::$_instance->connect($cnf['host'], $cnf['port']);
if(!$res) {
$this->setError('redis_connect');
return false;
}
}
return self::$_instance;
}
}

77
model/mShop.php

@ -7,8 +7,85 @@ include_once(SERVER_ROOT."/model/mBase.php");
class mShop extends mBase {
private $obj;
private $shop;
public function __construct() {
$this->obj = new dShop();
$this->shop = 'shop_list';
}
public function addShop($name, $access_token, $expire_time, $uid=0) {
$data = array();
$data['access_token'] = $access_token;
$data['expire_time'] = $expire_time;
$info = $this->getShopByName($name);
if ($info) {
$res = $this->updateShop($info['id'], $data);
return $info;
}
if ($uid) {
$data['uid'] = $uid;
} else {
$uobj = new mUser();
$uid = $uobj->addUser();
var_dump($uid);
if (!$uid) {
$this->setError('uid创建失败');
return false;
}
$data['uid'] = $uid;
}
$data['name'] = $name;
$res = $this->obj->insert($this->shop, $data);
$this->syncHistoricalOrders($name);
$info = $this->getShopByName($name);
return $info;
}
/**
* 同步最近3个月历史订单
* @param unknown $name
* @return boolean
*/
public function syncHistoricalOrders($name) {
$rdobj = $this->initRedis();
$start_date = date("Y-m-d", strtotime('-3 month'));
for($i=0; $i<100; $i++) {
$date = date("Y-m-d", strtotime($start_date)+$i*86400);
if ($date > date("Y-m-d H:i:s")) break;
// 同步历史订单
$rdobj->lpush(_RQ_SYNC_HISTORICAL_ORDERS, json_encode(array('name'=>$name, 'start_date'=>$date)));
// 同步增量订单开始时间
if ($date == date("Y-m-d")) {
$rdobj->lpush(_RQ_SYNC_INCREMENT_ORDERS, json_encode(array('name'=>$name, 'start_date'=>date("Y-m-d H:i:s"))));
}
}
return true;
}
public function getShopByName($name) {
return $this->obj->select($this->shop, array('sql'=>'`name`=?', 'vals'=>array($name)));
}
public function getShopById($id) {
return $this->obj->select($this->shop, array('sql'=>'`id`=?', 'vals'=>array($id)));
}
public function updateShop($id, $data) {
return $this->obj->update($this->shop, $data, array('sql'=>'`id`=?', 'vals'=>array($id)));
}
}

8
model/mUser.php

@ -6,9 +6,17 @@ include_once(SERVER_ROOT."/model/mBase.php");
class mUser extends mBase {
private $obj;
private $user;
public function __construct() {
$this->obj = new dUser();
$this->user = 'user_list';
}
public function addUser() {
$data['status'] = USER_STATUS_VALID;
return $this->obj->insert($this->user, $data);
}
}

14
project_vhost.conf

@ -0,0 +1,14 @@
<VirtualHost *:80>
ServerName tid.checkcopy.com
# ServerAlias xxx
DocumentRoot /data1/www/order_processing
ErrorLog /var/log/httpd/order_processing-error_log
CustomLog /var/log/httpd/order_processing-access_log combined
RewriteEngine on
RewriteRule ^/images/(.*)$ /view/images/$1 [L]
RewriteRule ^/css/(.*)$ /view/css/$1 [L]
RewriteRule ^/js/(.*)$ /view/js/$1 [L]
RewriteRule ^(.*)$ /index.php?argv=$1 [L]
</VirtualHost>

45
queue/base/cronBase.php

@ -7,14 +7,11 @@
* @version 2.0 - 2011-11-25
* @package Daemon
*/
include_once(dirname(dirname(dirname(__FILE__)))."/library/publicBase.php");
date_default_timezone_set("Asia/Shanghai");
abstract class cronBase {
protected $process; // 队列进程列表,必选项
protected $procnumlist; // 队列进程数限制,必选项
protected $procnum = 0; // 默认启动进程数
protected $procnum = 1; // 默认启动进程数
protected $maxtimelist; // 队列进程最大执行时间限制列表
protected $maxtime = 480; // 队列一次循环的默认最长时间, 未自定义则该项有效, 超过该值进程将被杀死
protected $bin_php = '/usr/local/bin/php'; // php执行文件路径
@ -28,8 +25,8 @@ abstract class cronBase {
$this->path_conf = dirname(dirname(__FILE__))."/config/daemonconf.php";
include_once($this->path_conf);
$this->path_daemon = dirname(dirname(dirname(__FILE__))).'/queue/deal/';
$this->path_prochealth = dirname(dirname(dirname(__FILE__))).'/queue/cache/proc/deal_%s.txt';
$this->path_daemon = dirname(dirname(__FILE__)).'/deal/';
$this->path_prochealth = dirname(dirname(__FILE__)).'/cache/proc/deal_%s.txt';
$this->setPara();
$this->prepare();
@ -49,50 +46,50 @@ abstract class cronBase {
}
private function checkProc() {
$obj = new mBase();
$server_ip = $obj->getServerIp();
$rdobj = $obj->initRedis();
// 检测
foreach($this->process as $deal_flag => $proc) {
foreach($this->process as $k => $proc) {
$active_proc_codes = array();
// 搜集存活的进程号、数
$path_proc = $this->path_daemon.$proc;
$chk_shell = "ps -ef|grep '{$path_proc}'|grep -v grep|grep -v '\/bin\/sh'|awk -F ' ' '{print $2\" \"$10\" \"$11}'";
$maxtime = $this->maxtimelist[$deal_flag]+0>0 ? $this->maxtimelist[$deal_flag] : $this->maxtime;
$maxtime = $this->maxtimelist[$k]+0>0 ? $this->maxtimelist[$k] : $this->maxtime;
$zombieProcNum = 0;
$fp = @popen($chk_shell, 'r');
while (!feof($fp)) {
$buffer = fgets($fp, 4096);
$procinfo = explode(' ', trim($buffer));
$procid = $procinfo[0]+0;
$proc_code = is_numeric($procinfo[2]) ? $procinfo[2] : $procinfo[1]+0;
if($procid==0) continue;
// 杀死僵死进程
$lasttime = $rdobj->get(sprintf(_DAEMON_HEALTH, $server_ip, $deal_flag, $proc_code));
$file_prochealth = sprintf($this->path_prochealth, $proc_code.'_'.md5($path_proc));
if(file_exists($file_prochealth)) {
$lasttime_data = explode('|', file_get_contents($file_prochealth));
$lasttime = strtotime($lasttime_data[0]);
$nowtime = time();
}
if($lasttime === false || time()-$lasttime > $maxtime) {
if(!file_exists($file_prochealth) || ($nowtime-$lasttime > $maxtime)) {
system("/bin/kill -9 $procid");
error_log('['.date('Y-m-d H:i:s').']kill:'.$path_proc.'|'.$proc_code.'_'.md5($path_proc).'|'.time().'|'.$lasttime.'|'.$maxtime."\n", 3, dirname(dirname(__FILE__)).'/cache/proc/cron_track.log');
error_log('['.date('Y-m-d H:i:s').']kill:'.$path_proc.'|'.$proc_code.'_'.md5($path_proc).'|'.$nowtime.'|'.$lasttime.'|'.$maxtime."\n", 3, dirname(dirname(__FILE__)).'/cache/proc/cron_track.log');
$zombieProcNum++;
} else {
// 存活的进程
$active_proc_codes[] = $proc_code;
}
}
$procnum = $this->procnumlist[$deal_flag]+0>0 ? $this->procnumlist[$deal_flag] : $this->procnum;
$procnum = $this->procnumlist[$k]+0>0 ? $this->procnumlist[$k] : $this->procnum;
for($i=0;$i<$procnum;$i++) {
if(in_array($i, $active_proc_codes)) continue;
$this->proc_start[$deal_flag]['proc'] = $path_proc;
$this->proc_start[$deal_flag]['startnum'][] = $i;
$this->proc_start[$k]['proc'] = $path_proc;
$this->proc_start[$k]['startnum'][] = $i;
}
if($fp) @pclose($fp);
}
}
@ -101,11 +98,11 @@ abstract class cronBase {
private function startProc() {
// 启动队列
if(empty($this->proc_start)) return ;
foreach($this->proc_start as $deal_flag => $proc) {
foreach($this->proc_start as $k => $proc) {
if(empty($proc['startnum'])) continue;
foreach ($proc['startnum'] as $proc_code) {
$cmd = "{$this->bin_php} {$proc['proc']} {$deal_flag} {$proc_code} &";
$cmd = "{$this->bin_php} {$proc['proc']} {$proc_code} &";
//echo $cmd."\n";
//error_log('['.date('Y-m-d H:i:s').']startproc:'.$cmd."\n", 3, dirname(__FILE__).'/cron_track.log');
$fp = @popen($cmd, "r");

141
queue/base/dealBase.php

@ -10,11 +10,9 @@ set_time_limit(0);
include_once(dirname(dirname(dirname(__FILE__)))."/library/publicBase.php");
abstract class dealBase extends publicBase {
protected $processnum = 0; // 程序限制进程数,默认为1
protected $processnum = 1; // 程序限制进程数,默认为1
protected $is_while = true; // 是否无限循环,默认为是
protected $deal_sleep = 1; // 每执行一次后等待的时间,单位为妙,默认为1
protected $proc_code; // 当前队列自定义进程数号码标识
protected $server_ip;
private $path_conf; // 配置文件路径
private $path_proc; // 进程状态路径
@ -24,13 +22,12 @@ abstract class dealBase extends publicBase {
private $file_deal; // 队列文件路径
private $path_deal; // 队列文件路径(包含标识)
private $deal_flag=''; // 队列类别标识
private $proc_code; // 当前队列自定义进程数号码标识
private $close_path; // 开关标识文件
private $restart_server; // 重启服务
public function __construct() {
$this->path_conf = dirname(dirname(__FILE__))."/config/daemonconf.php";
$this->path_proc = dirname(dirname(dirname(__FILE__))).'/queue/cache/proc/deal_%s.txt';
$this->path_proc = dirname(dirname(__FILE__)).'/cache/proc/deal_%s.txt';
$this->close_path = dirname(dirname(__FILE__)).'/cache/proc/close.txt';
$this->file_deal = $_SERVER['SCRIPT_FILENAME'];
@ -47,22 +44,11 @@ abstract class dealBase extends publicBase {
include_once($this->path_conf);
$this->server_ip = $this->getServerIp();
$this->setPara();
if($this->processnum+0==0) $this->processnum = 1;
$this->collectVerifyMd5();
// 循环达到一定次数,重置最大进程数
$i=0;
do {
if($i == GET_DAEMON_MAXNUM_CYCLE_TIMES) $i=0;
if($i == 0) {
$obj = new mDaemon();
$this->processnum = $obj->getDaemonNum($this->server_ip, $this->deal_flag);
}
$this->setProcHealth();
if(file_exists($this->close_path)) {
sleep(10);
@ -70,13 +56,10 @@ abstract class dealBase extends publicBase {
}
$this->checkVerifyMd5();
if(!$this->cProcessNum()) exit("Process limit <{$this->processnum}>\n"); // 每次循环执行任务调用ps系统命令导致cpu使用过高
//if(!$this->cProcessNum()) exit("Process limit <{$this->processnum}>\n"); // 每次循环执行任务调用ps系统命令导致cpu使用过高
$this->deal();
sleep($this->deal_sleep);
$i++;
} while($this->is_while);
return;
}
@ -92,10 +75,6 @@ abstract class dealBase extends publicBase {
$this->conf_md5 = md5_file($this->path_conf);
$this->deal_md5 = md5_file($this->file_deal);
$this->base_md5 = md5_file(__FILE__);
$obj = new mBase();
$rdobj = $obj->initRedis();
$this->restart_server = $rdobj->get(sprintf(_RD_RESTART_SERVER, $this->server_ip));
}
/* 校验三个文件是否修改,如修改,退出 */
@ -103,11 +82,6 @@ abstract class dealBase extends publicBase {
if($this->conf_md5 != md5_file($this->path_conf)) exit("daemon conf file modified.\n");
if($this->deal_md5 != md5_file($this->file_deal)) exit("deal file modified.\n");
if($this->base_md5 != md5_file(__FILE__)) exit("base class file modified.\n");
$obj = new mBase();
$rdobj = $obj->initRedis();
$restart_server = $rdobj->get(sprintf(_RD_RESTART_SERVER, $this->server_ip));
if($this->restart_server != $restart_server) exit("restart server.\n");
}
/**
@ -116,10 +90,17 @@ abstract class dealBase extends publicBase {
* @return boolean
*/
protected function setProcHealth() {
$obj = new mBase();
$rdobj = $obj->initRedis();
$res = $rdobj->set(sprintf(_DAEMON_HEALTH, $this->server_ip, $this->deal_flag, $this->proc_code), time());
return true;
$proc_path = sprintf($this->path_proc, $this->proc_code.'_'.md5($this->path_deal));
$handle = fopen($proc_path, 'w');
if(!$handle) {
return false;
}
$content = date('Y-m-d H:i:s').'|'.$this->path_deal;
if(!fwrite($handle, $content)) {
return false;
}
fclose($handle);
}
/**
@ -129,14 +110,20 @@ abstract class dealBase extends publicBase {
*/
private function cProcessNum() {
if($this->proc_code+1>$this->processnum) {
$obj = new mBase();
$rdobj = $obj->initRedis();
$is_exist = $rdobj->get(sprintf(_RD_UP_DOWN, $this->server_ip, $this->deal_flag, $this->proc_code));
if($is_exist) return true;
//error_log('['.date('Y-m-d H:i:s').']'.$this->proc_code."|procnum:{$this->processnum}\n", 3, dirname(__FILE__).'/deal_track.log');
return false;
}
$cmd = "ps -ef | grep '{$this->path_deal} {$this->proc_code}' | grep -v grep | grep -v '\/bin\/sh' | grep -v 'sh -c' | wc -l";
$rcmd = @popen($cmd, 'r');
$num = @fread($rcmd, 512);
$num += 0;
@pclose($rcmd);
if($num > $this->processnum) {
//error_log('['.date('Y-m-d H:i:s').']procnum:'."$num|{$this->processnum}|$cmd\n", 3, dirname(__FILE__).'/deal_track.log');
return false;
}
return true;
}
@ -164,79 +151,5 @@ abstract class dealBase extends publicBase {
return true;
}
/**
* 获取上传/下载任务
* @param unknown $task_key
* @param unknown $auto_type // 0上传 1下载
*/
public function getTask($task_key, $auto_type=0) {
$obj = new mBase();
$robj = $obj->initRedis();
// 该进程是否存在上次未处理完的任务
$proc_key = sprintf(_RD_UP_DOWN, $this->server_ip, $this->deal_flag, $this->proc_code);
$sale_id = $robj->get($proc_key);
if($sale_id==false) {
// 不存在未处理完的任务, 从队列中取
$sale_id = $robj->rpop($task_key);
if($sale_id === false) return false;
$res = $robj->set($proc_key, $sale_id);
}
// key saleid
// value 进程key
// 用于 重新上传 重新下载时 把原占用进程删除, 防止原进程一直在占用这个saleid
$active_key = sprintf(_RD_UPLOAD_ACTIVE_PROC, $sale_id);
if($auto_type==AUTO_CHECK_DOWN) $active_key = sprintf(_RD_DOWN_ACTIVE_PROC, $sale_id);
$this->setProcKey($active_key, $proc_key, 24*60*60);
return $sale_id;
}
/**
* 重新放入任务队列
* @param unknown $key
* @param unknown $val
* @param string $proc_key
* @return boolean
*/
public function lpushToList($key, $val, $proc_key='') {
$obj = new mBase();
$robj = $obj->initRedis();
$robj->lpush($key, $val);
if($proc_key) $this->delProcKey($proc_key);
return true;
}
/**
* 删除进程key
* @param unknown $proc_key
*/
public function delProcKey($proc_key) {
$obj = new mBase();
$robj = $obj->initRedis();
$robj->del($proc_key);
return true;
}
/**
* 设置进程key
* @param unknown $key
* @param unknown $val
* @param number $expire_time
* @return boolean
*/
public function setProcKey($key, $val, $expire_time=0) {
$obj = new mBase();
$robj = $obj->initRedis();
$robj->set($key, $val);
if($expire_time>0) $robj->expire($key, $expire_time);
return true;
}
}

19
queue/config/daemonconf.php

@ -1,14 +1,17 @@
<?php
$GLOBALS['DAEMON_MAXTIME'] = array(
);
$GLOBALS['DAEMON_LIST'] = array(
);
define('DAEMON_SYNC_HISTORICAL_ORDERS', 'daemon_sync_hisorical_orders');
define('DAEMON_SYNC_INCREMENT_ORDERS', 'daemon_sync_increment_orders');
define('DAEMON_SYNC_ORDERS_STATUS', 'daemon_sync_orders_status');
$GLOBALS['DAEMON_LIST_DESC'] = array(
$GLOBALS['DAEMON_LIST'] = array(
DAEMON_SYNC_HISTORICAL_ORDERS => 'sync_historical_orders.php',
DAEMON_SYNC_INCREMENT_ORDERS => 'sync_increment_orders.php',
DAEMON_SYNC_ORDERS_STATUS => 'sync_orders_status.php',
);
$GLOBALS['DAEMON_NUMLIMIT'] = array(
$GLOBALS['DAEMON_NUMLIMIT'] = array(
DAEMON_SYNC_HISTORICAL_ORDERS => 10,
DAEMON_SYNC_INCREMENT_ORDERS => 2,
DAEMON_SYNC_ORDERS_STATUS => 1,
);

43
queue/deal/sync_historical_orders.php

@ -0,0 +1,43 @@
<?php
/**
* 同步历史订单
*/
include_once dirname(dirname(dirname(__FILE__))).'/base/dealBase.php';
class syncHistoricalOrders extends dealBase {
public function setPara() {
$this->processnum = $GLOBALS['DAEMON_NUMLIMIT'][DAEMON_SYNC_HISTORICAL_ORDERS];
// $this->is_while = false;
}
public function deal() {
$obj = new mOrder();
$rdobj = $obj->initRedis();
$jsondata = $rdobj->rpop(_RQ_SYNC_HISTORICAL_ORDERS);
if ($jsondata === false) exit();
$data = json_decode($jsondata, true);
$start_date = $data['start_date'];
$name = $data['name'];
$sobj = new mShop();
$shopinfo = $sobj->getShopByName($name);
if (empty($shopinfo)) return false;
$pobj = new mPdd();
for ($page=1;;$page++) {
$trades = $pobj->getPddOrderList($name, $start_date, $start_date.' 23:59:59', ORDER_STATUS_FULL, REFUND_STATUS_FULL, $page, 100);
if (!$trades) break;
if ($trades['has_next'] != true) break;
$obj->addOrders($trades['order_list'], $shopinfo['id'], $shopinfo['uid']);
}
}
}
new syncHistoricalOrders();

43
queue/deal/sync_increment_orders.php

@ -0,0 +1,43 @@
<?php
/**
* 同步增量订单
*/
include_once dirname(dirname(dirname(__FILE__))).'/base/dealBase.php';
class syncIncrementOrders extends dealBase {
public function setPara() {
$this->processnum = $GLOBALS['DAEMON_NUMLIMIT'][DAEMON_SYNC_INCREMENT_ORDERS];
// $this->is_while = false;
}
public function deal() {
$obj = new mOrder();
$rdobj = $obj->initRedis();
$jsondata = $rdobj->rpop(_RQ_SYNC_INCREMENT_ORDERS);
if ($jsondata === false) exit();
$data = json_decode($jsondata, true);
$start_date = $data['start_date'];
$name = $data['name'];
$sobj = new mShop();
$shopinfo = $sobj->getShopByName($name);
if (empty($shopinfo)) return false;
$pobj = new mPdd();
for ($page=1;;$page++) {
$trades = $pobj->getPddIncrOrderList($name, $start_date, $start_date.' 23:59:59', ORDER_STATUS_FULL, REFUND_STATUS_FULL, $page, 100);
if (!$trades) break;
if ($trades['has_next'] != true) break;
$obj->addOrders($trades['order_list'], $shopinfo['id'], $shopinfo['uid']);
}
}
}
new syncIncrementOrders();

43
queue/deal/sync_orders_status.php

@ -0,0 +1,43 @@
<?php
/**
* 同步历史订单
*/
include_once dirname(dirname(dirname(__FILE__))).'/base/dealBase.php';
class syncHistoricalOrders extends dealBase {
public function setPara() {
$this->processnum = $GLOBALS['DAEMON_NUMLIMIT'][DAEMON_SYNC_ORDERS_STATUS];
$this->deal_sleep = 60;
// $this->is_while = false;
}
public function deal() {
$obj = new mOrder();
$order_list = $obj->getNotFinishedOrders();
if (empty($order_list)) return true;
$shopid2orders = array();
foreach ($order_list as $order) {
$shopid2orders[$order['shop_id']][] = $order['order_sn'];
}
$pobj = new mPdd();
foreach ($shopid2orders as $shopid => $tids) {
$tids_status = $pobj->getPddOrderStatus($tids, '', $shopid);
if (!$tids_status) continue;
foreach ($tids_status as $info) {
if (!$info) continue;
$obj->updateOrderBySn($info['orderSn'], array('order_status'=>$info['order_status'], 'refund_status'=>$info['refund_status']));
}
}
}
}
new syncHistoricalOrders();
Loading…
Cancel
Save