【程序目录】商品采集,积分商品,运费计算优化

This commit is contained in:
evoxwht 2022-04-27 11:41:36 +08:00
parent 7f9a5c2f69
commit a3d74411db
6 changed files with 134 additions and 194 deletions

View File

@ -13,7 +13,11 @@ namespace app\jobs;
use app\services\product\product\CopyTaobaoServices;
use app\services\product\product\StoreDescriptionServices;
use app\services\product\product\StoreProductServices;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\basic\BaseJobs;
use crmeb\services\CacheService;
use crmeb\traits\QueueTrait;
use think\facade\Log;
@ -31,12 +35,34 @@ class ProductCopyJob extends BaseJobs
* @param $id
* @return bool
*/
public function copyDescriptionImage($id)
public function copyDescriptionImage($id, $description, $image, $count)
{
try {
/** @var CopyTaobaoServices $copyTaobao */
$copyTaobao = app()->make(CopyTaobaoServices::class);
$copyTaobao->uploadDescriptionImage((int)$id);
/** @var StoreDescriptionServices $storeDescriptionServices */
$storeDescriptionServices = app()->make(StoreDescriptionServices::class);
if (is_int(strpos($image, 'http'))) {
$d_image = $image;
} else {
$d_image = 'http://' . ltrim($image, '\//');
}
$description_cache = CacheService::getTokenBucket('desc_images_' . $id);
if ($description_cache === null) {
$description_cache = $description;
CacheService::setTokenBucket('desc_images_count' . $id, 0);
}
$res = $copyTaobao->downloadCopyImage($d_image);
$description_cache = str_replace($image, $res, $description_cache);
$desc_count = CacheService::getTokenBucket('desc_images_count' . $id) + 1;
if ($desc_count == $count) {
CacheService::clearToken('desc_images_' . $id);
CacheService::clearToken('desc_images_count' . $id);
$storeDescriptionServices->saveDescription((int)$id, $description_cache);
} else {
CacheService::setTokenBucket('desc_images_' . $id, $description_cache);
CacheService::setTokenBucket('desc_images_count' . $id, $desc_count);
}
} catch (\Throwable $e) {
Log::error('下载商品详情图片失败,失败原因:' . $e->getMessage());
}
@ -48,12 +74,33 @@ class ProductCopyJob extends BaseJobs
* @param $id
* @return bool
*/
public function copySliderImage($id)
public function copySliderImage($id, $image, $count)
{
try {
/** @var CopyTaobaoServices $copyTaobao */
$copyTaobao = app()->make(CopyTaobaoServices::class);
$copyTaobao->uploadSliderImage((int)$id);
/** @var StoreProductServices $StoreProductServices */
$StoreProductServices = app()->make(StoreProductServices::class);
/** @var StoreProductAttrValueServices $StoreProductAttrValueServices */
$StoreProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
//下载图片
$res = $copyTaobao->downloadCopyImage($image);
//获取缓存中的轮播图
$slider_images = CacheService::getTokenBucket('slider_images_' . $id);
//缓存为null则赋值[]
if ($slider_images === null) $slider_images = [];
//将下载的图片插入数组
array_push($slider_images, $res);
//如果$slider_images中图片数量和传入的$count相等,说明已经下载完成,写入商品表,如果不等则继续插入缓存
if (count($slider_images) == $count) {
CacheService::clearToken('slider_images_' . $id);
$image = $slider_images[0];
$slider_images = $slider_images ? json_encode($slider_images) : '';
$StoreProductServices->update($id, ['slider_image' => $slider_images, 'image' => $image]);
$StoreProductAttrValueServices->update(['product_id' => $id], ['image' => $image]);
} else {
CacheService::setTokenBucket('slider_images_' . $id, $slider_images);
}
} catch (\Throwable $e) {
Log::error('下载商品轮播图片失败,失败原因:' . $e->getMessage());
}

View File

@ -214,7 +214,7 @@ class StoreIntegralServices extends BaseServices
$header[] = ['title' => $item['value'], 'key' => 'value' . ($key + 1), 'align' => 'center', 'minWidth' => 80];
}
$header[] = ['title' => '图片', 'slot' => 'pic', 'align' => 'center', 'minWidth' => 120];
$header[] = ['title' => '兑换积分', 'slot' => 'price', 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '兑换积分', 'key' => 'price', 'type' => 1, 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '库存', 'key' => 'stock', 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '兑换次数', 'key' => 'quota', 'type' => 1, 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '重量(KG)', 'key' => 'weight', 'align' => 'center', 'minWidth' => 80];
@ -245,7 +245,7 @@ class StoreIntegralServices extends BaseServices
foreach ($detail as $k => $v) {
$valueNew[$count]['value' . ($k + 1)] = $v;
}
$valueNew[$count]['detail'] = json_encode(array_combine($head,$detail));
$valueNew[$count]['detail'] = json_encode(array_combine($head, $detail));
$valueNew[$count]['pic'] = $sukValue[$suk]['pic'] ?? '';
$valueNew[$count]['price'] = $sukValue[$suk]['price'] ? floatval($sukValue[$suk]['price']) : 0;
$valueNew[$count]['cost'] = $sukValue[$suk]['cost'] ? floatval($sukValue[$suk]['cost']) : 0;

View File

@ -259,6 +259,7 @@ class StoreCartServices extends BaseServices
$info['cart_num'] = $cart_num;
$info['productInfo'] = $productInfo ? $productInfo->toArray() : [];
$info['productInfo']['attrInfo'] = $attrInfo->toArray();
$info['attrInfo'] = $attrInfo->toArray();
$info['sum_price'] = $info['productInfo']['attrInfo']['price'];
//砍价
if ($bargain_id) {

View File

@ -474,22 +474,26 @@ class StoreOrderComputedServices extends BaseServices
}
$tempId = $item['productInfo']['temp_id'] ?? 0;
$tempPostage = $truePostageArr[$tempId] ?? 0;
$type = $temp_num[$tempId]['type'];
$tempNumber = $temp_num[$tempId]['number'] ?? 0;
if (!$tempId || !$tempPostage || !$tempNumber) continue;
$cartNumber = $item['cart_num'];
if ((($cartAlready[$tempId]['number'] ?? 0) + $cartNumber) >= $tempNumber) {
$price = isset($cartAlready[$tempId]['price']) ? bcsub((string)$tempPostage, (string)$cartAlready[$tempId]['price'], 6) : $tempPostage;
} else {
$price = bcmul((string)$tempPostage, bcdiv((string)$cartNumber, (string)$tempNumber, 6), 6);
}
$cartAlready[$tempId]['number'] = bcadd((string)($cartNumber[$tempId]['number'] ?? 0), (string)$cartNumber, 4);
$cartAlready[$tempId]['price'] = bcadd((string)($cartNumber[$tempId]['price'] ?? 0.00), (string)$price, 4);
if ($express_rule_number && $express_rule_number < 100) {
$price = bcmul($price, bcdiv($express_rule_number, 100, 4), 4);
}
if ($type == 2) {
$price = bcmul($price, $item['productInfo']['attrInfo']['weight'], 6);
} elseif ($type == 3) {
$price = bcmul($price, $item['productInfo']['attrInfo']['volume'], 6);
}
$price = sprintf("%.2f", $price);
$item['postage_price'] = $price;
}

