caipan_shop_admin/app/repository/SpuRepository.php

926 lines
32 KiB
PHP
Raw Normal View History

2022-05-25 11:35:57 +00:00
<?php
namespace app\repository;
use app\exception\RepositoryException;
use app\model\AccountRecord;
use app\model\mall\Category;
use app\model\mall\SpuCategoryPivot;
use app\model\mall\SpuLimitTime;
use app\model\Order;
use app\model\OrderActivity;
use app\model\OrderGroupList;
use app\model\Sku;
use app\model\sku\SpecParam;
use app\model\sku\SpecValue;
use app\model\Spu;
use app\model\SpuActivity;
use app\service\Repository;
use app\traits\spu\LimitTimeTrait;
use app\traits\spu\SkuTrait;
use Exception;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\facade\Log;
use think\Model;
/**
* Class SpuRepository
* @package app\repository
* @method self getInstance(Model $model = null) static
*/
class SpuRepository extends Repository
{
use SkuTrait;
use LimitTimeTrait;
/**
* 获取商品列表【后台使用】
*
* @param array $params
* @return array
* @throws Exception
*/
public function list(array $params = []): array
{
event('SpuCheck');
$whereMap = [];
$order = $params['order'] ?? ['sort' => 'desc', 'id' => 'desc'];
$type = $params['type'] ?? '';//type为空时 默认为商品管理 包含除积分商品外所有类型
if (!empty($type)) {
$whereMap[] = ['activity_type', '=', $type];
}
switch ($type) {
case Spu::TYPE_NORMAL:
$whereMap[] = ['is_activity', '=', Spu::COMMON_OFF];
$whereMap[] = ['is_score', '=', Spu::COMMON_OFF];
break;
case Spu::TYPE_SCORE:
$whereMap[] = ['is_activity', '=', Spu::COMMON_OFF];
$whereMap[] = ['is_score', '=', Spu::COMMON_ON];
break;
case Spu::TYPE_GROUP_MAKE:
case Spu::TYPE_GROUP_BUY:
case Spu::TYPE_LIMIT_TIME:
$whereMap[] = ['is_activity', '=', Spu::COMMON_ON];
$whereMap[] = ['is_score', '=', Spu::COMMON_OFF];
break;
default:
$whereMap[] = ['is_score', '=', Spu::COMMON_OFF];
// $whereMap[] = ['is_activity', '=', Spu::COMMON_OFF];
}
if (isset($params['saleable'])) {
$whereMap[] = ['saleable', '=', $params['saleable']];
}
if (isset($params['keyword']) && !empty($params['keyword'])) {
$whereMap[] = ['name|subtitle', 'like', '%'.$params['keyword'].'%'];
}
if (isset($params['spu_type']) && !empty($params['spu_type'])) {
$whereMap[] = ['spu_type', '=', $params['spu_type']];
}
$whereMap[] = ['deleted_at', '=', null];
$params['page'] = $params['page'] ?? 1;
$params['size'] = $params['size'] ?? 20;
$fields = $params['fields'] ?? [];
return Spu::findList($whereMap, $fields, $params['page'], $params['size'], null, $order);
}
/**
* 获取活动商品列表【后台使用】
*
* @param array $params
* @return array
* @throws Exception
*/
public function activityList(array $params = []): array
{
$whereMap = [];
$order = $params['order'] ?? ['sort' => 'desc', 'id' => 'desc'];
$type = $params['type'] ?? '';//type为空时 默认为商品管理 包含除积分商品外所有类型
if (!empty($type)) {
$whereMap[] = ['activity_type', '=', $type];
}
if (isset($params['saleable'])) {
$whereMap[] = ['saleable', '=', $params['saleable']];
}
if (isset($params['keyword']) && !empty($params['keyword'])) {
$whereMap[] = ['name|subtitle', 'like', '%'.$params['keyword'].'%'];
}
if (isset($params['spu_type']) && !empty($params['spu_type'])) {
$whereMap[] = ['spu_type', '=', $params['spu_type']];
}
$whereMap[] = ['deleted_at', '=', null];
$params['page'] = $params['page'] ?? 1;
$params['size'] = $params['size'] ?? 20;
$fields = $params['fields'] ?? [];
return SpuActivity::findList($whereMap, $fields, $params['page'], $params['size'], null, $order);
}
/**
* 前端商品列表
*
* @throws Exception
*/
public function listForFront(array $params = [], callable $callback = null, array $order = [], array $where = []): array
{
$page = $params['page'] ?? 1;
$size = $params['size'] ?? 10;
$page = (!is_numeric($page) || $page <= 0) ? 1 : $page;
$size = (!is_numeric($size) || $size <= 0) ? 10 : $size;
event('SpuCheck');
$searchMap = $where;
// 商品名称模糊搜索
if (isset($params['keyword']) && !empty($params['keyword'])) {
$searchMap[] = ['name', 'like', '%'.$params['keyword'].'%'];
}
// 活动类型搜索
if (isset($params['activity']) && !empty($params['activity'])) {
$searchMap[] = ['activity_type', 'in', explode(',', $params['activity'])];
if (!in_array($params['activity'], [Spu::TYPE_NORMAL, Spu::TYPE_SCORE])) {
$searchMap[] = ['is_activity', '=', Spu::COMMON_ON];
}
}
// 价格区间开始
if (isset($params['price_from']) && is_numeric($params['price_from'])) {
$searchMap[] = ['price', '>=', $params['price_from']];
}
// 价格区间结束
if (isset($params['price_to']) && is_numeric($params['price_to'])) {
$searchMap[] = ['price', '<=', $params['price_to']];
}
$searchMap[] = ['saleable', '=', Spu::COMMON_ON];
// 是否积分
if (isset($params['is_score'])) {
$searchMap[] = ['is_score', '=', $params['is_score']];
}
// 是否热门
if (isset($params['is_hot'])) {
$searchMap[] = ['is_hot', '=', $params['is_hot']];
}
// 是否推荐到首页
if (isset($params['is_home']) && in_array($params['is_home'], [0, 1])) {
$searchMap[] = ['is_home', '=', $params['is_home']];
}
// 指定分类
if (isset($params['category_id']) && !empty($params['category_id'])) {
// 多个分类逗号分割
$spuIds = SpuCategoryPivot::whereIn('category_id', explode(',', $params['category_id']))->column('spu_id');
if ($spuIds) {
$searchMap[] = ['id', 'in', array_unique($spuIds)];
}else{
$searchMap[] = ['id', '=', 0];
}
}
$fields = $params['fields'] ?? ['id', 'name', 'price', 'original_price', 'cover', 'activity_type'];
if (empty($order)) {
$order = ['published_at' => 'desc'];
}
2022-05-27 05:55:45 +00:00
2022-05-25 11:35:57 +00:00
$list = Spu::findList($searchMap, $fields, $page, $size, $callback, $order);
$activityText = Spu::activityTextList();
$list['list'] = $list['list']->each(function ($item) use ($activityText) {
2022-05-27 06:04:09 +00:00
$spuSkuList = $this->spuSkuList($item->id);
$item->skuId = $spuSkuList[0]["id"] ?? 0;
2022-05-25 11:35:57 +00:00
$item->tag = $activityText[$item->activity_type] ?? '';
});
return $list;
}
/**
* 内容详情
*
* @param int $id
* @param int $accountId
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws RepositoryException
* @throws Exception
*/
public function detail(int $id, int $accountId = 0): array
{
$field = [
2022-05-27 05:55:45 +00:00
'id', 'activity_id', 'activity_type', 'name', 'subtitle', 'price', 'original_price', 'unit','limit_num', 'cover', 'images',
2022-05-25 11:35:57 +00:00
'share_img', 'is_activity', 'stock', 'amount', 'multi_spec', 'content'
];
if (!$spu = $this->findById($id, $field)) {
throw new RepositoryException('数据不存在');
}
$spu = $spu->toArray();
if ($spu['is_activity'] == Spu::COMMON_ON) {
switch ($spu['activity_type']) {
case SpuLimitTime::TYPE:
$activityInfo = SpuLimitTime::findById($spu['activity_id']);
break;
default:
$activityInfo = null;
}
if (!$activityInfo) {
throw new RepositoryException('活动不存在');
}
if ($activityInfo['status'] != Spu::COMMON_ON) {
throw new RepositoryException('活动已下架');
}
$now = date('Y-m-d H:i:s');
if ($activityInfo['end_at'] < $now || $activityInfo['begin_at'] > $now) {
throw new RepositoryException('不在活动时间内');
}
$spu['name'] = $activityInfo['name'];
$spu['subtitle'] = $activityInfo['subtitle'];
$spu['begin_at'] = $activityInfo['begin_at'];
$spu['end_at'] = $activityInfo['end_at'];
}
if (isset($spu['is_score']) && $spu['is_score']) {
$spu['activity_type'] = Spu::TYPE_NORMAL;
}
$spu['activity_text'] = '';
$spu['tag'] = '';
// 活动标签
if ($spu['is_activity'] && isset($spu['activity_type'])) {
$spu['activity_text'] = Spu::activityTextList()[$spu['activity_type']] ?? '';
$spu['tag'] = Spu::activityTextList()[$spu['activity_type']] ?? '';
}
// 规格列表
$skuList = $spu['is_activity'] == Spu::COMMON_ON ? $this->spuSkuList($spu['activity_id'], $spu['activity_type'], true) : $this->spuSkuList($id);
if ($spu['is_activity'] == Spu::COMMON_ON) {
$default = $skuList->where('is_default', Spu::COMMON_ON)->first();
$spu['original_price'] = $spu['price'];
$spu['price'] = $default['price'];
}
2022-05-27 05:55:45 +00:00
$spu["skuId"] = $skuList[0]["id"] ?? 0;
2022-05-25 11:35:57 +00:00
$res['detail'] = $spu;
// $res['sku'] = $skuList;
return $res;
}
/**
* 获取商品规格列表
*
* @param int $id ID
* @param string $activityType 活动类型 normal=普通 limit_time=限时折扣
* @param bool $isActivity 是否活动
* @return Sku[]|array|Collection
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function spuSkuList(int $id, string $activityType = Spu::TYPE_NORMAL, bool $isActivity = false)
{
$skuFields = ['id', 'coding', 'title', 'stock', 'price', 'original_price', 'score', 'is_default'];
$where = [];
$where[] = ['type', '=', $activityType];
if ($isActivity) {
$where[] = ['spu_activity_id', '=', $id];
} else {
$where[] = ['spu_id', '=', $id];
}
return Sku::where($where)->field($skuFields)->select();
}
/**
* 获取商品 相关产品推荐
*
* @param int $spuId
* @param bool $isScore 是否积分商品
* @param int $page
* @param int $size
* @return mixed
* @throws Exception
*/
public function spuProduct(int $spuId, bool $isScore = false, int $page = 1, int $size = 10)
{
$params = [];
$params['is_score'] = $isScore;
$params['page'] = $page;
$params['size'] = $size;
$params['fields'] = $isScore ? Spu::scoreListFields() : Spu::spuListFields();
return $this->listForFront($params, function ($q) use ($spuId) {
return $q->where('id', '<>', $spuId)->order('published_at', 'desc');
})['list'];
}
/**
* 添加SPU商品信息
*
* @param array $data 基础信息
* @param array $sku 规格信息
* @return Model
* @throws RepositoryException
*/
public function addSpu(array $data, array $sku): Model
{
Db::startTrans();
try {
$now = date('Y-m-d H:i:s');
$data['saleable'] = $data['saleable'] ?? Spu::COMMON_ON;
$data['published_at'] = $data['published_at'] ?? $now;
$data['created_at'] = $now;
if (isset($data['init_amount']) && $data['init_amount'] > 0) {
$data['amount'] += $data['init_amount'];
}
$categoryIds = $data['category_id'] ?? '';
$categoryIds = explode(',', $categoryIds);
$multiSpec = (bool) $data['multi_spec'];
$spu = $this->create($data);
$skuData = $this->handleSku($spu['id'], $sku, [], 'normal', $multiSpec);
(new Sku())->saveAll($skuData['data']);
$spu->save([
'stock' => $skuData['stock'],
'price' => $skuData['price'],
'original_price' => $skuData['original_price'],
'score' => $skuData['score'],
'spec' => json_encode($skuData['spec'], JSON_UNESCAPED_UNICODE)
]);
// 中间表
$this->setCategory($spu->id, $categoryIds);
Db::commit();
return $spu;
} catch (RepositoryException $e) {
// 回滚事务
Db::rollback();
throw $e;
} catch (Exception $e) {
SpuRepository::log($e->getMessage(), $e);
// 回滚事务
Db::rollback();
throw new RepositoryException('商品创建失败');
}
}
/**
* 编辑商品信息
*
* @param int $id
* @param array $data 基础信息
* @param array $sku 规格信息
* @param array $originalSkuList 原始规格列表
* @throws RepositoryException
*/
public function editSpu(int $id, array $data, array $sku, array $originalSkuList)
{
Db::startTrans();
try {
$spu = $this->findById($id);
if (empty($spu)) {
throw new RepositoryException('没有相关的商品记录');
}
if (isset($data['init_amount']) && $data['init_amount'] > 0) {
$data['amount'] = $spu['amount'] - $spu['init_amount'];
$data['amount'] = $data['amount'] > 0 ? $data['amount'] : 0;
$data['amount'] += $data['init_amount'];
}
$now = date('Y-m-d H:i:s');
$data['saleable'] = $data['saleable'] ?? Spu::COMMON_ON;
$data['published_at'] = $data['published_at'] ?? $now;
$data['updated_at'] = $now;
$categoryIds = $data['category_id'] ?? '';
$categoryIds = explode(',', $categoryIds);
$multiSpec = (bool) $data['multi_spec'];
$skuData = $this->handleSku($id, $sku, array_column($originalSkuList, 'id'), 'normal', $multiSpec);
(new Sku())->saveAll($skuData['data']);
(new Sku())->where('id', 'in', $skuData['delete'])->delete();
$data['stock'] = $skuData['stock'];
$data['price'] = $skuData['price'];
$data['original_price'] = $skuData['original_price'];
$data['score'] = $skuData['score'];
$data['spec'] = json_encode($skuData['spec'], JSON_UNESCAPED_UNICODE);
$spu->save($data);
$this->setCategory($id, $categoryIds);
Db::commit();
} catch (RepositoryException $e) {
// 回滚事务
Db::rollback();
throw $e;
} catch (Exception $e) {
// 回滚事务
Db::rollback();
throw new RepositoryException('商品信息修改失败');
}
}
/**
* 删除SPU商品信息 软删除
*
* @param array $ids
* @return bool
* @throws RepositoryException
*/
public function deleteSpu(array $ids): bool
{
try {
return $this->model->whereIn('id', $ids)->save(['deleted_at' => date('Y-m-d H:i:s')]);
} catch (Exception $e) {
throw new RepositoryException('删除失败'.$e->getMessage());
}
}
/**
* 处理SKU数据
*
* @param int $id spu_id或spu_activity_id
* @param array $data
* @param array $originalSkuIds 原始skuID列表
* @param string $type normal=普通商品 limit_time=限时折扣
* @param bool $isMulti 是否多规格 默认是·
* @return array
* @throws RepositoryException
*/
public function handleSku(int $id, array $data, array $originalSkuIds = [], string $type = 'normal', bool $isMulti = true): array
{
if (empty($data)) {
throw new RepositoryException('规格不能为空');
}
$stock = 0;//总库存
$defaultNum = 0;//默认规格数量
$defaultPrice = 0;//默认规格价格
$defaultOriginalPrice = 0;//默认规格原价
$defaultScore = 0;//默认规格积分
$deleteIds = array_diff($originalSkuIds, array_column($data, 'id'));;//待删除待skuID列表
// 获取所有规格值及其相关规格
$specValueList = SpecValue::alias('sv')->leftJoin('spec_param sp', 'sv.spec_id = sp.id')
->where('sv.status', SpecValue::COMMON_ON)
->where('sp.status', SpecParam::COMMON_ON)
->field('sv.id as value_id, sv.title as value_title, sv.spec_id,sp.title as spec_title')
->order('sv.sort', 'desc')
->order('sv.id', 'asc')
->select();
$valueKvList = $isMulti ? $specValueList->column('value_title', 'value_id') : [];
$value2Spec = $isMulti ? $specValueList->column('spec_id', 'value_id') : [];
$value2SpecTitle = $isMulti ? $specValueList->column('spec_title', 'value_id') : [];
$specValueIds = [];// 该商品启用的规格值
// 验证规格
foreach ($data as $key => &$spec) {
// ID为空的表示新增 去掉id字段 saveAll时 自动识别更新或新增
if (empty($spec['id'])) {
unset($spec['id']);
}
if ($isMulti) {
$keys = explode('-', $key);
$spec['indexes'] = $key;
$spec['title'] = '';
$specText = [];
$specValueIds = array_merge($specValueIds, $keys);
foreach ($keys as $k) {
$spec['title'] .= ' '.($valueKvList[$k] ?? '');
$specText[] = [$value2SpecTitle[$k] => $valueKvList[$k]];
}
$spec['spec_text'] = json_encode($specText, JSON_UNESCAPED_UNICODE);
}
if (!isset($spec['stock']) || !isset($spec['is_default'])) {
throw new RepositoryException('规格信息不完整');
}
if (empty($spec['stock'])) {
throw new RepositoryException('请填写库存');
}
$spec['price'] = $spec['original_price'] ?? 0;
if (isset($spec['price']) && $spec['price'] <= 0) {
throw new RepositoryException('规格价格必须大于0');
}
if (!isset($spec['price']) && !isset($spec['score'])) {
throw new RepositoryException('规格价格|积分不能为空');
}
$spec['original_price'] = $spec['original_price'] ?: $spec['price'];
if ($spec['is_default'] == 1) {
$defaultNum += 1;
$defaultPrice = $spec['price'];
$defaultOriginalPrice = $spec['original_price'];
$defaultScore = $spec['score'] ?? 0;
}
if ($type == 'normal') {
if (!isset($spec['spu_id'])) {
$spec['spu_id'] = $id;
}
} else {
if (!isset($spec['spu_activity_id'])) {
$spec['spu_activity_id'] = $id;
}
$spec['type'] = $type;
}
if (!isset($spec['coding']) || empty($spec['coding'])) {
$spec['coding'] = generateCode();
}
$stock += $spec['stock'];
}
$specInfo = [];// 该商品的启用的规格及其规格值
$specValueIds = array_unique($specValueIds);
foreach ($specValueIds as $valueId) {
$specId = $value2Spec[$valueId] ?? 0;
if ($specId > 0 && !isset($specInfo[$specId])) {
$specInfo[$specId] = [];
}
$specInfo[$specId][] = $valueId;
}
if ($defaultNum !== 1) {
throw new RepositoryException('默认规格有且仅有一个');
}
return [
'data' => $data,
'stock' => $stock,
'price' => $defaultPrice,
'original_price' => $defaultOriginalPrice,
'score' => $defaultScore,
'delete' => $deleteIds,
'spec' => $specInfo
];
}
/**
* 添加SPU活动商品信息
*
* @param string $type
* @param array $data 活动基础信息
* @param int $spuId
* @param array $sku 规格信息
* @return Model
* @throws RepositoryException
*/
public function addActivity(string $type, array $data, int $spuId, array $sku): Model
{
Db::startTrans();
try {
if (!$spu = Spu::findById($spuId)) {
throw new RepositoryException('商品不存在');
}
$insert = $spu->toArray();
unset($insert['id']);
$allowFields = [
'name', 'subtitle', 'saleable', 'price', 'original_price', 'score', 'level_id',
'is_hot', 'has_postage', 'cover', 'images', 'share_img', 'video', 'spu_type', 'content', 'views',
];
$now = date('Y-m-d H:i:s');
$insert = arrayKeysFilter($insert, $allowFields);
$insert['activity_type'] = $type;
$insert['cover'] = $data['cover'] ?: $insert['cover'];
$insert['activity_begin_at'] = $data['activity_begin_at'];
$insert['activity_end_at'] = $data['activity_end_at'];
$insert['limit_time'] = $data['limit_time'] ?? 0;
$insert['limit_num'] = $data['limit_num'] ?? 0;
$insert['group_base_num'] = $data['group_base_num'] ?? 0;
$insert['group_num'] = $data['group_num'] ?? 0;
$insert['group_time'] = $data['group_time'] ?? 0;
$insert['virtual_group'] = $data['virtual_group'] ?? 0;
$insert['open_one'] = $data['open_one'] ?? 0;
$insert['amount'] = 0;//销量设为0
$insert['spu_id'] = $spuId;
$insert['created_at'] = $now;
$insert['updated_at'] = $now;
$insert['published_at'] = $now;
$spuActivity = SpuActivity::create($insert);
$spu->save([
'activity_id' => $spuActivity['id'],
'is_activity' => Spu::COMMON_ON,
'activity_type' => $type,
]);
$skuData = $this->handleSku($spuActivity['id'], $sku, [], 'activity');
(new Sku())->saveAll($skuData['data']);
$spuActivity->save([
'stock' => $skuData['stock'],
'price' => $skuData['price'],
'original_price' => $skuData['original_price'],
'score' => $skuData['score'],
]);
Db::commit();
return $spu;
} catch (RepositoryException $e) {
// 回滚事务
Db::rollback();
throw $e;
} catch (Exception $e) {
SpuRepository::log($e->getMessage(), $e);
// 回滚事务
Db::rollback();
throw new RepositoryException('活动商品创建失败');
}
}
/**
* 编辑活动商品信息
*
* @param int $id
* @param array $data 基础信息
* @param array $sku 规格信息
* @param array $originalSkuList 原始规格列表
* @throws RepositoryException
*/
public function editActivity(int $id, array $data, array $sku, array $originalSkuList)
{
Db::startTrans();
try {
if (!$spuActivity = SpuActivity::findById($id)) {
throw new RepositoryException('没有相关的活动商品记录');
}
$now = date('Y-m-d H:i:s');
$data['updated_at'] = $now;
$skuData = $this->handleSku($id, $sku, array_column($originalSkuList, 'id'), 'activity');
(new Sku())->saveAll($skuData['data']);
(new Sku())->where('id', 'in', $skuData['delete'])->delete();
$data['stock'] = $skuData['stock'];
$data['price'] = $skuData['price'];
$data['original_price'] = $skuData['original_price'];
$data['score'] = $skuData['score'];
$spuActivity->save($data);
Db::commit();
} catch (RepositoryException $e) {
// 回滚事务
Db::rollback();
throw $e;
} catch (Exception $e) {
// 回滚事务
Db::rollback();
throw new RepositoryException('活动商品信息修改失败'.$e->getLine());
}
}
/**
* 获取活动商品的订单列表
*
* @throws Exception
*/
public function getActivityOrderList(int $activityId, string $type = Spu::TYPE_LIMIT_TIME, int $page = 1, int $size = 0): array
{
$where = [];
$where[] = ['spu_activity_id', '=', $activityId];
$where[] = ['deleted_at', '=', null];
$where[] = ['type', '=', $type];
$res = OrderActivity::findList($where, [], $page, $size, function ($q) {
return $q->with(['orderInfo', 'account']);
}, ['id' => 'desc']);
$res['list'] = $res['list']->each(function ($item) {
$item->activity_text = Spu::activityTextList()[$item->activity_type] ?? '';
$item->created_at = $item->orderInfo->created_at ?? '';
$item->phone = $item->orderInfo->phone ?? '';
$item->status = $item->orderInfo->status ?? '';
$item->status_text = Order::statusTextList()[$item->status] ?? '';
$item->nickname = $item->account->nickname ?? '';
$item->real_name = $item->account->real_name ?? '';
});
return $res;
}
/**
* 商品分类 构造xmSelect 需要的数据[xmSelect使用时需要json_encode处理]
*
* @param array $selected
* @param array $disabled
* @param bool $excludeParent 拥有下级的节点是否不可勾选 默认false
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function categoryXmSelect(array $selected = [], array $disabled = [], bool $excludeParent = false): array
{
$category = Category::order('sort', 'desc')
->field('id,pid,title')
->select()->toArray();
foreach ($category as $k => $m) {
$category[$k]['selected'] = in_array($m['id'], $selected);
$category[$k]['disabled'] = in_array($m['id'], $disabled);
}
$category = CmsRepository::getInstance()->buildMenuChild(0, $category, 'children', $excludeParent);
return CmsRepository::getInstance()->handleSelectedList($category);
}
/**
* 商品分类
*
* @param int $pid
* @param array $fields
* @return Category[]|array|Collection
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function category(int $pid = 0, array $fields = ['id', 'title'])
{
return Category::where('pid', $pid)
->field($fields)
->order('sort', 'desc')
->order('id', 'asc')
2022-05-27 10:36:21 +00:00
->withAttr("cover",function ($value){
return resourceJoin($value,request()->domain());
})
2022-05-25 11:35:57 +00:00
->select();
}
2022-05-27 10:36:21 +00:00
public function categoryAll(array $fields = ['id', 'title'])
{
$list = Category::field($fields)
->order('sort', 'desc')
->order('id', 'asc')
->select()
->withAttr("cover",function ($value){
return resourceJoin($value,request()->domain());
})
->toArray();
return list_to_tree($list);
}
2022-05-25 11:35:57 +00:00
/**
* 设置商品分类
*
* @param int $spuId
* @param array $categoryIds
*/
public function setCategory(int $spuId, array $categoryIds)
{
SpuCategoryPivot::where('spu_id', $spuId)->delete();
if ($categoryIds) {
$insert = [];
foreach ($categoryIds as $categoryId) {
$insert[] = [
'spu_id' => $spuId,
'category_id' => $categoryId
];
}
(new SpuCategoryPivot())->insertAll($insert);
}
}
/**
* 获取商品分类ID列表
*
* @param int $spuId
* @return array
*/
public function getCategoryIdList(int $spuId): array
{
return SpuCategoryPivot::where('spu_id', $spuId)->column('category_id');
}
/**
* 获取商品规格信息
*
* @param int $spuId
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws RepositoryException
*/
public function getSpec(int $spuId): array
{
if (!$spu = Spu::findById($spuId)) {
throw new RepositoryException('商品不存在');
}
$res = [];
if ($spu['is_activity'] == Spu::COMMON_ON) {
$where[] = ['spu_activity_id', '=', $spu['activity_id']];
$where[] = ['type', '=', $spu['activity_type']];
} else {
$where[] = ['spu_id', '=', $spuId];
}
$fields = ['id', 'spu_id', 'indexes', 'title', 'coding', 'stock', 'price', 'original_price', 'is_default'];
$skuList = Sku::where($where)->field($fields)->select();
$res['sku_list'] = $skuList;//SKU列表
$res['sku'] = $skuList->where('is_default', Sku::COMMON_ON)->first();//默认SKU
$res['spec'] = [];//规格
if ($spu['multi_spec'] > 0) {
$spec = json_decode($spu['spec'], true);
$specIds = array_keys($spec);
$valueIds = [];
foreach (array_values($spec) as $arr) {
$valueIds = array_merge($valueIds, $arr);
}
$specList = SpecParam::whereIn('id', $specIds)->order('sort', 'desc')->order('id', 'asc')->select()->toArray();
$specValueList = SpecValue::whereIn('id', $valueIds)->order('sort', 'desc')->order('id', 'asc')->select()->toArray();
foreach ($specList as $sl) {
$arr = [];
$arr['id'] = $sl['id'];
$arr['title'] = $sl['title'];
$children = [];
foreach ($specValueList as $vl) {
if ($vl['spec_id'] == $sl['id']) {
$children[] = [
'id' => $vl['id'],
'title' => $vl['title'],
];
}
}
$arr['children'] = $children;
$res['spec'][] = $arr;
}
}
return $res;
}
/**
* [{"颜色": "红色"},{"尺寸": "L"}] 转成 ["颜色:红色","尺寸:L"]
*
* @param $specArr
* @return array
*/
public function convertSpecInfo($specArr): array
{
if (!$specArr) {
return [];
}
$arr = [];
foreach ($specArr as $s) {
$k = key($s);
$arr[] = sprintf("%s%s", $k, $s[$k] ?? '');
}
return $arr;
}
}