CopyProductService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 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. use stdClass;
  13. use think\facade\Cache;
  14. /**
  15. * 复制主流商城商品
  16. * Class CopyProductService
  17. * @package crmeb\services
  18. */
  19. class CopyProductService
  20. {
  21. //接口地址
  22. protected static $api = [
  23. 'taobao' => 'https://api03.6bqb.com/taobao/detail', //https://api03.6bqb.com/app/taobao/detail
  24. 'tmall' => 'https://api03.6bqb.com/tmall/detail',
  25. 'jd' => 'https://api03.6bqb.com/jd/detail',
  26. 'pdd' => 'https://api03.6bqb.com/pdd/detail',
  27. 'suning' => 'https://api03.6bqb.com/suning/detail',
  28. 'alibaba' => 'https://api03.6bqb.com/alibaba/detail'
  29. ];
  30. protected static $apiKey = '';
  31. //商品默认字段
  32. protected static $productInfo = [
  33. 'cate_id' => '',
  34. 'store_name' => '',
  35. 'store_info' => '',
  36. 'unit_name' => '件',
  37. 'price' => 0,
  38. 'keyword' => '',
  39. 'ficti' => 0,
  40. 'ot_price' => 0,
  41. 'give_integral' => 0,
  42. 'postage' => 0,
  43. 'cost' => 0,
  44. 'image' => '',
  45. 'slider_image' => '',
  46. 'video_link' => '',
  47. 'add_time' => 0,
  48. 'stock' => 0,
  49. 'description' => '',
  50. 'description_images' => [],
  51. 'soure_link' => '',
  52. 'temp_id' => '',
  53. 'items' => [],
  54. 'attrs' => [],
  55. 'info' => [],
  56. ];
  57. /**
  58. * 整合
  59. * @param $url
  60. * @param $method
  61. * @param $data
  62. * @return string
  63. */
  64. public static function makeUrl(string $url, string $method, array $data)
  65. {
  66. $param = '';
  67. if (strtolower($method) == 'get' && $data) {
  68. foreach ($data as $key => $value) {
  69. $param .= '&' . $key . '=' . $value;
  70. }
  71. }
  72. return $url . '?apikey=' . self::$apiKey . $param;
  73. }
  74. /**
  75. * @param bool $status
  76. * @param string $msg
  77. * @param array $data
  78. */
  79. public static function setReturn(bool $status = true, string $msg = 'SUCCESS', array $data = [])
  80. {
  81. return ['status' => $status, 'msg' => $msg, 'data' => $data];
  82. }
  83. /**
  84. *
  85. * @param array $data
  86. */
  87. public static function getInfo(string $type = 'taobao', array $data = [], string $apikey = '')
  88. {
  89. if (!$apikey) {
  90. return self::setReturn(false, '请先去设置复制商品apiKey');
  91. }
  92. $url = self::$api[$type] ?? '';
  93. $action = $type . 'Info';
  94. $deal_action = $type . 'Deal';
  95. $method = 'get';
  96. self::$apiKey = $apikey;
  97. if (!$data || !$url || !is_callable(self::class, $action) || !is_callable(self::class, $deal_action)) {
  98. return self::setReturn(false, '暂不支持该平台商品复制');
  99. }
  100. switch ($type) {
  101. case 'taobao':
  102. case 'tmall':
  103. case 'jd':
  104. case 'pdd':
  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 = Cache::get(md5($url))) {
  119. return self::setReturn(true, 'SUCCESS', $cache_info);
  120. }
  121. /*
  122. * 测试 节省次数用
  123. */
  124. // if (!$info = Cache::get('info'.md5($url))) {
  125. // $info = self::$action($url, $data);
  126. // Cache::set('info'.md5($url),$info);
  127. // }
  128. $info = self::$action($url, $data);
  129. if (!$info) return self::setReturn(false, '获取商品失败');
  130. $info = json_decode($info, true);
  131. if (!$info || (!in_array($info['retcode'], ['0000']))) {
  132. return self::setReturn(false, $info['data'], $info);
  133. }
  134. $result = $info['data'];
  135. /*
  136. 可能存在下一页 但是api中没有分页参数 暂留
  137. */
  138. // if (isset($info['hasNext']) && $info['hasNext']) {
  139. // $data['page'] = $info['page'] + 1;
  140. // }
  141. $result = self::$deal_action($result);
  142. if ($result['items']) {
  143. foreach ($result['items'] as $k => $item) {
  144. if ($item['value'] == '') unset($result['items'][$k]);
  145. }
  146. $result['spec_type'] = 1;
  147. $attr = array_values($result['items']);
  148. $result['info'] = self::formatAttr($attr);
  149. } else {
  150. $result['spec_type'] = 0;
  151. $result['info'] = null;
  152. }
  153. if (!$result['image'] && $result['slider_image']) $result['image'] = $result['slider_image'][0] ?? '';
  154. if ($result['description']) {
  155. if (!empty($result['description_images'])) {
  156. $result['description'] = self::formatDescriptionImages($result['description_images']);
  157. }
  158. $result['description'] = str_replace('data-lazyload', 'src', $result['description']);
  159. $pattern = '/<img size=(.*?)>/';
  160. $replacement = '<img src="';
  161. $result['description'] = preg_replace($pattern, $replacement, $result['description']);
  162. $result['description'] = preg_replace('/<\/img>/', '">', $result['description']);
  163. }
  164. Cache::set(md5($url), $result, 3600 * 24);
  165. return self::setReturn(true, 'SUCCESS', $result);
  166. }
  167. /**
  168. * 获取淘宝商品
  169. * @param $url
  170. * @param $data
  171. * @param string $method
  172. * @return bool|string
  173. */
  174. public static function taobaoInfo(string $url, array $data, string $method = 'get')
  175. {
  176. $info = HttpService::request($url, $method, $data);
  177. $result = false;
  178. if ($info) {
  179. $result = $info;
  180. }
  181. return $result;
  182. }
  183. /**
  184. * 处理获取淘宝的商品
  185. * @param $data
  186. * @return mixed
  187. */
  188. public static function taobaoDeal(array $data)
  189. {
  190. $info = $data['item'] ?? [];
  191. $result = self::$productInfo;
  192. if ($info) {
  193. $result['store_name'] = $info['title'] ?? '';
  194. $result['store_info'] = $info['subTitle'] ?? '';
  195. $result['slider_image'] = $info['images'] ?? '';
  196. $result['description'] = $info['desc'] ?? '';
  197. $result['description_images'] = $info['descImgs'] ?? [];
  198. $items = [];
  199. if (isset($info['props']) && $info['props']) {
  200. foreach ($info['props'] as $key => $prop) {
  201. $item['value'] = $prop['name'];
  202. $item['detail'] = [];
  203. foreach ($prop['values'] as $name) {
  204. $item['detail'][] = $name['name'];
  205. }
  206. $items[] = $item;
  207. }
  208. }
  209. $result['items'] = $items;
  210. }
  211. return $result;
  212. }
  213. /**
  214. * 获取天猫商品
  215. * @param $url
  216. * @param $data
  217. * @param string $method
  218. * @return bool|string
  219. */
  220. public static function tmallInfo(string $url, array $data, string $method = 'get')
  221. {
  222. $info = HttpService::request($url, $method, $data);
  223. $result = false;
  224. if ($info) {
  225. $result = $info;
  226. }
  227. return $result;
  228. }
  229. /**
  230. * 处理天猫商品
  231. * @param $data
  232. * @return mixed
  233. */
  234. public static function tmallDeal(array $data)
  235. {
  236. $info = $data['item'] ?? [];
  237. $result = self::$productInfo;
  238. if ($info) {
  239. $result['store_name'] = $info['title'] ?? '';
  240. $result['store_info'] = $info['subTitle'] ?? '';
  241. $result['slider_image'] = $info['images'] ?? '';
  242. $result['description'] = $info['desc'] ?? '';
  243. $result['description_images'] = $info['descImgs'] ?? [];
  244. $items = [];
  245. if (isset($info['props']) && $info['props']) {
  246. foreach ($info['props'] as $key => $prop) {
  247. $item['value'] = $prop['name'];
  248. $item['detail'] = [];
  249. foreach ($prop['values'] as $name) {
  250. $item['detail'][] = $name['name'];
  251. }
  252. $items[] = $item;
  253. }
  254. }
  255. $result['items'] = $items;
  256. }
  257. return $result;
  258. }
  259. /**
  260. * 获取京东商品
  261. * @param $url
  262. * @param $data
  263. * @param string $method
  264. * @return bool|string
  265. */
  266. public static function jdInfo(string $url, array $data, string $method = 'get')
  267. {
  268. $info = HttpService::request($url, $method, $data);
  269. $result = false;
  270. if ($info) {
  271. $result = $info;
  272. }
  273. return $result;
  274. }
  275. /**
  276. * 处理京东商品
  277. * @param $data
  278. * @return mixed
  279. */
  280. public static function jdDeal(array $data)
  281. {
  282. $info = $data['item'] ?? [];
  283. $result = self::$productInfo;
  284. if ($info) {
  285. $result['store_name'] = $info['name'] ?? '';
  286. $result['store_info'] = $result['store_name'];
  287. $result['price'] = $info['price'] ?? 0;
  288. $result['ot_price'] = $info['originalPrice'] ?? 0;
  289. $result['slider_image'] = $info['images'] ?? [];
  290. $result['description'] = $info['desc'] ?? '';
  291. $result['description_images'] = $info['descImgs'] ?? [];
  292. $items = [];
  293. if (isset($info['skuProps']) && $info['skuProps']) {
  294. foreach ($info['skuProps'] as $key => $prop) {
  295. $item['value'] = $info['saleProp'][$key] ?? '';
  296. $item['detail'] = $prop;
  297. $items[] = $item;
  298. }
  299. }
  300. $result['items'] = $items;
  301. }
  302. return $result;
  303. }
  304. /**
  305. * 获取拼多多商品
  306. * @param $url
  307. * @param $data
  308. * @param string $method
  309. * @return bool|string
  310. */
  311. public static function pddInfo(string $url, array $data, string $method = 'get')
  312. {
  313. $info = HttpService::request($url, $method, $data);
  314. $result = false;
  315. if ($info) {
  316. $result = $info;
  317. }
  318. return $result;
  319. }
  320. /**
  321. * 处理拼多多商品
  322. * @param $data
  323. * @return mixed
  324. */
  325. public static function pddDeal(array $data)
  326. {
  327. $info = $data['item'] ?? [];
  328. $result = self::$productInfo;
  329. if ($info) {
  330. $result['store_name'] = $info['goodsName'] ?? '';
  331. $result['store_info'] = $info['goodsDesc'] ?? '';
  332. $result['image'] = $info['thumbUrl'] ?? '';
  333. $result['slider_image'] = $info['banner'] ?? [];
  334. $result['video_link'] = $info['video']['videoUrl'] ?? '';
  335. $result['price'] = $info['maxNormalPrice'] ?? 0;
  336. $result['ot_price'] = $info['marketPrice'] ?? 0;
  337. $descImgs = [];
  338. if (isset($info['detail']) && $info['detail']) {
  339. foreach ($info['detail'] as $img) {
  340. if (isset($img['url']) && $img['url']) $descImgs[] = $img['url'];
  341. }
  342. }
  343. $result['description_images'] = $descImgs;
  344. $items = [];
  345. if (isset($info['skus']) && $info['skus']) {
  346. $i = $y = 0;
  347. foreach ($info['skus'] as $sku) {
  348. foreach ($sku['specs'] as $key => $spec) {
  349. if ($i == 0) $items[$y]['value'] = $spec['spec_key'];
  350. $items[$y]['detail'][] = $spec['spec_value'];
  351. $y++;
  352. }
  353. $i++;
  354. }
  355. }
  356. foreach ($items as $k => $item) {
  357. $items[$k]['detail'] = array_unique($item['detail']);
  358. }
  359. $result['items'] = $items;
  360. }
  361. return $result;
  362. }
  363. /**
  364. * 获取苏宁商品
  365. * @param $url
  366. * @param $data
  367. * @param string $method
  368. * @return bool|string
  369. */
  370. public static function suningInfo(string $url, array $data, string $method = 'get')
  371. {
  372. $info = HttpService::request($url, $method, $data);
  373. $result = false;
  374. if ($info) {
  375. $result = $info;
  376. }
  377. return $result;
  378. }
  379. /**
  380. * 处理苏宁商品
  381. * @param $data
  382. * @return mixed
  383. */
  384. public static function suningDeal(array $data)
  385. {
  386. $result = self::$productInfo;
  387. if ($data) {
  388. $result['store_name'] = $data['title'] ?? '';
  389. $result['store_info'] = $result['store_name'];
  390. $result['slider_image'] = $data['images'] ?? [];
  391. $result['price'] = $data['price'] ?? 0;
  392. $result['desc'] = $data['desc'] ?? '';
  393. $items = [];
  394. if (isset($data['passSubList']) && $data['passSubList']) {
  395. $i = 0;
  396. foreach ($data['passSubList'] as $passSUb) {
  397. $j = 0;
  398. foreach ($passSUb as $key => $sub) {
  399. if ($i == 0) $items[$j]['value'] = $key;
  400. foreach ($sub as $value) {
  401. if (isset($value['characterValueDisplayName']) && $value['characterValueDisplayName'])
  402. $items[$j]['detail'][] = $value['characterValueDisplayName'];
  403. }
  404. $j++;
  405. }
  406. $i++;
  407. }
  408. }
  409. foreach ($items as $k => $item) {
  410. $items[$k]['detail'] = array_unique($item['detail']);
  411. }
  412. $result['items'] = $items;
  413. }
  414. return $result;
  415. }
  416. /**
  417. *
  418. * @param string $url
  419. * @param array $data
  420. * @param string $method
  421. * @return bool|string
  422. */
  423. public static function alibabaInfo(string $url, array $data, string $method = 'get')
  424. {
  425. $info = HttpService::request($url, $method, $data);
  426. $result = false;
  427. if ($info) {
  428. $result = $info;
  429. }
  430. return $result;
  431. }
  432. /**
  433. * @param array $data
  434. * @return array
  435. */
  436. public static function alibabaDeal(array $data)
  437. {
  438. $result = self::$productInfo;
  439. if ($data) {
  440. $result['store_name'] = $data['title'] ?? '';
  441. $result['store_info'] = $result['store_name'];
  442. $result['slider_image'] = $data['images'] ?? [];
  443. $result['price'] = $data['price'] ?? 0;
  444. $result['description'] = $data['desc'] ?? '';
  445. $items = [];
  446. if (isset($data['skuProps']) && $data['skuProps']) {
  447. $i = 0;
  448. foreach ($data['skuProps'] as $passSUb) {
  449. $items[$i]['value'] = $passSUb['prop'];
  450. $items[$i]['detail'] = array_column($passSUb['value'], 'name');
  451. $i++;
  452. }
  453. }
  454. foreach ($items as $k => $item) {
  455. $items[$k]['detail'] = array_unique($item['detail']);
  456. }
  457. $result['items'] = $items;
  458. }
  459. return $result;
  460. }
  461. /**
  462. * 格式化规格
  463. * @param $attr
  464. * @return array
  465. */
  466. public static function formatAttr(array $attr)
  467. {
  468. [$attr,$head] = attr_format($attr);
  469. $valueNew = [];
  470. $count = 0;
  471. foreach ($attr as $suk) {
  472. $detail = explode(',',$suk);
  473. foreach ($detail as $k => $v) {
  474. $valueNew[$count]['value' . ($k + 1)] = $v;
  475. }
  476. $valueNew[$count]['detail'] = array_combine($head, $detail);
  477. $valueNew[$count]['image'] = '';
  478. $valueNew[$count]['price'] = 0;
  479. $valueNew[$count]['cost'] = 0;
  480. $valueNew[$count]['ot_price'] = 0;
  481. $valueNew[$count]['stock'] = 0;
  482. $valueNew[$count]['bar_code'] = '';
  483. $valueNew[$count]['weight'] = 0;
  484. $valueNew[$count]['volume'] = 0;
  485. $valueNew[$count]['brokerage'] = 0;
  486. $valueNew[$count]['brokerage_two'] = 0;
  487. $count++;
  488. }
  489. $info = ['attr' => $attr, 'value' => $valueNew];
  490. return $info;
  491. }
  492. /**
  493. * 提还详情数据
  494. * @param array $description_images 详情图片
  495. * @return string
  496. *
  497. * @date 2023/08/31
  498. * @author yyw
  499. */
  500. public static function formatDescriptionImages(array $description_images)
  501. {
  502. $content = '';
  503. foreach ($description_images as $image) {
  504. if (strstr($image, 'http') === false) {
  505. $image = 'http:' . $image;
  506. }
  507. $content .= '<p><img src="' . $image . '"></p>';
  508. }
  509. return $content;
  510. }
  511. }