assign('breadcrumb1','基础信息'); $this->assign('breadcrumb2','产品管理'); } /** * 首页列表 * * */ public function index(Model $Model,AdminUser $AdminUser,Producer $Producer){ // 接受参数 $code = request('product_code',''); $name = request('name',''); $status = request('status'); $startTime = request('start_time',''); // 编码转ID $id = $code ? $Model->codeToId($code) : 0; // 查询条件 $map = []; // 编码ID if( $id ) $map[] = ['id','=',$id]; if( $name ) $map[] = ['name','like','%'.$name.'%']; if( $startTime ) $map[] = ['insert_time','>=',Carbon::createFromFormat('Y-m-d',$startTime)->startOfDay()->getTimestamp()]; if( $startTime ) $map[] = ['insert_time','<=',Carbon::createFromFormat('Y-m-d',$startTime)->endOfDay()->getTimestamp()]; if( !is_null($status) ) $map[] = ['status','=',$status]; // 查询数据 $list = $Model->query()->where($map)->orderByDesc('id')->paginate(request('limit',config('page_num',10)))->appends(request()->all()); // 循环处理数据 foreach ($list as $key => $value) { // id转编号 $value['product_code'] = $Model->idToCode($value['id']); // 创建人 $value['admin_name'] = $AdminUser->getOne($value['admin_uid'],'username'); // 生产厂家 $value['producer_name'] = $Producer->getOne($value['producer_id'],'name'); // 重组 $list[$key] = $value; } // 分配数据 $this->assign('empty', '~~暂无数据'); $this->assign('list', $list); // 加载模板 return $this->fetch(); } /** * 添加 * * */ public function add( Request $request, Model $Model,Producer $Producer,Business $Business,ProductType $ProductType,ProductSpec $ProductSpec,ProductAttr $ProductAttr,ProductSkus $ProductSkus,City $City,ProductCity $ProductCity){ if( request()->isMethod('post') ){ // 验证参数 $request->scene('add')->validate(); // 组合数据 $data['name'] = request('name',''); $data['thumb'] = request('thumb',''); $data['poster'] = request('poster',''); $data['spec'] = request('spec',''); $data['price'] = request('price',0); $data['market_price'] = request('market_price',0); $data['producer_id'] = request('producer_id',0); $data['business_id'] = request('business_id',0); $data['stock'] = request('stock',0); $data['admin_uid'] = admin('uid'); $description = request('description',''); $attr = request('attr',[]); $skuList = request('sku',[]); $cityIds = request('city_ids',[]); // 如果没有选择,则意味着全部 $cityIds = $cityIds ? $cityIds : [1]; // 总库存 if( $skuList ) $data['stock'] = array_sum(array_column($skuList,'stock')); // 获取规格属性 $specAttr = $this->getSpecAttr($attr,$ProductSpec,true); // 开启事务 DB::beginTransaction(); try { // 写入 $id = $Model->add($data); // 提示新增失败 if( !$id ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'新增失败']); } // 组合数据 foreach ($specAttr as $key => $value) { // 查询结果 $value['id'] = $ProductAttr->upsertByName($value['name'],$id,$value['spec_id']); // 提示新增失败 if( !$value['id'] ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'商品属性新增失败']); } // 重组 $specAttr[$key] = $value; } // 循环SKU foreach ($skuList as $attrNames => $value) { // 属性ID值 $value['attr_ids'] = []; // 规格属性值组合 $value['attr_names']= $attrNames; // 切割成数据 $names = explode(',',$attrNames); // 循环处理 foreach ($names as $name) { foreach ($specAttr as $vv) { if( $name == $vv['name'] ) { // 提示新增失败 if( !$vv['id'] ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'属性SKU匹配失败']); } $value['attr_ids'][] = $vv['id']; } } } // 转成好存储的数据 $value['attr_ids'] = implode(',',$value['attr_ids']); // 转成好存储的数据 $value['product_id']= $id; // 转成好存储的数据 $value['insert_time']= time(); // 转成好存储的数据 $value['update_time']= time(); // SKU结果 $skuList[$attrNames] = $value; } // 循环城市范围 foreach ($cityIds as $key => $value) { // 重组数据 $cityIds[$key] = ['city_id'=>$value,'product_id'=>$id,'insert_time'=>time(),'update_time'=>time()]; } // 写入城市范围 $ProductCity->query()->insert($cityIds); // 返回结果 $result = $ProductSkus->insert($skuList); // 提示新增失败 if( !$result ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'SKU插入失败']); } // 更新内容 $Model->updateDesc($id,$description); // 提交 DB::commit(); // 记录行为 $this->addAdminHistory(admin('uid'),$Model->getTable(),$id,1,[],$data); // 告知结果 return json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']); } catch (\Throwable $th) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'系统异常,写入失败','data'=>$th->getMessage()]); } } // 获取类型数据 $typeList = $ProductType->getList(); $cityList = $City->getCityList(); $businessList = $Business->getList(); $producerList = $Producer->getList(); // 分配数据 $this->assign('crumbs','新增'); $this->assign('typeList',$typeList); $this->assign('cityList',$cityList); $this->assign('businessList',$businessList); $this->assign('producerList',$producerList); // 加载模板 return $this->fetch(); } /** * 编辑 * * */ public function edit( Request $request, Model $Model,Producer $Producer,Business $Business,ProductType $ProductType,ProductSpec $ProductSpec,ProductAttr $ProductAttr,ProductSkus $ProductSkus,City $City,ProductCity $ProductCity){ if(request()->isMethod('post')){ // 验证参数 $request->scene('edit')->validate(); // 组合数据 $id = request('id',0); $data['name'] = request('name',''); $data['thumb'] = request('thumb',''); $data['poster'] = request('poster',''); $data['spec'] = request('spec',''); $data['price'] = request('price',0); $data['market_price'] = request('market_price',0); $data['producer_id'] = request('producer_id',0); $data['business_id'] = request('business_id',0); $data['stock'] = request('stock',0); $description = request('description',''); $attr = request('attr',[]); $skuList = request('sku',[]); $cityIds = request('city_ids',[]); // 如果没有选择,则意味着全部 $cityIds = $cityIds ? $cityIds : [1]; // 总库存 if( $skuList ) $data['stock'] = array_sum(array_column($skuList,'stock')); // 获取规格属性 $specAttr = $this->getSpecAttr($attr,$ProductSpec,true); // 开启事务 DB::beginTransaction(); try { // 写入 $result = $Model->edit($id,$data); // 提示新增失败 if( !$result ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'修改失败']); } // 组合数据 foreach ($specAttr as $key => $value) { // 查询结果 $value['id'] = $ProductAttr->upsertByName($value['name'],$id,$value['spec_id']); // 提示新增失败 if( !$value['id'] ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'商品属性新增失败']); } // 重组 $specAttr[$key] = $value; } // 如果不在这个属性列表中的数据删除 $ProductAttr->query()->where([['product_id','=',$id]])->whereNotIn('id',array_column($specAttr,'id'))->delete(); // 循环SKU foreach ($skuList as $attrNames => $value) { // 属性ID值 $value['attr_ids'] = []; // 规格属性值组合 $value['attr_names']= $attrNames; // 切割成数据 $names = explode(',',$attrNames); // 循环处理 foreach ($names as $name) { foreach ($specAttr as $vv) { if( $name == $vv['name'] ) { // 提示新增失败 if( !$vv['id'] ) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'属性SKU匹配失败']); } $value['attr_ids'][] = $vv['id']; } } } // 转成好存储的数据 $value['attr_ids'] = implode(',',$value['attr_ids']); // 转成好存储的数据 $value['product_id']= $id; // 查询 $oldSkuId = $ProductSkus->query()->where([['product_id','=',$id],['attr_ids','=',$value['attr_ids']]])->value('id'); // 判断是否存在ID $value['id'] = $oldSkuId ? $ProductSkus->edit($oldSkuId,$value) : $ProductSkus->add($value); // SKU结果 $skuList[$attrNames]= $value; } // 如果不在这个属性列表中的数据删除 $ProductSkus->query()->where([['product_id','=',$id]])->whereNotIn('id',array_column($skuList,'id'))->delete(); // 获取之前的城市ID $oldCityIds = $ProductCity->getListByProductId($id); // 循环城市范围 foreach ($cityIds as $key => $value) { // 不存在则新增 if( !in_array($value,$oldCityIds) ) $ProductCity->add(['city_id'=>$value,'product_id'=>$id]); } // 不存在的城市删除 $ProductCity->query()->where([['product_id','=',$id]])->whereNotIn('city_id',$cityIds)->delete(); // 更新内容 $Model->updateDesc($id,$description); // 提交 DB::commit(); // 记录行为 $this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],$data); // 告知结果 return json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']); } catch (\Throwable $th) { // 回滚 DB::rollBack(); // 提示 return json_send(['code'=>'error','msg'=>'系统异常,写入失败','data'=>$th->getMessage()]); } } // 接收参数 $id = request('id',0); // 查询数据 $oldData = $Model->where(['id'=>$id])->first(); // 如果是没有数据 if( !$oldData ) return $this->error('查无数据'); // 产品信息转格式 $oldData = $oldData->toArray(); $oldData['description'] = $Model->getDesc($id); $oldData['city_ids'] = $ProductCity->getListByProductId($id); // 获取产品属性 $attrList = $ProductAttr->getListByProductId($id); // 规格属性 $specList = []; // 获取数据 foreach ($attrList as $value) { $value['active'] = 0; if( !isset($specList[$value['spec_id']]) ) $specList[$value['spec_id']] = $ProductSpec->getOne($value['spec_id']); $specList[$value['spec_id']]['attr_list'][] = $value; } // 产品类型 $skuList = $ProductSkus->getListByProductId($id); // 循环处理 foreach ($skuList as $key => $value) { // 数据解析 $value['attr_ids'] = explode(',',$value['attr_ids']); // 循环处理 foreach ( $value['attr_ids'] as $k=>$attrId ) { // 获取ids对应的name $value['attr_ids'][$k] = $ProductAttr->getValueById($attrId,'name'); } // 数据合并 $value['attr_ids'] = implode(',',$value['attr_ids']); // 重组 $skuList[$key] = $value; } // 获取类型数据 $typeList = $ProductType->getList(); $cityList = $City->getCityList(); $businessList = $Business->getList(); $producerList = $Producer->getList(); // 分配数据 $this->assign('crumbs','新增'); $this->assign('typeList',$typeList); $this->assign('cityList',$cityList); $this->assign('businessList',$businessList); $this->assign('producerList',$producerList); $this->assign('oldData',$oldData); $this->assign('skuList',$skuList); $this->assign('specList',$specList); $this->assign('crumbs','修改'); // 加载模板 return $this->fetch(); } /** * 状态 * * */ public function set_status( Request $request, Model $Model ){ // 验证参数 $request->scene('set_status')->validate(); // 接收参数 $id = request('id',0); $status = request('status',0); // 查询数据 $result = $Model->edit($id,['status'=>$status]); // 提示新增失败 if( !$result ) return json_send(['code'=>'error','msg'=>'设置失败']); // 记录行为 $this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,[],['status'=>$status]); // 告知结果 return json_send(['code'=>'success','msg'=>'设置成功','path'=>'']); } /** * 获取某个类目下的规格 * */ public function get_spec_html( ProductSpec $ProductSpec){ // 接收参数 $typeId = request('type_id',0); // 查询数据 $specList = $ProductSpec->getList(); // 循环处理 foreach ($specList as $key => $value) { if( $value['type_id'] != $typeId ) unset($specList[$key]); } // 分配数据 $this->assign('specList',$specList); // 加载模板 return $this->fetch(); } /** * 获取某个类目下的规格 * */ public function get_sku_html( ProductSpec $ProductSpec,ProductSkus $ProductSkus){ // 接收参数 $attr = request('attr',[]); $id = request('product_id',0); // 产品类型 $oldSkus = $id ? $ProductSkus->getListByProductId($id) : []; // 获取规格属性 $specAttr = $this->getSpecAttr($attr,$ProductSpec); // 组合SKU $brushList = []; // 循环规格属性 foreach ($specAttr as $specId => $value) { // 获取SKU组合 $brushList[$specId] = array_column($value['attr_list'],'name'); } // sku列表 $skuList = $this->brush([],$brushList); // 循环规格属性 foreach ($skuList as $newKey => $new) { // 获取新数据 $new = ['attr_names'=>$new,'price'=>0,'stock'=>0,'status'=>0]; // 循环旧的sku foreach ($oldSkus as $oldKey => $old) { // 如果有相等的规格 if( $old['attr_names'] == $new['attr_names']) { $new['price'] = $old['price']; $new['stock'] = $old['stock']; $new['status'] = $old['status']; } } $skuList[$newKey] = $new; } // 分配数据 $this->assign('specAttr',$specAttr); $this->assign('skuList',$skuList); // 加载模板 return $this->fetch(); } /** * 获取规格属性 * @param ProductSpec $ProductSpec * */ private function getSpecAttr($attr,$ProductSpec,$onlyList=false){ // 组合参数 $specAttr = []; // 循环处理数据 foreach ($attr as $specId => $value) { $specAttr[$specId]['spec_id'] = $specId; $specAttr[$specId]['spec_name'] = $ProductSpec->getOne($specId,'name'); $specAttr[$specId]['attr_list'] = []; foreach ($value['name'] as $key => $name) { // 如果没有名称的,跳过 if( !$name ) continue; // 结果 $temp = ['id'=>0,'spec_id'=>$specId,'thumb'=>'','name'=>'','remark'=>'']; // 获取名称 $temp['name'] = $name; // 获取对应的备注信息 if( !empty($value['remark'][$key]) ) $temp['remark'] = $value['remark'][$key]; if( !empty($value['thumb'][$key]) ) $temp['thumb'] = $value['thumb'][$key]; // 获取对应的数据 $specAttr[$specId]['attr_list'][]= $temp; } // 没有属性的规格,移除 if( !$specAttr[$specId]['attr_list'] ) unset($specAttr[$specId]); } // 仅获取属性列表 if( $onlyList ) { // 属性列表 $attrList = []; // 判断结果 foreach ($specAttr as $value) { // 获取数据 array_push($attrList,...$value['attr_list']); } // 返回结果 $specAttr = $attrList; } // 返回结果 return $specAttr; } /** * 组合SKU * */ private function brush($res = [], $arr = []){ // 获取第一个规格的属性 if (empty($res)) $res = (array) array_shift($arr); // 如果只有一个规格,返回该规格的属性即可 if (empty($arr)) return $res; // 接下来要参与计算的一组属性 $current = array_shift($arr); // 计算的列表 $last = []; // 循环上一次已经算出的集合 foreach ($res as $attr) { foreach ($current as $col_val) { $last[] = $attr . ',' . $col_val; } } return $this->brush($last,$arr); # 递归处理, 直到$arr滚到最后一组属性 } }