20240120-ljl-routeConfig
elf 10 months ago
parent 7b148c25b8
commit 06d0651dea

@ -0,0 +1,18 @@
<?php
use Service\Order\OrderMergeService;
use Service\Order\OrderPrintService;
use Service\Order\OrderService;
class LogisticsController extends AbstractApiController {
private $orderPrintService;
private $orderService;
private $orderMergeService;
public function __construct($route) {
parent::__construct($route);
$this->orderService = OrderService::instance();
$this->orderPrintService = OrderPrintService::instance();
$this->orderMergeService = OrderMergeService::instance();
}
}

@ -2,7 +2,223 @@
namespace Dao\AfterSale;
use AfterSalesConst;
use Dao\AbstractDao;
use Dao\Order\OpOrderDao;
use Dao\Order\OpOrderExtDao;
use Dao\Order\OpOrderGoodsDao;
use Dao\PurchaseOrder\PurchaseOrderDao;
use RedisExt;
use RedisKeyConst;
use StatusConst;
use ZcArrayHelper;
class AfterSalesDao extends AbstractDao {
public function searchPage($mallId, $filter, $page, $pageSize, $isNeedCheckSlowQuery) {
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
list($conditions, $joinTables, $orderByString) = $this->getSearchCondition($filter, $mallIds);
$whereStr = !empty($conditions) ? implode(' ', $conditions) : '';
$joinStr = !empty($joinTables) ? implode(' ', $joinTables) : '';
$opOrderTbl = OpOrderDao::tableName();
$sql = $this->prepare("SELECT afs.* FROM %b o %l where o.mall_id in %li %l group by afs.`after_sales_id` %l", $this->getTable(), $joinStr, $mallIds, $whereStr, $orderByString);
if ($isNeedCheckSlowQuery && !isset($filter['orderSn']) && !isset($filter['afterSalesId']) && $this->checkIsSlowQuery($sql)) {
return [[], 0, 1];
}
list($afterSalesList, $total) = $this->queryPage("SELECT afs.* FROM %b o %l where o.mall_id in %li %l group by afs.`after_sales_id` %l", $opOrderTbl, $joinStr, $mallIds, $whereStr, $orderByString, $page, $pageSize);
\Zc::getLog('sqlDebug')->info('sql: ' . $this->lastSql());
return [$afterSalesList, $total, 0];
}
public function checkIsSlowQuery($sql, $limit = 150000) {
$slowQueryRedisKey = RedisKeyConst::buildSlowQueryKey(md5($sql));
$bizRedis = RedisExt::factory('bizCache');
if ($bizRedis->get($slowQueryRedisKey)) {
return true;
}
$rows = $this->query($sql);
if (empty($rows) || !is_array($rows)) {
return false;
}
$isSlowQuery = false;
foreach ($rows as $row) {
if ($row['rows'] > $limit) {
$isSlowQuery = true;
\Zc::getLog('slowQueryDebug')->info("sql: {$sql}");
$bizRedis->setex($slowQueryRedisKey, 3600, 1);
break;
}
}
return $isSlowQuery;
}
private function getSearchCondition($filter, $mallIds) {
$wheres = [];
$joinTables = [];
$orderByString = '';
$afterSalesTbl = $this->getTable();
$opOrderGoodsTbl = OpOrderGoodsDao::tableName();
$opOrderExtTbl = OpOrderExtDao::tableName();
$purchaseOrderTbl = PurchaseOrderDao::tableName();
$joinTables[$afterSalesTbl] = $this->prepare('inner join %b afs on o.order_sn = afs.order_sn', $afterSalesTbl);
if (!empty($filter['afterSalesStatus'])) {
$afterSalesStatusFilter = is_array($filter['afterSalesStatus']) ? $filter['afterSalesStatus'] : [$filter['afterSalesStatus']];
$wheres[] = $this->prepare('and afs.after_sales_status in %li', $afterSalesStatusFilter);
}
if (isset($filter['shippingStatus']) && is_numeric($filter['shippingStatus'])) {
$wheres[] = $this->prepare('and afs.shipping_status = %i', $filter['shippingStatus']);
}
if (isset($filter['afterSalesType']) && is_numeric($filter['afterSalesType'])) {
$wheres[] = $this->prepare('and afs.after_sales_type = %i', $filter['afterSalesType']);
}
if (!empty($filter['orderSn'])) {
$wheres[] = $this->prepare('and afs.order_sn in %ls', $filter['orderSn']);
}
if (!empty($filter['afterSalesId'])) {
$wheres[] = $this->prepare('and afs.after_sales_id in %ls', $filter['afterSalesId']);
}
if (!empty($filter['goodsId'])) {
$joinTables[$opOrderGoodsTbl] = $this->prepare('left join %b oog on oog.order_id = o.order_id', $opOrderGoodsTbl);
$wheres[] = $this->prepare('and oog.goods_id = %i', $filter['goodsId']);
}
if (!empty($filter['trackingNumbers'])) {
$wheres[] = $this->prepare('and afs.tracking_number IN %ls', $filter['trackingNumbers']);
}
if (!empty($filter['recreatedAtStart'])) {
$wheres[] = $this->prepare("AND afs.`recreated_at` >= %s", $filter['recreatedAtStart']);
}
if (!empty($filter['recreatedAtEnd'])) {
$wheres[] = $this->prepare("AND afs.`recreated_at` <= %s", $filter['recreatedAtEnd']);
}
if (!empty($filter['expireStartTime'])) {
$wheres[] = $this->prepare("AND afs.`expire_time` >= %s", $filter['expireStartTime']);
}
if (!empty($filter['expireEndTime'])) {
$wheres[] = $this->prepare("AND afs.`expire_time` <= %s", $filter['expireEndTime']);
}
if (!empty($filter['mallNote'])) {
$wheres[] = $this->prepare('AND afs.`mall_note` like %ss', $filter['mallNote']);
}
if (isset($filter['hasMallNote']) && is_numeric($filter['hasMallNote'])) {
if ($filter['hasMallNote']) {
$wheres[] = $this->prepare("AND afs.`mall_note` != ''");
} else {
$wheres[] = $this->prepare("AND afs.`mall_note` = ''");
}
}
if (!empty($filter['mallNoteFlag'])) {
$wheres[] = $this->prepare("AND afs.`mall_note_flag` IN %li", (is_array($filter['mallNoteFlag']) ? $filter['mallNoteFlag'] : [$filter['mallNoteFlag']]));
}
if (!empty($filter['purchaseStartTime'])) {
$wheres[] = $this->prepare("AND po.`purchase_order_start_time` >= %s", $filter['purchaseStartTime']);
$joinTables['purchase_order'] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
if (!empty($filter['purchaseEndTime'])) {
$wheres[] = $this->prepare("AND po.`purchase_order_start_time` <= %s", $filter['purchaseEndTime']);
$joinTables['purchase_order'] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
if (!empty($filter['refundAmountStart'])) {
$wheres[] = $this->prepare("AND afs.`refund_amount` >= %s", $filter['refundAmountStart']);
}
if (!empty($filter['refundAmountEnd'])) {
$wheres[] = $this->prepare("AND afs.`refund_amount` <= %s", $filter['refundAmountEnd']);
}
if (!empty($filter['purchasePlatform'])) {
$wheres[] = $this->prepare("AND po.`purchase_platform` = %s", $filter['purchasePlatform']);
$joinTables['purchase_order'] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
if (!empty($filter['purchaseOrderSn'])) {
$wheres[] = $this->prepare("AND po.`purchase_order_sn` = %s", $filter['purchaseOrderSn']);
$joinTables['purchase_order'] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
if (!empty($filter['purchaseOrderStatus'])) {
$wheres[] = $this->prepare("AND po.`purchase_order_status` = %s", $filter['purchaseOrderStatus']);
$joinTables['purchase_order'] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
if (!empty($filter['filterPurchaseStatus']) && is_array($filter['filterPurchaseStatus'])) {
$wheres[] = $this->prepare("AND ooe.filter_purchase_status in %li", $filter['filterPurchaseStatus']);
$joinTables[$opOrderExtTbl] = $this->prepare('left join %b ooe on ooe.order_id = o.order_id', $opOrderExtTbl);
} elseif (is_numeric($filter['filterPurchaseStatus'])) {
$wheres[] = $this->prepare("AND ooe.filter_purchase_status = %i", $filter['filterPurchaseStatus']);
$joinTables[$opOrderExtTbl] = $this->prepare('left join %b ooe on ooe.order_id = o.order_id', $opOrderExtTbl);
}
if (!empty($filter['receiverNameSearchText'])) {
$wheres[] = $this->prepare("AND o.`receiver_name_smd5` = %s", $filter['receiverNameSearchText']);
}
if (!empty($filter['receiverMobileSearchText'])) {
$wheres[] = $this->prepare("AND o.`receiver_phone_smd5` = %s", $filter['receiverMobileSearchText']);
}
if (isset($filter['speedRefundFlag']) && in_array($filter['speedRefundFlag'], [AfterSalesConst::speedRefundFlagYes, AfterSalesConst::speedRefundFlagNo])) {
$wheres[] = $this->prepare("AND afs.`speed_refund_flag` = %i", $filter['speedRefundFlag']);
}
if (!empty($joinTables['purchase_order'])) {
$wheres[] = $this->prepare("AND po.`status` = %s", StatusConst::normal);
}
if (!empty($filter['purchaseOrderBuyer'])) {
$wheres[] = $this->prepare("AND po.status = %s and po.`purchase_order_buyer` = %s", StatusConst::normal, $filter['purchaseOrderBuyer']);
$joinTables[$purchaseOrderTbl] = $this->prepare('LEFT JOIN purchase_order po ON po.`order_id` = o.`order_id`');
}
switch ($filter['sortType']) {
case 'applyTimeDesc' :
$orderByString = 'order by afs.recreated_at desc';
break;
case 'applyTimeAsc' :
$orderByString = 'order by afs.recreated_at asc';
break;
case 'timeoutTimeDesc' :
$orderByString = 'order by afs.expire_time desc';
break;
case 'timeoutTimeAsc' :
$orderByString = 'order by afs.expire_time asc';
break;
}
return [$wheres, $joinTables, $orderByString];
}
public function getAfterSalesCount($mallId, $filter) {
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
list($conditions, $joinTables) = $this->getSearchCondition($filter, $mallIds);
unset($joinTables[$this->getTable()]);
$whereStr = !empty($conditions) ? implode(' ', $conditions) : '';
$joinStr = !empty($joinTables) ? implode(' ', $joinTables) : '';
if (count($mallIds) <= 50) {
$count = $this->queryFirstField('select count(*) from %b afs %l where afs.mall_id in %li %l', $this->getTable(), $joinStr, $mallIds, $whereStr);
} else {
$count = 0;
foreach (array_chunk($mallIds, 50) as $chunkMallIds) {
$chunkCount = $this->queryFirstField('select count(*) from %b afs %l where afs.mall_id in %li %l', $this->getTable(), $joinStr, $chunkMallIds, $whereStr);
$count += (int)$chunkCount;
}
}
return (int)$count;
}
public function getStatusCountMap($mallIds) {
$rows = $this->query('select after_sales_status, count(*) as after_sales_status_count from %b afs where afs.mall_id in %li and afs.after_sales_status != %i group by afs.`after_sales_status`', $this->getTable(), $mallIds, AfterSalesConst::afterSalesStatusRefundSuccess);
return ZcArrayHelper::mapNameValue($rows, 'after_sales_status', 'after_sales_status_count');
}
}

@ -2,6 +2,7 @@
namespace Dao\Common;
use CommonTool;
use Dao\AbstractDao;
use ZcArrayHelper;
@ -20,6 +21,15 @@ class LogisticsDao extends AbstractDao {
return $logistics;
}
public function getCompanyIdAndNameMap($companyIds, $platform) {
if (CommonTool::anyEmpty($companyIds, $platform)) {
return [];
}
$logisticsPlatformTbl = LogisticsPlatformDao::tableName();
$rows = $this->query('select lpc.company_id, l.logistics_name from %b l left join %b lpc on lpc.logistics_id = l.logistics_id where lpc.company_id in %li and lpc.platform = %s %l', $this->getTable(), $logisticsPlatformTbl, $companyIds, $platform);
return ZcArrayHelper::mapNameValue($rows, 'companyId', 'logisticsName');
}
public function getLogisticsMap($status = null, $includeAll = false) {
$where = '';
if ($status) {

@ -20,14 +20,14 @@ class LogisticsPlatformDao extends AbstractDao {
}
public function getListByLogisticsId($logisticsIds) {
return $this->query('select * from logistics_platform where logistics_id in %li', $logisticsIds);
return $this->query('select * from %b where logistics_id in %li', $this->getTable(), $logisticsIds);
}
public function getMapByCompanyCodes($companyCodes, $platform) {
if (CommonTool::anyEmpty($companyCodes, $platform)) {
return [];
}
$logistics = $this->query('select l.*,lpc.company_code from logistics_platform lpc left join logistics l on l.logistics_id = lpc.logistics_id where company_code in %ls and platform = %s', $companyCodes, $platform);
$logistics = $this->query('select l.*,lpc.company_code from %b lpc left join logistics l on l.logistics_id = lpc.logistics_id where company_code in %ls and platform = %s', $this->getTable(), $companyCodes, $platform);
return ZcArrayHelper::changeKeyRow($logistics, 'companyCode');
}
@ -35,7 +35,15 @@ class LogisticsPlatformDao extends AbstractDao {
if (CommonTool::anyEmpty($logisticsIds, $platform)) {
return [];
}
$rows = $this->query('select logistics_id, company_id from logistics_platform where logistics_id in %li and platform = %s', $logisticsIds, $platform);
$rows = $this->query('select logistics_id, company_id from %b where logistics_id in %li and platform = %s', $this->getTable(), $logisticsIds, $platform);
return ZcArrayHelper::mapNameValue($rows, 'logisticsId', 'companyId');
}
public function getMapByCompanyIds($companyIds, $platform) {
if (CommonTool::anyEmpty($companyIds, $platform)) {
return [];
}
$logistics = $this->query('select l.*,lpc.company_id from %b lpc left join logistics l on l.logistics_id = lpc.logistics_id where company_id in %ls and platform = %s', $this->getTable(), $companyIds, $platform);
return ZcArrayHelper::changeKeyRow($logistics, 'company_id');
}
}

@ -3,6 +3,7 @@
namespace Dao\CustomPrint;
use Dao\AbstractDao;
use OrderPrintConst;
class CustomOrderExpressNoDao extends AbstractDao {
public function getCustomOrderIdAndExpressNoListMap($mallIds, $customOrderIds) {
@ -15,4 +16,84 @@ class CustomOrderExpressNoDao extends AbstractDao {
}
return $datas;
}
public function searchPage($mallId, $filter, $page, $pageSize) {
$mallIds = empty($filter['authMallIds']) ? [$mallId] : (is_array($filter['authMallIds']) ? $filter['authMallIds'] : [$filter['authMallIds']]);
list($conditons, $joinTables) = $this->buildSearchLogisticsWarningCustomOrderCondition($filter, $mallId);
$whereStr = !empty($conditons) ? implode(' ', $conditons) : '';
$joinStr = !empty($joinTables) ? implode(' ', $joinTables) : '';
return $this->queryPage("SELECT co.* FROM custom_order_express_no coen left join custom_order co on coen.custom_order_id = co.custom_order_id %l WHERE co.mall_id IN %li %l order by coen.`gmt_create` desc", $joinStr, $mallIds, $whereStr, $page, $pageSize);
}
protected function buildSearchLogisticsWarningCustomOrderCondition($filter, $mallId) {
if (!empty($filter['bizOrderNum'])) {
$whereConditions[] = $this->prepare("AND co.`biz_order_num` = %s", $filter['bizOrderNum']);
unset($filter['orderStartTime'], $filter['orderEndTime']);
}
if (!empty($filter['orderStartTime'])) {
$whereConditions[] = $this->prepare("AND coen.`gmt_create` >= %s", $filter['orderStartTime']);
}
if (!empty($filter['orderEndTime'])) {
$whereConditions[] = $this->prepare("AND coen.`gmt_create` <= %s", $filter['orderEndTime']);
}
if (!empty($filter['waybillCode'])) {
$whereConditions[] = $this->prepare("AND coen.`express_no` = %s", $filter['waybillCode']);
}
if (!empty($filter['logisticsId'])) {
$whereConditions[] = $this->prepare("AND coen.`logistics_id` = %i", $filter['logisticsId']);
}
if (!empty($filter['waybillType'])) {
$whereConditions[] = $this->prepare("AND coen.`waybill_type` = %i", $filter['waybillType']);
}
if ($filter['logisticsStatus']) {
if (is_array($filter['logisticsStatus'])) {
$logisticsStatusWhere = $this->prepare('AND coe.`logistics_status` in %ls', $filter['logisticsStatus']);
} else if ($filter['logisticsStatus'] == OrderPrintConst::logisticsStatusFilterGot) {
$logisticsStatusWhere = $this->prepare('AND coe.`logistics_status` = %s', OrderPrintConst::logisticsActionGot);
} else if ($filter['logisticsStatus'] == OrderPrintConst::logisticsStatusFilterWaitGot) {
$logisticsStatusWhere = $this->prepare('AND coe.`logistics_status` is null');
} else if ($filter['logisticsStatus'] == OrderPrintConst::logisticsStatusFilterHasTrace) {
$logisticsStatusWhere = $this->prepare('AND coe.`logistics_status` is not null');
}
if ($logisticsStatusWhere) {
$whereConditions[] = $logisticsStatusWhere;
$joinTables['custom_order_ext'] = $this->prepare('LEFT JOIN custom_order_ext coe ON co.`custom_order_id` = coe.`custom_order_id`');
}
}
if ($filter['logisticsOvertimeType']) {
$filterLogisticsOvertimeType = is_array($filter['logisticsOvertimeType']) ? $filter['logisticsOvertimeType'] : [$filter['logisticsOvertimeType']];
$whereConditions[] = $this->prepare('AND coe.`logistics_overtime_type` in %li', $filterLogisticsOvertimeType);
$joinTables['custom_order_ext'] = $this->prepare('LEFT JOIN custom_order_ext coe ON co.`custom_order_id` = coe.`custom_order_id`');
}
if ($filter['logisticsExceptionOvertimeType']) {
$filterLogisticsOvertimeType = is_array($filter['logisticsExceptionOvertimeType']) ? $filter['logisticsExceptionOvertimeType'] : [$filter['logisticsExceptionOvertimeType']];
$whereConditions[] = $this->prepare('AND coe.`logistics_exception_overtime_type` in %li', $filterLogisticsOvertimeType);
$joinTables['custom_order_ext'] = $this->prepare('LEFT JOIN custom_order_ext coe ON co.`custom_order_id` = coe.`custom_order_id`');
}
if ($filter['notLogisticsWarningAndException']) {
$whereConditions[] = $this->prepare('AND coe.`logistics_overtime_type` is null and coe.`logistics_exception_overtime_type` is null');
$joinTables['custom_order_ext'] = $this->prepare('LEFT JOIN custom_order_ext coe ON co.`custom_order_id` = coe.`custom_order_id`');
}
return [$whereConditions, $joinTables];
}
public function getCustomOrderCount($mallId, $filter) {
list($conditions, $joinTables) = $this->buildSearchLogisticsWarningCustomOrderCondition($filter, $mallId);
$whereStr = !empty($conditions) ? implode(' ', $conditions) : '';
$joinStr = !empty($joinTables) ? implode(' ', $joinTables) : '';
$count = $this->queryFirstField("SELECT count(*) FROM custom_order_express_no coen left join custom_order co on coen.custom_order_id = co.custom_order_id %l WHERE co.mall_id = %i %l", $joinStr, $mallId, $whereStr);
return (int)$count;
}
}

@ -3,6 +3,29 @@
namespace Dao\CustomPrint;
use Dao\AbstractDao;
use ZcArrayHelper;
class CustomOrderExtDao extends AbstractDao {
public function getMapByOrderIds($customOrderIds) {
if (empty($customOrderIds)) {
return [];
}
$rows = $this->query("select * from %b where custom_order_id in %li", $this->getTable(), $customOrderIds);
if (empty($rows)) {
return [];
}
return ZcArrayHelper::changeKeyRow($rows, 'customOrderId');
}
public function batchCancelLogisticsWarning($customOrderIds) {
if (empty($customOrderIds)) {
return false;
}
$updateData = [
'logistics_status' => null,
'logistics_overtime_type' => null,
];
return $this->update($updateData, 'custom_order_id IN %li', $customOrderIds);
}
}

@ -0,0 +1,11 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderCollectLogDao extends AbstractDao {
public function getByFulfillmentOrderId($fulfillmentOrderId) {
return $this->queryFirstRow('select * from %b where fulfillment_order_id = %i', $this->getTable(), $fulfillmentOrderId);
}
}

@ -0,0 +1,116 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
use FulfillmentOrderConst;
use ZcArrayHelper;
class FulfillmentOrderDao extends AbstractDao {
public function searchPage($mallId, $filter, $page, $pageSize) {
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
list($whereArr, $joinTables) = $this->getSearchOrderCondition($filter, $mallIds);
$whereStr = !empty($whereArr) ? implode(' ', $whereArr) : '';
$joinStr = !empty($joinTables) ? implode(' ', $joinTables) : '';
$orderByQuery = $this->getOrderByQueryString($filter['sortType']);
return $this->queryPage("SELECT fo.* FROM %b fo %l WHERE fo.mall_id in %li %l %l", $this->getTable(), $joinStr, $mallIds, $whereStr, $orderByQuery, $page, $pageSize);
}
private function getSearchOrderCondition($filter, $mallIds) {
$foeTbl = FulfillmentOrderExtDao::tableName();
$whereConditions = [];
$joinTables = [];
if ($filter['fulfillmentStatus']) {
$whereConditions[] = $this->prepare('and fo.fulfillment_status = %i', $filter['fulfillmentStatus']);
}
if (!empty($filter['fulfillmentSn'])) {
$orderSns = is_array($filter['orderSn']) ? $filter['orderSn'] : array($filter['orderSn']);
$whereConditions[] = $this->prepare('and fo.fulfillment_sn in %ls', $orderSns);
}
if (!empty($filter['orderStartTime'])) {
$whereConditions[] = $this->prepare('and fo.confirm_time >= %s', $filter['orderStartTime']);
}
if (!empty($filter['orderEndTime'])) {
$whereConditions[] = $this->prepare('and fo.confirm_time <= %s', $filter['orderEndTime']);
}
if ($filter['goodsId']) {
$filter['goodsId'] = is_array($filter['goodsId']) ? $filter['goodsId'] : [$filter['goodsId']];
$whereConditions[] = $this->prepare('and fo.goods_id in %li', $filter['goodsId']);
}
if ($filter['goodsName']) {
$whereConditions[] = $this->prepare('and fo.goods_name like %ss', $filter['goodsName']);
}
if ($filter['sellerNote']) {
$whereConditions[] = $this->prepare('and fo.seller_note like %ss', $filter['sellerNote']);
}
if ($filter['promiseDeliveryTimeFilter']) {
if ($filter['promiseDeliveryTimeFilter'] == FulfillmentOrderConst::promiseDeliverTimeOvertime) {
$whereConditions[] = $this->prepare('and fo.promise_delivery_time < %s', date('Y-m-d H:i:s'));
} elseif (in_array($filter['promiseDeliveryTimeFilter'], [FulfillmentOrderConst::promiseDeliverTimeOneDay, FulfillmentOrderConst::promiseDeliverTimeTwoDay, FulfillmentOrderConst::promiseDeliverTimeThreeDay])) {
$promiseDeliverTime = date('Y-m-d H:i:s', strtotime("+{$filter['promiseDeliveryTimeFilter']} hours"));
$whereConditions[] = $this->prepare('and fo.promise_delivery_time > %s and fo.promise_delivery_time < %s', date('Y-m-d H:i:s'), $promiseDeliverTime);
}
}
if ($filter['goodsLabelCodePrintFilter'] == FulfillmentOrderConst::goodsLabelCodePrinted) {
$joinTables[$foeTbl] = $this->prepare('left join %b foe on fo.fulfillment_sn = foe.fulfillment_sn', $foeTbl);
$whereConditions[] = $this->prepare('and foe.filter_goods_label_code_printed = 1');
} elseif ($filter['goodsLabelCodePrintFilter'] == FulfillmentOrderConst::goodsLabelCodeNoPrinted) {
$joinTables[$foeTbl] = $this->prepare('left join %b foe on fo.fulfillment_sn = foe.fulfillment_sn', $foeTbl);
$whereConditions[] = $this->prepare('and foe.filter_goods_label_code_printed = 0 or foe.filter_goods_label_code_printed is null');
}
return [$whereConditions, $joinTables];
}
public function getOrderByQueryString($sortType) {
switch ($sortType) {
case 'orderConfirmTimeDesc':
$query = 'order by fo.`confirm_time` desc';
break;
case 'orderConfirmTimeAsc':
$query = 'order by fo.`confirm_time` asc';
break;
case 'promiseDeliveryTimeDesc':
$query = 'order by fo.`promise_delivery_time` desc';
break;
case 'promiseDeliveryTimeAsc':
$query = 'order by fo.`promise_delivery_time` asc';
break;
default:
$query = 'order by fo.`confirm_time` desc';
break;
}
return empty($query) ? '' : $query;
}
public function getStatusAndOrderCountMap($mallIds) {
$orderStatusAndOrderCountMap = $this->query('select fulfillment_status, count(*) as order_count from %b WHERE mall_id in %li group by fulfillment_status', $this->getTable(), $mallIds);
return ZcArrayHelper::mapNameValue($orderStatusAndOrderCountMap, 'fulfillmentStatus', 'orderCount');
}
public function getWillDelaySendOrderCount($mallIds) {
return $this->queryFirstField('select count(*) from %b where mall_id in %li and fulfillment_status = %i and promise_delivery_time > %s and promise_delivery_time < %s', $this->getTable(), $mallIds, FulfillmentOrderConst::fulfillmentOrderStatusWaitSellerSendGoods, date('Y-m-d H:i:s'), date('Y-m-d H:i:s', strtotime("+24 hours")));
}
public function getHasDelaySendOrderCount($mallIds) {
return $this->queryFirstField('select count(*) from %b where mall_id in %li and fulfillment_status = %i and promise_delivery_time < %s', $this->getTable(), $mallIds, FulfillmentOrderConst::fulfillmentOrderStatusWaitSellerSendGoods, date('Y-m-d H:i:s'));
}
public function getCourierCollectOrderCount($mallIds) {
return $this->queryFirstField('select count(*) from %b where mall_id in %li and courier_door_to_door_collect = 1', $this->getTable(), $mallIds);
}
public function getByFulfillmentSn($fulfillmentSn) {
return $this->queryFirstRow('select * FROM %b WHERE fulfillment_sn = %s', $this->getTable(), $fulfillmentSn);
}
}

@ -0,0 +1,9 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderEncryptDao extends AbstractDao {
}

@ -0,0 +1,9 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderExtDao extends AbstractDao {
}

@ -0,0 +1,47 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderGoodsLabelCodeDao extends AbstractDao {
public function getByFulfillmentSn($fulfillmentSn) {
if (empty($fulfillmentSn)) {
return null;
}
return $this->queryFirstRow('select * from %b where fulfillment_sn = %s', $this->getTable(), $fulfillmentSn);
}
public function searchPage($mallId, $filter, $page, $pageSize) {
$mallIds = !empty($filter['authMallIds']) ? (is_array($filter['authMallIds']) ? $filter['authMallIds'] : [$filter['authMallIds']]) : [$mallId];
$where = $this->getSearchLogWhere($filter);
return $this->queryPage("SELECT * FROM %b WHERE `mall_id` IN %li and is_preview != 1 %l ORDER BY `op_print_goods_label_code_log_id` DESC", $this->getTable(), $mallIds, $where, $page, $pageSize);
}
private function getSearchLogWhere($filter) {
$whereArray = array();
if ($filter['startTime']) {
$whereArray[] = $this->prepare('and gmt_create >= %s', $filter['startTime']);
}
if ($filter['endTime']) {
$whereArray[] = $this->prepare('and gmt_create <= %s', $filter['endTime']);
}
if ($filter['fulfillmentSn']) {
$whereArray[] = $this->prepare('and fulfillment_sn in %ls', $filter['fulfillmentSn']);
}
if ($filter['logisticsId']) {
$whereArray[] = $this->prepare('and logistics_id = %s', $filter['logisticsId']);
}
if ($filter['waybillCode']) {
$whereArray[] = $this->prepare('and waybill_code = %s', $filter['waybillCode']);
}
if ($filter['waybillCodes']) {
$whereArray[] = $this->prepare('and express_no in %ls', $filter['waybillCodes']);
}
if($filter['status']) {
$whereArray[] = $this->prepare('and status = %s', $filter['status']);
}
$where = implode(' ', $whereArray);
return $where;
}
}

@ -0,0 +1,14 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
use ZcArrayHelper;
class FulfillmentOrderInsensitiveInfoDao extends AbstractDao {
public function getFulfillmentOrderIdAndReceiverInfoMap($fulfillmentOrderIds) {
$encryptTbl = FulfillmentOrderEncryptDao::tableName();
$rows = $this->query('select foe.*, foii.receiver_name, foii.receiver_phone, foii.receiver_address from %b foii left join %b foe on foii.fulfillment_order_id = foe.fulfillment_order_id where foii.fulfillment_order_id in %li', $this->getTable(), $encryptTbl, $fulfillmentOrderIds);
return ZcArrayHelper::changeKeyRow($rows, 'fulfillmentOrderId');
}
}

@ -0,0 +1,40 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderOutstorageHistoryDao extends AbstractDao {
public function searchPage($mallId, $filter, $page, $pageSize) {
$mallIds = !empty($filter['authMallIds']) ? (is_array($filter['authMallIds']) ? $filter['authMallIds'] : [$filter['authMallIds']]) : [$mallId];
$where = $this->getSearchLogWhere($filter);
return $this->queryPage("SELECT * FROM %b WHERE `mall_id` IN %li %l ORDER BY `fulfillment_order_outstorage_history_id` DESC", $this->getTable(), $mallIds, $where, $page, $pageSize);
}
private function getSearchLogWhere($filter) {
$whereArray = [];
if ($filter['startTime']) {
$whereArray[] = $this->prepare('and gmt_create >= %s', $filter['startTime']);
}
if ($filter['endTime']) {
$whereArray[] = $this->prepare('and gmt_create <= %s', $filter['endTime']);
}
if ($filter['fulfillmentSn']) {
$whereArray[] = $this->prepare('and fulfillment_sn in %ls', $filter['fulfillmentSn']);
}
if ($filter['logisticsId']) {
$whereArray[] = $this->prepare('and logistics_id = %s', $filter['logisticsId']);
}
if ($filter['waybillCode']) {
$whereArray[] = $this->prepare('and waybill_code = %s', $filter['waybillCode']);
}
if ($filter['waybillCodes']) {
$whereArray[] = $this->prepare('and express_no in %ls', $filter['waybillCodes']);
}
if($filter['status']) {
$whereArray[] = $this->prepare('and status = %s', $filter['status']);
}
$where = implode(' ', $whereArray);
return $where;
}
}

@ -0,0 +1,19 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class FulfillmentOrderOutstorageStopDao extends AbstractDao {
public function getByFulfillmentSn($mallId, $fulfillmentSn) {
return $this->queryFirstRow('select * from %b where mall_id = %i and fulfillment_sn = %s ', $this->getTable(), $mallId, $fulfillmentSn);
}
public function add($mallId, $fulfillmentSn, $reason) {
return $this->insert(array(
'mall_id' => $mallId,
'fulfillment_sn' => $fulfillmentSn,
'reason' => $reason,
));
}
}

@ -0,0 +1,9 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
class OpPrintGoodsLabelCodeLogDao extends AbstractDao {
protected $hasGmtModified = false;
}

@ -0,0 +1,23 @@
<?php
namespace Dao\FulfillmentOrder;
use Dao\AbstractDao;
use OrderPrintTool;
class OpSysFulfillmentGoodsLabelCodeTplDao extends AbstractDao {
public function getDefault() {
$row = $this->queryFirstRow('select * from %b where is_default = 1', $this->getTable());
if (empty($row)) {
return null;
}
$row['globalStyle'] = unserialize($row['globalStyle']);
$row['positionMap'] = unserialize($row['positionMap']);
foreach ($row['positionMap'] as &$item) {
if ($item['nv']['field'] == 'image' || $item['nv']['field'] == 'logo') {
$item['nv']['imgSrc'] = OrderPrintTool::opPubAbsUrl($item['nv']['imgPath']);
}
}
return $row;
}
}

@ -25,7 +25,7 @@ class OpOrderDao extends AbstractDao {
if(!empty($filterCondition['sortType'])){
$orderByQuery = $this->getOrderByQuery($filterCondition['sortType']);
}
return $this->queryPage("SELECT o.* FROM op_order o %l WHERE o.mall_id in %li %l group by o.`order_id` %l", $joinStr, $filterMallIds, $whereStr, $orderByQuery, $page, $pageSize);
return $this->queryPage("SELECT o.* FROM %b o %l WHERE o.mall_id in %li %l group by o.`order_id` %l", $this->getTable(), $joinStr, $filterMallIds, $whereStr, $orderByQuery, $page, $pageSize);
}
public function getSearchOrderCondition($filter, $mallIds) {

@ -2,8 +2,10 @@
namespace Dao\Order;
use CommonTool;
use Dao\AbstractDao;
use ZcArrayHelper;
use ZcDbEval;
class OpOrderExtDao extends AbstractDao {
protected $pk = 'order_id';
@ -14,4 +16,22 @@ class OpOrderExtDao extends AbstractDao {
$opOrderExtData['mall_id'] = $mallId;
return $this->insertUpdate($opOrderExtData);
}
public function updateOrderPreOutstorageFlag($mallIds, $orderIds, $isPreOutstorage) {
if (CommonTool::anyEmpty($mallIds, $orderIds)) {
return false;
}
return $this->update('op_order_ext', ['is_pre_outstorage' => $isPreOutstorage ? 1 : 0, 'gmt_modified' => ZcDbEval::now(), 'gmt_pre_outstorage' => ZcDbEval::now()], 'mall_id in %li and order_id in %li', $mallIds, $orderIds);
}
public function batchCancelLogisticsWarning($orderIds) {
if (empty($orderIds)) {
return false;
}
$updateData = [
'logistics_status' => null,
'logistics_overtime_type' => null,
];
return $this->update($updateData, 'order_id IN %li', $orderIds);
}
}

@ -0,0 +1,27 @@
<?php
namespace Dao\Order;
use Dao\AbstractDao;
class OpOrderLogisticsTraceDao extends AbstractDao {
public function getLogisticsAndTraceListMap($logisticsIds , $expressNos) {
$logisticsIds = array_unique(array_filter($logisticsIds));
$expressNos = array_unique(array_filter($expressNos));
if (empty($logisticsIds) || empty($expressNos)) {
return [];
}
$list = $this->query('select * from %b where logistics_id in %li and tracking_number in %ls order by status_time desc', $this->getTable(), $logisticsIds, $expressNos);
$traceMap = [];
foreach ($list as $trace) {
$traceMap[$trace['logisticsId'].'_'.$trace['trackingNumber']][] = $trace;
}
foreach ($traceMap as &$traceList) {
uasort($traceList, function ($v1, $v2) {
return $v1['statusTime'] < $v2['statusTime'];
});
}
return $traceMap;
}
}

@ -4,6 +4,7 @@ namespace Dao\Order;
use Dao\AbstractDao;
use StatusConst;
use ZcArrayHelper;
class OpOrderMapDao extends AbstractDao {
public function getListByChildOrderIds($childOrderIds, $status = \StatusConst::normal) {
@ -61,4 +62,38 @@ class OpOrderMapDao extends AbstractDao {
public function getExistChildOrderIds( $mallId, $orderIds) {
return $this->queryFirstColumn("SELECT child_order_id FROM %b WHERE mall_id = %i AND child_order_id in %li and is_master = 0", $this->getTable(), $mallId, $orderIds);
}
public function getChildOrderIdAndOrderIdMap($childOrderIds) {
$opOrderMap = $this->query('select order_id,child_order_id from %b where child_order_id in %li and status = %s', $this->getTable(), $childOrderIds, StatusConst::normal);
return ZcArrayHelper::mapNameValue($opOrderMap, 'childOrderId', 'orderId');
}
public function getOrderIdAndChildOrderIdsMap($orderIds, $status = StatusConst::normal) {
if (empty($orderIds)) {
return [];
}
$opOrderMaps = $this->query('select order_id, child_order_id from %b where order_id in %li and status = %s', $this->getTable(), $orderIds, $status);
$orderIdAndOrderInfoMap = ZcArrayHelper::changeKey($opOrderMaps, 'orderId', true);
$orderIdAndChildOrderIdsMap = array_map(function ($item) {
return ZcArrayHelper::getSub($item, 'childOrderId');
}, $orderIdAndOrderInfoMap);
return $orderIdAndChildOrderIdsMap;
}
public function getParentOrderIdsByChildOrderIds($orderIds, $status = StatusConst::normal) {
if (empty($orderIds)) {
return [];
}
$orderIds = $this->queryFirstColumn('select order_id from %b where child_order_id in %li and status = %s', $this->getTable(), $orderIds, $status);
return array_unique($orderIds);
}
public function getChildOrderIdsByParentOrderIds($orderIds, $status = StatusConst::normal) {
if (empty($orderIds)) {
return [];
}
$childOrderIds = $this->queryFirstColumn('select child_order_id from %b where order_id in %li and status = %s', $this->getTable(), $orderIds, $status);
return array_unique($childOrderIds);
}
}

@ -10,11 +10,16 @@ class OpOrderExpressNoDao extends AbstractDao {
if (empty($orderIds)) {
return [];
}
$rows = $this->query("select * from op_order_express_no where order_id in %li order by op_order_express_no_id asc", $orderIds);
$rows = $this->query("select * from %b where order_id in %li order by op_order_express_no_id asc", $this->getTable(), $orderIds);
return ZcArrayHelper::changeKey($rows, 'orderId', true);
}
public function getListByLogisticsIdAndWaybillType($mallId, $orderId, $logisticsId, $waybillType) {
return $this->query("select * from %b where mall_id = %i and order_id = %i and logistics_id = %i and waybill_type = %i order by op_order_express_no_id asc", $this->getTable(), $mallId, $orderId, $logisticsId, $waybillType);
}
public function getOrderIdAndExpressInfoMap($orderIds) {
$expressList = $this->query('select ooeo.*,oo.order_status, oo.refund_status from op_order_express_no ooeo left join op_order oo on ooeo.order_id = oo.order_id where ooeo.order_id in %li', $orderIds);
return ZcArrayHelper::changeKeyRow($expressList, 'orderId');
}
}

@ -107,4 +107,8 @@ class OpWaybillInfoDao extends AbstractDao {
public function getListByWaybillCodes($waybillCodes) {
return $this->query('select * from %b where waybill_code in %ls', $this->getTable(), $waybillCodes);
}
public function getExistsWaybillCodes($waybillCodes) {
return $this->queryFirstColumn('select waybill_code from %b where waybill_code in %ls and wb_user_id > 0', $waybillCodes);
}
}

@ -79,4 +79,8 @@ class OpOrderOutstorageHistoryDao extends AbstractDao {
$data = ZcArrayHelper::filterColumns($data, 'operator_mall_id,source,mall_id,order_sn,purchase_order_sn,purchase_platform,purchase_account,pull_order_count,action,error_code,reason,detail,gmt_create,gmt_modified');
$this->insert($data);
}
public function getLastHistoryIdsByOrderSns($mallIds, $orderSns) {
return $this->queryFirstColumn('SELECT MAX(op_order_outstorage_history_id) FROM %b WHERE mall_id in %li AND order_sn in %ls GROUP BY order_sn', $this->getTable(), $mallIds, $orderSns);
}
}

@ -0,0 +1,9 @@
<?php
namespace Dao\PendingMatter;
use Dao\AbstractDao;
use OrderPrintTool;
class PendingMasterQueueDao extends AbstractDao {
}

@ -0,0 +1,8 @@
<?php
namespace Dao\PendingMatter;
use Dao\AbstractDao;
class PendingMatterBufferDao extends AbstractDao {
}

@ -0,0 +1,16 @@
<?php
namespace Dao\PendingMatter;
use Dao\AbstractDao;
use OrderPrintTool;
class PendingMatterCategoryDao extends AbstractDao {
public function searchPage($mallId, $page, $pageSize) {
return $this->queryPage('select * from %b where mall_id = %i order by pending_matter_category_id desc', $this->getTable(), $mallId, $page, $pageSize);
}
public function getAllByMallId($mallId) {
return $this->query('select * from %b where mall_id = %i order by pending_matter_category_id desc', $this->getTable(), $mallId);
}
}

@ -0,0 +1,40 @@
<?php
namespace Dao\PendingMatter;
use Dao\AbstractDao;
use ZcArrayHelper;
class PendingMatterDao extends AbstractDao {
public function getOrderSnAndCountMap($orderSns) {
if (empty($orderSns)) {
return [];
}
$orderSns = is_array($orderSns) ? $orderSns : [$orderSns];
$rows = $this->query('select order_sn, count(*) as pending_matter_count from %b where order_sn IN %ls and status = %s group by order_sn', $this->getTable(), $orderSns, \StatusConst::wait);
return ZcArrayHelper::changeKeyRow($rows, 'orderSn');
}
private function getSearchCondition($filter) {
$wheres = [];
if (!empty($filter['orderSn'])) {
$filterOrderSn = is_array($filter['orderSn']) ? $filter['orderSn'] : [$filter['orderSn']];
$wheres[] = $this->prepare('and pm.order_sn IN %ls', $filterOrderSn);
}
if (isset($filter['pendingMatterCategoryId']) && is_numeric($filter['pendingMatterCategoryId'])) {
$wheres[] = $this->prepare('and pm.pending_matter_category_id = %i', $filter['pendingMatterCategoryId']);
}
if (!empty($filter['status'])) {
$wheres[] = $this->prepare('and pm.status = %s', $filter['status']);
}
return $wheres;
}
public function searchPage($mallId, $filter, $page, $pageSize) {
$authMallIds = empty($filter['authMallIds']) ? [$mallId] : (is_array($filter['authMallIds']) ? $filter['authMallIds'] : [$filter['authMallIds']]);
$wheres = $this->getSearchCondition($filter);
$whereString = implode(' ', $wheres);
return $this->queryPage('select pm.* from %b pm where pm.mall_id IN %li %l order by pm.pending_matter_id desc', $this->getTable(), $authMallIds, $whereString, $page, $pageSize);
}
}

@ -2,10 +2,568 @@
namespace Service\AfterSale;
use AfterSalesConst;
use AppConst;
use CommonTool;
use Dao\AfterSale\AfterSalesDao;
use Dao\Common\LogisticsDao;
use Dao\Common\LogisticsPlatformDao;
use Dao\Mall\MallSDao;
use Dao\Order\OpOrderAllergyRefundDao;
use Dao\Order\OpOrderDao;
use Dao\Order\SearchConditionLogDao;
use Exception\BizException;
use OrderPrintConst;
use OrderPrintTool;
use PddApi;
use PermissionTool;
use PurchaseOrderConst;
use Repository\OrderPrint\OrderPrintRepository;
use Service\AbstractService;
use ZcArrayHelper;
use ZcDateHelper;
class AfterSaleService extends AbstractService {
private $mallSDao;
private $opOrderDao;
private $logisticsDao;
private $logisticsPlatformDao;
private $afterSalesDao;
private $searchConditionLogDao;
private $opOrderAllergyRefundDao;
private $orderPrintRepository;
protected function __construct() {
$this->mallSDao = MallSDao::instance();
$this->opOrderDao = OpOrderDao::instance();
$this->logisticsDao = LogisticsDao::instance();
$this->logisticsPlatformDao = LogisticsPlatformDao::instance();
$this->afterSalesDao = AfterSalesDao::instance();
$this->searchConditionLogDao = SearchConditionLogDao::instance();
$this->opOrderAllergyRefundDao = OpOrderAllergyRefundDao::instance();
$this->orderPrintRepository = OrderPrintRepository::instance();
}
private function getSearchAfterSalesListFilter($post, $operatorInfo) {
$mallId = $operatorInfo['mallId'];
$filter = [];
$tabType = $post['tabType'];
if (!empty($post['authMallIds'])) {
PermissionTool::checkMultiShopValid($mallId, $post['authMallIds']);
}
if (isset($post['shippingStatus']) && is_numeric($post['shippingStatus'])) {
$filter['shippingStatus'] = $post['shippingStatus'];
}
if (isset($post['afterSalesType']) && is_numeric($post['afterSalesType'])) {
$filter['afterSalesType'] = $post['afterSalesType'];
}
if (!empty($post['afterSalesStatus'])) {
$filter['afterSalesStatus'] = is_array($post['afterSalesStatus']) ? $post['afterSalesStatus'] : [$post['afterSalesStatus']];
}
if (!empty($post['orderSn'])) {
$filter['orderSn'] = CommonTool::convertValToArray($post['orderSn']);
}
if (!empty($post['afterSalesId'])) {
$filter['afterSalesId'] = CommonTool::convertValToArray($post['afterSalesId']);
}
if (!empty($post['goodsId'])) {
$filter['goodsId'] = $post['goodsId'];
}
if (!empty($post['recreatedAtStart'])) {
$filter['recreatedAtStart'] = ZcDateHelper::formatDate($post['recreatedAtStart']);
}
if (!empty($post['recreatedAtEnd'])) {
$filter['recreatedAtEnd'] = date('Y-m-d 23:59:59', strtotime($post['recreatedAtEnd']));
}
if (!empty($post['purchaseStartTime'])) {
$filter['purchaseStartTime'] = ZcDateHelper::formatDate($post['purchaseStartTime']);
}
if (!empty($post['purchaseEndTime'])) {
$filter['purchaseEndTime'] = date('Y-m-d 23:59:59', strtotime($post['purchaseEndTime']));
}
if (!empty($post['expireStartTime'])) {
$filter['expireStartTime'] = $post['expireStartTime'];
}
if (!empty($post['expireEndTime'])) {
$filter['expireEndTime'] = $post['expireEndTime'];
}
if (!empty($post['refundAmountStart'])) {
$filter['refundAmountStart'] = $post['refundAmountStart'];
}
if (!empty($post['refundAmountEnd'])) {
$filter['refundAmountEnd'] = $post['refundAmountEnd'];
}
if (!empty($post['purchasePlatform'])) {
$filter['purchasePlatform'] = $post['purchasePlatform'];
}
if (!empty($post['purchaseOrderSn'])) {
$filter['purchaseOrderSn'] = $post['purchaseOrderSn'];
}
if (!empty($post['purchaseOrderStatus'])) {
$filter['purchaseOrderStatus'] = $post['purchaseOrderStatus'];
}
if (isset($post['isPurchase']) && is_numeric($post['isPurchase'])) {
if($post['isPurchase'] == 1){
$filter['filterPurchaseStatus'] = array(PurchaseOrderConst::filterPurchaseStatusPartPurchase, PurchaseOrderConst::filterPurchaseStatusHasPurchase, PurchaseOrderConst::filterPurchaseStatusManualHasPurchase);
}else{
$filter['filterPurchaseStatus'] = array(PurchaseOrderConst::filterPurchaseStatusWaitPurchase);
}
}
if (!empty($post['receiverNameOrPhone'])) {
$receiverInfoFilter = [];
if (preg_match('/^[1-9]{1}\d{10}$/', $post['receiverNameOrPhone'])) {
$receiverInfoFilter['receiverPhone'] = $post['receiverNameOrPhone'];
} else {
$receiverInfoFilter['receiverName'] = $post['receiverNameOrPhone'];
}
$kmsSearchList = PddApi::getKmsSearchList($receiverInfoFilter, $operatorInfo['accessToken']);
if (!empty($kmsSearchList['receiverNameSearchText'])) {
$filter['receiverNameSearchText'] = $kmsSearchList['receiverNameSearchText'];
}
if (!empty($kmsSearchList['receiverMobileSearchText'])) {
$filter['receiverMobileSearchText'] = $kmsSearchList['receiverMobileSearchText'];
}
}
if (isset($post['speedRefundFlag']) && is_numeric($post['speedRefundFlag'])) {
$filter['speedRefundFlag'] = $post['speedRefundFlag'];
}
if (!empty($post['mallNote'])) {
$filter['mallNote'] = trim($post['mallNote']);
}
if (isset($post['hasMallNote']) && is_numeric($post['hasMallNote'])) {
$filter['hasMallNote'] = $post['hasMallNote'];
}
if (!empty($post['mallNoteFlag'])) {
$mallNoteFlag = array_filter($post['mallNoteFlag'], 'is_numeric');
if ($mallNoteFlag) {
$filter['mallNoteFlag'] = $mallNoteFlag;
}
}
if (!empty($post['sortType'])) {
$filter['sortType'] = $post['sortType'];
}
if (!empty($post['purchaseOrderBuyer'])) {
$filter['purchaseOrderBuyer'] = $post['purchaseOrderBuyer'];
}
if (!empty($post['trackingNumber'])) {
$filter['trackingNumbers'] = CommonTool::convertValToArray($post['trackingNumber']);
}
return $filter;
}
public function searchAfterSalesList($params, $operatorInfo) {
$mallId = $operatorInfo['mallId'];
$page = intval($params['page'] ?: 1);
$pageSize = intval($params['pageSize'] ?: 20);
$filter = $this->getSearchAfterSalesListFilter($params, $operatorInfo);
$this->searchConditionLogDao->add($mallId, OrderPrintConst::searchConditionBizCodeAfterSale, $params);
list($afterSalesList, $total, $isSlowQuery) = $this->afterSalesDao->searchPage($mallId, $filter, $page, $pageSize, true);
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
if ($isSlowQuery) {
throw new BizException('筛选订单数量太多,请减少店铺数量');
}
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
if (in_array(\Zc::C('appName'), [AppConst::appPddDz, AppConst::appPddDzOp, AppConst::appMsPddOp, AppConst::appMsPddOpEbill])) {
$afterSalesList = $this->getAfterSalesOpOrders($mallIds, $afterSalesList);
} else {
throw new BizException('暂未支持');
}
return [
'afterSalesList' => $afterSalesList,
'total' => $total,
];
}
public function getAfterSalesCount($params, $operatorInfo) {
$mallId = $operatorInfo['mallId'];
$mallIds = $params['authMallIds'] ? $params['authMallIds'] : array($mallId);
$filter = [
'authMallIds' => $mallIds,
'expireStartTime' => date('Y-m-d H:i:s', time()),
'expireEndTime' => date('Y-m-d H:i:s', strtotime('+ 24 hour')),
];
$expireCount = $this->afterSalesDao->getAfterSalesCount($mallId, $filter);
$afterSalesStatusCountMap = $this->afterSalesDao->getStatusCountMap($mallIds);
$filter = $this->getSearchAfterSalesListFilter($params, $operatorInfo);
$afterSalesTabAllCount = $this->afterSalesDao->getAfterSalesCount($mallId, $filter);
$platformAgreeRefundCount = $afterSalesStatusCountMap[AfterSalesConst::afterSalesStatusPlatformAgreeRefund];
$afterSalesTabRefundApplyProcessCount = $afterSalesStatusCountMap[AfterSalesConst::afterSalesStatusBuyerApplyRefund] ? : 0;
$afterSalesTabReturnGoodsProcessCount = $afterSalesStatusCountMap[AfterSalesConst::afterSalesStatusReturnRefund] ? : 0;
$afterSalesTabExchangeGoodsProcessCount = $afterSalesStatusCountMap[AfterSalesConst::afterSalesStatusExchangeGoodsWaitSellerProcess] ? : 0;
$afterSalesTabPlatformProcessCount = $afterSalesStatusCountMap[AfterSalesConst::afterSalesStatusPlatformProcessing] ? : 0;
$afterSalesTabOverdueWithin24HoursCount = $expireCount;
$filter = [
'authMallIds' => $mallIds,
'afterSalesType' => AfterSalesConst::afterSalesTypeRepair,
];
$afterSalesTabMaintainProcessCount = $this->afterSalesDao->getAfterSalesCount($mallId, $filter);
return [
'afterSalesTabAllCount' => $afterSalesTabAllCount,
'afterSalesTabRefundApplyProcessCount' => $afterSalesTabRefundApplyProcessCount,
'afterSalesTabReturnGoodsProcessCount' => $afterSalesTabReturnGoodsProcessCount,
'afterSalesTabExchangeGoodsProcessCount' => $afterSalesTabExchangeGoodsProcessCount,
'afterSalesTabOverdueWithin24HoursCount' => $afterSalesTabOverdueWithin24HoursCount,
'afterSalesTabMaintainProcessCount' => $afterSalesTabMaintainProcessCount,
'afterSalesTabPlatformProcessCount' => $afterSalesTabPlatformProcessCount,
'expireCount' => $expireCount,
'platformAgreeRefundCount' => $platformAgreeRefundCount,
];
}
private function getAfterSalesOpOrders($mallIds, $afterSalesList) {
$orderSns = array_unique(ZcArrayHelper::getSub($afterSalesList, 'orderSn'));
$orders = $this->opOrderDao->getListByOrderSns($orderSns);
$orders = $this->orderPrintRepository->rebuildOrderListIfHasOld($orders);
$orders = $this->orderPrintRepository->decryptOrders($orders);
$ordersAndOrderSnMap = ZcArrayHelper::changeKey($orders, 'orderSn');
$orderIds = array_unique(ZcArrayHelper::getSub($orders, 'orderId'));
$ordersGoodsList = $this->orderPrintRepository->getOpOrdersGoodsListByOrderIds($orderIds);
$mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
$returnAfterSales = [];
$logisticsIds = array_unique(array_filter(ZcArrayHelper::getSub($orders, 'logisticsId')));
$pddLogisticsIdAndNameMap = $this->logisticsDao->getCompanyIdAndNameMap($logisticsIds, AppConst::appPlatformPdd);
$allergyRefundOrderIds = $this->opOrderAllergyRefundDao->getOrderIdsByOrderIds($orderIds);
foreach ($afterSalesList as $afterSalesItem) {
$order = $ordersAndOrderSnMap[$afterSalesItem['orderSn']];
$orderId = $order['orderId'];
$fullAddress = OrderPrintTool::joinFullAddress($order['province'], $order['city'], $order['town'], $order['address']);
$orderGoods = ZcArrayHelper::changeKey($ordersGoodsList[$orderId], 'skuId');
$orderItems = [];
foreach ($orderGoods as $goods) {
$orderItems[] = array(
'orderId' => $goods['orderId'],
'mallId' => $goods['mallId'],
'goodsId' => $goods['goodsId'],
'skuId' => $goods['skuId'],
'skuName' => $goods['skuName'],
'goodsName' => $goods['goodsName'],
'goodsPrice' => $goods['goodsPrice'],
'skuSubName' => $goods['skuSubName'],
'itemTotal' => $goods['goodsCount'],
'totalPrice' => $goods['totalPrice'],
'goodsImg' => $goods['goodsImg'],
'shortWeight' => $goods['shortWeight'],
'goodsSpec' => $goods['goodsSpec'],
'url' => CommonTool::buildPddGoodsUrl($goods['goodsId']),
);
}
$returnAfterSales[] = [
'afterSalesId' => $afterSalesItem['afterSalesId'],
'orderSn' => $afterSalesItem['orderSn'],
'speedRefundStatus' => $afterSalesItem['speedRefundStatus'],
'shippingStatus' => $afterSalesItem['shippingStatus'],
'afterSalesType' => $afterSalesItem['afterSalesType'],
'recreatedAt' => $afterSalesItem['recreatedAt'],
'speedRefundFlag' => $afterSalesItem['speedRefundFlag'],
'afterSalesStatus' => $afterSalesItem['afterSalesStatus'],
'refundAmount' => $afterSalesItem['refundAmount'],
'expireTime' => $afterSalesItem['expireTime'],
'afterSaleReason' => $afterSalesItem['afterSaleReason'],
'orderPayment' => $order['payAmount'] + $order['platformDiscount'],
'receiverName' => $order['receiverName'],
'receiverPhone' => $order['receiverPhone'],
'fullAddress' => $fullAddress,
'mallName' => $mallIdAndMallNameMap[$afterSalesItem['mallId']],
'orderItems' => $orderItems,
'orderId' => $orderId,
'orderStatus' => $order['orderStatus'],
'refundStatus' => $order['refundStatus'],
'logisticsName' => $pddLogisticsIdAndNameMap[$order['logisticsId']] ? : '',
'trackingNumber' => $order['trackingNumber'],
'confirmTime' => $order['confirmTime'],
'refundTrackingNumber' => $afterSalesItem['trackingNumber'],
'refundLogisticsName' => $afterSalesItem['shippingName'],
'isAllergyRefundOrder' => in_array($orderId, $allergyRefundOrderIds) ? 1 : 0,
];
}
return $returnAfterSales;
}
private function getOdExportAfterSalesHeaders() {
return [
'所属店铺',
'退款订单号',
'申请时间',
'客户姓名',
'客户电话',
'客户地址',
'商品标题',
'商品ID',
'SKUID',
'数量',
'实付金额',
'退款金额',
'售后编号',
'订单状态',
'售后类型',
'售后状态',
'退款原因',
'采购平台',
'采购时间',
'采购账号',
'采购状态',
'采购订单号',
'采购姓名',
'采购电话',
'采购地址',
];
}
private function getOpExportAfterSalesHeaders() {
return [
'所属店铺',
'订单号',
'申请时间',
'收货人姓名',
'收货人电话',
'收货人地址',
'商品标题',
'商品ID',
'SKUID',
'数量',
'实付金额',
'退款金额',
'售后编号',
'订单状态',
'订单运单号',
'订单物流公司',
'售后类型',
'售后状态',
'退款原因',
'发货物流信息',
'退货物流信息',
'售后预期时间',
];
}
public function exportAfterSales() {
$pageSize = 20;
$page = 1;
$isOpApp = in_array(Zc::C('appName'), [AppConst::appPddDz, AppConst::appPddDzOp, AppConst::appMsPddOp, AppConst::appMsPddOpEbill]);
$cookieName = empty($_POST['cookieName']) ? 'exportAfterSales' : $_POST['cookieName'];
$objPHPExcel = new PHPExcel();
$headers = $isOpApp ? $this->getOpExportAfterSalesHeaders() : $this->getOdExportAfterSalesHeaders();
$activeSheet = ExcelTool::createNewSheetAndSetTitle($objPHPExcel, 0, '退款申请单');
ExcelTool::setSheetRowValues($activeSheet, 1, $headers);
$mallIds = $_POST['authMallIds'] ? $_POST['authMallIds'] : array($this->mallId);
$filterRet = $this->getSearchAfterSalesListFilter($_POST);
if (CommonTool::isFailRet($filterRet)) {
return $this->renderJSON($filterRet);
}
$filter = $filterRet['filter'];
$afterSalesList = [];
while (true) {
list($afterSalesChunk, $total) = $this->afterSalesService->searchAfterSalesList($this->mallId, $filter, $page, $pageSize);
if (!$afterSalesChunk) {
break;
}
$afterSalesList = array_merge($afterSalesList, $afterSalesChunk);
if (count($afterSalesChunk) < $pageSize) {
break;
}
$page ++;
}
if ($isOpApp) {
$afterSalesList = $this->getAfterSalesOpOrders($mallIds, $afterSalesList);
$this->packOpExportAfterSalesData($activeSheet, $afterSalesList);
} else {
$afterSalesList = $this->getAfterSalesPurchaseOrders($mallIds, $afterSalesList);
$this->packOdExportAfterSalesData($activeSheet, $afterSalesList);
}
ExcelTool::outputExcel($objPHPExcel, '导出售后单', $cookieName);
exit;
}
private function packOpExportAfterSalesData(&$activeSheet, $afterSalesList) {
$row = 2;
foreach ($afterSalesList as $afterSales) {
$column = 1;
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['mallName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['orderSn']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['recreatedAt']);
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['receiverName'], 'name'));
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['receiverPhone'], 'mobile'));
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['fullAddress'], 'address'));
foreach ($afterSales['orderItems'] as $orderItem) {
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['skuName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['goodsId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['skuId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['itemTotal']);
}
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['orderPayment']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['refundAmount']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['afterSalesId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, OrderConst::getOrderStatusText($afterSales['orderStatus'], $afterSales['refundStatus']));
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['trackingNumber']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['logisticsName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getAfterSalesTypeMap()[$afterSales['afterSalesType']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getAfterSalesStatusMap()[$afterSales['afterSalesStatus']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getAfterSalesTypeMap()[$afterSales['afterSaleReason']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['trackingNumber']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['refundTrackingNumber']);
if (!empty($afterSales['expireTime'])) {
$exireTime = strtotime($afterSales['expireTime']);
if ($exireTime > time()) {
$leftTime = $exireTime - time();
$leftDays = floor($leftTime / (3600 * 24));
$leftHours = floor(($leftTime % (3600 * 24)) / 3600);
$leftMinutes = floor((($leftTime % (3600 * 24)) % 3600) / 60);
$timeTip = '距逾期时间还剩';
if ($leftDays || $leftHours || $leftMinutes) {
$leftDays = $leftDays ? $leftDays . '天' : '';
$leftHours = $leftHours ? $leftHours . '时' : '';
$leftMinutes = $leftMinutes ? $leftMinutes . '分' : '';
$timeTip = $leftDays . $leftHours . $leftMinutes;
}
} else {
$timeTip = '已逾期';
}
ExcelTool::setCellValue($activeSheet, $column++, $row, $timeTip);
}
$row ++;
}
}
private function packOdExportAfterSalesData(&$activeSheet, $afterSalesList) {
$row = 2;
foreach ($afterSalesList as $afterSales) {
$column = 1;
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['mallName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['orderSn']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['recreatedAt']);
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['receiverName'], 'name'));
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['receiverPhone'], 'mobile'));
ExcelTool::setCellValue($activeSheet, $column++, $row, CommonTool::ensconceString($afterSales['fullAddress'], 'address'));
foreach ($afterSales['orderItems'] as $orderItem) {
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['skuName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['goodsId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['skuId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderItem['itemTotal']);
}
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['orderPayment']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['refundAmount']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['afterSalesId']);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getShippingStatusMap()[$afterSales['shippingStatus']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getAfterSalesTypeMap()[$afterSales['afterSalesType']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, AfterSalesConst::getAfterSalesStatusMap()[$afterSales['afterSalesStatus']]);
ExcelTool::setCellValue($activeSheet, $column++, $row, $afterSales['afterSaleReason']);
foreach ($afterSales['purchaseOrders'] as $purchaseOrder) {
$platformName = PurchaseOrderConst::getPurchasePlatformName($purchaseOrder['purchasePlatform']);
$purchaseOrderStatus = '';
if ($purchaseOrder['purchaseOrderStatus'] == PurchaseOrderConst::purchaseOrderStatusHasSend) {
$purchaseOrderStatus = $platformName . '已发货';
} elseif ($purchaseOrder['purchaseOrderStatus'] == PurchaseOrderConst::purchaseOrderStatusFinished) {
$purchaseOrderStatus = $platformName . '已完成';
} elseif ($purchaseOrder['purchaseOrderStatus'] == PurchaseOrderConst::purchaseOrderStatusCancel) {
$purchaseOrderStatus = $platformName . '已关闭';
} elseif ($purchaseOrder['purchaseOrderStatus'] == PurchaseOrderConst::purchaseOrderStatusRefund) {
$purchaseOrderStatus = $platformName . '退款中';
} else {
$purchaseOrderStatus = $platformName . '未发货';
}
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchasePlatform']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderStartTime']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderBuyer']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrderStatus);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderSn']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderFullname']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderMobile']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $purchaseOrder['purchaseOrderFullAddress']);
}
$row ++;
}
}
public function saveDefaultAdditionalAfterSalesColumns() {
$subAccountId = $_SESSION[SessionConst::mallSubAccountId];
$ret = $this->orderPrintService->saveUserDefaultAdditionalAfterSalesColumns($this->mallId, $subAccountId, $_POST['fields']);
if (!$ret) {
return $this->renderJSON(CommonTool::failResult('保存默认展示字段失败'));
}
return $this->renderJSON(CommonTool::successResult());
}
public function triggerRsyncAfterSales() {
$multiShopOptions = $this->mallService->getMultiShopOptions($this->mallId, $_SESSION[SessionConst::mallName], $_SESSION[SessionConst::mallSubAccountId]);
foreach ($multiShopOptions as $authMallId => $shopName) {
$this->opOrderService->tryRsyncAfterSales($authMallId);
}
return $this->renderJSON(CommonTool::successResult());
}
public function checkRsyncAfterSalesFinish() {
$multiShopOptions = $this->mallService->getMultiShopOptions($this->mallId, $_SESSION[SessionConst::mallName], $_SESSION[SessionConst::mallSubAccountId]);
$authMallIds = array_keys($multiShopOptions);
$queueCount = $this->afterSalesService->getAfterSalesRsyncQueueCount($authMallIds);
$ret = CommonTool::successResult([
'status' => $queueCount ? StatusConst::process : StatusConst::finish
]);
return $this->renderJSON($ret);
}
public function updateAfterSaleMallNote() {
$afterSalesId = $_POST['afterSalesId'] ?: null;
$flag = $_POST['flag'] ?: 0;
$mallNote = $_POST['mallNote'] ?: '';
$afterSalesInfo = $this->afterSalesService->getAfterSalesInfoByAfterSalesId($afterSalesId);
if (strlen($mallNote) > 200) {
return $this->renderJSON(CommonTool::failResult('备注信息不能超过200个字符'));
}
if (empty($afterSalesInfo)) {
return $this->renderJSON(CommonTool::failResult('售后不存在'));
}
$checkRet = $this->mallUtil->checkMultiShopValid($this->mallId, array($afterSalesInfo['mall_id']));
if (CommonTool::isFailRet($checkRet)) {
return $this->renderJSON($checkRet);
}
$ret = $this->afterSalesService->updateAfterSaleMallNote($afterSalesId, $flag, $mallNote);
return $this->renderJSON($ret);
}
}

@ -0,0 +1,553 @@
<?php
namespace Service\FulfillmentOrder;
use AppConst;
use CommonTool;
use Dao\Common\LogisticsDao;
use Dao\Common\LogisticsPlatformDao;
use Dao\FulfillmentOrder\FulfillmentOrderCollectLogDao;
use Dao\FulfillmentOrder\FulfillmentOrderDao;
use Dao\FulfillmentOrder\FulfillmentOrderExtDao;
use Dao\FulfillmentOrder\FulfillmentOrderGoodsLabelCodeDao;
use Dao\FulfillmentOrder\FulfillmentOrderInsensitiveInfoDao;
use Dao\FulfillmentOrder\FulfillmentOrderOutstorageHistoryDao;
use Dao\FulfillmentOrder\FulfillmentOrderOutstorageStopDao;
use Dao\FulfillmentOrder\OpPrintGoodsLabelCodeLogDao;
use Dao\FulfillmentOrder\OpSysFulfillmentGoodsLabelCodeTplDao;
use Dao\Mall\MallSDao;
use DbTool;
use Exception\BizException;
use Exception\CheckClientException;
use FulfillmentOrderConst;
use FulfillmentOrderTool;
use LogisticsConst;
use OrderConst;
use OrderPrintTool;
use PddApi;
use PermissionTool;
use Repository\Mall\MallRepository;
use Service\AbstractService;
use StatusConst;
use ZcArrayHelper;
use ZcDateHelper;
class FulfillmentOrderService extends AbstractService {
private $mallSDao;
private $fulfillmentOrderDao;
private $fulfillmentOrderExtDao;
private $fulfillmentOrderInsensitiveInfoDao;
private $logisticsDao;
private $logisticsPlatformDao;
private $fulfillmentOrderOutstorageStopDao;
private $fulfillmentOrderOutstorageHistoryDao;
private $fulfillmentOrderCollectLogDao;
private $fulfillmentOrderGoodsLabelCodeDao;
private $opSysFulfillmentGoodsLabelCodeTplDao;
private $opPrintGoodsLabelCodeLogDao;
private $mallRepository;
protected function __construct() {
$this->mallSDao = MallSDao::instance();
$this->fulfillmentOrderDao = FulfillmentOrderDao::instance();
$this->fulfillmentOrderExtDao = FulfillmentOrderExtDao::instance();
$this->fulfillmentOrderInsensitiveInfoDao = FulfillmentOrderInsensitiveInfoDao::instance();
$this->logisticsDao = LogisticsDao::instance();
$this->logisticsPlatformDao = LogisticsPlatformDao::instance();
$this->fulfillmentOrderOutstorageStopDao = FulfillmentOrderOutstorageStopDao::instance();
$this->fulfillmentOrderOutstorageHistoryDao = FulfillmentOrderOutstorageHistoryDao::instance();
$this->fulfillmentOrderCollectLogDao = FulfillmentOrderCollectLogDao::instance();
$this->fulfillmentOrderGoodsLabelCodeDao = FulfillmentOrderGoodsLabelCodeDao::instance();
$this->opSysFulfillmentGoodsLabelCodeTplDao = OpSysFulfillmentGoodsLabelCodeTplDao::instance();
$this->opPrintGoodsLabelCodeLogDao = OpPrintGoodsLabelCodeLogDao::instance();
$this->mallRepository = MallRepository::instance();
}
public function searchOrderList($mallId, $params) {
$page = intval($params['page'] ?: 1);
$pageSize = intval($params['pageSize'] ?: 20);
$filter = $this->getSearchOrderFilter($mallId, $params);
list($orderList, $total) = $this->fulfillmentOrderDao->searchPage($mallId, $filter, $page, $pageSize);
if (empty($orderList)) {
return [
'orderList' => $orderList,
'total' => $total,
];
}
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
$fulfillmentOrderIds = ZcArrayHelper::getSub($orderList, 'fulfillmentOrderId');
$fulfillmentOrderIdAndReceiverInfoMap = $this->fulfillmentOrderInsensitiveInfoDao->getFulfillmentOrderIdAndReceiverInfoMap($fulfillmentOrderIds);
$mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
foreach ($orderList as &$order) {
$receiverInfo = $fulfillmentOrderIdAndReceiverInfoMap[$order['fulfillmentOrderId']];
$order['mallName'] = $mallIdAndMallNameMap[$order['mallIid']];
$order['receiverName'] = $receiverInfo['receiverName'] ? : '';
$order['receiverPhone'] = $receiverInfo['receiverPhone'] ?: '';
$order['receiverAddress'] = $receiverInfo['receiverAddress'] ?: '';
$order['realReceiverName'] = $receiverInfo['receiverNameS'] ? CommonTool::decrypt($receiverInfo['receiverNameS']) : '';
$order['realReceiverPhone'] = $receiverInfo['receiverPhoneS'] ? CommonTool::decrypt($receiverInfo['receiverPhoneS']) : '';
$order['realReceiverAddress'] = $receiverInfo['receiverAddressS'] ? CommonTool::decrypt($receiverInfo['receiverAddressS']) : '';
}
$orderList = ZcArrayHelper::rebuildArrayKeyToCamelCase($orderList);
return [
'orderList' => $orderList,
'total' => $total,
];
}
private function getSearchOrderFilter($mallId, $params) {
$filter = [];
$params['authMallIds'] = empty($params['authMallIds']) ? array($mallId) : (is_array($params['authMallIds']) ? $params['authMallIds'] : explode(',', $params['authMallIds']));
PermissionTool::checkMultiShopValid($mallId, $params['authMallIds']);
$filter['authMallIds'] = $params['authMallIds'];
if ($params['orderTab'] == FulfillmentOrderConst::orderTabWaitSend) {
$filter['fulfillmentStatus'] = FulfillmentOrderConst::fulfillmentOrderStatusWaitSellerSendGoods;
} elseif ($params['orderTab'] == FulfillmentOrderConst::orderTabHasSend) {
$filter['fulfillmentStatus'] = FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods;
} elseif ($params['orderTab'] == FulfillmentOrderConst::orderTabFinished) {
$filter['fulfillmentStatus'] = FulfillmentOrderConst::fulfillmentOrderStatusFinished;
}
if (!empty($params['fulfillmentSn'])) {
$filter['fulfillmentSn'] = is_array($params['fulfillmentSn']) ? $params['fulfillmentSn'] : CommonTool::splitWithComma($params['fulfillmentSn']);
unset($filter['fulfillmentStatus']);
}
if (empty($params['orderStartTime'])) {
$params['orderStartTime'] = date('Y-m-d H:i:s', strtotime('-7 days'));
}
if (!empty($params['orderStartTime'])) {
$filter['orderStartTime'] = ZcDateHelper::formatDate($params['orderStartTime']);
}
if (!empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
if (empty($params['orderFilterDatePickTime'])) {
$filter['orderEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
} else {
$filter['orderEndTime'] = ZcDateHelper::formatDate($params['orderEndTime']);
}
}
if (!empty($params['goodsId'])) {
$filter['goodsId'] = is_array($params['goodsId']) ? $params['goodsId'] : CommonTool::splitWithComma($params['goodsId']);
}
if (!empty($params['goodsName'])) {
$filter['goodsName'] = $params['goodsName'];
}
if (!empty($params['sellerNote'])) {
$filter['sellerNote'] = trim($params['sellerNote']);
}
if (!empty($params['sortType'])) {
$filter['sortType'] = trim($params['sortType']);
}
if ($params['promiseDeliveryTimeFilter']) {
$filter['promiseDeliveryTimeFilter'] = $params['promiseDeliveryTimeFilter'];
}
if ($params['goodsLabelCodePrintFilter']) {
$filter['goodsLabelCodePrintFilter'] = $params['goodsLabelCodePrintFilter'];
}
if (!empty($params['delaySendStatus'])) {
if ($params['delaySendStatus'] == FulfillmentOrderConst::willDelaySend) {
$filter['promiseDeliveryTimeFilter'] = FulfillmentOrderConst::promiseDeliverTimeOneDay;
} elseif ($params['delaySendStatus'] == FulfillmentOrderConst::hasDelaySend) {
$filter['promiseDeliveryTimeFilter'] = FulfillmentOrderConst::promiseDeliverTimeOvertime;
} elseif ($params['delaySendStatus'] == FulfillmentOrderConst::courierCollect) {
$filter['courierDoorToDoorCollect'] = 1;
}
}
return $filter;
}
public function getOrderCountMap($mallId, $params) {
$filter = $this->getSearchOrderFilter($mallId, $params);
$mallIds = $filter['authMallIds'] ? $filter['authMallIds'] : array($mallId);
$orderStatusAndOrderCountMap = $this->fulfillmentOrderDao->getStatusAndOrderCountMap($mallIds);
$willDelaySendOrderCount = $this->fulfillmentOrderDao->getWillDelaySendOrderCount($mallIds);
$hasDelaySendOrderCount = $this->fulfillmentOrderDao->getHasDelaySendOrderCount($mallIds);
$courierCollectOrderCount = $this->fulfillmentOrderDao->getCourierCollectOrderCount($mallIds);
return [
'waitSendOrderCount' => $orderStatusAndOrderCountMap[FulfillmentOrderConst::fulfillmentOrderStatusWaitSellerSendGoods] ?: 0,
'hasSendOrderCount' => $orderStatusAndOrderCountMap[FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods] ?: 0,
'finishOrderCount' => $orderStatusAndOrderCountMap[FulfillmentOrderConst::fulfillmentOrderStatusFinished] ?: 0,
'willDelaySendOrderCount' => $willDelaySendOrderCount,
'hasDelaySendOrderCount' => $hasDelaySendOrderCount,
'courierCollectOrderCount' => $courierCollectOrderCount,
];
}
public function saveBatchSellerNote($mallId, $params) {
$fulfillmentOrderIds = $params['fulfillmentOrderIds'];
$note = $params['note'];
$coverOriginal = (int)$params['coverOriginal'];
if (empty($fulfillmentOrderIds)) {
throw new CheckClientException('请先选择订单');
}
if (mb_strlen($note, 'utf-8') > 500) {
throw new CheckClientException('便笺信息不能超过500个字');
}
$orders = $this->fulfillmentOrderDao->getMapByIds($fulfillmentOrderIds);
$autoMallIds = array_values(array_unique(ZcArrayHelper::getSub($orders, 'mallId')));
PermissionTool::checkMultiShopValid($mallId, $autoMallIds);
$errorMap = array();
$successCount = 0;
foreach ($fulfillmentOrderIds as $fulfillmentOrderId) {
if (!isset($orders[$fulfillmentOrderId])) {
$errorMap[$fulfillmentOrderId] = '订单不存在';
continue;
}
$order = $orders[$fulfillmentOrderId];
$orderMallId = $order['mallId'];
$updateNote = $note;
if (!$coverOriginal) {
$updateNote = $order ? ($order['sellerNote'] . $updateNote) : $updateNote;
}
if (mb_strlen($updateNote, 'utf-8') > 500) {
$errorMap[$fulfillmentOrderId] = '便笺信息不能超过500个字';
continue;
}
$updateRet = $this->updateFulfillmentOrderSellerNote($orderMallId, $fulfillmentOrderId, $updateNote);
if (!$updateRet) {
$errorMap[$fulfillmentOrderId] = '更新失败';
continue;
}
$successCount ++;
}
return [
'successCount' => $successCount,
'errorCount' => count($errorMap),
'errorMap' => $errorMap,
'newNote' => $updateNote,
];
}
public function updateFulfillmentOrderSellerNote($mallId, $fulfillmentOrderId, $sellerNote) {
if (empty($mallId) || empty($fulfillmentOrderId)) {
return false;
}
$order = $this->fulfillmentOrderDao->getById($fulfillmentOrderId);
if (!$order || $order['mallId'] != $mallId) {
return false;
}
$update = array(
'seller_note' => $sellerNote,
);
$ret = $this->fulfillmentOrderDao->update($update, 'fulfillment_order_id = %i', $fulfillmentOrderId);
return $ret === false ? false : true;
}
public function getRefundAddressList($mallId, $operatorInfo) {
$operatorMallId = $operatorInfo['mallId'];
if ($operatorMallId == $mallId) {
$accessToken = $operatorInfo['accessToken'];
} else {
$authMalls = PermissionTool::checkMultiShopValid($operatorMallId, [$mallId]);
$accessToken = $authMalls[$mallId]['accessToken'];
}
return PddApi::getRefundAddressList($accessToken);
}
public function manualOrderOutStorage($mallId, $params) {
$orderId = $params['orderId'];
$logisticsId = $params['logisticsId'];
$expressNo = $params['expressNo'];
$refundAddressId = $params['refundAddressId'] ?: null;
$redeliveryType = $params['isUpdate'] ? FulfillmentOrderConst::orderLogisticsSendRedeliveryTypeModify : FulfillmentOrderConst::orderLogisticsSendRedeliveryTypeFirst;
$orders = $this->fulfillmentOrderDao->getMapByIds([$orderId]);
$authMallIds = array_values(array_unique(ZcArrayHelper::getSub($orders, 'mallId')));
$authMalls = PermissionTool::checkMultiShopValid($mallId, $authMallIds);
$order = $orders[$orderId];
$accessToken = $authMalls[$order['mallId']]['accessToken'];
$companyId = $this->logisticsPlatformDao->getCompanyCodeByLogisticsId([$logisticsId], \AppConst::appPlatformPdd);
$deliveryInfo = FulfillmentOrderTool::buildDeliveryInfo($order['fulfillmentSn'], $logisticsId, $companyId, $expressNo, $refundAddressId, $redeliveryType);
$this->logisticsSend($order['mallId'], $mallId, $deliveryInfo, $accessToken, FulfillmentOrderConst::outstorageSourceManual);
}
public function logisticsSend($mallId, $operatorMallId, $deliveryInfo, $accessToken, $source = '', $needRetry = false) {
if (CommonTool::anyEmpty($mallId, $operatorMallId, $deliveryInfo, $accessToken)) {
throw new CheckClientException('参数错误');
}
$this->checkLogisticsSend($mallId, $deliveryInfo);
for ($i = 0; $i < 3; $i++) {
$outstorageRet = PddApi::fulfillmentSend($deliveryInfo, $accessToken);
if (CommonTool::isSuccessRet($outstorageRet)) {
break;
}
$failReason = $outstorageRet['reason'];
if (preg_match('/(商家后台发货|订单已发货|当前发货单不支持发货)/isU', $failReason)) {
$this->fulfillmentOrderOutstorageStopDao->add($mallId, $deliveryInfo['fulfillmentSn'], $failReason);
break;
}
if (!$needRetry) {
break;
}
if (preg_match('/重试/', $failReason)) {
sleep(10);
continue;
}
}
$this->addFulfillmentOrderOutstorageHistory($mallId, $operatorMallId, $deliveryInfo, $outstorageRet, $source);
if (CommonTool::isSuccessRet($outstorageRet)) {
$this->updateFulfillmentOrderCollectLog($deliveryInfo['fulfillmentSn'], $deliveryInfo['logisticsId'], $deliveryInfo['trackingNumber']);
} else {
throw new BizException($outstorageRet['reason']);
}
}
private function checkLogisticsSend($mallId, $deliveryInfo) {
if ($deliveryInfo['redeliveryType'] == OrderConst::orderLogisticsSendRedeliveryTypeFirst) {
$fulfillmentSn = $deliveryInfo['fulfillmentSn'];
$orderOutstorageStop = $this->fulfillmentOrderOutstorageStopDao->getByFulfillmentSn($mallId, $fulfillmentSn);
if ($orderOutstorageStop) {
throw new BizException($orderOutstorageStop['reason']);
}
$order = $this->fulfillmentOrderDao->getByFulfillmentSn($fulfillmentSn);
if (in_array($order['fulfillmentStatus'], [FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods, FulfillmentOrderConst::fulfillmentOrderStatusFinished])) {
$failReason = $order['fulfillmentStatus'] == FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods ? '订单已发货' : '订单已签收';
$this->fulfillmentOrderOutstorageStopDao->add($mallId, $fulfillmentSn, $failReason);
return CommonTool::failResult($failReason);
throw new BizException($failReason);
}
}
$logisticsInfo = $this->logisticsPlatformDao->getByCompanyId($deliveryInfo['companyId'], AppConst::appPlatformPdd);
if (empty($logisticsInfo)) {
throw new CheckClientException('发货物流公司未找到');
}
}
public function addFulfillmentOrderOutstorageHistory($mallId, $operatorMallId, $deliveryInfo, $outstorageRet, $source = '') {
$status = CommonTool::isSuccessRet($outstorageRet) ? StatusConst::success : StatusConst::fail;
$trans = DbTool::beginTrans(FulfillmentOrderDao::tableName());
$this->fulfillmentOrderOutstorageHistoryDao->insert(array(
'mall_id' => $mallId,
'fulfillment_sn' => $deliveryInfo['fulfillmentSn'],
'logistics_id' => $deliveryInfo['logisticsId'],
'company_id' => $deliveryInfo['companyId'],
'express_no' => $deliveryInfo['trackingNumber'],
'source' => $source,
'status' => $status,
'reason' => $outstorageRet['reason'],
'detail' => $outstorageRet['detail'],
'is_cover_old_logistics' => $deliveryInfo['redeliveryType'] == FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods ? 1 : 0,
'operator_mall_id' => $operatorMallId,
'gmt_outstorage' => \ZcDbEval::now(),
));
if ($status == \StatusConst::success) {
//更新订单信息
$update = [
'tracking_number' => $deliveryInfo['trackingNumber'],
'gmt_modified' => \ZcDbEval::now()
];
if ($deliveryInfo['redeliveryType'] == FulfillmentOrderConst::orderLogisticsSendRedeliveryTypeFirst) {
$update['fulfillment_status'] = FulfillmentOrderConst::fulfillmentOrderStatusWaitBuyerConfirmGoods;
}
$this->fulfillmentOrderDao->update($update, 'mall_id = %i and order_sn = %s', $mallId, $deliveryInfo['orderSn']);
}
DbTool::commitTrans($trans);
}
private function updateFulfillmentOrderCollectLog($fulfillmentOrderSn, $logisticsId, $expressNo) {
$order = $this->fulfillmentOrderDao->getByFulfillmentSn($fulfillmentOrderSn);
if (empty($order)) {
return false;
}
$log = $this->fulfillmentOrderCollectLogDao->getByFulfillmentOrderId($order['fulfillmentOrderId']);
if (empty($log)) {
return false;
}
return $this->fulfillmentOrderCollectLogDao->update([
'logistics_id' => $logisticsId,
'express_no' => $expressNo,
'shipping_time' => \ZcDbEval::now(),
], 'fulfillment_order_id = %i', $order['fulfillmentOrderId']);
}
public function searchOutstorageLog($mallId, $params) {
$page = intval($params['page'] ?: 1);
$pageSize = intval($params['pageSize'] ?: 20);
$filter = $this->getSearchLogFilter($mallId, $params);
list($outstorageRows, $total) = $this->fulfillmentOrderOutstorageHistoryDao->searchPage($mallId, $filter, $page, $pageSize);
$outstorageRows = $this->buildUserOutstorageLog($outstorageRows);
return [
'outstorageRows' => $outstorageRows,
'total' => $total,
];
}
public function buildUserOutstorageLog($rows) {
$mallIds = array_column($rows, 'mallId');
$mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
$logisticsMap = $this->logisticsDao->getLogisticsMap();
foreach ($rows as &$row) {
$row['mallName'] = $mallIdAndMallNameMap[$row['mallId']];
$row['logisticsName'] = $logisticsMap[$row['logisticsId']];
}
return $rows;
}
private function getSearchLogFilter($mallId, $data) {
$filter = array();
if ($data['isMultiShop']) {
$data['authMallIds'] = empty($data['authMallIds']) ? array($mallId) : $data['authMallIds'];
PermissionTool::checkMultiShopValid($mallId, $data['authMallIds']);
$filter['authMallIds'] = $data['authMallIds'];
}
$filter['isMultiShop'] = $data['isMultiShop'];
if ($data['logIds']) {
$filter['logIds'] = $data['logIds'];
}
if ($data['startTime']) {
$pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})\s+([0-9]{2})\:([0-9]{2})\:([0-9]{2})$/';
if (preg_match($pattern, $data['startTime'])) {
$filter['startTime'] = $data['startTime'];
} else {
$filter['startTime'] = date('Y-m-d 00:00:00', strtotime($data['startTime']));
}
}
if ($data['endTime']) {
$pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})\s+([0-9]{2})\:([0-9]{2})\:([0-9]{2})$/';
if (preg_match($pattern, $data['endTime'])) {
$filter['endTime'] = $data['endTime'];
} else {
$filter['endTime'] = date('Y-m-d 23:59:59', strtotime($data['endTime']));
}
}
if ($data['fulfillmentSn']) {
$filter['fulfillmentSn'] = CommonTool::convertValToArray($data['fulfillmentSn']);
}
if ($data['logisticsId']) {
$filter['logisticsId'] = $data['logisticsId'];
}
if ($_POST['waybillCode']) {
$filter['waybillCode'] = CommonTool::convertValToArray($data['waybillCode']);
}
if ($_POST['waybillCodes']) {
$filter['waybillCodes'] = CommonTool::convertValToArray($data['waybillCodes']);
}
if ($data['status']) {
$filter['status'] = $data['status'];
}
return $filter;
}
public function getGoodsLabelCodeTplDetail() {
$fulfillmentSn = $_POST['fulfillmentSn'];
$goodsLabelCodeInfo = $this->fulfillmentOrderGoodsLabelCodeDao->getByFulfillmentSn($fulfillmentSn);
if (empty($goodsLabelCodeInfo)) {
throw new BizException('获取商品标签失败');
}
$tpl = $this->opSysFulfillmentGoodsLabelCodeTplDao->getDefault();
if (empty($tpl)) {
throw new BizException('获取商品标签模板失败');
}
$tplData = OrderPrintTool::convertTplInfo($tpl);
$goodsLabelCodeInfo = ZcArrayHelper::rebuildArrayKeyToCamelCase($goodsLabelCodeInfo);
$tplData['nodes'] = $this->buildNodePrintText($tplData['nodes'], $goodsLabelCodeInfo);
return [
'tplData' => empty($tplData) ? null : $tplData,
'goodsLabelCodeInfo' => $goodsLabelCodeInfo
];
}
private function buildNodePrintText($nodes, $goodsLabelCodeInfo) {
foreach ($nodes as &$node) {
switch ($node['nv']['field']) {
case LogisticsConst::labelCodeBarcode:
$node['printText'] = $goodsLabelCodeInfo['labelCode'];
break;
case LogisticsConst::bgProdSkcId:
$node['printText'] = $goodsLabelCodeInfo['bgProdSkcId'];
break;
case LogisticsConst::spec:
$node['printText'] = $goodsLabelCodeInfo['spec'];
break;
case LogisticsConst::bgProdSkuId:
$node['printText'] = $goodsLabelCodeInfo['bgProdSkuId'];
break;
case LogisticsConst::madeIn:
$node['printText'] = $goodsLabelCodeInfo['madeIn'];
break;
case LogisticsConst::clothesSpec:
$node['printText'] = $goodsLabelCodeInfo['clothesSpec'];
break;
}
}
return $nodes;
}
public function updateGoodsLabelCodePrintStatus($operateMallId, $params) {
$fulfillmentSn = $params['fulfillmentSn'];
$printRet = $params['printRet'];
$isPreview = $params['isPreview'] ? 1 : 0;
$printStatus = CommonTool::isFailRet($printRet) ? StatusConst::fail : StatusConst::success;
$printReason = isset($printRet['reason']) ? $printRet['reason'] : null;
$fulfillmentOrderInfo = $this->fulfillmentOrderDao->getByFulfillmentSn($fulfillmentSn);
$trans = DbTool::beginTrans(FulfillmentOrderExtDao::instance());
$insertDto = [
'mall_id' => $fulfillmentOrderInfo['mallId'],
'fulfillment_sn' => $fulfillmentOrderInfo['fulfillmentSn'],
'operator_mall_id' => $operateMallId,
'status' => $printStatus,
'reason' => $printReason,
'is_preview' => $isPreview,
];
$this->opPrintGoodsLabelCodeLogDao->insert($insertDto);
$extUpdateDto = [
'mall_id' => $fulfillmentOrderInfo['mall_id'],
'fulfillment_sn' => $fulfillmentOrderInfo['fulfillment_sn'],
'filter_goods_label_code_printed' => 1,
];
$this->fulfillmentOrderExtDao->insertUpdate($extUpdateDto);
DbTool::commitTrans($trans);
}
public function searchGoodsLabelCodePrintLog($mallId, $params) {
$page = intval($params['page'] ?: 1);
$pageSize = intval($params['pageSize'] ?: 20);
$filter = $this->getSearchLogFilter($mallId, $params);
list($goodsLabelCodePrintLogRows, $total) = $this->fulfillmentOrderGoodsLabelCodeDao->searchPage($mallId, $filter, $page, $pageSize);
$goodsLabelCodePrintLogRows = $this->buildGoodsLabelCodePrintLog($goodsLabelCodePrintLogRows);
return [
'goodsLabelCodePrintLogRows' => $goodsLabelCodePrintLogRows,
'total' => $total,
];
}
private function buildGoodsLabelCodePrintLog($rows) {
$rows = $this->mallRepository->appendMallFields($rows);
return $rows;
}
}

