<?php namespace App\Http\Services; use App\Http\Controllers\Filter\SkuListFilter; use App\Model\IntracodeModel; use App\Model\LogModel; use App\Model\RedisModel; use App\Model\SkuUploadLogModel; use App\Model\SupplierChannelModel; use App\Model\TagsModel; use GuzzleHttp\Client; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Redis; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; class SkuService extends BaseService { const OPERATE_TYPE_PUTAWAY = 1; const OPERATE_TYPE_OFF_SHELVES = -1; const LONG_TERM_TIMESTAMP = 2051193600; //获取供应商列表需要统计的信息 public function getSkuList() { $data['data']['goods_id'] = []; $filter = new SkuListFilter(); $map = $filter->listFilter(); $url = env('ES_SKU_URL', ''); $map['show_status'] = 1; $map['no_rule'] = 1122; $return = curl($url, $map, 1); $data = json_decode($return, true); $list = []; if (isset($data['error_code']) && $data['error_code'] == 0) { $redis = new RedisModel; //处理供应商 $spuRedis = Redis::connection('spu'); foreach ($data['data']['goods_id'] as $k => $goodsId) { $uploadItemService = new SkuUploadItemService(); $auditData = $uploadItemService->getSkuAuditData($data['data']['goods_id']); if (empty($goodsId) || $goodsId == 0) { continue; } $sku = json_decode($redis->hget('sku', $goodsId), true); if (empty($sku)) { $sku = ['goods_id' => $goodsId]; $list[] = $sku; continue; } //赋值 $sku['goods_id'] = $goodsId; $sku['update_time'] = date('Y-m-d H:i:s', $sku['update_time']); $sku['status_name'] = Config('field.GoodsStatus')[$sku['goods_status']]; if (!empty($auditData[$goodsId])) { $sku['audit_time'] = date('Y-m-d H:i:s', $auditData[$goodsId]['audit_time']); $sku['audit_user'] = $auditData[$goodsId]['audit_name']; } //添加sku是否过期 $sku['is_expire'] = $data['data']['status'][$goodsId] && $data['data']['status'][$goodsId] > 0 ? 0 : 1; $spu = json_decode($spuRedis->hget('spu', $sku['spu_id']), true); $sku['spu_name'] = $spu['spu_name']; //型号处理 if (empty($sku['goods_name']) && !empty($spu)) { $sku['goods_name'] = $spu['spu_name']; } $sku['encap'] = array_get($spu, 'encap', ''); //制造商处理 if (empty($sku['brand_name']) && !empty($spu)) { $brand = $redis->hget('brand', $spu['brand_id']); if ($brand) { $sku['brand_name'] = $brand; } else { $brand = DB::connection('spu')->table('brand')->where('brand_id', $spu['brand_id'])->lists('brand_name', 'brand_id'); if ($brand) { $sku['brand_name'] = $brand[$spu['brand_id']]; } } } $standardBrandId = array_get($spu, 's_brand_id'); if ($standardBrandId) { $standardBrand = $redis->hget('standard_brand', $standardBrandId); $standardBrand = json_decode($standardBrand, true); $sku['standard_brand_name'] = $standardBrand['brand_name']; } //获取价格 $moqPrice = []; if (!empty($sku['ladder_price'])) { $priceService = new PriceService(); $moqPrice = $priceService->getMoqPrice($sku['ladder_price']); if (!is_array($sku['ladder_price'])) { $sku['ladder_price'] = json_decode($sku['ladder_price'], true); } foreach ($sku['ladder_price'] as &$ladder) { $ladder['purchases'] = $ladder['purchases'] == 0 ? $sku['moq'] : $ladder['purchases']; } unset($ladder); } $sku['cn_price'] = array_get($moqPrice, 'price_cn'); $sku['us_price'] = array_get($moqPrice, 'price_us'); //获取是否精选和标签 $goodsTag = $this->getGoodsTag($sku['goods_id']); $sku['goods_label'] = array_get($goodsTag, 'goods_label', ''); if ($this->orgId == 1) { $sku['goods_label_name'] = array_get(config('field.SkuGoodsLabel'), $sku['goods_label'], ''); } else { $sku['goods_label_name'] = array_get(config('field.SkuGoodsLabelForIedge'), $sku['goods_label'], ''); } $sku['tags'] = array_get($goodsTag, 'tags', []); if (!empty($sku['tags'])) { $sku['is_prefer'] = in_array(1, $sku['tags']) ? 1 : 0; } else { $sku['is_prefer'] = 0; } $list[] = $sku; } $intraCodeModel = new IntracodeModel(); $encodedList = array_column($list, 'encoded'); $encodedUsers = $intraCodeModel->getEncodedUserByEncoded($encodedList); $list = array_map(function ($item) use ($encodedUsers, $redis) { if (empty($item['goods_name'])) { return $item; } $encoded = array_get($item, 'encoded', 0); $item['encoded_user_name'] = array_get($encodedUsers, $encoded, ''); $item['moq'] = $item['moq'] ?: 0; $item['stock'] = $item['stock'] ?: 0; $item['cp_time'] = $item['cp_time'] ? date('Y-m-d H:i:s', $item['cp_time']) : ''; $goodsTag = $redis->hget('goods_tag', $item['goods_id']); $goodsTag = $goodsTag ? json_decode($goodsTag, true) : ''; $item['sku_tags'] = $goodsTag ? array_get($goodsTag, 'customer_tag') : ''; //去db找出相关数据,有些数据只能去db找.... $dbInfo = getSpuSkuDb($item['goods_id']); $connection = DB::connection($dbInfo["db"]); $table = $dbInfo['table']; $selectFields = ['goods_id', 'create_time', 'eccn', 'source', 'encoded', 'org_id']; $skuDBData = $connection->table($table)->select($selectFields)->where('goods_id', $item['goods_id'])->first(); $skuDBData = $skuDBData ? $skuDBData : []; $item['source_name'] = array_get(config('field.SkuSource'), @$skuDBData['source'], ''); $item['org_name'] = array_get(config('field.SkuOrgList'), @$skuDBData['org_id'], ''); return $item; }, $list); $list = $this->transformInvalidSkuTag($list); } return [ 'list' => $list, 'total' => !empty($data['data']['total']) ? $data['data']['total'] : 0 ]; } //这个是用来区分商品标签是否有效 public function transformInvalidSkuTag($skuList) { foreach ($skuList as &$sku) { $validGoodsTags = TagsModel::where('tag_use', 16)->where('tag_type', 2) ->where('status', TagsModel::STATUS_OK)->pluck('tag_name')->toArray(); $skuTags = !empty($sku['sku_tags']) ? explode(' ', $sku['sku_tags']) : []; if (empty($sku['sku_tags'])) { $sku['invalid_sku_tags'] = $sku['valid_sku_tags'] = ''; continue; } $invalidSkuTags = $validSkuTags = []; //然后判断哪些是离职,哪些是在职的 foreach ($skuTags as $tag) { if (empty($tag)) { continue; } if (!in_array($tag, $validGoodsTags)) { $invalidSkuTags[] = $tag; } else { $validSkuTags[] = $tag; } } $sku['invalid_sku_tags'] = $invalidSkuTags ? implode(',', $invalidSkuTags) : ''; $sku['valid_sku_tags'] = $validSkuTags ? implode(',', $validSkuTags) : ''; } unset($sku); return $skuList; } //设置精选 public function setPreferSku($skuIds, $prefer) { //直接操作redis的goods_tag,然后推送es的修改任务即可 $redis = new RedisModel(); foreach ($skuIds as $skuId) { $goodsTag = $redis->hget('goods_tag', $skuId); $goodsTag = json_decode($goodsTag, true); if (!empty($goodsTag)) { $tag = array_get($goodsTag, 'tags', []); $tag = $tag ?: []; //判断是否有精选标签(1),而且操作是取消精选 if ($prefer == -1) { if (in_array(1, $tag)) { $key = array_search(1, $tag); if ($key !== false) { unset($goodsTag['tags'][$key]); } } } else { if (!in_array(1, $tag)) { $tag[] = 1; $goodsTag['tags'] = $tag; } } $result = $redis->hset('goods_tag', $skuId, json_encode($goodsTag)); } else { //没有直接跳过 continue; } if ($result === false) { return false; } $redis->lpush('update_list_sku', $skuId); } return true; } private function getGoodsTag($skuId) { $redis = new RedisModel(); $result = $redis->hget('goods_tag', $skuId); return $result ? json_decode($result, true) : []; } //批量上下架队列 public function batchOffShelfSkuQueue($data) { $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'), config('database.connections.rabbitmq2.port'), config('database.connections.rabbitmq2.login'), config('database.connections.rabbitmq2.password')); $channel = $conn->channel(); $channel->queue_declare('lie_footstone_batch_downsku_queue', false, true, false, false); $msg = new AMQPMessage(json_encode($data), array('content_type' => 'text/plain')); $channel->basic_publish($msg, '', 'lie_footstone_batch_downsku_queue'); } //批量修改内部编码 public function batchUpdateEncodedQueue($data) { $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'), config('database.connections.rabbitmq2.port'), config('database.connections.rabbitmq2.login'), config('database.connections.rabbitmq2.password')); $channel = $conn->channel(); $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false); $msg = new AMQPMessage(json_encode($data), array('content_type' => 'text/plain')); $channel->basic_publish($msg, '', 'lie_footstone_update_sku_info_queue'); } //批量修改商品信息队列 public function batchUpdateSkuInfoQueue($data) { $conn = new AMQPStreamConnection(config('database.connections.rabbitmq2.host'), config('database.connections.rabbitmq2.port'), config('database.connections.rabbitmq2.login'), config('database.connections.rabbitmq2.password')); $channel = $conn->channel(); $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false); $msg = new AMQPMessage(json_encode($data), array('content_type' => 'text/plain')); $channel->basic_publish($msg, '', 'lie_footstone_update_sku_info_queue'); } //批量更新sku状态,走队列的 public function batchUpdateSkuStatus($data) { try { $skuIds = explode(',', $data['sku_ids']); //构建队列数据 //上架 $queueData = []; if ($data['operate_type'] == self::OPERATE_TYPE_PUTAWAY) { $queueName = 'lie_footstone_batch_upsku_queue'; $data['cp_time'] = $data['is_long_term'] == 1 ? self::LONG_TERM_TIMESTAMP : strtotime($data['cp_time']); foreach ($skuIds as $skuId) { $queueData[] = [ 'sku_id' => $skuId, 'cp_time' => $data['cp_time'], ]; } } else { $queueName = 'lie_footstone_batch_downsku_queue'; $queueData['down_type'] = 2; $queueData['data'] = $skuIds; } QueueService::publishQueueSecond($queueName, $queueData); } catch (\Exception $exception) { return $exception; } return true; } //获取第一次上传sku时间和最后一次上传sku时间 public static function getUploadTimeBySupplierCode($supplierCode = '', $type = 'first') { if ($type == 'last') { $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,max(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code = ?'; } else { $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,min(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code = ?'; } $time = 0; $data = DB::connection('spu') ->select($rawSql, [$supplierCode]); foreach ($data as $item) { if ($item['supplier_code'] == $supplierCode) { $time = $item['create_time']; } } return $time; } //获取第一次上传sku时间和最后一次上传sku时间 public static function getUploadTimeBySupplierCodes($supplierCodes = [], $type = 'first') { $supplierCodesTemp = array_map(function ($value) { return "'" . $value . "'"; }, $supplierCodes); $supplierCodeInSql = implode(',', $supplierCodesTemp); if (empty($supplierCodeInSql)) { return []; } if ($type == 'last') { $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,max(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code IN (' . $supplierCodeInSql . ')'; } else { $rawSql = 'SELECT supplier_code,create_time FROM (SELECT supplier_code,min(create_time) AS create_time FROM lie_sku_upload_log GROUP BY supplier_code) AS temp WHERE supplier_code IN (' . $supplierCodeInSql . ')'; } $data = DB::connection('spu') ->select($rawSql); $result = []; foreach ($supplierCodes as $supplierCode) { $result[$supplierCode] = 0; foreach ($data as $item) { if ($item['supplier_code'] == $supplierCode) { $result[$supplierCode] = $item['create_time']; } } } return $result; } public function getSystemTags() { $tags = TagsModel::where('tag_use', 16)->where('tag_type', 2)->where('status', TagsModel::STATUS_OK) ->pluck('tag_name', 'tag_name')->toArray(); $result = []; foreach ($tags as $key => $value) { if (empty($value)) { continue; } $result[] = [ 'tag_id' => $value, 'tag_name' => $value, ]; } return $result; } public function batchAddSkuTags($type, $supplierCode, $skuIds, $skuTags) { $skuTags = trim($skuTags, ','); //判断是类型1(针对商品)还是类型2(针对供应商) if ($type == 1) { $redis = new RedisModel(); $skuIds = explode(',', $skuIds); $skuTags = explode(',', $skuTags); foreach ($skuIds as $skuId) { $skuId = (int)$skuId; $goodsTag = $redis->hget('goods_tag', $skuId); if ($goodsTag) { $goodsTag = json_decode($goodsTag, true); $goodsTag['customer_tag'] = implode(" ", $skuTags); } else { $goodsTag = [ 'customer_tag' => implode(" ", $skuTags), ]; } $redis->hset('goods_tag', $skuId, json_encode($goodsTag)); $redis->lpush('update_list_sku', $skuId); } } else { $skuTags = explode(',', $skuTags); $data = [ 'canal' => $supplierCode, 'customer_tag' => implode(" ", $skuTags), ]; $this->batchUpdateSkuInfoQueue($data); } } //设置上架有效期 public function setSupplierSkuCpTimeLimit($setType, $supplierGroup, $supplierCode, $cpTimeData) { $dayType = $cpTimeData['day_type']; $cpTimeDay = (int)$cpTimeData['cp_time_day']; $futuresDayType = $cpTimeData['futures_day_type']; $futuresCpTimeDay = (int)$cpTimeData['futures_cp_time_day']; if ($dayType == 2) { $cpTimeDay = -1; } if ($futuresDayType == 2) { $futuresCpTimeDay = -1; } $redis = new RedisModel(); //批量设置 if ($setType == 1) { $supplierIds = SupplierChannelModel::where('supplier_group', $supplierGroup)->where('is_type', 0) ->pluck('supplier_id')->toArray(); $supplierIds = collect($supplierIds)->chunk(300)->toArray(); foreach ($supplierIds as $supplierIdList) { $supplierIdList = array_values($supplierIdList); //先去批量设置过期时间限制天数 SupplierChannelModel::whereIn('supplier_id', $supplierIdList)->update([ 'cp_time_day' => $cpTimeDay, 'futures_cp_time_day' => $futuresCpTimeDay, ]); foreach ($supplierIdList as $supplierId) { $ruler = $redis->hget('supplier_sku_upload_ruler_v2', $supplierId); if ($ruler) { $ruler = json_decode($ruler, true); } $ruler['upload_validity_period'] = $cpTimeDay; $ruler['upload_futures_goods_validity_period'] = $futuresCpTimeDay; $ruler = json_encode($ruler); $redis->hset('supplier_sku_upload_ruler_v2', $supplierId, $ruler); } $cpTimeDayStr = $cpTimeDay == -1 ? '无限制' : $cpTimeDay; (new LogService())->BatchAddIgnoreAuditLogs($supplierIdList, LogModel::UPDATE_OPERATE, '批量配置供应商sku上架有效期', '上架有效期修改为' . $cpTimeDayStr . '天,期货有效期修改为' . $futuresCpTimeDay . '天'); } } //单个设置 if ($setType == 2) { $supplier = SupplierChannelModel::where('supplier_code', $supplierCode)->first(); if (!empty($supplier)) { $supplier = $supplier->toArray(); $supplierId = $supplier['supplier_id']; //先去批量设置过期时间限制天数 SupplierChannelModel::where('supplier_id', $supplierId)->update([ 'cp_time_day' => $cpTimeDay, 'futures_cp_time_day' => $futuresCpTimeDay, ]); $originDay = '[ ]'; $originFuturesDay = '[ ]'; $ruler = $redis->hget('supplier_sku_upload_ruler_v2', $supplierId); if ($ruler) { $ruler = json_decode($ruler, true); $originDay = array_get($ruler, 'upload_validity_period'); $originDay = $originDay ? $originDay . '天' : '[ ]'; $originFuturesDay = array_get($ruler, 'upload_futures_goods_validity_period'); $originFuturesDay = $originFuturesDay ? $originFuturesDay . '天' : '[ ]'; } $ruler['upload_validity_period'] = $cpTimeDay; $ruler['upload_futures_goods_validity_period'] = $futuresCpTimeDay; (new SupplierService())->saveSkuCpTimeRulerToRedis($supplierId, $ruler); $cpTimeDay = $cpTimeDay == -1 ? '无限制' : $cpTimeDay; (new LogService())->AddIgnoreAuditCheckLog($supplierId, LogModel::UPDATE_OPERATE, '批量配置供应商sku上架有效期', '上架有效期修由' . $originDay . '改为' . $cpTimeDay . '天,期货有效期由' . $originFuturesDay . '改为' . $futuresCpTimeDay . '天'); } } } //设置供应商相关sku的队列数据 public function setSupplierSkuCpTimeLimitQueue($supplier) { } public function batchUpdateGoodsLabel($type, $supplierCode, $skuIds, $goodsLabel) { $goodsLabel = (int)$goodsLabel; //判断是类型1(针对商品)还是类型2(针对供应商) if ($type == 1) { self::updateGoodsLabel($skuIds, $goodsLabel); } else { $data = [ 'canal' => $supplierCode, 'goods_label' => (int)$goodsLabel, ]; $this->batchUpdateSkuInfoQueue($data); } } public static function updateGoodsLabel($skuIds, $goodsLabel) { if (!is_array($skuIds)) { $skuIds = explode(',', trim($skuIds)); } $conn = new AMQPStreamConnection(config('database.connections.rabbitmqSku.host'), config('database.connections.rabbitmqSku.port'), config('database.connections.rabbitmqSku.login'), config('database.connections.rabbitmqSku.password')); foreach ($skuIds as $skuId) { $channel = $conn->channel(); $channel->queue_declare('lie_footstone_update_sku_info_queue', false, true, false, false); if (empty($skuId)) { continue; } $msg = new AMQPMessage(json_encode([[ 'goods_id' => $skuId, 'goods_label' => $goodsLabel, ]]), array('content_type' => 'text/plain')); $channel->basic_publish($msg, '', 'sku_update'); } } }