diff --git a/app/libs/controller/order/class.LogisticsController.php b/app/libs/controller/order/class.LogisticsController.php
new file mode 100644
index 0000000..fc7cb9e
--- /dev/null
+++ b/app/libs/controller/order/class.LogisticsController.php
@@ -0,0 +1,18 @@
+orderService = OrderService::instance();
+ $this->orderPrintService = OrderPrintService::instance();
+ $this->orderMergeService = OrderMergeService::instance();
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/AfterSale/AfterSalesDao.php b/app/libs/daos/AfterSale/AfterSalesDao.php
index fd8f558..99bcddb 100644
--- a/app/libs/daos/AfterSale/AfterSalesDao.php
+++ b/app/libs/daos/AfterSale/AfterSalesDao.php
@@ -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');
+ }
}
diff --git a/app/libs/daos/Common/LogisticsDao.php b/app/libs/daos/Common/LogisticsDao.php
index a5c7444..22cf470 100644
--- a/app/libs/daos/Common/LogisticsDao.php
+++ b/app/libs/daos/Common/LogisticsDao.php
@@ -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) {
diff --git a/app/libs/daos/Common/LogisticsPlatformDao.php b/app/libs/daos/Common/LogisticsPlatformDao.php
index c3b1d0f..873b95c 100644
--- a/app/libs/daos/Common/LogisticsPlatformDao.php
+++ b/app/libs/daos/Common/LogisticsPlatformDao.php
@@ -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');
+ }
}
diff --git a/app/libs/daos/CustomPrint/CustomOrderExpressNoDao.php b/app/libs/daos/CustomPrint/CustomOrderExpressNoDao.php
index c6aa026..1fd97f5 100644
--- a/app/libs/daos/CustomPrint/CustomOrderExpressNoDao.php
+++ b/app/libs/daos/CustomPrint/CustomOrderExpressNoDao.php
@@ -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;
+ }
}
\ No newline at end of file
diff --git a/app/libs/daos/CustomPrint/CustomOrderExtDao.php b/app/libs/daos/CustomPrint/CustomOrderExtDao.php
index 8da1023..9e66bbb 100644
--- a/app/libs/daos/CustomPrint/CustomOrderExtDao.php
+++ b/app/libs/daos/CustomPrint/CustomOrderExtDao.php
@@ -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);
+ }
}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderCollectLogDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderCollectLogDao.php
new file mode 100644
index 0000000..7dffafb
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderCollectLogDao.php
@@ -0,0 +1,11 @@
+queryFirstRow('select * from %b where fulfillment_order_id = %i', $this->getTable(), $fulfillmentOrderId);
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderDao.php
new file mode 100644
index 0000000..d82c0e2
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderDao.php
@@ -0,0 +1,116 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderEncryptDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderEncryptDao.php
new file mode 100644
index 0000000..6020387
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderEncryptDao.php
@@ -0,0 +1,9 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderInsensitiveInfoDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderInsensitiveInfoDao.php
new file mode 100644
index 0000000..5b84f56
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderInsensitiveInfoDao.php
@@ -0,0 +1,14 @@
+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');
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageHistoryDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageHistoryDao.php
new file mode 100644
index 0000000..1736d57
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageHistoryDao.php
@@ -0,0 +1,40 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageStopDao.php b/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageStopDao.php
new file mode 100644
index 0000000..be43f1c
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/FulfillmentOrderOutstorageStopDao.php
@@ -0,0 +1,19 @@
+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,
+ ));
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/FulfillmentOrder/OpPrintGoodsLabelCodeLogDao.php b/app/libs/daos/FulfillmentOrder/OpPrintGoodsLabelCodeLogDao.php
new file mode 100644
index 0000000..9413599
--- /dev/null
+++ b/app/libs/daos/FulfillmentOrder/OpPrintGoodsLabelCodeLogDao.php
@@ -0,0 +1,9 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/Order/OpOrderDao.php b/app/libs/daos/Order/OpOrderDao.php
index 57cadbb..6eb416b 100644
--- a/app/libs/daos/Order/OpOrderDao.php
+++ b/app/libs/daos/Order/OpOrderDao.php
@@ -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) {
diff --git a/app/libs/daos/Order/OpOrderExtDao.php b/app/libs/daos/Order/OpOrderExtDao.php
index 8e80bd2..25bc001 100644
--- a/app/libs/daos/Order/OpOrderExtDao.php
+++ b/app/libs/daos/Order/OpOrderExtDao.php
@@ -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);
+ }
}
diff --git a/app/libs/daos/Order/OpOrderLogisticsTraceDao.php b/app/libs/daos/Order/OpOrderLogisticsTraceDao.php
new file mode 100644
index 0000000..1b20004
--- /dev/null
+++ b/app/libs/daos/Order/OpOrderLogisticsTraceDao.php
@@ -0,0 +1,27 @@
+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;
+ }
+}
diff --git a/app/libs/daos/Order/OpOrderMapDao.php b/app/libs/daos/Order/OpOrderMapDao.php
index 50490c3..797c6c1 100644
--- a/app/libs/daos/Order/OpOrderMapDao.php
+++ b/app/libs/daos/Order/OpOrderMapDao.php
@@ -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);
+ }
}
\ No newline at end of file
diff --git a/app/libs/daos/OrderPrint/OpOrderExpressNoDao.php b/app/libs/daos/OrderPrint/OpOrderExpressNoDao.php
index 4737d8a..7133474 100644
--- a/app/libs/daos/OrderPrint/OpOrderExpressNoDao.php
+++ b/app/libs/daos/OrderPrint/OpOrderExpressNoDao.php
@@ -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');
+ }
}
diff --git a/app/libs/daos/OrderPrint/OpWaybillInfoDao.php b/app/libs/daos/OrderPrint/OpWaybillInfoDao.php
index e889ee5..9e7498e 100644
--- a/app/libs/daos/OrderPrint/OpWaybillInfoDao.php
+++ b/app/libs/daos/OrderPrint/OpWaybillInfoDao.php
@@ -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);
+ }
}
\ No newline at end of file
diff --git a/app/libs/daos/OrderSend/OpOrderOutstorageHistoryDao.php b/app/libs/daos/OrderSend/OpOrderOutstorageHistoryDao.php
index 3a70743..3f352c7 100644
--- a/app/libs/daos/OrderSend/OpOrderOutstorageHistoryDao.php
+++ b/app/libs/daos/OrderSend/OpOrderOutstorageHistoryDao.php
@@ -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);
+ }
}
diff --git a/app/libs/daos/PendingMatter/PendingMasterQueueDao.php b/app/libs/daos/PendingMatter/PendingMasterQueueDao.php
new file mode 100644
index 0000000..dd03db6
--- /dev/null
+++ b/app/libs/daos/PendingMatter/PendingMasterQueueDao.php
@@ -0,0 +1,9 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/app/libs/daos/PendingMatter/PendingMatterDao.php b/app/libs/daos/PendingMatter/PendingMatterDao.php
new file mode 100644
index 0000000..4847622
--- /dev/null
+++ b/app/libs/daos/PendingMatter/PendingMatterDao.php
@@ -0,0 +1,40 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/app/libs/services/AfterSale/AfterSaleService.php b/app/libs/services/AfterSale/AfterSaleService.php
index c252e69..a8fefda 100644
--- a/app/libs/services/AfterSale/AfterSaleService.php
+++ b/app/libs/services/AfterSale/AfterSaleService.php
@@ -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);
}
}
\ No newline at end of file
diff --git a/app/libs/services/FulfillmentOrder/FulfillmentOrderService.php b/app/libs/services/FulfillmentOrder/FulfillmentOrderService.php
new file mode 100644
index 0000000..47f83fd
--- /dev/null
+++ b/app/libs/services/FulfillmentOrder/FulfillmentOrderService.php
@@ -0,0 +1,553 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/libs/services/Logistics/LogisticsService.php b/app/libs/services/Logistics/LogisticsService.php
new file mode 100644
index 0000000..e5f983e
--- /dev/null
+++ b/app/libs/services/Logistics/LogisticsService.php
@@ -0,0 +1,1020 @@
+mallSDao = MallSDao::instance();
+ $this->opOrderDao = OpOrderDao::instance();
+ $this->pendingMatterDao = PendingMatterDao::instance();
+ $this->pendingMatterCategoryDao = PendingMatterCategoryDao::instance();
+ $this->pendingMatterBufferDao = PendingMatterBufferDao::instance();
+ $this->searchConditionLogDao = SearchConditionLogDao::instance();
+ $this->opOrderOutstorageHistoryDao = OpOrderOutstorageHistoryDao::instance();
+ $this->opOrderMapDao = OpOrderMapDao::instance();
+ $this->opOrderExpressNoDao = OpOrderExpressNoDao::instance();
+ $this->opOrderExtDao = OpOrderExtDao::instance();
+ $this->opOrderReceiveAddressDao = OpOrderReceiveAddressDao::instance();
+ $this->opOrderLogisticsTraceDao = OpOrderLogisticsTraceDao::instance();
+ $this->orderPrintRepository = OrderPrintRepository::instance();
+ $this->opLogisticsStatusCheckBufferDao = OpLogisticsStatusCheckBufferDao::instance();
+ $this->opWaybillInfoDao = OpWaybillInfoDao::instance();
+ $this->customOrderExpressNoDao = CustomOrderExpressNoDao::instance();
+ $this->customOrderExtDao = CustomOrderExtDao::instance();
+ $this->customOrderDao = CustomOrderDao::instance();
+ $this->logisticsDao = LogisticsDao::instance();
+ $this->logisticsPlatformDao = LogisticsPlatformDao::instance();
+ }
+
+ public function getPreOutstorageOrderList($params, $operatorInfo) {
+ $mallId = $operatorInfo['mallId'];
+ $page = intval($params['page'] ?: 1);
+ $pageSize = intval($params['pageSize'] ?: 20);
+
+ $this->searchConditionLogDao->add($mallId, OrderPrintConst::searchConditionBizCodePreOutStorage, $params);
+
+ $params = $this->buildSearchPreOutstorageOrderCondition($params, $operatorInfo);
+ if ($params['onlyShowRefunding'] && $params['onlyShowRefunded']) {
+ return [
+ 'orderList' => [],
+ 'total' => 0,
+ ];
+ }
+ list($orderList, $total) = $this->searchPreOutstorageOrderList($mallId, $params, $page, $pageSize);
+
+ return [
+ 'orderList' => $orderList,
+ 'total' => $total,
+ ];
+ }
+
+ public function searchPreOutstorageOrderList($mallId, $filterCondition, $page, $pageSize) {
+ $mallIds = !empty($filterCondition['authMallIds']) ? (is_array($filterCondition['authMallIds']) ? $filterCondition['authMallIds'] : [$filterCondition['authMallIds']]) : [$mallId];
+ list ($orderList, $total) = $this->opOrderDao->searchPage($mallIds, $filterCondition, $page, $pageSize);
+ if (empty($orderList)) {
+ return array();
+ }
+
+ $orderIds = ZcArrayHelper::getSub($orderList, 'orderId');
+ $childOrderIdAndOrderIdMap = $this->opOrderMapDao->getChildOrderIdAndOrderIdMap($orderIds);
+ $ordersIdExpressInfosMap = $this->opOrderExpressNoDao->getMapByOrderIds(array_unique(array_merge($orderIds, $childOrderIdAndOrderIdMap)));
+ $ordersCustomAddr = $this->opOrderReceiveAddressDao->getListByOrderIds($orderIds);
+ $orderGoodsList = $this->orderPrintRepository->getOpOrdersGoodsListByOrderIds($orderIds);
+ $orderExts = $this->opOrderExtDao->getMapByIds($orderIds);
+ $mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
+ $logisticsIds = $expressNos = [];
+ foreach ($orderList as $order) {
+ $orderId = $order['orderId'];
+ if ($ordersIdExpressInfosMap[$orderId][0]) {
+ $logisticsIds[] = $ordersIdExpressInfosMap[$orderId][0]['logisticsId'];
+ $expressNos[] = $ordersIdExpressInfosMap[$orderId][0]['expressNo'];
+ }
+ }
+
+ $traceMap = $this->opOrderLogisticsTraceDao->getLogisticsAndTraceListMap($logisticsIds, $expressNos);
+ $rows = array();
+ $orderList = $this->orderPrintRepository->decryptOrders($orderList);
+ foreach ($orderList as $order) {
+ $orderId = $order['orderId'];
+ $orderMallId = $order['mallId'];
+
+
+ $customAddr = $ordersCustomAddr[$orderId];
+ $mobile = $customAddr ? CommonTool::ensconceString($customAddr['mobile'], 'mobile') : $order['receiverPhone'];
+ $telephone = $customAddr ? CommonTool::ensconceString($customAddr['telephone'], 'mobile') : $order['receiverPhone'];
+ $expressDetail = $ordersIdExpressInfosMap[$orderId][0];
+ $traceKey = $expressDetail['logisticsId'] . '_' . $expressDetail['expressNo'];
+
+ $fullName = $customAddr ? CommonTool::ensconceString($customAddr['fullname'], 'webViewName') : $order['receiverName'];
+ $address = $customAddr ? CommonTool::ensconceString($customAddr['address'], 'webViewAddress') : $order['address'];
+ $fullAddress = OrderPrintTool::joinFullAddress($order['province'], $order['city'], $order['town'], $address);
+
+ if ($childOrderIdAndOrderIdMap[$orderId]) {
+ $expressDetail = $ordersIdExpressInfosMap[$childOrderIdAndOrderIdMap[$orderId]][0];
+ }
+
+ $rows[$orderId] = array(
+ 'mallName' => $mallIdAndMallNameMap[$orderMallId],
+ 'bFullname' => $fullName,
+ 'bTelephone' => $telephone,
+ 'bMobile' => $mobile,
+ 'bFullAddress' => $fullAddress,
+ 'expressDetail' => $expressDetail,
+ 'logisticsStatus' => $orderExts[$orderId]['logisticsStatus'],
+ 'traceList' => $traceMap[$traceKey],
+ );
+
+ $order['goodsList'] = $orderGoodsList[$orderId];
+ $rows[$orderId] = array_merge($rows[$orderId], OrderPrintTool::formartOrderDetailNv($order));
+
+
+ }
+ $this->buildPreAutoOutstorageStatusToOpOrder($mallIds, $rows);
+
+ return [$rows, $total];
+ }
+
+ public function buildPreAutoOutstorageStatusToOpOrder($mallIds, &$orders) {
+ if (empty($orders)) {
+ return false;
+ }
+ $orderSns = ZcArrayHelper::getSub($orders, 'orderSn');
+ $lastOpOrderOutstorageHistoryIds = $this->opOrderOutstorageHistoryDao->getLastHistoryIdsByOrderSns($mallIds, $orderSns);
+ $opOrderOutstorageHistoryList = $this->opOrderOutstorageHistoryDao->getListByIds($lastOpOrderOutstorageHistoryIds);
+ $orderSnAndOutstorageInfoMap = ZcArrayHelper::changeKeyRow($opOrderOutstorageHistoryList, 'ordeSn');
+ foreach ($orders as &$order) {
+ $orderSn = $order['orderSn'];
+ if (isset($orderSnAndOutstorageInfoMap[$orderSn]) && $orderSnAndOutstorageInfoMap[$orderSn]['source'] == PurchaseOrderConst::outstorageSourcePreAuto) {
+ $lastHistory = $orderSnAndOutstorageInfoMap[$orderSn];
+ $order['preAutoOutstorageStatus'] = $lastHistory['status'];
+ $order['preAutoOutstorageReason'] = $lastHistory['reason'];
+ }
+ }
+
+ }
+
+ protected function buildSearchPreOutstorageOrderCondition($params, $operatorInfo) {
+ $mallId = $operatorInfo['accessToken'];
+ $params['orderStatus'] = OrderConst::orderStatusWaitSellerSendGoods;
+ $params['isPreOutstorage'] = 1;
+ if (is_numeric($params['isRefund'])) {
+ if ($params['isRefund']) {
+ $params['refundStatus'] = [OrderConst::refundStatusProcessing, OrderConst::refundStatusRefunding, OrderConst::refundStatusSuccess];
+ } else {
+ $params['refundStatus'] = OrderConst::refundStatusNoRefund;
+ }
+ }
+ if ($params['delaySendStatus'] == OrderConst::willDelaySend) {
+ $params['afterSalesLastShipLeftHours'] = 12;
+ }
+
+ if ($params['orderSn']) {
+ $params['orderSn'] = trim($params['orderSn']);
+ }
+ if ($params['waybillCode']) {
+ $params['waybillCode'] = trim($params['waybillCode']);
+ }
+ if (!empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ $params['orderEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ }
+ if (!empty($params['authMallIds'])) {
+ $params['authMallIds'] = empty($params['authMallIds']) ? array($mallId) : $params['authMallIds'];
+ PermissionTool::checkMultiShopValid($mallId, $params['authMallIds']);
+ }
+ if (!empty($data['orderStartTime'])) {
+ $condition['orderStartTime'] = ZcDateHelper::formatDate($data['orderStartTime']);
+ }
+ if (!empty($data['orderEndTime']) && ($data['orderEndTime'] >= $data['orderStartTime'])) {
+ $condition['orderEndTime'] = date('Y-m-d 23:59:59', strtotime($data['orderEndTime']));
+ }
+ if (isset($params['timeType']) && in_array($params['timeType'], ['createdTime', 'preOutstorageTime'])) {
+ if (!empty($params['orderStartTime'])) {
+ if ($params['timeType'] == 'createdTime') {
+ $params['orderCreatedStartTime'] = ZcDateHelper::formatDate($params['orderStartTime']);
+ } else {
+ $params['preOutstorageStartTime'] = ZcDateHelper::formatDate($params['orderStartTime']);
+ }
+ }
+ if (!empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ if ($params['timeType'] == 'createdTime') {
+ $params['orderCreatedEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ } else {
+ $params['preOutstorageEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ }
+ }
+ unset($params['orderStartTime']);
+ unset($params['orderEndTime']);
+ }
+ if ($params['onlyShowAutoShipFailed']) {
+ $params['onlyShowAutoShipFailed'] = trim($params['onlyShowAutoShipFailed']);
+ }
+ if ($params['onlyShowRefunding']) {
+ $params['refundStatus'] = [OrderConst::refundStatusProcessing, OrderConst::refundStatusRefunding];
+ }
+ if ($params['onlyShowRefunded']) {
+ $params['refundStatus'] = OrderConst::refundStatusSuccess;
+ }
+
+ $kmsSearchList = PddApi::getKmsSearchList($params, $operatorInfo['accessToken']);
+ if (!empty($kmsSearchList['receiverNameSearchText'])) {
+ $params['receiverNameSearchText'] = $kmsSearchList['receiverNameSearchText'];
+ }
+ if (!empty($kmsSearchList['receiverMobileSearchText'])) {
+ $params['receiverMobileSearchText'] = $kmsSearchList['receiverMobileSearchText'];
+ }
+
+ if(isset($params['sortType'])){
+ $printOrderSortTypeArray = array_keys(OrderPrintTool::getOpPreOutstorageSortTypeMap());
+ $condition['sortType'] = in_array($params['sortType'], $printOrderSortTypeArray) ? $params['sortType'] : $printOrderSortTypeArray[0];
+ }
+
+ return $params;
+ }
+
+ public function orderPreOutstorage($mallId, $orderIds) {
+ $orderInfos = $this->opOrderDao->getMapByIds($orderIds);
+ $authMallIds = ZcArrayHelper::getSub($orderInfos, 'mallId');
+ PermissionTool::checkMultiShopValid($mallId, $authMallIds);
+
+ return $this->preOutstorageOrders($authMallIds, $orderIds);
+ }
+
+ private function preOutstorageOrders($mallIds, $orderIds) {
+ $orderIds = array_unique(array_filter($orderIds));
+
+ $orderIdAncChildOrderIdsMap = $this->opOrderMapDao->getOrderIdAndChildOrderIdsMap($orderIds);
+ $singleOrderIds = array_diff($orderIds, array_keys($orderIdAncChildOrderIdsMap));
+ foreach ($singleOrderIds as $singleOrderId) {
+ $orderIdAncChildOrderIdsMap[$singleOrderId] = [$singleOrderId];
+ }
+
+ $orderIdAndExpressInfoMap = $this->opOrderExpressNoDao->getOrderIdAndExpressInfoMap(array_keys($orderIdAncChildOrderIdsMap));
+ $wxExpressNos = $this->opWaybillInfoDao->getExistsWaybillCodes(array_column($orderIdAndExpressInfoMap, 'expressMo'));
+ $outstorageExpressNos = [];
+
+ $orderIdErrorMap = [];
+ $preOutstorageOrderIds = [];
+ $preOutstorageOrderIdCount = 0;
+ foreach ($orderIdAncChildOrderIdsMap as $parentOrderId => $childOrderIds) {
+ $preOutstorageOrderIdCount += count($childOrderIds);
+ $expressItem = $orderIdAndExpressInfoMap[$parentOrderId];
+ if (empty($expressItem)) {
+ $orderIdErrorMap[] = count($childOrderIds) . '个订单未打印';
+ continue;
+ }
+ $orderSn = $expressItem['orderSn'];
+ if (in_array($expressItem['expressNo'], $wxExpressNos)) {
+ $orderIdErrorMap[$orderSn] = '预发货暂时不支持站外面单';
+ continue;
+ }
+ if ($expressItem['waybillType'] != LogisticsConst::waybillPdd || $expressItem['express_type'] != OrderPrintConst::expressTypeDzmd) {
+ $orderIdErrorMap[$orderSn] = '预发货暂时只支持拼多多电子面单';
+ continue;
+ }
+ if ($expressItem['orderStatus'] != OrderConst::orderStatusWaitSellerSendGoods || $expressItem['refund_status'] != OrderConst::refundStatusNoRefund) {
+ $orderIdErrorMap[$orderSn] = '订单状态错误';
+ continue;
+ }
+ $preOutstorageOrderIds = array_merge($preOutstorageOrderIds, $childOrderIds);
+ $outstorageExpressNos[] = $expressItem['expressNo'];
+
+ }
+
+ $successCount = 0;
+ if ($preOutstorageOrderIds) {
+ $preOutstorageOrderIds = array_unique($preOutstorageOrderIds);
+ $successCount = (int)$this->opOrderExtDao->updateOrderPreOutstorageFlag($mallIds, $preOutstorageOrderIds, 1);
+ $this->opLogisticsStatusCheckBufferDao->update(['gmt_exec' => ZcDbEval::now(), 'gmt_modified' => ZcDbEval::now()], 'express_no in %ls', $outstorageExpressNos);
+ }
+
+ return [
+ 'totalCount' => $preOutstorageOrderIdCount,
+ 'successCount' => $successCount,
+ 'failCount' => $preOutstorageOrderIdCount - $successCount,
+ 'orderIdErrorMap' => $orderIdErrorMap,
+ ];
+ }
+
+ public function cancelOrderPreOutstorage($mallId, $orderIds) {
+ if (!is_array($orderIds)) {
+ $orderIds = [$orderIds];
+ }
+
+ $orderInfos = $this->opOrderDao->getListByIds($orderIds);
+ $authMallIds = ZcArrayHelper::getSub($orderInfos, 'mallId');
+ PermissionTool::checkMultiShopValid($mallId, $authMallIds);
+
+ $parentOrderIds = $this->opOrderMapDao->getParentOrderIdsByChildOrderIds($orderIds);
+ $childOrderIds = $this->opOrderMapDao->getChildOrderIdsByParentOrderIds($parentOrderIds);
+
+ $parentOrderInfos = $this->opOrderDao->getListByIds($parentOrderIds);
+ foreach ($parentOrderInfos as $parentOrderInfo) {
+ if ($parentOrderInfo['orderStatus'] != OrderConst::orderStatusWaitSellerSendGoods) {
+ throw new CheckClientException('父订单不是待发货状态,不允许取消预发货');
+ }
+ }
+
+ $needCancelPreOutstorageOrderIds = array_unique(array_merge($orderIds, $childOrderIds));
+
+ $affRow = $this->doCancelOrderPreOutstorage($authMallIds, $needCancelPreOutstorageOrderIds);
+ if ($affRow === false) {
+ throw new BizException('取消预发货失败');
+ }
+ }
+
+ private function doCancelOrderPreOutstorage($mallIds, $orderIds) {
+ if (!is_array($orderIds)) {
+ $orderIds = [$orderIds];
+ }
+ return $this->opOrderExtDao->updateOrderPreOutstorageFlag($mallIds, $orderIds, 0);
+ }
+
+ public function searchLogisticsWarningOrderList($mallId, $params) {
+ $page = intval($params['page'] ?: 1);
+ $pageSize = intval($params['pageSize'] ?: 20);
+
+ $this->searchConditionLogDao->add($mallId, OrderPrintConst::searchConditionBizCodeLogisticsWarning, $params);
+
+ if ($params['orderType'] == 'customOrder') {
+ list($orderList, $total) = $this->searchLogisticsWarningCustomOrderList($mallId, $params, $page, $pageSize);
+ } else {
+ list($orderList, $total) = $this->searchLogisticsWarningPddOrderList($mallId, $params, $page, $pageSize);
+ }
+ return [
+ 'orderList' => $orderList,
+ 'total' => $total,
+ ];
+ }
+
+ private function searchLogisticsWarningCustomOrderList($mallId, $params, $page, $pageSize = 20) {
+ $filterCondition = $this->buildSearchLogisticsWarningCustomOrderCondition($mallId, $params);
+ list ($orderList, $total) = $this->customOrderExpressNoDao->searchPage($mallId, $filterCondition, $page, $pageSize);
+ if (empty($orderList)) {
+ return array([], 0);
+ }
+
+ $mallIds = array_column($orderList, 'mallId');
+ $orderList = ZcArrayHelper::changeKeyRow($orderList, 'customOrderId');
+ $customOrderIds = array_keys($orderList);
+ $orderExpressNos = $this->customOrderExpressNoDao->getCustomOrderIdAndExpressNoListMap($mallIds, $customOrderIds);
+ $orderExts = $this->customOrderExtDao->getMapByOrderIds($customOrderIds);
+
+ $logisticsIds = $expressNos = [];
+ foreach ($orderList as $order) {
+ $orderId = $order['custom_order_id'];
+ if ($orderExpressNos[$orderId][0]) {
+ $logisticsIds[] = $orderExpressNos[$orderId][0]['logisticsId'];
+ $expressNos[] = $orderExpressNos[$orderId][0]['expressNo'];
+ }
+ }
+ $traceMap = $this->opOrderLogisticsTraceDao->getLogisticsAndTraceListMap($logisticsIds, $expressNos);
+
+ $rows = array();
+ $orderList = OrderDecryptTool::decryptInfoListByTableName($orderList, 'custom_order');
+ $mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
+ foreach ($orderList as $orderId => $order) {
+ $expressDetail = $orderExpressNos[$orderId][0];
+ $traceKey = $expressDetail['logisticsId'] . '_' . $expressDetail['expressNo'];
+ $fullAddress = OrderPrintTool::joinFullAddress($order['province'], $order['city'], $order['town'], $order['address']);
+
+ $rows[$orderId] = array(
+ 'mallName' => $mallIdAndMallNameMap[$order['mallId']],
+ 'bizOrderNum' => $order['bizOrderNum'],
+ 'fullname' => $order['receiverName'],
+ 'telephone' => trim($order['receiverPhone']),
+ 'mobile' => trim($order['receiverMobile']),
+ 'fullAddress' => $fullAddress,
+ 'expressDetail' => $expressDetail,
+ 'logisticsStatus' => $orderExts[$orderId]['logisticsStatus'],
+ 'logisticsOvertimeType' => $orderExts[$orderId]['logisticsOvertimeType'],
+ 'traceList' => $traceMap[$traceKey],
+ );
+ }
+ return array($rows, $total);
+ }
+
+ private function buildSearchLogisticsWarningCustomOrderCondition($mallId, $params) {
+ $params['waybillType'] = LogisticsConst::waybillPdd;
+ if ($params['overtime'] == OrderPrintConst::logisticsFilterOvertimeGot) {
+ unset($params['overtime']);
+ }
+
+ if ($params['overtime'] == OrderPrintConst::logisticsFilterRejection) {
+ $params['logisticsStatus'] = OrderPrintConst::getLogisticsRejectActions();
+ } else if ($params['overtime']) {
+ $params['logisticsOvertimeType'] = $params['overtime'];
+ }
+ unset($params['overtime']);
+
+ $params['bizOrderNum'] = trim($params['orderSn']);
+ unset($params['orderSn']);
+
+ if ($params['waybillCode']) {
+ $params['waybillCode'] = trim($params['waybillCode']);
+ }
+
+ if (!empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ $params['orderEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ }
+ if ($params['isMultiShop']) {
+ $params['authMallIds'] = empty($params['authMallIds']) ? array($mallId) : $params['authMallIds'];
+ PermissionTool::checkMultiShopValid($mallId, $params['authMallIds']);
+ }
+
+ if (!empty($params['opLogisticsStatus'])) {
+ if ($params['opLogisticsStatus'] == 'waitGet') {
+ $params['logisticsStatus'] = OrderPrintConst::logisticsStatusFilterWaitGot;
+ } elseif ($params['opLogisticsStatus'] == 'onlyGet') {
+ $params['logisticsStatus'] = [OrderPrintConst::logisticsActionGot];
+ } elseif ($params['opLogisticsStatus'] == 'notOnlyGet') {
+ $params['logisticsStatus'] = [
+ OrderPrintConst::logisticsActionArrival,
+ OrderPrintConst::logisticsActionDeparture,
+ OrderPrintConst::logisticsActionSend,
+ OrderPrintConst::logisticsActionFail,
+ OrderPrintConst::logisticsActionSign,
+ OrderPrintConst::logisticsActionRejection,
+ OrderPrintConst::logisticsActionStayInWarehouse,
+ OrderPrintConst::logisticsActionSignOnBehalf,
+ OrderPrintConst::logisticsActionOther,
+ OrderPrintConst::logisticsActionReturn,
+ OrderPrintConst::logisticsActionInCabinet,
+ OrderPrintConst::logisticsActionOutCabinet,
+ OrderPrintConst::logisticsActionClearanceStart,
+ OrderPrintConst::logisticsActionClearanceFinish,
+ ];
+ } elseif ($params['opLogisticsStatus'] == 'sending') {
+ $params['logisticsStatus'] = [OrderPrintConst::logisticsActionSend];
+ } elseif ($params['opLogisticsStatus'] == 'signed') {
+ $params['logisticsStatus'] = [
+ OrderPrintConst::logisticsActionSign,
+ OrderPrintConst::logisticsActionSignOnBehalf,
+ OrderPrintConst::logisticsActionInCabinet,
+ OrderPrintConst::logisticsActionOutCabinet,
+ ];
+ }
+ unset($params['opLogisticsStatus']);
+ }
+
+ if (!empty($params['opWarningStatus'])) {
+ if ($params['opWarningStatus'] == 'hasWarning') {
+ $params['logisticsOvertimeType'] = [
+ OrderPrintConst::logisticsFilterOvertimeGot,
+ OrderPrintConst::logisticsFilterOvertimeNoArrival,
+ OrderPrintConst::logisticsFilterOvertimeNoNewTrace,
+ OrderPrintConst::logisticsFilterOvertimeNoSign,
+ OrderPrintConst::logisticsFilterRejection,
+ OrderPrintConst::logisticsFilterAllocateStay,
+ OrderPrintConst::logisticsFilterNodeStayJZHW,
+ OrderPrintConst::logisticsFilterNodeStayJJJ,
+ OrderPrintConst::logisticsFilterNodeStayTYSF,
+ OrderPrintConst::logisticsFilterNodeStayBTSF,
+ OrderPrintConst::logisticsFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'notGotWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterOvertimeGot];
+ } elseif ($params['opWarningStatus'] == 'GotNotUpdateWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterOvertimeNoArrival];
+ } elseif ($params['opWarningStatus'] == 'allocateStayWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterAllocateStay];
+ } elseif ($params['opWarningStatus'] == 'nodeStayWarning') {
+ $params['logisticsOvertimeType'] = [
+ OrderPrintConst::logisticsFilterNodeStayJZHW,
+ OrderPrintConst::logisticsFilterNodeStayJJJ,
+ OrderPrintConst::logisticsFilterNodeStayTYSF,
+ OrderPrintConst::logisticsFilterNodeStayBTSF,
+ OrderPrintConst::logisticsFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'rejectionWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterRejection];
+ } elseif ($params['opWarningStatus'] == 'hasException') {
+ $params['logisticsExceptionOvertimeType'] = [
+ OrderPrintConst::logisticsExceptionFilterOvertimeGot,
+ OrderPrintConst::logisticsExceptionFilterOvertimeNoArrival,
+ OrderPrintConst::logisticsExceptionFilterAllocateStay,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJZHW,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJJJ,
+ OrderPrintConst::logisticsExceptionFilterNodeStayTYSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayBTSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'notGotException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterOvertimeGot];
+ } elseif ($params['opWarningStatus'] == 'GotNotUpdateException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterOvertimeNoArrival];
+ } elseif ($params['opWarningStatus'] == 'allocateStayException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterAllocateStay];
+ } elseif ($params['opWarningStatus'] == 'nodeStayException') {
+ $params['logisticsExceptionOvertimeType'] = [
+ OrderPrintConst::logisticsExceptionFilterNodeStayJZHW,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJJJ,
+ OrderPrintConst::logisticsExceptionFilterNodeStayTYSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayBTSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'normal') {
+ $params['notLogisticsWarningAndException'] = 1;
+ }
+ unset($params['opWarningStatus']);
+ }
+
+ return $params;
+ }
+
+ public function searchLogisticsWarningPddOrderList($mallId, $params, $page, $pageSize = 20) {
+ $filter = $this->buildSearchLogisticsWarningOrderCondition($mallId, $params);
+ $filter['sortType'] = 'orderStartTimeAsc';
+ $mallIds = !empty($filter['authMallIds']) ? (is_array($filter['authMallIds']) ? $filter['authMallIds'] : [$filter['authMallIds']]) : [$mallId];
+ list($orderList, $total) = $this->opOrderDao->searchPage($mallIds, $filter, $page, $pageSize);
+ if (empty($orderList)) {
+ return [[], 0];
+ }
+
+ $orderIds = ZcArrayHelper::getSub($orderList, 'orderId');
+ $ordersCustomAddr = $this->opOrderReceiveAddressDao->getListByOrderIds($orderIds);
+ $orderExts = $this->opOrderExtDao->getMapByIds($orderIds);
+ $logisticsIds = $expressNos = [];
+ $pddLogisticsIds = [];
+
+ if ($filter['orderStatus'] == OrderConst::orderStatusWaitSellerSendGoods) {
+ $ordersExpressNos = $this->opOrderExpressNoDao->getMapByOrderIds($orderIds);
+ }
+
+ foreach ($orderList as $order) {
+ $orderId = $order['orderId'];
+ if ($order['logisticsId']) {
+ $pddLogisticsIds[] = $order['logisticsId'];
+ $expressNos[] = $order['trackingNumber'];
+ }
+ if ($ordersExpressNos[$orderId][0]) {
+ $logisticsIds[] = $ordersExpressNos[$orderId][0]['logisticsId'];
+ $expressNos[] = $ordersExpressNos[$orderId][0]['expressNo'];
+ }
+ }
+
+ if ($pddLogisticsIds) {
+ $companyIdLogisticsMap = $this->logisticsPlatformDao->getMapByCompanyIds($pddLogisticsIds, AppConst::appPlatformPdd);
+ foreach ($pddLogisticsIds as $logisticsId) {
+ $logisticsIds[] = $companyIdLogisticsMap[$logisticsId]['logisticsId'];
+ }
+ }
+
+ $traceMap = $this->opOrderLogisticsTraceDao->getLogisticsAndTraceListMap($logisticsIds, $expressNos);
+
+ $rows = array();
+ $orderList = $this->orderPrintRepository->decryptOrders($orderList);
+ $mallIdAndMallNameMap = $this->mallSDao->getMallIdAndMallNameMap($mallIds);
+ foreach ($orderList as $order) {
+ $orderId = $order['order_id'];
+ $customAddr = $ordersCustomAddr[$orderId];
+ $mobile = $customAddr ? CommonTool::ensconceString($customAddr['mobile'], 'mobile') : $order['receiverPhone'];
+ $telephone = $customAddr ? CommonTool::ensconceString($customAddr['telephone'], 'mobile') : $order['receiverPhone'];
+
+ $fullName = $customAddr ? CommonTool::ensconceString($customAddr['fullname'], 'webViewName') : $order['receiverName'];
+ $address = $customAddr ? CommonTool::ensconceString($customAddr['address'], 'webViewAddress') : $order['address'];
+ $fullAddress = OrderPrintTool::joinFullAddress($order['province'], $order['city'], $order['town'], $address);
+
+ if ($order['logisticsId'] && $order['trackingNumber']) {
+ $expressDetail = [
+ 'logisticsId' => $companyIdLogisticsMap[$order['logisticsId']]['logisticsId'],
+ 'expressNo' => $order['trackingNumber'],
+ ];
+ } else {
+ $expressDetail = $ordersExpressNos[$orderId][0];
+ }
+
+ $traceKey = $expressDetail['logisticsId'] . '_' . $expressDetail['expressNo'];
+
+ $rows[$orderId] = array(
+ 'mallName' => $mallIdAndMallNameMap[$order['mallId']],
+ 'bFullname' => $fullName,
+ 'bTelephone' => $telephone,
+ 'bMobile' => $mobile,
+ 'bFullAddress' => $fullAddress,
+ 'expressDetail' => $expressDetail,
+ 'logisticsStatus' => $orderExts[$orderId]['logisticsStatus'],
+ 'logisticsOvertimeType' => $orderExts[$orderId]['logisticsOvertimeType'],
+ 'traceList' => $traceMap[$traceKey],
+ 'refundStatus' => $order['refundStatus'],
+ 'logisticsExceptionOvertimeType' => $orderExts[$orderId]['logisticsExceptionOvertimeType'],
+ 'logisticsExceptionOvertimeText' => $orderExts[$orderId]['logisticsExceptionOvertimeText'],
+ );
+
+ $rows[$orderId] = array_merge($rows[$orderId], OrderPrintTool::formartOrderDetailNv($order));
+ }
+ return [$rows, $total];
+ }
+
+ protected function buildSearchLogisticsWarningOrderCondition($mallId, $params) {
+ $params['isPrintOrder'] = true;
+ $params['waybillType'] = LogisticsConst::waybillPdd;
+ if ($params['waybillCode']) {
+ $params['waybillCode'] = trim($params['waybillCode']);
+ }
+
+ if ($params['orderType'] == 'waitSendOrder') {
+ $params['orderStatus'] = OrderConst::orderStatusWaitSellerSendGoods;
+ $params['refundStatus'] = OrderConst::refundStatusNoRefund;
+ if ($params['waybillCode']) {
+ $params['opWaybillCode'] = $params['waybillCode'];
+ unset($params['waybillCode']);
+ }
+ if ($params['logisticsId']) {
+ $params['opLogisticsId'] = $params['logisticsId'];
+ unset($params['logisticsId']);
+ }
+ } else {
+ $params['orderStatus'] = OrderConst::orderStatusWaitBuyerConfirmGoods;
+ }
+
+ if ($params['overtime'] == OrderPrintConst::logisticsFilterRejection) {
+ $params['logisticsStatus'] = OrderPrintConst::getLogisticsRejectActions();
+ } else if ($params['overtime']) {
+ $params['logisticsOvertimeType'] = $params['overtime'];
+ }
+ unset($params['overtime']);
+ if (!empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ $params['orderEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ }
+ if ($params['logisticsId']) {
+ $params['logisticsId'] = $this->logisticsPlatformDao->getCompanyCodeByLogisticsId($params['logisticsId'], AppConst::appPlatformPdd);
+ }
+ if ($params['isMultiShop']) {
+ $params['authMallIds'] = empty($params['authMallIds']) ? array($mallId) : $params['authMallIds'];
+ PermissionTool::checkMultiShopValid($mallId, $params['authMallIds']);
+ }
+ if (isset($params['timeType'])) {
+ if ($params['timeType'] == 'createdTime' && !empty($params['orderStartTime'])) {
+ $params['orderCreatedStartTime'] = ZcDateHelper::formatDate($params['orderStartTime']);
+ unset($params['orderStartTime']);
+ }
+ if ($params['timeType'] == 'createdTime' & !empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ $params['orderCreatedEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ unset($params['orderEndTime']);
+ }
+ if ($params['timeType'] == 'orderSendTime' && !empty($params['orderStartTime'])) {
+ $params['orderSendStartTime'] = ZcDateHelper::formatDate($params['orderStartTime']);
+ unset($params['orderStartTime']);
+ }
+ if ($params['timeType'] == 'orderSendTime' & !empty($params['orderEndTime']) && ($params['orderEndTime'] >= $params['orderStartTime'])) {
+ $params['orderSendEndTime'] = date('Y-m-d 23:59:59', strtotime($params['orderEndTime']));
+ unset($params['orderEndTime']);
+ }
+ }
+
+ if (!empty($params['orderRefundStatus'])) {
+ if ($params['orderRefundStatus'] == 'hasRefund') {
+ $params['refundStatus'] = [OrderConst::refundStatusProcessing, OrderConst::refundStatusRefunding, OrderConst::refundStatusSuccess];
+ } else {
+ $params['refundStatus'] = OrderConst::refundStatusNoRefund;
+ }
+ unset($params['orderRefundStatus']);
+ }
+
+ if (!empty($params['opLogisticsStatus'])) {
+ if ($params['opLogisticsStatus'] == 'waitGet') {
+ $params['logisticsStatus'] = OrderPrintConst::logisticsStatusFilterWaitGot;
+ } elseif ($params['opLogisticsStatus'] == 'onlyGet') {
+ $params['logisticsStatus'] = [OrderPrintConst::logisticsActionGot];
+ } elseif ($params['opLogisticsStatus'] == 'notOnlyGet') {
+ $params['logisticsStatus'] = [
+ OrderPrintConst::logisticsActionArrival,
+ OrderPrintConst::logisticsActionDeparture,
+ OrderPrintConst::logisticsActionSend,
+ OrderPrintConst::logisticsActionFail,
+ OrderPrintConst::logisticsActionSign,
+ OrderPrintConst::logisticsActionRejection,
+ OrderPrintConst::logisticsActionStayInWarehouse,
+ OrderPrintConst::logisticsActionSignOnBehalf,
+ OrderPrintConst::logisticsActionOther,
+ OrderPrintConst::logisticsActionReturn,
+ OrderPrintConst::logisticsActionInCabinet,
+ OrderPrintConst::logisticsActionOutCabinet,
+ OrderPrintConst::logisticsActionClearanceStart,
+ OrderPrintConst::logisticsActionClearanceFinish,
+ ];
+ } elseif ($params['opLogisticsStatus'] == 'sending') {
+ $params['logisticsStatus'] = [OrderPrintConst::logisticsActionSend];
+ } elseif ($params['opLogisticsStatus'] == 'signed') {
+ $params['logisticsStatus'] = [
+ OrderPrintConst::logisticsActionSign,
+ OrderPrintConst::logisticsActionSignOnBehalf,
+ OrderPrintConst::logisticsActionInCabinet,
+ OrderPrintConst::logisticsActionOutCabinet,
+ ];
+ }
+ unset($params['opLogisticsStatus']);
+ }
+
+ if (!empty($params['opWarningStatus'])) {
+ if ($params['opWarningStatus'] == 'hasWarning') {
+ $params['logisticsOvertimeType'] = [
+ OrderPrintConst::logisticsFilterOvertimeGot,
+ OrderPrintConst::logisticsFilterOvertimeNoArrival,
+ OrderPrintConst::logisticsFilterOvertimeNoNewTrace,
+ OrderPrintConst::logisticsFilterOvertimeNoSign,
+ OrderPrintConst::logisticsFilterRejection,
+ OrderPrintConst::logisticsFilterAllocateStay,
+ OrderPrintConst::logisticsFilterNodeStayJZHW,
+ OrderPrintConst::logisticsFilterNodeStayJJJ,
+ OrderPrintConst::logisticsFilterNodeStayTYSF,
+ OrderPrintConst::logisticsFilterNodeStayBTSF,
+ OrderPrintConst::logisticsFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'notGotWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterOvertimeGot];
+ } elseif ($params['opWarningStatus'] == 'GotNotUpdateWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterOvertimeNoArrival];
+ } elseif ($params['opWarningStatus'] == 'allocateStayWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterAllocateStay];
+ } elseif ($params['opWarningStatus'] == 'nodeStayWarning') {
+ $params['logisticsOvertimeType'] = [
+ OrderPrintConst::logisticsFilterNodeStayJZHW,
+ OrderPrintConst::logisticsFilterNodeStayJJJ,
+ OrderPrintConst::logisticsFilterNodeStayTYSF,
+ OrderPrintConst::logisticsFilterNodeStayBTSF,
+ OrderPrintConst::logisticsFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'rejectionWarning') {
+ $params['logisticsOvertimeType'] = [OrderPrintConst::logisticsFilterRejection];
+ } elseif ($params['opWarningStatus'] == 'hasException') {
+ $params['logisticsExceptionOvertimeType'] = [
+ OrderPrintConst::logisticsExceptionFilterOvertimeGot,
+ OrderPrintConst::logisticsExceptionFilterOvertimeNoArrival,
+ OrderPrintConst::logisticsExceptionFilterAllocateStay,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJZHW,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJJJ,
+ OrderPrintConst::logisticsExceptionFilterNodeStayTYSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayBTSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'notGotException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterOvertimeGot];
+ } elseif ($params['opWarningStatus'] == 'GotNotUpdateException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterOvertimeNoArrival];
+ } elseif ($params['opWarningStatus'] == 'allocateStayException') {
+ $params['logisticsExceptionOvertimeType'] = [OrderPrintConst::logisticsExceptionFilterAllocateStay];
+ } elseif ($params['opWarningStatus'] == 'nodeStayException') {
+ $params['logisticsExceptionOvertimeType'] = [
+ OrderPrintConst::logisticsExceptionFilterNodeStayJZHW,
+ OrderPrintConst::logisticsExceptionFilterNodeStayJJJ,
+ OrderPrintConst::logisticsExceptionFilterNodeStayTYSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayBTSF,
+ OrderPrintConst::logisticsExceptionFilterNodeStayXXN,
+ ];
+ } elseif ($params['opWarningStatus'] == 'normal') {
+ $params['notLogisticsWarningAndException'] = 1;
+ }
+ unset($params['opWarningStatus']);
+ }
+
+ return $params;
+ }
+
+ public function batchUpdateLogisticsTrace($deliveryInfos) {
+ $logisticsIds = ZcArrayHelper::getSub($deliveryInfos, 'logisticsId');
+ $logisticsIdCompanyCodeMap = $this->logisticsPlatformDao->getLogisticsIdAndCompanyIdMap($logisticsIds, AppConst::appPlatformPdd);
+
+ $fCnt = $sCnt = 0;
+ foreach ($deliveryInfos as $data) {
+ $expressNo = $data['expressNo'];
+ $logisticsId = $data['logisticsId'];
+ $companyCode = $logisticsIdCompanyCodeMap[$logisticsId];
+
+ try {
+ $this->updateLogisticsTraceFromPdd($companyCode, $logisticsId, $expressNo);
+ $sCnt ++;
+ } catch (Exception $e) {
+ $fCnt ++;
+ }
+ }
+
+ return [
+ 'fCnt' => $fCnt,
+ 'sCnt' => $sCnt
+ ];
+ }
+
+ public function updateLogisticsTraceFromPdd($companyCode, $logisticsId, $expressNo) {
+ $traceRet = PddApi::getPddLogisticsTrace($companyCode, $expressNo, false);
+ if (CommonTool::isFailRet($traceRet)) {
+ throw new BizException($traceRet['reason']);
+ }
+ $insertList = [];
+ foreach ($traceRet['trace_list'] as $item) {
+ $insertList[] = [
+ 'logistics_id' => $logisticsId,
+ 'tracking_number' => $expressNo,
+ 'status_desc' => $item['status_desc'],
+ 'action' => $item['action'],
+ 'node_description' => $item['node_description'],
+ 'status_time' => $item['status_time'],
+ 'time' => $item['time'],
+ 'desc' => $item['desc'],
+ ];
+ }
+
+ if (empty($insertList)) {
+ return;
+ }
+ $this->opOrderLogisticsTraceDao->delete('logistics_id = %i and tracking_number = %s', $logisticsId, $expressNo);
+ $this->opOrderLogisticsTraceDao->insert($insertList);
+ }
+
+ public function batchCancelLogisticsWarning($mallId, $orderIds, $orderType) {
+ if (!$orderIds) {
+ throw new CheckClientException('请选择要取消的订单');
+ }
+ $orderIds = is_array($orderIds) ? $orderIds : [$orderIds];
+ if ($orderType == 'customOrder') {
+ $orderList = $this->customOrderDao->getListByBizOrderNums($orderIds);
+ } else {
+ $orderList = $this->opOrderDao->getListByIds($orderIds);
+ }
+ if (!$orderList) {
+ throw new CheckClientException('订单不存在');
+ }
+ $mallIds = ZcArrayHelper::getSub($orderList, 'mallId');
+ PermissionTool::checkMultiShopValid($mallId, $mallIds);
+
+ if ($orderType == 'customOrder') {
+ $cancelRet = $this->customOrderExtDao->batchCancelLogisticsWarning(ZcArrayHelper::getSub($orderList, 'customOrderId'));
+ } else {
+ $cancelRet = $this->opOrderExtDao->batchCancelLogisticsWarning($orderIds);
+ }
+ if ($cancelRet === false) {
+ throw new BizException('取消失败');
+ }
+ }
+
+ public function exportWarningOrder($mallId, $params) {
+ $orderType = $params['orderType'];
+ $pageSize = 50;
+ $page = 1;
+
+ $objPHPExcel = new \PHPExcel();
+
+ $activeSheet = ExcelTool::createNewSheetAndSetTitle($objPHPExcel, 0, '物流预警');
+
+ if ($orderType == 'customOrder') {
+ $headers = $this->getCustomExportWarningOrderHeaders();
+ } else {
+ $headers = $this->getOpExportWarningOrderHeaders();
+ }
+ ExcelTool::setSheetRowValues($activeSheet, 1, $headers);
+
+ $warningOrderList = [];
+ while (true) {
+ if ($orderType == 'customOrder') {
+ list($orderList, $total) = $this->searchLogisticsWarningCustomOrderList($mallId, $params, $page, $pageSize);
+ } else {
+ list($orderList, $total) = $this->searchLogisticsWarningPddOrderList($mallId, $params, $page, $pageSize);
+ }
+
+ if (!$orderList) {
+ break;
+ }
+
+ $warningOrderList = array_merge($warningOrderList, $orderList);
+
+ if (count($orderList) < $pageSize) {
+ break;
+ }
+
+ $page ++;
+ }
+
+ if ($orderType == 'customOrder') {
+ $this->packExportCustomLogisticsWarningData($activeSheet, $warningOrderList);
+ } else {
+ $this->packExportLogisticsWarningData($activeSheet, $warningOrderList);
+ }
+ ExcelTool::downloadExcel($objPHPExcel, '导出物流预警单');
+ exit;
+ }
+
+ private function packExportLogisticsWarningData(&$activeSheet, $warningOrderList) {
+ $logisticsMap = $this->logisticsDao->getLogisticsMap();
+ $row = 2;
+ foreach ($warningOrderList as $warningOrder) {
+ $column = 1;
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['mallName']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $logisticsMap[$warningOrder['expressDetail']['logisticsId']]);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['expressDetail']['express_no']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, HtmlTool::renderLogisticsStatus($warningOrder['logisticsStatus']));
+ ExcelTool::setCellValue($activeSheet, $column++, $row, (empty($warningOrder['shippingTime']) || $warningOrder['shippingTime'] == '0000-00-00 00:00:00') ? '--' : $warningOrder['shippingTime']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, strip_tags(HtmlTool::buildLogisticsWarningHtml($warningOrder['logisticsOvertimeType'], $warningOrder['logisticsStatus'])));
+ if (!empty($warningOrder['traceList'])) {
+ $lastTrace = $warningOrder['traceList'][0];
+ ExcelTool::setCellValue($activeSheet, $column++, $row, ($lastTrace['statusTime'] . ':' . $lastTrace['desc']));
+ } else {
+ ExcelTool::setCellValue($activeSheet, $column++, $row, '--');
+ }
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['orderSn']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, OrderConst::getOrderStatusText($warningOrder['orderStatus'], $warningOrder['refundStatus']));
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['fullname']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['fullAddress']);
+ $row ++;
+ }
+ }
+
+ private function packExportCustomLogisticsWarningData(&$activeSheet, $warningOrderList) {
+ $logisticsMap = $this->logisticsDao->getLogisticsMap();
+ $row = 2;
+ foreach ($warningOrderList as $warningOrder) {
+ $column = 1;
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['mallName']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $logisticsMap[$warningOrder['expressDetail']['logistics_id']]);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['expressDetail']['express_no']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, HtmlTool::renderLogisticsStatus($warningOrder['logisticsStatus']));
+ ExcelTool::setCellValue($activeSheet, $column++, $row, strip_tags(HtmlTool::buildLogisticsWarningHtml($warningOrder['logisticsOvertimeType'], $warningOrder['logisticsStatus'])));
+ if (!empty($warningOrder['traceList'])) {
+ $lastTrace = $warningOrder['traceList'][0];
+ ExcelTool::setCellValue($activeSheet, $column++, $row, ($lastTrace['statusTime'] . ':' . $lastTrace['desc']));
+ } else {
+ ExcelTool::setCellValue($activeSheet, $column++, $row, '--');
+ }
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['orderSn']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['fullname']);
+ ExcelTool::setCellValue($activeSheet, $column++, $row, $warningOrder['fullAddress']);
+ $row ++;
+ }
+ }
+
+ private function getOpExportWarningOrderHeaders() {
+ return [
+ '店铺名称',
+ '快递公司',
+ '运单号',
+ '包裹状态',
+ '发货时间',
+ '预警信息',
+ '最新物流信息',
+ '订单号',
+ '订单状态',
+ '收货人',
+ '收货地址',
+ ];
+ }
+
+ private function getCustomExportWarningOrderHeaders() {
+ return [
+ '店铺名称',
+ '快递公司',
+ '运单号',
+ '包裹状态',
+ '预警信息',
+ '最新物流信息',
+ '订单号',
+ '收货人',
+ '收货地址',
+ ];
+ }
+}
\ No newline at end of file
diff --git a/app/libs/services/Order/OrderSendService.php b/app/libs/services/Order/OrderSendService.php
index 2bd6d3a..b8af8bb 100644
--- a/app/libs/services/Order/OrderSendService.php
+++ b/app/libs/services/Order/OrderSendService.php
@@ -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'];
diff --git a/app/libs/services/PendingMaster/PendingMatterService.php b/app/libs/services/PendingMaster/PendingMatterService.php
new file mode 100644
index 0000000..f0816a0
--- /dev/null
+++ b/app/libs/services/PendingMaster/PendingMatterService.php
@@ -0,0 +1,308 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/libs/tool/class.HtmlTool.php b/app/libs/tool/class.HtmlTool.php
index 59fa644..421dbe7 100644
--- a/app/libs/tool/class.HtmlTool.php
+++ b/app/libs/tool/class.HtmlTool.php
@@ -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 '买家拒收';
+ }
+ switch ($warningType) {
+ case OrderPrintConst::logisticsFilterOvertimeGot:
+ return '超时未揽收';
+ case OrderPrintConst::logisticsFilterOvertimeNoArrival:
+ return '超时未流转';
+ case OrderPrintConst::logisticsFilterOvertimeNoNewTrace:
+ return '超时无物流更新';
+ case OrderPrintConst::logisticsFilterOvertimeNoSign:
+ return '超时未签收';
+ case OrderPrintConst::logisticsFilterRejection:
+ return '买家拒收';
+ case OrderPrintConst::logisticsFilterAllocateStay:
+ return '分拨停留';
+ case OrderPrintConst::logisticsFilterNodeStayJZHW:
+ return '江浙沪皖节点停留';
+ case OrderPrintConst::logisticsFilterNodeStayJJJ:
+ return '京津冀节点停留';
+ case OrderPrintConst::logisticsFilterNodeStayTYSF:
+ return '同意省份节点停留';
+ case OrderPrintConst::logisticsFilterNodeStayBTSF:
+ return '不同省份节点停留';
+ case OrderPrintConst::logisticsFilterNodeStayXXN:
+ return '任一地址在新疆、西藏或内蒙古节点停留';
+
+ }
+ }
}
\ No newline at end of file
diff --git a/app/libs/tool/class.PddApi.php b/app/libs/tool/class.PddApi.php
index ec744bb..a7fdccc 100644
--- a/app/libs/tool/class.PddApi.php
+++ b/app/libs/tool/class.PddApi.php
@@ -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);
+ }
}
\ No newline at end of file