MQuickGoods.Class.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. <?php
  2. namespace JinDouYun\Model\Goods;
  3. use JinDouYun\Cache\GoodsBasicCache;
  4. use JinDouYun\Cache\GoodsBasicRelevant;
  5. use Jindouyun\Cache\RoleAclCache;
  6. use JinDouYun\Cache\SkuCache;
  7. use JinDouYun\Controller\Common\Logger;
  8. use JinDouYun\Dao\GoodsManage\DGoodsBasic;
  9. use JinDouYun\Dao\GoodsManage\DSku;
  10. use JinDouYun\Model\Commission\MCommissionSetting;
  11. use JinDouYun\Model\GoodsManage\MGoodsBasic;
  12. use JinDouYun\Model\GoodsManage\MSku;
  13. use JinDouYun\Model\MBaseModel;
  14. use JinDouYun\Model\Price\MCustomerPriceAdjustment;
  15. use JinDouYun\Model\Price\MCustomerTypePriceAdjustment;
  16. use JinDouYun\Model\Shop\MShop;
  17. use JinDouYun\Model\Stock\MInventory;
  18. use Mall\Framework\Core\ErrorCode;
  19. use Mall\Framework\Core\ResultWrapper;
  20. use Mall\Framework\Core\StatusCode;
  21. use Util\Common\ChineseCharacter;
  22. use const Grpc\STATUS_ABORTED;
  23. class MQuickGoods extends MBaseModel
  24. {
  25. /**
  26. * BasicAndSkuCache
  27. */
  28. use BasicAndSkuCache;
  29. /**
  30. * @var integer
  31. */
  32. private $onlineEnterpriseId;
  33. /**
  34. * @var integer
  35. */
  36. private $onlineUserId;
  37. /**
  38. * @var MGoods
  39. */
  40. private $objMGoods;
  41. /**
  42. * @var MGoodsBasic
  43. */
  44. private $objMGoodsBasic;
  45. /**
  46. * @var DGoodsBasic
  47. */
  48. private $objDGoodsBasic;
  49. /**
  50. * @var DSku
  51. */
  52. private $objDSku;
  53. private $objGoodsBasicCache;
  54. /**
  55. * @var MShop
  56. */
  57. private $objMShop;
  58. /**
  59. * @var MInventory
  60. */
  61. private $objMInventory;
  62. /**
  63. * @var GoodsBasicRelevant
  64. */
  65. private $objGoodsBasicRelevant;
  66. /**
  67. * @var SkuCache
  68. */
  69. private $objSkuCache;
  70. /**
  71. * @var MCommissionSetting
  72. */
  73. private $objMCommissionSetting;
  74. /**
  75. * @var MSku
  76. */
  77. private $objMSku;
  78. /**
  79. * MQuickGoods constructor.
  80. * @param $onlineEnterpriseId
  81. * @param $onlineUserId
  82. * @throws \Exception
  83. */
  84. public function __construct($onlineEnterpriseId, $onlineUserId)
  85. {
  86. $this->onlineEnterpriseId = $onlineEnterpriseId;
  87. $this->onlineUserId = $onlineUserId;
  88. parent::__construct($onlineEnterpriseId, $onlineUserId);
  89. $this->objMGoods = new MGoods($this->onlineEnterpriseId, false, $this->onlineUserId);
  90. $this->objMGoodsBasic = new MGoodsBasic($this->onlineUserId, $this->onlineEnterpriseId);
  91. $this->objDGoodsBasic = new DGoodsBasic();
  92. $this->objDGoodsBasic->setTable('qianniao_goods_basic_'.$this->onlineEnterpriseId);
  93. $this->objDSku = new DSku();
  94. $this->objMSku = new MSku($this->onlineUserId,$this->onlineEnterpriseId);
  95. $this->objMShop = new MShop($this->onlineEnterpriseId,$this->onlineUserId);
  96. $this->objMInventory = new MInventory($this->onlineEnterpriseId,$this->onlineUserId);
  97. $this->objDSku->setTable('qianniao_sku_'.$this->onlineEnterpriseId);
  98. $this->objGoodsBasicCache = new GoodsBasicCache($this->onlineEnterpriseId);
  99. $this->objGoodsBasicRelevant = new GoodsBasicRelevant($this->onlineEnterpriseId);
  100. $this->objSkuCache = new SkuCache($this->onlineEnterpriseId);
  101. $this->objMCommissionSetting = new MCommissionSetting($this->onlineEnterpriseId,$this->onlineUserId);
  102. }
  103. /**
  104. * @param $params
  105. * @return ResultWrapper
  106. * @throws \Exception
  107. */
  108. public function addBasicAndPublishGoods($params)
  109. {
  110. $goodsBasic = [
  111. 'title' => $params['title'],
  112. 'categoryId' => $params['categoryId'],
  113. 'categoryPath' => $params['categoryPath'],
  114. 'assistCategoryId' => $params['assistCategoryId'],
  115. 'assistCategoryPath' => $params['assistCategoryPath'],
  116. 'images' => $params['images'],
  117. 'specType' => $params['specType'],
  118. 'brandId' => $params['brandId'],
  119. 'description' => $params['description'],
  120. 'describe' => $params['describe'],
  121. 'expireTime' => $params['expireTime'],
  122. 'tag' => $params['tag'],
  123. 'barCode' => $params['barCode'],
  124. 'link' => $params['link'],
  125. 'noSalesShop' => $params['noSalesShop'],
  126. 'specGroup' => $params['specGroup'],
  127. 'extends' => getArrayItem($params, 'extends', '[]'),
  128. 'supplierId' => getArrayItem($params,'supplierId',0),
  129. 'isEq' => getArrayItem($params,'isEq',StatusCode::$delete),
  130. 'merchantId' => $params['merchantId'],
  131. ];
  132. if (isset($params['isStore']) && $params['isStore'] == true){
  133. $goodsBasic['storeId'] = $params['shopId'];//发布此商品的商户id
  134. $goodsBasic['level'] = StatusCode::$delete;//商户级别商品
  135. }
  136. $dbResult = self::addQuickGoodsBasic($params,$goodsBasic,$params['unitData'],$params['specMultiple']);
  137. if (!$dbResult ->isSuccess()){
  138. return ResultWrapper::fail($dbResult->getData(),$dbResult->getErrorCode());
  139. }
  140. return ResultWrapper::success($dbResult);
  141. }
  142. /**
  143. * @param $params
  144. * @param $goodsBasic
  145. * @param $unitData
  146. * @param $specMultiple
  147. * @return ResultWrapper
  148. * @throws \Exception
  149. */
  150. public function addQuickGoodsBasic($params,$goodsBasic, $unitData, $specMultiple)
  151. {
  152. $goodsBasic['addUserId'] = $this->onlineUserId;//创建人id
  153. $objRoleAclCache = new RoleAclCache();
  154. $staffId = $objRoleAclCache->getStaffIdAndUserCenterId($this->onlineEnterpriseId, $this->onlineUserId);
  155. $goodsBasic['salesManId'] = empty($staffId) ? 0 : $staffId;
  156. //商品名称转换搜索条件
  157. $objChineseCharacter = new ChineseCharacter();
  158. $goodsBasic['condition'] = $objChineseCharacter->getInitials(trim($params['title']));
  159. $this->objDGoodsBasic->beginTransaction();
  160. $dbResult = $this->objDGoodsBasic->insert($goodsBasic);
  161. if ($dbResult === false) {
  162. $this->objDGoodsBasic->rollBack();
  163. return ResultWrapper::fail($this->objDGoodsBasic->error(), ErrorCode::$dberror);
  164. }
  165. $goodsBasicId = $dbResult;
  166. $skuInsert = [];
  167. foreach ($specMultiple as $key => $item) {
  168. $skuInsert[$key] = [
  169. 'goodsId' => $goodsBasicId,
  170. 'conversion' => isset($item['conversion']) ? $item['conversion'] : 0,
  171. 'unitId' => $item['unitId'],
  172. 'unitName' => $item['unitName'],
  173. 'isMaster' => $item['isMaster'],
  174. 'createTime' => time(),
  175. 'specType' => $params['specType'],
  176. 'barCode' => isset($item['barCode']) ? $item['barCode'] : '',
  177. 'isDefault' => isset($item['isDefault']) ? $item['isDefault'] : StatusCode::$delete,
  178. 'weight' => isset($item['weight']) ? $item['weight'] : 0,
  179. 'isNew' => StatusCode::$standard,
  180. ];
  181. if ($params['specType'] == StatusCode::$specType['multiple']){
  182. $specGroupIds = array_column($item['specGroup'], 'specValueId');
  183. $hash = md5(implode('|', $specGroupIds));
  184. $skuInsert[$key]['specImage'] = json_encode($item['specImage']);
  185. $skuInsert[$key]['specGroupHash'] = $hash;
  186. $skuInsert[$key]['specData'] = json_encode($item['specGroup']);
  187. }
  188. }
  189. //添加sku
  190. $skuResult =$this->objDSku->insert($skuInsert,true);
  191. if ($skuResult === false) {
  192. $this->objDGoodsBasic->rollBack();
  193. return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
  194. }
  195. //缓存sku
  196. $this->updateSku = $skuResult;
  197. $this->isUpdateSku = true;
  198. //缓存商品分类下基础商品数量
  199. $categoryIds = explode(',', $params['categoryPath']);
  200. foreach ($categoryIds as $v) {
  201. $this->objGoodsBasicCache->categoryKeyScoreIncr($v);
  202. }
  203. $this->objGoodsBasicCache->brandKeyScoreIncr($params['brandId']);
  204. //缓存基础商品数据
  205. $this->isUpdateBasicCache = true;
  206. $this->objectId = $goodsBasicId;
  207. //操作es
  208. //$this->objMGoodsBasic->updateEsData($goodsBasicId);
  209. //将sku写入salePrice中
  210. $priceData = [];
  211. $customerPrices = [];//客户调价
  212. $customerTypePrices = [];//客户类型调价
  213. $skuResult = (array) $skuResult;
  214. foreach ($skuResult as $key => $id){
  215. if (!isset($specMultiple[$key])){
  216. continue;
  217. }
  218. $thisSalePrice = null;
  219. $thisSalePrice = $specMultiple[$key]['salePrice'];
  220. $thisSalePrice['id'] = $id;
  221. $priceData[] = $thisSalePrice;
  222. $thisCustomerPrice = null;
  223. $thisCustomerPrice = isset($specMultiple[$key]['customerPrice']) ? $specMultiple[$key]['customerPrice'] : [];
  224. if (!empty($thisCustomerPrice)){
  225. self::pushVal($thisCustomerPrice,$id,'skuId');
  226. $customerPrices[] = $thisCustomerPrice;
  227. }
  228. $thisCustomerTypePrice = null;
  229. $thisCustomerTypePrice = isset($specMultiple[$key]['customerTypePrice']) ? $specMultiple[$key]['customerTypePrice'] : [];
  230. if (!empty($thisCustomerTypePrice)){
  231. self::pushVal($thisCustomerTypePrice,$id,'skuId');
  232. $customerTypePrices[] = $thisCustomerTypePrice;
  233. }
  234. }
  235. $goods = [
  236. 'basicGoodsId' => $goodsBasicId,
  237. 'merchantId' => getArrayItem($params, 'merchantId', 0),
  238. 'goodsName' => $params['title'],
  239. 'shopId' => $params['shopId'],
  240. 'staffId' => $goodsBasic['addUserId'],
  241. 'shopName' => $params['shopName'],//商铺名称
  242. 'images' => $params['images'],
  243. 'specType' => $params['specType'],//规格类型
  244. 'enableStatus' => getArrayItem($params, 'enableStatus', StatusCode::$delete),
  245. 'priceData' => $priceData,
  246. 'createUserName' => $params['createUserName'],
  247. 'content' => $params['description'],
  248. 'isRecommend' => StatusCode::$standard,
  249. 'sort' => $params['sort'],
  250. 'deleteStatus'=> StatusCode::$standard,
  251. 'createTime' => time(),
  252. 'supplierId' => getArrayItem($params,'supplierId',0),
  253. 'isShield' => getArrayItem($params,'isShield',0),
  254. 'notArea' => getArrayItem($params,'notArea',''),
  255. 'notCustomerType' => getArrayItem($params,'notCustomerType',''),
  256. 'notCustomer' => getArrayItem($params,'notCustomer',''),
  257. 'isDistribution' => getArrayItem($params,'isDistribution',StatusCode::$delete),
  258. ];
  259. if (isset($params['isStore']) && $params['isStore'] == true){
  260. $goods['auditStatus'] = StatusCode::$auditStatus['auditing'];//正在审核
  261. $goods['enableStatus'] = StatusCode::$delete;//下架状态
  262. $goods['isOption'] = StatusCode::$standard;//自选商品
  263. }
  264. isset($params['deliverySupIds']) && $goods['deliverySupIds'] = $params['deliverySupIds'];
  265. isset($params['expressType']) && $goods['expressType'] = $params['expressType'];
  266. isset($params['ruleId']) && $goods['ruleId'] = $params['ruleId'];
  267. isset($params['expressFee']) && $goods['expressFee'] = $params['expressFee'];
  268. isset($params['showExpress']) && $goods['showExpress'] = $params['showExpress'];
  269. $commissionResult = $this->objMCommissionSetting->getSetting('goods');
  270. if (!$commissionResult->isSuccess()){
  271. $this->objDGoodsBasic->rollBack();
  272. return ResultWrapper::fail($commissionResult->getData(),$commissionResult->getErrorCode());
  273. }
  274. $goods['isJoinCommission'] = !empty($commissionResult->getData()) ? $commissionResult->getData() : StatusCode::$delete;
  275. //将数据写入商品表
  276. $goodsResult = $this->objMGoods->addGoods($goods);
  277. if (!$goodsResult->isSuccess()){
  278. $this->objDGoodsBasic->rollBack();
  279. return ResultWrapper::fail($goodsResult->getData(), $goodsResult->getErrorCode());
  280. }
  281. $params['goodsId'] = (int)$goodsResult->getData();
  282. if (!empty($customerPrices)){
  283. //生成客户调价单
  284. $buildCustomerPrice = self::buildCustomerPrice($customerPrices,$params);
  285. $objMCustomerPriceAdjustment = new MCustomerPriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
  286. $adjustmentResult = $objMCustomerPriceAdjustment->add($buildCustomerPrice);
  287. if (!$adjustmentResult->isSuccess()){
  288. Logger::logs(E_USER_ERROR,'add',__CLASS__,__LINE__,$adjustmentResult->getData());
  289. $this->objDGoodsBasic->rollBack();
  290. return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
  291. }
  292. $sheetIds = $adjustmentResult->getData();
  293. foreach ($sheetIds as $key => $id){
  294. $row = getArrayItem($buildCustomerPrice,$key,[]);
  295. $effectiveResult = $objMCustomerPriceAdjustment->effective($id,$row);
  296. if (!$effectiveResult->isSuccess()){
  297. $this->objDGoodsBasic->rollBack();
  298. return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
  299. }
  300. }
  301. }
  302. if (!empty($customerTypePrices)){
  303. //生成客户类型调价
  304. $buildCustomerTypePrice = self::buildCustomerTypePrice($customerTypePrices,$params);
  305. $objMCustomerTypePriceAdjustment = new MCustomerTypePriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
  306. $adjustmentResult = $objMCustomerTypePriceAdjustment->add($buildCustomerTypePrice);
  307. if (!$adjustmentResult->isSuccess()){
  308. Logger::logs(E_USER_ERROR,'add',__CLASS__,__LINE__,$adjustmentResult->getData());
  309. $this->objDGoodsBasic->rollBack();
  310. return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
  311. }
  312. $sheetIds = $adjustmentResult->getData();
  313. foreach ($sheetIds as $key => $id){
  314. $row = getArrayItem($buildCustomerTypePrice,$key,[]);
  315. $effectiveResult = $objMCustomerTypePriceAdjustment->effective($id,$row);
  316. if (!$effectiveResult->isSuccess()){
  317. $this->objDGoodsBasic->rollBack();
  318. return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
  319. }
  320. }
  321. }
  322. $this->objDGoodsBasic->commit();
  323. $this->objGoodsBasicCache->brandKeyScoreIncr($params['brandId']);
  324. return ResultWrapper::success($goodsResult);
  325. }
  326. /**
  327. * Doc: (des="")
  328. * User: XMing
  329. * Date: 2021/3/25
  330. * Time: 4:22 下午
  331. * @param array $params
  332. * @param array $common
  333. * @return array
  334. */
  335. private function buildCustomerPrice(array $params,array $common): array
  336. {
  337. if (empty($params)){
  338. return [];
  339. }
  340. $line = [
  341. "createUserName" => getArrayItem($common,'createUserName',''),
  342. "goodsName" => getArrayItem($common,'title',''),
  343. 'goodsCode' => createCode(StatusCode::$code['goodsBasic']['prefix'], $common['goodsId'], StatusCode::$code['goodsBasic']['length']),
  344. "goodsId" => getArrayItem($common,'goodsId',0),
  345. "shopId" => getArrayItem($common,'shopId',0),
  346. "shopName" => getArrayItem($common,'shopName',''),
  347. 'createTime' => time(),
  348. 'updateTime' => time()
  349. ];
  350. $map = [];
  351. foreach ($params as $key => $items){
  352. foreach ($items as $row){
  353. $salePrice[$row['customerId']][] = [
  354. "price" => $row['price'],
  355. "skuId" => $row['skuId'],
  356. "unitName" => getArrayItem($row,'unitName',''),
  357. "adjPricetag" => $row['adjPricetag']
  358. ];
  359. $map[$row['customerId']] = [
  360. "customerName" => getArrayItem($row,'customerName',''),
  361. "customerId" => getArrayItem($row,'customerId',0),
  362. "salePrice" => json_encode($salePrice[$row['customerId']])
  363. ];
  364. }
  365. }
  366. foreach ($map as &$value){
  367. $value = array_merge($value,$line);
  368. }
  369. return array_values($map);
  370. }
  371. /**
  372. * Doc: (des="")
  373. * User: XMing
  374. * Date: 2021/3/25
  375. * Time: 5:00 下午
  376. * @param array $params
  377. * @param array $common
  378. * @return array
  379. */
  380. private function buildCustomerTypePrice(array $params,array $common): array
  381. {
  382. if (empty($params)){
  383. return [];
  384. }
  385. $line = [
  386. "createUserName" => getArrayItem($common,'createUserName',''),
  387. "goodsName" => getArrayItem($common,'title',''),
  388. "goodsId" => getArrayItem($common,'goodsId',0),
  389. 'goodsCode' => createCode(StatusCode::$code['goodsBasic']['prefix'], $common['goodsId'], StatusCode::$code['goodsBasic']['length']),
  390. "shopId" => getArrayItem($common,'shopId',0),
  391. "shopName" => getArrayItem($common,'shopName',''),
  392. 'createTime' => time(),
  393. 'updateTime' => time()
  394. ];
  395. $map = [];
  396. foreach ($params as $key => $items){
  397. foreach ($items as $row){
  398. $salePrice[$row['customerType']][] = [
  399. "price" => $row['price'],
  400. "skuId" => $row['skuId'],
  401. "unitName" => getArrayItem($row,'unitName',''),
  402. "adjPricetag" => $row['adjPricetag']
  403. ];
  404. $map[$row['customerType']] = [
  405. "customerName" => getArrayItem($row,'customerName',''),
  406. "customerType" => getArrayItem($row,'customerType',0),
  407. "salePrice" => json_encode($salePrice[$row['customerType']])
  408. ];
  409. }
  410. }
  411. foreach ($map as &$value){
  412. $value = array_merge($value,$line);
  413. }
  414. return array_values($map);
  415. }
  416. /**
  417. * Doc: (des="")
  418. * User: XMing
  419. * Date: 2020/12/18
  420. * Time: 3:08 下午
  421. * @param $originArr
  422. * @param $val
  423. * @param string $field
  424. * @param bool $mul
  425. * @return void
  426. */
  427. private function pushVal(&$originArr, $val,$field = 'orderId', $mul = false)
  428. {
  429. if (empty($originArr)){
  430. return;
  431. }
  432. $map = [];
  433. foreach ($originArr as $key => &$item) {
  434. if ($mul === false) {
  435. $item[$field] = $val;
  436. continue;
  437. }
  438. foreach ($item as &$value) {
  439. $value[$field] = $val;
  440. $map[] = $value;
  441. }
  442. }
  443. $mul === true && $originArr = $map;
  444. $originArr = array_values($originArr);
  445. }
  446. /**
  447. * @param int $goodsId
  448. * @return ResultWrapper
  449. * @throws \Exception
  450. */
  451. public function getQuickGoodsInfo(int $goodsId)
  452. {
  453. $goodsResult = $this->objMGoods->getGoodsInfo($goodsId);
  454. if (!$goodsResult->isSuccess()){
  455. return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
  456. }
  457. $format = self::format($goodsResult->getData());
  458. $format = self::getSkuInventorySpec($format);
  459. return ResultWrapper::success($format);
  460. }
  461. /**
  462. * @param $data
  463. * @return mixed
  464. */
  465. public static function format($data)
  466. {
  467. if (empty($data)){
  468. return $data;
  469. }
  470. $data['description'] = $data['content'];
  471. $specMultiple = $data['specMultiple'];
  472. foreach ($specMultiple as &$spec){
  473. $spec['salePrice'] = [
  474. 'id' => $spec['id'],
  475. 'conversion' => $spec['conversion'],
  476. "unitName"=> $spec['unitName'],
  477. "unitId"=> $spec['unitId'],
  478. "isMaster"=> $spec['isMaster'],
  479. "deleteStatus"=> StatusCode::$delete,
  480. "enabledLadder"=> $spec['enabledLadder'],
  481. "salePriceAreaType"=> 1,
  482. "salePrice"=> $spec['salePrice'],
  483. "ladderPrice"=> $spec['ladderPrice'],
  484. "marketPrice"=> $spec['marketPrice'],
  485. "setNum"=> $spec['setNum']
  486. ];
  487. }
  488. $data['specMultiple'] = $specMultiple;
  489. return $data;
  490. }
  491. /**
  492. * @param $data
  493. * @return mixed
  494. */
  495. private function getSkuInventorySpec(array $data)
  496. {
  497. //查询物料库存
  498. $materielResult = $this->objMInventory->getInventoryByMaterielIds([$data['basicGoodsId']]);
  499. $materielMap = [];
  500. if (!$materielResult->isSuccess()){
  501. file_put_contents('/www/wwwroot/logs/api.junhailan.com/MQuickGoods_error.log', date('Y-m-d H:i:s') . '错误信息|sql错误 :' . var_export($materielResult->getData()) . PHP_EOL, FILE_APPEND);
  502. }else{
  503. $materielMap = $materielResult->getData();
  504. }
  505. if (!isset($materielMap[$data['basicGoodsId']])){
  506. //从来没有采购过
  507. $data['isEditSpec'] = StatusCode::$standard;
  508. }else{
  509. //采购过
  510. $data['isEditSpec'] = StatusCode::$delete;
  511. }
  512. return $data;
  513. }
  514. /**
  515. * @param array $params
  516. * @param int $goodsId
  517. * @param int $basicGoodsId
  518. * @return ResultWrapper
  519. * @throws \Exception
  520. */
  521. public function editQuickGoods(array $params,int $goodsId,int $basicGoodsId)
  522. {
  523. $goodsBasic = [
  524. 'title' => $params['title'],
  525. 'assistCategoryId' => $params['assistCategoryId'],
  526. 'assistCategoryPath' => $params['assistCategoryPath'],
  527. 'categoryId' => $params['categoryId'],
  528. 'categoryPath' => $params['categoryPath'],
  529. 'images' => $params['images'],
  530. 'specType' => $params['specType'],
  531. 'brandId' => $params['brandId'],
  532. 'description' => $params['description'],
  533. 'describe' => $params['describe'],
  534. 'expireTime' => $params['expireTime'],
  535. 'tag' => $params['tag'],
  536. 'barCode' => $params['barCode'],
  537. 'link' => $params['link'],
  538. 'noSalesShop' => $params['noSalesShop'],
  539. 'specGroup' => $params['specGroup'],
  540. 'extends' => $params['extends'],
  541. 'condition' => $params['condition'],
  542. 'isEq' => $params['isEq']
  543. ];
  544. //商品名称转换搜索条件
  545. if(isset($goodsBasic['title'])){
  546. $objChineseCharacter = new ChineseCharacter();
  547. $goodsBasic['condition'] = $objChineseCharacter->getInitials(trim($goodsBasic['title']));
  548. }
  549. $priceData = [];
  550. $customerPrices = [];//客户调价
  551. $customerTypePrices = [];//客户类型调价
  552. $this->objDGoodsBasic->beginTransaction();
  553. //1.编辑基础资料
  554. $updateResult = $this->objDGoodsBasic->update($goodsBasic,['id'=> $basicGoodsId]);
  555. if ($updateResult === false){
  556. $this->objDGoodsBasic->rollBack();
  557. return ResultWrapper::fail($this->objDGoodsBasic->error(),ErrorCode::$dberror);
  558. }
  559. //编辑sku
  560. $dbResult = self::commonMerge($params['specMultiple'],$basicGoodsId,$params['specType']);
  561. if (!$dbResult->isSuccess()) {
  562. $this->objDGoodsBasic->rollBack();
  563. return ResultWrapper::fail($dbResult->getData(), $dbResult->getErrorCode());
  564. }
  565. $groupData = $dbResult->getData();
  566. if (!empty($groupData['insert'])){
  567. $format = self::formatMapPriceAndSku($groupData['insert']);
  568. $skuResult = $this->objDSku->insert($format['sku'],true);
  569. if ($skuResult === false){
  570. $this->objDGoodsBasic->rollBack();
  571. return ResultWrapper::fail($this->objDSku->error(),ErrorCode::$dberror);
  572. }
  573. $this->updateSku = array_merge($this->updateSku,$skuResult);
  574. $skuResult = (array) $skuResult;
  575. foreach ($skuResult as $key => $id){
  576. if (!isset($format['salePrice'][$key])){
  577. continue;
  578. }
  579. $thisSalePrice = null;
  580. $thisSalePrice = $format['salePrice'][$key];
  581. $thisSalePrice['id'] = $id;
  582. $priceData = array_merge($priceData,[$thisSalePrice]);
  583. $thisCustomerPrice = null;
  584. $thisCustomerPrice = isset($specMultiple[$key]['customerPrice']) ? $specMultiple[$key]['customerPrice'] : [];
  585. if (!empty($thisCustomerPrice)){
  586. self::pushVal($thisCustomerPrice,$id,'skuId');
  587. $customerPrices[] = $thisCustomerPrice;
  588. }
  589. $thisCustomerTypePrice = null;
  590. $thisCustomerTypePrice = isset($specMultiple[$key]['customerTypePrice']) ? $specMultiple[$key]['customerTypePrice'] : [];
  591. if (!empty($thisCustomerTypePrice)){
  592. self::pushVal($thisCustomerTypePrice,$id,'skuId');
  593. $customerTypePrices[] = $thisCustomerTypePrice;
  594. }
  595. }
  596. }
  597. if (!empty($groupData['update'])){
  598. $format = self::formatMapPriceAndSku($groupData['update']);
  599. $priceData = array_merge($priceData,$format['salePrice']);//商品价格数据
  600. $customerPrices = array_merge($customerPrices, $format['customerPrice']);
  601. $customerTypePrices = array_merge($customerTypePrices, $format['customerTypePrice']);
  602. foreach ($format['sku'] as &$spec) {
  603. unset($spec['hash']);
  604. $skuResult = $this->objDSku->update($spec, ['id' => $spec['id']]);
  605. $this->updateSku = array_merge($this->updateSku,[$spec['id']]);
  606. }
  607. if ($skuResult === false) {
  608. $this->objDGoodsBasic->rollBack();
  609. return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
  610. }
  611. }
  612. if (!empty($groupData['delete'])){
  613. $format = self::formatMapPriceAndSku($groupData['delete']);
  614. $skuResult = $this->objDSku->update(
  615. [
  616. 'deleteStatus' => StatusCode::$delete
  617. ],
  618. [
  619. 'id' => array_column($format['sku'], 'id')
  620. ]);
  621. if ($skuResult === false) {
  622. $this->objDGoodsBasic->rollBack();
  623. return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
  624. }
  625. }
  626. //3.缓存基础资料
  627. $this->isUpdateBasicCache = true;
  628. $this->isUpdateSku = true;
  629. $this->objectId = $basicGoodsId;
  630. //4.更新es
  631. $this->objMGoodsBasic->updateEsData($basicGoodsId);
  632. //5.编辑商品
  633. $goods = [
  634. 'id' => $goodsId,
  635. 'basicGoodsId' => $basicGoodsId,
  636. 'goodsName' => $params['title'],
  637. 'shopId' => $params['shopId'],
  638. 'shopName' => $params['shopName'],//商铺名称
  639. 'images' => $params['images'],
  640. 'specType' => $params['specType'],//规格类型
  641. 'enableStatus' => $params['enableStatus'],
  642. 'priceData' => $priceData,
  643. 'createUserName' => $params['createUserName'],
  644. 'content' => $params['description'],
  645. 'isRecommend' => StatusCode::$standard,
  646. 'sort' => $params['sort'],
  647. 'deleteStatus'=> StatusCode::$standard,
  648. 'updateTime' => time(),
  649. 'isShield' => getArrayItem($params,'isShield',0),
  650. 'notArea' => getArrayItem($params,'notArea',''),
  651. 'notCustomerType' => getArrayItem($params,'notCustomerType',''),
  652. 'notCustomer' => getArrayItem($params,'notCustomer',''),
  653. 'isDistribution' => getArrayItem($params,'isDistribution',StatusCode::$delete)
  654. ];
  655. isset($params['deliverySupIds']) && $goods['deliverySupIds'] = $params['deliverySupIds'];
  656. isset($params['expressType']) && $goods['expressType'] = $params['expressType'];
  657. isset($params['ruleId']) && $goods['ruleId'] = $params['ruleId'];
  658. isset($params['expressFee']) && $goods['expressFee'] = $params['expressFee'];
  659. isset($params['showExpress']) && $goods['showExpress'] = $params['showExpress'];
  660. $goodsResult = $this->objMGoods->editGoods($goods);
  661. if (!$goodsResult->isSuccess()){
  662. $this->objDGoodsBasic->rollBack();
  663. return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
  664. }
  665. $params['goodsId'] = $goodsId;
  666. if (!empty($customerPrices)){
  667. //生成客户调价单
  668. $buildCustomerPrice = self::buildCustomerPrice($customerPrices,$params);
  669. $objMCustomerPriceAdjustment = new MCustomerPriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
  670. $adjustmentResult = $objMCustomerPriceAdjustment->add($buildCustomerPrice);
  671. if (!$adjustmentResult->isSuccess()){
  672. $this->objDGoodsBasic->rollBack();
  673. return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
  674. }
  675. $sheetIds = $adjustmentResult->getData();
  676. foreach ($sheetIds as $key => $id){
  677. $row = getArrayItem($buildCustomerPrice,$key,[]);
  678. $effectiveResult = $objMCustomerPriceAdjustment->effective($id,$row);
  679. if (!$effectiveResult->isSuccess()){
  680. $this->objDGoodsBasic->rollBack();
  681. return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
  682. }
  683. }
  684. }
  685. if (!empty($customerTypePrices)){
  686. //生成客户类型调价
  687. $buildCustomerTypePrice = self::buildCustomerTypePrice($customerTypePrices,$params);
  688. $objMCustomerTypePriceAdjustment = new MCustomerTypePriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
  689. $adjustmentResult = $objMCustomerTypePriceAdjustment->add($buildCustomerTypePrice);
  690. if (!$adjustmentResult->isSuccess()){
  691. $this->objDGoodsBasic->rollBack();
  692. return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
  693. }
  694. $sheetIds = $adjustmentResult->getData();
  695. foreach ($sheetIds as $key => $id){
  696. $row = getArrayItem($buildCustomerTypePrice,$key,[]);
  697. $effectiveResult = $objMCustomerTypePriceAdjustment->effective($id,$row);
  698. if (!$effectiveResult->isSuccess()){
  699. $this->objDGoodsBasic->rollBack();
  700. return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
  701. }
  702. }
  703. }
  704. $this->objDGoodsBasic->commit();
  705. $this->objMSku->delSkuCache($basicGoodsId);
  706. return ResultWrapper::success($goodsResult);
  707. }
  708. /**
  709. * @param $data
  710. * @return array
  711. */
  712. private static function formatMapPriceAndSku(array $data)
  713. {
  714. if (empty($data)){
  715. return [];
  716. }
  717. $map = [];
  718. $map['customerPrice'] = [];
  719. $map['customerTypePrice'] = [];
  720. foreach ($data as &$row){
  721. $map['salePrice'][] = $row['salePrice'];
  722. unset($row['salePrice']);
  723. if(isset($row['customerPrice'])){
  724. $map['customerPrice'][] = $row['customerPrice'];
  725. unset($row['customerPrice']);
  726. }
  727. if(isset($row['customerTypePrice'])){
  728. $map['customerTypePrice'][] = $row['customerTypePrice'];
  729. unset($row['customerTypePrice']);
  730. }
  731. $map['sku'][] = $row;
  732. }
  733. return $map;
  734. }
  735. /**
  736. * @param array $specMultiple
  737. * @param int $basicGoodsId
  738. * @return ResultWrapper
  739. */
  740. public function commonMerge(array $specMultiple, int $basicGoodsId,int $specType)
  741. {
  742. $isNewResult = $this->objMSku->getIsNewByGoodsId($basicGoodsId);
  743. if (!$isNewResult->isSuccess()){
  744. return ResultWrapper::fail($isNewResult->getData(),$isNewResult->getErrorCode());
  745. }
  746. $isNew = $isNewResult->getData();
  747. // 查询当前商品所有sku数据
  748. $skuResult = $this->objDSku->select(['goodsId'=>$basicGoodsId,'deleteStatus'=>StatusCode::$standard]);
  749. if ($skuResult === false) {
  750. return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
  751. }
  752. if (empty($skuResult)){
  753. return ResultWrapper::success([]);
  754. }
  755. //1.对旧数据生成hash
  756. $mapping = [];
  757. $allHash = [];
  758. foreach ($skuResult as &$value) {
  759. $hash = md5($value['goodsId'] . $value['unitId'] . $value['isMaster'] . $value['specGroupHash']);
  760. $value['hash'] = $hash;
  761. $mapping[$value['hash']] = $value;
  762. $allHash[] = $value['hash'];
  763. }
  764. //2.对现在数据生成hash
  765. $nowData = [];
  766. foreach ($specMultiple as $key => $spec){
  767. if (!empty($spec['specGroup'])){
  768. $specGroupIds = array_column($spec['specGroup'], 'specValueId');
  769. $specGroupHash = md5(implode('|', $specGroupIds));//属性hash值
  770. }else{
  771. $specGroupHash = '';
  772. }
  773. $hash = md5($basicGoodsId . $spec['unitId'] . $spec['isMaster'] . $specGroupHash);//对单行数据生成hash值
  774. $nowData[$key] = [
  775. 'goodsId' => $basicGoodsId,
  776. 'specData' => empty($spec['specGroup']) ? null : json_encode($spec['specGroup']),
  777. 'specImage' => empty($spec['specImage']) ? null : json_encode([$spec['specImage']]),
  778. 'specType' => $specType,
  779. 'unitId' => $spec['unitId'],
  780. 'isMaster' => $spec['isMaster'],
  781. 'unitName' => $spec['unitName'],
  782. 'conversion' => $spec['conversion'],
  783. 'specGroupHash' => $specGroupHash,
  784. 'hash' => $hash,
  785. 'barCode' => isset($spec['barCode']) ? $spec['barCode'] : '',
  786. 'isDefault' => isset($spec['isDefault']) ? $spec['isDefault'] : StatusCode::$delete,
  787. 'weight' => isset($spec['weight']) ? $spec['weight'] : 0,
  788. 'salePrice' => $spec['salePrice'],
  789. 'isNew' => $isNew
  790. ];//新的数据
  791. if(!empty($spec['customerPrice'])){
  792. $nowData[$key]['customerPrice'] = $spec['customerPrice'];
  793. }
  794. if(!empty($spec['customerTypePrice'])){
  795. $nowData[$key]['customerTypePrice'] = $spec['customerTypePrice'];
  796. }
  797. }
  798. unset($spec);
  799. //3.比对数据
  800. $insert = [];
  801. $update = [];
  802. $delete = [];
  803. foreach ($nowData as &$spec) {
  804. if (in_array($spec['hash'], $allHash)) {
  805. $spec['id'] = $mapping[$spec['hash']]['id'];
  806. $spec['salePrice']['id'] = $mapping[$spec['hash']]['id'];//价格信息+skuId
  807. if( isset($spec['customerPrice']) ){
  808. foreach ($spec['customerPrice'] as $key => $value){
  809. $spec['customerPrice'][$key]['skuId'] = $mapping[$spec['hash']]['id'];
  810. }
  811. }
  812. if( isset($spec['customerTypePrice']) ){
  813. foreach ($spec['customerTypePrice'] as $key => $value){
  814. $spec['customerTypePrice'][$key]['skuId'] = $mapping[$spec['hash']]['id'];
  815. }
  816. }
  817. $update[] = $spec;
  818. unset($mapping[$spec['hash']]);
  819. } else {
  820. unset($spec['hash']);
  821. $insert[] = $spec;
  822. }
  823. }
  824. return ResultWrapper::success([
  825. 'insert' => $insert,
  826. 'update' => $update,
  827. 'delete' => array_values($mapping),
  828. ]);
  829. }
  830. /**
  831. * @return ResultWrapper
  832. */
  833. public function getShopData()
  834. {
  835. $shopResult = $this->objMShop->getScopeShopInfo($this->onlineEnterpriseId,'id,name');
  836. if (!$shopResult->isSuccess()){
  837. return ResultWrapper::fail($shopResult->getData(),$shopResult->getErrorCode());
  838. }
  839. return ResultWrapper::success($shopResult->getData());
  840. }
  841. /**
  842. * @After
  843. * 缓存基础资料数据
  844. */
  845. public function __destruct()
  846. {
  847. // TODO: Implement __destruct() method.
  848. self::cacheBasic();
  849. self::cacheSku();
  850. }
  851. }