View File

@ -232,181 +232,6 @@ class CopyTaobaoServices extends BaseServices
return true;
}
/**
* 下载商品轮播图片
* @param int $id
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function uploadSliderImage(int $id)
{
//查询附件分类
/** @var SystemAttachmentCategoryServices $systemAttachmentCategoryService */
$systemAttachmentCategoryService = app()->make(SystemAttachmentCategoryServices::class);
/** @var StoreProductServices $StoreProductServices */
$StoreProductServices = app()->make(StoreProductServices::class);
/** @var StoreProductAttrValueServices $StoreProductAttrValueServices */
$StoreProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
$AttachmentCategory = $systemAttachmentCategoryService->getOne(['name' => $this->AttachmentCategoryName]);
//不存在则创建
if (!$AttachmentCategory) $AttachmentCategory = $systemAttachmentCategoryService->save(['pid' => '0', 'name' => $this->AttachmentCategoryName, 'enname' => '']);
//生成附件目录
try {
if (make_path('attach', 3, true) === '')
throw new AdminException('无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS);
} catch (\Exception $e) {
throw new AdminException($e->getMessage() . '或无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS);
}
$slider_image = $StoreProductServices->value(['id' => $id], 'slider_image');
$slider_image = $slider_image ? json_decode($slider_image, true) : [];
$images = [];
//放入轮播图
foreach ($slider_image as $item) {
$value = ['w' => 640, 'h' => 640, 'line' => $item, 'valuename' => 'slider_image', 'isTwoArray' => true];
array_push($images, $value);
}
$res = $this->uploadImage($images, false, 0, $AttachmentCategory['id']);
if (!is_array($res)) throw new AdminException($this->errorInfo ? $this->errorInfo : '保存图片失败');
if (isset($res['slider_image'])) $slider_images = $res['slider_image'];
if (count($slider_images)) {
$slider_images = array_map(function ($item) {
$item = str_replace('\\', '/', $item);
return $item;
}, $slider_images);
}
$image = $slider_images[0];
$slider_images = $slider_images ? json_encode($slider_images) : '';
$StoreProductServices->update($id, ['slider_image' => $slider_images, 'image' => $image]);
$StoreProductAttrValueServices->update(['product_id' => $id], ['image' => $image]);
return true;
}
// /**
// * 保存数据
// * @param array $data
// * @throws \think\db\exception\DataNotFoundException
// * @throws \think\db\exception\DbException
// * @throws \think\db\exception\ModelNotFoundException
// */
// public function save(array $data)
// {
// $detail = $data['attrs'];
// $attrs = $data['items'];
// $data['spec_type'] = $data['attrs'] ? 1 : 0;
// if (count($detail)) {
// $data['price'] = min(array_column($detail, 'price'));
// $data['ot_price'] = min(array_column($detail, 'ot_price'));
// $data['cost'] = min(array_column($detail, 'cost'));
// $data['stock'] = array_sum(array_column($detail, 'stock'));
// }
// unset($data['attrs'], $data['items'], $data['info']);
// if (!$data['cate_id']) throw new AdminException('请选择分类!');
// if (!$data['store_name']) throw new AdminException('请填写商品名称');
// if (!$data['unit_name']) throw new AdminException('请填写商品单位');
// if (!$data['temp_id']) throw new AdminException('请选择运费模板');
// //查询附件分类
// /** @var SystemAttachmentCategoryServices $systemAttachmentCategoryService */
// $systemAttachmentCategoryService = app()->make(SystemAttachmentCategoryServices::class);
// $AttachmentCategory = $systemAttachmentCategoryService->getOne(['name' => $this->AttachmentCategoryName]);
// //不存在则创建
// if (!$AttachmentCategory) $AttachmentCategory = $systemAttachmentCategoryService->save(['pid' => '0', 'name' => $this->AttachmentCategoryName, 'enname' => '']);
// //生成附件目录
// try {
// if (make_path('attach', 3, true) === '')
// throw new AdminException('无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS);
//
// } catch (\Exception $e) {
// throw new AdminException($e->getMessage() . '或无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS);
// }
// ini_set("max_execution_time", '600');
// /** @var StoreProductServices $storeProductServices */
// $storeProductServices = app()->make(StoreProductServices::class);
// /** @var StoreDescriptionServices $storeDescriptionServices */
// $storeDescriptionServices = app()->make(StoreDescriptionServices::class);
// /** @var StoreProductCateServices $storeProductCateServices */
// $storeProductCateServices = app()->make(StoreProductCateServices::class);
// /** @var StoreProductAttrServices $storeProductAttrServices */
// $storeProductAttrServices = app()->make(StoreProductAttrServices::class);
// /** @var StoreProductCouponServices $storeProductCouponServices */
// $storeProductCouponServices = app()->make(StoreProductCouponServices::class);
// /** @var StoreCategoryServices $storeCategoryServices */
// $storeCategoryServices = app()->make(StoreCategoryServices::class);
// //开始图片下载处理
// $this->transaction(function () use ($attrs, $detail, $data, $AttachmentCategory, $storeCategoryServices, $storeProductServices, $storeDescriptionServices, $storeProductCateServices, $storeProductAttrServices, $storeProductCouponServices) {
// //放入主图
// $images = [
// ['w' => 305, 'h' => 305, 'line' => $data['image'], 'valuename' => 'image']
// ];
// //放入轮播图
// foreach ($data['slider_image'] as $item) {
// $value = ['w' => 640, 'h' => 640, 'line' => $item, 'valuename' => 'slider_image', 'isTwoArray' => true];
// array_push($images, $value);
// }
// //执行下载
// $res = $this->uploadImage($images, false, 0, $AttachmentCategory['id']);
// if (!is_array($res)) throw new AdminException($this->errorInfo ?: '保存图片失败');
// if (isset($res['image'])) $data['image'] = $res['image'];
// if (isset($res['slider_image'])) $data['slider_image'] = $res['slider_image'];
// $data['image'] = str_replace('\\', '/', $data['image']);
// if (count($data['slider_image'])) {
// $data['slider_image'] = array_map(function ($item) {
// $item = str_replace('\\', '/', $item);
// return $item;
// }, $data['slider_image']);
// }
// $data['slider_image'] = count($data['slider_image']) ? json_encode($data['slider_image']) : '';
// //替换并下载详情里面的图片默认下载全部图片
// $data['description'] = preg_replace('#<style>.*?</style>#is', '', $data['description']);
// $data['description'] = $this->uploadImage($data['description_images'], $data['description'], 1, $AttachmentCategory['id']);
// unset($data['description_images']);
// $description = $data['description'];
// unset($data['description']);
// $data['add_time'] = time();
// $cate_id = $data['cate_id'];
// $data['cate_id'] = implode(',', $data['cate_id']);
// $productInfo = $storeProductServices->getOne(['soure_link' => $data['soure_link']]);
// if ($productInfo) {
// $productInfo->slider_image = $data['slider_image'];
// $productInfo->image = $data['image'];
// $productInfo->store_name = $data['store_name'];
// $res = $storeProductServices->update($productInfo->id, $data);
// if (!$res) throw new AdminException('保存失败');
// $storeDescriptionServices->saveDescription($productInfo->id, $description);
// } else {
// $data['code_path'] = '';
// $data['spu'] = $this->createSpu();
// if ($data['spec_type'] == 0) {
// $attrs = [
// [
// 'value' => '规格',
// 'detailValue' => '',
// 'attrHidden' => '',
// 'detail' => ['默认']
// ]
// ];
// $detail[0]['value1'] = '规格';
// $detail[0]['detail'] = ['规格' => '默认'];
// }
// $res = $storeProductServices->create($data);
// $storeDescriptionServices->saveDescription((int)$res['id'], $description);
// $cateData = [];
// $time = time();
// $cateGory = $storeCategoryServices->getColumn([['id', 'IN', $cate_id]], 'id,pid', 'id');
// foreach ($cate_id as $cid) {
// if ($cid && isset($cateGory[$cid]['pid'])) {
// $cateData[] = ['product_id' => $res['id'], 'cate_id' => $cid, 'cate_pid' => $cateGory[$cid]['pid'], 'status' => $data['is_show'], 'add_time' => $time];
// }
// }
// $storeProductCateServices->change($res['id'], $cateData);
// $skuList = $storeProductServices->validateProductAttr($attrs, $detail, (int)$res['id']);
// $attrRes = $storeProductAttrServices->saveProductAttr($skuList, (int)$res['id'], 0);
// if (!empty($coupon_ids)) $storeProductCouponServices->setCoupon((int)$res['id'], $coupon_ids);
// if (!$attrRes) throw new AdminException('添加失败!');
// }
// });
// }
/**
* 上传图片处理
* @param array $images
@ -599,4 +424,58 @@ class CopyTaobaoServices extends BaseServices
{
return substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8) . str_pad((string)mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}
/**
* 下载远程图片并上传
* @param $image
* @return false|mixed|string
* @throws \Exception
*/
public function downloadCopyImage($image)
{
//查询附件分类
/** @var SystemAttachmentCategoryServices $systemAttachmentCategoryService */
$attachmentCategoryService = app()->make(SystemAttachmentCategoryServices::class);
$AttachmentCategory = $attachmentCategoryService->getOne(['name' => '远程下载']);
//不存在则创建
if (!$AttachmentCategory) {
$AttachmentCategory = $systemAttachmentCategoryService->save(['pid' => '0', 'name' => '远程下载', 'enname' => '']);
}
//生成附件目录
if (make_path('attach', 3, true) === '') {
throw new AdminException('无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS);
}
//上传图片
/** @var SystemAttachmentServices $systemAttachmentService */
$systemAttachmentService = app()->make(SystemAttachmentServices::class);
$siteUrl = sys_config('site_url');
$uploadValue = $this->downloadImage($image);
if (is_array($uploadValue)) {
//TODO 拼接图片地址
if ($uploadValue['image_type'] == 1) {
$imagePath = $siteUrl . $uploadValue['path'];
} else {
$imagePath = $uploadValue['path'];
}
//写入数据库
if (!$uploadValue['is_exists'] && $AttachmentCategory['id']) {
$systemAttachmentService->save([
'name' => $uploadValue['name'],
'real_name' => $uploadValue['name'],
'att_dir' => $imagePath,
'satt_dir' => $imagePath,
'att_size' => $uploadValue['size'],
'att_type' => $uploadValue['mime'],
'image_type' => $uploadValue['image_type'],
'module_type' => 1,
'time' => time(),
'pid' => $AttachmentCategory['id']
]);
}
return $imagePath;
}
return false;
}
}

View File

@ -377,8 +377,8 @@ class StoreProductServices extends BaseServices
$valueNew = [];
$count = 0;
foreach ($value as $suk) {
$detail = explode(',', $suk);
foreach ($value as $suk) {
$detail = explode(',', $suk);
$types = 1;
if ($id) {
@ -423,7 +423,7 @@ class StoreProductServices extends BaseServices
$sukValue[$suk]['brokerage_two'] = 0;
}
if ($types) { //编辑商品时,将没有规格的数据不生成默认值
foreach ($head as $k => $title) {
foreach ($head as $k => $title) {
$header[$k]['title'] = $title;
$header[$k]['align'] = 'center';
$header[$k]['minWidth'] = 130;
@ -432,7 +432,7 @@ class StoreProductServices extends BaseServices
$valueNew[$count]['value' . ($k + 1)] = $v;
$header[$k]['key'] = 'value' . ($k + 1);
}
$valueNew[$count]['detail'] = array_combine($head,$detail);
$valueNew[$count]['detail'] = array_combine($head, $detail);
$valueNew[$count]['pic'] = $sukValue[$suk]['pic'] ?? '';
$valueNew[$count]['price'] = $sukValue[$suk]['price'] ? floatval($sukValue[$suk]['price']) : 0;
$valueNew[$count]['cost'] = $sukValue[$suk]['cost'] ? floatval($sukValue[$suk]['cost']) : 0;
@ -555,6 +555,7 @@ class StoreProductServices extends BaseServices
}
$data['cate_id'] = implode(',', $data['cate_id']);
$data['label_id'] = implode(',', $data['label_id']);
$slider_image = $data['slider_image'];
$data['image'] = $data['slider_image'][0];
$data['slider_image'] = json_encode($data['slider_image']);
$data['stock'] = array_sum(array_column($detail, 'stock'));
@ -575,7 +576,7 @@ class StoreProductServices extends BaseServices
if (isset($data['description_images'])) {
$descriptionImages = $data['description_images'];
}
$this->transaction(function () use ($id, $is_copy, $data, $descriptionImages, $description, $cate_id, $storeDescriptionServices, $storeProductCateServices, $storeProductAttrServices, $storeProductCouponServices, $storeCategoryServices, $detail, $attr, $coupon_ids, $type) {
$this->transaction(function () use ($id, $is_copy, $data, $descriptionImages, $description, $cate_id, $storeDescriptionServices, $storeProductCateServices, $storeProductAttrServices, $storeProductCouponServices, $storeCategoryServices, $detail, $attr, $coupon_ids, $type, $slider_image) {
if ($data['spec_type'] == 0) {
$attr = [
[
@ -639,11 +640,18 @@ class StoreProductServices extends BaseServices
$attrRes = $storeProductAttrServices->saveProductAttr($skuList, $res->id, 0, $data['is_vip'], $data['virtual_type']);
if (!empty($coupon_ids)) $storeProductCouponServices->setCoupon($res->id, $coupon_ids);
if (!$attrRes) throw new AdminException('添加失败!');
//采集商品下载图片
if ($type == -1) {
//下载商品详情图片
ProductCopyJob::dispatchDo('copyDescriptionImage', [$res->id]);
//下载商品轮播图片
ProductCopyJob::dispatchDo('copySliderImage', [$res->id]);
//下载商品轮播图
foreach ($slider_image as $s_image) {
ProductCopyJob::dispatchDo('copySliderImage', [$res->id, $s_image, count($slider_image)]);
}
preg_match_all('#<img.*?src="([^"]*)"[^>]*>#i', $description, $match);
foreach ($match[1] as $d_image) {
ProductCopyJob::dispatchDo('copyDescriptionImage', [$res->id, $description, $d_image, count($match[1])]);
}
}
}
});
@ -921,7 +929,7 @@ class StoreProductServices extends BaseServices
$header[] = ['title' => '成本价', 'key' => 'cost', 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '日常售价', 'key' => 'r_price', 'align' => 'center', 'minWidth' => 80];
} elseif ($type == 4) {
$header[] = ['title' => '兑换积分', 'slot' => 'price', 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '兑换积分', 'key' => 'price', 'type' => 1, 'align' => 'center', 'minWidth' => 80];
} elseif ($type == 6) {
$header[] = ['title' => '预售价', 'key' => 'price', 'type' => 1, 'align' => 'center', 'minWidth' => 80];
$header[] = ['title' => '成本价', 'key' => 'cost', 'align' => 'center', 'minWidth' => 80];
@ -1258,7 +1266,7 @@ class StoreProductServices extends BaseServices
$storeInfo['userCollect'] = $storeProductRelationServices->isProductRelation(['uid' => $uid, 'product_id' => $id, 'type' => 'collect', 'category' => 'product']);
$storeInfo['userLike'] = false;
$storeInfo['small_image'] = $storeInfo['image'];
$storeInfo = get_thumb_water($storeInfo, 'big', ['image', 'slider_image', 'small_image']);
$storeInfo = get_thumb_water($storeInfo, 'small', ['small_image']);
//预售相关
if ($storeInfo['presale']) {
@ -1322,6 +1330,7 @@ class StoreProductServices extends BaseServices
/** @var MemberCardServices $memberCardService */
$memberCardService = app()->make(MemberCardServices::class);
$data['svip_open'] = $vipStatus = $memberCardService->isOpenMemberCard('vip_price');
$data['svip_price_open'] = (int)sys_config('member_price_status');
$data['storeInfo']['svip_economize_price'] = bcsub((string)$data['storeInfo']['price'], (string)$data['storeInfo']['vip_price'], 2);
if (!$this->vipIsOpen(!!$storeInfo['is_vip'], $vipStatus)) {
$data['storeInfo']['vip_price'] = 0;