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.
yanzong/app/common/service/GoodsCateEs.php

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);
}
}