|
|
@@ -2,8 +2,7 @@
|
|
2
|
2
|
/**
|
|
3
|
3
|
* 1688分销严选采购解决方案 - 商品服务类
|
|
4
|
4
|
*
|
|
5
|
|
- * 提供商品搜索/列表查询功能
|
|
6
|
|
- * API文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.fenxiao%3Ajxhy.product.getPageList-1&aopApiCategory=category_new
|
|
|
5
|
+ * 提供商品搜索/列表查询、详情获取、批量入库等功能
|
|
7
|
6
|
*
|
|
8
|
7
|
* @author: yourname
|
|
9
|
8
|
* @day: 2026/04/27
|
|
|
@@ -11,6 +10,9 @@
|
|
11
|
10
|
|
|
12
|
11
|
namespace app\services\ThirdParty\AlibabaAgent;
|
|
13
|
12
|
|
|
|
13
|
+use think\facade\Db;
|
|
|
14
|
+use think\facade\Log;
|
|
|
15
|
+
|
|
14
|
16
|
class ProductService extends AlibabaAgentBaseService
|
|
15
|
17
|
{
|
|
16
|
18
|
/**
|
|
|
@@ -25,33 +27,20 @@ class ProductService extends AlibabaAgentBaseService
|
|
25
|
27
|
{
|
|
26
|
28
|
$businessParams = [];
|
|
27
|
29
|
|
|
28
|
|
- // 关键词搜索
|
|
29
|
30
|
if (!empty($params['keyword'])) {
|
|
30
|
31
|
$businessParams['keyword'] = $params['keyword'];
|
|
31
|
32
|
}
|
|
32
|
|
-
|
|
33
|
|
- // 类目ID
|
|
34
|
33
|
if (!empty($params['categoryId'])) {
|
|
35
|
34
|
$businessParams['categoryId'] = $params['categoryId'];
|
|
36
|
35
|
}
|
|
37
|
|
-
|
|
38
|
|
- // 页码,默认1
|
|
39
|
36
|
$businessParams['pageNo'] = $params['page'] ?? 1;
|
|
40
|
|
-
|
|
41
|
|
- // 每页条数,最大50
|
|
42
|
37
|
$businessParams['pageSize'] = min($params['limit'] ?? 20, 50);
|
|
43
|
|
-
|
|
44
|
|
- // 排序方式
|
|
45
|
38
|
if (!empty($params['sort'])) {
|
|
46
|
39
|
$businessParams['sort'] = $params['sort'];
|
|
47
|
40
|
}
|
|
48
|
|
-
|
|
49
|
|
- // 最低价格过滤(仅当 > 0 时传入)
|
|
50
|
41
|
if (!empty($params['minPrice']) && $params['minPrice'] > 0) {
|
|
51
|
42
|
$businessParams['priceStart'] = $params['minPrice'];
|
|
52
|
43
|
}
|
|
53
|
|
-
|
|
54
|
|
- // 最高价格过滤(仅当 > 0 时传入)
|
|
55
|
44
|
if (!empty($params['maxPrice']) && $params['maxPrice'] > 0) {
|
|
56
|
45
|
$businessParams['priceEnd'] = $params['maxPrice'];
|
|
57
|
46
|
}
|
|
|
@@ -79,30 +68,16 @@ class ProductService extends AlibabaAgentBaseService
|
|
79
|
68
|
protected function formatSearchResult(array $result): array
|
|
80
|
69
|
{
|
|
81
|
70
|
$productList = [];
|
|
82
|
|
-
|
|
83
|
|
- // 1688 API返回结构:
|
|
84
|
|
- // {
|
|
85
|
|
- // "result": {
|
|
86
|
|
- // "success": true,
|
|
87
|
|
- // "code": "0",
|
|
88
|
|
- // "result": [ {商品1}, {商品2}, ... ], // 商品列表
|
|
89
|
|
- // "pageInfo": {
|
|
90
|
|
- // "currentPage": 1,
|
|
91
|
|
- // "totalRecords": 2000,
|
|
92
|
|
- // "pageSize": 10
|
|
93
|
|
- // }
|
|
94
|
|
- // }
|
|
95
|
|
- // }
|
|
96
|
71
|
$data = $result['result'] ?? $result;
|
|
97
|
|
- $products = $data['result'] ?? []; // 商品列表在 result.result 中
|
|
|
72
|
+ $products = $data['result'] ?? [];
|
|
98
|
73
|
$pageInfo = $data['pageInfo'] ?? [];
|
|
99
|
74
|
|
|
100
|
75
|
if (empty($products)) {
|
|
101
|
76
|
return [
|
|
102
|
|
- 'total' => 0,
|
|
103
|
|
- 'page' => (int)($pageInfo['currentPage'] ?? 1),
|
|
|
77
|
+ 'total' => 0,
|
|
|
78
|
+ 'page' => (int)($pageInfo['currentPage'] ?? 1),
|
|
104
|
79
|
'pageSize' => (int)($pageInfo['pageSize'] ?? 20),
|
|
105
|
|
- 'list' => [],
|
|
|
80
|
+ 'list' => [],
|
|
106
|
81
|
];
|
|
107
|
82
|
}
|
|
108
|
83
|
|
|
|
@@ -111,10 +86,10 @@ class ProductService extends AlibabaAgentBaseService
|
|
111
|
86
|
}
|
|
112
|
87
|
|
|
113
|
88
|
return [
|
|
114
|
|
- 'total' => (int)($pageInfo['totalRecords'] ?? count($productList)),
|
|
115
|
|
- 'page' => (int)($pageInfo['currentPage'] ?? 1),
|
|
|
89
|
+ 'total' => (int)($pageInfo['totalRecords'] ?? count($productList)),
|
|
|
90
|
+ 'page' => (int)($pageInfo['currentPage'] ?? 1),
|
|
116
|
91
|
'pageSize' => (int)($pageInfo['pageSize'] ?? 20),
|
|
117
|
|
- 'list' => $productList,
|
|
|
92
|
+ 'list' => $productList,
|
|
118
|
93
|
];
|
|
119
|
94
|
}
|
|
120
|
95
|
|
|
|
@@ -126,13 +101,8 @@ class ProductService extends AlibabaAgentBaseService
|
|
126
|
101
|
*/
|
|
127
|
102
|
public function formatProduct(array $product): array
|
|
128
|
103
|
{
|
|
129
|
|
- // 1688分销商品列表API返回字段:
|
|
130
|
|
- // itemId, title, imgUrl, minPrice, maxPrice, salesCnt90d, skuCnt, serviceList
|
|
131
|
|
-
|
|
132
|
|
- // 主图
|
|
133
|
104
|
$mainImage = $product['imgUrl'] ?? $product['mainImage'] ?? $product['mainPicture'] ?? '';
|
|
134
|
105
|
|
|
135
|
|
- // 服务标签
|
|
136
|
106
|
$serviceTags = [];
|
|
137
|
107
|
if (!empty($product['serviceList'])) {
|
|
138
|
108
|
foreach ($product['serviceList'] as $service) {
|
|
|
@@ -141,62 +111,44 @@ class ProductService extends AlibabaAgentBaseService
|
|
141
|
111
|
}
|
|
142
|
112
|
|
|
143
|
113
|
return [
|
|
144
|
|
- // 基础信息
|
|
145
|
|
- 'productId' => $product['itemId'] ?? $product['productId'] ?? $product['offerId'] ?? $product['id'] ?? 0,
|
|
146
|
|
- 'productType' => $product['productType'] ?? '',
|
|
147
|
|
- 'categoryId' => $product['categoryId'] ?? $product['catId'] ?? 0,
|
|
148
|
|
- 'categoryName' => $product['categoryName'] ?? '',
|
|
149
|
|
-
|
|
150
|
|
- // 标题与描述
|
|
151
|
|
- 'title' => $product['title'] ?? $product['subject'] ?? $product['name'] ?? '',
|
|
152
|
|
- 'description' => $product['description'] ?? $product['detail'] ?? '',
|
|
153
|
|
-
|
|
154
|
|
- // 价格信息
|
|
155
|
|
- 'price' => $product['minPrice'] ?? $product['price'] ?? $product['offerPrice'] ?? 0,
|
|
156
|
|
- 'salePrice' => $product['maxPrice'] ?? $product['salePrice'] ?? $product['price'] ?? 0,
|
|
157
|
|
- 'minPrice' => $product['minPrice'] ?? $product['price'] ?? 0,
|
|
158
|
|
- 'maxPrice' => $product['maxPrice'] ?? $product['price'] ?? 0,
|
|
159
|
|
-
|
|
160
|
|
- // 库存信息(该接口不返回库存,用skuCnt作为参考)
|
|
161
|
|
- 'stock' => $product['stock'] ?? $product['totalAvailableStock'] ?? 0,
|
|
162
|
|
- 'unit' => $product['unit'] ?? '件',
|
|
163
|
|
-
|
|
164
|
|
- // 图片信息
|
|
165
|
|
- 'mainImage' => $mainImage,
|
|
166
|
|
- 'imageList' => [$mainImage],
|
|
167
|
|
-
|
|
168
|
|
- // SKU数量
|
|
169
|
|
- 'skuCnt' => $product['skuCnt'] ?? 0,
|
|
170
|
|
-
|
|
171
|
|
- // 销售信息
|
|
172
|
|
- 'monthSales' => $product['monthSales'] ?? $product['salesCnt90d'] ?? 0,
|
|
173
|
|
- 'totalSales' => $product['totalSales'] ?? 0,
|
|
174
|
|
-
|
|
175
|
|
- // 服务标签
|
|
176
|
|
- 'serviceTags' => $serviceTags,
|
|
177
|
|
-
|
|
178
|
|
- // 分销属性
|
|
179
|
|
- 'isDistribution' => $product['isDistribution'] ?? false,
|
|
|
114
|
+ 'productId' => $product['itemId'] ?? $product['productId'] ?? $product['offerId'] ?? $product['id'] ?? 0,
|
|
|
115
|
+ 'productType' => $product['productType'] ?? '',
|
|
|
116
|
+ 'categoryId' => $product['categoryId'] ?? $product['catId'] ?? 0,
|
|
|
117
|
+ 'categoryName' => $product['categoryName'] ?? '',
|
|
|
118
|
+ 'title' => $product['title'] ?? $product['subject'] ?? $product['name'] ?? '',
|
|
|
119
|
+ 'description' => $product['description'] ?? $product['detail'] ?? '',
|
|
|
120
|
+ 'price' => $product['minPrice'] ?? $product['price'] ?? $product['offerPrice'] ?? 0,
|
|
|
121
|
+ 'salePrice' => $product['maxPrice'] ?? $product['salePrice'] ?? $product['price'] ?? 0,
|
|
|
122
|
+ 'minPrice' => $product['minPrice'] ?? $product['price'] ?? 0,
|
|
|
123
|
+ 'maxPrice' => $product['maxPrice'] ?? $product['price'] ?? 0,
|
|
|
124
|
+ 'stock' => $product['stock'] ?? $product['totalAvailableStock'] ?? 0,
|
|
|
125
|
+ 'unit' => $product['unit'] ?? '件',
|
|
|
126
|
+ 'mainImage' => $mainImage,
|
|
|
127
|
+ 'imageList' => [$mainImage],
|
|
|
128
|
+ 'skuCnt' => $product['skuCnt'] ?? 0,
|
|
|
129
|
+ 'monthSales' => $product['monthSales'] ?? $product['salesCnt90d'] ?? 0,
|
|
|
130
|
+ 'totalSales' => $product['totalSales'] ?? 0,
|
|
|
131
|
+ 'serviceTags' => $serviceTags,
|
|
|
132
|
+ 'isDistribution' => $product['isDistribution'] ?? false,
|
|
180
|
133
|
'isStrictSelected' => $product['isStrictSelected'] ?? false,
|
|
181
|
134
|
'distributorPrice' => $product['distributorPrice'] ?? 0,
|
|
182
|
|
-
|
|
183
|
|
- // 店铺信息(该接口不返回店铺信息)
|
|
184
|
|
- 'shopName' => $product['shopName'] ?? $product['companyName'] ?? '',
|
|
185
|
|
- 'shopId' => $product['shopId'] ?? $product['memberId'] ?? '',
|
|
186
|
|
-
|
|
187
|
|
- // 链接
|
|
188
|
|
- 'detailUrl' => $product['detailUrl'] ?? $product['offerUrl'] ?? '',
|
|
|
135
|
+ 'shopName' => $product['shopName'] ?? $product['companyName'] ?? '',
|
|
|
136
|
+ 'shopId' => $product['shopId'] ?? $product['memberId'] ?? '',
|
|
|
137
|
+ 'detailUrl' => $product['detailUrl'] ?? $product['offerUrl'] ?? '',
|
|
189
|
138
|
];
|
|
190
|
139
|
}
|
|
191
|
140
|
|
|
|
141
|
+ // ================================================================
|
|
|
142
|
+ // 商品详情
|
|
|
143
|
+ // ================================================================
|
|
|
144
|
+
|
|
192
|
145
|
/**
|
|
193
|
146
|
* 获取分销商品详情(含SKU、图片等完整信息)
|
|
194
|
147
|
*
|
|
195
|
148
|
* API: com.alibaba.fenxiao:alibaba.pifatuan.product.detail.list-2
|
|
196
|
|
- * 文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.fenxiao%3Aalibaba.pifatuan.product.detail.list-2
|
|
197
|
149
|
*
|
|
198
|
150
|
* @param int|string $productId 1688商品ID
|
|
199
|
|
- * @return array|false
|
|
|
151
|
+ * @return array|false 格式化后的商品详情数据
|
|
200
|
152
|
*/
|
|
201
|
153
|
public function getProductDetail($productId)
|
|
202
|
154
|
{
|
|
|
@@ -205,7 +157,6 @@ class ProductService extends AlibabaAgentBaseService
|
|
205
|
157
|
return false;
|
|
206
|
158
|
}
|
|
207
|
159
|
|
|
208
|
|
- // API要求参数名为 offerIds,类型为 Long[](数组)
|
|
209
|
160
|
$businessParams = [
|
|
210
|
161
|
'offerIds' => '[' . $productId . ']',
|
|
211
|
162
|
];
|
|
|
@@ -221,23 +172,33 @@ class ProductService extends AlibabaAgentBaseService
|
|
221
|
172
|
return false;
|
|
222
|
173
|
}
|
|
223
|
174
|
|
|
224
|
|
- // 临时:直接返回原始数据,方便查看结构
|
|
225
|
|
- return $result;
|
|
|
175
|
+ return $this->formatDetailResult($result);
|
|
226
|
176
|
}
|
|
227
|
177
|
|
|
228
|
178
|
/**
|
|
229
|
179
|
* 格式化商品详情结果
|
|
230
|
180
|
*
|
|
231
|
|
- * 1688商品详情API返回结构:
|
|
|
181
|
+ * 实际API返回结构:
|
|
232
|
182
|
* {
|
|
233
|
183
|
* "result": {
|
|
234
|
184
|
* "success": true,
|
|
235
|
|
- * "code": "0",
|
|
236
|
|
- * "result": {
|
|
237
|
|
- * "productInfo": { 商品详细信息 },
|
|
238
|
|
- * "skuList": [ SKU列表 ],
|
|
239
|
|
- * "productImgList": [ 图片列表 ]
|
|
240
|
|
- * }
|
|
|
185
|
+ * "result": [
|
|
|
186
|
+ * {
|
|
|
187
|
+ * "wangwangAccount": "...",
|
|
|
188
|
+ * "productInfo": {
|
|
|
189
|
+ * "productID": 635835395997,
|
|
|
190
|
+ * "subject": "商品标题",
|
|
|
191
|
+ * "image": { "images": ["img/ibank/..."] },
|
|
|
192
|
+ * "saleInfo": { "amountOnSale": 536989, "priceRanges": [...], "unit": "PCS" },
|
|
|
193
|
+ * "skuInfos": [{ "skuId": 5580608617712, "consignPrice": 4.14, "pifaPrice": 0.14, ... }],
|
|
|
194
|
+ * "categoryID": 202060914,
|
|
|
195
|
+ * "categoryName": "晶体振荡器",
|
|
|
196
|
+ * "description": "<div>..."
|
|
|
197
|
+ * },
|
|
|
198
|
+ * "tagInfoList": ["一件代发", "一件代发包邮"],
|
|
|
199
|
+ * "sellerOpenUid": "BBBAAvFPtiSWOJWNj2-MpLo4w"
|
|
|
200
|
+ * }
|
|
|
201
|
+ * ]
|
|
241
|
202
|
* }
|
|
242
|
203
|
* }
|
|
243
|
204
|
*
|
|
|
@@ -247,103 +208,244 @@ class ProductService extends AlibabaAgentBaseService
|
|
247
|
208
|
protected function formatDetailResult(array $result): array
|
|
248
|
209
|
{
|
|
249
|
210
|
$data = $result['result'] ?? $result;
|
|
250
|
|
- $detailData = $data['result'] ?? [];
|
|
|
211
|
+ $items = $data['result'] ?? [];
|
|
251
|
212
|
|
|
252
|
|
- if (empty($detailData)) {
|
|
|
213
|
+ if (empty($items) || !is_array($items)) {
|
|
253
|
214
|
return [];
|
|
254
|
215
|
}
|
|
255
|
216
|
|
|
256
|
|
- $productInfo = $detailData['productInfo'] ?? $detailData;
|
|
257
|
|
- $skuList = $detailData['skuList'] ?? [];
|
|
258
|
|
- $productImgList = $detailData['productImgList'] ?? [];
|
|
|
217
|
+ // 取第一个商品(API按offerIds查询单个商品)
|
|
|
218
|
+ $item = $items[0] ?? [];
|
|
|
219
|
+ if (empty($item)) {
|
|
|
220
|
+ return [];
|
|
|
221
|
+ }
|
|
259
|
222
|
|
|
260
|
|
- // 格式化SKU
|
|
261
|
|
- $formattedSkus = [];
|
|
262
|
|
- if (!empty($skuList)) {
|
|
263
|
|
- foreach ($skuList as $sku) {
|
|
264
|
|
- $formattedSkus[] = [
|
|
265
|
|
- 'skuId' => $sku['skuId'] ?? '',
|
|
266
|
|
- 'specId' => $sku['specId'] ?? '',
|
|
267
|
|
- 'price' => $sku['price'] ?? $sku['retailPrice'] ?? 0,
|
|
268
|
|
- 'salePrice' => $sku['salePrice'] ?? $sku['price'] ?? 0,
|
|
269
|
|
- 'stock' => $sku['stock'] ?? $sku['availableStock'] ?? 0,
|
|
270
|
|
- 'specName' => $sku['specName'] ?? $sku['name'] ?? '',
|
|
271
|
|
- 'image' => $sku['image'] ?? '',
|
|
272
|
|
- ];
|
|
|
223
|
+ $productInfo = $item['productInfo'] ?? [];
|
|
|
224
|
+ $tagInfoList = $item['tagInfoList'] ?? [];
|
|
|
225
|
+ $wangwangAccount = $item['wangwangAccount'] ?? '';
|
|
|
226
|
+
|
|
|
227
|
+ // --- 图片处理 ---
|
|
|
228
|
+ $imageData = $productInfo['image'] ?? [];
|
|
|
229
|
+ $rawImages = $imageData['images'] ?? [];
|
|
|
230
|
+ $imageList = [];
|
|
|
231
|
+ $mainImage = '';
|
|
|
232
|
+ if (!empty($rawImages)) {
|
|
|
233
|
+ foreach ($rawImages as $img) {
|
|
|
234
|
+ $fullUrl = $this->buildImageUrl($img);
|
|
|
235
|
+ $imageList[] = $fullUrl;
|
|
|
236
|
+ if (empty($mainImage)) {
|
|
|
237
|
+ $mainImage = $fullUrl;
|
|
|
238
|
+ }
|
|
273
|
239
|
}
|
|
274
|
240
|
}
|
|
275
|
241
|
|
|
276
|
|
- // 格式化图片列表
|
|
277
|
|
- $imageList = [];
|
|
278
|
|
- if (!empty($productImgList)) {
|
|
279
|
|
- foreach ($productImgList as $img) {
|
|
280
|
|
- $url = is_string($img) ? $img : ($img['url'] ?? $img['imgUrl'] ?? '');
|
|
281
|
|
- if (!empty($url)) {
|
|
282
|
|
- $imageList[] = $url;
|
|
|
242
|
+ // --- 价格处理 ---
|
|
|
243
|
+ $saleInfo = $productInfo['saleInfo'] ?? [];
|
|
|
244
|
+ $priceRanges = $saleInfo['priceRanges'] ?? [];
|
|
|
245
|
+ $minPrice = 0;
|
|
|
246
|
+ $maxPrice = 0;
|
|
|
247
|
+ if (!empty($priceRanges)) {
|
|
|
248
|
+ $prices = array_column($priceRanges, 'price');
|
|
|
249
|
+ $minPrice = !empty($prices) ? (float)min($prices) : 0;
|
|
|
250
|
+ $maxPrice = !empty($prices) ? (float)max($prices) : 0;
|
|
|
251
|
+ }
|
|
|
252
|
+
|
|
|
253
|
+ // --- 商品属性(如品牌、货号、规格等) ---
|
|
|
254
|
+ $attributes = $productInfo['attributes'] ?? [];
|
|
|
255
|
+
|
|
|
256
|
+ // --- SKU处理(提取规格名称、规格值、成本价) ---
|
|
|
257
|
+ $skuInfos = $productInfo['skuInfos'] ?? [];
|
|
|
258
|
+ $formattedSkus = [];
|
|
|
259
|
+ if (!empty($skuInfos)) {
|
|
|
260
|
+ foreach ($skuInfos as $sku) {
|
|
|
261
|
+ // 提取规格属性(规则名称 + 规格值名称)
|
|
|
262
|
+ $skuAttrs = $sku['attributes'] ?? [];
|
|
|
263
|
+ $specNames = [];
|
|
|
264
|
+ $specValues = [];
|
|
|
265
|
+ $skuAttrList = [];
|
|
|
266
|
+ foreach ($skuAttrs as $attr) {
|
|
|
267
|
+ $attrName = $attr['attributeName'] ?? '';
|
|
|
268
|
+ $attrValue = $attr['attributeValue'] ?? '';
|
|
|
269
|
+ if ($attrName !== '') {
|
|
|
270
|
+ $specNames[] = $attrName;
|
|
|
271
|
+ $specValues[] = $attrValue;
|
|
|
272
|
+ $skuAttrList[] = [
|
|
|
273
|
+ 'name' => $attrName,
|
|
|
274
|
+ 'value' => $attrValue,
|
|
|
275
|
+ ];
|
|
|
276
|
+ }
|
|
283
|
277
|
}
|
|
|
278
|
+
|
|
|
279
|
+ // 成本价(consignPrice 是分销价/代发价)
|
|
|
280
|
+ $costPrice = (float)($sku['consignPrice'] ?? $sku['pifaPrice'] ?? 0);
|
|
|
281
|
+
|
|
|
282
|
+ $formattedSkus[] = [
|
|
|
283
|
+ 'skuId' => $sku['skuId'] ?? '',
|
|
|
284
|
+ 'specId' => $sku['specId'] ?? '',
|
|
|
285
|
+ 'consignPrice' => $costPrice,
|
|
|
286
|
+ 'pifaPrice' => (float)($sku['pifaPrice'] ?? 0),
|
|
|
287
|
+ 'costPrice' => $costPrice,
|
|
|
288
|
+ 'stock' => $sku['amountOnSale'] ?? 0,
|
|
|
289
|
+ 'cargoNumber' => $sku['cargoNumber'] ?? '',
|
|
|
290
|
+ // 规格信息
|
|
|
291
|
+ 'specNames' => $specNames,
|
|
|
292
|
+ 'specValues' => $specValues,
|
|
|
293
|
+ 'specInfo' => !empty($skuAttrList) ? json_encode($skuAttrList, JSON_UNESCAPED_UNICODE) : ($sku['specInfo'] ?? ''),
|
|
|
294
|
+ 'skuAttrs' => $skuAttrList,
|
|
|
295
|
+ // 规格图片
|
|
|
296
|
+ 'image' => !empty($skuAttrs[0]['skuImageUrl'] ?? '') ? $this->buildImageUrl($skuAttrs[0]['skuImageUrl']) : '',
|
|
|
297
|
+ ];
|
|
284
|
298
|
}
|
|
285
|
299
|
}
|
|
286
|
300
|
|
|
287
|
|
- // 主图
|
|
288
|
|
- $mainImage = $productInfo['imgUrl'] ?? $productInfo['mainImage'] ?? $productInfo['mainPicture'] ?? '';
|
|
289
|
|
- if (empty($mainImage) && !empty($imageList)) {
|
|
290
|
|
- $mainImage = $imageList[0];
|
|
|
301
|
+ // --- 描述处理 ---
|
|
|
302
|
+ $description = $productInfo['description'] ?? '';
|
|
|
303
|
+
|
|
|
304
|
+ return [
|
|
|
305
|
+ 'productId' => $productInfo['productID'] ?? $productInfo['productId'] ?? 0,
|
|
|
306
|
+ 'categoryId' => $productInfo['categoryID'] ?? $productInfo['categoryId'] ?? 0,
|
|
|
307
|
+ 'categoryName' => $productInfo['categoryName'] ?? '',
|
|
|
308
|
+ 'title' => $productInfo['subject'] ?? '',
|
|
|
309
|
+ 'description' => $description,
|
|
|
310
|
+ 'price' => $minPrice,
|
|
|
311
|
+ 'minPrice' => $minPrice,
|
|
|
312
|
+ 'maxPrice' => $maxPrice,
|
|
|
313
|
+ 'stock' => $saleInfo['amountOnSale'] ?? 0,
|
|
|
314
|
+ 'unit' => $saleInfo['unit'] ?? '件',
|
|
|
315
|
+ 'mainImage' => $mainImage,
|
|
|
316
|
+ 'imageList' => $imageList,
|
|
|
317
|
+ 'attributes' => $attributes,
|
|
|
318
|
+ 'skuList' => $formattedSkus,
|
|
|
319
|
+ 'shopName' => $wangwangAccount,
|
|
|
320
|
+ 'sellerOpenUid' => $item['sellerOpenUid'] ?? '',
|
|
|
321
|
+ 'serviceTags' => $tagInfoList,
|
|
|
322
|
+ ];
|
|
|
323
|
+ }
|
|
|
324
|
+
|
|
|
325
|
+ /**
|
|
|
326
|
+ * 构建图片完整URL
|
|
|
327
|
+ *
|
|
|
328
|
+ * @param string $path 图片路径
|
|
|
329
|
+ * @return string
|
|
|
330
|
+ */
|
|
|
331
|
+ protected function buildImageUrl(string $path): string
|
|
|
332
|
+ {
|
|
|
333
|
+ if (empty($path)) {
|
|
|
334
|
+ return '';
|
|
|
335
|
+ }
|
|
|
336
|
+ if (strpos($path, 'http://') === 0 || strpos($path, 'https://') === 0) {
|
|
|
337
|
+ return $path;
|
|
291
|
338
|
}
|
|
|
339
|
+ // 1688 图片路径为相对路径如 img/ibank/O1CN01...,需拼接阿里云CDN域名
|
|
|
340
|
+ return 'https://cbu01.alicdn.com/' . ltrim($path, '/');
|
|
|
341
|
+ }
|
|
292
|
342
|
|
|
293
|
|
- // 服务标签
|
|
294
|
|
- $serviceTags = [];
|
|
295
|
|
- if (!empty($productInfo['serviceList'])) {
|
|
296
|
|
- foreach ($productInfo['serviceList'] as $service) {
|
|
297
|
|
- $serviceTags[] = $service['name'] ?? '';
|
|
|
343
|
+ // ================================================================
|
|
|
344
|
+ // 批量入库
|
|
|
345
|
+ // ================================================================
|
|
|
346
|
+
|
|
|
347
|
+ /**
|
|
|
348
|
+ * 对价格进行加价处理(加价50%)
|
|
|
349
|
+ *
|
|
|
350
|
+ * @param float $price 原价
|
|
|
351
|
+ * @return float 加价后的价格
|
|
|
352
|
+ */
|
|
|
353
|
+ protected function applyMarkup(float $price): float
|
|
|
354
|
+ {
|
|
|
355
|
+ return round($price * 1.5, 2);
|
|
|
356
|
+ }
|
|
|
357
|
+
|
|
|
358
|
+ /**
|
|
|
359
|
+ * 批量导入1688商品到 alibaba_import_goods 表
|
|
|
360
|
+ *
|
|
|
361
|
+ * 业务场景:从1688商品列表中选择多个商品,一键入库
|
|
|
362
|
+ * 将商品详情数据以JSON格式完整存储到 alibaba_import_goods 表
|
|
|
363
|
+ * 入库时自动对所有价格加价50%
|
|
|
364
|
+ *
|
|
|
365
|
+ * @param array $productIds 1688商品ID数组,如 [635835395997, 635835395998]
|
|
|
366
|
+ * @param int $merId 商户ID
|
|
|
367
|
+ * @param array $extra 额外参数(预留)
|
|
|
368
|
+ * @return array ['success' => [productId => localId], 'fail' => [productId => reason]]
|
|
|
369
|
+ */
|
|
|
370
|
+ public function batchImport(array $productIds, int $merId, array $extra = []): array
|
|
|
371
|
+ {
|
|
|
372
|
+ $success = [];
|
|
|
373
|
+ $fail = [];
|
|
|
374
|
+ $now = date('Y-m-d H:i:s');
|
|
|
375
|
+
|
|
|
376
|
+ foreach ($productIds as $productId) {
|
|
|
377
|
+ try {
|
|
|
378
|
+ // 检查是否已入库(product_id唯一)
|
|
|
379
|
+ $exists = Db::name('alibaba_import_goods')
|
|
|
380
|
+ ->where('product_id', (int)$productId)
|
|
|
381
|
+ ->where('status', 1)
|
|
|
382
|
+ ->find();
|
|
|
383
|
+
|
|
|
384
|
+ if ($exists) {
|
|
|
385
|
+ $success[$productId] = $exists['id'];
|
|
|
386
|
+ Log::info("[1688入库] 商品{$productId}已存在,跳过入库,本地ID:{$exists['id']}");
|
|
|
387
|
+ continue;
|
|
|
388
|
+ }
|
|
|
389
|
+
|
|
|
390
|
+ // 调用详情API获取完整数据
|
|
|
391
|
+ $detail = $this->getProductDetail($productId);
|
|
|
392
|
+ if ($detail === false || empty($detail)) {
|
|
|
393
|
+ $fail[$productId] = '获取1688商品详情失败';
|
|
|
394
|
+ continue;
|
|
|
395
|
+ }
|
|
|
396
|
+
|
|
|
397
|
+ // ===== 加价处理:所有价格加价50% =====
|
|
|
398
|
+ // 1. SKU级别成本价加价
|
|
|
399
|
+ $skuList = $detail['skuList'] ?? [];
|
|
|
400
|
+ foreach ($skuList as &$sku) {
|
|
|
401
|
+ $sku['originalCostPrice'] = $sku['costPrice'] ?? 0;
|
|
|
402
|
+ $sku['costPrice'] = $this->applyMarkup((float)$sku['costPrice']);
|
|
|
403
|
+ $sku['originalConsignPrice'] = $sku['consignPrice'] ?? 0;
|
|
|
404
|
+ $sku['consignPrice'] = $this->applyMarkup((float)$sku['consignPrice']);
|
|
|
405
|
+ $sku['originalPifaPrice'] = $sku['pifaPrice'] ?? 0;
|
|
|
406
|
+ $sku['pifaPrice'] = $this->applyMarkup((float)$sku['pifaPrice']);
|
|
|
407
|
+ }
|
|
|
408
|
+ unset($sku);
|
|
|
409
|
+ $detail['skuList'] = $skuList;
|
|
|
410
|
+
|
|
|
411
|
+ // 2. 商品级别价格加价
|
|
|
412
|
+ $detail['originalMinPrice'] = $detail['minPrice'] ?? 0;
|
|
|
413
|
+ $detail['originalMaxPrice'] = $detail['maxPrice'] ?? 0;
|
|
|
414
|
+ $detail['originalPrice'] = $detail['price'] ?? 0;
|
|
|
415
|
+ $detail['minPrice'] = $this->applyMarkup((float)$detail['minPrice']);
|
|
|
416
|
+ $detail['maxPrice'] = $this->applyMarkup((float)$detail['maxPrice']);
|
|
|
417
|
+ $detail['price'] = $this->applyMarkup((float)$detail['price']);
|
|
|
418
|
+
|
|
|
419
|
+ // 3. 标记加价比例
|
|
|
420
|
+ $detail['markupRate'] = 50;
|
|
|
421
|
+ $detail['markupMultiplier'] = 1.5;
|
|
|
422
|
+
|
|
|
423
|
+ // 写入 alibaba_import_goods 表(完整JSON存储,含加价后价格)
|
|
|
424
|
+ $insertData = [
|
|
|
425
|
+ 'product_id' => (int)$productId,
|
|
|
426
|
+ 'product_name' => $detail['title'] ?? '',
|
|
|
427
|
+ 'image' => $detail['mainImage'] ?? '',
|
|
|
428
|
+ 'product_info' => json_encode($detail, JSON_UNESCAPED_UNICODE),
|
|
|
429
|
+ 'status' => 1,
|
|
|
430
|
+ 'create_time' => $now,
|
|
|
431
|
+ ];
|
|
|
432
|
+ $localId = Db::name('alibaba_import_goods')->insertGetId($insertData);
|
|
|
433
|
+
|
|
|
434
|
+ if ($localId) {
|
|
|
435
|
+ $success[$productId] = $localId;
|
|
|
436
|
+ Log::info("[1688入库] 商品{$productId}入库成功,本地ID:{$localId},已加价50%");
|
|
|
437
|
+ } else {
|
|
|
438
|
+ $fail[$productId] = '写入数据库失败';
|
|
|
439
|
+ }
|
|
|
440
|
+ } catch (\Throwable $e) {
|
|
|
441
|
+ $fail[$productId] = '异常: ' . $e->getMessage();
|
|
|
442
|
+ Log::error("[1688入库] 商品{$productId}入库异常: " . $e->getMessage());
|
|
298
|
443
|
}
|
|
299
|
444
|
}
|
|
300
|
445
|
|
|
301
|
446
|
return [
|
|
302
|
|
- // 基础信息
|
|
303
|
|
- 'productId' => $productInfo['itemId'] ?? $productInfo['productId'] ?? $productInfo['offerId'] ?? 0,
|
|
304
|
|
- 'productType' => $productInfo['productType'] ?? '',
|
|
305
|
|
- 'categoryId' => $productInfo['categoryId'] ?? $productInfo['catId'] ?? 0,
|
|
306
|
|
- 'categoryName' => $productInfo['categoryName'] ?? '',
|
|
307
|
|
-
|
|
308
|
|
- // 标题与描述
|
|
309
|
|
- 'title' => $productInfo['title'] ?? $productInfo['subject'] ?? $productInfo['name'] ?? '',
|
|
310
|
|
- 'description' => $productInfo['description'] ?? $productInfo['detail'] ?? '',
|
|
311
|
|
-
|
|
312
|
|
- // 价格信息
|
|
313
|
|
- 'price' => $productInfo['minPrice'] ?? $productInfo['price'] ?? $productInfo['offerPrice'] ?? 0,
|
|
314
|
|
- 'salePrice' => $productInfo['maxPrice'] ?? $productInfo['salePrice'] ?? $productInfo['price'] ?? 0,
|
|
315
|
|
- 'minPrice' => $productInfo['minPrice'] ?? $productInfo['price'] ?? 0,
|
|
316
|
|
- 'maxPrice' => $productInfo['maxPrice'] ?? $productInfo['price'] ?? 0,
|
|
317
|
|
-
|
|
318
|
|
- // 库存信息
|
|
319
|
|
- 'stock' => $productInfo['stock'] ?? $productInfo['totalAvailableStock'] ?? 0,
|
|
320
|
|
- 'unit' => $productInfo['unit'] ?? '件',
|
|
321
|
|
-
|
|
322
|
|
- // 图片信息
|
|
323
|
|
- 'mainImage' => $mainImage,
|
|
324
|
|
- 'imageList' => $imageList,
|
|
325
|
|
-
|
|
326
|
|
- // SKU列表
|
|
327
|
|
- 'skuList' => $formattedSkus,
|
|
328
|
|
-
|
|
329
|
|
- // 销售信息
|
|
330
|
|
- 'monthSales' => $productInfo['monthSales'] ?? $productInfo['salesCnt90d'] ?? 0,
|
|
331
|
|
- 'totalSales' => $productInfo['totalSales'] ?? 0,
|
|
332
|
|
-
|
|
333
|
|
- // 服务标签
|
|
334
|
|
- 'serviceTags' => $serviceTags,
|
|
335
|
|
-
|
|
336
|
|
- // 分销属性
|
|
337
|
|
- 'isDistribution' => $productInfo['isDistribution'] ?? false,
|
|
338
|
|
- 'isStrictSelected' => $productInfo['isStrictSelected'] ?? false,
|
|
339
|
|
- 'distributorPrice' => $productInfo['distributorPrice'] ?? 0,
|
|
340
|
|
-
|
|
341
|
|
- // 店铺信息
|
|
342
|
|
- 'shopName' => $productInfo['shopName'] ?? $productInfo['companyName'] ?? '',
|
|
343
|
|
- 'shopId' => $productInfo['shopId'] ?? $productInfo['memberId'] ?? '',
|
|
344
|
|
-
|
|
345
|
|
- // 链接
|
|
346
|
|
- 'detailUrl' => $productInfo['detailUrl'] ?? $productInfo['offerUrl'] ?? '',
|
|
|
447
|
+ 'success' => $success,
|
|
|
448
|
+ 'fail' => $fail,
|
|
347
|
449
|
];
|
|
348
|
450
|
}
|
|
349
|
451
|
}
|