CopyProductService.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services;
  12. /**
  13. * 复制主流商城商品
  14. * Class CopyProductService
  15. * @package crmeb\services
  16. */
  17. class CopyProductService
  18. {
  19. //接口地址
  20. protected static $api = [
  21. 'taobao' => 'https://api03.6bqb.com/taobao/detail', //https://api03.6bqb.com/app/taobao/detail
  22. 'tmall' => 'https://api03.6bqb.com/tmall/detail',
  23. 'jd' => 'https://api03.6bqb.com/jd/detail',
  24. 'pdd' => 'https://api03.6bqb.com/pdd/detail',
  25. 'suning' => 'https://api03.6bqb.com/suning/detail',
  26. '1688' => 'https://api03.6bqb.com/alibaba/detail'
  27. ];
  28. protected static $apiKey = '';//996EF05B079F8706345938A0CD7339BB
  29. //商品默认字段
  30. protected static $productInfo = [
  31. 'cate_id' => '',
  32. 'store_name' => '',
  33. 'store_info' => '',
  34. 'unit_name' => '件',
  35. 'price' => 0,
  36. 'keyword' => '',
  37. 'ficti' => 0,
  38. 'ot_price' => 0,
  39. 'give_integral' => 0,
  40. 'postage' => 0,
  41. 'cost' => 0,
  42. 'image' => '',
  43. 'slider_image' => '',
  44. 'video_link' => '',
  45. 'add_time' => 0,
  46. 'stock' => 0,
  47. 'description' => '',
  48. 'description_images' => [],
  49. 'soure_link' => '',
  50. 'temp_id' => '',
  51. 'items' => [],
  52. 'attrs' => [],
  53. 'info' => [],
  54. ];
  55. /**
  56. * 整合
  57. * @param $url
  58. * @param $method
  59. * @param $data
  60. * @return string
  61. */
  62. public static function makeUrl(string $url, string $method, array $data)
  63. {
  64. $param = '';
  65. if (strtolower($method) == 'get' && $data) {
  66. foreach ($data as $key => $value) {
  67. $param .= '&' . $key . '=' . $value;
  68. }
  69. }
  70. return $url . '?apikey=' . self::$apiKey . $param;
  71. }
  72. /**
  73. * @param bool $status
  74. * @param string $msg
  75. * @param array $data
  76. */
  77. public static function setReturn(bool $status = true, string $msg = 'SUCCESS', array $data = [])
  78. {
  79. return ['status' => $status, 'msg' => $msg, 'data' => $data];
  80. }
  81. /**
  82. *
  83. * @param array $data
  84. */
  85. public static function getInfo(string $type = 'taobao', array $data = [], string $apikey = '')
  86. {
  87. if (!$apikey) {
  88. return self::setReturn(false, '请先去设置复制商品apiKey');
  89. }
  90. $url = self::$api[$type] ?? '';
  91. $type = $type == '1688' ? 'alibaba' : $type;
  92. $action = $type . 'Info';
  93. $deal_action = $type . 'Deal';
  94. $method = 'get';
  95. self::$apiKey = $apikey;
  96. if (!$data || !$url || !is_callable(self::class, $action) || !is_callable(self::class, $deal_action)) {
  97. return self::setReturn(false, '暂不支持该平台商品复制');
  98. }
  99. switch ($type) {
  100. case 'taobao':
  101. case 'tmall':
  102. case 'jd':
  103. case 'pdd':
  104. case 'alibaba':
  105. $method = 'get';
  106. if (!isset($data['itemid']) || !$data['itemid'])
  107. return self::setReturn(false, '缺少商品ID');
  108. break;
  109. case 'suning':
  110. $method = 'get';
  111. if (!isset($data['itemid']) || !$data['itemid'])
  112. return self::setReturn(false, '缺少商品ID');
  113. if (!isset($data['shopid']) || !$data['shopid'])
  114. return self::setReturn(false, '缺少商户ID');
  115. break;
  116. }
  117. $url = self::makeUrl($url, $method, $data);
  118. if ($cache_info = CacheService::get(md5($url))) {
  119. return self::setReturn(true, 'SUCCESS', $cache_info);
  120. }
  121. $info = self::$action($url, $data);
  122. if (!$info) return self::setReturn(false, '获取商品失败');
  123. $info = json_decode($info, true);
  124. if (!$info || (!in_array($info['retcode'], ['0000']))) {
  125. return self::setReturn(false, $info['message'] ?? '获取商品失败', $info);
  126. }
  127. $result = $info['data'];
  128. //可能存在下一页 但是api中没有分页参数 暂留
  129. // if (isset($info['hasNext']) && $info['hasNext']) {
  130. // $data['page'] = $info['page'] + 1;
  131. // }
  132. $result = self::$deal_action($result);
  133. //过滤采集到的规格 删除其中的空值
  134. if ($result['items']) {
  135. foreach ($result['items'] as $k => $item) {
  136. if (isset($item['value'])) {
  137. if ($item['value'] == '') unset($result['items'][$k]);
  138. if (!$item['detail'] || !isset($item['detail'][0]) || $item['detail'][0] == '') unset($result['items'][$k]);
  139. } else {
  140. unset($result['items'][$k]);
  141. }
  142. }
  143. }
  144. if (!$result['items']) {
  145. $result['items'] = [
  146. [
  147. 'value' => '默认',
  148. 'detail' => [
  149. '默认'
  150. ]
  151. ]
  152. ];
  153. }
  154. $result['info'] = self::formatAttr(array_values($result['items']));
  155. if (!$result['image'] && $result['slider_image'])
  156. $result['image'] = $result['slider_image'][0] ?? '';
  157. if ($result['description']) {
  158. $result['description'] = str_replace('data-lazyload', 'src', $result['description']);
  159. }
  160. CacheService::set(md5($url), $result, 3600 * 24);
  161. return self::setReturn(true, 'SUCCESS', $result);
  162. }
  163. /**
  164. * 获取淘宝商品
  165. * @param $url
  166. * @param $data
  167. * @param string $method
  168. * @return bool|string
  169. */
  170. public static function taobaoInfo(string $url, array $data, string $method = 'get')
  171. {
  172. $info = HttpService::request($url, $method, $data);
  173. $result = false;
  174. if ($info) {
  175. $result = $info;
  176. }
  177. return $result;
  178. }
  179. /**
  180. * 处理获取淘宝的商品
  181. * @param $data
  182. * @return mixed
  183. */
  184. public static function taobaoDeal(array $data)
  185. {
  186. $info = $data['item'] ?? [];
  187. $result = self::$productInfo;
  188. if ($info) {
  189. $result['store_name'] = $info['title'] ?? '';
  190. $result['store_info'] = $info['subTitle'] ?? '';
  191. $result['slider_image'] = $info['images'] ?? '';
  192. $result['description'] = $info['desc'] ?? '';
  193. $result['description_images'] = $info['descImgs'] ?? [];
  194. $items = [];
  195. if (isset($info['props']) && $info['props']) {
  196. foreach ($info['props'] as $key => $prop) {
  197. $item['value'] = $prop['name'];
  198. $item['detail'] = [];
  199. foreach ($prop['values'] as $name) {
  200. $item['detail'][] = $name['name'];
  201. }
  202. $items[] = $item;
  203. }
  204. }
  205. $result['items'] = $items;
  206. }
  207. return $result;
  208. }
  209. /**
  210. * 获取天猫商品
  211. * @param $url
  212. * @param $data
  213. * @param string $method
  214. * @return bool|string
  215. */
  216. public static function tmallInfo(string $url, array $data, string $method = 'get')
  217. {
  218. $info = HttpService::request($url, $method, $data);
  219. $result = false;
  220. if ($info) {
  221. $result = $info;
  222. }
  223. return $result;
  224. }
  225. /**
  226. * 处理天猫商品
  227. * @param $data
  228. * @return mixed
  229. */
  230. public static function tmallDeal(array $data)
  231. {
  232. $info = $data['item'] ?? [];
  233. $result = self::$productInfo;
  234. if ($info) {
  235. $result['store_name'] = $info['title'] ?? '';
  236. $result['store_info'] = $info['subTitle'] ?? '';
  237. $result['slider_image'] = self::lingByHttp($info['images'] ?? '');
  238. $result['description_images'] = self::lingByHttp($info['descImgs'] ?? []);
  239. $description = '';
  240. foreach ($result['description_images'] as $item) {
  241. $description .= '<img src="' . $item . '">';
  242. }
  243. unset($item);
  244. $result['description'] = $description;
  245. $items = [];
  246. if (isset($info['props']) && $info['props']) {
  247. foreach ($info['props'] as $key => $prop) {
  248. $item['value'] = $prop['name'];
  249. $item['detail'] = [];
  250. foreach ($prop['values'] as $name) {
  251. $item['detail'][] = $name['name'];
  252. }
  253. $items[] = $item;
  254. }
  255. }
  256. $result['items'] = $items;
  257. }
  258. return $result;
  259. }
  260. /**
  261. * 获取京东商品
  262. * @param $url
  263. * @param $data
  264. * @param string $method
  265. * @return bool|string
  266. */
  267. public static function jdInfo(string $url, array $data, string $method = 'get')
  268. {
  269. $info = HttpService::request($url, $method, $data);
  270. $result = false;
  271. if ($info) {
  272. $result = $info;
  273. }
  274. return $result;
  275. }
  276. /**
  277. * 处理京东商品
  278. * @param $data
  279. * @return mixed
  280. */
  281. public static function jdDeal(array $data)
  282. {
  283. $info = $data['item'] ?? [];
  284. $result = self::$productInfo;
  285. if ($info) {
  286. $result['store_name'] = $info['name'] ?? '';
  287. $result['store_info'] = $result['store_name'];
  288. $result['price'] = $info['price'] ?? 0;
  289. $result['ot_price'] = $info['originalPrice'] ?? 0;
  290. $result['slider_image'] = $info['images'] ?? [];
  291. $result['description'] = $info['desc'] ?? '';
  292. $result['description_images'] = $info['descImgs'] ?? [];
  293. $result['description_images'] = array_map(function ($item) {
  294. if (strstr($item, 'http') === false) {
  295. $item = 'http:' . $item;
  296. }
  297. return $item;
  298. }, $result['description_images']);
  299. if (strstr($result['description'], '<style>') !== false && strstr($result['description'], '<img') === false) {
  300. $content = '';
  301. foreach ($result['description_images'] as $item) {
  302. $content .= '<p><img src="' . $item . '"></p>';
  303. }
  304. $result['description'] = $content;
  305. }
  306. $items = [];
  307. if (isset($info['skuProps']) && $info['skuProps']) {
  308. foreach ($info['skuProps'] as $key => $prop) {
  309. $item = [];
  310. $item['value'] = $info['saleProp'][$key] ?? '';
  311. $item['detail'] = $prop;
  312. $items[] = $item;
  313. }
  314. }
  315. $result['items'] = $items;
  316. }
  317. return $result;
  318. }
  319. /**
  320. * @param $data
  321. * @return array|string
  322. */
  323. public static function lingByHttp($data)
  324. {
  325. if (is_array($data)) {
  326. foreach ($data as &$item) {
  327. if (strstr($item, 'http://') === false && strstr($item, 'https://') === false) {
  328. $item = 'http:' . $item;
  329. }
  330. }
  331. return $data;
  332. } else {
  333. if (strstr($data, 'http://') === false && strstr($data, 'https://') === false) {
  334. $data = 'http:' . $data;
  335. }
  336. return $data;
  337. }
  338. }
  339. /**
  340. * 获取拼多多商品
  341. * @param $url
  342. * @param $data
  343. * @param string $method
  344. * @return bool|string
  345. */
  346. public static function pddInfo(string $url, array $data, string $method = 'get')
  347. {
  348. $info = HttpService::request($url, $method, $data);
  349. $result = false;
  350. if ($info) {
  351. $result = $info;
  352. }
  353. return $result;
  354. }
  355. /**
  356. * 处理拼多多商品
  357. * @param $data
  358. * @return mixed
  359. */
  360. public static function pddDeal(array $data)
  361. {
  362. $info = $data['item'] ?? [];
  363. $result = self::$productInfo;
  364. if ($info) {
  365. $result['store_name'] = $info['goodsName'] ?? '';
  366. $result['store_info'] = $info['goodsDesc'] ?? '';
  367. $result['image'] = $info['thumbUrl'] ?? '';
  368. $result['slider_image'] = $info['banner'] ?? [];
  369. $image = [];
  370. foreach ($result['slider_image'] as &$item) {
  371. if (is_array($item) && isset($item['url'])) {
  372. $image[] = $item['url'];
  373. }
  374. }
  375. if ($image) {
  376. $result['slider_image'] = $image;
  377. }
  378. $result['video_link'] = $info['video']['videoUrl'] ?? '';
  379. $result['price'] = $info['maxNormalPrice'] ?? 0;
  380. $result['ot_price'] = $info['marketPrice'] ?? 0;
  381. $descImgs = [];
  382. if (isset($info['detail']) && $info['detail']) {
  383. foreach ($info['detail'] as $img) {
  384. if (isset($img['url']) && $img['url']) $descImgs[] = $img['url'];
  385. }
  386. }
  387. $result['description_images'] = $descImgs;
  388. $desc = '<p>';
  389. foreach ($descImgs as $item) {
  390. $desc .= '<img src="' . $item . '"/>';
  391. }
  392. $desc .= '</p>';
  393. $result['description'] = $desc;
  394. $items = [];
  395. if (isset($info['skus']) && $info['skus']) {
  396. $i = 0;
  397. foreach ($info['skus'] as $sku) {
  398. foreach ($sku['specs'] as $key => $spec) {
  399. if ($i == 0) $items[$key]['value'] = $spec['spec_key'];
  400. $items[$key]['detail'][] = $spec['spec_value'];
  401. }
  402. $i++;
  403. }
  404. }
  405. foreach ($items as $k => $item) {
  406. $items[$k]['detail'] = array_unique($item['detail']);
  407. }
  408. $result['items'] = $items;
  409. }
  410. return $result;
  411. }
  412. /**
  413. * 获取苏宁商品
  414. * @param $url
  415. * @param $data
  416. * @param string $method
  417. * @return bool|string
  418. */
  419. public static function suningInfo(string $url, array $data, string $method = 'get')
  420. {
  421. $info = HttpService::request($url, $method, $data);
  422. $result = false;
  423. if ($info) {
  424. $result = $info;
  425. }
  426. return $result;
  427. }
  428. /**
  429. *
  430. * @param string $url
  431. * @param array $data
  432. * @param string $method
  433. * @return bool|string
  434. */
  435. public static function alibabaInfo(string $url, array $data, string $method = 'get')
  436. {
  437. $info = HttpService::request($url, $method, $data);
  438. $result = false;
  439. if ($info) {
  440. $result = $info;
  441. }
  442. return $result;
  443. }
  444. /**
  445. * @param array $data
  446. * @return array
  447. */
  448. public static function alibabaDeal(array $data)
  449. {
  450. $result = self::$productInfo;
  451. if ($data) {
  452. $result['store_name'] = $data['title'] ?? '';
  453. $result['store_info'] = $result['store_name'];
  454. $result['slider_image'] = $data['images'] ?? [];
  455. $result['price'] = $data['price'] ?? 0;
  456. $result['description'] = $data['desc'] ?? '';
  457. $items = [];
  458. if (isset($data['skuProps']) && $data['skuProps']) {
  459. $i = 0;
  460. foreach ($data['skuProps'] as $passSUb) {
  461. $items[$i]['value'] = $passSUb['prop'];
  462. $items[$i]['detail'] = array_column($passSUb['value'], 'name');
  463. $i++;
  464. }
  465. }
  466. foreach ($items as $k => $item) {
  467. $items[$k]['detail'] = array_unique($item['detail']);
  468. }
  469. $result['items'] = $items;
  470. }
  471. return $result;
  472. }
  473. /**
  474. * 处理苏宁商品
  475. * @param $data
  476. * @return mixed
  477. */
  478. public static function suningDeal(array $data)
  479. {
  480. $result = self::$productInfo;
  481. if ($data) {
  482. $result['store_name'] = $data['title'] ?? '';
  483. $result['store_info'] = $result['store_name'];
  484. $result['slider_image'] = $data['images'] ?? [];
  485. $result['price'] = $data['price'] ?? 0;
  486. $result['description'] = $data['desc'] ?? '';
  487. $items = [];
  488. if (isset($data['passSubList']) && $data['passSubList']) {
  489. $i = 0;
  490. foreach ($data['passSubList'] as $passSUb) {
  491. $j = 0;
  492. foreach ($passSUb as $key => $sub) {
  493. if ($i == 0) $items[$j]['value'] = $key;
  494. foreach ($sub as $value) {
  495. if (isset($value['characterValueDisplayName']) && $value['characterValueDisplayName'])
  496. $items[$j]['detail'][] = $value['characterValueDisplayName'];
  497. }
  498. $j++;
  499. }
  500. $i++;
  501. }
  502. }
  503. foreach ($items as $k => $item) {
  504. $items[$k]['detail'] = array_unique($item['detail']);
  505. }
  506. $result['items'] = $items;
  507. }
  508. return $result;
  509. }
  510. /**
  511. * 格式化规格
  512. * @param $attr
  513. * @return array
  514. */
  515. public static function formatAttr(array $attr)
  516. {
  517. $value = attr_format($attr)[1];
  518. $valueNew = [];
  519. $count = 0;
  520. foreach ($value as $key => $item) {
  521. $detail = $item['detail'];
  522. // sort($item['detail'], SORT_STRING);
  523. $suk = implode(',', $item['detail']);
  524. $sukValue[$suk]['pic'] = '';
  525. $sukValue[$suk]['price'] = 0;
  526. $sukValue[$suk]['cost'] = 0;
  527. $sukValue[$suk]['ot_price'] = 0;
  528. $sukValue[$suk]['stock'] = 0;
  529. $sukValue[$suk]['bar_code'] = '';
  530. $sukValue[$suk]['weight'] = 0;
  531. $sukValue[$suk]['volume'] = 0;
  532. $sukValue[$suk]['brokerage'] = 0;
  533. $sukValue[$suk]['brokerage_two'] = 0;
  534. foreach (array_keys($detail) as $k => $title) {
  535. if ($title == '') continue;
  536. $header[$k]['title'] = $title;
  537. $header[$k]['align'] = 'center';
  538. $header[$k]['minWidth'] = 120;
  539. }
  540. foreach (array_values($detail) as $k => $v) {
  541. if ($v == '') continue;
  542. $valueNew[$count]['value' . ($k + 1)] = $v;
  543. $header[$k]['key'] = 'value' . ($k + 1);
  544. }
  545. $valueNew[$count]['detail'] = $detail;
  546. $valueNew[$count]['pic'] = $sukValue[$suk]['pic'] ?? '';
  547. $valueNew[$count]['price'] = $sukValue[$suk]['price'] ? floatval($sukValue[$suk]['price']) : 0;
  548. $valueNew[$count]['cost'] = $sukValue[$suk]['cost'] ? floatval($sukValue[$suk]['cost']) : 0;
  549. $valueNew[$count]['ot_price'] = isset($sukValue[$suk]['ot_price']) ? floatval($sukValue[$suk]['ot_price']) : 0;
  550. $valueNew[$count]['vip_price'] = isset($sukValue[$suk]['vip_price']) ? floatval($sukValue[$suk]['vip_price']) : 0;
  551. $valueNew[$count]['stock'] = $sukValue[$suk]['stock'] ? intval($sukValue[$suk]['stock']) : 0;
  552. $valueNew[$count]['bar_code'] = $sukValue[$suk]['bar_code'] ?? '';
  553. $valueNew[$count]['weight'] = $sukValue[$suk]['weight'] ? floatval($sukValue[$suk]['weight']) : 0;
  554. $valueNew[$count]['volume'] = $sukValue[$suk]['volume'] ? floatval($sukValue[$suk]['volume']) : 0;
  555. $valueNew[$count]['brokerage'] = $sukValue[$suk]['brokerage'] ? floatval($sukValue[$suk]['brokerage']) : 0;
  556. $valueNew[$count]['brokerage_two'] = $sukValue[$suk]['brokerage_two'] ? floatval($sukValue[$suk]['brokerage_two']) : 0;
  557. $count++;
  558. }
  559. $header[] = ['title' => '图片', 'slot' => 'pic', 'align' => 'center', 'minWidth' => 80];
  560. $header[] = ['title' => '售价', 'slot' => 'price', 'align' => 'center', 'minWidth' => 95];
  561. $header[] = ['title' => '成本价', 'slot' => 'cost', 'align' => 'center', 'minWidth' => 95];
  562. $header[] = ['title' => '原价', 'slot' => 'ot_price', 'align' => 'center', 'minWidth' => 95];
  563. $header[] = ['title' => '会员价', 'slot' => 'vip_price', 'align' => 'center', 'minWidth' => 140];
  564. $header[] = ['title' => '库存', 'slot' => 'stock', 'align' => 'center', 'minWidth' => 95];
  565. $header[] = ['title' => '商品编号', 'slot' => 'bar_code', 'align' => 'center', 'minWidth' => 120];
  566. $header[] = ['title' => '重量(KG)', 'slot' => 'weight', 'align' => 'center', 'minWidth' => 95];
  567. $header[] = ['title' => '体积(m³)', 'slot' => 'volume', 'align' => 'center', 'minWidth' => 95];
  568. $header[] = ['title' => '操作', 'slot' => 'action', 'align' => 'center', 'minWidth' => 70];
  569. $info = ['attr' => $attr, 'value' => $valueNew, 'header' => $header];
  570. return $info;
  571. }
  572. }