mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 13:31:04 +00:00
fix(商品导出): 修正一级分类上提与轮播图解析,补齐导入产品类型映射
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
4e408874f2
commit
a7a15c49cd
@ -3503,13 +3503,17 @@ class CenterProductServices extends BaseService
|
||||
$productAttr = $specs['productAttr'] ?? [];
|
||||
$productValue = $specs['productValue'] ?? [];
|
||||
|
||||
$cateName = array_filter($cateList, function ($val) use ($productInfo) {
|
||||
if (in_array($val['id'], explode(',', $productInfo['cate_id']))) {
|
||||
return $val;
|
||||
}
|
||||
});
|
||||
if (count($cateName) == 1 && is_null($cateName[0]['one'])) {
|
||||
$cateName = [['one' => $cateName[0]['two'], 'two' => '', 'id' => $cateName[0]['id']]];
|
||||
$cateMatched = array_values(array_filter($cateList, function ($val) use ($productInfo) {
|
||||
return in_array($val['id'], explode(',', (string)($productInfo['cate_id'] ?? '')), false);
|
||||
}));
|
||||
$cateRow = $cateMatched[0] ?? null;
|
||||
// 仅挂一级分类时 one 为空、名称在 two,导出时上提到一级列
|
||||
if ($cateRow && ($cateRow['one'] ?? null) === null) {
|
||||
$cateNameOne = (string)($cateRow['two'] ?? '');
|
||||
$cateNameTwo = '';
|
||||
} else {
|
||||
$cateNameOne = (string)($cateRow['one'] ?? '');
|
||||
$cateNameTwo = (string)($cateRow['two'] ?? '');
|
||||
}
|
||||
|
||||
// 构造规格类型值字符串
|
||||
@ -3520,22 +3524,44 @@ class CenterProductServices extends BaseService
|
||||
}
|
||||
$attrString = implode(';', $attrArr);
|
||||
|
||||
$sliderImage = $productInfo['slider_image'] ?? [];
|
||||
if (!is_array($sliderImage)) {
|
||||
$sliderImage = $sliderImage !== '' && $sliderImage !== null
|
||||
? (array)json_decode((string)$sliderImage, true)
|
||||
: [];
|
||||
if (!$sliderImage) {
|
||||
$sliderImage = array_filter(explode(',', (string)($productInfo['slider_image'] ?? '')));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($productValue as $unique => $value) {
|
||||
$detail = $value['detail'] ?? ($value['suk'] ? array_map('trim', explode(',', $value['suk'])) : ['默认']);
|
||||
if (!is_array($detail)) {
|
||||
$detail = ['默认'];
|
||||
}
|
||||
// detail 可能是关联数组(规格名=>值),按 productAttr 顺序取值
|
||||
if ($detail !== [] && !array_is_list($detail)) {
|
||||
$ordered = [];
|
||||
foreach ($productAttr as $attrItem) {
|
||||
$attrName = $attrItem['attr_name'] ?? '';
|
||||
$ordered[] = $detail[$attrName] ?? '';
|
||||
}
|
||||
$detail = $ordered ?: array_values($detail);
|
||||
}
|
||||
$skuArr = [];
|
||||
foreach ($productAttr as $index => $attrItem) {
|
||||
$attrName = $attrItem['attr_name'] ?? ('规格' . ($index + 1));
|
||||
$skuArr[$attrName] = $detail[$index] ?? '';
|
||||
}
|
||||
// 字段顺序必须与上方 $header / 导入模板一一对应,禁止多插 type_name 等列
|
||||
$one_data = [
|
||||
'id' => intval($product_id),
|
||||
'store_name' => $productInfo['name'],
|
||||
'product_type' => $productInfo['product_type'] ?? 'normal',
|
||||
'type_name' => $this->getProductTypeName($productInfo['product_type'] ?? 'normal'),
|
||||
'cate_name_one' => reset($cateName)['one'] ?? '',
|
||||
'cate_name_two' => reset($cateName)['two'] ?? '',
|
||||
'product_type' => $this->getProductTypeName($productInfo['product_type'] ?? 'normal'),
|
||||
'cate_name_one' => $cateNameOne,
|
||||
'cate_name_two' => $cateNameTwo,
|
||||
'unit_name' => $productInfo['unit_name'],
|
||||
'slider_image' => implode(';', $productInfo['slider_image']),
|
||||
'slider_image' => implode(';', $sliderImage),
|
||||
'video_link' => $productInfo['video_link'],
|
||||
'description' => htmlspecialchars_decode($descriptionArr[$productInfo['id']] ?? ''),
|
||||
'ficti' => intval($productInfo['virtual_sales'] ?? 0),
|
||||
@ -3543,16 +3569,16 @@ class CenterProductServices extends BaseService
|
||||
'spec_type' => intval($productInfo['spec_type']) == 1 ? '多规格' : '单规格',
|
||||
'sku_type_value' => $attrString,
|
||||
'sku_name' => implode(',', $detail),
|
||||
'sku_value' => implode(';', array_map(function ($key, $value) {
|
||||
return "$key=$value";
|
||||
'sku_value' => implode(';', array_map(function ($key, $val) {
|
||||
return "$key=$val";
|
||||
}, array_keys($skuArr), $skuArr)),
|
||||
'pic' => $value['image'] ?? '',
|
||||
'price' => floatval($value['price'] ?? 0),
|
||||
'ot_price' => floatval($value['ot_price'] ?? 0),
|
||||
'cost' => floatval($value['cost'] ?? 0),
|
||||
'stock' => intval($value['stock'] ?? 0),
|
||||
'volume' => intval($value['volume'] ?? 0),
|
||||
'weight' => intval($value['weight'] ?? 0),
|
||||
'volume' => intval($value['volume'] ?? 0),
|
||||
'bar_code' => $value['bar_code'] ?? '',
|
||||
'bar_code_number' => $value['bar_code_number'] ?? '',
|
||||
'store_info' => $productInfo['intro'],
|
||||
@ -3592,9 +3618,51 @@ class CenterProductServices extends BaseService
|
||||
$barCodeArr = array_unique((is_array($barCodeResults) && $barCodeResults[0] !== null) ? $barCodeResults[0] : []);
|
||||
$barCodeNumberResults = event('ProductTypeDataProxy', ['product_type' => 'normal', 'action' => 'getColumn', 'args' => [[], 'bar_code_number', 'id']]);
|
||||
$barCodeNumberArr = array_unique((is_array($barCodeNumberResults) && $barCodeNumberResults[0] !== null) ? $barCodeNumberResults[0] : []);
|
||||
// 导出写中文类型名,导入需还原为注册中心 typeKey;兼容直接写 normal/cardkey/virtual
|
||||
$resolveProductType = function ($raw): string {
|
||||
$raw = trim((string)$raw);
|
||||
if ($raw === '') {
|
||||
return 'normal';
|
||||
}
|
||||
/** @var ProductTypeRegistry $registry */
|
||||
$registry = app()->make(ProductTypeRegistry::class);
|
||||
if ($registry->has($raw)) {
|
||||
return $raw;
|
||||
}
|
||||
foreach ($registry->all() as $typeKey) {
|
||||
if ($registry->get((string)$typeKey)->getTypeName() === $raw) {
|
||||
return (string)$typeKey;
|
||||
}
|
||||
}
|
||||
// 历史别名
|
||||
$alias = [
|
||||
'普通商品' => 'normal',
|
||||
'实物' => 'normal',
|
||||
'卡密/网盘' => 'cardkey',
|
||||
'卡密' => 'cardkey',
|
||||
'虚拟商品' => 'virtual',
|
||||
'虚拟' => 'virtual',
|
||||
'网盘' => 'virtual',
|
||||
'优惠券' => 'normal',
|
||||
];
|
||||
return $alias[$raw] ?? 'normal';
|
||||
};
|
||||
|
||||
foreach ($importData as $sku) {
|
||||
if ($sku['id'] == null) continue;
|
||||
if ($sku['id'] === null || $sku['id'] === '') {
|
||||
continue;
|
||||
}
|
||||
$barCode = trim((string)($sku['bar_code'] ?? ''));
|
||||
$barCodeNumber = trim((string)($sku['bar_code_number'] ?? ''));
|
||||
// 仅非空条码做唯一性拦截;库中大量空串时 in_array('', ...) 会误伤全部无码商品
|
||||
if ($barCode !== '' && in_array($barCode, $barCodeArr, true)) {
|
||||
$issetProductArr[] = $sku['id'];
|
||||
}
|
||||
if ($barCodeNumber !== '' && in_array($barCodeNumber, $barCodeNumberArr, true)) {
|
||||
$issetProductArr[] = $sku['id'];
|
||||
}
|
||||
if (!isset($productData[$sku['id']])) {
|
||||
$sliderRaw = trim((string)($sku['slider_image'] ?? ''));
|
||||
$productData[$sku['id']]['disk_info'] = '';
|
||||
$productData[$sku['id']]['logistics'] = [1, 2];
|
||||
$productData[$sku['id']]['freight'] = 2;
|
||||
@ -3604,17 +3672,20 @@ class CenterProductServices extends BaseService
|
||||
$productData[$sku['id']]['is_limit'] = 0;
|
||||
$productData[$sku['id']]['limit_type'] = 0;
|
||||
$productData[$sku['id']]['limit_num'] = 0;
|
||||
$productData[$sku['id']]['video_open'] = $sku['video_link'] !== '' ? 1 : 0;
|
||||
$productData[$sku['id']]['video_open'] = ($sku['video_link'] ?? '') !== '' ? 1 : 0;
|
||||
$productData[$sku['id']]['vip_product'] = 0;
|
||||
$productData[$sku['id']]['custom_form'] = [];
|
||||
$productData[$sku['id']]['store_name'] = $sku['store_name'];
|
||||
$productData[$sku['id']]['cate_id'] = $productCateServices->getCateId($sku['cate_name_one'] ?? '', $sku['cate_name_two'] ?? '');
|
||||
$productData[$sku['id']]['cate_id'] = $productCateServices->getCateId(
|
||||
(string)($sku['cate_name_one'] ?? ''),
|
||||
(string)($sku['cate_name_two'] ?? '')
|
||||
);
|
||||
$productData[$sku['id']]['keyword'] = $sku['keyword'] ?? '';
|
||||
$productData[$sku['id']]['unit_name'] = $sku['unit_name'] ?? '';
|
||||
$productData[$sku['id']]['store_info'] = $sku['store_info'] ?? '';
|
||||
$productData[$sku['id']]['image'] = '';
|
||||
$productData[$sku['id']]['recommend_image'] = '';
|
||||
$productData[$sku['id']]['slider_image'] = explode(';', $sku['slider_image']);
|
||||
$productData[$sku['id']]['slider_image'] = $sliderRaw === '' ? [] : array_values(array_filter(explode(';', $sliderRaw)));
|
||||
$productData[$sku['id']]['description'] = $sku['description'] ?? '';
|
||||
$productData[$sku['id']]['ficti'] = $sku['ficti'] ?? 0;
|
||||
$productData[$sku['id']]['give_integral'] = $sku['give_integral'] ?? 0;
|
||||
@ -3624,16 +3695,16 @@ class CenterProductServices extends BaseService
|
||||
$productData[$sku['id']]['is_sub'] = 0;
|
||||
$productData[$sku['id']]['is_vip'] = 0;
|
||||
$productData[$sku['id']]['recommend_list'] = [];
|
||||
$productData[$sku['id']]['product_type'] = $sku['product_type'] ?? 'normal';
|
||||
$productData[$sku['id']]['spec_type'] = $sku['spec_type'] == '多规格' ? 1 : 0;
|
||||
$productData[$sku['id']]['product_type'] = $resolveProductType($sku['product_type'] ?? 'normal');
|
||||
$productData[$sku['id']]['spec_type'] = ($sku['spec_type'] ?? '') == '多规格' ? 1 : 0;
|
||||
$productData[$sku['id']]['is_virtual'] = 0;
|
||||
$productData[$sku['id']]['video_link'] = is_null($sku['video_link']) ? '' : $sku['video_link'];
|
||||
$productData[$sku['id']]['video_link'] = (string)($sku['video_link'] ?? '');
|
||||
$productData[$sku['id']]['temp_id'] = '';
|
||||
$productData[$sku['id']]['activity'] = ['默认', '秒杀', '砍价', '拼团'];
|
||||
$productData[$sku['id']]['couponName'] = [];
|
||||
$productData[$sku['id']]['coupon_ids'] = [];
|
||||
$productData[$sku['id']]['command_word'] = $sku['command_word'] ?? '';
|
||||
$productData[$sku['id']]['min_qty'] = $sku['min_qty'];
|
||||
$productData[$sku['id']]['min_qty'] = $sku['min_qty'] !== '' && $sku['min_qty'] !== null ? $sku['min_qty'] : 1;
|
||||
$productData[$sku['id']]['type'] = 0;
|
||||
$productData[$sku['id']]['is_copy'] = 0;
|
||||
$productData[$sku['id']]['label_id'] = [];
|
||||
@ -3642,19 +3713,21 @@ class CenterProductServices extends BaseService
|
||||
$productData[$sku['id']]['protection_list'] = [];
|
||||
}
|
||||
$detail = [];
|
||||
foreach (explode(';', $sku['sku_value']) as $pair) {
|
||||
list($key, $value) = explode('=', $pair);
|
||||
$detail[$key] = $value;
|
||||
}
|
||||
if ($sku['bar_code'] !== '' && in_array($sku['bar_code'], $barCodeArr)) {
|
||||
$issetProductArr[] = $sku['id'];
|
||||
}
|
||||
if ($sku['bar_code_number'] !== '' && in_array($sku['bar_code_number'], $barCodeNumberArr)) {
|
||||
$issetProductArr[] = $sku['id'];
|
||||
$skuValue = trim((string)($sku['sku_value'] ?? ''));
|
||||
if ($skuValue !== '') {
|
||||
foreach (explode(';', $skuValue) as $pair) {
|
||||
if ($pair === '' || !str_contains($pair, '=')) {
|
||||
continue;
|
||||
}
|
||||
[$key, $value] = explode('=', $pair, 2);
|
||||
$detail[$key] = $value;
|
||||
}
|
||||
}
|
||||
$productData[$sku['id']]['attrs'][] = [
|
||||
'attr_arr' => explode(',', $sku['sku_name']),
|
||||
'detail' => $detail,
|
||||
'attr_arr' => $sku['sku_name'] === '' || $sku['sku_name'] === null
|
||||
? ['默认']
|
||||
: explode(',', (string)$sku['sku_name']),
|
||||
'detail' => $detail ?: ['规格' => '默认'],
|
||||
'price' => $sku['price'],
|
||||
'pic' => $sku['pic'],
|
||||
'ot_price' => $sku['ot_price'] ?? 0,
|
||||
@ -3670,29 +3743,36 @@ class CenterProductServices extends BaseService
|
||||
'unique' => '',
|
||||
'weight' => $sku['weight'],
|
||||
'volume' => $sku['volume'],
|
||||
'bar_code' => $sku['bar_code'],
|
||||
'bar_code_number' => $sku['bar_code_number'],
|
||||
'bar_code' => $barCode,
|
||||
'bar_code_number' => $barCodeNumber,
|
||||
];
|
||||
$items = [];
|
||||
$pairs = explode(';', $sku['sku_type_value']);
|
||||
$skuTypeValue = trim((string)($sku['sku_type_value'] ?? ''));
|
||||
$pairs = $skuTypeValue === '' ? [] : explode(';', $skuTypeValue);
|
||||
foreach ($pairs as $pair) {
|
||||
// 将每个部分按等号分割成 key 和 value
|
||||
list($key, $values) = explode('=', $pair);
|
||||
// 将 value 部分按逗号分割为数组
|
||||
$detailArray = explode(',', $values);
|
||||
if ($pair === '' || !str_contains($pair, '=')) {
|
||||
continue;
|
||||
}
|
||||
[$key, $values] = explode('=', $pair, 2);
|
||||
$detailArray = $values === '' ? [] : explode(',', $values);
|
||||
$detail = [];
|
||||
foreach ($detailArray as &$det) {
|
||||
foreach ($detailArray as $det) {
|
||||
$detail[] = [
|
||||
'value' => $det,
|
||||
'pic' => '',
|
||||
];
|
||||
}
|
||||
// 重新构建原始数组的结构
|
||||
$items[] = [
|
||||
'value' => $key,
|
||||
'detail' => $detail
|
||||
];
|
||||
}
|
||||
if ($items === []) {
|
||||
$items[] = [
|
||||
'value' => '规格',
|
||||
'detail' => [['value' => '默认', 'pic' => '']],
|
||||
];
|
||||
}
|
||||
$productData[$sku['id']]['items'] = $items;
|
||||
}
|
||||
$all = count($productData);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user