| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047 |
- <?php
- // +----------------------------------------------------------------------
- // | LikeShop有特色的全开源社交分销电商系统
- // +----------------------------------------------------------------------
- // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
- // | 商业用途务必购买系统授权,以免引起不必要的法律纠纷
- // | 禁止对系统程序代码以任何目的,任何形式的再发布
- // | 微信公众号:好象科技
- // | 访问官网:http://www.likemarket.net
- // | 访问社区:http://bbs.likemarket.net
- // | 访问手册:http://doc.likemarket.net
- // | 好象科技开发团队 版权所有 拥有最终解释权
- // +----------------------------------------------------------------------
- // | Author: LikeShopTeam
- // +----------------------------------------------------------------------
- namespace app\adminapi\logic\goods;
- use think\facade\Db;
- use app\common\enum\{ActivityEnum, YesNoEnum, GoodsEnum, DefaultEnum};
- use app\common\model\{Cart,
- DistributionGoods,
- Goods,
- Freight,
- GoodsActivity,
- GoodsUnit,
- GoodsSpec,
- GoodsItem,
- GoodsImage,
- GoodsBrand,
- GoodsSupplier,
- GoodsCategory,
- GoodsSpecValue,
- GoodsCategoryIndex};
- /**
- * 商品逻辑层
- * Class GoodsLogic
- * @package app\adminapi\logic\goods
- */
- class GoodsLogic
- {
- /**
- * Notes:添加商品
- * @param array $postData 商品信息
- * @return bool|string
- * @author: cjhao 2021/7/9 18:04
- */
- public function add(array $params)
- {
- Db::startTrans();
- try {
- $goods = $this->setBase($params);
- $this->addGoodsItem($goods,$params);
- Db::commit();
- return true;
- } catch (\Exception $e) {
- Db::rollback();
- return $e->getMessage();
- }
- }
- /**
- * @notes 编辑商品
- * @param array $params
- * @return array|bool[]
- * @author cjhao
- * @date 2021/7/14 18:09
- */
- public function edit(array $params)
- {
- Db::startTrans();
- try {
- $oldItemIds = GoodsItem::where('goods_id', $params['id'])->column('id');
-
- $goods = $this->setBase($params);
- $this->editGoodsItem($goods,$params);
-
- $newItemIds = GoodsItem::where('goods_id', $params['id'])->column('id');
-
- //todo 其他业务逻辑
- $isDistributionGoods = false;
- $distributionGoods = DistributionGoods::where('goods_id', $params['id'])->findOrEmpty()->toArray();
-
- // 存在分销 且sku已经变更 则清除分销信息
- if ($distributionGoods && $oldItemIds != $newItemIds) {
- // 编辑商品时清除已设置好的分销比例,商家须重新设置
- $deleteIds = DistributionGoods::where('goods_id', $params['id'])->column('id');
- DistributionGoods::destroy($deleteIds);
- $isDistributionGoods = true;
- }
- Db::commit();
- return [
- 'status' => true,
- 'is_distribution_goods' => $isDistributionGoods,
- ];
- } catch (\Exception $e) {
- Db::rollback();
- return [
- 'status' => false,
- 'err' => $e->getMessage()
- ];
- }
- }
- /**
- * @notes 商品基础信息
- * @param array $params
- * @return Goods|array|\think\Model|null
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author cjhao
- * @date 2021/7/22 14:01
- */
- public function setBase(array $params){
- $goods = new Goods();
- $goodsImage = $params['goods_image'];
- $goodsCategory = $params['category_id'];
- //总库存
- $totalStock = array_sum(array_column($params['spec_value_list'],'stock'));
- //售价数组
- $specPriceArray = array_column($params['spec_value_list'],'sell_price');
- //划线价数组
- $specLineationPriceArray = array_column($params['spec_value_list'],'lineation_price');
- //编辑操作
- if(isset($params['id'])){
- $goods = $goods::find($params['id']);
- //删除轮播图
- GoodsImage::where(['goods_id'=>$goods->id])->delete();
- //删除商品分类
- GoodsCategoryIndex::where(['goods_id'=>$goods->id])->delete();
- //保存改变前的规格类型
- $goods->oldSpecType = $goods->spec_type;
- }
- $isExpress = GoodsEnum::GOODS_REALITY == $params['type'] ? $params['is_express'] : 0 ; //快递
- $isSelffetch = GoodsEnum::GOODS_REALITY == $params['type'] ? $params['is_selffetch'] : 0 ; //自提
- $isVirtualdelivery = GoodsEnum::GOODS_VIRTUAL == $params['type'] ? 1 : 0; //虚拟发货
- $afterPay = 0;
- $afterDelivery = 0;
- switch ($params['type']){
- case 1:
- $isExpress = $params['is_express'];
- $isSelffetch = $params['is_selffetch'];
- break;
- case 2:
- $isVirtualdelivery = 1;
- $afterPay = $params['after_pay'];
- $afterDelivery = $params['after_delivery'];
- break;
- }
- //更新商品基础信息
- $goods->name = $params['name'];
- $goods->code = $params['code'];
- $goods->type = $goods['type'] ?? $params['type']; //编辑不允许修改类型
- $goods->brand_id = $params['brand_id'];
- $goods->supplier_id = $params['supplier_id'];
- $goods->unit_id = $params['unit_id'];
- $goods->image = array_shift($goodsImage); //弹出第一张图片,设为商品主图;
- $goods->spec_type = $params['spec_type'];
- $goods->video_source = $params['video_source'];
- $goods->video_cover = $params['video_cover'];
- $goods->video = $params['video'];
- $goods->poster = $params['poster'];
- $goods->total_stock = $totalStock;
- $goods->min_price = min($specPriceArray);
- $goods->max_price = max($specPriceArray);
- $goods->min_lineation_price = min($specLineationPriceArray);
- $goods->max_lineation_price = max($specLineationPriceArray);
- $goods->express_type = $params['express_type'];
- $goods->express_money = $params['express_money'];
- $goods->express_template_id = $params['express_template_id'];
- $goods->stock_warning = $params['stock_warning'];
- $goods->virtual_sales_num = $params['virtual_sales_num'];
- $goods->virtual_click_num = $params['virtual_click_num'] ?? 0;
- $goods->sort = $params['sort'] ?? DefaultEnum::SORT;
- $goods->status = $params['status'];
- $goods->content = $params['content'];
- $goods->is_express = $isExpress; //快递配送
- $goods->is_selffetch = $isSelffetch; //上门自提
- $goods->is_virtualdelivery = $isVirtualdelivery; //虚拟发货
- $goods->after_pay = $afterPay; //买家付款后:1-自动发货,2-手动发货
- $goods->after_delivery = $afterDelivery; //发货后:1-自动完成订单,2-需要买家确认
- $goods->delivery_content = $params['delivery_content'] ?? ''; //发货内容
- $goods->delivery_type = $params['delivery_type'] ?? 0;// 发货类型
- $goods->delivery_template_id= $params['delivery_template_id'] ?? 0;// 发货模版
- $goods->is_address = $params['is_address'] ?? 0;
- $goods->limit_type = $params['limit_type'];
- $goods->limit_value = $params['limit_value'];
- $goods->service_guarantee_ids = $params['service_guarantee_ids'] ?? [];
- $goods->save();
- //添加商品轮播图
- if ($goodsImage) {
- array_walk($goodsImage, function (&$image){
- $image = ['uri' => $image];
- });
- $goods->imageList()->saveAll($goodsImage);
- }
- //添加商品分类关联表
- if($goodsCategory){
- array_walk($goodsCategory, function (&$category_id){
- $category_id = ['category_id' => $category_id];
- });
- $goods->goodsCategoryIndex()->saveAll($goodsCategory);
- }
- return $goods;
- }
- /**
- * @notes 添加商品规格信息
- * @param Goods $goods
- * @param array $params
- * @author cjhao
- * @date 2021/7/22 14:37
- */
- public function addGoodsItem(Goods $goods,array $params)
- {
- $specType = $params['spec_type'];
- //添加商品规格
- if (GoodsEnum::SEPC_TYPE_SIGNLE == $specType) {
- //单规格商品
- $specValueList = $params['spec_value_list'];
- foreach ($specValueList as $spec) {
- $goodsSpec = new GoodsSpec();
- $goodsSpec->goods_id = $goods->id;
- $goodsSpec->name = '默认';
- $goodsSpec->save();
- $goodsSpecValue = new GoodsSpecValue();
- $goodsSpecValue->save([
- 'goods_id' => $goodsSpec->goods_id,
- 'spec_id' => $goodsSpec->id,
- 'value' => '默认',
- ]);
- $specValueData = [
- 'goods_id' => $goods->id,
- 'spec_value_ids' => $goodsSpecValue->id,
- 'spec_value_str' => '默认',
- 'image' => $spec['image'],
- 'sell_price' => $spec['sell_price'],
- 'lineation_price' => $spec['lineation_price'],
- 'cost_price' => $spec['cost_price'],
- 'stock' => $spec['stock'],
- 'volume' => $spec['volume'],
- 'weight' => $spec['weight'],
- 'bar_code' => $spec['bar_code'],
- ];
- (new GoodsItem())->save($specValueData);
- }
- } else {
- //添加规格项
- $postSpecValue = $params['spec_value'];
- $specData = [];
- foreach ($postSpecValue as $sepcKey => $specVal) {
- $goodsSpec = new GoodsSpec();
- $goodsSpec->goods_id = $goods->id;
- $goodsSpec->name = $specVal['name'];
- $goodsSpec->save();
- //处理规格值
- array_walk($specVal['spec_list'], function ($spec) use ($goodsSpec,&$specData){
- $specData[] = ['spec_id'=>$goodsSpec->id,'value'=>$spec['value']];
- });
- }
- $goods->specValueSpec()->saveAll($specData);
- //添加规格信息
- $serverSpecValueList = $params['server_spec_value_list'];
- //改变数据结构,ids为索引
- $postSpecValueList = array_column($params['spec_value_list'], null, 'ids');
- // $goodsSpecValueList = GoodsSpecValue::where(['goods_id'=>$goods->id])
- // ->group('spec_id')
- // ->column(' GROUP_CONCAT(value Separator \',\') as spec_values,GROUP_CONCAT(id Separator \',\') as spec_ids');
- //GROUP_CONCAT函数有长度限制,替换成下面的方法
- $goodsSpecValue = GoodsSpecValue::where(['goods_id'=>$goods->id])
- ->column('id,spec_id,value');
- $goodsSpecValueList = [];
- foreach ($goodsSpecValue as $goodsSpecValue_val) {
- $goodsSpecValueList[$goodsSpecValue_val['spec_id']][] = $goodsSpecValue_val;
- }
- foreach ($goodsSpecValueList as $goodsSpecValueList_key=>$goodsSpecValueList_val) {
- $spec_values = array_column($goodsSpecValueList_val,'value');
- $spec_values = implode(',',$spec_values);
- $spec_ids = array_column($goodsSpecValueList_val,'id');
- $spec_ids = implode(',',$spec_ids);
- $goodsSpecValueList[$goodsSpecValueList_key] = [];
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_values'] = $spec_values;
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_ids'] = $spec_ids;
- }
- $goodsSpecValueList = array_values($goodsSpecValueList);
- $specValueData = [];
- foreach ($serverSpecValueList as $serverValue) {
- $specValueList = $postSpecValueList[$serverValue['ids']];
- $specValue = explode(GoodsEnum::SPEC_SEPARATOR, $serverValue['spec_value']);
- $specIds = [];
- //获取规格值对应的id
- foreach ($specValue as $specIndex => $specVal){
- $specListValues = explode(',',$goodsSpecValueList[$specIndex]['spec_values']);
- $specListIds = explode(',',$goodsSpecValueList[$specIndex]['spec_ids']);
- $specValueIds = array_combine($specListValues,$specListIds);
- $specIds[] = $specValueIds[$specVal];
- }
- $specValueData[] = [
- 'spec_value_ids' => implode(GoodsEnum::SPEC_SEPARATOR, $specIds),
- 'spec_value_str' => $serverValue['spec_value'],
- 'image' => $specValueList['image'],
- 'sell_price' => $specValueList['sell_price'],
- 'lineation_price' => $specValueList['lineation_price'],
- 'cost_price' => $specValueList['cost_price'],
- 'stock' => $specValueList['stock'],
- 'volume' => $specValueList['volume'],
- 'weight' => $specValueList['weight'],
- 'bar_code' => $specValueList['bar_code'],
- ];
- }
- $goods->specValueList()->saveAll($specValueData);
- }
- }
- /**
- * @notes 编辑商品规格信息
- * @param Goods $goods
- * @param array $params
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author cjhao
- * @date 2021/7/22 14:46
- */
- public function editGoodsItem(Goods $goods,array $params)
- {
- $specType = $params['spec_type']; //编辑后的规格类型
- $oldSpecType = $goods->oldSpecType; //原来的规格类型
- //编辑商品规格
- if(GoodsEnum::SEPC_TYPE_SIGNLE == $specType){
- //原来单规格,更新规格信息
- $specValueList = $params['spec_value_list'][0];
- if(GoodsEnum::SEPC_TYPE_SIGNLE == $oldSpecType){
- GoodsItem::update([
- 'id' => $specValueList['id'],
- 'sell_price' => $specValueList['sell_price'],
- 'lineation_price' => $specValueList['lineation_price'],
- 'cost_price' => $specValueList['cost_price'],
- 'stock' => $specValueList['stock'],
- 'volume' => $specValueList['volume'],
- 'weight' => $specValueList['weight'],
- 'bar_code' => $specValueList['bar_code'],
- ]);
- }else{
- //原来多规格,删除多规格数据
- GoodsSpec::where(['goods_id'=>$goods->id])->delete();
- GoodsSpecValue::where(['goods_id'=>$goods->id])->delete();
- GoodsItem::where(['goods_id'=>$goods->id])->delete();
- //写入单规格数据
- $goodsSpec = new GoodsSpec();
- $goodsSpec->goods_id = $goods->id;
- $goodsSpec->name = '默认';
- $goodsSpec->save();
- $goodsSpecValue = new GoodsSpecValue();
- $goodsSpecValue->save([
- 'goods_id' => $goodsSpec->goods_id,
- 'spec_id' => $goodsSpec->id,
- 'value' => '默认',
- ]);
- $specValueData = [
- 'goods_id' => $goods->id,
- 'spec_value_ids' => $goodsSpecValue->id,
- 'spec_value_str' => '默认',
- 'image' => $specValueList['image'],
- 'sell_price' => $specValueList['sell_price'],
- 'lineation_price' => $specValueList['lineation_price'],
- 'cost_price' => $specValueList['cost_price'],
- 'stock' => $specValueList['stock'],
- 'volume' => $specValueList['volume'],
- 'weight' => $specValueList['weight'],
- 'bar_code' => $specValueList['bar_code'],
- ];
- (new GoodsItem())->save($specValueData);
- }
- }else{
- //原单规格
- if(GoodsEnum::SEPC_TYPE_SIGNLE == $oldSpecType){
- //原来单规格,删除单规格数据
- GoodsSpec::where(['goods_id'=>$goods->id])->delete();
- GoodsSpecValue::where(['goods_id'=>$goods->id])->delete();
- GoodsItem::where(['goods_id'=>$goods->id])->delete();
- //添加规格项
- $postSpecValue = $params['spec_value'];
- $specData = [];
- foreach ($postSpecValue as $specVal) {
- $goodsSpec = new GoodsSpec();
- $goodsSpec->goods_id = $goods->id;
- $goodsSpec->name = $specVal['name'];
- $goodsSpec->save();
- //处理规格值
- array_walk($specVal['spec_list'], function ($spec) use ($goodsSpec,&$specData){
- $specData[] = ['spec_id'=>$goodsSpec->id,'value'=>$spec['value']];
- });
- }
- $goods->specValueSpec()->saveAll($specData);
- //添加规格信息
- $serverSpecValueList = $params['server_spec_value_list'];
- //改变数据结构,ids为索引
- $postSpecValueList = array_column($params['spec_value_list'], null, 'ids');
- // $goodsSpecValueList = GoodsSpecValue::where(['goods_id'=>$goods->id])
- // ->group('spec_id')
- // ->column(' GROUP_CONCAT(value Separator \',\') as spec_values,GROUP_CONCAT(id Separator \',\') as spec_ids');
- //GROUP_CONCAT函数有长度限制,替换成下面的方法
- $goodsSpecValue = GoodsSpecValue::where(['goods_id'=>$goods->id])
- ->column('id,spec_id,value');
- $goodsSpecValueList = [];
- foreach ($goodsSpecValue as $goodsSpecValue_val) {
- $goodsSpecValueList[$goodsSpecValue_val['spec_id']][] = $goodsSpecValue_val;
- }
- foreach ($goodsSpecValueList as $goodsSpecValueList_key=>$goodsSpecValueList_val) {
- $spec_values = array_column($goodsSpecValueList_val,'value');
- $spec_values = implode(',',$spec_values);
- $spec_ids = array_column($goodsSpecValueList_val,'id');
- $spec_ids = implode(',',$spec_ids);
- $goodsSpecValueList[$goodsSpecValueList_key] = [];
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_values'] = $spec_values;
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_ids'] = $spec_ids;
- }
- $goodsSpecValueList = array_values($goodsSpecValueList);
- $specValueData = [];
- foreach ($serverSpecValueList as $serverValue) {
- $specValueList = $postSpecValueList[$serverValue['ids']];
- $specValue = explode(GoodsEnum::SPEC_SEPARATOR, $serverValue['spec_value']);
- $specIds = [];
- //获取规格值对应的id
- foreach ($specValue as $specIndex => $specVal){
- $specListValues = explode(',',$goodsSpecValueList[$specIndex]['spec_values']);
- $specListIds = explode(',',$goodsSpecValueList[$specIndex]['spec_ids']);
- $specValueIds = array_combine($specListValues,$specListIds);
- $specIds[] = $specValueIds[$specVal];
- }
- $specValueData[] = [
- 'spec_value_ids' => implode(GoodsEnum::SPEC_SEPARATOR, $specIds),
- 'spec_value_str' => $serverValue['spec_value'],
- 'image' => $specValueList['image'],
- 'sell_price' => $specValueList['sell_price'],
- 'lineation_price' => $specValueList['lineation_price'],
- 'cost_price' => $specValueList['cost_price'],
- 'stock' => $specValueList['stock'],
- 'volume' => $specValueList['volume'],
- 'weight' => $specValueList['weight'],
- 'bar_code' => $specValueList['bar_code'],
- ];
- }
- $goods->specValueList()->saveAll($specValueData);
- }else{
- //原来多规格,改变后还是多规格
- $goodsSpecIds = GoodsSpec::where(['goods_id'=>$goods->id])->column('id');
- $goodsSpecValueIds = GoodsSpecValue::where(['goods_id'=>$goods->id])->column('id');
- $goodsItemIds = GoodsItem::where(['goods_id'=>$goods->id])->column('id');
- $postSpecValue = $params['spec_value'];
- $postGoodsSpecValueIds = [];
- foreach ($postSpecValue as $spec) {
- $goodsSpec = new GoodsSpec();
- //存在规格id,进行更新操作
- if($spec['id'] > 0){
- $goodsSpec = $goodsSpec->find($spec['id']);
- }
- $goodsSpec->goods_id = $goods->id;
- $goodsSpec->name = $spec['name'];
- $goodsSpec->save();
- //合并规格值id
- $postGoodsSpecValueIds = array_merge($postGoodsSpecValueIds,array_column($spec['spec_list'],'id'));
- //写入规格,存在则更新
- array_walk($spec['spec_list'], function ($specVal) use ($goodsSpec, &$specList) {
- $goodsSpecValue = new GoodsSpecValue();
- //存在规格值id,进行更新操作
- if($specVal['id'] > 0){
- $goodsSpecValue = $goodsSpecValue->find($specVal['id']);
- }
- $goodsSpecValue->save([
- 'goods_id' => $goodsSpec->goods_id,
- 'spec_id' => $goodsSpec->id,
- 'value' => $specVal['value'],
- ]);
- });
- }
- //添加规格信息
- $serverSpecValueList = $params['server_spec_value_list'];
- //改变数据结构,ids为索引
- $postSpecValueList = array_column($params['spec_value_list'], null, 'ids');
- $specValues = array_column($serverSpecValueList, 'spec_value');
- $specValues = implode(',',$specValues);
- // $goodsSpecValueList = GoodsSpecValue::where(['goods_id'=>$goods->id])
- // ->where('value','in',$specValues)
- // ->group('spec_id')
- // ->column(' GROUP_CONCAT(value Separator \',\') as spec_values,GROUP_CONCAT(id Separator \',\') as spec_ids');
- //GROUP_CONCAT函数有长度限制,替换成下面的方法
- $goodsSpecValue = GoodsSpecValue::where(['goods_id'=>$goods->id])
- ->where('value','in',$specValues)
- ->column('id,spec_id,value');
- $goodsSpecValueList = [];
- foreach ($goodsSpecValue as $goodsSpecValue_val) {
- $goodsSpecValueList[$goodsSpecValue_val['spec_id']][] = $goodsSpecValue_val;
- }
- foreach ($goodsSpecValueList as $goodsSpecValueList_key=>$goodsSpecValueList_val) {
- $spec_values = array_column($goodsSpecValueList_val,'value');
- $spec_values = implode(',',$spec_values);
- $spec_ids = array_column($goodsSpecValueList_val,'id');
- $spec_ids = implode(',',$spec_ids);
- $goodsSpecValueList[$goodsSpecValueList_key] = [];
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_values'] = $spec_values;
- $goodsSpecValueList[$goodsSpecValueList_key]['spec_ids'] = $spec_ids;
- }
- $goodsSpecValueList = array_values($goodsSpecValueList);
- $specValueData = [];
- foreach ($serverSpecValueList as $serverValue) {
- $specValueList = $postSpecValueList[$serverValue['ids']];
- $specValue = explode(GoodsEnum::SPEC_SEPARATOR, $serverValue['spec_value']);
- $specIds = [];
- //获取规格值对应的id
- foreach ($specValue as $specIndex => $specVal){
- $specListValues = explode(',',$goodsSpecValueList[$specIndex]['spec_values']);
- $specListIds = explode(',',$goodsSpecValueList[$specIndex]['spec_ids']);
- $specValueIds = array_combine($specListValues,$specListIds);
- $specIds[] = $specValueIds[$specVal];
- }
- //添加的数据
- $itemData = [
- 'spec_value_ids' => implode(GoodsEnum::SPEC_SEPARATOR, $specIds),
- 'spec_value_str' => $serverValue['spec_value'],
- 'image' => $specValueList['image'],
- 'sell_price' => $specValueList['sell_price'],
- 'lineation_price' => $specValueList['lineation_price'],
- 'cost_price' => $specValueList['cost_price'],
- 'stock' => $specValueList['stock'],
- 'volume' => $specValueList['volume'],
- 'weight' => $specValueList['weight'],
- 'bar_code' => $specValueList['bar_code'],
- ];
- //更新规格
- if($specValueList['id'] > 0){
- $itemData['id'] = $specValueList['id'];
- }
- $specValueData[] = $itemData;
- }
- $goods->specValueList()->saveAll($specValueData);
- $postSpecIds = array_column($postSpecValue,'id');
- $postItemIds = array_column($params['spec_value_list'],'id');
- //对比规格是否需要删除
- $delSpecIds = array_diff($goodsSpecIds, $postSpecIds);
- $delSpecValyeIds = array_diff($goodsSpecValueIds, $postGoodsSpecValueIds);
- $delItemIds = array_diff($goodsItemIds, $postItemIds);
- //需要删除规格名
- if($delSpecIds){
- GoodsSpec::where(['id'=>array_values($delSpecIds)])->delete();
- }
- //删除规格值
- if($delSpecValyeIds){
- GoodsSpecValue::where(['id'=>array_values($delSpecValyeIds)])->delete();
- }
- //删除规格信息
- if($delItemIds){
- GoodsItem::where(['id'=>array_values($delItemIds)])->delete();
- }
- }
- }
- }
- /**
- * @notes 商品其他列表
- * @param string $type
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author cjhao
- * @date 2021/7/22 15:47
- */
- public function otherList(string $type)
- {
- $supplierList = GoodsSupplier::field('id,name')->order('sort','asc')->select();
- $categoryList = GoodsCategory::field('id,pid,name')->order('sort','asc')->select()->toArray();
- $categoryList = linear_to_tree($categoryList,'sons');
- if('all' !== $type){
- $activityLists = ActivityEnum::getActivityDesc();
- $activityLists = [0=>'未参与'] + $activityLists;
- return [
- 'supplier_list' => $supplierList,
- 'category_list' => $categoryList,
- 'type_list' => GoodsEnum::getGoodsTypeDesc(),
- 'activity_list' => $activityLists,
- ];
- }
- $unitList = GoodsUnit::field('id,name')->order('sort','asc')->select();
- $brandList = GoodsBrand::field('id,name')->order('sort','asc')->select();
- $freightList = Freight::field('id,name')->select();
- $list = [
- 'supplier_list' => $supplierList,
- 'category_list' => $categoryList,
- 'brand_list' => $brandList,
- 'unit_list' => $unitList,
- 'freight_list' => $freightList,
- ];
- return $list;
- }
- /**
- * @notes 商品详情
- * @param int $id 商品id
- * @return array|\think\Model|null
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author cjhao
- * @date 2021/7/15 15:49
- */
- public function detail(int $id)
- {
- $goods = Goods::with(['spec_value.spec_list','spec_value_list'])
- ->withoutField('create_time,update_time')
- ->append(['goods_image','category_id'])
- ->find($id)
- ->toArray();
- return $goods;
- }
- /**
- * @notes 商品上下架
- * @param array $params
- * @return Goods
- * @author cjhao
- * @date 2021/7/17 17:10
- */
- public function status(array $params)
- {
- $status = YesNoEnum::YES == $params['status'] ? 1 : 0;
- return Goods::update(['status'=>$status],['id'=>$params['ids']]);
- }
- /**
- * @notes 设置商品上下架
- * @param array $params
- * @return Goods
- * @author cjhao
- * @date 2021/7/22 9:51
- */
- public function sort(array $params)
- {
- return Goods::update(['id'=>$params['id'],'sort'=>(int)$params['sort']]);
- }
- /**
- * @notes 删除商品 todo 删除接口需要考虑商品的其他状态
- * @param array $ids
- * @return bool
- * @author cjhao
- * @date 2021/7/17 17:23
- */
- public function del(array $ids)
- {
- Db::startTrans();
- try {
- Goods::destroy(['id'=>$ids]);
- // 删除商品时清除已设置好的分销比例
- $deleteIds = DistributionGoods::where('goods_id', 'in', $ids)->column('id');
- DistributionGoods::destroy($deleteIds);
- // 删掉用户购物车商品
- Cart::where(['goods_id'=>$ids])->delete();
- Db::commit();
- return true;
- } catch (\Exception $e) {
- Db::rollback();
- return false;
- }
- }
- /**
- * @notes 修改商品名称
- * @param array $params
- * @return Goods
- * @author cjhao
- * @date 2021/7/29 16:11
- */
- public function rename(array $params)
- {
- return Goods::update(['id'=>$params['id'],'name'=>$params['name']]);
- }
- /**
- * @notes 移动分类
- * @param array $params
- * @throws \Exception
- * @author ljj
- * @date 2023/5/6 2:24 下午
- */
- public function changeCategory(array $params)
- {
- //删除旧的商品分类
- GoodsCategoryIndex::where(['goods_id'=>$params['ids']])->delete();
- //创建新的商品分类
- $data = [];
- foreach ($params['ids'] as $id) {
- foreach ($params['category_id'] as $category_id) {
- $data[] = ['goods_id'=>$id,'category_id'=>$category_id];
- }
- }
- (new GoodsCategoryIndex())->saveAll($data);
- return true;
- }
- /**
- * @notes 商品规格价格导入
- * @param array $params
- * @return bool|string
- * @author
- * @date 2024/01/01 00:00
- */
- public function importSpecPrice(array $params)
- {
- if (empty($params['file'])) {
- return '请上传导入文件';
- }
- Db::startTrans();
- try {
- // 处理上传的Excel文件
- $file = $params['file'];
- $data = $this->parseExcelFile($file);
-
- if (empty($data)) {
- return '导入文件为空或格式错误';
- }
- $successCount = 0;
- $errorMessages = [];
- foreach ($data as $row => $item) {
- try {
- // 验证必要字段
- if (empty($item['item_id']) || empty($item['goods_id'])) {
- $errorMessages[] = "第{$row}行:商品ID或规格ID不能为空";
- continue;
- }
- // 检查商品是否存在
- $goods = Goods::find($item['goods_id']);
- if (!$goods) {
- $errorMessages[] = "第{$row}行:商品ID {$item['goods_id']} 不存在";
- continue;
- }
- // 检查规格是否存在
- $goodsItem = GoodsItem::where('id', $item['item_id'])
- ->where('goods_id', $item['goods_id'])
- ->find();
-
- if (!$goodsItem) {
- $errorMessages[] = "第{$row}行:规格ID {$item['item_id']} 不存在或不属于该商品";
- continue;
- }
- // 更新规格价格信息
- $updateData = [];
- if (isset($item['sell_price']) && is_numeric($item['sell_price'])) {
- $updateData['sell_price'] = $item['sell_price'];
- }
- if (isset($item['lineation_price']) && is_numeric($item['lineation_price'])) {
- $updateData['lineation_price'] = $item['lineation_price'];
- }
- if (isset($item['cost_price']) && is_numeric($item['cost_price'])) {
- $updateData['cost_price'] = $item['cost_price'];
- }
- if (isset($item['stock']) && is_numeric($item['stock'])) {
- $updateData['stock'] = $item['stock'];
- }
- if (isset($item['weight']) && is_numeric($item['weight'])) {
- $updateData['weight'] = $item['weight'];
- }
- if (isset($item['volume']) && is_numeric($item['volume'])) {
- $updateData['volume'] = $item['volume'];
- }
- if (!empty($updateData)) {
- GoodsItem::where('id', $item['item_id'])->update($updateData);
-
- // 更新商品的最小最大价格
- $this->updateGoodsMinMaxPrice($item['goods_id']);
-
- $successCount++;
- }
- } catch (\Exception $e) {
- $errorMessages[] = "第{$row}行:" . $e->getMessage();
- }
- }
- Db::commit();
- if (!empty($errorMessages)) {
- return "导入完成,成功{$successCount}条,失败" . count($errorMessages) . "条。错误信息:" . implode(';', array_slice($errorMessages, 0, 5));
- }
- return true;
- } catch (\Exception $e) {
- Db::rollback();
- return '导入失败:' . $e->getMessage();
- }
- }
- /**
- * @notes 商品规格价格导入列表处理
- * @param array $lists
- * @param string $filename
- * @return array|string
- * @author
- * @date 2024/01/01 00:00
- */
- public function importSpecPriceLists(array $lists, $filename)
- {
- try {
- Db::startTrans();
-
- // 移除表头
- array_shift($lists);
- $lists = array_values($lists);
- $nums = count($lists);
-
- $successCount = 0;
- $failCount = 0;
- $errorMessages = [];
-
- foreach ($lists as $index => $info) {
- try {
- $goodsId = trim($info['A']);
- $itemId = trim($info['D']);
-
- // 检查商品是否存在
- $goods = \app\common\model\Goods::find($goodsId);
- if (!$goods) {
- $errorMessages[] = "第" . ($index + 2) . "行:商品ID {$goodsId} 不存在";
- $failCount++;
- continue;
- }
-
- // 检查规格是否存在且属于该商品
- $goodsItem = \app\common\model\GoodsItem::where('id', $itemId)
- ->where('goods_id', $goodsId)
- ->find();
-
- if (!$goodsItem) {
- $errorMessages[] = "第" . ($index + 2) . "行:规格ID {$itemId} 不存在或不属于商品ID {$goodsId}";
- $failCount++;
- continue;
- }
-
- // 准备更新数据
- $updateData = [];
-
- // 销售价格(F列)
- if (!empty(trim($info['F']))) {
- $updateData['sell_price'] = trim($info['F']);
- }
-
- // 划线价格(G列)
- if (!empty(trim($info['G']))) {
- $updateData['lineation_price'] = trim($info['G']);
- }
-
- // 成本价格(H列)
- if (!empty(trim($info['H']))) {
- $updateData['cost_price'] = trim($info['H']);
- }
-
- // 库存数量(I列)
- if (!empty(trim($info['I']))) {
- $updateData['stock'] = trim($info['I']);
- }
-
- // 重量(J列)
- if (!empty(trim($info['J']))) {
- $updateData['weight'] = trim($info['J']);
- }
-
- // 体积(K列)
- if (!empty(trim($info['K']))) {
- $updateData['volume'] = trim($info['K']);
- }
-
- // 如果有数据需要更新
- if (!empty($updateData)) {
- \app\common\model\GoodsItem::where('id', $itemId)->update($updateData);
-
- // 更新商品的最小最大价格
- $this->updateGoodsMinMaxPrice($goodsId);
-
- $successCount++;
- } else {
- $errorMessages[] = "第" . ($index + 2) . "行:没有需要更新的价格信息";
- $failCount++;
- }
-
- } catch (\Exception $e) {
- $errorMessages[] = "第" . ($index + 2) . "行:" . $e->getMessage();
- $failCount++;
- }
- }
-
- Db::commit();
-
- $result = [
- 'total' => $nums,
- 'success' => $successCount,
- 'fail' => $failCount,
- 'filename' => $filename
- ];
-
- if (!empty($errorMessages)) {
- $result['errors'] = array_slice($errorMessages, 0, 10); // 只返回前10个错误
- }
-
- return $result;
-
- } catch (\Throwable $e) {
- Db::rollback();
- return $e->getMessage();
- }
- }
- /**
- * @notes 更新商品的最小最大价格
- * @param int $goodsId 商品ID
- * @return void
- * @author
- * @date 2024/01/01 00:00
- */
- private function updateGoodsMinMaxPrice($goodsId)
- {
- // 获取该商品所有规格的销售价格
- $priceData = \app\common\model\GoodsItem::where('goods_id', $goodsId)
- ->where('sell_price', '>', 0)
- ->column('sell_price');
-
- if (!empty($priceData)) {
- $minPrice = min($priceData);
- $maxPrice = max($priceData);
-
- // 更新商品表的最小最大价格
- \app\common\model\Goods::where('id', $goodsId)->update([
- 'min_price' => $minPrice,
- 'max_price' => $maxPrice
- ]);
- }
- }
-
- }
|