Files
douba_shop/app/haichao/HaichaoJstServices.php
Karlcarlo 7e422335e4 feat(haichao): 新增聚水潭ERP集成功能
- 新增聚水潭回调接口及事件处理机制
- 添加聚水潭商品、订单、售后同步任务
- 实现聚水潭订单推送及售后状态同步
- 新增手动同步聚水潭商品功能
- 在各路由组添加聚水潭中间件支持
2026-04-01 11:55:18 +08:00

816 lines
30 KiB
PHP

<?php
namespace app\haichao;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderRefundServices;
use app\services\order\StoreOrderServices;
use app\services\supplier\SystemSupplierServices;
use crmeb\exceptions\AdminException;
use think\exception\ValidateException;
use think\facade\Log;
class HaichaoJstServices extends HaichaoBridge
{
/**
* 同步物流公司信息并推送订单发货节点
* @param string $postId
* @param string $postName
* @param int $oid
* @return array
*/
public function updateStoreOrderDelivery(string $postId, string $postName, $oid = 0): array
{
$postList = [];
$postList[] = [
'l_id' => $postId,
'l_name' => $postName,
'warehouseRemark' => ''
];
$rt = $this->post('open/express/register/upload', $postList);
$this->orderPush($oid, 'WAIT_BUYER_CONFIRM_GOODS', '', [], [
'l_id' => $postId,
'l_name' => $postName,
'warehouseRemark' => ''
]);
return $rt;
}
/**
* 推送订单到聚水潭(含支付/发货/退款等状态同步)
* @param int $oid
* @param string $status
* @param string $rftype
* @param array $rfinfo
* @param array $extpm
* @return bool
*/
public function orderPush(int $oid, string $status = 'WAIT_SELLER_SEND_GOODS', $rftype = '', $rfinfo = [], $extpm = []): bool
{
Log::info('jst.order_push.start ' . $oid . ' ' . $status);
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$order = $orderServices->get($oid, ['*'], ['store']);
if (!$order || $order['id'] < 1) {
throw new AdminException('订单信息不能为空');
}
if ($order['product_type'] != 4) {
if ($order['product_type'] > 0 || !$order['paid']) {
return true;
}
}
$rid = $order['supplier_id'] ?? 0;
$shopid = (int)$this->getShopId();
if ($rid) {
/** @var SystemSupplierServices $systemSupplierServices */
$systemSupplierServices = app()->make(SystemSupplierServices::class);
$info = $systemSupplierServices->getSupplierInfo((int)$rid, 'erp_shopid');
if (!$info || !$info['erp_shopid']) return true;
$shopid = (int)$info['erp_shopid'];
if (!$shopid) return true;
}
$items = $this->getItems($oid, (int)$order['uid'], $order['unique'], $rftype);
if (isset($extpm['l_id'])) {
$order['delivery_id'] = $extpm['l_id'];
$order['delivery_name'] = $extpm['l_name'];
}
$biz = [
'shop_id' => $shopid,
'so_id' => $order['order_id'],
'shop_status' => $status,
'buyer_message' => $order['mark'],
'shop_buyer_id' => (string)$order['uid'],
'receiver_name' => $order['real_name'],
'receiver_mobile' => $order['user_phone'],
'pay_amount' => (float)$order['pay_price'],
'freight' => (float)$order['freight_price'],
'order_date' => date('Y-m-d H:i:s', $order['add_time']),
'shop_modified' => date('Y-m-d H:i:s', $order['add_time']),
'items' => $items,
'l_id' => $order['delivery_id'] ?? '',
'logistics_company' => $order['delivery_name'] ?? '',
'pay' => [],
];
if ($rfinfo) {
$biz['pay'] = [
'outer_pay_id' => $rfinfo['order_id'] ?? $order['order_id'],
'pay_date' => date('Y-m-d H:i:s'),
'payment' => $order['pay_type'],
'seller_account' => 'seller',
'buyer_account' => 'buyer' . $order['uid'],
'amount' => 0 - (float)($rfinfo['refunded_price'] ?? 0)
];
$q = [
'shop_id' => $shopid,
'so_ids' => [$order['order_id']]
];
$resultb = $this->post('open/orders/single/query', $q)['data'];
$biz['shop_status'] = $resultb['orders'][0]['shop_status'] ?? $status;
} else {
$biz['pay'] = [
'outer_pay_id' => $order['order_id'],
'pay_date' => date('Y-m-d H:i:s', $order['pay_time']),
'payment' => $order['pay_type'],
'seller_account' => 'seller',
'buyer_account' => 'buyer' . $order['uid'],
'amount' => (float)$order['pay_price']
];
}
$addr = $this->getAddress($order['user_address']);
$biz = array_merge($biz, $addr);
if (isset($biz['l_id']) && $biz['l_id'] === '') {
unset($biz['l_id']);
}
if (isset($biz['logistics_company']) && $biz['logistics_company'] === '') {
unset($biz['logistics_company']);
}
if (isset($biz['receiver_zip']) && $biz['receiver_zip'] === '') {
unset($biz['receiver_zip']);
}
if (isset($biz['items']) && is_array($biz['items'])) {
foreach ($biz['items'] as $k => $item) {
if (is_array($item) && isset($item['pic']) && $item['pic'] === '') {
unset($item['pic']);
$biz['items'][$k] = $item;
}
}
}
$num = 3;
for ($i = $num; $i >= 0; $i--) {
if ($i <= 0) {
Log::error('ERP订单上传失败 ' . json_encode([
'api' => 'open/jushuitan/orders/upload',
'shop_id' => $shopid,
'so_id' => (string)($biz['so_id'] ?? ''),
], JSON_UNESCAPED_UNICODE));
return false;
}
try {
$resp = $this->post('open/jushuitan/orders/upload', [$biz]);
$result = $resp['data'] ?? [];
if (!empty($result['datas'][0]['issuccess']) && $order['erp_order_id'] != $biz['so_id']) {
$order->save(['erp_id' => $result['datas'][0]['o_id'], 'erp_order_id' => $biz['so_id']]);
}
break;
} catch (\Throwable $e) {
usleep(1000 * 50);
Log::error('ERP订单上传失败:' . $e->getMessage() . ' ' . json_encode([
'try' => ($num - $i + 1),
'api' => 'open/jushuitan/orders/upload',
'shop_id' => $shopid,
'so_id' => (string)($biz['so_id'] ?? ''),
], JSON_UNESCAPED_UNICODE));
}
}
return true;
}
/**
* 售后单创建推送(本地 -> 聚水潭)
* @param int $refundId
* @return bool
*/
public function afterSaleCreatePush(int $refundId): bool
{
$api = 'open/aftersale/upload';
Log::info('jst.after_sale.create.start ' . json_encode(['refund_id' => $refundId], JSON_UNESCAPED_UNICODE));
/** @var StoreOrderRefundServices $storeOrderRefundServices */
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
$refund = $storeOrderRefundServices->get($refundId);
if (!$refund) {
Log::warning('jst.after_sale.create.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'refund_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (method_exists($refund, 'toArray')) {
$refund = $refund->toArray();
}
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
$order = $storeOrderServices->get((int)($refund['store_order_id'] ?? 0), ['*'], ['store']);
if (!$order) {
Log::warning('jst.after_sale.create.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'order_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (($order['product_type'] ?? 0) != 4) {
if (($order['product_type'] ?? 0) > 0 || !($order['paid'] ?? 0)) {
Log::info('jst.after_sale.create.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'product_filter',
'product_type' => $order['product_type'] ?? null,
'paid' => $order['paid'] ?? null,
], JSON_UNESCAPED_UNICODE));
return true;
}
}
$shopid = $this->resolveShopIdByOrder($order);
if (!$shopid) {
Log::info('jst.after_sale.create.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'missing_shopid',
'supplier_id' => $order['supplier_id'] ?? 0
], JSON_UNESCAPED_UNICODE));
return true;
}
$outerAsId = (string)($refund['order_id'] ?? '');
if ($outerAsId === '') {
$outerAsId = (string)$refundId;
}
$items = $this->buildAfterSaleItemsFromRefund($refund);
$applyType = (int)($refund['apply_type'] ?? $refund['refund_type'] ?? 0);
if ($applyType == 1) {
$typeStr = '仅退款';
$goodStatus = 'BUYER_NOT_RECEIVED';
} else {
$typeStr = '普通退货';
$goodStatus = 'BUYER_RETURNED_GOODS';
}
if ($applyType == 1) {
$items = [];
} elseif (is_array($items)) {
foreach ($items as $idx => $it) {
if (is_array($it)) {
$it['type'] = '退货';
$items[$idx] = $it;
}
}
}
$biz = [
'shop_id' => $shopid,
'so_id' => (string)($order['order_id'] ?? ''),
'outer_as_id' => $outerAsId,
'type' => $typeStr,
'good_status' => $goodStatus,
'shop_status' => 'wait',
'total_amount' => (float)($order['pay_price'] ?? 0),
'payment' => 0.00,
'question_type' => (string)($refund['refund_reason'] ?? $refund['refund_explain'] ?? ''),
'refund' => (float)($refund['refund_price'] ?? $refund['apply_price'] ?? 0),
'remark' => (string)($refund['remark'] ?? ''),
'items' => $items,
];
$this->retryPost($api, [$biz], 'jst.after_sale.create');
return true;
}
/**
* 售后单撤销推送(本地 -> 聚水潭)
* @param int $refundId
* @return bool
*/
public function afterSaleCancelPush(int $refundId): bool
{
$api = 'open/webapi/aftersaleapi/open/cancel';
Log::info('jst.after_sale.cancel.start ' . json_encode(['refund_id' => $refundId], JSON_UNESCAPED_UNICODE));
/** @var StoreOrderRefundServices $storeOrderRefundServices */
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
$refund = $storeOrderRefundServices->get($refundId);
if (!$refund) {
Log::warning('jst.after_sale.cancel.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'refund_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (method_exists($refund, 'toArray')) {
$refund = $refund->toArray();
}
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
$order = $storeOrderServices->get((int)($refund['store_order_id'] ?? 0), ['*'], ['store']);
if (!$order) {
Log::warning('jst.after_sale.cancel.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'order_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (($order['product_type'] ?? 0) != 4) {
if (($order['product_type'] ?? 0) > 0 || !($order['paid'] ?? 0)) {
Log::info('jst.after_sale.cancel.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'product_filter',
'product_type' => $order['product_type'] ?? null,
'paid' => $order['paid'] ?? null,
], JSON_UNESCAPED_UNICODE));
return true;
}
}
$shopid = $this->resolveShopIdByOrder($order);
if (!$shopid) {
Log::info('jst.after_sale.cancel.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'missing_shopid',
'supplier_id' => $order['supplier_id'] ?? 0
], JSON_UNESCAPED_UNICODE));
return true;
}
$outerAsId = (string)($refund['order_id'] ?? '');
if ($outerAsId === '') {
$outerAsId = (string)$refundId;
}
$erpInfo = [];
if (!empty($refund['erp'])) {
$erpInfo = json_decode($refund['erp'], true) ?: [];
}
$asId = $erpInfo['as_id'] ?? 0;
if ($asId) {
$biz = [
'as_ids' => [(int)$asId],
];
} else {
$biz = [
'shop_id' => $shopid,
'so_id' => (string)($order['order_id'] ?? ''),
'outer_as_id' => $outerAsId,
'reason' => (string)($refund['refuse_reason'] ?? $refund['refund_reason'] ?? ''),
];
}
$this->retryPost($api, $biz, 'jst.after_sale.cancel');
return true;
}
/**
* 售后单确认退款推送(本地 -> 聚水潭)
* @param int $refundId
* @return bool
*/
public function afterSaleRefundedPush(int $refundId): bool
{
$api = 'open/webapi/aftersaleapi/open/confirm';
Log::info('jst.after_sale.refunded.start ' . json_encode(['refund_id' => $refundId], JSON_UNESCAPED_UNICODE));
/** @var StoreOrderRefundServices $storeOrderRefundServices */
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
$refund = $storeOrderRefundServices->get($refundId);
if (!$refund) {
Log::warning('jst.after_sale.refunded.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'refund_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (method_exists($refund, 'toArray')) {
$refund = $refund->toArray();
}
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
$order = $storeOrderServices->get((int)($refund['store_order_id'] ?? 0), ['*'], ['store']);
if (!$order) {
Log::warning('jst.after_sale.refunded.skip ' . json_encode(['refund_id' => $refundId, 'reason' => 'order_missing'], JSON_UNESCAPED_UNICODE));
return true;
}
if (($order['product_type'] ?? 0) != 4) {
if (($order['product_type'] ?? 0) > 0 || !($order['paid'] ?? 0)) {
Log::info('jst.after_sale.refunded.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'product_filter',
'product_type' => $order['product_type'] ?? null,
'paid' => $order['paid'] ?? null,
], JSON_UNESCAPED_UNICODE));
return true;
}
}
$shopid = $this->resolveShopIdByOrder($order);
if (!$shopid) {
Log::info('jst.after_sale.refunded.skip ' . json_encode([
'refund_id' => $refundId,
'reason' => 'missing_shopid',
'supplier_id' => $order['supplier_id'] ?? 0
], JSON_UNESCAPED_UNICODE));
return true;
}
$outerAsId = (string)($refund['order_id'] ?? '');
if ($outerAsId === '') {
$outerAsId = (string)$refundId;
}
$erpInfo = [];
if (!empty($refund['erp'])) {
$erpInfo = json_decode($refund['erp'], true) ?: [];
}
$asId = $erpInfo['as_id'] ?? 0;
if ($asId) {
$biz = [
'as_ids' => [(int)$asId],
'exchange_force' => true,
'confirm_refund' => true,
];
} else {
$biz = [
'shop_id' => $shopid,
'so_id' => (string)($order['order_id'] ?? ''),
'outer_as_id' => $outerAsId,
'amount' => sprintf('%.2f', (float)($refund['refund_price'] ?? $refund['apply_price'] ?? 0)),
];
}
$this->retryPost($api, $biz, 'jst.after_sale.refunded');
return true;
}
public function getItems(int $oid, int $uid, string $unique, $rftype = ''): array
{
/** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
$storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
$cartInfo = $storeOrderCartInfoServices->getOrderCartInfo($oid);
if (empty($cartInfo)) {
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$orderInfo = $orderServices->getCacheOrderInfo($uid, $unique);
$cartInfo = $orderInfo['cartInfo'] ?? [];
}
$items = [];
foreach ($cartInfo as $cart) {
$cart = $cart['cart_info'] ?? $cart;
$attrInfo = $cart['productInfo']['attrInfo'];
$truePrice = (string)($cart['sum_true_price'] ?? $cart['truePrice']);
$itemdet = [
'sku_id' => $attrInfo['code'] ?: ($attrInfo['unique'] . 'ok'),
'shop_sku_id' => $attrInfo['code'] ?: ($attrInfo['unique'] . 'ok'),
'base_price' => (float)($attrInfo['price'] ?? 0),
'price' => (float)bcdiv($truePrice, (string)$cart['cart_num'], 2),
'amount' => (float)$truePrice,
'qty' => $cart['cart_num'],
'pic' => $cart['productInfo']['image'],
'name' => $cart['productInfo']['store_name'],
'properties_value' => $attrInfo['suk'],
'outer_oi_id' => $cart['product_attr_unique'],
'refund_qty' => $rftype == 'refund_nosend' ? $cart['cart_num'] : ($cart['refund_num'] ?? 0),
];
if ($itemdet['qty'] == $itemdet['refund_qty']) {
$itemdet['refund_status'] = 'success';
}
$items[] = $itemdet;
}
return $items;
}
private function resolveShopIdByOrder($order): int
{
$rid = $order['supplier_id'] ?? 0;
$shopid = (int)$this->getShopId();
if ($rid) {
/** @var SystemSupplierServices $systemSupplierServices */
$systemSupplierServices = app()->make(SystemSupplierServices::class);
$info = $systemSupplierServices->getSupplierInfo((int)$rid, 'erp_shopid');
if (!$info || !$info['erp_shopid']) {
return 0;
}
$shopid = (int)$info['erp_shopid'];
}
return (int)$shopid;
}
private function buildAfterSaleItemsFromRefund(array $refund): array
{
$cartInfo = $refund['cart_info'] ?? [];
if (is_string($cartInfo)) {
$decoded = json_decode($cartInfo, true);
if (is_array($decoded)) {
$cartInfo = $decoded;
}
}
if (!is_array($cartInfo)) {
$cartInfo = [];
}
$items = [];
foreach ($cartInfo as $cart) {
$cart = $cart['cart_info'] ?? $cart;
$productInfo = $cart['productInfo'] ?? [];
$attrInfo = $productInfo['attrInfo'] ?? [];
$skuId = (string)($attrInfo['code'] ?? '');
if ($skuId === '') {
$skuId = (string)($attrInfo['unique'] ?? '');
if ($skuId !== '') {
$skuId .= 'ok';
}
}
$items[] = [
'sku_id' => $skuId,
'qty' => (int)($cart['cart_num'] ?? 0),
'price' => sprintf('%.2f', (float)($attrInfo['price'] ?? 0)),
'amount' => sprintf('%.2f', (float)($cart['sum_true_price'] ?? 0)),
'outer_oi_id' => (string)($cart['product_attr_unique'] ?? ''),
'name' => (string)($productInfo['store_name'] ?? ''),
];
}
return $items;
}
private function retryPost(string $api, array $biz, string $logPrefix): void
{
$meta = $this->extractBizMeta($biz);
$num = 3;
for ($i = $num; $i >= 0; $i--) {
if ($i <= 0) {
Log::error($logPrefix . '.failed ' . json_encode(array_merge([
'api' => $api,
], $meta), JSON_UNESCAPED_UNICODE));
return;
}
try {
$rt = $this->post($api, $biz);
return;
} catch (\Throwable $e) {
usleep(1000 * 50);
Log::error($logPrefix . '.error ' . $e->getMessage() . ' ' . json_encode(array_merge([
'try' => ($num - $i + 1),
'api' => $api,
], $meta), JSON_UNESCAPED_UNICODE));
}
}
}
private function extractBizMeta(array $biz): array
{
$first = $biz;
if ($this->isListArray($biz) && isset($biz[0]) && is_array($biz[0])) {
$first = $biz[0];
}
if (!is_array($first)) {
return [];
}
$meta = [];
foreach (['shop_id', 'so_id', 'outer_as_id', 'as_ids'] as $k) {
if (array_key_exists($k, $first)) {
$meta[$k] = $first[$k];
}
}
return $meta;
}
private function isListArray(array $arr): bool
{
if ($arr === []) {
return true;
}
return array_keys($arr) === range(0, count($arr) - 1);
}
private function getAddress($address): array
{
if (is_string($address)) {
$decoded = json_decode($address, true);
if (is_array($decoded)) {
$address = $decoded;
} else {
$parts = preg_split('/\s+/u', trim($address));
if (is_array($parts) && count($parts) >= 3) {
$address = [
'province' => $parts[0] ?? '',
'city' => $parts[1] ?? '',
'area' => $parts[2] ?? '',
'detail' => trim(implode(' ', array_slice($parts, 3))),
];
if (($address['detail'] ?? '') === '') {
$address['detail'] = $parts[2] ?? '';
}
} else {
$address = ['detail' => $address];
}
}
}
if (!is_array($address)) {
$address = [];
}
return [
'receiver_address' => $address['detail'] ?? '',
'receiver_state' => $address['province'] ?? '',
'receiver_city' => $address['city'] ?? '',
'receiver_district' => $address['area'] ?? '',
'receiver_zip' => $address['post_code'] ?? '',
];
}
public static function getServices(): HaichaoJstServices
{
return new HaichaoJstServices();
}
public function getProductListShop($key = ''): array
{
$time = 1;
$data = $this->post('open/skumap/query', [
'modified_begin' => date('Y-m-d H:i', (time() - (86400 * $time))),
'modified_end' => date('Y-m-d H:i', time() - (86400 * $time) + 7 * 86400),
'page_index' => 1,
'page_size' => 50,
'shop_id' => $key
])['data'];
return $data;
}
public function getProductListName($key = ''): array
{
$data = $this->post('open/sku/query', [
'exactly_name' => $key,
'page_index' => 1,
'page_size' => 10,
])['data'];
return $data;
}
public function syncProductSingle($data, $pid = 0)
{
$jstProductSync = app()->make(\app\haichao\sync\JstProductSync::class);
return $jstProductSync->syncProductSingle($data, $pid);
}
public function getProductListSku($key = ''): array
{
$data = $this->post('open/sku/query', [
'sku_ids' => $key,
'page_index' => 1,
'page_size' => 10,
])['data'];
return $data;
}
public function getProductListKuan($key = ''): array
{
$data = $this->post('open/mall/item/query', [
'i_ids' => [$key],
'page_index' => 1,
'page_size' => 10,
'date_field' => '',
])['data'];
return $data;
}
public function getProductListStand(): array
{
$time = 10;
$data = $this->post('open/mall/item/query', [
'modified_begin' => date('Y-m-d H:i', (time() - (86400 * $time))),
'modified_end' => date('Y-m-d H:i', time() - (86400 * $time) + 7 * 86400),
'i_ids' => [],
'page_index' => 1,
'page_size' => 50,
'date_field' => '',
])['data'];
return $data;
}
public function getProductList(): array
{
$time = 1;
if (file_exists(root_path() . 'runtime/jstdata/synctime.txt')) {
$time = file_get_contents(root_path() . 'runtime/jstdata/synctime.txt');
}
$syncint = 0;
if (file_exists(root_path() . 'runtime/jstdata/syncint.txt')) {
$syncint = file_get_contents(root_path() . 'runtime/jstdata/syncint.txt');
}
$syncint++; // 这里的 $syncint 实际上代表要拉取的页码(page_index)
$data = $this->post('open/mall/item/query', [
'modified_begin' => date('Y-m-d H:i', (time() - (86400 * $time))),
'modified_end' => date('Y-m-d H:i', time() - (86400 * $time) + 7 * 86400),
'i_ids' => [],
'page_index' => $syncint, // 将写死的 1 改为动态的页码变量
'page_size' => 10,
'date_field' => '',
])['data'];
if ($syncint > $data['page_count']) {
$syncint = 1;
$time += 7;
if ($time > 500) {
$time = 1;
}
}
if (!is_dir(root_path() . 'runtime/jstdata')) {
mkdir(root_path() . 'runtime/jstdata', 0777, true);
}
file_put_contents(root_path() . 'runtime/jstdata/syncint.txt', $syncint);
file_put_contents(root_path() . 'runtime/jstdata/synctime.txt', $time);
return $data;
}
public function getStork(string $ids): array
{
return $this->post('open/inventory/query', [
'page_index' => 1,
'page_size' => 100,
'sku_ids' => $ids,
]);
}
public function getInneropenItemList(): array
{
$return = [];
$n = 1;
if (file_exists(root_path() . 'runtime/jstdata/syncintgood.txt')) {
$n = file_get_contents(root_path() . 'runtime/jstdata/syncintgood.txt');
}
$data = $this->post('open/api/goods/inneropen/goods/querygoodslist', [
'page_num' => $n,
'page_size' => 10,
'sort' => 'ASC'
])['data'];
$result = $data['list'];
$return = array_merge($result, $return);
if (file_exists(root_path() . 'runtime/jstdata/syncintgood.txt')) {
$n = file_get_contents(root_path() . 'runtime/jstdata/syncintgood.txt');
$n++;
if ($n > ceil($data['total'] / 10)) {
$n = 1;
}
}
if (!is_dir(root_path() . 'runtime/jstdata')) {
mkdir(root_path() . 'runtime/jstdata', 0777, true);
}
file_put_contents(root_path() . 'runtime/jstdata/syncintgood.txt', $n);
return $return;
}
public function getInneropenItemDetail($skuId): array
{
return $this->post('open/api/goods/inneropen/goods/querygoodsdetail', [
'item_spuId' => $skuId
])['data'];
}
public function findStockBySkuId($skuid = ''): array
{
$result = $this->post('open/inventory/query', [
'page_num' => 1,
'page_size' => 500,
'sku_ids' => $skuid,
])['data']['inventorys'];
return $result;
}
public function getInneropenStockAndDetailList($styleCodes): array
{
$rt = [];
$i = 1;
do {
$result = $this->post('open/inventory/query', [
'page_index' => $i++,
'page_size' => 100,
'sku_ids' => $styleCodes
])['data']['inventorys'] ?? [];
// 适配原来的返回格式结构
$formatResult = [];
foreach ($result as $item) {
$formatResult[] = [
'item_code' => $item['sku_id'],
'stock' => max(0, ($item['qty'] ?? 0) - ($item['order_lock'] ?? 0)) // 实际可用库存
];
}
$rt = array_merge($formatResult, $rt);
usleep(550);
} while (count($result) == 100);
return $rt;
}
public function findAllInneropenItemBySkuId(string $skuIds): array
{
return $this->getInneropenStockAndDetailList($skuIds);
}
public function getInneropenList(int $status = 2): array
{
$rt = $this->post('open/api/company/inneropen/partner/channel/querymysupplier', [
'page_num' => 1,
'page_size' => 100,
])['data']['supplier_vos'];
$rtr = [];
foreach ($rt as $inneropen) {
if ($inneropen['status'] == $status) {
$rtr[] = $inneropen;
}
}
return $rtr;
}
public function getSyncProduct(): \app\haichao\sync\JstProductSync
{
return new \app\haichao\sync\JstProductSync();
}
public function getSyncStork(): \app\haichao\sync\JstStorkSync
{
return new \app\haichao\sync\JstStorkSync();
}
}