You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
714 lines
22 KiB
714 lines
22 KiB
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\library\elasticsearch\Client;
|
|
use app\common\model\GoodsCategoryRel;
|
|
use app\common\model\Goods;
|
|
use think\Exception;
|
|
use app\common\library\helper;
|
|
|
|
class GoodsCateEs
|
|
{
|
|
private Client $esService;
|
|
|
|
private string $index_name = 'goods_category';
|
|
|
|
private string $field = 'goods_name,goods_id,category_id,goods_price_min,profit,profit_rate,status,create_time,goods_no,sort,store_id';
|
|
|
|
public function __construct($index_name = "")
|
|
{
|
|
$index_name = $index_name ? $index_name : $this->index_name;
|
|
$this->esService = Client::setEs($index_name);
|
|
}
|
|
|
|
/**
|
|
* 商品列表
|
|
* [list description]
|
|
* @param array $params [description]
|
|
* @param integer $page [description]
|
|
* @param integer $limit [description]
|
|
* @return [type] [description]
|
|
*/
|
|
public function list(array $params = [],$page = 1, $limit = 10)
|
|
{
|
|
|
|
$between = $ins = $orlike = $equal = [];
|
|
//商品名称like查询
|
|
if (isset($params['keyword']) && $params['keyword']) {
|
|
$orlike[] = ['goods_name' => $params['keyword'] ?? ''];
|
|
$orlike[] = ['goods_no' => $params['keyword'] ?? ''];
|
|
}
|
|
$equal[] = ['is_delete' => 0];
|
|
//等于查询
|
|
if (isset($params['status']) && $params['status']) {
|
|
$equal[] = ['status' => $params['status'] ?? 0];
|
|
}
|
|
if (isset($params['store_id']) && $params['store_id']) {
|
|
$equal[] = ['store_id' => $params['store_id'] ?? 0];
|
|
}
|
|
if (isset($params['merchantId']) && $params['merchantId']) {
|
|
$equal[] = ['merchant_id' => $params['merchantId'] ?? 0];
|
|
}
|
|
//between查询
|
|
if (isset($params['fliter_condition']) && $params['fliter_condition']) {
|
|
$fliter_condition = json_decode($params['fliter_condition'], true);
|
|
foreach ($fliter_condition as $key => $value) {
|
|
$between[] = [
|
|
'category_id' => $value['category'],
|
|
'profit' => $value['profit'],
|
|
'profit_rate' => $value['profit_rate']
|
|
];
|
|
}
|
|
}
|
|
//in查询
|
|
if (isset($params['channels']) && !empty($params['channels'])) {
|
|
$ins[] = ['channel' => $params['channels']];
|
|
}
|
|
|
|
$sort = $this->setQuerySort($params);
|
|
$data = $this->esService
|
|
->select($this->field)
|
|
->orlike($orlike)
|
|
->hasChild($between)
|
|
->in($ins)
|
|
->equal($equal)
|
|
->from($page)
|
|
->size($limit)
|
|
->order($sort)
|
|
//->setDebug()
|
|
->query();
|
|
if ($data['data']) {
|
|
$model = new Goods;
|
|
$goods_ids = array_column($data['data'], "goods_id");
|
|
$goods_list = array_column($data['data'], null, "goods_id");
|
|
// var_dump($goods_ids);
|
|
// exit();
|
|
$list = $model->getListByIds($goods_ids, 10);
|
|
if ($list) {
|
|
foreach ($list as &$value) {
|
|
$value['highlight_goods_name'] = $goods_list[$value['goods_id']]['highlight_goods_name'] ?? "";
|
|
}
|
|
}
|
|
|
|
$data['data'] = $list;
|
|
|
|
}
|
|
return $data;
|
|
}
|
|
/**
|
|
* 检索排序条件
|
|
* @param array $param
|
|
* @return array|string[]
|
|
*/
|
|
private function setQuerySort(array $param = []): array
|
|
{
|
|
$params = helper::setQueryDefaultValue($param, [
|
|
'sortType' => 'all', // 排序类型 (all默认 sales销量 price价格)
|
|
'sortPrice' => false, // 价格排序 (true高到低 false低到高)
|
|
]);
|
|
//var_dump($params);
|
|
// 排序规则
|
|
$sort[] = ["_score" => 'desc'];
|
|
if ($params['sortType'] === 'all') {
|
|
$sort[] = ['sort' => 'asc'];
|
|
} elseif ($params['sortType'] === 'sales') {
|
|
$sort[] = ['sales_actual' => 'desc'];
|
|
} elseif ($params['sortType'] === 'price') {
|
|
$sort[] = $params['sortPrice'] ? ['goods_price_min' => 'desc'] : ['goods_price_min' => 'asc'];
|
|
}
|
|
$sort[] = ["goods_id" => 'desc'];
|
|
return $sort;
|
|
}
|
|
|
|
/**
|
|
* 计算总数
|
|
* [count description]
|
|
* @param array $params [description]
|
|
* @param integer $page [description]
|
|
* @param integer $limit [description]
|
|
* @return [type] [description]
|
|
*/
|
|
public function count($params = [],$page = 1, $limit = 10)
|
|
{
|
|
$between = $ins = [];
|
|
$like = ['goods_name' => $params['goods_name'] ?? ''];
|
|
$equal = ['status' => $params['status']];
|
|
if (isset($params['fliter_condition']) && $params['fliter_condition']) {
|
|
$fliter_condition = json_decode($params['fliter_condition'], true);
|
|
foreach ($fliter_condition as $key => $value)
|
|
{
|
|
$between[] = [
|
|
'category_id' => $value['category'],
|
|
'profit' => $value['profit'],
|
|
'profit_rate' => $value['profit_rate']
|
|
];
|
|
}
|
|
unset($params['fliter_condition']);
|
|
|
|
}
|
|
|
|
if (!empty($params['channels'])) {
|
|
$ins = ['channels' => $params['channels']];
|
|
unset($params['channels']);
|
|
}
|
|
return $this->esService
|
|
//->setDebug()
|
|
->like($like)
|
|
->hasChild($between)
|
|
->in($ins)
|
|
->equal($equal)
|
|
->from($page)
|
|
->size($limit)
|
|
->query(true);
|
|
}
|
|
|
|
|
|
/**
|
|
* 更新商品
|
|
*/
|
|
public function updateData($goods_id, $data)
|
|
{
|
|
return $this->esService->update($goods_id, $data);
|
|
}
|
|
|
|
/**
|
|
* 查询商品详情
|
|
*/
|
|
public function detail($goods_id)
|
|
{
|
|
return $this->esService->getDoc($goods_id);
|
|
}
|
|
|
|
/**
|
|
* 创建商品
|
|
*/
|
|
public function createData($goods_id, $goods)
|
|
{
|
|
$list['goods_category_field'] = [
|
|
'name' => 'goods'
|
|
];
|
|
return $this->esService->addDoc('goods_'.$goods_id, $goods)->asArray();
|
|
}
|
|
|
|
/**
|
|
* 创建商品分类
|
|
*/
|
|
public function createCateData($id, $value)
|
|
{
|
|
|
|
$parent_id = 'goods_'.$value['goods_id'];
|
|
$doc = [
|
|
'id' => $value['id'],
|
|
'category_id' => $value['category_id'],
|
|
'cate_store_id' => $value['store_id'],
|
|
//'cate_create_time' => strtotime($value['create_time']),
|
|
'cate_create_time' => $value['create_time'],
|
|
'goods_category_field' => [
|
|
'name' => 'category',
|
|
'parent' => $parent_id
|
|
],
|
|
|
|
];
|
|
return $this->esService->addChildDoc('category_'.$id, $parent_id, $doc)->asArray();
|
|
}
|
|
|
|
|
|
/**
|
|
* 批量创建数据
|
|
* @return
|
|
*/
|
|
public function batchCreateData()
|
|
{
|
|
for ($page = 1; $page <= 224; $page++)
|
|
{
|
|
$this->addData($page);
|
|
//sleep(1);
|
|
}
|
|
}
|
|
|
|
public function addData($page)
|
|
{
|
|
$goods_cate_list = GoodsCategoryRel::where('category_id', '>', 0)
|
|
->where('id', '>', 1628858)
|
|
->where('goods_id', '>', 0)
|
|
//->order('goods_id desc')
|
|
->page($page)
|
|
->limit(5000)
|
|
->select()
|
|
->toArray();
|
|
// dd($goods_cate_list);
|
|
$i = 0;
|
|
if (!empty($goods_cate_list)){
|
|
foreach ($goods_cate_list as $value) {
|
|
$parent_id = 'goods_'.$value['goods_id'];
|
|
$doc = [
|
|
'id' => $value['id'],
|
|
'category_id' => $value['category_id'],
|
|
'cate_store_id' => $value['store_id'],
|
|
'cate_create_time' => strtotime($value['create_time']),
|
|
//'cate_create_time' => $value['create_time'],
|
|
'goods_category_field' => [
|
|
'name' => 'category',
|
|
'parent' => $parent_id
|
|
],
|
|
|
|
];
|
|
// dd($doc);
|
|
$res = $this->esService->addChildDoc('category_'.$value['id'], $parent_id, $doc)->asArray();
|
|
if($res['result'] == 'created')
|
|
{
|
|
$i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo('同步成功'.$i.'条数据').PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* 批量创建商品
|
|
* @return
|
|
*/
|
|
public function batchCreateGoodsData()
|
|
{
|
|
for ($page = 1; $page <= 173; $page++)
|
|
{
|
|
$this->addGoodsData($page);
|
|
//sleep(1);
|
|
}
|
|
}
|
|
|
|
public function addGoodsData($page)
|
|
{
|
|
$goods_list = Goods::where('goods_id', '>', 0)
|
|
//->order('goods_id desc')
|
|
->page($page)
|
|
->limit(2000)
|
|
->select()
|
|
->toArray();
|
|
// dd($goods_list);
|
|
|
|
$i = 0;
|
|
foreach ($goods_list as $value) {
|
|
//$value['create_time'] = $value['create_time'];
|
|
//$value['update_time'] = $value['update_time'];
|
|
$value['delivery_type'] = implode(',', $value['delivery_type']);
|
|
$value['goods_category_field'] = [
|
|
'name' => 'goods'
|
|
];
|
|
$res = $this->esService->addDoc('goods_'.$value['goods_id'], $value)->asArray();
|
|
if($res['result'] == 'created')
|
|
{
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
echo('同步成功'.$i.'条数据').PHP_EOL;
|
|
}
|
|
/**
|
|
* 批量创建商品分类
|
|
* [batchCreateGoodsCategory description]
|
|
* @param integer $goods_cate_id [description]
|
|
* @return [type] [description]
|
|
*/
|
|
public function batchCreateGoodsCategory($goods_cate_id = 0, $storeId = 0){
|
|
$where = [];
|
|
if ($storeId) {
|
|
$where['store_id'] = $storeId;
|
|
}
|
|
while (TRUE) {
|
|
echo $goods_cate_id.PHP_EOL;
|
|
$goods_cate_list = GoodsCategoryRel::where('id', '>', $goods_cate_id)
|
|
->where($where)
|
|
->where('category_id', '>', 0)
|
|
->where('goods_id', '>', 0)
|
|
->order('id asc')
|
|
->limit(1000)
|
|
->select()
|
|
->toArray();
|
|
if (!$goods_cate_list) {
|
|
echo "没有商品分类了".PHP_EOL;
|
|
return false;
|
|
}
|
|
foreach ($goods_cate_list as $goods_cate) {
|
|
$res = $this->createCateData($goods_cate['id'], $goods_cate);
|
|
if($res['result'] == 'created' || $res['result'] == 'updated'){
|
|
echo('商品分类同步成功'.$goods_cate['id'].'条数据').PHP_EOL;
|
|
}
|
|
}
|
|
$goods_cate_id = end($goods_cate_list)['id'];
|
|
}
|
|
}
|
|
/**
|
|
* 批量创建商品
|
|
* [batchCreateGoods description]
|
|
* @param integer $goods_id [description]
|
|
* @return [type] [description]
|
|
*/
|
|
public function batchCreateGoods($goods_id = 0, $storeId = 0){
|
|
$where = [];
|
|
if ($storeId) {
|
|
$where['store_id'] = $storeId;
|
|
}
|
|
while (TRUE) {
|
|
echo $goods_id.PHP_EOL;
|
|
$goods_list = Goods::where('goods_id', '>', $goods_id)
|
|
->where($where)
|
|
->order('goods_id asc')
|
|
->limit(1000)
|
|
->select()
|
|
->toArray();
|
|
//dd($goods_list);
|
|
if (!$goods_list) {
|
|
echo "没有商品了".PHP_EOL;
|
|
return false;
|
|
}
|
|
foreach ($goods_list as $goods) {
|
|
$res = $this->createData($goods['goods_id'], $goods);
|
|
if($res['result'] == 'created' || $res['result'] == 'updated'){
|
|
echo('商品同步成功'.$goods['goods_id'].'条数据').PHP_EOL;
|
|
}
|
|
}
|
|
$goods_id = end($goods_list)['goods_id'];
|
|
|
|
}
|
|
}
|
|
/**
|
|
* 添加或者更新商品
|
|
* [addOrUpdateGoodsAndGoodsCate description]
|
|
* @param [type] $goods_list [description]
|
|
*/
|
|
public function addOrUpdateGoodsAndGoodsCate($goods_list){
|
|
if (!$goods_list) {
|
|
return true;
|
|
}
|
|
$goods_cate_list = GoodsCategoryRel::whereIn('goods_id', array_column($goods_list, "goods_id"))->select()->toArray();
|
|
$arr = [];
|
|
foreach ($goods_cate_list as $key => $value) {
|
|
$arr[$value['goods_id']][] = $value;
|
|
}
|
|
foreach ($goods_list as &$goods) {
|
|
$goods['create_time'] = date("Y-m-d H:i:s", $goods['create_time']);
|
|
$goods['update_time'] = date("Y-m-d H:i:s", $goods['update_time']);
|
|
$this->createData($goods['goods_id'], $goods);
|
|
$goods_cate_items = $arr[$goods['goods_id']] ?? [];
|
|
if (!$goods_cate_items) {
|
|
continue;
|
|
}
|
|
foreach ($goods_cate_items as $goods_cate) {
|
|
$this->createCateData($goods_cate['id'], $goods_cate);
|
|
}
|
|
}
|
|
return true;
|
|
|
|
}
|
|
/**
|
|
* 批量删除父子关系的数据
|
|
* [batchDelete description]
|
|
* @param [type] $parentIds [description]
|
|
* @return [type] [description]
|
|
*/
|
|
public function batchDelete($parentIds){
|
|
$bulkBody = [];
|
|
foreach ($parentIds as $parentId) {
|
|
$bulkBody[] = [
|
|
'delete' => [
|
|
'_index' => $this->index_name,
|
|
//'_type' => '_doc', // 在 Elasticsearch 7.x 之前的版本中,类型字段是必需的
|
|
'_id' => 'goods_'.$parentId
|
|
]
|
|
];
|
|
}
|
|
return $this->esService->batchDelete($bulkBody);
|
|
}
|
|
/**
|
|
* 删除商品
|
|
*/
|
|
public function delete($goods_id)
|
|
{
|
|
return $this->esService->deleteDoc($goods_id);
|
|
}
|
|
|
|
/**
|
|
* 删除索引
|
|
*/
|
|
public function deleteIndex()
|
|
{
|
|
return $this->esService->deleteIndexNew();
|
|
}
|
|
|
|
/**
|
|
* 创建商品分类关联索引
|
|
*/
|
|
public function createGoodsCateIndex()
|
|
{
|
|
|
|
$mapping = [
|
|
'properties' => [
|
|
'goods_id' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'goods_type' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'goods_name' => [
|
|
'type' => 'text',
|
|
"analyzer" => "ik_max_word",
|
|
"search_analyzer" => "ik_smart"
|
|
],
|
|
'goods_no' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'video_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'brand_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'video_cover_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'selling_point' => [
|
|
'type' => 'keyword',
|
|
],
|
|
'spec_type' => [
|
|
'type' => 'integer'
|
|
],
|
|
'cost_price_min' => [
|
|
'type' => 'float'
|
|
],
|
|
'goods_price_min' => [
|
|
'type' => 'float'
|
|
],
|
|
'goods_price_max' => [
|
|
'type' => 'float'
|
|
],
|
|
'line_price_min' => [
|
|
'type' => 'float'
|
|
],
|
|
'line_price_max' => [
|
|
'type' => 'float'
|
|
],
|
|
'stock_total' => [
|
|
'type' => 'integer'
|
|
],
|
|
'deduct_stock_type' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_restrict' => [
|
|
'type' => 'integer'
|
|
],
|
|
'restrict_total' => [
|
|
'type' => 'integer'
|
|
],
|
|
'restrict_single' => [
|
|
'type' => 'integer'
|
|
],
|
|
'content' => [
|
|
'type' => 'text',
|
|
],
|
|
'sales_initial' => [
|
|
'type' => 'integer'
|
|
],
|
|
'delivery_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_points_gift' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_points_discount' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_alone_points_discount' => [
|
|
'type' => 'integer'
|
|
],
|
|
'points_discount_config' => [
|
|
'type' => 'text'
|
|
],
|
|
'is_enable_grade' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_alone_grade' => [
|
|
'type' => 'integer'
|
|
],
|
|
'alone_grade_equity' => [
|
|
'type' => 'text'
|
|
],
|
|
'is_ind_dealer' => [
|
|
'type' => 'integer'
|
|
],
|
|
'dealer_money_type' => [
|
|
'type' => 'integer'
|
|
],
|
|
'first_money' => [
|
|
'type' => 'float'
|
|
],
|
|
'second_money' => [
|
|
'type' => 'float'
|
|
],
|
|
'third_money' => [
|
|
'type' => 'float'
|
|
],
|
|
'is_ind_delivery_type' => [
|
|
'type' => 'integer'
|
|
],
|
|
'delivery_type' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'status' => [
|
|
'type' => 'integer'
|
|
],
|
|
'sort' => [
|
|
'type' => 'integer'
|
|
],
|
|
'store_id' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'merchant_id' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'create_time' => [
|
|
'type' => 'date',
|
|
'format' => 'yyyy-MM-dd HH:mm:ss'
|
|
],
|
|
'update_time' => [
|
|
'type' => 'date',
|
|
'format' => 'yyyy-MM-dd HH:mm:ss'
|
|
],
|
|
'is_brand' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_new' => [
|
|
'type' => 'integer'
|
|
],
|
|
'paihang' => [
|
|
'type' => 'integer'
|
|
],
|
|
'remaizhishu' => [
|
|
'type' => 'integer'
|
|
],
|
|
'spu_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'channel' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'unicode' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'is_in_store' => [
|
|
'type' => 'integer'
|
|
],
|
|
'profit' => [
|
|
'type' => 'float'
|
|
],
|
|
'profit_rate' => [
|
|
'type' => 'float'
|
|
],
|
|
'cmmdty_model'=> [
|
|
'type' => 'keyword'
|
|
],
|
|
'remark' => [
|
|
'type' => 'text'
|
|
],
|
|
'sale_areas' => [
|
|
'type' => 'text'
|
|
],
|
|
'sale_areas_id' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'data_type' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_pool' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_self' => [
|
|
'type' => 'integer'
|
|
],
|
|
'link' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'origin_goods_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'link_other' => [
|
|
'type' => 'text'
|
|
],
|
|
'goods_no_other' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'region' => [
|
|
'type' => 'text'
|
|
],
|
|
'region_text' => [
|
|
'type' => 'text'
|
|
],
|
|
'specific_value' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'cate_status' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_check' => [
|
|
'type' => 'integer'
|
|
],
|
|
'goods_source' => [
|
|
'type' => 'keyword'
|
|
],
|
|
'delivery_time' => [
|
|
'type' => 'integer'
|
|
],
|
|
'distribute_price' => [
|
|
'type' => 'float'
|
|
],
|
|
'shop_price' => [
|
|
'type' => 'float'
|
|
],
|
|
'is_has_banner' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_has_detail' => [
|
|
'type' => 'integer'
|
|
],
|
|
'is_jingpin' => [
|
|
'type' => 'integer'
|
|
],
|
|
'sale_time' => [
|
|
'type' => 'integer'
|
|
],
|
|
'markup_rate' => [
|
|
'type' => 'integer'
|
|
],
|
|
'id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'category_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'cate_store_id' => [
|
|
'type' => 'integer'
|
|
],
|
|
'cate_create_time' => [
|
|
'type' => 'date',
|
|
'format' => 'yyyy-MM-dd HH:mm:ss'
|
|
],
|
|
'goods_category_field' => [
|
|
'type' => 'join',
|
|
'relations' => [
|
|
'goods' => 'category'
|
|
]
|
|
]
|
|
]
|
|
];
|
|
//var_dump($mapping);
|
|
//exit();
|
|
return $this->esService->createIndexNew($mapping);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} |