File diff suppressed because it is too large Load Diff

@ -413,6 +413,51 @@ class OrderSendService extends AbstractService {
return $this->opOrderOutstorageTaskDao->getMallProcessingTask($mallId);
}
public function orderOutstoragePreManual($mallId, $deliveryInfos) {
$orderIds = ZcArrayHelper::getSub($deliveryInfos, 'orderId');
$logisticsIds = ZcArrayHelper::getSub($deliveryInfos, 'logisticsId');
$logisticsIdCompanyIdMap = $this->logisticsPlatformDao->getLogisticsIdAndCompanyIdMap($logisticsIds, AppConst::appPlatformPdd);
$orders = $this->opOrderDao->getMapByIds($orderIds);
$authMallIds = array_values(array_unique(ZcArrayHelper::getSub($orders, 'mallId')));
$authMalls = PermissionTool::checkMultiShopValid($mallId, $authMallIds);
$orderSnErrorMap = [];
$fCnt = 0;
$sCnt = 0;
foreach ($deliveryInfos as $data) {
$orderId = $data['orderId'];
$order = $orders[$orderId];
$expressNo = $data['expressNo'];
$logisticsId = $data['logisticsId'];
$accessToken = $authMalls[$order['mallId']]['accessToken'];
$companyId = $logisticsIdCompanyIdMap[$logisticsId];
if (empty($expressNo)) {
$orderSnErrorMap[$order['orderSn']] = '运单号为空';
$fCnt++;
continue;
}
$deliveryInfo = $this->buildDeliveryInfo($order['orderSn'], $logisticsId, $companyId, $expressNo);
$updateRet = $this->logisticsSend($order['mallId'], $mallId, $deliveryInfo, $accessToken, null, false, PurchaseOrderConst::outstorageSourcePreManual);
if (CommonTool::isSuccessRet($updateRet)) {
// TODO
// $this->opOrderService->rsyncOpOrderByOrderSns($order['mallId'], [$data['orderSn']], $accessToken);
$sCnt ++;
} else {
$orderSnErrorMap[$order['orderSn']] = $updateRet['reason'];
$fCnt ++;
}
}
return [
'orderSnErrorMap' => $orderSnErrorMap,
'fCnt' => $fCnt,
'sCnt' => $sCnt
];
}
public function orderOutstorage($deliveryInfos, $source, $operatorInfo, $isReturn = false) {
$operatorMallId = $operatorInfo['mallId'];

@ -0,0 +1,308 @@
<?php
namespace Service\OrderPrint;
use CommonTool;
use Dao\Mall\MallSDao;
use Dao\Order\OpOrderDao;
use Dao\PendingMatter\PendingMasterQueueDao;
use Dao\PendingMatter\PendingMatterBufferDao;
use Dao\PendingMatter\PendingMatterCategoryDao;
use Dao\PendingMatter\PendingMatterDao;
use DbTool;
use ExcelTool;
use Exception\BizException;
use Exception\CheckClientException;
use PermissionTool;
use Service\AbstractService;
use StatusConst;
use ZcArrayHelper;
class PendingMatterService extends AbstractService {
private $mallSDao;
private $opOrderDao;
private $pendingMatterDao;
private $pendingMatterCategoryDao;
private $pendingMatterBufferDao;
private $pendingMasterQueueDao;
protected function __construct() {
$this->mallSDao = MallSDao::instance();
$this->opOrderDao = OpOrderDao::instance();
$this->pendingMatterDao = PendingMatterDao::instance();
$this->pendingMatterCategoryDao = PendingMatterCategoryDao::instance();
$this->pendingMatterBufferDao = PendingMatterBufferDao::instance();
$this->pendingMasterQueueDao = PendingMasterQueueDao::instance();
}
public function deletePendingMatterCategory($mallId, $pendingMatterCategoryId) {
if (CommonTool::anyEmpty($mallId, $pendingMatterCategoryId)) {
throw new CheckClientException('参数错误');
}
$trans = DbTool::beginTrans(PendingMatterDao::instance());
$this->pendingMatterCategoryDao->delete('pending_matter_category_id = %i and mall_id = %i', $pendingMatterCategoryId, $mallId);
$updatePendingMatterData = [
'pending_matter_category_id' => 0,
];
$this->pendingMatterDao->update($updatePendingMatterData, 'pending_matter_category_id = %i', $pendingMatterCategoryId);
DbTool::commitTrans($trans);
}
public function savePendingMatterCategory($mallId, $pendingMatterCategoryId, $categoryName) {
if (CommonTool::anyEmpty($mallId, $categoryName)) {
throw new CheckClientException('参数错误');
}
$data = [
'mall_id' => $mallId,
'category_name' => $categoryName,
];
if ($pendingMatterCategoryId) {
$affect = $this->pendingMatterCategoryDao->update($data, 'pending_matter_category_id = %i and mall_id = %i', $pendingMatterCategoryId, $mallId);
} else {
$affect = $this->pendingMatterCategoryDao->insert($data);
}
if ($affect === false) {
throw new BizException('保存失败');
}
}
public function searchPendingMatterCategoryList($mallId, $page, $pageSize) {
return $this->pendingMatterCategoryDao->searchPage($mallId, $page, $pageSize);
}
public function getAllPendingMatterCategoryList($mallId) {
return $this->pendingMatterCategoryDao->getAllByMallId($mallId);
}
public function getOrderPendingMattersByPendingMatterIds($pendingMatterIds) {
return $this->pendingMatterDao->getListByIds($pendingMatterIds);
}
private function checkOrderPendingMatterData($params) {
if (empty($params['orderSn'])) {
throw new CheckClientException('请输入订单号');
}
if (empty($params['mallId'])) {
throw new CheckClientException('请选择店铺');
}
$orderInfo = $this->opOrderDao->getByOrderSn($params['orderSn']);
if (empty($orderInfo)) {
throw new CheckClientException('订单不存在 或者 未同步');
}
if ($orderInfo['mallId'] != $params['mallId']) {
throw new CheckClientException('订单所属店铺与选择的不一致');
}
if (!empty($params['isTimerRemind']) && empty($params['gmtRemind'])) {
throw new CheckClientException('未设置提醒时间');
}
}
public function saveOrderPendingMatter($pendingMatterData) {
$this->checkOrderPendingMatterData($pendingMatterData);
$orderMallId = $pendingMatterData['mallId'];
$pendingMatterId = $pendingMatterData['pendingMatterId'];
$isTimerRemind = empty($pendingMatterData['isTimerRemind']) ? 0 : 1;
$gmtRemind = $isTimerRemind && !empty($pendingMatterData['gmtRemind']) ? $pendingMatterData['gmtRemind'] : null;
if ($gmtRemind) {
$gmtRemind = date('Y-m-d H:i:s', strtotime($gmtRemind));
}
$data = [
'mall_id' => $pendingMatterData['mallId'],
'order_sn' => $pendingMatterData['orderSn'],
'is_timer_remind' => $isTimerRemind,
'gmt_remind' => $gmtRemind,
'pending_matter_category_id' => empty($pendingMatterData['pendingMatterCategoryId']) ? 0 : $pendingMatterData['pendingMatterCategoryId'],
'desc' => empty($pendingMatterData['desc']) ? null : $pendingMatterData['desc'],
'status' => !empty($pendingMatterData['status']) && in_array($pendingMatterData['status'], [StatusConst::wait, StatusConst::finish]) ? $pendingMatterData['status'] : StatusConst::wait,
];
$trans = DbTool::beginTrans(PendingMatterDao::class);
if ($pendingMatterId) {
$this->pendingMatterDao->update($data, 'pending_matter_id = %i', $pendingMatterId);
} else {
$this->pendingMatterDao->insert($data);
$pendingMatterId = $this->pendingMatterDao->lastInsertId();
}
if (!$isTimerRemind) {
$this->pendingMatterBufferDao->delete('mall_id = %i and pending_matter_id = %i', $orderMallId, $pendingMatterId);
$this->pendingMasterQueueDao->delete('mall_id = %i and pending_matter_id = %i', $orderMallId, $pendingMatterId);
} else {
$this->insertUpdatePendingMatterBuffer($orderMallId, $pendingMatterId, $gmtRemind);
}
DbTool::commitTrans($trans);
}
private function insertUpdatePendingMatterBuffer($mallId, $pendingMatterId, $gmtRemind) {
if (CommonTool::anyEmpty($mallId, $pendingMatterId, $gmtRemind)) {
return false;
}
$updateData = [
'mall_id' => $mallId,
'pending_matter_id' => $pendingMatterId,
'gmt_exec' => $gmtRemind,
];
return $this->pendingMatterBufferDao->insertUpdate($updateData);
}
public function searchOrderPendingMatterList($mallId, $params) {
$page = intval($params['page'] ?: 1);
$pageSize = intval($params['pageSize'] ?: 20);
$filter = $this->getOrderPendingMatterFilter($params);
list($pendingMatterList, $total) = $this->pendingMatterDao->searchPage($mallId, $filter, $page, $pageSize);
if (empty($pendingMatterList)) {
return [];
}
$pendingMatterCategoryIds = ZcArrayHelper::getSub($pendingMatterList, 'pendingMatterCategoryId');
$pendingMatterCategoryIds = array_unique(array_filter($pendingMatterCategoryIds, 'isNumeric'));
$mallIds = array_column($pendingMatterList, 'mallId');
$mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
$categoryIdAndPendingMatterCategoryInfoMap = $this->getPendingMatterCategoryListByCategoryIds($pendingMatterCategoryIds);
foreach ($pendingMatterList as &$pendingMatter) {
$categoryName = $categoryIdAndPendingMatterCategoryInfoMap[$pendingMatter['pendingMatterCategoryId']]['categoryName'];
if ($pendingMatter['pendingMatterCategoryId'] == 0) {
$categoryName = '默认分类';
}
$pendingMatter['mallName'] = $mallIdAndMallNameMap[$pendingMatter['mallId']];
$pendingMatter['categoryName'] = $categoryName;
}
return [$pendingMatterList, $total];
}
private function getOrderPendingMatterFilter($params) {
$filter = [];
if (!empty($params['authMallIds'])) {
$filter['authMallIds'] = is_array($params['authMallIds']) ? $params['authMallIds'] : [$params['authMallIds']];
}
if (!empty($params['orderSn'])) {
$filter['orderSn'] = is_array($params['orderSn']) ? $params['orderSn'] : CommonTool::splitWithComma($params['orderSn']);
}
if (isset($params['pendingMatterCategoryId']) && is_numeric($params['pendingMatterCategoryId'])) {
$filter['pendingMatterCategoryId'] = $params['pendingMatterCategoryId'];
}
if (!empty($params['status']) && in_array($params['status'], [StatusConst::wait, StatusConst::finish])) {
$filter['status'] = $params['status'];
}
return $filter;
}
public function getPendingMatterCategoryListByCategoryIds($pendingMatterCategoryIds) {
return $this->pendingMatterCategoryDao->getMapByIds($pendingMatterCategoryIds);
}
public function deletePendingMatter($pendingMatterIds) {
if (empty($pendingMatterIds)) {
return false;
}
$pendingMatterIds = is_array($pendingMatterIds) ? $pendingMatterIds : [$pendingMatterIds];
$trans = DbTool::beginTrans(PendingMatterDao::class);
$this->pendingMatterDao->delete('pending_matter_id IN %li', $pendingMatterIds);
$this->pendingMatterBufferDao->delete('pending_matter_id IN %li', $pendingMatterIds);
$this->pendingMasterQueueDao->delete('pending_matter_id IN %li', $pendingMatterIds);
DbTool::commitTrans($trans);
}
public function markPendingMatter($mallId, $pendingMatterId, $status) {
if (CommonTool::anyEmpty($pendingMatterId, $status)) {
return false;
}
$pendingMatterInfo = $this->pendingMatterDao->getById($pendingMatterId);
if (!$status || !$pendingMatterId || !$pendingMatterInfo) {
throw new BizException('参数错误');
}
PermissionTool::checkMultiShopValid($mallId, [$pendingMatterInfo['mallId']]);
$pendingMatterInfo = $this->pendingMatterDao->getById($pendingMatterId);
$trans = DbTool::beginTrans(PendingMatterDao::class);
$updateData = [
'status' => $status,
];
$this->pendingMatterDao->update($updateData, 'pending_matter_id = %i', $pendingMatterId);
if ($status == StatusConst::finish) {
$this->pendingMatterBufferDao->delete('pending_matter_id = %i', $pendingMatterId);
$this->pendingMasterQueueDao->delete('pending_matter_id = %i', $pendingMatterId);
}
if ($status == StatusConst::wait && $pendingMatterInfo['isTimerRemind'] && $pendingMatterInfo['gmtRemind'] && (strtotime($pendingMatterInfo['gmtRemind']) > time())) {
$this->insertUpdatePendingMatterBuffer($pendingMatterInfo['mallId'], $pendingMatterId, $pendingMatterInfo['gmtRemind']);
}
DbTool::commitTrans($trans);
}
public function getOrderPendingMatter($mallId, $pendingMatterId) {
$pendingMatterInfo = $this->pendingMatterDao->getById($pendingMatterId);
if (!$pendingMatterInfo) {
throw new BizException('待处理事项不存在');
}
PermissionTool::checkMultiShopValid($mallId, [$pendingMatterInfo['mallId']]);
return [
'pendingMatterId' => $pendingMatterInfo['pendingMatterId'],
'pendingMatterCategoryId' => $pendingMatterInfo['pendingMatterCategoryId'],
'mallId' => $pendingMatterInfo['mallId'],
'orderSn' => $pendingMatterInfo['orderSn'],
'isTimerRemind' => $pendingMatterInfo['isTimerRemind'],
'gmtRemind' => $pendingMatterInfo['gmtRemind'],
'desc' => $pendingMatterInfo['desc'],
'status' => $pendingMatterInfo['status'],
];
}
public function getOrderPendingMatterCount($orderSn) {
$orderSn = CommonTool::convertValToArray($orderSn);
$orderSnAndPendingMatterCountMap = $this->pendingMatterDao->getOrderSnAndCountMap($orderSn);
$data = [];
foreach ($orderSnAndPendingMatterCountMap as $orderSnAndPendingMatterCountInfo) {
$data[] = [
'orderSn' => $orderSnAndPendingMatterCountInfo['orderSn'],
'count' => $orderSnAndPendingMatterCountInfo['pendingMatterCount'],
];
}
return $data;
}
public function exportPendingMatter($mallId, $params) {
$orderPendingMatterData = $this->getExportPendingMatter($mallId, $params);
$objPHPExcel = new \PHPExcel();
$activeSheet = ExcelTool::createNewSheetAndSetTitle($objPHPExcel, 0);
$headers = ['店铺', '订单号', '事项描述', '事项分类', '提醒时间', '状态'];
ExcelTool::setSheetRowValues($activeSheet, 1, $headers);
$row = 2;
foreach ($orderPendingMatterData as $orderPendingMatter) {
$column = 1;
ExcelTool::setCellValue($activeSheet, $column++, $row, empty($orderPendingMatter['mallName']) ? '' : $orderPendingMatter['mallName']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderPendingMatter['orderSn']);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderPendingMatter['desc']);
ExcelTool::setCellValue($activeSheet, $column++, $row, empty($orderPendingMatter['categoryName']) ? '' : $orderPendingMatter['categoryName']);
$gmtRemind = $orderPendingMatter['isTimerRemind'] ? $orderPendingMatter['gmtRemind'] : '';
ExcelTool::setCellValue($activeSheet, $column++, $row, $gmtRemind);
ExcelTool::setCellValue($activeSheet, $column++, $row, $orderPendingMatter['status'] == StatusConst::finish ? '已处理' : '未处理');
$row++;
}
ExcelTool::downloadExcel($objPHPExcel, date('Y-m-d', time()) . '-待处理事项');
return false;
}
private function getExportPendingMatter($mallId, $params) {
$page = 1;
$pageSize = 50;
$orderPendingMatterList = [];
while (true) {
$params['page'] = $page;
$params['pageSize'] = $pageSize;
list($pendingMatterList, $total) = $this->searchOrderPendingMatterList($mallId, $params);
if (empty($pendingMatterList)) {
break;
}
$orderPendingMatterList = array_merge($orderPendingMatterList, $pendingMatterList);
if (count($pendingMatterList) < $pageSize) {
break;
}
}
return $orderPendingMatterList;
}
}

