|
|
<?php
|
|
|
|
|
|
class BatchController extends ZcController {
|
|
|
/**
|
|
|
* @var ShopService
|
|
|
*/
|
|
|
private $shopService;
|
|
|
/**
|
|
|
* @var MoveService
|
|
|
*/
|
|
|
private $moveService;
|
|
|
/**
|
|
|
* @var ProductService
|
|
|
*/
|
|
|
private $productService;
|
|
|
/**
|
|
|
* @var RsyncProductService
|
|
|
*/
|
|
|
private $rsyncProductService;
|
|
|
/**
|
|
|
* @var MoveImportService
|
|
|
*/
|
|
|
private $moveImportService;
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* @var CSVParse
|
|
|
*/
|
|
|
private $csvParse;
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* @var WatermarkService
|
|
|
*/
|
|
|
private $watermarkService;
|
|
|
|
|
|
/**
|
|
|
* @var FeedbackService
|
|
|
*/
|
|
|
private $feedbackService;
|
|
|
|
|
|
/**
|
|
|
* @var ProductUtil
|
|
|
*/
|
|
|
private $productUtil;
|
|
|
/**
|
|
|
* @var MoveUtil
|
|
|
*/
|
|
|
private $moveUtil;
|
|
|
|
|
|
/**
|
|
|
* @var MaterialUtil
|
|
|
*/
|
|
|
private $materialUtil;
|
|
|
/**
|
|
|
* @var TailorImgTool
|
|
|
*/
|
|
|
private $tailorImgTool;
|
|
|
/**
|
|
|
*
|
|
|
* @var PageSpider
|
|
|
*/
|
|
|
private $spider;
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* @var DsClient
|
|
|
*/
|
|
|
private $dsClient;
|
|
|
|
|
|
/**
|
|
|
* @var LtaoTool
|
|
|
*/
|
|
|
private $ltaoTool;
|
|
|
|
|
|
private $redis;
|
|
|
private $webShop;
|
|
|
private $moveBatchSettingLog;
|
|
|
private $moveBatchUrlLog;
|
|
|
private $timeStatLog;
|
|
|
private $moveBatchSaveTaskLog;
|
|
|
private $moveBatchDebugLog;
|
|
|
private $failRetryMoveTaskLog;
|
|
|
private $moveAgainDetailLog;
|
|
|
private $moveBatchShopLog;
|
|
|
|
|
|
/**
|
|
|
* @var MaterialService
|
|
|
*/
|
|
|
private $materialService;
|
|
|
|
|
|
public function __construct($route) {
|
|
|
parent::__construct($route);
|
|
|
|
|
|
header('Access-Control-Allow-Credentials: true');
|
|
|
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
|
|
|
|
|
|
$this->shopService = Zc::singleton(ShopService::class);
|
|
|
$this->moveService = Zc::singleton(MoveService::class);
|
|
|
$this->productService = Zc::singleton(ProductService::class);
|
|
|
$this->rsyncProductService = Zc::singleton(RsyncProductService::class);
|
|
|
$this->watermarkService = Zc::singleton('WatermarkService');
|
|
|
$this->moveImportService = Zc::singleton('MoveImportService');
|
|
|
$this->feedbackService = Zc::singleton(FeedbackService::class);
|
|
|
|
|
|
$this->productUtil = Zc::singleton(ProductUtil::class);
|
|
|
$this->moveUtil = Zc::singleton(MoveUtil::class);
|
|
|
$this->materialUtil = Zc::singleton('MaterialUtil');
|
|
|
$this->spider = new PageSpider(array (), null, $_SERVER['REMOTE_ADDR']);
|
|
|
|
|
|
$this->dsClient = Zc::singleton('DsClient');
|
|
|
$this->webShop = Zc::getWebUser();
|
|
|
$this->moveBatchSettingLog = Zc::getLog('move/batch/setting');
|
|
|
$this->moveBatchUrlLog = Zc::getLog('move/batch/url');
|
|
|
$this->timeStatLog = Zc::getLog('move/batch/time_stat');
|
|
|
$this->moveBatchSaveTaskLog = Zc::getLog('move/batch/saveTask');
|
|
|
$this->moveBatchDebugLog = Zc::getLog('move/batch/debug');
|
|
|
$this->failRetryMoveTaskLog = Zc::getLog('move/batch/fail_retry');
|
|
|
$this->moveAgainDetailLog = Zc::getLog('move/batch/again_detail');
|
|
|
$this->moveBatchShopLog = Zc::getLog('move/batch/shop');
|
|
|
$this->tailorImgTool = new TailorImgTool();
|
|
|
$this->ltaoTool = new LtaoTool();
|
|
|
|
|
|
$this->materialService = Zc::singleton(MaterialService::class);
|
|
|
|
|
|
Zc::import('@.vendor.CSVParse', '', '.php', 'class.');
|
|
|
$this->csvParse = new CSVParse();
|
|
|
$this->redis = RedisExt::factory('bizCache');
|
|
|
}
|
|
|
|
|
|
|
|
|
public function target() {
|
|
|
if (!isset($_SESSION[SessionConst::geoIpArea])) {
|
|
|
$geoInfo = $this->shopService->getGeoIpInfo(CommonTool::clientIp(), false);
|
|
|
if (!empty($geoInfo)) {
|
|
|
$_SESSION[SessionConst::geoIpArea] = $geoInfo;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ($_GET['copyType'] == MoveConst::collectFetchBank) {
|
|
|
$this->redirect(Zc::url(RouteConst::moveBatchTarget, array('copyType' => $_GET['copyType']), 'https', Zc::C('fetchBank.domain')));
|
|
|
}
|
|
|
|
|
|
$copyType = in_array($_GET['copyType'], array (
|
|
|
MoveConst::collectLinksCopy,
|
|
|
MoveConst::collectShopCopy,
|
|
|
MoveConst::collectWebsiteCopy,
|
|
|
MoveConst::collectDsCopy,
|
|
|
MoveConst::collectLtaoCopy,
|
|
|
MoveConst::collectSameProduct,
|
|
|
MoveConst::collectClueCopy,
|
|
|
)) ? $_GET['copyType'] : MoveConst::collectLinksCopy;
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$shopName = $_SESSION[SessionConst::shopName];
|
|
|
|
|
|
$moveAdvancedConfig = $this->moveService->getMoveAdvancedConfig($shopId);
|
|
|
|
|
|
$appOrder = $this->shopService->getShopFirstAppOrder($shopId);
|
|
|
$isFetchBank = $this->webShop->getFlash('isFetchBank') ?: $_POST['isFetchBank'];
|
|
|
$categoryOptionArray = $this->productUtil->getCategoryOptionArray($shopId);
|
|
|
|
|
|
$dsHelpArticleList = [];
|
|
|
|
|
|
$dsBuyUrl = $this->moveService->getDsBuyUrl($shopId);
|
|
|
$dsMemberInfo = $this->moveService->getDsMemberInfo($shopId);
|
|
|
$dsMemberName = $dsMemberInfo['cnali_member_name'];
|
|
|
$ruleList = $this->getChoicenessSourceItemTag();
|
|
|
|
|
|
$collectTaskWareIds = $_POST['collectTaskWareIds'] ? json_decode($_POST['collectTaskWareIds'], true) : $this->webShop->getFlash('collectTaskWareIds');
|
|
|
$fetchBankDetailIds = $_POST['fetchBankDetailIds'] ? json_decode($_POST['fetchBankDetailIds'], true) : $this->webShop->getFlash('fetchBankDetailIds');
|
|
|
|
|
|
$this->render(array (
|
|
|
'copyType' => $copyType,
|
|
|
'shopId' => $shopId,
|
|
|
'shopName' => $shopName,
|
|
|
'appOrder' => $appOrder,
|
|
|
'isFetchBank' => $isFetchBank,
|
|
|
'collectTaskWareIds' => $collectTaskWareIds,
|
|
|
'fetchBankDetailIds' => $fetchBankDetailIds,
|
|
|
'moveAdvancedConfig' => $moveAdvancedConfig,
|
|
|
'categoryOptionArray' => $categoryOptionArray,
|
|
|
'alibabaHelpArticleList' => $dsHelpArticleList,
|
|
|
'ltaoAuthInfo' => $ltaoAuthInfo,
|
|
|
'dsBuyUrl' => $dsBuyUrl,
|
|
|
'alibabaMemberName' => $dsMemberName,
|
|
|
'alibabaMemberExpire' => $dsMemberInfo['gmt_expire'],
|
|
|
'folderMenuTree' => $this->materialService->getMaterialFolderMenuTree($shopId),
|
|
|
'ruleList' => $ruleList,
|
|
|
), 'move/batch/target_all');
|
|
|
}
|
|
|
|
|
|
private function getChoicenessSourceItemTag() {
|
|
|
$tagCache = DsClientTool::tryGetChoicenessSourceItemTagByLocal();
|
|
|
if ($tagCache) {
|
|
|
return $tagCache;
|
|
|
}
|
|
|
|
|
|
$getRet = $this->dsClient->getChoicenessSourceItemTag(DsConst::platformDd);
|
|
|
if (CommonTool::isSuccessRet($getRet)) {
|
|
|
DsClientTool::stashChoicenessSourceItemTagToLocal($getRet['data']);
|
|
|
}
|
|
|
|
|
|
return $getRet['data'];
|
|
|
}
|
|
|
|
|
|
public function resetMoveSetting() {
|
|
|
$moveSettingId = !empty($_POST['moveSettingId']) ? (int)$_POST['moveSettingId'] : 0;
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
if (!$moveSettingId || !$shopId) {
|
|
|
return $this->renderJSON(CommonTool::failResult('参数错误'));
|
|
|
}
|
|
|
|
|
|
$newMoveSettingId = $this->moveUtil->resetMoveSetting($moveSettingId, $shopId);
|
|
|
if ($newMoveSettingId) {
|
|
|
$moveSettingList = $this->moveUtil->getInitMoveSettingList($shopId);
|
|
|
$renderData = array(
|
|
|
'moveSettingList' => $moveSettingList,
|
|
|
'moveSettingId' => $newMoveSettingId,
|
|
|
);
|
|
|
return $this->renderJSON(CommonTool::successResult($renderData));
|
|
|
}
|
|
|
return $this->renderJSON(CommonTool::failResult('恢复默认设置失败'));
|
|
|
}
|
|
|
|
|
|
public function getInitDataList() {
|
|
|
header('Access-Control-Allow-Credentials: true');
|
|
|
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
|
|
|
|
|
|
$ret = $this->moveUtil->getInitDataList();
|
|
|
return $this->renderJSON($ret);
|
|
|
}
|
|
|
|
|
|
|
|
|
public function getFreightTemplateList() {
|
|
|
$shopId = $_POST['authShopId'] ? $_POST['authShopId'] : $_SESSION[SessionConst::shopId];
|
|
|
$accessToken = $this->shopService->getShopAccessToken($shopId);
|
|
|
$freightTemplateRet = $this->moveService->getFreightTemplateListFromDd($accessToken);
|
|
|
$ret = [
|
|
|
'freightTemplateList' => $freightTemplateRet['freightTemplateList'] ? $freightTemplateRet['freightTemplateList'] : [],
|
|
|
];
|
|
|
$this->renderJSON(CommonTool::successResult($ret));
|
|
|
}
|
|
|
|
|
|
public function getCurrentShopMoveSetting() {
|
|
|
header('Access-Control-Allow-Credentials: true');
|
|
|
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
|
|
|
|
|
|
$shopId = $_POST['curShopId'] ? $_POST['curShopId'] : $_SESSION[SessionConst::shopId];
|
|
|
$accessToken = $_SESSION[SessionConst::accessToken];
|
|
|
if (empty($shopId) || empty($accessToken)) {
|
|
|
$this->renderJSON(CommonTool::failResult("获取用户id失败,请联系客服"));
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
$moveSettingList = $this->moveUtil->getInitMoveSettingList($shopId);
|
|
|
|
|
|
foreach ($moveSettingList as $moveSetting) {
|
|
|
if ($moveSetting['is_config_default'] == 1) {
|
|
|
return $this->renderJSON(CommonTool::successResult('moveSetting', $moveSetting));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$moveSetting = array_shift($moveSettingList);
|
|
|
|
|
|
return $this->renderJSON(CommonTool::successResult('moveSetting', $moveSetting));
|
|
|
}
|
|
|
|
|
|
public function saveMoveBatchConfigFirst() {
|
|
|
header('Access-Control-Allow-Credentials: true');
|
|
|
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$moveSetting = $_POST['moveSetting'];
|
|
|
|
|
|
$ret = $this->moveUtil->saveMoveBatchConfigFirst($shopId, $moveSetting, $this->moveBatchSettingLog);
|
|
|
return $this->renderJSON($ret);
|
|
|
}
|
|
|
|
|
|
|
|
|
public function fetchAlibabaDetailUrlInfo() {
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$alibabaMemberId = $this->moveService->getAlibabaMemberId($shopId);
|
|
|
if (empty($alibabaMemberId)) {
|
|
|
$isExistDs = $this->moveService->isExistDs($shopId);
|
|
|
if ($isExistDs) {
|
|
|
return $this->renderJSON(CommonTool::failCodeResult(ErrorCodeConst::expireDsAuth, '抖店和1688授权过期,请重新授权'));
|
|
|
}
|
|
|
|
|
|
return $this->renderJSON(CommonTool::failCodeResult(ErrorCodeConst::noDsAuth, '抖店没有1688主客授权,请授权'));
|
|
|
}
|
|
|
|
|
|
$checkRet = $this->moveUtil->checkAbnormalRequest($shopId);
|
|
|
if (CommonTool::isFailRet($checkRet)) {
|
|
|
return $this->renderJSON($checkRet);
|
|
|
}
|
|
|
|
|
|
$startTime = ZcNumberHelper::microtimeFloat();
|
|
|
$this->moveBatchUrlLog->info('fetchDetailUrlInfo, shopId[' . $_SESSION[SessionConst::shopId] . '], post: ' . print_r($_POST, true));
|
|
|
$detailUrls = $_POST['detailUrls'];
|
|
|
|
|
|
$getProductInfoListRet = $this->getAlibabaProductsInfoListByDetailUrls($detailUrls, $shopId, true);
|
|
|
if (CommonTool::isFailRet($getProductInfoListRet)) {
|
|
|
return $this->renderJSON($getProductInfoListRet);
|
|
|
}
|
|
|
|
|
|
$endTime = ZcNumberHelper::microtimeFloat();
|
|
|
$costTime = bcsub($endTime, $startTime, 3);
|
|
|
$timeStatLogStr = sprintf('searchProductStat | %s | %s | %s', $shopId, count($detailUrls), $costTime);
|
|
|
$this->timeStatLog->info($timeStatLogStr);
|
|
|
|
|
|
$productsInfoList = $getProductInfoListRet['productsInfoList'];
|
|
|
$productList = $this->moveUtil->processProductList($productsInfoList, $shopId, null, $_POST['productClueCatePathMap'] ?: [], $_POST['productClueIdMap'] ?: []);
|
|
|
$productList = $this->moveUtil->attachIsMoved($productList, $shopId);
|
|
|
return $this->renderJSON(CommonTool::successResult(array(
|
|
|
'productList' => $productList,
|
|
|
'sourceItemIds' => array_keys($productList),
|
|
|
'hostname' => gethostname()
|
|
|
)));
|
|
|
}
|
|
|
|
|
|
private function getAlibabaProductsInfoListByDetailUrls($detailUrls, $shopId, $needCheckFree = false) {
|
|
|
$detailUrls = array_map('trim', preg_split("/\\r\\n|\\r|\\n|,|,|;|;/u", $detailUrls));
|
|
|
|
|
|
$ret = $this->buildAlibabaFetchUrlList($shopId, $detailUrls, $needCheckFree);
|
|
|
if (CommonTool::isFailRet($ret)) {
|
|
|
return $ret;
|
|
|
}
|
|
|
$fetchList = $ret['fetchList'];
|
|
|
|
|
|
$productsInfoListRet = $this->moveUtil->fetchProductsList($fetchList, true);
|
|
|
$productsInfoList = $productsInfoListRet['productsInfoList'];
|
|
|
return CommonTool::successResult(array(
|
|
|
'productsInfoList' => $productsInfoList,
|
|
|
));
|
|
|
}
|
|
|
|
|
|
private function buildAlibabaFetchUrlList($shopId, $detailUrls, $needCheckFree = false) {
|
|
|
$uniqueSourceProductArray = array();
|
|
|
$sourceProducts = array();
|
|
|
$fetchList = array();
|
|
|
$fetchSourceList = [];
|
|
|
$aliCount = 0;
|
|
|
$shortUrlToNormalUrlMap = $this->moveUtil->getRealItemUrlFromShortUrl($detailUrls);
|
|
|
|
|
|
foreach ($detailUrls as $url){
|
|
|
//ctype_digit纯数字检测
|
|
|
if(empty($url) || ctype_digit($url)){
|
|
|
continue;
|
|
|
}
|
|
|
$url = $shortUrlToNormalUrlMap[$url] ? : $url;
|
|
|
$sourceProduct = $this->moveUtil->parseDetailUrl($url);
|
|
|
if (!empty($sourceProduct)) {
|
|
|
$productId = $sourceProduct['itemId'];
|
|
|
$source = $sourceProduct['source'];
|
|
|
$site = $sourceProduct['site'];
|
|
|
$isFromMobileLink = $sourceProduct['isFromMobileLink'];
|
|
|
|
|
|
if ($uniqueSourceProductArray[$source.$productId.$site]) {
|
|
|
continue;
|
|
|
}
|
|
|
$uniqueSourceProductArray[$source.$productId.$site] = true;
|
|
|
|
|
|
if ($source == FetchClientConst::collectTaskSource1688) {
|
|
|
$aliCount++;
|
|
|
}
|
|
|
$sourceProducts[] = $sourceProduct;
|
|
|
$fetchSourceList[] = $source;
|
|
|
}
|
|
|
if ($source == FetchClientConst::collectTaskSource1688) {
|
|
|
$fetchUrl = Zc::url(RouteConst::TimerMoveTaskFetchDsItem, array('itemId' => $productId, 'source' => $source, 'site' => $site, 'shopId' => $shopId, 'isFromMobileLink' => $isFromMobileLink, 'moveNeedCollectDetail' => FetchClientTool::moveNeedCollectDetail($source), 'trace' => MoveConst::traceDdmsFetchUrl()), 'http', Zc::C('multi.crawler.domain'));
|
|
|
} else {
|
|
|
$fetchUrl = Zc::url(RouteConst::TimerMoveTaskFetchItem, array('itemId' => $productId, 'source' => $source, 'site' => $site, 'shopId' => $shopId, 'isFromMobileLink' => $isFromMobileLink, 'moveNeedCollectDetail' => FetchClientTool::moveNeedCollectDetail($source), 'trace' => MoveConst::traceDdmsFetchUrl()), 'http', Zc::C('multi.crawler.domain'));
|
|
|
}
|
|
|
|
|
|
$fetchList[$fetchUrl] = array();
|
|
|
}
|
|
|
|
|
|
$ret = $this->moveService->checkPlatformAuthorize($fetchSourceList, [FetchClientConst::collectTaskSource1688]);
|
|
|
if (CommonTool::isFailRet($ret)) {
|
|
|
return $ret;
|
|
|
}
|
|
|
|
|
|
if ($needCheckFree && $aliCount > 50) {
|
|
|
$getVersionRet = $this->shopService->getShopAppVersion($shopId);
|
|
|
$shopVersion = $getVersionRet['appVersion'];
|
|
|
if (AppConst::checkIsFreeVersion($shopVersion)) {
|
|
|
$authCode = $this->shopService->getAuthCodeByShopId($shopId);
|
|
|
$searchRet = $this->dsClient->getDsMemberVersion(DsConst::platformDd, $authCode);
|
|
|
if (CommonTool::isFailRet($searchRet)) {
|
|
|
return $searchRet;
|
|
|
}
|
|
|
$isFree = $searchRet['isFree'];
|
|
|
if ($isFree) {
|
|
|
return CommonTool::failCodeResult(ErrorCodeConst::isDsFreeUserLimit, '每次输入链接最多50条,请减少商品数量后重试或升级高级版');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$ret = $this->checkProductErrorInfo($sourceProducts, $aliCount);
|
|
|
if (CommonTool::isFailRet($ret)) {
|
|
|
return $ret;
|
|
|
}
|
|
|
|
|
|
return CommonTool::successResult([
|
|
|
'fetchList' => $fetchList,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function checkProductErrorInfo($sourceProducts, $aliCount) {
|
|
|
if(empty($sourceProducts)){
|
|
|
return CommonTool::failResult("商品详情页面链接或者ID错误, 请重新输入");
|
|
|
}
|
|
|
if ($aliCount > 200) {
|
|
|
return CommonTool::failCodeResult('overLimit', "1688商品一次最多只支持200个链接,您当前提交了{$aliCount}个商品");
|
|
|
}
|
|
|
if(count($sourceProducts) > 500){
|
|
|
return CommonTool::failCodeResult('overLimit', "最多支持500个商品链接");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private function checkRequireAttrAndQuality($products, $setting) {
|
|
|
if (!empty($setting['isValidateRequire'])) {
|
|
|
return CommonTool::successResult();
|
|
|
}
|
|
|
|
|
|
$requirePresetAttrNames = MoveConst::getRequirePresetAttrNames();
|
|
|
$requirePresetQualityNames = MoveConst::getRequirePresetQualityNames();
|
|
|
|
|
|
$checkAttrNames = [];
|
|
|
foreach ($requirePresetAttrNames as $attrName) {
|
|
|
$isset = false;
|
|
|
foreach ((array)$setting['preset_attrs'] as $presetAttr) {
|
|
|
if (($attrName == $presetAttr['presetAttrName']) && $presetAttr['presetAttrValue'] && ($presetAttr['presetAttrEnable'] == 1)) {
|
|
|
$isset = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (!$isset) {
|
|
|
$checkAttrNames[] = $attrName;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$checkQualityNames = [];
|
|
|
$ret = $this->doGetQualityListByCid($setting['move_shop_setting_id'], 0);
|
|
|
foreach ($requirePresetQualityNames as $qualityName) {
|
|
|
$isset = false;
|
|
|
foreach ($ret['qualityList'] as $quality) {
|
|
|
if (($qualityName == $quality['quality_name']) && !empty($quality['img_list'])) {
|
|
|
$isset = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (!$isset) {
|
|
|
$checkQualityNames[] = $qualityName;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!$checkAttrNames && !$checkQualityNames) {
|
|
|
return CommonTool::successResult();
|
|
|
}
|
|
|
|
|
|
$needGetCateAttrCids = $needGetCateQualityCids = [];
|
|
|
foreach ($products as $product) {
|
|
|
if ($checkAttrNames) {
|
|
|
$needGetCateAttrCids[] = $product['cid'];
|
|
|
}
|
|
|
if ($checkQualityNames) {
|
|
|
$needGetCateQualityCids[] = $product['cid'];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
list($cateAttrs, $cateQualitys) = $this->moveService->getCateAttrsAndQualitys($needGetCateAttrCids, $needGetCateQualityCids, $_SESSION[SessionConst::accessToken]);
|
|
|
if ($needGetCateQualityCids) {
|
|
|
$needGetCateQualityCids[] = 0;
|
|
|
$shopProductQualitySettingList = $this->moveService->getShopProductQualitySettingList($_SESSION[SessionConst::shopId], $setting['move_shop_setting_id'], $needGetCateQualityCids);
|
|
|
$qualitySettings = [];
|
|
|
foreach ($shopProductQualitySettingList as $qualitySetting) {
|
|
|
$qualitySettings[$qualitySetting['cid']][] = $qualitySetting;
|
|
|
}
|
|
|
$productQualityMap = $qualitySettings ? $this->moveService->getProductQualityMap() : null;
|
|
|
}
|
|
|
|
|
|
$requireAttrNames = $requireQualityList = [];
|
|
|
foreach ($products as $product) {
|
|
|
$cid = $product['cid'];
|
|
|
|
|
|
if (!empty($cateAttrs[$cid])) {
|
|
|
foreach ($cateAttrs[$cid] as $prop) {
|
|
|
$propId = $prop['property_id'];
|
|
|
if (in_array($prop['property_name'], $checkAttrNames) && empty($product['props'][$propId]) && $prop['required']) {
|
|
|
$requireAttrNames[] = $prop['property_name'];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!empty($cateQualitys[$cid])) {
|
|
|
$productQualityList = $cateQualitys[$cid];
|
|
|
if ($qualitySettings[0]) {
|
|
|
$productQualityList = $this->moveUtil->appendQualityImgs($productQualityList, $qualitySettings[0], $productQualityMap);
|
|
|
}
|
|
|
if ($qualitySettings[$cid]) {
|
|
|
$productQualityList = $this->moveUtil->appendQualityImgs($productQualityList, $qualitySettings[$cid], $productQualityMap);
|
|
|
}
|
|
|
|
|
|
foreach ($productQualityList as $quality) {
|
|
|
if(!$quality['is_required']) {
|
|
|
continue;
|
|
|
}
|
|
|
if (isset($product['productQualityMap'][$cid][$quality['quality_key']]) && array_filter($product['productQualityMap'][$cid][$quality['quality_key']])) {
|
|
|
continue;
|
|
|
}
|
|
|
if (!empty($quality['img_list'])) {
|
|
|
continue;
|
|
|
}
|
|
|
$requireQualityList[$quality['quality_key']] = $quality;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$res = [];
|
|
|
$requireAttrNames && $res['requireAttrNames'] = $requireAttrNames;
|
|
|
$requireQualityList && $res['requireQualityList'] = $requireQualityList;
|
|
|
if ($res) {
|
|
|
return CommonTool::failResult($res);
|
|
|
} else {
|
|
|
return CommonTool::successResult();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public function saveTask() {
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId start saveTask");
|
|
|
|
|
|
ini_set('memory_limit', '1024M');
|
|
|
$_POST = $_POST['valueMap'] ? json_decode($_POST['valueMap'], true) : json_decode(file_get_contents('php://input'), true); // 20220112起没有valueMap,兼容作用
|
|
|
$needMoveShopIds = isset($_POST['needMoveShopIds']) ? $_POST['needMoveShopIds'] : (array($shopId)); // 前端没有传这个参数的时候使用这个用户自己
|
|
|
$productSimpleDetails = json_decode($_POST['productSimpleDetails'], true);
|
|
|
|
|
|
$copyType = $_POST['copyType'];
|
|
|
|
|
|
$shopMoveSettingOperateLogMap = json_decode($_POST['shopMoveSettingOperateLogMap'], true);
|
|
|
$shopMoveConditionMap = $_POST['shopMoveConditionMap'];
|
|
|
$shopPreviewCateAttr = json_decode($_POST['previewCateAttr'], true);
|
|
|
|
|
|
$source = $_POST['source'];
|
|
|
$isFetchBank = $_POST['isFetchBank'] ? $_POST['isFetchBank'] : false;
|
|
|
$copyType = $isFetchBank ? MoveConst::collectFetchBank : $_POST['copyType'];
|
|
|
|
|
|
$hostname = gethostname();
|
|
|
|
|
|
$shopGroupMoveType = isset($_POST['shopGroupMoveType']) ? $_POST['shopGroupMoveType'] : null;
|
|
|
$shopGroupAllocType = isset($_POST['shopGroupAllocType']) ? $_POST['shopGroupAllocType'] : null;
|
|
|
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId start checkAndFormatData");
|
|
|
$checkAndFormatRet = $this->checkAndFormatData($shopId, $needMoveShopIds, $_POST, $shopMoveConditionMap, $shopPreviewCateAttr, $productSimpleDetails, $hostname, $copyType);
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId end checkAndFormatData");
|
|
|
if (CommonTool::isFailRet($checkAndFormatRet)) {
|
|
|
return $this->renderJSON($checkAndFormatRet);
|
|
|
}
|
|
|
|
|
|
$curProductDetails = $checkAndFormatRet['curProductDetails'];
|
|
|
$shopConditions = $checkAndFormatRet['shopConditions'];
|
|
|
$shopMoveConditionMap = $checkAndFormatRet['shopMoveConditionMap'];
|
|
|
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId start allocShopProductsByAuthShop");
|
|
|
$shopProducts = $this->allocShopProductsByAuthShop($needMoveShopIds, $curProductDetails);
|
|
|
|
|
|
$checkDsValidRet = $this->checkDsValid($needMoveShopIds, $shopProducts);
|
|
|
if (CommonTool::isFailRet($checkDsValidRet)) {
|
|
|
return $this->renderJSON($checkDsValidRet);
|
|
|
}
|
|
|
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId start saveTaskByAuthShop");
|
|
|
$operateSource = $_POST['copyStep2Preview'] ? 'pc' : 'platform'; // 埋点,主客统计搬家来源
|
|
|
$isFromLtaoRank = isset($_POST['isFromLtaoRank']) ? $_POST['isFromLtaoRank'] : 0;
|
|
|
$saveRet = $this->saveTaskByAuthShop($shopId, $copyType, $shopMoveConditionMap, $shopMoveSettingOperateLogMap, $shopConditions, $shopProducts, $shopPreviewCateAttr, $hostname, $operateSource, $isFromLtaoRank);
|
|
|
|
|
|
if (CommonTool::isFailRet($saveRet)) {
|
|
|
return $this->renderJSON($saveRet);
|
|
|
}
|
|
|
|
|
|
$shopTaskId = $saveRet['taskId'];
|
|
|
$redirectURL = Zc::url(RouteConst::moveBatchFinish, array('taskId' => $shopTaskId, 'source' => $source));
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId session shopId " . $_SESSION[SessionConst::shopId] . " saveTask success " . print_r(Zc::G(), true));
|
|
|
$submitCnt = (int)count($shopProducts[$_SESSION[SessionConst::shopId]]);
|
|
|
if ($submitCnt == 0) {
|
|
|
return $this->renderJSON(array(
|
|
|
'result' => 'fail',
|
|
|
'reason' => sprintf('%s:提交商品数为0,请检查是否正常提交商品', $hostname),
|
|
|
'taskId' => $shopTaskId,
|
|
|
'submitCnt' => $submitCnt,
|
|
|
));
|
|
|
}
|
|
|
|
|
|
if ($_POST['sameType']) {
|
|
|
$this->moveService->saveSameProductCopyLog($_POST['sameType'], $_POST['searchSameProductMap'], $shopId, $copyType == MoveConst::collectDsCopy);
|
|
|
}
|
|
|
$this->renderJSON(CommonTool::successResult(array(
|
|
|
'hostname' => $hostname,
|
|
|
'taskId' => $shopTaskId,
|
|
|
'submitCnt' => $submitCnt,
|
|
|
'redirectURL' => $redirectURL
|
|
|
)));
|
|
|
}
|
|
|
|
|
|
private function checkNeedChangeBrand($shopMoveConditionMap) {
|
|
|
return CommonTool::successResult(); // 先不判断
|
|
|
foreach ($shopMoveConditionMap as $authShopId => $moveCondition) {
|
|
|
$brandId = $moveCondition['brand_id'];
|
|
|
|
|
|
if(!is_numeric($brandId) || empty($brandId)) {
|
|
|
return CommonTool::successResult();
|
|
|
}
|
|
|
|
|
|
$name = $this->moveService->getBrandName($brandId, $authShopId);
|
|
|
if(empty($name)) {
|
|
|
return CommonTool::failResult('请在搬家配置重新设置品牌信息在提交任务!');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return CommonTool::successResult();
|
|
|
}
|
|
|
|
|
|
|
|
|
private function getProductSimpleDetails($productSimpleDetails, $shopId) {
|
|
|
foreach ($productSimpleDetails as $authShopId => &$curProductDetails) {
|
|
|
foreach ($curProductDetails as $skipProductId => &$product) {
|
|
|
if ($product['needSkip'] == 1) {
|
|
|
unset($curProductDetails[$skipProductId]);
|
|
|
}
|
|
|
if ($shopId != $authShopId) {
|
|
|
unset($product['freight_template_id']);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return $productSimpleDetails;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function saveTaskFailLog() {
|
|
|
$this->moveService->saveTaskFailLog($_SESSION[SessionConst::shopId], $_REQUEST, $_SERVER, CommonTool::clientIp(), 'save_task_fail_log');
|
|
|
$this->renderJSON(CommonTool::successResult());
|
|
|
}
|
|
|
|
|
|
private function checkAndFormatData($shopId, $needMoveShopIds, $post, $shopMoveConditionMap, $shopPreviewCateAttr, $productSimpleDetails, $hostname, $copyType) {
|
|
|
$hasError = false;
|
|
|
$errorArray = array();
|
|
|
$shopConditions = array();
|
|
|
|
|
|
$productSimpleDetails = $this->getProductSimpleDetails($productSimpleDetails, $shopId);
|
|
|
$curProductDetails = $productSimpleDetails[$shopId];
|
|
|
if(empty($curProductDetails)){
|
|
|
$this->moveService->saveTaskFailLog($_SESSION[SessionConst::shopId], $_REQUEST, $_SERVER, CommonTool::clientIp(), 'save_task');
|
|
|
$this->moveBatchDebugLog->info("shopId[$shopId] empty curProductDetails");
|
|
|
$this->moveBatchDebugLog->info($post);
|
|
|
$ret = CommonTool::failResult(sprintf('%s shopId:%s,未选择要搬家的商品', $hostname, $shopId));
|
|
|
$ret['hostname'] = $hostname;
|
|
|
return $ret;
|
|
|
}
|
|
|
foreach ($curProductDetails as $productId => $productDetail) {
|
|
|
if (!$productDetail['cid']) {
|
|
|
$this->moveBatchDebugLog->info("shopId[$shopId] productId[$productId] invalid cid");
|
|
|
$ret = CommonTool::failResult(sprintf('商品ID:%s 类目必填,请先设置', $productId));
|
|
|
$ret['hostname'] = $hostname;
|
|
|
return $ret;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach ($needMoveShopIds as $authShopId) {
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId $authShopId start rebuild move data");
|
|
|
if (empty($shopMoveConditionMap[$authShopId]) || empty($shopMoveConditionMap[$authShopId]['desc_copy_type'])) {
|
|
|
$hasError = true;
|
|
|
$errorArray[] = sprintf('shopId:%s,搬家配置数据不完整,提交失败。请联系客服!', $authShopId);
|
|
|
$this->moveBatchDebugLog->info("shopId[$authShopId] 搬家配置数据不完整~~");
|
|
|
$this->moveBatchDebugLog->info($post);
|
|
|
break;
|
|
|
}
|
|
|
if (!empty($shopPreviewCateAttr[$authShopId])) {
|
|
|
$shopMoveConditionMap[$authShopId]['usePreviewCommonCateAttr'] = true;
|
|
|
}
|
|
|
$conditionRet = $this->moveService->getTaskCondition($shopMoveConditionMap[$authShopId]);
|
|
|
if(CommonTool::isFailRet($conditionRet)){
|
|
|
$hasError = true;
|
|
|
$errorArray[] = $conditionRet['reason'];
|
|
|
break;
|
|
|
}
|
|
|
$shopConditions[$authShopId] = $conditionRet['condition'];
|
|
|
|
|
|
$shopIsExpire = $this->moveService->checkShopIsExpire($authShopId);
|
|
|
if ($shopIsExpire) {
|
|
|
$shopInfo = $this->shopService->getShop($authShopId);
|
|
|
$hasError = true;
|
|
|
$tip = ($shopId == $authShopId) ? '请联系客服续费!</a>' : '请取消搬家至该店铺';
|
|
|
$errorArray[] = sprintf('店铺【%s】,已过期,%s', $shopInfo['shop_name'], $tip);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if ($copyType == MoveConst::collectDsCopy) {
|
|
|
$this->moveService->attachDsMoveCopyTotal($authShopId);
|
|
|
}
|
|
|
|
|
|
$moveConfig = $this->moveService->getAvailableCopyCount($authShopId);
|
|
|
$productTotal = count($curProductDetails);
|
|
|
$dsProducts = $this->moveService->getDsDetails($curProductDetails);
|
|
|
$dsProductTotal = $dsProducts ? count($dsProducts) : 0;
|
|
|
$productTotal = $productTotal - $dsProductTotal;
|
|
|
if ($productTotal > 0 && $productTotal > $moveConfig['available_total']){
|
|
|
$appVersionRet = $this->shopService->getShopAppVersion($shopId);
|
|
|
$this->moveService->recordTriggerAppVersionLimitLog($shopId, $appVersionRet['appVersion'], $moveConfig['total'], $moveConfig['used_total'], $productTotal, 'move');
|
|
|
$shopInfo = $this->shopService->getShop($authShopId);
|
|
|
$hasError = true;
|
|
|
$tip = $this->moveUtil->getChargeTipByShopInfo($shopInfo, $productTotal, $moveConfig['available_total']);
|
|
|
|
|
|
$errorArray[] = $tip;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ($hasError) {
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId saveTask hasError" . print_r(Zc::G(), true));
|
|
|
$ret = CommonTool::failResult(implode(';', $errorArray));
|
|
|
$ret['hostname'] = $hostname;
|
|
|
return $ret;
|
|
|
}
|
|
|
|
|
|
return CommonTool::successResult(array(
|
|
|
'curProductDetails' => $curProductDetails,
|
|
|
'shopConditions' => $shopConditions,
|
|
|
'shopMoveConditionMap' => $shopMoveConditionMap,
|
|
|
));
|
|
|
}
|
|
|
|
|
|
private function allocShopProductsByAuthShop($needMoveShopIds, $curProductDetails) {
|
|
|
$shopProducts = array();
|
|
|
foreach ($needMoveShopIds as $authShopId) {
|
|
|
foreach ($curProductDetails as $productInfo){
|
|
|
$newProduct = $this->moveUtil->formatSaveMoveTaskProduct($productInfo, $authShopId);
|
|
|
if (empty($newProduct)) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
$productId = $productInfo['productId'];
|
|
|
$shopProducts[$authShopId][$productId] = $newProduct;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return $shopProducts;
|
|
|
}
|
|
|
|
|
|
private function saveTaskByAuthShop($shopId, $copyType, $shopMoveConditionMap, $shopMoveSettingOperateLogMap, $shopConditions, $shopProducts, $shopPreviewCateAttr, $hostname, $operateSource, $isFromLtaoRank) {
|
|
|
Zc::G("shopId $shopId start saveMoveSetting");
|
|
|
list($updateErrorShopIds, $moveShopSettingIds) = $this->saveMoveSetting($shopMoveConditionMap, $shopMoveSettingOperateLogMap);
|
|
|
Zc::G("shopId $shopId end saveMoveSetting");
|
|
|
if (!empty($updateErrorShopIds)) {
|
|
|
$ret = CommonTool::failResult(sprintf('店铺Id:%s,保存搬家配置失败,请稍后再尝试', implode(' ', $updateErrorShopIds)));
|
|
|
$ret['hostname'] = $hostname;
|
|
|
return $ret;
|
|
|
}
|
|
|
|
|
|
if ($copyType == MoveConst::collectLinksCopy) {
|
|
|
$name = sprintf('%s 批量抓取', ZcDateHelper::now());
|
|
|
} else {
|
|
|
$name = sprintf('%s', ZcDateHelper::now());
|
|
|
}
|
|
|
|
|
|
Zc::G("shopId $shopId start replaceShopConditionsBigField");
|
|
|
$shopConditions = $this->moveService->replaceShopConditionsBigField($shopConditions, $moveShopSettingIds);
|
|
|
Zc::G("shopId $shopId end replaceShopConditionsBigField");
|
|
|
$shopConditions = $this->attachMoveSettingIdToMoveTaskCondition($moveShopSettingIds, $shopConditions);
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId start addShopCollectTask");
|
|
|
|
|
|
$addRet = $this->moveService->addShopCollectTask($shopId, $shopProducts, $name, $copyType, $shopConditions, $shopPreviewCateAttr, $operateSource,$isFromLtaoRank);
|
|
|
|
|
|
if (CommonTool::isFailRet($addRet)) {
|
|
|
$this->moveBatchSaveTaskLog->info("shopId $shopId saveTask addRet fail" . print_r(Zc::G(), true));
|
|
|
$addRet['hostname'] = $hostname;
|
|
|
}
|
|
|
|
|
|
return $addRet;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function saveMoveSetting($shopMoveConditionMap, $shopMoveSettingOperateLogMap = array()) {
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$updateErrorShopIds = array();
|
|
|
$moveShopSettingIds = array();
|
|
|
foreach ($shopMoveConditionMap as $authShopId => $moveCondition) {
|
|
|
if (empty($moveCondition)) {
|
|
|
$this->moveBatchSettingLog->info("authShopId[$authShopId] get empty moveCondition");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
$moveCondition = $this->moveUtil->processMoveSetting($moveCondition);
|
|
|
$moveCondition['shop_id'] = $authShopId;
|
|
|
$moveShopSettingId = $moveCondition['move_shop_setting_id'];
|
|
|
if ($moveShopSettingId) {
|
|
|
$ret = $this->moveService->updateMoveSetting($authShopId, $moveShopSettingId, $moveCondition);
|
|
|
$this->moveService->addMoveShopSettingOperateLog($shopId, $authShopId, $shopMoveSettingOperateLogMap[$authShopId]);
|
|
|
$moveShopSettingIds[$authShopId] = $moveShopSettingId;
|
|
|
} else {
|
|
|
$ret = $this->moveService->insertMoveSetting($moveCondition);
|
|
|
if ($ret) {
|
|
|
$moveShopSettingIds[$authShopId] = $ret;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!$ret) {
|
|
|
$updateErrorShopIds[] = $authShopId;
|
|
|
}
|
|
|
$this->moveBatchSettingLog->info("shopId[$shopId] authShopId[$authShopId] post data:" . print_r($moveCondition, true) . "update ret:[$ret]" );
|
|
|
}
|
|
|
return [$updateErrorShopIds, $moveShopSettingIds];
|
|
|
}
|
|
|
|
|
|
public function history() {
|
|
|
$moveShopStopInfo = $this->moveService->getMoveShopStopInfo($_SESSION[SessionConst::shopId]);
|
|
|
$folderMenuTree = $this->materialService->getMaterialFolderMenuTree($_SESSION[SessionConst::shopId]);
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$productCatList = $this->rsyncProductService->getAllLeafProductCatList($_SESSION[SessionConst::shopId]);
|
|
|
$cates = [];
|
|
|
$cates[] = '请选择分类';
|
|
|
foreach ($productCatList as $productCat) {
|
|
|
$cates[$productCat['category_id']] = $productCat['path'];
|
|
|
}
|
|
|
|
|
|
$this->render([
|
|
|
'moveShopStopInfo' => $moveShopStopInfo,
|
|
|
'folderMenuTree' => $folderMenuTree,
|
|
|
'shopId' => $shopId,
|
|
|
'productCatList' => $cates
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
public function historyProductList() {
|
|
|
$pageNo = $_GET['page'] > 0 ? (int)$_GET['page'] : 1;
|
|
|
$pageSize = $_GET['pageSize'] > 0 ? (int)$_GET['pageSize'] : 20;
|
|
|
$source = $_GET['source'];
|
|
|
$status = $_GET['status'];
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$filter = $this->moveUtil->buildHistoryProductListFilter($_GET);
|
|
|
$filter['isMoveHugeSeller'] = $_SESSION[SessionConst::isMoveHugeSeller];
|
|
|
if (!in_array($pageSize, [20, 40, 100, 500, 1000, 2000])) {
|
|
|
$pageSize = 20;
|
|
|
}
|
|
|
|
|
|
list($processingTaskCount, $taskDetailList, $total, $moveShopStopInfo) = $this->productUtil->getHistoryProductList($shopId, $filter, $pageNo, $pageSize);
|
|
|
$taskDetailList = $this->productUtil->buildLtaoProductToDsItemTag($taskDetailList);
|
|
|
$pagin = new ZcPagination($total, $pageSize, $pageNo);
|
|
|
$html = $this->renderWithoutLayout(array(
|
|
|
'taskDetailList' => $taskDetailList,
|
|
|
'pagin' => $pagin,
|
|
|
'pageSize' => $pageSize,
|
|
|
'status' => $status,
|
|
|
'source' => $source,
|
|
|
'taskTotal' => $total,
|
|
|
'processingTaskCount' => $processingTaskCount,
|
|
|
'filter' => $filter,
|
|
|
'moveShopStopInfo' => $moveShopStopInfo,
|
|
|
'showLimitPublishReason' => $this->productUtil->showLimitPublishReason($taskDetailList, $moveShopStopInfo),
|
|
|
), 'move/batch/history_product_list', true);
|
|
|
$data['html'] = $html;
|
|
|
return $this->renderJSON($data);
|
|
|
}
|
|
|
|
|
|
|
|
|
public function failRetryMoveTasks() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$taskDetailIds = is_array($_POST['taskDetailIds']) ? $_POST['taskDetailIds'] : [$_POST['taskDetailIds']];
|
|
|
|
|
|
$retryRet = $this->moveUtil->failRetryMoveTasks($shopId, $taskDetailIds, $this->failRetryMoveTaskLog);
|
|
|
$this->renderJSON($retryRet);
|
|
|
}
|
|
|
|
|
|
|
|
|
public function moveAgainDetail() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$taskDetailIds = is_array($_POST['taskDetailIds']) ? $_POST['taskDetailIds'] : [$_POST['taskDetailIds']];
|
|
|
|
|
|
|
|
|
if (count($taskDetailIds) == 1) {
|
|
|
$newDetailId = $this->moveService->moveAgainDetailsByDetailId($shopId, array_pop($taskDetailIds), false, $this->moveAgainDetailLog);
|
|
|
if ($newDetailId) {
|
|
|
return $this->renderJSON(CommonTool::successResult('processCount', 1));
|
|
|
} else {
|
|
|
return $this->renderJSON(CommonTool::failResult('当前商品数据已失效,暂不支持操作,如有疑问请联系客服'));
|
|
|
}
|
|
|
} else {
|
|
|
$ret = $this->moveUtil->moveAgainDetail($shopId, $taskDetailIds, $this->moveAgainDetailLog);
|
|
|
return $this->renderJSON($ret);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public function deleteDeleteTask(){
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult(ErrorCodeConst::csrfTokenErrorTip));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$delCnt = 0;
|
|
|
ZC::G('start deleteDeleteTask');
|
|
|
$detailIds = $this->moveService->getAllDeleteMoveCollectTaskDetailIds($shopId);
|
|
|
|
|
|
$allChunkedDetailIds = array_chunk($detailIds, 100);
|
|
|
foreach ($allChunkedDetailIds as $sliceDetailIds) {
|
|
|
foreach ($sliceDetailIds as $detailId) {
|
|
|
$delRet = $this->moveService->delMoveTaskDetailHistory($shopId, $detailId);
|
|
|
if ($delRet) {
|
|
|
$delCnt++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
ZC::G('end deleteFailTask');
|
|
|
|
|
|
return $this->renderJSON(CommonTool::successResult('total', $delCnt));
|
|
|
}
|
|
|
|
|
|
public function batchDeleteTaskDetail() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$accessToken = $_SESSION[SessionConst::accessToken];
|
|
|
$ret = $this->moveUtil->batchDeleteTaskDetail($shopId, $accessToken);
|
|
|
return $this->renderJSON($ret);
|
|
|
}
|
|
|
|
|
|
public function cancelCollectTask() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
list($successCancelDetailIds, $skipCancelDetailIds) = $this->moveUtil->cancelCollectTask();
|
|
|
$html = '';
|
|
|
if ($skipCancelDetailIds) {
|
|
|
list($processingTaskCount, $taskDetailList,) = $this->productUtil->getHistoryProductList($_SESSION[SessionConst::shopId], ['taskDetailIds' => $skipCancelDetailIds], 1, count($skipCancelDetailIds));
|
|
|
$html = $this->renderWithoutLayout(array(
|
|
|
'taskDetailList' => $taskDetailList,
|
|
|
), 'move/batch/skip_cancel', true);
|
|
|
}
|
|
|
|
|
|
return $this->renderJSON(CommonTool::successResult([
|
|
|
'processCount' => count($successCancelDetailIds),
|
|
|
'skipCount' => count($skipCancelDetailIds),
|
|
|
'html' => $html
|
|
|
]));
|
|
|
}
|
|
|
|
|
|
public function deleteFailTaskDetail() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$delCount = $this->moveService->delMoveHistoryByStatus($shopId, StatusConst::fail);
|
|
|
return $this->renderJSON(CommonTool::successResult('total', $delCount));
|
|
|
}
|
|
|
|
|
|
public function deleteSkipTaskDetail() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult('CSRF校验不通过'));
|
|
|
}
|
|
|
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$delCount = $this->moveService->delMoveHistoryByStatus($shopId, StatusConst::skip);
|
|
|
return $this->renderJSON(CommonTool::successResult('total', $delCount));
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getDsAuthUrl() {
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$getUrlRet = $this->dsClient->getDsAuthUrl($shopId, AppConst::getDsPlatform(), Zc::C('acn.ds.domain'));
|
|
|
|
|
|
return $this->renderJSON($getUrlRet);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function checkDsAuthExpire() {
|
|
|
$log = Zc::getLog('tool/fetch/checkAuth');
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$authCode = $this->shopService->getAuthCodeByShopId($shopId);
|
|
|
if (empty($authCode)) {
|
|
|
return $this->renderJSON(CommonTool::successResult());
|
|
|
}
|
|
|
|
|
|
$dsMemberInfo = $this->moveService->getDsMemberInfo($shopId);
|
|
|
|
|
|
$checkRet = $this->dsClient->checkDsAppAuthExpire(AppConst::getDsPlatform(), [], $dsMemberInfo['cnali_member_id'], $authCode);
|
|
|
$log->info('-----checkRet-----' . print_r($checkRet, true));
|
|
|
if (CommonTool::isFailRet($checkRet)) {
|
|
|
return $this->renderJSON(CommonTool::successResult());
|
|
|
}
|
|
|
$checkRet = $checkRet['userIdAndCheckRetMap'][$shopId];
|
|
|
|
|
|
if (CommonTool::isSuccessRet($checkRet) || empty($checkRet['code'])) {
|
|
|
return $this->renderJSON(CommonTool::successResult());
|
|
|
}
|
|
|
|
|
|
if ($checkRet['code'] == DsConst::authExpireTypeAuthExpire) {
|
|
|
$getUrlRet = $this->dsClient->getDsAuthUrl($shopId, AppConst::getDsPlatform(), Zc::C('acn.ds.domain'));
|
|
|
if (CommonTool::isSuccessRet($getUrlRet)) {
|
|
|
$checkRet['reason'] = sprintf('<i class="fa fa-exclamation-circle" style="color: red;"></i>1688' . DsConst::getDsAppChineseName() . '授权已失效,<a href="%s" target="_blank">重新授权</a>', $getUrlRet['redirectUrl']);
|
|
|
}
|
|
|
} else {
|
|
|
$dsBuyUrl = $this->moveService->getDsBuyUrl($shopId);
|
|
|
$checkRet['reason'] = sprintf('<i class="fa fa-exclamation-circle" style="color: red;"></i>1688' . DsConst::getDsAppChineseName() . '已过期,<a href="%s" target="_blank">重新订购</a>', $dsBuyUrl);
|
|
|
}
|
|
|
|
|
|
return $this->renderJSON($checkRet);
|
|
|
}
|
|
|
|
|
|
private function buildSearchSameProductFilter($sameType, $detailUrls, $shopId, $cluePicUrlNameMap = []) {
|
|
|
if ($sameType == MoveConst::collectSameProductTypeImg) {
|
|
|
if (empty($_FILES['searchSameProductImg'])) {
|
|
|
return CommonTool::failResult('请上传图片');
|
|
|
}
|
|
|
$moveDir = 'shop/upload/' . $shopId;
|
|
|
$uploadRet = $this->materialUtil->uploadLocalMultipleImageToOss('searchSameProductImg', $moveDir, false);
|
|
|
if (CommonTool::isFailRet($uploadRet)) {
|
|
|
return $uploadRet;
|
|
|
}
|
|
|
$srcs = ZcArrayHelper::getSub($uploadRet['images'], 'src');
|
|
|
$detailUrls = implode(',', $srcs);
|
|
|
if (empty($detailUrls)) {
|
|
|
return CommonTool::failResult('上传图片失败,请重试');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$detailUrls = array_map('trim', preg_split("/\\r\\n|\\r|\\n|,|,|;|;/u", $detailUrls));
|
|
|
$detailUrls = array_filter(array_unique($detailUrls));
|
|
|
if (empty($detailUrls)) {
|
|
|
return CommonTool::failResult('请输入链接');
|
|
|
}
|
|
|
|
|
|
$detailUrls = array_slice($detailUrls, 0, 10);
|
|
|
$productsInfoList = [];
|
|
|
if ($sameType == MoveConst::collectSameProductTypeMixContent) {
|
|
|
$linkDetails = [];
|
|
|
$k = mt_rand(1000, 100000);
|
|
|
foreach ($detailUrls as $detailUrl) {
|
|
|
if (CommonTool::checkIsImageLink($detailUrl)) {
|
|
|
$k++;
|
|
|
$productsInfoList[$k] = [
|
|
|
'itemId' => $k,
|
|
|
'imgUrl' => $detailUrl,
|
|
|
'title' => $cluePicUrlNameMap[$detailUrl] ?: '',
|
|
|
];
|
|
|
} else {
|
|
|
$linkDetails[] = $detailUrl;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ($linkDetails) {
|
|
|
$getProductsInfoListRet = $this->moveUtil->getProductsInfoListByDetailUrls(implode(',', $linkDetails), $shopId, null, null, null, null, true);
|
|
|
if (CommonTool::isSuccessRet($getProductsInfoListRet)) {
|
|
|
$fetchProductsInfoList = $getProductsInfoListRet['productsInfoList'];
|
|
|
$fetchProductsInfoList = $this->buildSearchSameProductProductInfoList($fetchProductsInfoList);
|
|
|
$productsInfoList = $productsInfoList + $fetchProductsInfoList;
|
|
|
}
|
|
|
}
|
|
|
} else if ($sameType == MoveConst::collectSameProductTypeLink) {
|
|
|
$getProductsInfoListRet = $this->moveUtil->getProductsInfoListByDetailUrls(implode(',', $detailUrls), $shopId);
|
|
|
if (CommonTool::isFailRet($getProductsInfoListRet)) {
|
|
|
return $getProductsInfoListRet;
|
|
|
}
|
|
|
|
|
|
$productsInfoList = $getProductsInfoListRet['productsInfoList'];
|
|
|
$productsInfoList = $this->buildSearchSameProductProductInfoList($productsInfoList);
|
|
|
} else if ($sameType == MoveConst::collectSameProductTypeImgUrl || $sameType == MoveConst::collectSameProductTypeImg) {
|
|
|
$k = mt_rand(1000, 100000);
|
|
|
foreach ($detailUrls as $imgUrl) {
|
|
|
$k++;
|
|
|
$productsInfoList[$k] = [
|
|
|
'itemId' => $k,
|
|
|
'imgUrl' => $imgUrl,
|
|
|
'title' => $cluePicUrlNameMap[$imgUrl] ?: '',
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return CommonTool::successResult('productsInfoList', $productsInfoList);
|
|
|
}
|
|
|
|
|
|
public function searchSameProduct() {
|
|
|
if (!$this->webShop->validateCsrfToken()) {
|
|
|
return $this->renderJSON(CommonTool::failResult(ErrorCodeConst::csrfTokenErrorTip));
|
|
|
}
|
|
|
|
|
|
$this->moveBatchUrlLog->info('fetchDetailUrlInfo, shopId[' . $_SESSION[SessionConst::shopId] . '], post: ' . print_r($_POST, true));
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
$detailUrls = $_POST['detailUrls'];
|
|
|
$sameType = $_POST['sameType'];
|
|
|
$copyType = $_POST['copyType'];
|
|
|
$cluePicUrlNameMap = $_POST['cluePicUrlNameMap'];
|
|
|
|
|
|
$checkRet = $this->moveUtil->checkAbnormalRequest($shopId);
|
|
|
if (CommonTool::isFailRet($checkRet)) {
|
|
|
return $this->renderJSON($checkRet);
|
|
|
}
|
|
|
|
|
|
$ret = $this->buildSearchSameProductFilter($sameType, $detailUrls, $shopId, $cluePicUrlNameMap ?: []);
|
|
|
if (CommonTool::isFailRet($ret)) {
|
|
|
return $this->renderJSON($ret);
|
|
|
}
|
|
|
$productsInfoList = $ret['productsInfoList'];
|
|
|
|
|
|
if ($copyType == MoveConst::collectLtaoCopy) {
|
|
|
list($productsInfoList) = $this->moveUtil->searchLtaoSameProducts($productsInfoList, $shopId, $cluePicUrlNameMap ?: []);
|
|
|
} else {
|
|
|
$productsInfoList = $this->moveUtil->searchSameProducts($productsInfoList, FetchClientConst::collectTaskSource1688, $shopId, $copyType == MoveConst::collectDsCopy);
|
|
|
}
|
|
|
|
|
|
$productsInfoList = $this->mergeSameProductIsSelect($productsInfoList);
|
|
|
|
|
|
|
|
|
$html = $this->renderWithoutLayout([
|
|
|
'productsInfoList' => $productsInfoList,
|
|
|
'copyType' => $copyType,
|
|
|
], 'move/batch/search_1688_same_product', true);
|
|
|
|
|
|
return $this->renderJSON(CommonTool::successResult([
|
|
|
'html' => $html,
|
|
|
'productsInfoList' => $productsInfoList
|
|
|
]));
|
|
|
}
|
|
|
|
|
|
private function filterNotDsProducts($productsInfoList, $shopId) {
|
|
|
$i = 0;
|
|
|
foreach ($productsInfoList as &$productsInfo) {
|
|
|
$sameWareList = array_slice($productsInfo['sameWareList'], 0, 20);
|
|
|
$sameWareList = ZcArrayHelper::changeKeyRow($sameWareList, 'itemId');
|
|
|
$productsInfo['sameWareList'] = $sameWareList;
|
|
|
$productsInfo['sameWareNum'] = count($productsInfo['sameWareList']);
|
|
|
if ($i > 0) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
$detailUrls = ZcArrayHelper::getSub($productsInfo['sameWareList'], 'itemUrl');
|
|
|
|
|
|
$detailUrls = implode(',', $detailUrls);
|
|
|
$getProductInfoListRet = $this->getAlibabaProductsInfoListByDetailUrls($detailUrls, $shopId);
|
|
|
if (CommonTool::isFailRet($getProductInfoListRet)) {
|
|
|
$productsInfo['sameWareList'] = [];
|
|
|
$productsInfo['sameWareNum'] = 0;
|
|
|
$i++;
|
|
|
continue;
|
|
|
}
|
|
|
$itemsInfoList = $getProductInfoListRet['productsInfoList'];
|
|
|
|
|
|
foreach ($productsInfo['sameWareList'] as $itemId => $itemInfo) {
|
|
|
if (!isset($itemsInfoList[$itemId]) || !$itemsInfoList[$itemId]['isFromDs']) {
|
|
|
unset($productsInfo['sameWareList'][$itemId]);
|
|
|
}
|
|
|
}
|
|
|
$productsInfo['sameWareNum'] = count($productsInfo['sameWareList']);
|
|
|
$productsInfo['hasFilterDs'] = true;
|
|
|
$i++;
|
|
|
}
|
|
|
|
|
|
return $productsInfoList;
|
|
|
}
|
|
|
|
|
|
private function buildSearchSameProductProductInfoList($productsInfoList) {
|
|
|
$newProductsInfoList = [];
|
|
|
foreach ($productsInfoList as $productsInfo) {
|
|
|
$imgUrl = $productsInfo['item_image'] ?: reset($productsInfo['image_paths']);
|
|
|
if (empty($imgUrl)) {
|
|
|
continue;
|
|
|
}
|
|
|
$newProductsInfoList[$productsInfo['itemId']] = [
|
|
|
'itemId' => $productsInfo['itemId'],
|
|
|
'source' => $productsInfo['source'],
|
|
|
'site' => $productsInfo['site'],
|
|
|
'imgUrl' => $imgUrl,
|
|
|
'title' => $productsInfo['title'],
|
|
|
'price' => $productsInfo['sale_price'] ?: $productsInfo['jd_price']
|
|
|
];
|
|
|
}
|
|
|
|
|
|
return $newProductsInfoList;
|
|
|
}
|
|
|
|
|
|
private function mergeSameProductIsSelect($productsInfoList) {
|
|
|
foreach ($productsInfoList as &$productsInfo) {
|
|
|
foreach ($productsInfo['sameWareList'] as &$sameProduct) {
|
|
|
$sameProduct['isSelect'] = 0;
|
|
|
unset($sameProduct);
|
|
|
}
|
|
|
unset($productsInfo);
|
|
|
}
|
|
|
|
|
|
return $productsInfoList;
|
|
|
}
|
|
|
|
|
|
public function singleRetrySearchSameProduct() {
|
|
|
$shopId = $_SESSION[SessionConst::shopId];
|
|
|
|
|
|
$imgUrl = $_POST['imgUrl'];
|
|
|
$copyType = $_POST['copyType'];
|
|
|
$cluePicUrlNameMap = $_POST['cluePicUrlNameMap'];
|
|
|
|
|
|
$productsInfoList = ['100000' => ['itemId' => 100000, 'imgUrl' => $imgUrl]];
|
|
|
if ($copyType == MoveConst::collectLtaoCopy) {
|
|
|
list($productsInfoList) = $this->moveUtil->searchLtaoSameProducts($productsInfoList, $shopId, $cluePicUrlNameMap ?: []);
|
|
|
} else {
|
|
|
$productsInfoList = $this->moveUtil->searchSameProducts($productsInfoList, FetchClientConst::collectTaskSource1688, $shopId, $copyType == MoveConst::collectDsCopy);
|
|
|
}
|
|
|
$productsInfoList = $this->mergeSameProductIsSelect($productsInfoList);
|
|
|
|
|
|
if ($copyType == MoveConst::collectDsCopy) {
|
|
|
$productsInfoList = $this->filterNotDsProducts($productsInfoList, $shopId);
|
|
|
}
|
|
|
|
|
|
$sameProductInfos = $productsInfoList[100000];
|
|
|
|
|
|
return CommonTool::successResult([
|
|
|
'sameProductInfos' => $sameProductInfos
|
|
|
]);
|
|
|
}
|
|
|
} |