Take.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <?php
  2. namespace app\controller\api\douhuomall;
  3. use app\traits\GongApiRequest;
  4. use think\Exception;
  5. use think\facade\Db;
  6. use think\facade\Log;
  7. class Take
  8. {
  9. use GongApiRequest;
  10. /**
  11. * 同步 微唯宝 商品数据
  12. * @return string
  13. */
  14. public function get_goods_list()
  15. {
  16. try {
  17. // 1、不设置超时
  18. set_time_limit(0);
  19. // 2、循环拉取 商品 数据
  20. $allData = [];
  21. $page = 1;
  22. $limit = 100;
  23. $hasNextPage = true; // 是否有下一页的标志
  24. while ($hasNextPage) {
  25. $data = GongApiRequest::get_goods_list($page, $limit);
  26. if (!$data) {
  27. break; // 如果请求失败,停止循环
  28. }
  29. $allData = array_merge($allData, $data['list']); // 数据在list键下
  30. if (!count($data['list']) || count($data['list']) < $limit) {
  31. $hasNextPage = false; // 如果没有更多页面,停止循环
  32. } else {
  33. $page++; // 增加页码数
  34. }
  35. }
  36. // 3、获取 微唯宝 商品表 SPUId集合
  37. $goods_id_list = [];
  38. $spu_id_list = Db::name('douhuomall')->column('spu_id');
  39. // 4、
  40. // 同步到数据库
  41. foreach ($allData as $key => $value) {
  42. sleep(1);
  43. // if($key != 0) continue;
  44. // 4.1 获取商品详情
  45. $goodsInfo = GongApiRequest::get_goods_info($value['goods_id']);
  46. if (!$goodsInfo) continue;
  47. // 4.2 图片存放路径
  48. $targetDir = public_path() . 'images/gong/' . $value['goods_id'] . '/';
  49. // 4.3 清空路径下的文件
  50. $this->deleteFilesInDirectory($targetDir);
  51. // 4.4 获取图片地址 spuId_info商品详细信息处理
  52. $goodsInfo['cover_url'] = $this->seveImg($value['goods_id'], $goodsInfo['main_img'], $targetDir);
  53. $goodsInfo['spu_id'] = $goodsInfo['goods_id'];
  54. $goodsInfo['detail'] = "";
  55. $detail_img = $this->seveImg($value['goods_id'], $goodsInfo['detail_img'], $targetDir);
  56. foreach ($detail_img as $img_url) {
  57. $img_url = "<img src='" . $img_url . "' referrerpolicy='no-referrer' />";
  58. $goodsInfo['detail'] = $goodsInfo['detail'] . $img_url;
  59. }
  60. //sku信息处理
  61. $skuInfo = $goodsInfo['sku_list'];
  62. foreach ($skuInfo as $k => $v) {
  63. $skuInfo[$k]['img_url'] = $this->seveImg($value['goods_id'], $v['main_img'], $targetDir);//规格图片
  64. $skuInfo[$k]['cost_price'] = bcadd($v['plat_price'], bcmul($v['plat_price'], 0.03, 2), 2);//成本价格 原来进价的基础上加百分之3
  65. $skuInfo[$k]['market_price'] = bcadd($skuInfo[$k]['cost_price'], bcmul($skuInfo[$k]['cost_price'], 0.2, 2), 2);//销售价格 售价在成本价格的基础上加百分20
  66. $skuInfo[$k]['profit'] = bcdiv($skuInfo[$k]['market_price'], $skuInfo[$k]['cost_price'], 2);
  67. $skuInfo[$k]['mer_profit'] = bcsub($skuInfo[$k]['market_price'], $skuInfo[$k]['cost_price'], 2);
  68. $skuInfo[$k]['yanglaojin'] = '0.00';
  69. if (count($v['attr'])) {
  70. $skuInfo[$k]['attribute_json'] = $v['attr'];
  71. } else {
  72. $skuInfo[$k]['attribute_json'] = [['val' => '默认', 'name' => '默认']];
  73. }
  74. }
  75. unset($goodsInfo['sku_list']);
  76. $seveData = [
  77. 'spu_id' => $goodsInfo['spu_id'],
  78. 'skuId_info' => $skuInfo,
  79. 'sys_id' => '112',
  80. 'goods_id' => $goodsInfo['goods_id'],
  81. 'spuId_info' => $goodsInfo,
  82. 'sku_id' => $skuInfo[0]['sku_id'] ? $skuInfo[0]['sku_id'] : 0,
  83. 'status' => $goodsInfo['status'],
  84. 'cate_ids' => $goodsInfo['cate_ids'],
  85. 'title' => $goodsInfo['spu_name'],
  86. 'cxb_cate_id' => 0,
  87. ];
  88. // 4.5 保存商品信心到本地
  89. $this->add($seveData);
  90. $goods_id_list[] = $goodsInfo['spu_id'];
  91. // 4.6 如果上架到商品表 则更新商品表的图片
  92. $this->updata_product_img($goodsInfo['spu_id']);
  93. }
  94. // 5、将 未同步到的商品 进行下架
  95. sort($spu_id_list);
  96. sort($goods_id_list);
  97. $goodsIds = array_diff($spu_id_list, $goods_id_list);
  98. if (!empty($goodsIds)) {
  99. Db::name('log')->insert(['data' => '供应链拉取数据下架商品记录:' . json_encode(['spu_id_list' => $spu_id_list, 'goods_id_list' => $goods_id_list, 'goodsIds' => $goodsIds])]);
  100. $this->remove($goodsIds);
  101. }
  102. return 'sussess';
  103. } catch (Exception $e) {
  104. Log::error('供应链拉取数据:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】');
  105. echo '供应链拉取数据:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】';
  106. Db::name('log')->insert(['data' => '供应链拉取数据:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】']);
  107. return 'error';
  108. }
  109. }
  110. public function updata_product_img($spu_id)
  111. {
  112. // 1、验证该 SPUId 是否上架了 如果上架了 需要去更新商品 图片
  113. $product_id = Db::name('store_product')->where('spu_id', $spu_id)->value('product_id');
  114. if (!$product_id) return true;
  115. // 2、查找微唯宝 商品
  116. $data = Db::name('douhuomall')->where('spu_id', $spu_id)->find();
  117. // 3、获取 商品主图
  118. $spuId_info = json_decode($data['spuId_info'], true);
  119. $slider_image = $spuId_info['detail_img_list'] ?? '';
  120. $image = $spuId_info['cover_url'] ?? '';
  121. try {
  122. $slider_image = implode(',', json_decode($slider_image, true));
  123. } catch (\Exception $exception) {
  124. $slider_image = $image;
  125. }
  126. //更新产品图片数据
  127. $product_insert_data = [
  128. 'image' => $image,
  129. 'slider_image' => $slider_image,
  130. ];
  131. Db::name('store_product')->where('product_id', $product_id)->update($product_insert_data);
  132. echo '更新产品图片数据成功' . json_encode($product_insert_data);
  133. $detail = $spuId_info['detail'];
  134. if (!is_null(json_decode($detail))) {
  135. $detail_list = json_decode($detail);
  136. $detail = '';
  137. foreach ($detail_list as $value) {
  138. $detail .= "<img src='" . $value . "' referrerpolicy='no-referrer' /></img>";
  139. }
  140. }
  141. Db::name('store_product_content')->where('product_id', $product_id)->update(['content' => $detail]);
  142. return true;
  143. }
  144. public function seveImg($goods_id, $img_url, $targetDir)
  145. {
  146. return $img_url;
  147. if (!$img_url) return $img_url;
  148. if (is_array($img_url)) {
  149. $new_img_url = [];
  150. foreach ($img_url as $value) {
  151. $new_img_url[] = $this->seveImgUrl($goods_id, $value, $targetDir);
  152. }
  153. } else {
  154. $new_img_url = $this->seveImgUrl($goods_id, $img_url, $targetDir);
  155. }
  156. return $new_img_url;
  157. }
  158. public function seveImgUrl($goods_id, $remoteImageUrl, $targetDir)
  159. {
  160. // 目标路径(确保目录存在)
  161. $targetDirTow = rand(1000, 10000) . $this->upImgName(basename($remoteImageUrl));
  162. $targetPath = $targetDir . $targetDirTow; // 使用basename获取文件名
  163. // 检查目标目录是否存在,如果不存在则创建
  164. if (!is_dir($targetDir)) {
  165. mkdir($targetDir, 0777, true); // 第二个参数是权限,第三个参数是递归创建
  166. }
  167. ini_set("max_execution_time", 2);
  168. // 获取远程图片内容
  169. $imageContent = @file_get_contents($remoteImageUrl);
  170. // 检查是否成功获取内容
  171. if ($imageContent !== false) {
  172. // 保存图片到指定路径
  173. if (file_put_contents($targetPath, $imageContent)) {
  174. $new_img_url = env('APP_URL') . '/images/gong/' . $goods_id . '/' . $targetDirTow;
  175. return $new_img_url;
  176. } else {
  177. echo "保存图片时发生错误。";
  178. return $remoteImageUrl;
  179. }
  180. } else {
  181. echo "无法获取远程图片内容。";
  182. return $remoteImageUrl;
  183. }
  184. }
  185. public function upImgName($filename)
  186. {
  187. $position = strpos($filename, '?');
  188. if ($position !== false) {
  189. $filename = substr($filename, 0, $position);
  190. }
  191. return $filename;
  192. }
  193. public function deleteFilesInDirectory($dir)
  194. {
  195. if (!is_dir($dir)) return true;
  196. // 打开目录
  197. $files = scandir($dir);
  198. // 遍历目录中的所有文件
  199. foreach ($files as $file) {
  200. // 如果是文件(排除 . 和 ..)
  201. if ($file !== '.' && $file !== '..') {
  202. $filePath = $dir . '/' . $file;
  203. // 删除文件
  204. if (is_file($filePath)) {
  205. unlink($filePath);
  206. }
  207. }
  208. }
  209. return true;
  210. }
  211. public function add($data)
  212. {
  213. $findData = Db::name('douhuomall')->where('spu_id', $data['spu_id'])->find();
  214. try {
  215. $data['create_time'] = date('Y-m-d H:i:s');
  216. $data['update_time'] = date('Y-m-d H:i:s');
  217. $skuInfo = $this->arrSort($data['skuId_info'], 'cost_price', SORT_ASC);
  218. $data['cost_price'] = isset($skuInfo[0]['cost_price']) ? $skuInfo[0]['cost_price'] : 0;
  219. $data['market_price'] = isset($skuInfo[0]['market_price']) ? $skuInfo[0]['market_price'] : 0;
  220. $data['ot_price'] = isset($skuInfo[0]['retail_price']) ? $skuInfo[0]['retail_price'] : 0;
  221. $data['mer_profit'] = isset($skuInfo[0]['mer_profit']) ? $skuInfo[0]['mer_profit'] : 0;
  222. $data['pension'] = isset($skuInfo[0]['yanglaojin']) ? $skuInfo[0]['yanglaojin'] : 0;
  223. $data['profit'] = empty($data['cost_price']) || empty($data['market_price']) ? 0 : bcdiv($data['market_price'], $data['cost_price'], 2);
  224. if (empty($findData)) {
  225. $data['skuId_info'] = json_encode($data['skuId_info']);
  226. $data['spuId_info'] = json_encode($data['spuId_info']);
  227. Db::name('douhuomall')->insert($data);
  228. } else {
  229. // 如果货物 属于已被删除状态,并且新更新进来的状态 非删除状态,并且成本价、零售价、市场价、利润率没有变动的话,
  230. // if ($findData['status'] == 3
  231. // && $data['status'] !== 3
  232. // && $data['cost_price'] == $findData['cost_price']
  233. // && $data['ot_price'] == $findData['ot_price']
  234. // && $data['market_price'] == $findData['market_price']
  235. // && $data['profit'] == $findData['profit']) {
  236. // $count = Db::name('store_product')
  237. // ->where('spu_id', '=', $data['spu_id'])
  238. // ->where('is_show', '=', 0)
  239. // ->where('is_status', '=', 0)
  240. // ->count();
  241. // if ($count) {
  242. // Db::name('store_product')->where('spu_id', '=', $data['spu_id'])->update([
  243. // 'is_show' => 1
  244. // ]);
  245. // }
  246. // }
  247. Db::name('douhuomall')->where('spu_id', $findData['spu_id'])->update([
  248. 'status' => $data['status'],
  249. // 'create_time' => date('Y-m-d H:i:s'),
  250. 'update_time' => date('Y-m-d H:i:s'),
  251. 'cost_price' => $data['cost_price'],
  252. 'market_price' => $data['market_price'],
  253. 'ot_price' => $data['ot_price'],
  254. 'mer_profit' => $data['mer_profit'],
  255. 'pension' => $data['pension'],
  256. 'profit' => $data['profit'],
  257. 'skuId_info' => json_encode($data['skuId_info']),
  258. 'spuId_info' => json_encode($data['spuId_info']),
  259. 'title' => $data['title'],
  260. 'cate_ids' => $data['cate_ids'],
  261. 'cxb_cate_id' => $data['cxb_cate_id']
  262. ]);
  263. }
  264. return true;
  265. } catch (Exception $e) {
  266. echo '供应链产品添加:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】';
  267. return false;
  268. }
  269. }
  270. public function remove($goodsIds)
  271. {
  272. Db::startTrans();
  273. try {
  274. // 删除选品库对应的数据
  275. Db::name('douhuomall')->whereIn('spu_id', $goodsIds)->update([
  276. 'status' => 3,
  277. 'update_time' => date('Y-m-d H:i:s')
  278. ]);
  279. // 删除商品管理对应的数据
  280. Db::name('store_product')->whereIn('spu_id', $goodsIds)->update([
  281. // 'is_del' => 1,
  282. 'is_show' => 0
  283. ]);
  284. Db::commit();
  285. return true;
  286. } catch (Exception $e) {
  287. Db::rollback();
  288. Log::channel("gong")->error('供应链取消商品失败:' . $e->getMessage());
  289. return false;
  290. }
  291. }
  292. /**
  293. * 二维数组根据某个字段排序
  294. * @param array $array 要排序的数组
  295. * @param string $keys 要排序的键字段
  296. * @param string $sort 排序类型 SORT_ASC SORT_DESC
  297. * @return array 排序后的数组
  298. */
  299. function arrSort($array, $keys, $sort = SORT_DESC)
  300. {
  301. $keysValue = [];
  302. foreach ($array as $k => $v) {
  303. $keysValue[$k] = $v[$keys];
  304. }
  305. array_multisort($keysValue, $sort, $array);
  306. return $array;
  307. }
  308. }