@ -187,4 +187,70 @@ class HtmlTool {
}
return self::getStaticFile($files, $forceTimestamp);
}
public static function renderLogisticsStatus($logisticsStatus) {
switch ($logisticsStatus) {
case OrderPrintConst::logisticsActionGot:
return '已揽件';
case OrderPrintConst::logisticsActionSend:
return '派件';
case OrderPrintConst::logisticsActionSign:
return '签收';
case OrderPrintConst::logisticsActionRejection:
return '拒签';
case OrderPrintConst::logisticsActionReturn:
return '退件';
case OrderPrintConst::logisticsActionArrival:
case OrderPrintConst::logisticsActionDeparture:
return '流转中';
case OrderPrintConst::logisticsActionFail:
return '问题件';
case OrderPrintConst::logisticsActionStayInWarehouse:
return '留仓';
case OrderPrintConst::logisticsActionSignOnBehalf:
return '代收点代签';
case OrderPrintConst::logisticsActionOther:
return '其他';
case OrderPrintConst::logisticsActionInCabinet:
return '入代收点';
case OrderPrintConst::logisticsActionOutCabinet:
return '出代收点';
case OrderPrintConst::logisticsActionClearanceStart:
return '清关中';
case OrderPrintConst::logisticsActionClearanceFinish:
return '清关完成';
}
return '-';
}
public static function buildLogisticsWarningHtml($warningType, $logisticsStatus) {
if (in_array($logisticsStatus, OrderPrintConst::getLogisticsRejectActions())) {
return '<span class="label label-danger ws-normal">买家拒收</span>';
}
switch ($warningType) {
case OrderPrintConst::logisticsFilterOvertimeGot:
return '<span class="label label-danger ws-normal">超时未揽收</span>';
case OrderPrintConst::logisticsFilterOvertimeNoArrival:
return '<span class="label label-danger ws-normal">超时未流转</span>';
case OrderPrintConst::logisticsFilterOvertimeNoNewTrace:
return '<span class="label label-danger ws-normal">超时无物流更新</span>';
case OrderPrintConst::logisticsFilterOvertimeNoSign:
return '<span class="label label-danger ws-normal">超时未签收</span>';
case OrderPrintConst::logisticsFilterRejection:
return '<span class="label label-danger ws-normal">买家拒收</span>';
case OrderPrintConst::logisticsFilterAllocateStay:
return '<span class="label label-danger ws-normal">分拨停留</span>';
case OrderPrintConst::logisticsFilterNodeStayJZHW:
return '<span class="label label-danger ws-normal">江浙沪皖节点停留</span>';
case OrderPrintConst::logisticsFilterNodeStayJJJ:
return '<span class="label label-danger ws-normal">京津冀节点停留</span>';
case OrderPrintConst::logisticsFilterNodeStayTYSF:
return '<span class="label label-danger ws-normal">同意省份节点停留</span>';
case OrderPrintConst::logisticsFilterNodeStayBTSF:
return '<span class="label label-danger ws-normal">不同省份节点停留</span>';
case OrderPrintConst::logisticsFilterNodeStayXXN:
return '<span class="label label-danger ws-normal">任一地址在新疆、西藏或内蒙古节点停留</span>';
}
}
}

