| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082 |
- <?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);
- $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);
- $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();
- }
- }
- {
- try {
- // 使用PhpSpreadsheet处理Excel文件
- if (is_array($file)) {
- return $file;
- }
-
- // 检查文件是否存在
- if (!file_exists($file)) {
- throw new \Exception('文件不存在');
- }
-
- // 加载Excel文件
- $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file);
- $worksheet = $spreadsheet->getActiveSheet();
- $data = $worksheet->toArray();
-
- if (empty($data)) {
- throw new \Exception('Excel文件为空');
- }
-
- // 获取表头
- $headers = array_shift($data);
- $result = [];
-
- // 将表头映射为字段名
- $fieldMap = [
- '商品ID' => 'goods_id',
- '商品编码' => 'goods_code',
- '商品名称' => 'goods_name',
- '规格ID' => 'item_id',
- '规格名称' => 'spec_value_str',
- '销售价格' => 'sell_price',
- '划线价格' => 'lineation_price',
- '成本价格' => 'cost_price',
- '库存数量' => 'stock',
- '重量(kg)' => 'weight',
- '体积(m³)' => 'volume'
- ];
-
- // 创建字段索引映射
- $fieldIndexes = [];
- foreach ($headers as $index => $header) {
- if (isset($fieldMap[$header])) {
- $fieldIndexes[$fieldMap[$header]] = $index;
- }
- }
-
- // 处理数据行
- foreach ($data as $rowIndex => $row) {
- if (empty(array_filter($row))) {
- continue; // 跳过空行
- }
-
- $item = [];
- foreach ($fieldIndexes as $field => $index) {
- $item[$field] = isset($row[$index]) ? trim($row[$index]) : '';
- }
-
- if (!empty($item)) {
- $result[$rowIndex + 2] = $item; // +2 因为表头占一行,数组从0开始
- }
- }
-
- return $result;
-
- } catch (\Exception $e) {
- throw new \Exception('Excel文件解析失败:' . $e->getMessage());
- }
- }
- }
|