@ -474,4 +474,51 @@ class PddApi extends PddApiAbstract {
return [$waybillRetList, $needQueryDtos];
}
public static function getRefundAddressList($accessToken) {
$req = new PddRefundAddressListGet();
$response = self::getClient()->execute($req, $accessToken);
return self::handleResponse($response);
}
public static function fulfillmentSend($deliveryInfo, $accessToken) {
if (CommonTool::isForbidRequestOrder()) {
return CommonTool::failResult('禁止请求该接口');
}
$req = new PddLogisticsFulfillmentSendRequest();
$req->setFulfillmentSn($deliveryInfo['fulfillmentSn']);
$req->setLogisticsId($deliveryInfo['companyId']);
$req->setTrackingNumber($deliveryInfo['trackingNumber']);
if (!empty($deliveryInfo['redeliveryType'])) {
$req->setRedeliveryType($deliveryInfo['redeliveryType']);
}
if ($deliveryInfo['returnAddressId']) {
$req->setReturnAddressId($deliveryInfo['returnAddressId']);
}
$response = self::getClient()->execute($req, $accessToken);
return self::handleResponse($response);
}
public static function getPddLogisticsTrace($companyCode, $mailNo, $cache) {
$req = new PddLogisticsOrdertraceGet();
$req->setCompanyCode($companyCode);
$req->setMailNo($mailNo);
$req->setCache($cache);
$response = self::getClient()->execute($req);
return self::handleResponse($response);
}
public static function pddLogisticsIsvTraceNotifySub($companyCode, $expressNo, $tel) {
$req = new PddLogisticsIsvTraceNotifySub();
$req->setShipCode($companyCode);
$req->setTrackNo($expressNo);
$req->setTel($tel);
$response = self::getClient()->execute($req);
return self::handleResponse($response);
}
}
Loading…
Cancel
Save