2018-12-28 18:58:37 +08:00
< ? php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
2021-03-16 10:34:52 +08:00
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
2018-12-28 18:58:37 +08:00
// +----------------------------------------------------------------------
2021-03-16 10:34:52 +08:00
// | Licensed ( https://opensource.org/licenses/mit-license.php )
2018-12-28 18:58:37 +08:00
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service ;
2021-07-18 23:42:10 +08:00
use think\facade\Db ;
2022-04-21 22:08:53 +08:00
use app\service\SystemService ;
2021-04-11 15:51:06 +08:00
use app\service\SystemBaseService ;
2019-01-17 00:37:20 +08:00
use app\service\ResourcesService ;
2024-10-21 10:51:14 +08:00
use app\service\AttachmentService ;
2023-03-21 22:39:13 +08:00
use app\service\UserService ;
2019-01-17 00:37:20 +08:00
use app\service\BrandService ;
use app\service\RegionService ;
2020-07-16 22:34:56 +08:00
use app\service\WarehouseGoodsService ;
2023-02-08 21:20:04 +08:00
use app\service\GoodsCategoryService ;
2022-08-26 13:45:23 +08:00
use app\service\GoodsSpecService ;
2021-01-10 13:18:35 +08:00
use app\service\GoodsParamsService ;
2021-06-03 14:15:24 +08:00
use app\service\GoodsCommentsService ;
2018-12-28 18:58:37 +08:00
/**
* 商品服务层
* @ author Devil
* @ blog http :// gong . gg /
* @ version 0.0 . 1
* @ datetime 2016 - 12 - 01 T21 : 51 : 08 + 0800
*/
class GoodsService
{
2020-10-12 10:36:57 +08:00
// 规格转成字符串分割符号
public static $goods_spec_to_string_separator = '{|}' ;
2023-02-09 19:04:35 +08:00
/**
* 商品规格默认名称
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 02 - 09
* @ desc description
*/
public static function GoodsSpecDefaultName ()
{
return MyLang ( 'common_service.goods.base_goods_spec_default_name' );
}
2018-12-28 18:58:37 +08:00
/**
* 获取首页楼层数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 08 - 29
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function HomeFloorList ( $params = [])
2018-12-28 18:58:37 +08:00
{
2025-09-23 21:22:38 +08:00
// 是否读取规格,购物车
$is_spec = ( ! isset ( $params [ 'is_spec' ]) || $params [ 'is_spec' ] == 1 ) ? 1 : 0 ;
$is_cart = ( ! isset ( $params [ 'is_cart' ]) || $params [ 'is_cart' ] == 1 ) ? 1 : 0 ;
2020-04-03 16:28:01 +08:00
// 缓存
2022-04-21 22:08:53 +08:00
$key = SystemService :: CacheKey ( 'shopxo.cache_goods_floor_list_key' );
2021-07-18 23:42:10 +08:00
$data = MyCache ( $key );
2023-08-27 16:59:15 +08:00
if ( $data === null || MyEnv ( 'app_debug' ) || MyC ( 'common_data_is_use_cache' ) != 1 )
2018-12-28 18:58:37 +08:00
{
2020-04-03 16:28:01 +08:00
// 商品大分类
2023-02-08 21:20:04 +08:00
$data = GoodsCategoryService :: GoodsCategoryList ([ 'where' => [
2021-06-11 16:18:21 +08:00
[ 'pid' , '=' , 0 ],
[ 'is_home_recommended' , '=' , 1 ],
[ 'is_enable' , '=' , 1 ],
2022-04-18 00:54:11 +08:00
]]);
2020-04-03 16:28:01 +08:00
if ( ! empty ( $data ))
2018-12-28 18:58:37 +08:00
{
2020-11-26 18:34:41 +08:00
// 楼层左侧商品分类从配置中读取
$floor_left_top_category = MyC ( 'home_index_floor_left_top_category' );
if ( ! empty ( $floor_left_top_category ))
2020-08-17 11:26:39 +08:00
{
2020-11-26 18:34:41 +08:00
$floor_left_top_category = json_decode ( $floor_left_top_category , true );
2020-08-17 11:26:39 +08:00
}
2020-09-15 21:57:19 +08:00
// 楼层关键字从配置中读取
$floor_keywords = MyC ( 'home_index_floor_top_right_keywords' );
if ( ! empty ( $floor_keywords ))
{
$floor_keywords = json_decode ( $floor_keywords , true );
}
2020-11-25 22:59:17 +08:00
// 数据模式
// 0 自动模式
// 1 手动模式
2021-06-22 21:45:29 +08:00
// 2 拖拽模式
2020-11-25 22:59:17 +08:00
$floor_data_type = MyC ( 'home_index_floor_data_type' , 0 , true );
// 数据处理
switch ( $floor_data_type )
{
// 自动模式
case 0 :
// 商品数量
$goods_count = MyC ( 'home_index_floor_goods_max_count' , 8 , true );
// 排序配置
2023-08-27 16:59:15 +08:00
$floor_order_by_type_list = MyConst ( 'common_goods_order_by_type_list' );
2024-04-15 10:25:01 +08:00
$floor_order_by_rule_list = MyConst ( 'common_data_order_by_rule_list' );
2020-11-25 22:59:17 +08:00
$floor_order_by_type = MyC ( 'home_index_floor_goods_order_by_type' , 0 , true );
$floor_order_by_rule = MyC ( 'home_index_floor_goods_order_by_rule' , 0 , true );
// 排序字段名称
$order_by_field = array_key_exists ( $floor_order_by_type , $floor_order_by_type_list ) ? $floor_order_by_type_list [ $floor_order_by_type ][ 'value' ] : $floor_order_by_type_list [ 0 ][ 'value' ];
// 排序规则
$order_by_rule = array_key_exists ( $floor_order_by_rule , $floor_order_by_rule_list ) ? $floor_order_by_rule_list [ $floor_order_by_rule ][ 'value' ] : $floor_order_by_rule_list [ 0 ][ 'value' ];
// 排序
$order_by = implode ( ' ' . $order_by_rule . ', ' , explode ( ',' , $order_by_field )) . ' ' . $order_by_rule ;
break ;
// 手动模式
case 1 :
$manual_mode = MyC ( 'home_index_floor_manual_mode_goods' );
if ( ! empty ( $manual_mode ))
{
$floor_manual_mode_goods = json_decode ( $manual_mode , true );
}
break ;
}
2022-04-18 00:54:11 +08:00
// 首页获取数据信息钩子
$hook_name = 'plugins_service_home_floor_data_begin' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'data' => & $data ,
]);
2020-04-03 16:28:01 +08:00
// 根据分类获取楼层商品
foreach ( $data as & $v )
{
2020-11-25 22:59:17 +08:00
// 数据模式
switch ( $floor_data_type )
{
// 自动模式
case 0 :
if ( isset ( $goods_count ) && isset ( $order_by ))
{
// 获取分类ids
2023-02-08 21:20:04 +08:00
$category_ids = GoodsCategoryService :: GoodsCategoryItemsIds ([ $v [ 'id' ]], 1 );
2020-11-25 22:59:17 +08:00
2022-04-18 00:54:11 +08:00
// 获取商品id
$goods_params = [
2025-09-23 21:22:38 +08:00
'where' => [
2022-04-18 00:54:11 +08:00
[ 'gci.category_id' , 'in' , $category_ids ],
[ 'g.is_shelves' , '=' , 1 ],
[ 'g.is_delete_time' , '=' , 0 ],
],
2025-09-23 21:22:38 +08:00
'order_by' => $order_by ,
'field' => 'g.id' ,
'n' => $goods_count ,
'is_data_handle' => 0 ,
'is_spec' => $is_spec ,
'is_cart' => $is_cart ,
2020-11-25 22:59:17 +08:00
];
2022-04-18 00:54:11 +08:00
$res = self :: CategoryGoodsList ( $goods_params );
$v [ 'goods_ids' ] = empty ( $res ) ? [] : array_column ( $res , 'id' );
2020-11-25 22:59:17 +08:00
}
break ;
// 手动模式
case 1 :
if ( ! empty ( $floor_manual_mode_goods ) && is_array ( $floor_manual_mode_goods ) && array_key_exists ( $v [ 'id' ], $floor_manual_mode_goods ))
{
$v [ 'goods_ids' ] = $floor_manual_mode_goods [ $v [ 'id' ]];
}
break ;
}
// 商品数据、后面实时读取这里赋空值
2020-04-23 16:30:18 +08:00
$v [ 'goods' ] = [];
2020-09-15 21:57:19 +08:00
2020-11-26 18:34:41 +08:00
// 楼层左侧分类
if ( ! empty ( $floor_left_top_category ) && ! empty ( $floor_left_top_category [ $v [ 'id' ]]))
{
2025-09-23 21:22:38 +08:00
$v [ 'items' ] = GoodsCategoryService :: GoodsCategoryList ([ 'where' => [[ 'id' , 'in' , explode ( ',' , $floor_left_top_category [ $v [ 'id' ]])]], 'm' => 0 , 'n' => 0 , 'is_spec' => 0 , 'is_cart' => 0 ]);
2020-11-26 18:34:41 +08:00
} else {
$v [ 'items' ] = [];
}
2020-09-15 21:57:19 +08:00
// 楼层关键字
2020-11-26 18:34:41 +08:00
$v [ 'config_keywords' ] = ( empty ( $floor_keywords ) || empty ( $floor_keywords [ $v [ 'id' ]])) ? [] : explode ( ',' , $floor_keywords [ $v [ 'id' ]]);
2020-04-03 16:28:01 +08:00
}
2021-07-23 15:58:46 +08:00
} else {
$data = [];
2018-12-28 18:58:37 +08:00
}
2020-04-03 16:28:01 +08:00
// 存储缓存
2021-07-23 15:58:46 +08:00
MyCache ( $key , $data , 180 );
2018-12-28 18:58:37 +08:00
}
2020-04-23 16:30:18 +08:00
2020-09-15 21:57:19 +08:00
// 商品读取、商品信息需要实时读取
2020-04-23 16:30:18 +08:00
if ( ! empty ( $data ) && is_array ( $data ))
{
2020-11-25 22:59:17 +08:00
// 商品id一次性读取商品
$goods_ids = [];
foreach ( $data as $cg )
{
2020-11-26 18:34:41 +08:00
if ( ! empty ( $cg [ 'goods_ids' ]) && is_array ( $cg [ 'goods_ids' ]))
2020-11-25 22:59:17 +08:00
{
$goods_ids = array_merge ( $goods_ids , $cg [ 'goods_ids' ]);
}
}
// 读取商品
$goods_list = [];
if ( ! empty ( $goods_ids ))
{
2022-04-18 00:54:11 +08:00
$res = self :: GoodsList ([
2023-03-21 22:39:13 +08:00
'where' => [
2022-04-18 00:54:11 +08:00
[ 'id' , 'in' , array_unique ( $goods_ids )],
[ 'is_shelves' , '=' , 1 ],
],
2023-03-21 22:39:13 +08:00
'm' => 0 ,
'n' => 0 ,
'field' => '*' ,
2025-09-23 21:22:38 +08:00
'is_spec' => $is_spec ,
'is_cart' => $is_cart ,
2022-04-18 00:54:11 +08:00
]);
2020-11-25 22:59:17 +08:00
$goods_list = empty ( $res [ 'data' ]) ? [] : array_column ( $res [ 'data' ], null , 'id' );
}
2020-09-15 21:57:19 +08:00
2020-04-23 16:30:18 +08:00
// 根据分类获取楼层商品
2020-11-25 22:59:17 +08:00
if ( ! empty ( $goods_list ))
2020-04-23 16:30:18 +08:00
{
2020-11-25 22:59:17 +08:00
foreach ( $data as & $cv )
2020-04-23 16:30:18 +08:00
{
2020-11-25 22:59:17 +08:00
if ( ! empty ( $cv [ 'goods_ids' ]) && is_array ( $cv [ 'goods_ids' ]))
{
$temp = [];
foreach ( $cv [ 'goods_ids' ] as $gid )
{
if ( array_key_exists ( $gid , $goods_list ))
{
$temp [] = $goods_list [ $gid ];
}
}
$cv [ 'goods' ] = $temp ;
}
2020-04-23 16:30:18 +08:00
}
}
}
2020-04-03 16:28:01 +08:00
return $data ;
2018-12-28 18:58:37 +08:00
}
2025-09-23 21:22:38 +08:00
/**
* 商品数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 09 - 07
* @ desc description
* @ param array $where [ 条件 ]
*/
public static function GoodsData ( $goods_id , $field = '*' )
{
// 获取商品数据
$data = Db :: name ( 'Goods' ) -> field ( $field ) -> find ( $goods_id );
// 商品数据钩子
$hook_name = 'plugins_service_goods_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods_id' => $goods_id ,
'data' => & $data ,
]);
return $data ;
}
2018-12-28 18:58:37 +08:00
/**
* 获取分类与商品关联总数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 09 - 07
* @ desc description
* @ param array $where [ 条件 ]
*/
2019-01-17 00:37:20 +08:00
public static function CategoryGoodsTotal ( $where = [])
2018-12-28 18:58:37 +08:00
{
2023-03-18 23:48:06 +08:00
// 商品与分类联表总数读取前钩子
$hook_name = 'plugins_service_category_goods_total_begin' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'where' => & $where ,
]);
// 获取总数
2021-07-18 23:42:10 +08:00
return ( int ) Db :: name ( 'Goods' ) -> alias ( 'g' ) -> join ( 'goods_category_join gci' , 'g.id=gci.goods_id' ) -> where ( $where ) -> count ( 'DISTINCT g.id' );
2018-12-28 18:58:37 +08:00
}
/**
* 获取分类与商品关联列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 08 - 29
* @ desc description
* @ param array $params [ 输入参数 : where , field , is_photo ]
*/
2019-01-17 00:37:20 +08:00
public static function CategoryGoodsList ( $params = [])
2018-12-28 18:58:37 +08:00
{
$where = empty ( $params [ 'where' ]) ? [] : $params [ 'where' ];
$field = empty ( $params [ 'field' ]) ? 'g.*' : $params [ 'field' ];
2024-07-03 22:46:04 +08:00
$order_by = empty ( $params [ 'order_by' ]) ? 'g.sort_level desc, g.id desc' : trim ( $params [ 'order_by' ]);
2018-12-28 18:58:37 +08:00
$m = isset ( $params [ 'm' ]) ? intval ( $params [ 'm' ]) : 0 ;
$n = isset ( $params [ 'n' ]) ? intval ( $params [ 'n' ]) : 10 ;
2020-10-27 22:53:14 +08:00
// 商品列表读取前钩子
$hook_name = 'plugins_service_category_goods_list_begin' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2020-10-27 22:53:14 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'where' => & $where ,
'field' => & $field ,
'order_by' => & $order_by ,
'm' => & $m ,
'n' => & $n ,
]);
2024-10-21 10:51:14 +08:00
// 条件处理
$where_g = [];
$where_gci = [];
foreach ( $where as $v )
{
if ( is_array ( $v ) && count ( $v ) == 3 )
{
if ( substr ( $v [ 0 ], 0 , 4 ) == 'gci.' )
{
$where_gci [] = $v ;
} else {
$where_g [] = $v ;
}
}
}
// 只有商品条件、排序、字段
if ( empty ( $where_gci ) && stripos ( $field , 'gci.' ) === false && stripos ( $order_by , 'gci.' ) === false )
{
$data = Db :: name ( 'Goods' ) -> alias ( 'g' ) -> where ( $where_g ) -> field ( $field ) -> order ( $order_by ) -> limit ( $m , $n ) -> select () -> toArray ();
// 排序存在商品分类、商品
} else if (( stripos ( $order_by , 'gci.' ) !== false && stripos ( $order_by , 'g.' ) !== false ) || ( stripos ( $field , 'gci.' ) !== false && stripos ( $field , 'g.' ) !== false ))
{
$data = Db :: name ( 'Goods' ) -> alias ( 'g' ) -> join ( 'goods_category_join gci' , 'g.id=gci.goods_id' ) -> field ( $field ) -> where ( $where ) -> group ( 'g.id' ) -> order ( $order_by ) -> limit ( $m , $n ) -> select () -> toArray ();
// 子查询
} else {
$data = Db :: name ( 'Goods' ) -> alias ( 'g' ) -> where ( $where_g ) -> where ( 'g.id' , 'IN' , function ( $query ) use ( $where_gci ) {
$query -> name ( 'GoodsCategoryJoin' ) -> alias ( 'gci' ) -> where ( $where_gci ) -> field ( 'gci.goods_id' );
}) -> order ( $order_by ) -> limit ( $m , $n ) -> select () -> toArray ();
}
2018-12-28 18:58:37 +08:00
2020-07-07 18:58:29 +08:00
// 数据处理
2022-04-18 00:54:11 +08:00
if ( ! isset ( $params [ 'is_data_handle' ]) || $params [ 'is_data_handle' ] == 1 )
{
$data = self :: GoodsDataHandle ( $data , $params );
}
return $data ;
2018-12-28 18:58:37 +08:00
}
/**
* 商品数据处理
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ datetime 2018 - 12 - 08 T23 : 16 : 42 + 0800
* @ param [ array ] $data [ 商品列表 ]
2020-07-07 18:58:29 +08:00
* @ param [ array ] $params [ 输入参数 ]
2018-12-28 18:58:37 +08:00
*/
2020-07-07 18:58:29 +08:00
public static function GoodsDataHandle ( $data , $params = [])
2018-12-28 18:58:37 +08:00
{
if ( ! empty ( $data ))
{
2021-08-07 00:41:33 +08:00
// 商品列表钩子-前面
$hook_name = 'plugins_service_goods_list_handle_begin' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'data' => & $data ,
]);
2018-12-28 18:58:37 +08:00
// 其它额外处理
2024-04-15 10:25:01 +08:00
$is_photo = ! isset ( $params [ 'is_photo' ]) || ( isset ( $params [ 'is_photo' ]) && $params [ 'is_photo' ] == 1 );
$is_spec = isset ( $params [ 'is_spec' ]) && $params [ 'is_spec' ] == 1 ;
$is_content_app = isset ( $params [ 'is_content_app' ]) && $params [ 'is_content_app' ] == 1 ;
$is_category = isset ( $params [ 'is_category' ]) && $params [ 'is_category' ] == 1 ;
$is_params = isset ( $params [ 'is_params' ]) && $params [ 'is_params' ] == 1 ;
$is_cart = isset ( $params [ 'is_cart' ]) && $params [ 'is_cart' ] == 1 ;
$is_favor = isset ( $params [ 'is_favor' ]) && $params [ 'is_favor' ] == 1 ;
2025-05-13 21:46:05 +08:00
$is_score = isset ( $params [ 'is_score' ]) && $params [ 'is_score' ] == 1 ;
2020-09-17 14:10:41 +08:00
$data_key_field = empty ( $params [ 'data_key_field' ]) ? 'id' : $params [ 'data_key_field' ];
2023-01-17 16:37:00 +08:00
$goods_ids = array_filter ( array_column ( $data , $data_key_field ));
2024-04-15 10:25:01 +08:00
$currency_symbol = ResourcesService :: CurrencyDataSymbol ();
$common_goods_sales_price_status = MyC ( 'common_goods_sales_price_status' , 0 , true );
$common_goods_original_price_status = MyC ( 'common_goods_original_price_status' , 0 , true );
$common_goods_sales_price_unit_status = MyC ( 'common_goods_sales_price_unit_status' , 0 , true );
$common_goods_original_price_unit_status = MyC ( 'common_goods_original_price_unit_status' , 0 , true );
2024-07-03 22:46:04 +08:00
$common_goods_sales_number_status = MyC ( 'common_goods_sales_number_status' , 0 , true );
$common_goods_inventory_status = MyC ( 'common_goods_inventory_status' , 0 , true );
2018-12-28 18:58:37 +08:00
2021-01-27 22:21:04 +08:00
// 字段列表
$keys = ArrayKeys ( $data );
// 品牌名称
if ( in_array ( 'brand_id' , $keys ))
{
$brand_list = BrandService :: BrandName ( array_column ( $data , 'brand_id' ));
}
// 产地名称
2025-09-23 21:22:38 +08:00
if ( in_array ( 'produce_region' , $keys ))
2021-01-27 22:21:04 +08:00
{
2025-09-23 21:22:38 +08:00
$produce_region_list = RegionService :: RegionName ( array_column ( $data , 'produce_region' ));
2021-01-27 22:21:04 +08:00
}
2024-10-21 10:51:14 +08:00
// 相册
$photo = $is_photo ? self :: GoodsPhotoData ( $goods_ids ) : [];
2022-10-17 17:37:42 +08:00
// 商品分类
2024-01-19 14:49:32 +08:00
$category_group = $is_category ? self :: GoodsListCategoryGroupList ( $goods_ids , $params ) : [];
2023-01-17 16:37:00 +08:00
// 规格
2024-01-19 14:49:32 +08:00
$spec_group = $is_spec ? self :: GoodsSpecificationsData ( $goods_ids , $params ) : [];
2023-01-17 16:37:00 +08:00
// 参数
2024-01-19 14:49:32 +08:00
$params_group = $is_params ? self :: GoodsParametersData ( $goods_ids , $params ) : [];
2022-10-17 17:37:42 +08:00
2023-02-08 21:20:04 +08:00
// app数据
2024-01-19 14:49:32 +08:00
$app_group = $is_content_app ? self :: GoodsAppData ( $goods_ids , $params ) : [];
2023-02-08 21:20:04 +08:00
2023-03-21 22:39:13 +08:00
// 获取商品购物车数量
2024-01-19 14:49:32 +08:00
$user_cart = $is_cart ? self :: UserCartGoodsCountData ( $goods_ids , $params ) : [];
2023-03-21 22:39:13 +08:00
2024-04-15 10:25:01 +08:00
// 获取商品购物车数量
$user_favor = $is_favor ? self :: UserFavorGoodsCountData ( $goods_ids , $params ) : [];
2025-05-13 21:46:05 +08:00
// 评分
$goods_score = $is_score ? self :: GoodsScoreData ( $goods_ids , $params ) : [];
2026-03-04 10:21:47 +08:00
// 基础字段
$base_fields = MyConst ( 'common_goods_base_data_fields' );
// 商品详情基础自动展示配置
$base_fields_show = MyC ( 'common_goods_detail_base_fields_show' , [], true );
2018-12-28 18:58:37 +08:00
// 开始处理数据
2024-12-25 17:35:54 +08:00
foreach ( $data as $k =>& $v )
2018-12-28 18:58:37 +08:00
{
2024-12-25 17:35:54 +08:00
// 增加索引
$v [ 'data_index' ] = $k + 1 ;
2020-09-17 14:10:41 +08:00
// 数据主键id
$data_id = isset ( $v [ $data_key_field ]) ? $v [ $data_key_field ] : 0 ;
2025-04-25 20:21:19 +08:00
// 当前计量单位
2024-04-15 10:25:01 +08:00
$inventory_unit = empty ( $v [ 'inventory_unit' ]) ? '' : ' / ' . $v [ 'inventory_unit' ];
// 原价基础字段数据
// 原价标题名称
$v [ 'show_field_original_price_text' ] = MyLang ( 'goods_original_price_title' );
// 售价符号
$v [ 'show_original_price_symbol' ] = $currency_symbol ;
// 售价符号
$v [ 'show_original_price_unit' ] = $common_goods_original_price_unit_status == 1 ? $inventory_unit : '' ;
// 是否展示原价(否0, 是1)
$v [ 'show_field_original_price_status' ] = $common_goods_original_price_status ;
// 售价基础字段数据
// 售价标题名称
$v [ 'show_field_price_text' ] = MyLang ( 'goods_sales_price_title' );
// 售价符号
$v [ 'show_price_symbol' ] = $currency_symbol ;
// 售价符号
$v [ 'show_price_unit' ] = $common_goods_sales_price_unit_status == 1 ? $inventory_unit : '' ;
// 是否展示售价(否0, 是1)
$v [ 'show_field_price_status' ] = $common_goods_sales_price_status ;
2024-07-03 22:46:04 +08:00
// 是否展示销量和库存
$v [ 'show_sales_number_status' ] = $common_goods_sales_number_status ;
$v [ 'show_inventory_status' ] = $common_goods_inventory_status ;
2024-04-15 10:25:01 +08:00
// 公共插件数据
// 商品详情面板提示数据、一维数组
$v [ 'plugins_view_panel_data' ] = [];
// 商品详情icon数据、二维数组
// name 必填(建议不超过6个字符)
// bg_color 默认(#666)
// br_color 默认(#666)
// color 默认($fff)
// url 默认空(手机端请自行调整url地址)
// [
// 'name' => 'icon名称',
// 'bg_color' => '#666',
// 'br_color' => '#666',
// 'color' => '#fff',
// 'url' => 'url地址'
// ]
$v [ 'plugins_view_icon_data' ] = [];
2023-09-17 22:54:33 +08:00
// 商品价格容器
$v [ 'price_container' ] = [
'price' => isset ( $v [ 'price' ]) ? $v [ 'price' ] : 0.00 ,
'min_price' => isset ( $v [ 'min_price' ]) ? $v [ 'min_price' ] : 0.00 ,
'max_price' => isset ( $v [ 'max_price' ]) ? $v [ 'max_price' ] : 0.00 ,
'original_price' => isset ( $v [ 'original_price' ]) ? $v [ 'original_price' ] : 0.00 ,
'min_original_price' => isset ( $v [ 'min_original_price' ]) ? $v [ 'min_original_price' ] : 0.00 ,
'max_original_price' => isset ( $v [ 'max_original_price' ]) ? $v [ 'max_original_price' ] : 0.00 ,
];
2019-02-26 22:45:47 +08:00
// 商品处理前钩子
$hook_name = 'plugins_service_goods_handle_begin' ;
2021-07-18 23:42:10 +08:00
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
2019-02-26 22:45:47 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'goods' => & $v ,
2020-09-17 14:10:41 +08:00
'goods_id' => $data_id ,
2019-12-02 20:58:24 +08:00
]));
2019-02-26 22:45:47 +08:00
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
return $ret ;
}
2018-12-28 18:58:37 +08:00
// 商品url地址
2020-09-17 14:10:41 +08:00
if ( ! empty ( $data_id ))
2018-12-28 18:58:37 +08:00
{
2022-02-12 18:03:29 +08:00
$v [ 'goods_url' ] = self :: GoodsUrlCreate ( $data_id );
2018-12-28 18:58:37 +08:00
}
2020-08-11 21:26:43 +08:00
// 获取相册
2020-09-17 14:10:41 +08:00
if ( $is_photo && ! empty ( $data_id ))
2020-08-11 21:26:43 +08:00
{
2024-10-21 10:51:14 +08:00
$v [ 'photo' ] = ( empty ( $photo ) || empty ( $photo [ $data_id ])) ? [] : $photo [ $data_id ];
2020-08-11 21:26:43 +08:00
}
2018-12-28 18:58:37 +08:00
// 商品封面图片
if ( isset ( $v [ 'images' ]))
{
2020-08-19 22:37:14 +08:00
// 无封面图片
2020-08-11 21:26:43 +08:00
if ( empty ( $v [ 'images' ]))
{
2020-08-19 22:37:14 +08:00
// 获取商品封面图片
2020-09-17 14:10:41 +08:00
$v [ 'images' ] = ResourcesService :: AttachmentPathHandle ( self :: GoodsImagesCoverHandle ( $data_id , isset ( $v [ 'photo' ]) ? $v [ 'photo' ] : []));
2020-08-11 21:26:43 +08:00
}
2019-01-14 00:03:29 +08:00
$v [ 'images' ] = ResourcesService :: AttachmentPathViewHandle ( $v [ 'images' ]);
2018-12-28 18:58:37 +08:00
}
// 视频
if ( isset ( $v [ 'video' ]))
{
2019-01-14 00:03:29 +08:00
$v [ 'video' ] = ResourcesService :: AttachmentPathViewHandle ( $v [ 'video' ]);
2018-12-28 18:58:37 +08:00
}
2025-03-03 17:49:22 +08:00
// 分享图片
if ( isset ( $v [ 'share_images' ]))
{
$v [ 'share_images' ] = ResourcesService :: AttachmentPathViewHandle ( $v [ 'share_images' ]);
}
2018-12-28 18:58:37 +08:00
// PC内容处理
if ( isset ( $v [ 'content_web' ]))
{
$v [ 'content_web' ] = ResourcesService :: ContentStaticReplace ( $v [ 'content_web' ], 'get' );
2024-07-03 22:46:04 +08:00
// 手机端富文本处理
if ( APPLICATION == 'app' )
{
$v [ 'content_web' ] = ResourcesService :: ApMiniRichTextContentHandle ( $v [ 'content_web' ]);
}
2018-12-28 18:58:37 +08:00
}
2019-11-13 20:51:43 +08:00
// 虚拟商品展示数据
2019-11-19 21:46:22 +08:00
if ( isset ( $v [ 'fictitious_goods_value' ]))
2019-11-13 20:51:43 +08:00
{
2021-02-19 23:54:55 +08:00
// 非后台模块移除该字段、避免数据泄露
2021-07-18 23:42:10 +08:00
if ( RequestModule () != 'admin' )
2021-02-19 23:54:55 +08:00
{
unset ( $v [ 'fictitious_goods_value' ]);
} else {
$v [ 'fictitious_goods_value' ] = ResourcesService :: ContentStaticReplace ( $v [ 'fictitious_goods_value' ], 'get' );
}
2019-11-13 20:51:43 +08:00
}
2026-03-04 10:21:47 +08:00
// 使用指南数据
if ( isset ( $v [ 'use_guide' ]))
{
$v [ 'use_guide' ] = ResourcesService :: ContentStaticReplace ( $v [ 'use_guide' ], 'get' );
}
2018-12-28 18:58:37 +08:00
// 产地
2025-09-23 21:22:38 +08:00
if ( isset ( $v [ 'produce_region' ]))
2019-03-06 23:05:09 +08:00
{
2025-09-23 21:22:38 +08:00
$v [ 'produce_region_name' ] = ( ! empty ( $produce_region_list ) && is_array ( $produce_region_list ) && array_key_exists ( $v [ 'produce_region' ], $produce_region_list )) ? $produce_region_list [ $v [ 'produce_region' ]] : '' ;
2019-03-06 23:05:09 +08:00
}
2018-12-28 18:58:37 +08:00
// 品牌
2019-03-06 23:05:09 +08:00
if ( isset ( $v [ 'brand_id' ]))
{
2024-12-25 17:35:54 +08:00
$v [ 'brand_name' ] = ( ! empty ( $brand_list ) && is_array ( $brand_list ) && array_key_exists ( $v [ 'brand_id' ], $brand_list )) ? $brand_list [ $v [ 'brand_id' ]] : '' ;
2025-04-25 20:21:19 +08:00
$v [ 'brand_goods_url' ] = ( APPLICATION == 'app' ) ? '/pages/goods-search/goods-search?brand=' . $v [ 'brand_id' ] : MyUrl ( 'index/search/index' , [ 'brand' => $v [ 'brand_id' ]]);
2019-03-06 23:05:09 +08:00
}
2018-12-28 18:58:37 +08:00
// 时间
2026-03-04 10:21:47 +08:00
if ( isset ( $v [ 'approval_number_expire' ]))
{
$v [ 'approval_number_expire' ] = empty ( $v [ 'approval_number_expire' ]) ? '' : date ( 'Y-m-d' , $v [ 'approval_number_expire' ]);
}
if ( isset ( $v [ 'batch_number_expire' ]))
{
$v [ 'batch_number_expire' ] = empty ( $v [ 'batch_number_expire' ]) ? '' : date ( 'Y-m-d' , $v [ 'batch_number_expire' ]);
}
if ( isset ( $v [ 'add_time' ]))
2018-12-28 18:58:37 +08:00
{
$v [ 'add_time' ] = date ( 'Y-m-d H:i:s' , $v [ 'add_time' ]);
}
2026-03-04 10:21:47 +08:00
if ( isset ( $v [ 'upd_time' ]))
2018-12-28 18:58:37 +08:00
{
2022-05-06 23:46:47 +08:00
$v [ 'upd_time' ] = empty ( $v [ 'upd_time' ]) ? '' : date ( 'Y-m-d H:i:s' , $v [ 'upd_time' ]);
2018-12-28 18:58:37 +08:00
}
// 是否需要分类名称
2020-09-17 14:10:41 +08:00
if ( $is_category && ! empty ( $data_id ))
2018-12-28 18:58:37 +08:00
{
2022-10-17 17:37:42 +08:00
if ( array_key_exists ( $data_id , $category_group ))
{
$temp = $category_group [ $data_id ];
$v [ 'category_ids' ] = $temp [ 'category_ids' ];
$v [ 'category_text' ] = empty ( $temp [ 'category_names' ]) ? '' : implode ( ', ' , $temp [ 'category_names' ]);
} else {
$v [ 'category_ids' ] = [];
$v [ 'category_text' ] = '' ;
}
2018-12-28 18:58:37 +08:00
}
2019-09-23 13:56:03 +08:00
// 规格基础
if ( isset ( $v [ 'spec_base' ]))
{
$v [ 'spec_base' ] = empty ( $v [ 'spec_base' ]) ? '' : json_decode ( $v [ 'spec_base' ], true );
}
2018-12-28 18:58:37 +08:00
// 获取规格
2020-09-17 14:10:41 +08:00
if ( $is_spec && ! empty ( $data_id ))
2018-12-28 18:58:37 +08:00
{
2023-01-17 16:37:00 +08:00
$v [ 'specifications' ] = ( ! empty ( $spec_group ) && array_key_exists ( $data_id , $spec_group )) ? $spec_group [ $data_id ] : [];
2020-09-02 14:11:49 +08:00
}
// 获取商品参数
2020-09-17 14:10:41 +08:00
if ( $is_params && ! empty ( $data_id ))
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
$v [ 'parameters' ] = ( ! empty ( $params_group ) && array_key_exists ( $data_id , $params_group )) ? $params_group [ $data_id ] : [];
2018-12-28 18:58:37 +08:00
}
// 获取app内容
2020-09-17 14:10:41 +08:00
if ( $is_content_app && ! empty ( $data_id ))
2018-12-28 18:58:37 +08:00
{
2023-02-08 21:20:04 +08:00
$v [ 'content_app' ] = ( ! empty ( $app_group ) && array_key_exists ( $data_id , $app_group )) ? $app_group [ $data_id ] : [];
2018-12-28 18:58:37 +08:00
}
2019-02-26 22:45:47 +08:00
2023-03-21 22:39:13 +08:00
// 用户购物车总数
if ( $is_cart && ! empty ( $data_id ))
{
$v [ 'user_cart_count' ] = ( ! empty ( $user_cart ) && array_key_exists ( $data_id , $user_cart )) ? $user_cart [ $data_id ] : 0 ;
}
2024-04-15 10:25:01 +08:00
// 用户收藏
2025-05-13 21:46:05 +08:00
if ( $is_favor )
2024-04-15 10:25:01 +08:00
{
$v [ 'user_is_favor' ] = ( ! empty ( $user_favor ) && in_array ( $data_id , $user_favor )) ? 1 : 0 ;
}
2020-12-25 14:53:40 +08:00
2025-05-13 21:46:05 +08:00
// 评分
if ( $is_score )
{
$v [ 'goods_score' ] = ( ! empty ( $goods_score ) && array_key_exists ( $data_id , $goods_score )) ? $goods_score [ $data_id ] : [ 'avg' => 0 , 'score' => 0 , 'count' => 0 ];
}
2026-03-04 10:21:47 +08:00
// 基础数据
if ( ! empty ( $base_fields ) && is_array ( $base_fields ) && ! empty ( $base_fields_show ) && is_array ( $base_fields_show ))
{
$base_data = [];
foreach ( $base_fields as $bfk => $bfv )
{
if ( in_array ( $bfk , $base_fields_show ) && array_key_exists ( $bfk , $v ) && $v [ $bfk ] != 0 && $v [ $bfk ] != '' )
{
$base_data [] = [
'field' => $bfk ,
'name' => $bfv ,
'value' => $v [ $bfk ],
];
}
}
$v [ 'base_data' ] = empty ( $base_data ) ? '' : $base_data ;
}
2019-06-26 00:13:47 +08:00
// 商品处理后钩子
2019-02-26 22:45:47 +08:00
$hook_name = 'plugins_service_goods_handle_end' ;
2021-07-18 23:42:10 +08:00
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
2019-02-26 22:45:47 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'goods' => & $v ,
2020-09-17 14:10:41 +08:00
'goods_id' => isset ( $data_id ) ? $data_id : 0 ,
2019-12-02 20:58:24 +08:00
]));
2019-02-26 22:45:47 +08:00
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
return $ret ;
}
2018-12-28 18:58:37 +08:00
}
2021-08-07 00:41:33 +08:00
// 商品列表钩子-后面
$hook_name = 'plugins_service_goods_list_handle_end' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'data' => & $data ,
]);
2023-03-22 12:06:53 +08:00
// 错误处理
2026-06-02 16:12:10 +08:00
if ( ! empty ( $data ) && is_array ( $data ))
2023-03-22 12:06:53 +08:00
{
foreach ( $data as & $gv )
{
// 数据主键id
2026-06-02 16:12:10 +08:00
$data_id = isset ( $gv [ $data_key_field ]) ? $gv [ $data_key_field ] : 0 ;
2023-03-22 12:06:53 +08:00
// 错误处理
if ( ! isset ( $gv [ 'is_error' ]) || $gv [ 'is_error' ] == 0 )
{
$gv [ 'is_error' ] = 0 ;
$gv [ 'error_msg' ] = '' ;
}
if ( $gv [ 'is_error' ] == 0 && array_key_exists ( 'is_delete_time' , $gv ) && $gv [ 'is_delete_time' ] != 0 )
{
$gv [ 'is_error' ] = 1 ;
$gv [ 'error_msg' ] = MyLang ( 'goods_already_nullify_title' );
}
// 是否上架
if ( $gv [ 'is_error' ] == 0 && array_key_exists ( 'is_shelves' , $gv ) && $gv [ 'is_shelves' ] != 1 )
{
$gv [ 'is_error' ] = 1 ;
$gv [ 'error_msg' ] = MyLang ( 'goods_already_shelves_title' );
}
// 是否有库存
if ( $gv [ 'is_error' ] == 0 && array_key_exists ( 'inventory' , $gv ) && $gv [ 'inventory' ] <= 0 )
{
$gv [ 'is_error' ] = 1 ;
$gv [ 'error_msg' ] = MyLang ( 'goods_no_inventory_title' );
}
// 没错误则判断类型是否一致
if ( $gv [ 'is_error' ] == 0 && array_key_exists ( 'site_type' , $gv ) && ! empty ( $data_id ))
{
$ret = self :: IsGoodsSiteTypeConsistent ( $data_id , $gv [ 'site_type' ]);
if ( $ret [ 'code' ] != 0 )
{
$gv [ 'is_error' ] = 1 ;
$gv [ 'error_msg' ] = $ret [ 'msg' ];
}
}
}
}
2018-12-28 18:58:37 +08:00
}
2020-07-07 18:58:29 +08:00
return DataReturn ( 'success' , 0 , $data );
2018-12-28 18:58:37 +08:00
}
2022-10-17 17:37:42 +08:00
/**
* 商品列表获取产品分类分组信息
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2022 - 10 - 13
* @ desc description
* @ param [ array ] $goods_ids [ 商品id ]
2024-01-19 14:49:32 +08:00
* @ param [ array ] $params [ 输入参数 ]
2022-10-17 17:37:42 +08:00
*/
2024-01-19 14:49:32 +08:00
public static function GoodsListCategoryGroupList ( $goods_ids , $params = [])
2022-10-17 17:37:42 +08:00
{
$result = [];
$category_join = Db :: name ( 'GoodsCategoryJoin' ) -> where ([ 'goods_id' => $goods_ids ]) -> field ( 'goods_id,category_id' ) -> select () -> toArray ();
if ( ! empty ( $category_join ))
{
$category_name = Db :: name ( 'GoodsCategory' ) -> where ([ 'id' => array_unique ( array_column ( $category_join , 'category_id' ))]) -> column ( 'name' , 'id' );
if ( ! empty ( $category_name ))
{
foreach ( $category_join as $v )
{
if ( array_key_exists ( $v [ 'category_id' ], $category_name ))
{
if ( ! array_key_exists ( $v [ 'goods_id' ], $result ))
{
$result [ $v [ 'goods_id' ]] = [
'category_ids' => [],
'category_names' => [],
];
}
$result [ $v [ 'goods_id' ]][ 'category_ids' ][] = $v [ 'category_id' ];
$result [ $v [ 'goods_id' ]][ 'category_names' ][] = $category_name [ $v [ 'category_id' ]];
}
}
}
}
return $result ;
}
2020-08-19 22:37:14 +08:00
/**
* 获取商品封面图片
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 08 - 19
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ array ] $photo [ 商品相册 ]
*/
public static function GoodsImagesCoverHandle ( $goods_id = 0 , $photo = [])
{
// 是否已存在相册
if ( ! empty ( $photo ))
{
$photo = self :: GoodsPhotoData ( $goods_id );
if ( ! empty ( $photo [ 0 ]) && ! empty ( $photo [ 0 ][ 'images' ]))
{
$images = $photo [ 0 ][ 'images' ];
}
}
// 无主图, 并且有商品id
if ( empty ( $images ) && ! empty ( $goods_id ))
{
$images = Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_id , 'is_show' => 1 ]) -> order ( 'sort asc' ) -> value ( 'images' );
}
return isset ( $images ) ? $images : '' ;
}
/**
* 商品相册
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 08 - 19
* @ desc description
2024-10-21 10:51:14 +08:00
* @ param [ int | array ] $goods_ids [ 商品id ]
2020-08-19 22:37:14 +08:00
*/
2024-10-21 10:51:14 +08:00
public static function GoodsPhotoData ( $goods_ids )
2020-08-19 22:37:14 +08:00
{
2024-10-21 10:51:14 +08:00
$data = Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_ids , 'is_show' => 1 ]) -> order ( 'sort asc' ) -> select () -> toArray ();
if ( is_array ( $goods_ids ))
{
$group = [];
if ( ! empty ( $data ))
{
foreach ( $data as $v )
{
if ( ! array_key_exists ( $v [ 'goods_id' ], $group ))
{
$group [ $v [ 'goods_id' ]] = [];
}
$v [ 'images' ] = ResourcesService :: AttachmentPathViewHandle ( $v [ 'images' ]);
$group [ $v [ 'goods_id' ]][] = $v ;
}
}
return $group ;
}
return $data ;
2020-08-19 22:37:14 +08:00
}
2025-05-13 21:46:05 +08:00
/**
* 商品评分
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 03 - 20
* @ desc description
* @ param [ array ] $goods_ids [ 商品id ]
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsScoreData ( $goods_ids , $params = [])
{
$data = Db :: name ( 'GoodsComments' ) -> where ([ 'goods_id' => $goods_ids ]) -> group ( 'goods_id' ) -> column ( 'goods_id, AVG(rating) AS avg, COUNT(goods_id) AS count' , 'goods_id' );
if ( ! empty ( $data ))
{
foreach ( $data as & $v )
{
unset ( $v [ 'goods_id' ]);
$v [ 'avg' ] = PriceNumberFormat ( $v [ 'avg' ], 1 );
$v [ 'score' ] = ( $v [ 'avg' ] <= 0 ) ? 100 : intval (( $v [ 'avg' ] / 5 ) * 100 );
}
}
return $data ;
}
2024-04-15 10:25:01 +08:00
/**
* 获取用户收藏商品数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 03 - 20
* @ desc description
* @ param [ array ] $goods_ids [ 商品id ]
* @ param [ array ] $params [ 输入参数 ]
*/
public static function UserFavorGoodsCountData ( $goods_ids , $params = [])
{
$result = [];
$user = UserService :: LoginUserInfo ();
if ( ! empty ( $user ))
{
$where = [
[ 'goods_id' , 'in' , $goods_ids ],
[ 'user_id' , '=' , $user [ 'id' ]],
];
$result = Db :: name ( 'GoodsFavor' ) -> where ( $where ) -> column ( 'goods_id' );
}
return $result ;
}
2023-03-21 22:39:13 +08:00
/**
* 获取用户购物车商品总数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 03 - 20
* @ desc description
* @ param [ array ] $goods_ids [ 商品id ]
2024-01-19 14:49:32 +08:00
* @ param [ array ] $params [ 输入参数 ]
2023-03-21 22:39:13 +08:00
*/
2024-01-19 14:49:32 +08:00
public static function UserCartGoodsCountData ( $goods_ids , $params = [])
2023-03-21 22:39:13 +08:00
{
$result = [];
$user = UserService :: LoginUserInfo ();
if ( ! empty ( $user ))
{
$where = [
[ 'goods_id' , 'in' , $goods_ids ],
[ 'user_id' , '=' , $user [ 'id' ]],
];
$result = Db :: name ( 'Cart' ) -> where ( $where ) -> field ( 'SUM(stock) AS count, goods_id' ) -> group ( 'goods_id' ) -> select () -> toArray ();
if ( ! empty ( $result ))
{
$result = array_column ( $result , 'count' , 'goods_id' );
}
}
return $result ;
}
2018-12-28 18:58:37 +08:00
/**
* 获取商品手机详情
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
2023-02-08 21:20:04 +08:00
* @ param [ array ] $goods_ids [ 商品id ]
2024-01-19 14:49:32 +08:00
* @ param [ array ] $params [ 输入参数 ]
2023-02-08 21:20:04 +08:00
* @ return [ array ] [ app内容 ]
2018-12-28 18:58:37 +08:00
*/
2024-01-19 14:49:32 +08:00
public static function GoodsAppData ( $goods_ids , $params = [])
2018-12-28 18:58:37 +08:00
{
2026-03-04 10:21:47 +08:00
$data = [];
$list = Db :: name ( 'GoodsContentApp' ) -> where ([ 'goods_id' => $goods_ids ]) -> field ( 'id,goods_id,images,content' ) -> order ( 'sort asc' ) -> select () -> toArray ();
if ( ! empty ( $list ))
2018-12-28 18:58:37 +08:00
{
2026-03-04 10:21:47 +08:00
foreach ( $list as $v )
2018-12-28 18:58:37 +08:00
{
2023-02-08 21:20:04 +08:00
// 数据处理
2019-01-14 00:03:29 +08:00
$v [ 'images' ] = ResourcesService :: AttachmentPathViewHandle ( $v [ 'images' ]);
2018-12-28 18:58:37 +08:00
$v [ 'content_old' ] = $v [ 'content' ];
$v [ 'content' ] = empty ( $v [ 'content' ]) ? null : explode ( " \n " , $v [ 'content' ]);
2023-02-08 21:20:04 +08:00
// 数据组合
2026-03-04 10:21:47 +08:00
if ( ! array_key_exists ( $v [ 'goods_id' ], $data ))
2023-02-08 21:20:04 +08:00
{
2026-03-04 10:21:47 +08:00
$data [ $v [ 'goods_id' ]] = [];
2023-02-08 21:20:04 +08:00
}
2026-03-04 10:21:47 +08:00
$data [ $v [ 'goods_id' ]][] = $v ;
2018-12-28 18:58:37 +08:00
}
}
2026-03-04 10:21:47 +08:00
// 商品手机详情钩子
$hook_name = 'plugins_service_goods_content_app_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'data' => & $data ,
'goods_ids' => $goods_ids ,
]);
return $data ;
2018-12-28 18:58:37 +08:00
}
/**
2020-07-16 22:34:56 +08:00
* 获取商品规格
* @ author Devil
2018-12-28 18:58:37 +08:00
* @ blog http :// gong . gg /
* @ version 1.0 . 0
2020-07-16 22:34:56 +08:00
* @ date 2020 - 07 - 16
2018-12-28 18:58:37 +08:00
* @ desc description
2023-01-17 16:37:00 +08:00
* @ param [ array ] $goods_ids [ 商品id ]
2024-01-19 14:49:32 +08:00
* @ param [ array ] $params [ 输入参数 ]
2018-12-28 18:58:37 +08:00
*/
2024-01-19 14:49:32 +08:00
public static function GoodsSpecificationsData ( $goods_ids , $params = [])
2018-12-28 18:58:37 +08:00
{
2024-10-21 10:51:14 +08:00
// 静态数据容器,确保每一个商品只读取一次规格,避免重复读取浪费资源
static $goods_spec_group_static_data = [];
$temp_goods_ids = [];
foreach ( $goods_ids as $gid )
2018-12-28 18:58:37 +08:00
{
2024-10-21 10:51:14 +08:00
if ( empty ( $goods_spec_group_static_data ) || ! array_key_exists ( $gid , $goods_spec_group_static_data ))
2018-12-28 18:58:37 +08:00
{
2024-10-21 10:51:14 +08:00
$temp_goods_ids [] = $gid ;
2018-12-28 18:58:37 +08:00
}
2024-10-21 10:51:14 +08:00
}
// 存在未读取的规格咋数据库读取
if ( ! empty ( $temp_goods_ids ))
{
$temp_group = [];
$data = Db :: name ( 'GoodsSpecType' ) -> where ([ 'goods_id' => $temp_goods_ids ]) -> order ( 'id asc' ) -> select () -> toArray ();
if ( ! empty ( $data ))
2019-01-23 10:53:24 +08:00
{
2024-10-21 10:51:14 +08:00
// 分组
foreach ( $data as $v )
{
if ( ! array_key_exists ( $v [ 'goods_id' ], $temp_group ))
{
$temp_group [ $v [ 'goods_id' ]] = [ 'choose' => []];
}
$temp_group [ $v [ 'goods_id' ]][ 'choose' ][] = $v ;
}
// 数据处理
foreach ( $temp_group as $gid =>& $gv )
2019-01-23 10:53:24 +08:00
{
2024-10-21 10:51:14 +08:00
if ( ! empty ( $gv [ 'choose' ]))
2023-01-17 16:37:00 +08:00
{
2024-10-21 10:51:14 +08:00
// 基础处理
foreach ( $gv [ 'choose' ] as & $gvs )
2023-01-17 16:37:00 +08:00
{
2024-10-21 10:51:14 +08:00
$gvs_value = json_decode ( $gvs [ 'value' ], true );
foreach ( $gvs_value as & $gvss )
{
$gvss [ 'images' ] = ResourcesService :: AttachmentPathViewHandle ( $gvss [ 'images' ]);
}
$gvs [ 'value' ] = $gvs_value ;
$gvs [ 'add_time' ] = date ( 'Y-m-d H:i:s' , $gvs [ 'add_time' ]);
2023-01-17 16:37:00 +08:00
}
2024-10-21 10:51:14 +08:00
// 只有一个规格的时候直接获取规格值的库存数
if ( count ( $gv [ 'choose' ]) == 1 )
2023-01-17 16:37:00 +08:00
{
2024-10-21 10:51:14 +08:00
foreach ( $gv [ 'choose' ][ 0 ][ 'value' ] as & $temp_spec )
2023-01-17 16:37:00 +08:00
{
2024-10-21 10:51:14 +08:00
$temp_spec_params = array_merge ( $params , [
'id' => $gid ,
'spec' => [
[ 'type' => $gv [ 'choose' ][ 0 ][ 'name' ], 'value' => $temp_spec [ 'name' ]]
],
]);
$temp = self :: GoodsSpecDetail ( $temp_spec_params );
if ( $temp [ 'code' ] == 0 )
{
$temp_spec [ 'is_only_level_one' ] = 1 ;
$temp_spec [ 'inventory' ] = $temp [ 'data' ][ 'spec_base' ][ 'inventory' ];
}
2023-01-17 16:37:00 +08:00
}
}
2019-01-23 10:53:24 +08:00
}
2024-10-21 10:51:14 +08:00
$goods_spec_group_static_data [ $gid ] = $gv ;
}
}
// 空数据记录、避免重复查询
foreach ( $temp_goods_ids as $gid )
{
if ( ! array_key_exists ( $gid , $goods_spec_group_static_data ))
{
$goods_spec_group_static_data [ $gid ] = [];
}
}
}
// 返回当前指定的商品id对应的规格数据
2026-03-04 10:21:47 +08:00
$data = [];
2024-10-21 10:51:14 +08:00
if ( ! empty ( $goods_spec_group_static_data ))
{
foreach ( $goods_ids as $gid )
{
if ( ! empty ( $goods_spec_group_static_data [ $gid ]))
{
2026-03-04 10:21:47 +08:00
$data [ $gid ] = $goods_spec_group_static_data [ $gid ];
2019-01-23 10:53:24 +08:00
}
}
2018-12-28 18:58:37 +08:00
}
2026-03-04 10:21:47 +08:00
// 商品规格钩子
$hook_name = 'plugins_service_goods_spec_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'data' => & $data ,
'goods_ids' => $goods_ids ,
]);
return $data ;
2018-12-28 18:58:37 +08:00
}
2020-09-02 14:11:49 +08:00
/**
* 获取商品参数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 08 - 31
* @ desc description
2023-01-17 16:37:00 +08:00
* @ param [ array ] $goods_ids [ 商品id ]
2024-01-19 14:49:32 +08:00
* @ param [ array ] $params [ 输入参数 ]
2020-09-02 14:11:49 +08:00
*/
2024-01-19 14:49:32 +08:00
public static function GoodsParametersData ( $goods_ids , $params = [])
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
$data = [];
$list = Db :: name ( 'GoodsParams' ) -> where ([ 'goods_id' => $goods_ids ]) -> order ( 'id asc' ) -> select () -> toArray ();
2020-09-02 19:35:02 +08:00
if ( ! empty ( $list ))
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
// 分组
2020-09-02 19:35:02 +08:00
foreach ( $list as $v )
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
if ( ! array_key_exists ( $v [ 'goods_id' ], $data ))
{
$data [ $v [ 'goods_id' ]] = [ 'base' => [], 'detail' => []];
}
2020-09-02 14:11:49 +08:00
// 基础
2025-10-26 15:57:22 +08:00
if ( in_array ( $v [ 'scope' ], [ 0 , 2 ]))
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
$data [ $v [ 'goods_id' ]][ 'base' ][] = $v ;
2020-09-02 14:11:49 +08:00
}
// 详情
2025-10-26 15:57:22 +08:00
if ( in_array ( $v [ 'scope' ], [ 0 , 1 ]))
2020-09-02 14:11:49 +08:00
{
2023-01-17 16:37:00 +08:00
$data [ $v [ 'goods_id' ]][ 'detail' ][] = $v ;
2020-09-02 14:11:49 +08:00
}
}
}
2020-09-02 19:35:02 +08:00
// 商品参数钩子
$hook_name = 'plugins_service_goods_parameters_data' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2020-09-02 19:35:02 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'data' => & $data ,
2023-01-17 16:37:00 +08:00
'goods_ids' => $goods_ids ,
2020-09-02 19:35:02 +08:00
]);
return $data ;
2020-09-02 14:11:49 +08:00
}
2020-07-16 22:34:56 +08:00
/**
* 商品规格简洁的数据处理
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 07 - 15
* @ desc description
* @ param [ array ] $data [ 规格数据 ]
*/
public static function GoodsSpecificationsConcise ( $data )
{
$result = [];
if ( ! empty ( $data ))
{
foreach ( $data as $v )
{
$result [] = array_column ( $v [ 'value' ], 'name' );
}
}
return $result ;
}
/**
* 获取商品当前实际存在的规格
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 07 - 16
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
*/
public static function GoodsSpecificationsActual ( $goods_id )
{
// 规格名称
$where = [ 'goods_id' => $goods_id ];
$title = Db :: name ( 'GoodsSpecType' ) -> where ( $where ) -> column ( 'name' );
// 规格值
2021-07-18 23:42:10 +08:00
$value = Db :: name ( 'GoodsSpecValue' ) -> where ( $where ) -> field ( 'goods_spec_base_id,value' ) -> select () -> toArray ();
2020-07-16 23:56:16 +08:00
$group = [];
2020-07-16 22:34:56 +08:00
if ( ! empty ( $value ))
{
foreach ( $value as $v )
{
2020-07-16 23:56:16 +08:00
// 不存在则添加
if ( ! isset ( $group [ $v [ 'goods_spec_base_id' ]]))
{
$group [ $v [ 'goods_spec_base_id' ]] = [];
$group [ $v [ 'goods_spec_base_id' ]][ 'base_id' ] = $v [ 'goods_spec_base_id' ];
}
// 多个规格组合
$group [ $v [ 'goods_spec_base_id' ]][ 'value' ][] = $v [ 'value' ];
2020-07-16 22:34:56 +08:00
}
2020-07-16 23:56:16 +08:00
foreach ( $group as & $gv )
2020-07-16 22:34:56 +08:00
{
2020-10-12 10:36:57 +08:00
$gv [ 'value' ] = implode ( self :: $goods_spec_to_string_separator , $gv [ 'value' ]);
2020-07-16 22:34:56 +08:00
}
2020-07-16 23:56:16 +08:00
sort ( $group );
2020-07-16 22:34:56 +08:00
}
2020-07-17 00:07:12 +08:00
return [
2020-07-16 22:34:56 +08:00
'title' => $title ,
2020-07-16 23:56:16 +08:00
'value' => $group ,
2020-07-17 00:07:12 +08:00
];
2020-07-16 22:34:56 +08:00
}
2026-06-02 16:12:10 +08:00
/**
* 规格值组合
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 07 - 16
* @ desc description
* @ param [ string ] $spec_str [ 规格字符串,英文逗号分割 ]
* @ param [ array ] $spec_title [ 规格类型名称 ]
*/
public static function GoodsSpecMuster ( $spec_str , $spec_title )
{
$result = [];
$arr = explode ( self :: $goods_spec_to_string_separator , $spec_str );
if ( count ( $arr ) == count ( $spec_title ))
{
foreach ( $arr as $k => $v )
{
$result [] = [
'type' => $spec_title [ $k ],
'value' => $v ,
];
}
}
return $result ;
}
2018-12-28 18:58:37 +08:00
/**
* 商品访问统计加1
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 10 - 15
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsAccessCountInc ( $params = [])
2018-12-28 18:58:37 +08:00
{
if ( ! empty ( $params [ 'goods_id' ]))
{
2021-07-21 16:35:38 +08:00
return Db :: name ( 'Goods' ) -> where ([ 'id' => intval ( $params [ 'goods_id' ])]) -> inc ( 'access_count' ) -> update ();
2018-12-28 18:58:37 +08:00
}
return false ;
}
/**
* 获取商品总数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 09 - 07
* @ desc description
* @ param [ array ] $where [ 条件 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsTotal ( $where = [])
2018-12-28 18:58:37 +08:00
{
2023-03-18 23:48:06 +08:00
// 商品总数读取前钩子
$hook_name = 'plugins_service_goods_total_begin' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'where' => & $where ,
]);
// 获取总数
2018-12-28 18:58:37 +08:00
return ( int ) Db :: name ( 'Goods' ) -> where ( $where ) -> count ();
}
/**
* 获取商品列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 08 - 29
* @ desc description
* @ param array $params [ 输入参数 : where , field , is_photo ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsList ( $params = [])
2018-12-28 18:58:37 +08:00
{
$where = empty ( $params [ 'where' ]) ? [] : $params [ 'where' ];
$field = empty ( $params [ 'field' ]) ? '*' : $params [ 'field' ];
$order_by = empty ( $params [ 'order_by' ]) ? 'id desc' : trim ( $params [ 'order_by' ]);
$m = isset ( $params [ 'm' ]) ? intval ( $params [ 'm' ]) : 0 ;
$n = isset ( $params [ 'n' ]) ? intval ( $params [ 'n' ]) : 10 ;
2020-10-27 22:53:14 +08:00
// 商品列表读取前钩子
$hook_name = 'plugins_service_goods_list_begin' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2020-10-27 22:53:14 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'where' => & $where ,
'field' => & $field ,
'order_by' => & $order_by ,
'm' => & $m ,
'n' => & $n ,
]);
2022-04-18 00:54:11 +08:00
// 查询商品
2021-07-18 23:42:10 +08:00
$data = Db :: name ( 'Goods' ) -> field ( $field ) -> where ( $where ) -> order ( $order_by ) -> limit ( $m , $n ) -> select () -> toArray ();
2022-04-18 00:54:11 +08:00
// 数据处理
2020-07-07 18:58:29 +08:00
return self :: GoodsDataHandle ( $data , $params );
2018-12-28 18:58:37 +08:00
}
/**
* 商品保存
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ datetime 2018 - 12 - 10 T01 : 02 : 11 + 0800
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsSave ( $params = [])
2018-12-28 18:58:37 +08:00
{
2026-03-04 10:21:47 +08:00
// 商品分类id
$category_ids = empty ( $params [ 'category_id' ]) ? [] : ( is_array ( $params [ 'category_id' ]) ? $params [ 'category_id' ] : explode ( ',' , $params [ 'category_id' ]));
// 商品基础字段必填配置数据
$required_fields = empty ( $category_ids ) ? [] : self :: GoodsBaseFieldsRequiredConfigData ( $category_ids );
$is_simple_desc = ! empty ( $required_fields ) && isset ( $required_fields [ 'simple_desc' ]) && $required_fields [ 'simple_desc' ] == 1 ;
$is_spec_desc = ! empty ( $required_fields ) && isset ( $required_fields [ 'spec_desc' ]) && $required_fields [ 'spec_desc' ] == 1 ;
$is_approval_number = ! empty ( $required_fields ) && isset ( $required_fields [ 'approval_number' ]) && $required_fields [ 'approval_number' ] == 1 ;
$is_approval_number_expire = ! empty ( $required_fields ) && isset ( $required_fields [ 'approval_number_expire' ]) && $required_fields [ 'approval_number_expire' ] == 1 ;
$is_batch_number = ! empty ( $required_fields ) && isset ( $required_fields [ 'batch_number' ]) && $required_fields [ 'batch_number' ] == 1 ;
$is_batch_number_expire = ! empty ( $required_fields ) && isset ( $required_fields [ 'batch_number_expire' ]) && $required_fields [ 'batch_number_expire' ] == 1 ;
$is_coding = ! empty ( $required_fields ) && isset ( $required_fields [ 'coding' ]) && $required_fields [ 'coding' ] == 1 ;
$is_model = ! empty ( $required_fields ) && isset ( $required_fields [ 'model' ]) && $required_fields [ 'model' ] == 1 ;
$is_brand_id = ! empty ( $required_fields ) && isset ( $required_fields [ 'brand_id' ]) && $required_fields [ 'brand_id' ] == 1 ;
$is_produce_company = ! empty ( $required_fields ) && isset ( $required_fields [ 'produce_company' ]) && $required_fields [ 'produce_company' ] == 1 ;
$is_produce_region = ! empty ( $required_fields ) && isset ( $required_fields [ 'produce_region' ]) && $required_fields [ 'produce_region' ] == 1 ;
2018-12-28 18:58:37 +08:00
// 请求参数
$p = [
[
'checked_type' => 'length' ,
'key_name' => 'title' ,
2020-09-02 14:11:49 +08:00
'checked_data' => '2,160' ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_title_message' ),
2018-12-28 18:58:37 +08:00
],
2019-06-13 10:59:53 +08:00
[
'checked_type' => 'length' ,
'key_name' => 'simple_desc' ,
2026-03-04 10:21:47 +08:00
'checked_data' => $is_simple_desc ? '1,230' : '230' ,
'is_checked' => $is_simple_desc ? null : 1 ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_simple_desc_message' ),
2019-06-13 10:59:53 +08:00
],
2025-09-23 21:22:38 +08:00
[
'checked_type' => 'length' ,
'key_name' => 'spec_desc' ,
2026-03-04 10:21:47 +08:00
'checked_data' => $is_spec_desc ? '1,230' : '230' ,
'is_checked' => $is_spec_desc ? null : 1 ,
2025-09-23 21:22:38 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_spec_desc_message' ),
],
[
'checked_type' => 'length' ,
'key_name' => 'approval_number' ,
2026-03-04 10:21:47 +08:00
'checked_data' => $is_approval_number ? '1,180' : '180' ,
'is_checked' => $is_approval_number ? null : 1 ,
2025-09-23 21:22:38 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_approval_number_message' ),
],
2026-03-04 10:21:47 +08:00
[
'checked_type' => 'empty' ,
'key_name' => 'approval_number_expire' ,
'is_checked' => $is_approval_number_expire ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_approval_number_expire_message' ),
],
2025-09-23 21:22:38 +08:00
[
'checked_type' => 'length' ,
2026-03-04 10:21:47 +08:00
'key_name' => 'batch_number' ,
'checked_data' => $is_batch_number ? '1,180' : '180' ,
'is_checked' => $is_batch_number ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_batch_number_message' ),
],
[
'checked_type' => 'empty' ,
'key_name' => 'batch_number_expire' ,
'is_checked' => $is_batch_number_expire ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_batch_number_expire_message' ),
2025-09-23 21:22:38 +08:00
],
[
'checked_type' => 'length' ,
'key_name' => 'coding' ,
2026-03-04 10:21:47 +08:00
'checked_data' => $is_coding ? '1,180' : '180' ,
'is_checked' => $is_coding ? null : 1 ,
2025-09-23 21:22:38 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_coding_message' ),
],
2018-12-28 18:58:37 +08:00
[
'checked_type' => 'length' ,
'key_name' => 'model' ,
2026-03-04 10:21:47 +08:00
'checked_data' => $is_model ? '1,180' : '180' ,
'is_checked' => $is_model ? null : 1 ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_model_message' ),
2018-12-28 18:58:37 +08:00
],
2026-03-04 10:21:47 +08:00
[
'checked_type' => 'empty' ,
'key_name' => 'brand_id' ,
'is_checked' => $is_brand_id ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_brand_id_message' ),
],
[
'checked_type' => 'length' ,
'key_name' => 'produce_company' ,
'checked_data' => $is_produce_company ? '1,180' : '180' ,
'is_checked' => $is_produce_company ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_produce_company_message' ),
],
[
'checked_type' => 'empty' ,
'key_name' => 'produce_region' ,
'is_checked' => $is_produce_region ? null : 1 ,
'error_msg' => MyLang ( 'common_service.goods.form_item_produce_region_message' ),
],
2018-12-28 18:58:37 +08:00
[
'checked_type' => 'empty' ,
'key_name' => 'category_id' ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_category_id_message' ),
2018-12-28 18:58:37 +08:00
],
[
'checked_type' => 'length' ,
'key_name' => 'inventory_unit' ,
'checked_data' => '1,6' ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.form_item_inventory_unit_message' ),
2018-12-28 18:58:37 +08:00
],
2020-07-02 22:42:01 +08:00
[
'checked_type' => 'in' ,
'key_name' => 'site_type' ,
2024-04-15 10:25:01 +08:00
'checked_data' => array_column ( MyConst ( 'common_site_type_list' ), 'value' ),
2023-02-02 23:54:37 +08:00
'is_checked' => 1 ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.save_site_type_error_tips' ),
2020-07-02 22:42:01 +08:00
],
2019-06-02 21:45:10 +08:00
[
'checked_type' => 'length' ,
'key_name' => 'seo_title' ,
'checked_data' => '100' ,
'is_checked' => 1 ,
2023-02-04 16:47:48 +08:00
'error_msg' => MyLang ( 'form_seo_title_message' ),
2019-06-02 21:45:10 +08:00
],
2019-05-05 11:29:55 +08:00
[
'checked_type' => 'length' ,
'key_name' => 'seo_keywords' ,
'checked_data' => '130' ,
'is_checked' => 1 ,
2023-02-04 16:47:48 +08:00
'error_msg' => MyLang ( 'form_seo_keywords_message' ),
2019-05-05 11:29:55 +08:00
],
[
'checked_type' => 'length' ,
'key_name' => 'seo_desc' ,
'checked_data' => '230' ,
'is_checked' => 1 ,
2023-02-04 16:47:48 +08:00
'error_msg' => MyLang ( 'form_seo_desc_message' ),
2019-05-05 11:29:55 +08:00
],
2018-12-28 18:58:37 +08:00
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
2019-09-23 13:56:03 +08:00
// 规格基础
$specifications_base = self :: GetFormGoodsSpecificationsBaseParams ( $params );
if ( $specifications_base [ 'code' ] != 0 )
{
return $specifications_base ;
}
// 规格值
2019-01-17 00:37:20 +08:00
$specifications = self :: GetFormGoodsSpecificationsParams ( $params );
2018-12-28 18:58:37 +08:00
if ( $specifications [ 'code' ] != 0 )
{
return $specifications ;
}
2023-02-23 15:35:30 +08:00
2025-09-23 21:22:38 +08:00
// 商品参数
2025-10-26 15:57:22 +08:00
$parameter = GoodsParamsService :: GoodsParamsTemplateSaveHandle ( $params );
2026-06-02 16:12:10 +08:00
// 商品参数模板、是否必填验证,未开启自定义模式则需要按照模板验证
$parameter_template_check = GoodsParamsService :: GoodsParamsTemplateSaveCheck ([ 'category_ids' => $category_ids , 'parameter_value' => $parameter [ 'data' ]]);
if ( $parameter_template_check [ 'code' ] != 0 )
{
return $parameter_template_check ;
}
2025-09-23 21:22:38 +08:00
2018-12-28 18:58:37 +08:00
// 相册
2019-01-17 00:37:20 +08:00
$photo = self :: GetFormGoodsPhotoParams ( $params );
2018-12-28 18:58:37 +08:00
if ( $photo [ 'code' ] != 0 )
{
return $photo ;
}
// 手机端详情
2019-01-17 00:37:20 +08:00
$content_app = self :: GetFormGoodsContentAppParams ( $params );
2018-12-28 18:58:37 +08:00
if ( $content_app [ 'code' ] != 0 )
{
return $content_app ;
}
// 其它附件
2025-03-03 17:49:22 +08:00
$attachment = ResourcesService :: AttachmentParams ( $params , [ 'images' , 'video' , 'share_images' ]);
2018-12-28 18:58:37 +08:00
if ( $attachment [ 'code' ] != 0 )
{
return $attachment ;
}
2019-02-20 16:18:21 +08:00
// 编辑器内容
2025-04-25 20:21:19 +08:00
$content_web = empty ( $params [ 'content_web' ]) ? '' : str_replace ( " \n " , '' , ResourcesService :: ContentStaticReplace ( htmlspecialchars_decode ( $params [ 'content_web' ]), 'add' ));
$fictitious_goods_value = empty ( $params [ 'fictitious_goods_value' ]) ? '' : str_replace ( " \n " , '' , ResourcesService :: ContentStaticReplace ( htmlspecialchars_decode ( $params [ 'fictitious_goods_value' ]), 'add' ));
2026-03-04 10:21:47 +08:00
$use_guide = empty ( $params [ 'use_guide' ]) ? '' : str_replace ( " \n " , '' , ResourcesService :: ContentStaticReplace ( htmlspecialchars_decode ( $params [ 'use_guide' ]), 'add' ));
2019-02-20 16:18:21 +08:00
2020-09-02 14:11:49 +08:00
// 封面图片、默认相册第一张
$images = empty ( $attachment [ 'data' ][ 'images' ]) ? ( isset ( $photo [ 'data' ][ 0 ]) ? $photo [ 'data' ][ 0 ] : '' ) : $attachment [ 'data' ][ 'images' ];
2018-12-28 18:58:37 +08:00
// 基础数据
$data = [
2025-09-23 21:22:38 +08:00
'title' => $params [ 'title' ],
'title_color' => empty ( $params [ 'title_color' ]) ? '' : $params [ 'title_color' ],
'simple_desc' => empty ( $params [ 'simple_desc' ]) ? '' : $params [ 'simple_desc' ],
'spec_desc' => empty ( $params [ 'spec_desc' ]) ? '' : $params [ 'spec_desc' ],
'approval_number' => empty ( $params [ 'approval_number' ]) ? '' : $params [ 'approval_number' ],
2026-03-04 10:21:47 +08:00
'approval_number_expire' => empty ( $params [ 'approval_number_expire' ]) ? 0 : strtotime ( $params [ 'approval_number_expire' ]),
'batch_number' => empty ( $params [ 'batch_number' ]) ? '' : $params [ 'batch_number' ],
'batch_number_expire' => empty ( $params [ 'batch_number_expire' ]) ? 0 : strtotime ( $params [ 'batch_number_expire' ]),
2025-09-23 21:22:38 +08:00
'coding' => empty ( $params [ 'coding' ]) ? '' : $params [ 'coding' ],
'model' => empty ( $params [ 'model' ]) ? '' : $params [ 'model' ],
2026-03-04 10:21:47 +08:00
'produce_company' => empty ( $params [ 'produce_company' ]) ? '' : $params [ 'produce_company' ],
'produce_region' => isset ( $params [ 'produce_region' ]) ? intval ( $params [ 'produce_region' ]) : 0 ,
2025-09-23 21:22:38 +08:00
'inventory_unit' => $params [ 'inventory_unit' ],
'is_deduction_inventory' => isset ( $params [ 'is_deduction_inventory' ]) ? intval ( $params [ 'is_deduction_inventory' ]) : 0 ,
'is_shelves' => isset ( $params [ 'is_shelves' ]) ? intval ( $params [ 'is_shelves' ]) : 0 ,
'content_web' => $content_web ,
'photo_count' => count ( $photo [ 'data' ]),
'images' => $images ,
'brand_id' => isset ( $params [ 'brand_id' ]) ? intval ( $params [ 'brand_id' ]) : 0 ,
'video' => $attachment [ 'data' ][ 'video' ],
'seo_title' => empty ( $params [ 'seo_title' ]) ? '' : $params [ 'seo_title' ],
'seo_keywords' => empty ( $params [ 'seo_keywords' ]) ? '' : $params [ 'seo_keywords' ],
'seo_desc' => empty ( $params [ 'seo_desc' ]) ? '' : $params [ 'seo_desc' ],
'is_exist_many_spec' => empty ( $specifications [ 'data' ][ 'title' ]) ? 0 : 1 ,
'spec_base' => empty ( $specifications_base [ 'data' ]) ? '' : json_encode ( $specifications_base [ 'data' ], JSON_UNESCAPED_UNICODE ),
'fictitious_goods_value' => $fictitious_goods_value ,
2026-03-04 10:21:47 +08:00
'use_guide' => $use_guide ,
2025-09-23 21:22:38 +08:00
'site_type' => ( isset ( $params [ 'site_type' ]) && $params [ 'site_type' ] != '' ) ? $params [ 'site_type' ] : - 1 ,
'sort_level' => empty ( $params [ 'sort_level' ]) ? 0 : intval ( $params [ 'sort_level' ]),
'share_images' => $attachment [ 'data' ][ 'share_images' ],
2018-12-28 18:58:37 +08:00
];
2022-03-07 12:30:10 +08:00
// 是否存在赠送积分
if ( array_key_exists ( 'give_integral' , $params ))
{
2025-09-23 21:22:38 +08:00
$data [ 'give_integral' ] = intval ( $params [ 'give_integral' ]);
2022-03-07 12:30:10 +08:00
}
2019-07-24 00:12:51 +08:00
// 商品保存处理钩子
$hook_name = 'plugins_service_goods_save_handle' ;
2021-07-18 23:42:10 +08:00
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
2025-09-23 21:22:38 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => & $params ,
'data' => & $data ,
'spec' => & $specifications [ 'data' ],
'parameter' => & $parameter [ 'data' ],
'photo' => & $photo [ 'data' ],
'content_app' => & $content_app [ 'data' ],
'goods_id' => isset ( $params [ 'id' ]) ? intval ( $params [ 'id' ]) : 0 ,
2019-12-02 20:58:24 +08:00
]));
2019-07-24 00:12:51 +08:00
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
return $ret ;
}
2018-12-28 18:58:37 +08:00
// 启动事务
Db :: startTrans ();
2020-11-25 22:59:17 +08:00
// 捕获异常
try {
2025-09-23 21:22:38 +08:00
// 商品保存事物前钩子
$hook_name = 'plugins_service_goods_save_thing_begin' ;
$ret = MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'data' => & $data ,
'goods_id' => isset ( $params [ 'id' ]) ? intval ( $params [ 'id' ]) : 0 ,
]);
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
throw new \Exception ( $ret [ 'msg' ]);
}
2020-11-25 22:59:17 +08:00
// 添加/编辑
if ( empty ( $params [ 'id' ]))
2018-12-28 18:58:37 +08:00
{
2020-11-25 22:59:17 +08:00
$data [ 'add_time' ] = time ();
$goods_id = Db :: name ( 'Goods' ) -> insertGetId ( $data );
if ( $goods_id <= 0 )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'insert_fail' ));
2020-11-25 22:59:17 +08:00
}
} else {
$data [ 'upd_time' ] = time ();
if ( Db :: name ( 'Goods' ) -> where ([ 'id' => intval ( $params [ 'id' ])]) -> update ( $data ))
{
$goods_id = $params [ 'id' ];
} else {
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'update_fail' ));
2020-11-25 22:59:17 +08:00
}
2018-12-28 18:58:37 +08:00
}
// 分类
2026-03-04 10:21:47 +08:00
$ret = self :: GoodsCategoryInsert ( $category_ids , $goods_id );
2018-12-28 18:58:37 +08:00
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2018-12-28 18:58:37 +08:00
}
// 规格
2019-01-17 00:37:20 +08:00
$ret = self :: GoodsSpecificationsInsert ( $specifications [ 'data' ], $goods_id );
2018-12-28 18:58:37 +08:00
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2025-09-23 21:22:38 +08:00
}
// 更新商品基础信息
$ret = self :: GoodsSaveBaseUpdate ( $goods_id );
if ( $ret [ 'code' ] != 0 )
{
throw new \Exception ( $ret [ 'msg' ]);
2018-12-28 18:58:37 +08:00
}
// 相册
2019-01-17 00:37:20 +08:00
$ret = self :: GoodsPhotoInsert ( $photo [ 'data' ], $goods_id );
2018-12-28 18:58:37 +08:00
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2018-12-28 18:58:37 +08:00
}
// 手机详情
2019-01-17 00:37:20 +08:00
$ret = self :: GoodsContentAppInsert ( $content_app [ 'data' ], $goods_id );
2018-12-28 18:58:37 +08:00
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2018-12-28 18:58:37 +08:00
}
2020-09-02 14:11:49 +08:00
// 商品参数
2025-09-23 21:22:38 +08:00
$ret = self :: GoodsParamsInsert ( $parameter [ 'data' ], $goods_id );
2020-09-02 14:11:49 +08:00
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2020-09-02 14:11:49 +08:00
}
2020-10-11 23:26:06 +08:00
// 仓库规格库存同步
$ret = WarehouseGoodsService :: GoodsSpecChangeInventorySync ( $goods_id );
if ( $ret [ 'code' ] != 0 )
{
2020-11-25 22:59:17 +08:00
throw new \Exception ( $ret [ 'msg' ]);
2020-10-11 23:26:06 +08:00
}
2025-09-23 21:22:38 +08:00
// 商品保存事物后钩子
$hook_name = 'plugins_service_goods_save_thing_end' ;
$ret = MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'data' => $data ,
'goods_id' => $goods_id ,
]);
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
throw new \Exception ( $ret [ 'msg' ]);
}
2020-11-25 22:59:17 +08:00
// 完成
2018-12-28 18:58:37 +08:00
Db :: commit ();
2020-11-25 22:59:17 +08:00
} catch ( \Exception $e ) {
2020-09-21 16:03:38 +08:00
Db :: rollback ();
2020-11-25 22:59:17 +08:00
return DataReturn ( $e -> getMessage (), - 1 );
2018-12-28 18:58:37 +08:00
}
2020-09-21 16:03:38 +08:00
// 商品保存后钩子
$hook_name = 'plugins_service_goods_save_end' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2020-09-21 16:03:38 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'data' => $data ,
'goods_id' => $goods_id ,
]);
// 返回信息
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
2020-09-02 14:11:49 +08:00
/**
* 商品参数添加
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 08 - 31
* @ desc description
2025-09-23 21:22:38 +08:00
* @ param [ array ] $data [ 商品参数数据 ]
2020-09-02 14:11:49 +08:00
* @ param [ int ] $goods_id [ 商品id ]
*/
2025-09-23 21:22:38 +08:00
public static function GoodsParamsInsert ( $data , $goods_id )
2020-09-02 14:11:49 +08:00
{
// 删除商品参数
Db :: name ( 'GoodsParams' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
2020-11-28 20:59:21 +08:00
// 获取参数解析并添加
2025-09-23 21:22:38 +08:00
if ( ! empty ( $data ))
2020-09-02 14:11:49 +08:00
{
2025-09-23 21:22:38 +08:00
foreach ( $data as & $v )
2020-09-02 14:11:49 +08:00
{
2020-11-28 20:59:21 +08:00
$v [ 'goods_id' ] = $goods_id ;
$v [ 'add_time' ] = time ();
2020-09-02 14:11:49 +08:00
}
2025-09-23 21:22:38 +08:00
if ( Db :: name ( 'GoodsParams' ) -> insertAll ( $data ) < count ( $data ))
2020-09-02 14:11:49 +08:00
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_params_add_fail_tips' ), - 1 );
2020-09-02 14:11:49 +08:00
}
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 );
2020-09-02 14:11:49 +08:00
}
2018-12-28 18:58:37 +08:00
/**
* 商品保存基础信息更新
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ datetime 2018 - 12 - 16 T01 : 56 : 42 + 0800
2022-10-21 16:59:10 +08:00
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ array ] $params [ 输入参数 ]
2018-12-28 18:58:37 +08:00
*/
2022-10-21 16:59:10 +08:00
public static function GoodsSaveBaseUpdate ( $goods_id , $params = [])
2018-12-28 18:58:37 +08:00
{
2023-02-23 15:35:30 +08:00
// 商品基础数据
$base = Db :: name ( 'GoodsSpecBase' ) -> where ([ 'goods_id' => $goods_id ]) -> select () -> toArray ();
if ( empty ( $base ))
2018-12-28 18:58:37 +08:00
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_goods_base_empty_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
2023-02-23 15:35:30 +08:00
// 汇总处理
$data = [
'min_price' => min ( array_column ( $base , 'price' )),
'max_price' => max ( array_column ( $base , 'price' )),
'min_original_price' => min ( array_column ( $base , 'original_price' )),
'max_original_price' => max ( array_column ( $base , 'original_price' )),
'inventory' => array_sum ( array_column ( $base , 'inventory' )),
];
// 起购数、限购数处理
$data [ 'buy_min_number' ] = min ( array_column ( $base , 'buy_min_number' ));
if ( $data [ 'buy_min_number' ] <= 0 )
{
$data [ 'buy_min_number' ] = 1 ;
}
$buy_max_number = max ( array_column ( $base , 'buy_max_number' ));
$data [ 'buy_max_number' ] = ( $buy_max_number > 0 && min ( array_column ( $base , 'buy_max_number' )) > 0 ) ? $buy_max_number : 0 ;
2018-12-28 18:58:37 +08:00
// 销售价格 - 展示价格
$data [ 'price' ] = ( ! empty ( $data [ 'max_price' ]) && $data [ 'min_price' ] != $data [ 'max_price' ]) ? $data [ 'min_price' ] . '-' . $data [ 'max_price' ] : $data [ 'min_price' ];
// 原价价格 - 展示价格
$data [ 'original_price' ] = ( ! empty ( $data [ 'max_original_price' ]) && $data [ 'min_original_price' ] != $data [ 'max_original_price' ]) ? $data [ 'min_original_price' ] . '-' . $data [ 'max_original_price' ] : $data [ 'min_original_price' ];
// 更新商品表
$data [ 'upd_time' ] = time ();
2021-08-17 14:38:25 +08:00
if ( Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> update ( $data ) === false )
2018-12-28 18:58:37 +08:00
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_goods_base_update_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
2021-08-17 14:38:25 +08:00
// 商品基础数据更新钩子
$hook_name = 'plugins_service_goods_base_update' ;
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
2022-10-21 16:59:10 +08:00
'goods_id' => $goods_id ,
'params' => $params ,
2021-08-17 14:38:25 +08:00
]));
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
return $ret ;
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
/**
2019-09-23 13:56:03 +08:00
* 获取规格值参数
2018-12-28 18:58:37 +08:00
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 09
* @ desc description
2025-04-25 20:21:19 +08:00
* @ param [ array ] $params [ 输入参数 ]
* @ param [ array ] $base_count [ 教程参数个数, 默认9 ]
2018-12-28 18:58:37 +08:00
*/
2025-04-25 20:21:19 +08:00
public static function GetFormGoodsSpecificationsParams ( $params = [], $base_count = 9 )
2018-12-28 18:58:37 +08:00
{
$data = [];
$title = [];
$images = [];
2019-01-12 01:41:02 +08:00
// 基础字段数据字段长度
2023-02-23 15:35:30 +08:00
// 销售价、原价、起购数、限购数、重量、体积、编码、条形码、扩展
2019-01-12 01:41:02 +08:00
2018-12-28 18:58:37 +08:00
// 规格值
foreach ( $params as $k => $v )
{
if ( substr ( $k , 0 , 15 ) == 'specifications_' )
{
$keys = explode ( '_' , $k );
if ( count ( $keys ) > 1 )
{
if ( $keys [ 1 ] != 'name' )
{
foreach ( $v as $ks => $vs )
{
2019-07-22 00:46:16 +08:00
if ( $keys [ 1 ] == 'extends' )
{
$data [ $ks ][] = empty ( $vs ) ? null : htmlspecialchars_decode ( $vs );
} else {
2020-12-07 18:51:13 +08:00
$data [ $ks ][] = trim ( $vs );
2019-07-22 00:46:16 +08:00
}
2018-12-28 18:58:37 +08:00
}
}
}
}
}
2019-01-12 01:41:02 +08:00
// 规格处理
2018-12-28 18:58:37 +08:00
if ( ! empty ( $data [ 0 ]))
{
2019-01-12 01:41:02 +08:00
$count = count ( $data [ 0 ]) - $base_count ;
2018-12-28 18:58:37 +08:00
if ( $count > 0 )
{
2019-01-12 01:41:02 +08:00
// 列之间是否存在相同的值
$column_value = [];
foreach ( $data as $data_value )
{
foreach ( $data_value as $temp_key => $temp_value )
{
if ( $temp_key < $count )
{
$column_value [ $temp_key ][] = $temp_value ;
}
}
}
if ( ! empty ( $column_value ) && count ( $column_value ) > 1 )
{
$temp_column = [];
foreach ( $column_value as $column_key => $column_val )
{
foreach ( $column_value as $column_keys => $column_vals )
{
if ( $column_key != $column_keys )
{
$temp = array_intersect ( $column_val , $column_vals );
$temp_column = array_merge ( $temp_column , $temp );
}
}
}
if ( ! empty ( $temp_column ))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_column_repeat_tips' ) . '[' . implode ( ',' , array_unique ( $temp_column )) . ']' , - 1 );
2019-01-12 01:41:02 +08:00
}
}
2019-08-02 16:37:38 +08:00
// 规格值是否重复
if ( ! empty ( $column_value [ 0 ]))
{
$temp_row_data = [];
$temp_row_count = count ( $column_value );
foreach ( $column_value [ 0 ] as $row_key => $row_value )
{
for ( $i = 0 ; $i < $temp_row_count ; $i ++ )
{
if ( isset ( $column_value [ $i ][ $row_key ]))
{
if ( isset ( $temp_row_data [ $row_key ]))
{
$temp_row_data [ $row_key ] .= $column_value [ $i ][ $row_key ];
} else {
$temp_row_data [ $row_key ] = $column_value [ $i ][ $row_key ];
}
}
}
}
if ( ! empty ( $temp_row_data ))
{
$unique_all = array_unique ( $temp_row_data );
$repeat_rows_all = array_diff_assoc ( $temp_row_data , $unique_all );
if ( ! empty ( $repeat_rows_all ))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_value_repeat_tips' ) . '[' . implode ( ',' , array_unique ( $repeat_rows_all )) . ']' , - 1 );
2019-08-02 16:37:38 +08:00
}
}
}
2019-01-12 01:41:02 +08:00
// 规格名称
2019-01-14 01:08:02 +08:00
$names_value = [];
2018-12-28 18:58:37 +08:00
$names = array_slice ( $data [ 0 ], 0 , $count );
foreach ( $names as $v )
{
foreach ( $params as $ks => $vs )
{
if ( substr ( $ks , 0 , 21 ) == 'specifications_value_' )
{
if ( in_array ( $v , $vs ))
{
$key = substr ( $ks , 21 );
if ( ! empty ( $params [ 'specifications_name_' . $key ]))
{
2020-12-07 18:51:13 +08:00
$spec_name = trim ( $params [ 'specifications_name_' . $key ]);
$title [ $spec_name ] = [
'name' => $spec_name ,
2018-12-28 18:58:37 +08:00
'value' => array_unique ( $vs ),
];
2019-01-14 01:08:02 +08:00
$names_value [] = $params [ 'specifications_name_' . $key ];
2018-12-28 18:58:37 +08:00
}
}
}
}
}
2019-01-14 01:08:02 +08:00
2019-01-14 01:13:39 +08:00
// 规格名称列之间是否存在重复
2019-01-14 01:08:02 +08:00
$unique_all = array_unique ( $names_value );
$repeat_names_all = array_diff_assoc ( $names_value , $unique_all );
if ( ! empty ( $repeat_names_all ))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_name_column_repeat_tips' ) . '[' . implode ( ',' , array_unique ( $repeat_names_all )) . ']' , - 1 );
2019-01-14 01:08:02 +08:00
}
2018-12-28 18:58:37 +08:00
} else {
2021-02-15 22:45:33 +08:00
if ( ! isset ( $data [ 0 ][ 0 ]) || $data [ 0 ][ 0 ] < 0 )
2018-12-28 18:58:37 +08:00
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_base_price_error_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
} else {
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_empty_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
// 规格图片
if ( ! empty ( $params [ 'spec_images_name' ]) && ! empty ( $params [ 'spec_images' ]))
{
foreach ( $params [ 'spec_images_name' ] as $k => $v )
{
if ( ! empty ( $params [ 'spec_images' ][ $k ]))
{
$images [ $v ] = $params [ 'spec_images' ][ $k ];
}
}
}
2019-08-02 16:38:34 +08:00
2018-12-28 18:58:37 +08:00
return DataReturn ( 'success' , 0 , [ 'data' => $data , 'title' => $title , 'images' => $images ]);
}
2019-09-23 13:56:03 +08:00
/**
* 获取规格基础参数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2019 - 09 - 23
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2020-09-08 23:36:30 +08:00
public static function GetFormGoodsSpecificationsBaseParams ( $params = [])
2019-09-23 13:56:03 +08:00
{
$result = [];
foreach ( $params as $k => $v )
{
if ( substr ( $k , 0 , 16 ) == 'spec_base_title_' )
{
$key = substr ( $k , 16 );
$result [] = [
'title' => $v ,
'value' => isset ( $params [ 'spec_base_value_' . $key ]) ? $params [ 'spec_base_value_' . $key ] : [],
];
}
}
return DataReturn ( 'success' , 0 , $result );
}
2018-12-28 18:58:37 +08:00
/**
* 获取商品相册
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
* @ return [ array ] [ 一维数组但图片地址 ]
*/
2020-09-08 23:36:30 +08:00
public static function GetFormGoodsPhotoParams ( $params = [])
2018-12-28 18:58:37 +08:00
{
if ( empty ( $params [ 'photo' ]))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_photo_empty_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
2025-09-23 21:22:38 +08:00
$result = ResourcesService :: AttachmentPathHandle ( $params [ 'photo' ]);
2018-12-28 18:58:37 +08:00
return DataReturn ( 'success' , 0 , $result );
}
/**
* 获取app内容
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 09
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2020-09-08 23:36:30 +08:00
public static function GetFormGoodsContentAppParams ( $params = [])
2018-12-28 18:58:37 +08:00
{
// 开始处理
$result = [];
$name = 'content_app_' ;
foreach ( $params AS $k => $v )
{
if ( substr ( $k , 0 , 12 ) == $name )
{
$key = explode ( '_' , str_replace ( $name , '' , $k ));
if ( count ( $key ) == 2 )
{
$result [ $key [ 1 ]][ $key [ 0 ]] = $v ;
if ( $key [ 0 ] == 'images' )
{
$result [ $key [ 1 ]][ $key [ 0 ]] = ResourcesService :: AttachmentPathHandle ( $v );
}
}
}
}
return DataReturn ( 'success' , 0 , $result );
}
/**
* 商品分类添加
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
* @ param [ array ] $data [ 数据 ]
* @ param [ int ] $goods_id [ 商品id ]
* @ return [ array ] [ boolean | msg ]
*/
2020-09-08 23:36:30 +08:00
public static function GoodsCategoryInsert ( $data , $goods_id )
2018-12-28 18:58:37 +08:00
{
Db :: name ( 'GoodsCategoryJoin' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
if ( ! empty ( $data ))
{
foreach ( $data as $category_id )
{
$temp_category = [
'goods_id' => $goods_id ,
'category_id' => $category_id ,
'add_time' => time (),
];
if ( Db :: name ( 'GoodsCategoryJoin' ) -> insertGetId ( $temp_category ) <= 0 )
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_category_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'insert_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
/**
* 商品手机详情添加
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
* @ param [ array ] $data [ 数据 ]
* @ param [ int ] $goods_id [ 商品id ]
* @ return [ array ] [ boolean | msg ]
*/
2020-09-08 23:36:30 +08:00
public static function GoodsContentAppInsert ( $data , $goods_id )
2018-12-28 18:58:37 +08:00
{
Db :: name ( 'GoodsContentApp' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
if ( ! empty ( $data ))
{
foreach ( array_values ( $data ) as $k => $v )
{
$temp_content = [
'goods_id' => $goods_id ,
'images' => empty ( $v [ 'images' ]) ? '' : $v [ 'images' ],
'content' => $v [ 'text' ],
'sort' => $k ,
'add_time' => time (),
];
if ( Db :: name ( 'GoodsContentApp' ) -> insertGetId ( $temp_content ) <= 0 )
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_app_content_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'insert_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
/**
* 商品相册添加
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
* @ param [ array ] $data [ 数据 ]
* @ param [ int ] $goods_id [ 商品id ]
* @ return [ array ] [ boolean | msg ]
*/
2020-09-08 23:36:30 +08:00
public static function GoodsPhotoInsert ( $data , $goods_id )
2018-12-28 18:58:37 +08:00
{
Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
if ( ! empty ( $data ))
{
foreach ( $data as $k => $v )
{
$temp_photo = [
'goods_id' => $goods_id ,
'images' => $v ,
'is_show' => 1 ,
'sort' => $k ,
'add_time' => time (),
];
if ( Db :: name ( 'GoodsPhoto' ) -> insertGetId ( $temp_photo ) <= 0 )
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_photo_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'insert_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
/**
* 商品规格添加
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 07 - 10
* @ desc description
* @ param [ array ] $data [ 数据 ]
* @ param [ int ] $goods_id [ 商品id ]
* @ return [ array ] [ boolean | msg ]
*/
2020-09-08 23:36:30 +08:00
public static function GoodsSpecificationsInsert ( $data , $goods_id )
2018-12-28 18:58:37 +08:00
{
// 删除原来的数据
Db :: name ( 'GoodsSpecType' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
Db :: name ( 'GoodsSpecValue' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
Db :: name ( 'GoodsSpecBase' ) -> where ([ 'goods_id' => $goods_id ]) -> delete ();
// 类型
if ( ! empty ( $data [ 'title' ]))
{
foreach ( $data [ 'title' ] as & $v )
{
$spec = [];
foreach ( $v [ 'value' ] as $vs )
{
$spec [] = [
'name' => $vs ,
'images' => isset ( $data [ 'images' ][ $vs ]) ? ResourcesService :: AttachmentPathHandle ( $data [ 'images' ][ $vs ]) : '' ,
];
}
$v [ 'goods_id' ] = $goods_id ;
2020-07-25 00:13:18 +08:00
$v [ 'value' ] = json_encode ( $spec , JSON_UNESCAPED_UNICODE );
2018-12-28 18:58:37 +08:00
$v [ 'add_time' ] = time ();
}
if ( Db :: name ( 'GoodsSpecType' ) -> insertAll ( $data [ 'title' ]) < count ( $data [ 'title' ]))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_type_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
// 基础/规格值
if ( ! empty ( $data [ 'data' ]))
{
// 基础字段
$count = count ( $data [ 'data' ][ 0 ]);
2025-09-23 21:22:38 +08:00
$temp_key = self :: GoodsSpecBaseFields ();
2018-12-28 18:58:37 +08:00
$key_count = count ( $temp_key );
// 等于key总数则只有一列基础规格
if ( $count == $key_count )
{
$temp_data = [
'goods_id' => $goods_id ,
'add_time' => time (),
];
for ( $i = 0 ; $i < $count ; $i ++ )
{
$temp_data [ $temp_key [ $i ]] = $data [ 'data' ][ 0 ][ $i ];
}
2020-07-16 22:34:56 +08:00
// 获取仓库规格库存
2020-07-17 15:43:13 +08:00
$temp_data [ 'inventory' ] = WarehouseGoodsService :: WarehouseGoodsSpecInventory ( $goods_id );
2020-07-16 22:34:56 +08:00
2018-12-28 18:58:37 +08:00
// 规格基础添加
if ( Db :: name ( 'GoodsSpecBase' ) -> insertGetId ( $temp_data ) <= 0 )
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_base_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
// 多规格操作
} else {
$base_start = $count - $key_count ;
foreach ( $data [ 'data' ] as $v )
{
$temp_value = [];
$temp_data = [
'goods_id' => $goods_id ,
'add_time' => time (),
];
for ( $i = 0 ; $i < $count ; $i ++ )
{
if ( $i < $base_start )
{
$temp_value [] = [
'goods_id' => $goods_id ,
'value' => $v [ $i ],
2026-03-04 10:21:47 +08:00
'md5_key' => empty ( $v [ $i ]) ? '' : md5 ( $v [ $i ]),
2018-12-28 18:58:37 +08:00
'add_time' => time ()
];
} else {
$temp_data [ $temp_key [ $i - $base_start ]] = $v [ $i ];
}
}
2020-07-16 22:34:56 +08:00
// 获取仓库规格库存
2020-07-30 19:31:04 +08:00
$temp_data [ 'inventory' ] = WarehouseGoodsService :: WarehouseGoodsSpecInventory ( $goods_id , implode ( '' , array_column ( $temp_value , 'value' )));
2018-12-28 18:58:37 +08:00
// 规格基础添加
$base_id = Db :: name ( 'GoodsSpecBase' ) -> insertGetId ( $temp_data );
if ( empty ( $base_id ))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_base_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
// 规格值添加
foreach ( $temp_value as & $value )
{
$value [ 'goods_spec_base_id' ] = $base_id ;
}
if ( Db :: name ( 'GoodsSpecValue' ) -> insertAll ( $temp_value ) < count ( $temp_value ))
{
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.save_spec_value_add_fail_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
}
}
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'insert_success' ), 0 );
2018-12-28 18:58:37 +08:00
}
2025-09-23 21:22:38 +08:00
/**
* 商品规格基础数据字段
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 09 - 16
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsSpecBaseFields ( $params = [])
{
return [
'price' ,
'original_price' ,
'buy_min_number' ,
'buy_max_number' ,
'weight' ,
'volume' ,
'coding' ,
'barcode' ,
'inventory_unit' ,
'extends' ,
];
}
2018-12-28 18:58:37 +08:00
/**
* 商品删除
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ datetime 2018 - 12 - 07 T00 : 24 : 14 + 0800
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsDelete ( $params = [])
2018-12-28 18:58:37 +08:00
{
// 参数是否有误
2020-06-07 17:36:43 +08:00
if ( empty ( $params [ 'ids' ]))
2018-12-28 18:58:37 +08:00
{
2023-02-04 16:47:48 +08:00
return DataReturn ( MyLang ( 'data_id_error_tips' ), - 1 );
2018-12-28 18:58:37 +08:00
}
2020-06-07 17:36:43 +08:00
// 是否数组
if ( ! is_array ( $params [ 'ids' ]))
{
$params [ 'ids' ] = explode ( ',' , $params [ 'ids' ]);
}
2018-12-28 18:58:37 +08:00
2021-01-10 13:18:35 +08:00
// 启动事务
2018-12-28 18:58:37 +08:00
Db :: startTrans ();
2021-01-10 13:18:35 +08:00
// 捕获异常
try {
2021-01-27 22:21:04 +08:00
// 删除商品操作
2023-05-19 10:13:16 +08:00
self :: GoodsDeleteHandle ( $params [ 'ids' ], $params );
2018-12-28 18:58:37 +08:00
2020-09-21 16:03:38 +08:00
// 商品删除钩子
$hook_name = 'plugins_service_goods_delete' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2020-09-21 16:03:38 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
2021-01-27 22:21:04 +08:00
'goods_ids' => $params [ 'ids' ],
2020-09-21 16:03:38 +08:00
]);
2018-12-28 18:58:37 +08:00
// 提交事务
Db :: commit ();
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'delete_success' ), 0 );
2021-01-10 13:18:35 +08:00
} catch ( \Exception $e ) {
Db :: rollback ();
return DataReturn ( $e -> getMessage (), - 1 );
2018-12-28 18:58:37 +08:00
}
}
2021-01-27 22:21:04 +08:00
/**
* 商品删除操作
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2021 - 01 - 27
* @ desc description
* @ param [ array ] $goods_ids [ 商品id ]
2023-05-19 10:13:16 +08:00
* @ param [ array ] $params [ 输入参数 ]
2021-01-27 22:21:04 +08:00
*/
2023-05-19 10:13:16 +08:00
public static function GoodsDeleteHandle ( $goods_ids , $params = [])
2021-01-27 22:21:04 +08:00
{
2025-05-13 21:46:05 +08:00
// 是否删除附件
$del_attachment_data = [];
2023-05-19 10:13:16 +08:00
$is_del_images = isset ( $params [ 'is_del_images' ]) && $params [ 'is_del_images' ] == 1 ;
if ( $is_del_images )
{
// 商品主图
$goods_images = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'images' , '<>' , '' ]]) -> column ( 'images' );
if ( ! empty ( $goods_images ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $goods_images ));
}
// 商品视频
$goods_video = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'video' , '<>' , '' ]]) -> column ( 'video' );
if ( ! empty ( $goods_video ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $goods_video ));
2023-05-19 10:13:16 +08:00
}
2025-03-03 17:49:22 +08:00
// 商品分享图
$goods_share_images = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'share_images' , '<>' , '' ]]) -> column ( 'share_images' );
if ( ! empty ( $goods_share_images ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $goods_share_images ));
2025-03-03 17:49:22 +08:00
}
2023-05-19 10:13:16 +08:00
// 商品规格图
$goods_spec_type = Db :: name ( 'GoodsSpecType' ) -> where ([ 'goods_id' => $goods_ids ]) -> column ( 'value' );
if ( ! empty ( $goods_spec_type ))
{
foreach ( $goods_spec_type as $v )
{
$v = json_decode ( $v , true );
if ( ! empty ( $v ) && is_array ( $v ))
{
$temp = array_unique ( array_filter ( array_column ( $v , 'images' )));
if ( ! empty ( $temp ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
2023-05-19 10:13:16 +08:00
}
}
}
}
// 商品相册
$goods_photo = Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_ids ]) -> column ( 'images' );
if ( ! empty ( $goods_photo ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $goods_photo ));
2023-05-19 10:13:16 +08:00
}
2025-05-13 21:46:05 +08:00
// 商品详情内容
2023-05-19 10:13:16 +08:00
$goods_content = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'content_web' , '<>' , '' ]]) -> column ( 'content_web' );
if ( ! empty ( $goods_content ))
{
foreach ( $goods_content as $v )
{
2024-10-21 10:51:14 +08:00
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'images' );
2023-05-19 10:13:16 +08:00
if ( ! empty ( $temp ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'video' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
2025-09-23 21:22:38 +08:00
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'file' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
2025-05-13 21:46:05 +08:00
}
}
// 商品虚拟内容
$goods_fictitious = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'fictitious_goods_value' , '<>' , '' ]]) -> column ( 'fictitious_goods_value' );
if ( ! empty ( $goods_fictitious ))
{
foreach ( $goods_fictitious as $v )
{
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'images' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'video' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
2023-05-19 10:13:16 +08:00
}
2025-09-23 21:22:38 +08:00
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'file' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
2023-05-19 10:13:16 +08:00
}
}
2026-03-04 10:21:47 +08:00
// 商品使用指南内容
$goods_use_guide = Db :: name ( 'Goods' ) -> where ([[ 'id' , 'in' , $goods_ids ], [ 'use_guide' , '<>' , '' ]]) -> column ( 'use_guide' );
if ( ! empty ( $goods_use_guide ))
{
foreach ( $goods_use_guide as $v )
{
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'images' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'video' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
$temp = ResourcesService :: RichTextMatchContentAttachment ( $v , 'goods' , 'file' );
if ( ! empty ( $temp ))
{
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $temp ));
}
}
}
2023-05-19 10:13:16 +08:00
// 商品app
$goods_app = Db :: name ( 'GoodsContentApp' ) -> where ([[ 'goods_id' , 'in' , $goods_ids ], [ 'images' , '<>' , '' ]]) -> column ( 'images' );
if ( ! empty ( $goods_app ))
{
2025-05-13 21:46:05 +08:00
$del_attachment_data = array_unique ( array_merge ( $del_attachment_data , $goods_app ));
2023-05-19 10:13:16 +08:00
}
}
2021-01-27 22:21:04 +08:00
// 删除商品
2022-06-28 23:19:51 +08:00
if ( Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_ids ]) -> delete () === false )
2021-01-27 22:21:04 +08:00
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_goods_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
// 商品规格
if ( Db :: name ( 'GoodsSpecType' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_spec_type_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
if ( Db :: name ( 'GoodsSpecValue' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_spec_value_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
if ( Db :: name ( 'GoodsSpecBase' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_spec_base_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
2023-02-23 15:35:30 +08:00
// 关联分类
if ( Db :: name ( 'GoodsCategoryJoin' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
throw new \Exception ( MyLang ( 'common_service.goods.delete_goods_category_fail_tips' ));
}
2021-01-27 22:21:04 +08:00
// 相册
if ( Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_goods_photo_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
// app内容
if ( Db :: name ( 'GoodsContentApp' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_app_content_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
// 商品参数
if ( Db :: name ( 'GoodsParams' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_params_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
// 商品关联仓库信息+库存
if ( Db :: name ( 'WarehouseGoods' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_warehouse_goods_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
if ( Db :: name ( 'WarehouseGoodsSpec' ) -> where ([ 'goods_id' => $goods_ids ]) -> delete () === false )
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'common_service.goods.delete_warehouse_goods_spec_fail_tips' ));
2021-01-27 22:21:04 +08:00
}
2023-05-19 10:13:16 +08:00
// 是否删除图片
2025-05-13 21:46:05 +08:00
if ( $is_del_images && ! empty ( $del_attachment_data ))
2023-05-19 10:13:16 +08:00
{
2025-05-13 21:46:05 +08:00
AttachmentService :: AttachmentUrlDelete ( $del_attachment_data );
2023-05-19 10:13:16 +08:00
}
2021-01-27 22:21:04 +08:00
}
2018-12-28 18:58:37 +08:00
/**
* 商品状态更新
* @ author Devil
* @ blog http :// gong . gg /
* @ version 0.0 . 1
* @ datetime 2016 - 12 - 06 T21 : 31 : 53 + 0800
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsStatusUpdate ( $params = [])
2018-12-28 18:58:37 +08:00
{
// 请求参数
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'id' ,
2023-02-04 16:47:48 +08:00
'error_msg' => MyLang ( 'data_id_error_tips' ),
2018-12-28 18:58:37 +08:00
],
[
'checked_type' => 'empty' ,
'key_name' => 'field' ,
2023-02-06 18:30:08 +08:00
'error_msg' => MyLang ( 'operate_field_error_tips' ),
2018-12-28 18:58:37 +08:00
],
[
'checked_type' => 'in' ,
'key_name' => 'state' ,
'checked_data' => [ 0 , 1 ],
2023-02-04 16:47:48 +08:00
'error_msg' => MyLang ( 'form_status_range_message' ),
2018-12-28 18:58:37 +08:00
],
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
2021-01-27 22:21:04 +08:00
// 启动事务
Db :: startTrans ();
// 捕获异常
try {
// 基础参数
$goods_id = intval ( $params [ 'id' ]);
$field = $params [ 'field' ];
$status = intval ( $params [ 'state' ]);
// 数据更新
if ( ! Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> update ([ $field => $status , 'upd_time' => time ()]))
{
2023-02-08 21:20:04 +08:00
throw new \Exception ( MyLang ( 'operate_fail' ));
2021-01-27 22:21:04 +08:00
}
2022-06-06 16:49:59 +08:00
// 商品状态更新钩子
2021-01-27 22:21:04 +08:00
$hook_name = 'plugins_service_goods_field_status_update' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2021-01-27 22:21:04 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'goods_id' => $goods_id ,
'field' => $field ,
'status' => $status ,
]);
// 提交事务
Db :: commit ();
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 );
2021-01-27 22:21:04 +08:00
} catch ( \Exception $e ) {
Db :: rollback ();
return DataReturn ( $e -> getMessage (), - 1 );
2018-12-28 18:58:37 +08:00
}
}
/**
* 获取商品编辑规格
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 12 - 14
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsEditSpecifications ( $goods_id )
2018-12-28 18:58:37 +08:00
{
$where = [ 'goods_id' => $goods_id ];
// 获取规格类型
2021-07-18 23:42:10 +08:00
$type = Db :: name ( 'GoodsSpecType' ) -> where ( $where ) -> order ( 'id asc' ) -> field ( 'id,name,value' ) -> select () -> toArray ();
2018-12-28 18:58:37 +08:00
$value = [];
if ( ! empty ( $type ))
{
// 数据处理
foreach ( $type as & $temp_type )
{
$temp_type_value = json_decode ( $temp_type [ 'value' ], true );
foreach ( $temp_type_value as & $vs )
{
2019-01-14 00:03:29 +08:00
$vs [ 'images' ] = ResourcesService :: AttachmentPathViewHandle ( $vs [ 'images' ]);
2018-12-28 18:58:37 +08:00
}
$temp_type [ 'value' ] = $temp_type_value ;
}
// 获取规格值
2021-07-18 23:42:10 +08:00
$temp_value = Db :: name ( 'GoodsSpecValue' ) -> where ( $where ) -> field ( 'goods_spec_base_id,value' ) -> order ( 'id asc' ) -> select () -> toArray ();
2018-12-28 18:58:37 +08:00
if ( ! empty ( $temp_value ))
{
foreach ( $temp_value as $value_v )
{
$key = '' ;
foreach ( $type as $type_v )
{
foreach ( $type_v [ 'value' ] as $type_vs )
{
2020-12-07 18:51:13 +08:00
if ( trim ( $type_vs [ 'name' ]) == trim ( $value_v [ 'value' ]))
2018-12-28 18:58:37 +08:00
{
$key = $type_v [ 'id' ];
break ;
}
}
}
2020-12-07 18:51:13 +08:00
if ( ! empty ( $key ))
{
$value [ $value_v [ 'goods_spec_base_id' ]][] = [
'data_type' => 'spec' ,
'data' => [
'key' => $key ,
'value' => trim ( $value_v [ 'value' ]),
],
];
}
2018-12-28 18:58:37 +08:00
}
}
if ( ! empty ( $value ))
{
foreach ( $value as $k =>& $v )
{
$base = Db :: name ( 'GoodsSpecBase' ) -> find ( $k );
2019-02-25 11:15:31 +08:00
$base [ 'weight' ] = PriceBeautify ( $base [ 'weight' ]);
2022-07-17 22:27:23 +08:00
$base [ 'volume' ] = PriceBeautify ( $base [ 'volume' ]);
2018-12-28 18:58:37 +08:00
$v [] = [
'data_type' => 'base' ,
'data' => $base ,
];
}
}
} else {
$base = Db :: name ( 'GoodsSpecBase' ) -> where ( $where ) -> find ();
2025-09-23 21:22:38 +08:00
if ( ! empty ( $base ))
{
$base [ 'weight' ] = PriceBeautify ( $base [ 'weight' ]);
$base [ 'volume' ] = PriceBeautify ( $base [ 'volume' ]);
$value [] = [
[
'data_type' => 'base' ,
'data' => $base ,
]
];
}
2018-12-28 18:58:37 +08:00
}
return [
2026-03-04 10:21:47 +08:00
'type' => $type ,
'value' => array_values ( $value ),
2018-12-28 18:58:37 +08:00
];
}
2020-09-02 14:11:49 +08:00
/**
* 获取商品编辑参数
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 08 - 31
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
2025-10-26 15:57:22 +08:00
* @ param [ array ] $data [ 指定参数数据 ]
2020-09-02 14:11:49 +08:00
*/
2025-10-26 15:57:22 +08:00
public static function GoodsEditParameters ( $goods_id = 0 , $data = [])
2020-09-02 14:11:49 +08:00
{
2025-10-26 15:57:22 +08:00
$data = empty ( $data ) ? Db :: name ( 'GoodsParams' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'id asc' ) -> select () -> toArray () : $data ;
if ( ! empty ( $data ))
{
foreach ( $data as & $v )
{
$v [ 'key' ] = ( isset ( $v [ 'scope' ]) && isset ( $v [ 'name' ]) && isset ( $v [ 'data_type' ])) ? md5 ( $v [ 'scope' ] . $v [ 'name' ] . $v [ 'data_type' ]) : '' ;
if ( isset ( $v [ 'value' ]) && isset ( $v [ 'data_type' ]) && in_array ( $v [ 'data_type' ], [ 2 ]))
{
$v [ 'value' ] = explode ( ',' , $v [ 'value' ]);
}
}
$data = array_column ( $data , null , 'key' );
}
return $data ;
2020-09-02 14:11:49 +08:00
}
2018-12-28 18:58:37 +08:00
/**
* 商品规格信息
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 12 - 14
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsSpecDetail ( $params = [])
2018-12-28 18:58:37 +08:00
{
// 请求参数
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'id' ,
2023-02-06 18:30:08 +08:00
'error_msg' => MyLang ( 'goods_id_error_tips' ),
2018-12-28 18:58:37 +08:00
],
[
'checked_type' => 'empty' ,
'key_name' => 'spec' ,
'is_checked' => 1 ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.base_spec_not_choice_tips' ),
2018-12-28 18:58:37 +08:00
],
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
// 条件
$goods_id = intval ( $params [ 'id' ]);
$where = [
2023-01-17 16:37:00 +08:00
'goods_id' => $goods_id ,
2018-12-28 18:58:37 +08:00
];
2023-01-17 16:37:00 +08:00
// 规格数据
// 规格不为数组则为json字符串
$spec = [];
2018-12-28 18:58:37 +08:00
if ( ! empty ( $params [ 'spec' ]))
{
if ( ! is_array ( $params [ 'spec' ]))
{
2023-02-23 15:35:30 +08:00
$params [ 'spec' ] = json_decode ( htmlspecialchars_decode ( $params [ 'spec' ]), true );
2018-12-28 18:58:37 +08:00
}
2023-01-17 16:37:00 +08:00
$spec = array_column ( $params [ 'spec' ], 'value' );
}
2018-12-28 18:58:37 +08:00
2023-01-17 16:37:00 +08:00
// 规格基础静态临时存储
static $goods_service_goods_spec_base_static_data = [];
$key = $goods_id . ( empty ( $spec ) ? '' : md5 ( json_encode ( $spec , JSON_UNESCAPED_UNICODE )));
if ( array_key_exists ( $key , $goods_service_goods_spec_base_static_data ))
{
2023-03-01 15:58:28 +08:00
$base = Db :: name ( 'GoodsSpecBase' ) -> find ( $goods_service_goods_spec_base_static_data [ $key ]);
2023-01-17 16:37:00 +08:00
} else {
2023-09-02 23:56:57 +08:00
// 商品信息
$info = Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> field ( 'id,title,is_exist_many_spec' ) -> find ();
if ( empty ( $info ))
{
return DataReturn ( '【' . $goods_id . '】' . MyLang ( 'no_goods' ), - 1 );
}
// 规格值校验处理
2023-01-17 16:37:00 +08:00
$base = [];
2023-09-02 23:56:57 +08:00
if ( empty ( $spec ))
2018-12-28 18:58:37 +08:00
{
2023-09-02 23:56:57 +08:00
// 没有指定规格、但是商品已存在规则则报错
if ( $info [ 'is_exist_many_spec' ] == 1 )
{
return DataReturn ( '【' . $info [ 'title' ] . '】' . MyLang ( 'common_service.goods.base_spec_not_choice_tips' ), - 1 );
}
// 单个规则则直接获取规格基础
$base = Db :: name ( 'GoodsSpecBase' ) -> where ( $where ) -> find ();
} else {
// 指定规格规格、但是商品没有规格则报错
if ( $info [ 'is_exist_many_spec' ] == 0 )
{
return DataReturn ( '【' . $info [ 'title' ] . '】' . MyLang ( 'common_service.goods.base_spec_empty_tips' ), - 1 );
}
2023-01-17 16:37:00 +08:00
// 获取规格值基础值id
$where [ 'value' ] = $spec ;
$ids = Db :: name ( 'GoodsSpecValue' ) -> where ( $where ) -> column ( 'goods_spec_base_id' );
if ( ! empty ( $ids ))
2018-12-28 18:58:37 +08:00
{
2023-01-17 16:37:00 +08:00
// 根据基础值id获取规格值列表
$temp_data = Db :: name ( 'GoodsSpecValue' ) -> where ([ 'goods_spec_base_id' => $ids ]) -> field ( 'goods_spec_base_id,value' ) -> order ( 'id asc' ) -> select () -> toArray ();
if ( ! empty ( $temp_data ))
2018-12-28 18:58:37 +08:00
{
2023-01-17 16:37:00 +08:00
// 根据基础值id分组
$data = [];
foreach ( $temp_data as $v )
{
$data [ $v [ 'goods_spec_base_id' ]][] = $v ;
}
2018-12-28 18:58:37 +08:00
2023-01-17 16:37:00 +08:00
// 从条件中匹配对应的规格值得到最终的基础值id
$base_id = 0 ;
$spec_str = implode ( '' , array_column ( $params [ 'spec' ], 'value' ));
foreach ( $data as $value_v )
2018-12-28 18:58:37 +08:00
{
2023-01-17 16:37:00 +08:00
$temp_str = implode ( '' , array_column ( $value_v , 'value' ));
if ( $temp_str == $spec_str )
{
$base_id = $value_v [ 0 ][ 'goods_spec_base_id' ];
break ;
}
}
// 获取基础值数据
if ( ! empty ( $base_id ))
{
$base = Db :: name ( 'GoodsSpecBase' ) -> find ( $base_id );
2018-12-28 18:58:37 +08:00
}
}
}
}
2023-03-01 15:57:21 +08:00
if ( ! empty ( $base ))
{
$goods_service_goods_spec_base_static_data [ $key ] = $base [ 'id' ];
}
2019-02-26 23:07:22 +08:00
}
// 是否有规格
if ( ! empty ( $base ))
{
// 单位 .00 处理
2019-02-25 11:15:31 +08:00
$base [ 'weight' ] = PriceBeautify ( $base [ 'weight' ]);
2019-02-26 23:07:22 +08:00
2019-07-25 17:11:32 +08:00
// 处理好的数据
// 扩展元素标记与html内容数据
// extends_element下包含多个元素 ['element'=>'', 'content'=>'']
$data = [
'spec_base' => $base ,
'extends_element' => [],
];
// 商品获取规格钩子
2019-02-26 23:07:22 +08:00
$hook_name = 'plugins_service_goods_spec_base' ;
2021-07-18 23:42:10 +08:00
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
2019-02-26 23:07:22 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
2019-07-25 17:11:32 +08:00
'params' => $params ,
2025-09-23 21:22:38 +08:00
'spec' => $spec ,
2019-07-25 17:11:32 +08:00
'data' => & $data ,
2019-02-26 23:07:22 +08:00
'goods_id' => $goods_id
2019-12-02 20:58:24 +08:00
]));
2019-02-26 23:07:22 +08:00
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
2018-12-28 18:58:37 +08:00
{
2019-02-26 23:07:22 +08:00
return $ret ;
2018-12-28 18:58:37 +08:00
}
2019-02-26 23:07:22 +08:00
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 , $data );
2018-12-28 18:58:37 +08:00
}
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.base_spec_empty_tips' ), - 100 );
2018-12-28 18:58:37 +08:00
}
/**
* 商品规格类型
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 12 - 14
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2019-01-17 00:37:20 +08:00
public static function GoodsSpecType ( $params = [])
2018-12-28 18:58:37 +08:00
{
// 请求参数
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'id' ,
2023-02-06 18:30:08 +08:00
'error_msg' => MyLang ( 'goods_id_error_tips' ),
2018-12-28 18:58:37 +08:00
],
[
'checked_type' => 'empty' ,
'key_name' => 'spec' ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'common_service.goods.base_spec_not_choice_tips' ),
2018-12-28 18:58:37 +08:00
],
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
// 条件
$goods_id = intval ( $params [ 'id' ]);
$where = [
'goods_id' => intval ( $params [ 'id' ]),
];
// 规格不为数组则为json字符串
if ( ! is_array ( $params [ 'spec' ]))
{
2019-03-25 09:52:38 +08:00
$params [ 'spec' ] = json_decode ( htmlspecialchars_decode ( $params [ 'spec' ]), true );
2018-12-28 18:58:37 +08:00
}
2021-03-14 23:03:31 +08:00
$where [ 'value' ] = array_column ( $params [ 'spec' ], 'value' );
2018-12-28 18:58:37 +08:00
// 获取规格值基础值id
$ids = Db :: name ( 'GoodsSpecValue' ) -> where ( $where ) -> column ( 'goods_spec_base_id' );
if ( ! empty ( $ids ))
{
// 根据基础值id获取规格值列表
2021-07-18 23:42:10 +08:00
$temp_data = Db :: name ( 'GoodsSpecValue' ) -> where ([ 'goods_spec_base_id' => $ids ]) -> field ( 'goods_spec_base_id,value' ) -> order ( 'id asc' ) -> select () -> toArray ();
2018-12-28 18:58:37 +08:00
if ( ! empty ( $temp_data ))
{
// 根据基础值id分组
2019-07-25 17:11:32 +08:00
$group = [];
2018-12-28 18:58:37 +08:00
foreach ( $temp_data as $v )
{
2019-07-25 17:11:32 +08:00
$group [ $v [ 'goods_spec_base_id' ]][] = $v ;
2018-12-28 18:58:37 +08:00
}
// 获取当前操作元素索引
$index = count ( $params [ 'spec' ]) - 1 ;
$spec_str = implode ( '' , array_column ( $params [ 'spec' ], 'value' ));
2019-07-25 17:11:32 +08:00
$spec_type = [];
foreach ( $group as $v )
2018-12-28 18:58:37 +08:00
{
$temp_str = implode ( '' , array_column ( $v , 'value' ));
if ( isset ( $v [ $index + 1 ]) && stripos ( $temp_str , $spec_str ) !== false )
{
// 判断是否还有库存
$inventory = Db :: name ( 'GoodsSpecBase' ) -> where ([ 'id' => $v [ $index + 1 ][ 'goods_spec_base_id' ]]) -> value ( 'inventory' );
if ( $inventory > 0 )
{
2019-07-25 17:11:32 +08:00
$spec_type [ $v [ $index + 1 ][ 'value' ]] = $v [ $index + 1 ][ 'value' ];
2018-12-28 18:58:37 +08:00
}
}
}
2019-07-25 17:11:32 +08:00
// 处理好的数据
// 扩展元素标记与html内容数据
// extends_element下包含多个元素 ['element'=>'', 'content'=>'']
$data = [
'spec_type' => array_values ( $spec_type ),
'extends_element' => [],
];
// 商品获取规格类型钩子
$hook_name = 'plugins_service_goods_spec_type' ;
2021-07-18 23:42:10 +08:00
$ret = EventReturnHandle ( MyEventTrigger ( $hook_name , [
2019-07-25 17:11:32 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'data' => & $data ,
'goods_id' => $goods_id
2019-12-02 20:58:24 +08:00
]));
2019-07-25 17:11:32 +08:00
if ( isset ( $ret [ 'code' ]) && $ret [ 'code' ] != 0 )
{
return $ret ;
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 , $data );
2018-12-28 18:58:37 +08:00
}
}
2023-02-08 21:20:04 +08:00
return DataReturn ( MyLang ( 'common_service.goods.base_spec_type_empty_tips' ), - 100 );
2018-12-28 18:58:37 +08:00
}
2021-10-06 01:09:30 +08:00
/**
* 商品购买数量获取商品信息
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2021 - 10 - 05
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsStock ( $params = [])
{
2023-04-01 11:34:24 +08:00
// 是否批量
if ( ! empty ( $params [ 'goods_data' ]))
2021-10-06 01:09:30 +08:00
{
2023-04-01 11:34:24 +08:00
// 是否数组
if ( ! is_array ( $params [ 'goods_data' ]))
{
$params [ 'goods_data' ] = json_decode ( htmlspecialchars_decode ( $params [ 'goods_data' ]), true );
}
if ( empty ( $params [ 'goods_data' ]))
{
return DataReturn ( MyLang ( 'params_error_tips' ), - 1 );
}
// 循环处理
$result = [];
foreach ( $params [ 'goods_data' ] as $v )
{
// 请求参数
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'id' ,
'error_msg' => MyLang ( 'goods_id_error_tips' ),
],
[
'checked_type' => 'isset' ,
'key_name' => 'stock' ,
'error_msg' => MyLang ( 'common_service.goods.base_buy_stock_error_tips' ),
],
];
$ret = ParamsChecked ( $v , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
// 获取商品基础信息
$result [] = self :: GoodsSpecDetail ( $v );
}
return DataReturn ( MyLang ( 'operate_success' ), 0 , $result );
} else {
// 请求参数
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'id' ,
'error_msg' => MyLang ( 'goods_id_error_tips' ),
],
[
'checked_type' => 'isset' ,
'key_name' => 'stock' ,
'error_msg' => MyLang ( 'common_service.goods.base_buy_stock_error_tips' ),
],
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
2021-10-06 01:09:30 +08:00
2023-04-01 11:34:24 +08:00
// 获取商品基础信息
return self :: GoodsSpecDetail ( $params );
}
2021-10-06 01:09:30 +08:00
}
2019-07-21 23:51:47 +08:00
/**
* 商品规格扩展数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ datetime 2019 - 07 - 21 T16 : 08 : 34 + 0800
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsSpecificationsExtends ( $params = [])
{
// 数据
$data = [];
// 规格扩展数据钩子
$hook_name = 'plugins_service_goods_spec_extends_handle' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2019-07-21 23:51:47 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
2020-01-14 15:27:38 +08:00
'params' => $params ,
2019-07-21 23:51:47 +08:00
'data' => & $data ,
]);
2023-02-04 16:47:48 +08:00
return DataReturn ( MyLang ( 'get_success' ), 0 , $data );
2019-07-21 23:51:47 +08:00
}
2020-07-03 19:13:18 +08:00
/**
* 商品类型校验
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 07 - 03
* @ desc description
* @ param [ int ] $goods_id [ 商品 id ]
* @ param [ int ] $site_type [ 商品类型 ]
*/
public static function IsGoodsSiteTypeConsistent ( $goods_id , $site_type = null )
{
// 是否已指定商品类型
if ( $site_type === null )
{
$site_type = Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> value ( 'site_type' );
}
2025-03-03 17:49:22 +08:00
// 是否展示型商品
if ( $site_type == 4 )
{
return DataReturn ( MyLang ( 'goods_only_show_title' ), - 1 , $site_type );
}
2020-07-03 19:13:18 +08:00
// 商品类型与当前系统的类型是否一致包含其中
if ( IsGoodsSiteTypeConsistent ( $site_type ) == 1 )
{
return DataReturn ( 'success' , 0 , $site_type );
}
// 仅可单独购买
2023-08-27 16:59:15 +08:00
$site_type_arr = MyConst ( 'common_site_type_list' );
2023-02-08 21:20:04 +08:00
$msg = array_key_exists ( $site_type , $site_type_arr ) ? MyLang ( 'only_title' ) . $site_type_arr [ $site_type ][ 'name' ] : MyLang ( 'goods_only_buy_title' );
2022-05-03 23:28:25 +08:00
return DataReturn ( $msg , - 1 , $site_type );
2020-07-03 19:13:18 +08:00
}
/**
* 商品销售默认类型
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 07 - 03
* @ desc description
* @ param [ int ] $goods_id [ 商品 id ]
* @ param [ int ] $site_type [ 商品类型 ]
*/
public static function GoodsSalesModelType ( $goods_id , $site_type = null )
{
// 是否已指定商品类型
if ( $site_type === null )
{
$site_type = Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> value ( 'site_type' );
}
// 匹配商品销售模式
return DataReturn ( 'success' , 0 , GoodsSalesModelType ( $site_type ));
}
2020-08-13 13:41:36 +08:00
2024-10-21 10:51:14 +08:00
/**
* 商品底部左侧小导航
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2021 - 02 - 19
* @ desc description
* @ param [ array ] $goods [ 商品信息 ]
*/
public static function GoodsBuyLeftNavList ( $goods )
{
// 当前用户是否已收藏
$user_is_favor = isset ( $goods [ 'user_is_favor' ]) && $goods [ 'user_is_favor' ] == 1 ;
// 导航数据
// name 名称
// icon icon图标
// type 类型
// url url跳转地址
// active 是否选中( 0否、1是)
// class 自定义class
// document 元素数据
$data = [
[
'name' => MyLang ( 'home_title' ),
'icon' => ( APPLICATION == 'web' ) ? 'iconfont icon-index' : StaticAttachmentUrl ( 'home-icon.png' ),
'type' => 'home' ,
'url' => SystemService :: DomainUrl (),
'active' => 0 ,
'class' => '' ,
'document' => '' ,
],
[
'name' => $user_is_favor ? MyLang ( 'already_favor_title' ) : MyLang ( 'favor_title' ),
'icon' => ( APPLICATION == 'web' ) ? ( 'iconfont ' . ( $user_is_favor ? 'icon-heart' : 'icon-heart-o' )) : StaticAttachmentUrl ( 'favor' . ( $user_is_favor ? '-active' : '' ) . '-icon.png' ),
'type' => 'favor' ,
'active' => $user_is_favor ? 1 : 0 ,
'class' => '' ,
'document' => '' ,
]
];
2024-12-25 17:35:54 +08:00
// 手机端是否存在客服
if ( APPLICATION == 'app' && MyC ( 'common_app_is_online_service' ) == 1 )
{
// 是否存在自定义客服
$custom = MyC ( 'common_app_customer_service_custom' , []);
if ( empty ( $custom ) || empty ( $custom [ APPLICATION_CLIENT_TYPE ]))
{
// h5,ios,android端必须存在电话
$status = in_array ( APPLICATION_CLIENT_TYPE , [ 'h5' , 'ios' , 'android' ]);
if ( $status )
{
$tel = MyC ( 'common_app_customer_service_tel' );
$status = ! empty ( $tel );
} else {
$status = true ;
}
} else {
$status = true ;
}
if ( $status )
{
$data [] = [
'name' => MyLang ( 'chat_title' ),
'icon' => StaticAttachmentUrl ( 'chat-icon.png' ),
'type' => 'chat' ,
];
}
}
2024-10-21 10:51:14 +08:00
// 商品购买导航左侧钩子
$hook_name = 'plugins_service_goods_buy_left_nav_handle' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods' => $goods ,
'data' => & $data ,
]);
return $data ;
}
2021-02-19 20:21:44 +08:00
/**
* 商品购买按钮列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2021 - 02 - 19
* @ desc description
* @ param [ array ] $goods [ 商品信息 ]
*/
public static function GoodsBuyButtonList ( $goods )
{
// 错误信息
$error = '' ;
2022-11-18 14:35:16 +08:00
// 是否已下架
2025-09-23 21:22:38 +08:00
if ( isset ( $goods [ 'is_shelves' ]) && $goods [ 'is_shelves' ] != 1 )
2021-02-19 20:21:44 +08:00
{
2023-01-19 17:44:03 +08:00
$error = MyLang ( 'goods_already_shelves_title' );
2021-02-19 20:21:44 +08:00
}
// 按钮列表
// color 颜色类型[main主, second次](默认 main)
2026-06-02 16:12:10 +08:00
// type 类型[show|tel展示, buy购买, cart加入购物车, copy复制, url|link链接跳转, other其他值]
2021-02-19 20:21:44 +08:00
// name 名称
// title 元素title说明( 可选)
// value 数据值(可选)
// icon icon类名称( 可选)
// class 自定义类名称(可选)
2025-03-03 17:49:22 +08:00
// business 业务
2021-02-19 20:21:44 +08:00
$data = [];
if ( empty ( $error ))
{
2025-09-23 21:22:38 +08:00
if ( isset ( $goods [ 'id' ]) && isset ( $goods [ 'site_type' ]))
2021-02-19 20:21:44 +08:00
{
2025-09-23 21:22:38 +08:00
// 获取商品类型
$model_type = self :: GoodsSalesModelType ( $goods [ 'id' ], $goods [ 'site_type' ]);
2022-11-21 17:50:39 +08:00
2025-09-23 21:22:38 +08:00
// 是否展示型
if ( $model_type [ 'data' ] == 4 )
{
$name = MyC ( 'common_is_exhibition_mode_btn_text' );
$data [] = [
2022-11-21 17:50:39 +08:00
'color' => 'main' ,
2025-09-23 21:22:38 +08:00
'type' => 'show' ,
'name' => empty ( $name ) ? MyLang ( 'goods_show_title' ) : $name ,
2026-03-04 10:21:47 +08:00
'value' => MyC ( 'common_customer_store_chat_tel' ),
2025-09-23 21:22:38 +08:00
'icon' => 'am-icon-phone' ,
2021-02-19 20:21:44 +08:00
];
2025-09-23 21:22:38 +08:00
$error = MyLang ( 'goods_only_show_title' );
} else {
// 还有库存
if ( isset ( $goods [ 'inventory' ]) && $goods [ 'inventory' ] <= 0 )
{
$error = MyLang ( 'goods_no_inventory_title' );
}
if ( empty ( $error ))
2022-03-27 23:37:16 +08:00
{
2025-09-23 21:22:38 +08:00
// web端class
$class_name = ( APPLICATION == 'web' ) ? 'buy-event login-event' : '' ;
// 购买
$name = ( MyC ( 'common_order_is_booking' , 0 , true ) == 1 ) ? MyLang ( 'goods_booking_title' ) : MyLang ( 'goods_buy_title' );
$buy = [
'color' => 'main' ,
'type' => 'buy' ,
2023-01-19 17:44:03 +08:00
'title' => $name ,
'name' => $name ,
2022-11-21 17:50:39 +08:00
'class' => $class_name ,
2025-09-23 21:22:38 +08:00
'icon' => '' ,
2022-11-21 17:50:39 +08:00
];
2025-09-23 21:22:38 +08:00
// 商品类型是否和当前站点类型一致
$cart = [];
$ret = self :: IsGoodsSiteTypeConsistent ( $goods [ 'id' ], $goods [ 'site_type' ]);
if ( $ret [ 'code' ] == 0 )
2022-11-21 17:50:39 +08:00
{
2025-09-23 21:22:38 +08:00
// 加入购物车
$name = MyLang ( 'goods_cart_title' );
$cart = [
'color' => 'second' ,
'type' => 'cart' ,
'title' => $name ,
'name' => $name ,
'class' => $class_name ,
'icon' => 'am-icon-opencart' ,
];
} else {
$error = $ret [ 'msg' ];
2022-11-21 17:50:39 +08:00
}
2025-09-23 21:22:38 +08:00
2025-10-26 15:57:22 +08:00
// 是否关闭下单按钮
$close_buy_button = MyC ( 'common_goods_close_buy_button' );
if ( ! empty ( $close_buy_button ) && is_array ( $close_buy_button ))
2022-11-21 17:50:39 +08:00
{
2025-10-26 15:57:22 +08:00
if ( in_array ( 'cart' , $close_buy_button ))
2025-09-23 21:22:38 +08:00
{
2025-10-26 15:57:22 +08:00
$cart = [];
2025-09-23 21:22:38 +08:00
}
2025-10-26 15:57:22 +08:00
if ( in_array ( 'buy' , $close_buy_button ))
2025-09-23 21:22:38 +08:00
{
2025-10-26 15:57:22 +08:00
$buy = [];
2025-09-23 21:22:38 +08:00
}
2022-11-21 17:50:39 +08:00
}
2025-10-26 15:57:22 +08:00
// 按钮加到数据
if ( ! empty ( $buy ))
{
$data [] = $buy ;
}
if ( ! empty ( $cart ))
{
$data [] = $cart ;
}
// 主按钮顺序处理,手机端立即购买放在最后面
if ( APPLICATION == 'app' )
{
$data = array_reverse ( $data );
}
2022-03-27 23:37:16 +08:00
}
}
2021-02-19 20:21:44 +08:00
}
}
// 商品购买导航按钮钩子
$hook_name = 'plugins_service_goods_buy_nav_button_handle' ;
2021-07-18 23:42:10 +08:00
MyEventTrigger ( $hook_name , [
2021-02-19 20:21:44 +08:00
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods' => $goods ,
'data' => & $data ,
'error' => & $error ,
]);
// 是否存在按钮数据
if ( empty ( $data ) && empty ( $error ))
{
2023-01-19 17:44:03 +08:00
$error = MyLang ( 'goods_stop_sale_title' );
2021-02-19 20:21:44 +08:00
}
// 返回数据
2021-09-30 15:23:01 +08:00
$count = 0 ;
2025-03-03 17:49:22 +08:00
$types = [];
2021-09-30 15:23:01 +08:00
if ( ! empty ( $data ) && is_array ( $data ))
{
$count = count ( $data );
$types = array_column ( $data , 'type' );
}
2021-02-19 20:21:44 +08:00
return [
2021-09-30 15:23:01 +08:00
'data' => $data ,
'count' => $count ,
'error' => $error ,
'is_buy' => in_array ( 'buy' , $types ) ? 1 : 0 ,
'is_cart' => in_array ( 'cart' , $types ) ? 1 : 0 ,
'is_show' => in_array ( 'show' , $types ) ? 1 : 0 ,
2021-02-19 20:21:44 +08:00
];
}
2026-06-02 16:12:10 +08:00
/**
* 商品购买指向链接数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2026 - 03 - 09
* @ desc description
* @ param [ array ] $goods [ 商品信息 ]
*/
public static function GoodsBuyToLinkData ( $goods )
{
$data = [
// 购买
'buy' => MyUrl ( 'index/buy/index' ),
// 加入购物车
'cart' => MyUrl ( 'index/cart/save' ),
];
// 商品购买指向link地址钩子
$hook_name = 'plugins_service_goods_buy_to_link_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods' => $goods ,
'data' => & $data ,
]);
return $data ;
}
2021-06-03 14:15:24 +08:00
/**
* 商品详情中间tabs导航列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2021 - 02 - 19
* @ desc description
* @ param [ array ] $goods [ 商品信息 ]
*/
public static function GoodsDetailMiddleTabsNavList ( $goods )
{
2023-01-14 20:29:37 +08:00
// 从缓存获取
$key = SystemService :: CacheKey ( 'shopxo.cache_goods_detail_middle_tabs_key' ) . APPLICATION ;
$data = MyCache ( $key );
2023-08-27 16:59:15 +08:00
if ( $data === null || MyEnv ( 'app_debug' ) || MyC ( 'common_data_is_use_cache' ) != 1 )
2021-09-30 00:10:09 +08:00
{
2021-10-23 16:29:54 +08:00
// 是否展示商品评价
2025-03-03 17:49:22 +08:00
$is_comments = MyC ( 'common_is_goods_detail_show_comments' , 1 );
2023-01-14 20:29:37 +08:00
// app与web端不一致
if ( APPLICATION == 'app' )
2021-10-23 16:29:54 +08:00
{
2023-01-14 20:29:37 +08:00
// 这里的 ent 值必须和系统中区域块定义的一致
$data = [
2025-03-03 17:49:22 +08:00
[
'type' => 'main' ,
'name' => MyLang ( 'goods_main_title' ),
'ent' => '.page' ,
],
2023-01-14 20:29:37 +08:00
];
2021-10-23 16:29:54 +08:00
2023-01-14 20:29:37 +08:00
// 是否展示商品评价
if ( $is_comments == 1 )
{
2025-03-03 17:49:22 +08:00
$data [] = [
'type' => 'comments' ,
'name' => MyLang ( 'comment_title' ),
'ent' => '.goods-comment' ,
];
2023-01-14 20:29:37 +08:00
}
2021-10-23 16:29:54 +08:00
2023-01-14 20:29:37 +08:00
// 商品详情介绍
2025-03-03 17:49:22 +08:00
$data [] = [
'type' => 'detail' ,
'name' => MyLang ( 'detail_title' ),
'ent' => '.goods-detail' ,
];
2023-01-14 20:29:37 +08:00
} else {
// 评论总数
$comments_count = isset ( $goods [ 'comments_count' ]) ? $goods [ 'comments_count' ] : GoodsCommentsService :: GoodsCommentsTotal ([ 'goods_id' => $goods [ 'id' ], 'is_show' => 1 ]);
// 列表
// type 类型
// name 名称
// active 选中(可选)
// value 数据值(可选)
$data = [
[
'type' => 'detail' ,
2023-01-19 17:44:03 +08:00
'name' => MyLang ( 'detail_title' ),
2023-01-14 20:29:37 +08:00
'active' => 1 ,
],
];
// 是否展示商品评价
if ( $is_comments == 1 )
{
$data [] = [
'type' => 'comments' ,
2023-01-19 17:44:03 +08:00
'name' => MyLang ( 'comment_title' ) . '(' . $comments_count . ')' ,
2023-01-14 20:29:37 +08:00
];
}
// 猜你喜欢,目前以销量最高推荐
2025-03-03 17:49:22 +08:00
if ( MyC ( 'common_is_goods_detail_show_guess_you_like' , 0 ) == 1 )
{
$data [] = [
'type' => 'guess_you_like' ,
'name' => MyLang ( 'goods_guess_you_like_title' ),
];
}
2021-10-23 16:29:54 +08:00
}
2023-01-14 20:29:37 +08:00
// 商品详情中间导航钩子
$hook_name = 'plugins_service_goods_detail_middle_tabs_nav_handle' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods' => $goods ,
'data' => & $data ,
]);
2021-06-03 14:15:24 +08:00
2025-03-03 17:49:22 +08:00
// 格式集合
$data = [
'nav' => $data ,
'type' => array_column ( $data , 'type' ),
];
2021-06-03 14:15:24 +08:00
2023-01-14 20:29:37 +08:00
// 存储缓存
MyCache ( $key , $data , 180 );
2021-09-30 00:10:09 +08:00
}
2023-01-14 20:29:37 +08:00
return $data ;
2021-06-03 14:15:24 +08:00
}
2020-08-13 13:41:36 +08:00
/**
* 商品二维码生成
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
2026-03-04 10:21:47 +08:00
* @ date 2024 - 09 - 05
2020-08-13 13:41:36 +08:00
* @ desc description
2026-03-04 10:21:47 +08:00
* @ param [ array ] $goods [ 商品数据 ]
* @ param [ array ] $user [ 用户数据 ]
2020-08-13 13:41:36 +08:00
*/
2026-03-04 10:21:47 +08:00
public static function GoodsQrcode ( $goods = [], $user = [])
2020-08-13 13:41:36 +08:00
{
2026-03-04 10:21:47 +08:00
// 数据
if ( empty ( $goods ))
2020-08-13 13:41:36 +08:00
{
2026-03-04 10:21:47 +08:00
return DataReturn ( MyLang ( 'no_data' ), - 1 );
2020-08-13 13:41:36 +08:00
}
2026-03-04 10:21:47 +08:00
// pc地址
$url_params = [ 'id' => $goods [ 'id' ]];
if ( ! empty ( $user ))
{
$url_params [ 'referrer' ] = $user [ 'id' ];
}
$web_url = MyUrl ( 'index/goods/index' , $url_params );
2021-01-05 14:48:01 +08:00
2026-03-04 10:21:47 +08:00
// h5地址
$h5_url = MyC ( 'common_app_h5_url' );
2020-08-13 13:41:36 +08:00
2026-03-04 10:21:47 +08:00
// 生成各平台二维码
$qrcode = [];
$platform = MyConst ( 'common_platform_type' );
if ( ! empty ( $platform ) && is_array ( $platform ))
{
// 自定义路径和名称
$time_dir = date ( 'Y/m/d' , is_numeric ( $goods [ 'add_time' ]) ? $goods [ 'add_time' ] : strtotime ( $goods [ 'add_time' ])) . ( empty ( $user ) ? '' : '/' . $user [ 'id' ]);
$filename = $goods [ 'id' ] . '.png' ;
// 地址信息
$page = 'pages/goods-detail/goods-detail' ;
$query = 'id=' . $goods [ 'id' ];
if ( ! empty ( $user ))
{
$query .= '&referrer=' . $user [ 'id' ];
}
// h5地址拼接
if ( ! empty ( $h5_url ))
{
$h5_url .= $page . '?' . $query ;
}
foreach ( $platform as $v )
{
// 存储信息
$path = 'download' . DS . 'goods_qrcode' . DS . APPLICATION_CLIENT_TYPE . DS . $v [ 'value' ] . DS . $time_dir . DS ;
// 二维码处理参数
$dir_params = [
'path' => DS . $path ,
'filename' => $filename ,
'dir' => ROOT . 'public' . DS . $path . $filename ,
];
$status = false ;
if ( ! file_exists ( $dir_params [ 'dir' ]))
{
// 根据平台处理
switch ( $v [ 'value' ])
{
// pc
case 'pc' :
$ret = ( new \base\Qrcode ()) -> Create ( array_merge ( $dir_params , [ 'content' => $web_url ]));
if ( $ret [ 'code' ] == 0 )
{
$status = true ;
}
break ;
// h5
case 'h5' :
if ( ! empty ( $h5_url ))
{
$ret = ( new \base\Qrcode ()) -> Create ( array_merge ( $dir_params , [ 'content' => $h5_url ]));
if ( $ret [ 'code' ] == 0 )
{
$status = true ;
}
}
break ;
// 微信
case 'weixin' :
$appid = AppMiniUserService :: AppMiniConfig ( 'common_app_mini_weixin_appid' );
$appsecret = AppMiniUserService :: AppMiniConfig ( 'common_app_mini_weixin_appsecret' );
if ( ! empty ( $appid ) && ! empty ( $appsecret ))
{
$request_params = [
'page' => $page ,
'scene' => $query ,
'width' => 300 ,
];
$ret = ( new \base\Wechat ( $appid , $appsecret )) -> MiniQrCodeCreate ( $request_params );
if ( $ret [ 'code' ] == 0 )
{
if ( \base\FileUtil :: CreateDir ( ROOT . 'public' . DS . $path ))
{
if ( @ file_put_contents ( $dir_params [ 'dir' ], $ret [ 'data' ]) !== false )
{
$status = true ;
}
}
}
}
break ;
// 支付宝小程序
case 'alipay' :
$appid = AppMiniUserService :: AppMiniConfig ( 'common_app_mini_alipay_appid' );
if ( ! empty ( $appid ))
{
$request_params = [
'appid' => $appid ,
'page' => $page ,
'scene' => $query ,
'width' => 300 ,
];
$ret = ( new \base\Alipay ()) -> MiniQrCodeCreate ( $request_params );
if ( $ret [ 'code' ] == 0 )
{
if ( \base\FileUtil :: CreateDir ( ROOT . 'public' . DS . $path ))
{
if ( @ file_put_contents ( $dir_params [ 'dir' ], RequestGet ( $ret [ 'data' ])) !== false )
{
$status = true ;
}
}
}
}
break ;
// 头条小程序
case 'toutiao' :
$config = [
'appid' => AppMiniUserService :: AppMiniConfig ( 'common_app_mini_toutiao_appid' ),
'secret' => AppMiniUserService :: AppMiniConfig ( 'common_app_mini_toutiao_appsecret' ),
];
if ( ! empty ( $config [ 'appid' ]) && ! empty ( $config [ 'secret' ]))
{
$request_params = [
'page' => $page ,
'scene' => $query ,
'width' => 300 ,
];
$ret = ( new \base\Toutiao ( $config )) -> MiniQrCodeCreate ( $request_params );
if ( $ret [ 'code' ] == 0 )
{
if ( \base\FileUtil :: CreateDir ( ROOT . 'public' . DS . $path ))
{
if ( @ file_put_contents ( $dir_params [ 'dir' ], $ret [ 'data' ]) !== false )
{
$status = true ;
}
}
}
}
break ;
2020-08-13 13:41:36 +08:00
2026-03-04 10:21:47 +08:00
// 百度小程序
case 'baidu' :
$config = [
'appid' => AppMiniUserService :: AppMiniConfig ( 'common_app_mini_baidu_appid' ),
'key' => AppMiniUserService :: AppMiniConfig ( 'common_app_mini_baidu_appkey' ),
'secret' => AppMiniUserService :: AppMiniConfig ( 'common_app_mini_baidu_appsecret' ),
];
if ( ! empty ( $config [ 'appid' ]) && ! empty ( $config [ 'key' ]) && ! empty ( $config [ 'secret' ]))
{
$request_params = [
'page' => $page ,
'scene' => $query ,
'width' => 300 ,
];
$ret = ( new \base\Baidu ( $config )) -> MiniQrCodeCreate ( $request_params );
if ( $ret [ 'code' ] == 0 )
{
if ( \base\FileUtil :: CreateDir ( ROOT . 'public' . DS . $path ))
{
if ( @ file_put_contents ( $dir_params [ 'dir' ], $ret [ 'data' ]) !== false )
{
$status = true ;
}
}
}
}
break ;
// 快手小程序
case 'kuaishou' :
$appid = AppMiniUserService :: AppMiniConfig ( 'common_app_mini_kuaishou_appid' );
if ( ! empty ( $appid ))
{
$url = 'kwai://miniapp?appId=' . $appid . '&KSMP_source=011012&KSMP_internal_source=011012&path=' . urlencode ( $page . '?' . $query );
$ret = ( new \base\Qrcode ()) -> Create ( array_merge ( $dir_params , [ 'content' => $url ]));
if ( $ret [ 'code' ] == 0 )
{
$status = true ;
}
}
break ;
}
} else {
$status = true ;
}
if ( $status )
{
if (( $v [ 'value' ] == 'h5' && ! empty ( $h5_url )) || $v [ 'value' ] != 'h5' )
{
$qrcode [] = [
'name' => $v [ 'name' ],
'type' => $v [ 'value' ],
'url' => ( $v [ 'value' ] == 'h5' ) ? $h5_url : (( $v [ 'value' ] == 'pc' ) ? $web_url : '' ),
'qrcode' => ResourcesService :: AttachmentPathViewHandle ( $dir_params [ 'path' ] . $dir_params [ 'filename' ]),
];
}
}
}
}
return DataReturn ( 'success' , 0 , [
'qrcode' => $qrcode ,
'h5_url' => $h5_url ,
'web_url' => $web_url ,
]);
2020-08-13 13:41:36 +08:00
}
2022-02-12 18:03:29 +08:00
/**
* 商品url生成
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2022 - 02 - 12
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
*/
public static function GoodsUrlCreate ( $goods_id )
{
return ( APPLICATION_CLIENT_TYPE == 'pc' ) ? MyUrl ( 'index/goods/index' , [ 'id' => $goods_id ]) : '/pages/goods-detail/goods-detail?id=' . $goods_id ;
}
2022-04-18 00:54:11 +08:00
/**
* 获取商品列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2018 - 09 - 07
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsSearchList ( $params = [])
{
2022-05-27 18:35:07 +08:00
// 分页
$page = max ( 1 , isset ( $params [ 'page' ]) ? intval ( $params [ 'page' ]) : 1 );
$page_size = empty ( $params [ 'page_size' ]) ? 20 : min ( intval ( $params [ 'page_size' ]), 100 );
$page_start = intval (( $page - 1 ) * $page_size );
2022-04-18 00:54:11 +08:00
// 返回格式
$result = [
2022-05-27 18:35:07 +08:00
'page' => $page ,
'page_start' => $page_start ,
'page_size' => $page_size ,
2022-04-18 00:54:11 +08:00
'page_total' => 0 ,
'total' => 0 ,
'data' => [],
];
// 搜索条件
$where_base = empty ( $params [ 'where_base' ]) ? [] : $params [ 'where_base' ];
$where_keywords = empty ( $params [ 'where_keywords' ]) ? [] : $params [ 'where_keywords' ];
// 排序
$order_by = empty ( $params [ 'order_by' ]) ? 'access_count desc, sales_count desc, id desc' : $params [ 'order_by' ];
2022-05-27 18:35:07 +08:00
// 指定字段
2022-04-18 00:54:11 +08:00
$field = empty ( $params [ 'field' ]) ? '*' : $params [ 'field' ];
// 商品搜索列表读取前钩子
$hook_name = 'plugins_service_goods_search_list_begin' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'params' => $params ,
'where_base' => & $where_base ,
'where_keywords' => & $where_keywords ,
'field' => & $field ,
'order_by' => & $order_by ,
2022-05-27 18:35:07 +08:00
'page' => & $result [ 'page' ],
2022-04-18 00:54:11 +08:00
]);
// 获取商品总数
$result [ 'total' ] = ( int ) Db :: name ( 'Goods' ) -> where ( $where_base ) -> where ( function ( $query ) use ( $where_keywords ) {
$query -> whereOr ( $where_keywords );
}) -> count ();
// 获取商品列表
if ( $result [ 'total' ] > 0 )
{
// 查询数据
2024-12-25 17:35:54 +08:00
$goods = self :: GoodsDataHandle ( Db :: name ( 'Goods' ) -> field ( $field ) -> where ( $where_base ) -> where ( function ( $query ) use ( $where_keywords ) {
2022-04-18 00:54:11 +08:00
$query -> whereOr ( $where_keywords );
2024-12-25 17:35:54 +08:00
}) -> order ( $order_by ) -> limit ( $result [ 'page_start' ], $result [ 'page_size' ]) -> select () -> toArray (), $params );
2022-04-18 00:54:11 +08:00
// 返回数据
$result [ 'data' ] = $goods [ 'data' ];
2022-05-27 18:35:07 +08:00
$result [ 'page_total' ] = ceil ( $result [ 'total' ] / $result [ 'page_size' ]);
2022-04-18 00:54:11 +08:00
}
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'handle_success' ), 0 , $result );
2022-04-18 00:54:11 +08:00
}
2022-07-06 22:28:40 +08:00
2022-08-26 13:45:23 +08:00
/**
* 商品基础模板
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2022 - 08 - 26
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsBaseTemplate ( $params = [])
{
// 请求类型
$p = [
[
'checked_type' => 'empty' ,
'key_name' => 'category_ids' ,
2023-02-08 21:20:04 +08:00
'error_msg' => MyLang ( 'form_goods_category_message' ),
2022-08-26 13:45:23 +08:00
],
];
$ret = ParamsChecked ( $params , $p );
if ( $ret !== true )
{
return DataReturn ( $ret , - 1 );
}
2026-03-04 10:21:47 +08:00
if ( ! is_array ( $params [ 'category_ids' ]))
{
$params [ 'category_ids' ] = explode ( ',' , $params [ 'category_ids' ]);
}
2022-08-26 13:45:23 +08:00
// 规格模板
$spec = GoodsSpecService :: GoodsCategorySpecTemplateList ( $params );
// 参数模板
$parameter = GoodsParamsService :: GoodsCategoryParamsTemplateList ( $params );
2026-03-04 10:21:47 +08:00
// 商品基础字段必填配置数据
$required_fields = self :: GoodsBaseFieldsRequiredConfigData ( $params [ 'category_ids' ]);
2023-01-19 17:44:03 +08:00
return DataReturn ( MyLang ( 'operate_success' ), 0 , [
2026-03-04 10:21:47 +08:00
'spec' => $spec [ 'data' ],
'params' => $parameter [ 'data' ],
'required_fields' => empty ( $required_fields ) ? null : $required_fields ,
2022-08-26 13:45:23 +08:00
]);
}
2024-01-19 14:49:32 +08:00
2026-03-04 10:21:47 +08:00
/**
* 商品基础字段必填配置数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 11 - 06
* @ desc description
* @ param [ array ] $category_ids [ 商品分类id ]
*/
public static function GoodsBaseFieldsRequiredConfigData ( $category_ids )
{
if ( ! is_array ( $category_ids ))
{
$category_ids = explode ( ',' , $category_ids );
}
$required_fields = [];
$goods_base_fields_required = MyC ( 'common_goods_base_fields_required_data' );
if ( ! empty ( $goods_base_fields_required ) && is_array ( $goods_base_fields_required ))
{
foreach ( $goods_base_fields_required as $k => $v )
{
$ids = GoodsCategoryService :: GoodsCategoryItemsIds ( $v );
$temp = array_diff ( $ids , $category_ids );
$required_fields [ $k ] = ( count ( $temp ) < count ( $ids )) ? 1 : 0 ;
}
}
return $required_fields ;
}
2024-01-19 14:49:32 +08:00
/**
* 商品详情页面猜你喜欢的相关商品
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 12 - 29
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
2025-09-23 21:22:38 +08:00
* @ param [ array ] $params [ 输入参数 ]
2024-01-19 14:49:32 +08:00
*/
2025-09-23 21:22:38 +08:00
public static function GoodsDetailGuessYouLikeData ( $goods_id , $params = [])
2024-01-19 14:49:32 +08:00
{
$goods_list = [];
2025-03-03 17:49:22 +08:00
if ( ! empty ( $goods_id ) && MyC ( 'common_is_goods_detail_show_guess_you_like' , 0 ) == 1 )
2024-01-19 14:49:32 +08:00
{
$category_ids = Db :: name ( 'GoodsCategoryJoin' ) -> where ([ 'goods_id' => $goods_id ]) -> column ( 'category_id' );
if ( ! empty ( $category_ids ))
{
$category_ids = GoodsCategoryService :: GoodsCategoryParentIds ( GoodsCategoryService :: GoodsCategoryItemsIds ( $category_ids ));
2025-09-23 21:22:38 +08:00
$data_params = [
2024-01-19 14:49:32 +08:00
'where' => [
[ 'g.is_shelves' , '=' , 1 ],
[ 'g.is_delete_time' , '=' , 0 ],
[ 'gci.category_id' , 'in' , $category_ids ],
[ 'g.id' , 'not in' , $goods_id ],
],
2024-10-21 10:51:14 +08:00
'order_by' => 'g.sales_count desc' ,
2024-01-19 14:49:32 +08:00
'n' => 16 ,
2025-09-23 21:22:38 +08:00
'is_spec' => ( ! isset ( $params [ 'is_spec' ]) || $params [ 'is_spec' ] == 1 ) ? 1 : 0 ,
'is_cart' => ( ! isset ( $params [ 'is_cart' ]) || $params [ 'is_cart' ] == 1 ) ? 1 : 0 ,
2024-01-19 14:49:32 +08:00
];
2025-09-23 21:22:38 +08:00
$ret = self :: CategoryGoodsList ( $data_params );
2024-01-19 14:49:32 +08:00
$goods_list = empty ( $ret [ 'data' ]) ? [] : $ret [ 'data' ];
}
}
return $goods_list ;
}
/**
* 商品详情页面看了又看的相关商品
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2023 - 12 - 29
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
2025-09-23 21:22:38 +08:00
* @ param [ array ] $params [ 输入参数 ]
2024-01-19 14:49:32 +08:00
*/
2025-09-23 21:22:38 +08:00
public static function GoodsDetailSeeingYouData ( $goods_id , $params = [])
2024-01-19 14:49:32 +08:00
{
2025-03-03 17:49:22 +08:00
$goods_list = [];
if ( ! empty ( $goods_id ) && MyC ( 'common_is_goods_detail_show_seeing_you' , 0 ) == 1 )
{
2025-09-23 21:22:38 +08:00
$data_params = [
2025-03-03 17:49:22 +08:00
'where' => [
[ 'is_shelves' , '=' , 1 ],
[ 'is_delete_time' , '=' , 0 ],
[ 'id' , 'not in' , $goods_id ],
],
'order_by' => 'access_count desc' ,
'n' => 10 ,
2025-09-23 21:22:38 +08:00
'is_spec' => ( ! isset ( $params [ 'is_spec' ]) || $params [ 'is_spec' ] == 1 ) ? 1 : 0 ,
'is_cart' => ( ! isset ( $params [ 'is_cart' ]) || $params [ 'is_cart' ] == 1 ) ? 1 : 0 ,
2025-03-03 17:49:22 +08:00
];
2025-09-23 21:22:38 +08:00
$ret = self :: GoodsList ( $data_params );
2025-03-03 17:49:22 +08:00
if ( ! empty ( $ret [ 'data' ]))
{
$goods_list = $ret [ 'data' ];
}
}
return $goods_list ;
2024-01-19 14:49:32 +08:00
}
2024-10-21 10:51:14 +08:00
/**
* 指定读取商品列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 09 - 29
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2025-03-03 17:49:22 +08:00
public static function AppointGoodsList ( $params = [])
2024-10-21 10:51:14 +08:00
{
$result = [];
2025-03-03 17:49:22 +08:00
if ( ! empty ( $params [ 'goods_ids' ]))
2024-10-21 10:51:14 +08:00
{
// 非数组则转为数组
2025-03-03 17:49:22 +08:00
if ( ! is_array ( $params [ 'goods_ids' ]))
2024-10-21 10:51:14 +08:00
{
2025-03-03 17:49:22 +08:00
$params [ 'goods_ids' ] = explode ( ',' , $params [ 'goods_ids' ]);
2024-10-21 10:51:14 +08:00
}
// 基础条件
2025-09-23 21:22:38 +08:00
$params [ 'where' ] = [
2024-10-21 10:51:14 +08:00
[ 'is_delete_time' , '=' , 0 ],
[ 'is_shelves' , '=' , 1 ],
2025-03-03 17:49:22 +08:00
[ 'id' , 'in' , array_unique ( $params [ 'goods_ids' ])]
2024-10-21 10:51:14 +08:00
];
// 获取数据
2025-09-23 21:22:38 +08:00
$params [ 'is_spec' ] = isset ( $params [ 'is_spec' ]) ? $params [ 'is_spec' ] : 0 ;
$params [ 'is_cart' ] = isset ( $params [ 'is_cart' ]) ? $params [ 'is_cart' ] : 0 ;
$params [ 'is_favor' ] = isset ( $params [ 'is_favor' ]) ? $params [ 'is_favor' ] : 0 ;
$params [ 'm' ] = 0 ;
$params [ 'n' ] = 0 ;
$params [ 'field' ] = '*' ;
$params [ 'is_appoint_goods_list' ] = 1 ;
$ret = self :: GoodsList ( $params );
2024-10-21 10:51:14 +08:00
if ( ! empty ( $ret [ 'data' ]))
{
$temp = array_column ( $ret [ 'data' ], null , 'id' );
2025-03-03 17:49:22 +08:00
foreach ( $params [ 'goods_ids' ] as $id )
2024-10-21 10:51:14 +08:00
{
if ( ! empty ( $id ) && array_key_exists ( $id , $temp ))
{
$result [] = $temp [ $id ];
}
}
}
}
return $result ;
}
/**
* 自动读取商品列表
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2020 - 09 - 29
* @ desc description
* @ param [ array ] $params [ 输入参数 ]
*/
2025-03-03 17:49:22 +08:00
public static function AutoGoodsList ( $params = [])
2024-10-21 10:51:14 +08:00
{
// 基础条件
2025-09-23 21:22:38 +08:00
$params [ 'where' ] = [
2024-10-21 10:51:14 +08:00
[ 'g.is_delete_time' , '=' , 0 ],
[ 'g.is_shelves' , '=' , 1 ],
];
// 商品关键字
2025-03-03 17:49:22 +08:00
if ( ! empty ( $params [ 'goods_keywords' ]))
2024-10-21 10:51:14 +08:00
{
2025-09-23 21:22:38 +08:00
$params [ 'where' ][] = [ 'g.title|g.simple_desc' , 'like' , '%' . $params [ 'goods_keywords' ] . '%' ];
2024-10-21 10:51:14 +08:00
}
// 分类条件
2025-03-03 17:49:22 +08:00
if ( ! empty ( $params [ 'goods_category_ids' ]))
2024-10-21 10:51:14 +08:00
{
2025-03-03 17:49:22 +08:00
if ( ! is_array ( $params [ 'goods_category_ids' ]))
2024-10-21 10:51:14 +08:00
{
2025-03-03 17:49:22 +08:00
$params [ 'goods_category_ids' ] = explode ( ',' , $params [ 'goods_category_ids' ]);
2024-10-21 10:51:14 +08:00
}
2025-09-23 21:22:38 +08:00
$params [ 'where' ][] = [ 'gci.category_id' , 'in' , GoodsCategoryService :: GoodsCategoryItemsIds ( $params [ 'goods_category_ids' ], 1 )];
2024-10-21 10:51:14 +08:00
}
// 品牌条件
2025-03-03 17:49:22 +08:00
if ( ! empty ( $params [ 'goods_brand_ids' ]))
2024-10-21 10:51:14 +08:00
{
2025-03-03 17:49:22 +08:00
if ( ! is_array ( $params [ 'goods_brand_ids' ]))
2024-10-21 10:51:14 +08:00
{
2025-03-03 17:49:22 +08:00
$params [ 'goods_brand_ids' ] = explode ( ',' , $params [ 'goods_brand_ids' ]);
2024-10-21 10:51:14 +08:00
}
2025-09-23 21:22:38 +08:00
$params [ 'where' ][] = [ 'g.brand_id' , 'in' , $params [ 'goods_brand_ids' ]];
2024-10-21 10:51:14 +08:00
}
// 排序
$order_by_type_list = MyConst ( 'common_goods_order_by_type_list' );
$order_by_rule_list = MyConst ( 'common_data_order_by_rule_list' );
// 排序类型
2025-03-03 17:49:22 +08:00
$order_by_type = ! isset ( $params [ 'goods_order_by_type' ]) || ! array_key_exists ( $params [ 'goods_order_by_type' ], $order_by_type_list ) ? $order_by_type_list [ 0 ][ 'value' ] : $order_by_type_list [ $params [ 'goods_order_by_type' ]][ 'value' ];
2024-10-21 10:51:14 +08:00
// 排序值
2025-03-03 17:49:22 +08:00
$order_by_rule = ! isset ( $params [ 'goods_order_by_rule' ]) || ! array_key_exists ( $params [ 'goods_order_by_rule' ], $order_by_rule_list ) ? $order_by_rule_list [ 0 ][ 'value' ] : $order_by_rule_list [ $params [ 'goods_order_by_rule' ]][ 'value' ];
2024-10-21 10:51:14 +08:00
// 拼接排序
2025-09-23 21:22:38 +08:00
$params [ 'order_by' ] = $order_by_type . ' ' . $order_by_rule ;
$params [ 'm' ] = 0 ;
$params [ 'n' ] = empty ( $params [ 'goods_number' ]) ? 10 : intval ( $params [ 'goods_number' ]);
$params [ 'field' ] = 'g.*' ;
2024-10-21 10:51:14 +08:00
// 获取数据
2025-09-23 21:22:38 +08:00
$params [ 'is_spec' ] = isset ( $params [ 'is_spec' ]) ? $params [ 'is_spec' ] : 0 ;
$params [ 'is_cart' ] = isset ( $params [ 'is_cart' ]) ? $params [ 'is_cart' ] : 0 ;
$params [ 'is_favor' ] = isset ( $params [ 'is_favor' ]) ? $params [ 'is_favor' ] : 0 ;
$params [ 'is_auto_goods_list' ] = 1 ;
$ret = self :: CategoryGoodsList ( $params );
2024-10-21 10:51:14 +08:00
return empty ( $ret [ 'data' ]) ? [] : $ret [ 'data' ];
}
2025-09-23 21:22:38 +08:00
/**
* 商品基础禁止操作数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 07 - 02
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ array ] $goods [ 商品数据 ]
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsBaseForbidOperateData ( $goods_id = 0 , $goods = [], $params = [])
{
// 禁止的数据字段
$data = [
// 比如把标题和简述加入禁止修改
2026-03-04 10:21:47 +08:00
// title
// simple_desc
// spec_desc
// approval_number
// approval_number_expire
// batch_number
// batch_number_expire
// coding
// brand_id
// produce_company
// site_type
// images
// inventory_unit
// produce_region
// model
// category_ids
// sort_level
// give_integral
// photo
// video
2025-09-23 21:22:38 +08:00
];
// 商品参数操作数据钩子
$hook_name = 'plugins_service_goods_base_forbid_operate_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods_id' => $goods_id ,
'goods' => $goods ,
'params' => $params ,
'data' => & $data ,
]);
return $data ;
}
/**
* 商品参数操作数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 07 - 02
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ array ] $goods [ 商品数据 ]
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsParamsOperateData ( $goods_id = 0 , $goods = [], $params = [])
{
// 操作数据
$data = [
// 创建
'is_created' => 1 ,
// 添加
'is_add' => 1 ,
// 编辑
'is_edit' => 1 ,
// 复制
'is_copy' => 1 ,
// 移除
'is_remove' => 1 ,
// 提示信息
'msg' => '' ,
];
// 商品参数操作数据钩子
$hook_name = 'plugins_service_goods_params_operate_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods_id' => $goods_id ,
'goods' => $goods ,
'params' => $params ,
'data' => & $data ,
]);
return $data ;
}
/**
* 商品规格操作数据
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 07 - 02
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ array ] $goods [ 商品数据 ]
* @ param [ array ] $params [ 输入参数 ]
*/
public static function GoodsSpecOperateData ( $goods_id = 0 , $goods = [], $params = [])
{
// 操作数据
$data = [
// 创建
'is_created' => 1 ,
// 添加
'is_add' => 1 ,
// 编辑
'is_edit' => 1 ,
// 复制
'is_copy' => 1 ,
// 移除
'is_remove' => 1 ,
// 提示信息
'msg' => '' ,
];
// 商品规格操作数据钩子
$hook_name = 'plugins_service_goods_spec_operate_data' ;
MyEventTrigger ( $hook_name , [
'hook_name' => $hook_name ,
'is_backend' => true ,
'goods_id' => $goods_id ,
'goods' => $goods ,
'params' => $params ,
'data' => & $data ,
]);
return $data ;
}
/**
* 商品数据编辑状态
* @ author Devil
* @ blog http :// gong . gg /
* @ version 1.0 . 0
* @ date 2025 - 09 - 16
* @ desc description
* @ param [ int ] $goods_id [ 商品id ]
* @ param [ int ] $data [ 商品编辑的数据 ]
*/
public static function GoodsDataEditStatusCheck ( $goods_id , $data )
{
$result = [
// 基础
'is_base' => 0 ,
// 相册
'is_photo' => 0 ,
// 手机详情
'is_content_app' => 0 ,
// 参数
'is_parameter' => 0 ,
// 规格
'is_spec' => 0 ,
];
if ( ! empty ( $goods_id ))
{
// 基础
if ( empty ( $data [ 'data' ]))
{
$data [ 'data' ] = [];
}
$goods = Db :: name ( 'Goods' ) -> where ([ 'id' => $goods_id ]) -> find ();
$temp_data = [];
foreach ( $data [ 'data' ] as $k => $v )
{
if ( array_key_exists ( $k , $goods ))
{
$temp_data [ $k ] = $goods [ $k ];
}
}
$diff1 = array_diff ( $data [ 'data' ], $temp_data );
$diff2 = array_diff ( $temp_data , $data [ 'data' ]);
$result [ 'is_base' ] = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 相册
$temp_photo = empty ( $data [ 'photo' ]) ? [] : $data [ 'photo' ];
$photo = Db :: name ( 'GoodsPhoto' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'id asc' ) -> column ( 'images' );
$diff1 = array_diff ( $temp_photo , $photo );
$diff2 = array_diff ( $photo , $temp_photo );
$result [ 'is_photo' ] = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 手机详情
$temp_content_app = empty ( $data [ 'content_app' ]) ? [] : array_map ( function ( $item )
{
2026-03-04 10:21:47 +08:00
return implode ( ';' , array_filter ( $item ));
2025-09-23 21:22:38 +08:00
}, array_values ( $data [ 'content_app' ]));
$content_app = Db :: name ( 'GoodsContentApp' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'sort asc, id asc' ) -> field ( 'images,content as text' ) -> select () -> toArray ();
if ( ! empty ( $content_app ))
{
$content_app = array_map ( function ( $item )
{
2026-03-04 10:21:47 +08:00
return implode ( ';' , array_filter ( $item ));
2025-09-23 21:22:38 +08:00
}, array_values ( $content_app ));
}
$diff1 = array_diff ( $temp_content_app , $content_app );
$diff2 = array_diff ( $content_app , $temp_content_app );
$result [ 'is_content_app' ] = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 商品参数
$temp_parameter = empty ( $data [ 'parameter' ]) ? [] : array_map ( function ( $item )
{
2026-06-02 16:12:10 +08:00
unset ( $item [ 'md5_key' ]);
2025-09-23 21:22:38 +08:00
return implode ( ';' , $item );
}, array_values ( $data [ 'parameter' ]));
2026-03-04 10:21:47 +08:00
$parameter = Db :: name ( 'GoodsParams' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'id asc' ) -> field ( 'scope,data_type,name,value' ) -> select () -> toArray ();
2025-09-23 21:22:38 +08:00
if ( ! empty ( $parameter ))
{
$parameter = array_map ( function ( $item )
{
return implode ( ';' , $item );
}, array_values ( $parameter ));
}
$diff1 = array_diff ( $temp_parameter , $parameter );
$diff2 = array_diff ( $parameter , $temp_parameter );
$result [ 'is_parameter' ] = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 商品规格
// 类型标题
$temp_spec_title = [];
if ( ! empty ( $data [ 'spec' ][ 'title' ]))
{
foreach ( $data [ 'spec' ][ 'title' ] as $k => $v )
{
$spec = [];
foreach ( $v [ 'value' ] as $vs )
{
$spec [] = [
'name' => $vs ,
'images' => isset ( $data [ 'spec' ][ 'images' ][ $vs ]) ? ResourcesService :: AttachmentPathHandle ( $data [ 'spec' ][ 'images' ][ $vs ]) : '' ,
];
}
$v [ 'value' ] = json_encode ( $spec , JSON_UNESCAPED_UNICODE );
$temp_spec_title [] = $v ;
}
if ( ! empty ( $temp_spec_title ))
{
$temp_spec_title = array_map ( function ( $item )
{
return implode ( ';' , $item );
}, $temp_spec_title );
}
}
$spec_title = Db :: name ( 'GoodsSpecType' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'id asc' ) -> field ( 'name,value' ) -> select () -> toArray ();
if ( ! empty ( $spec_title ))
{
$spec_title = array_map ( function ( $item )
{
return implode ( ';' , $item );
}, $spec_title );
}
$diff1 = array_diff ( $temp_spec_title , $spec_title );
$diff2 = array_diff ( $spec_title , $temp_spec_title );
$is_spec_title = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 基础/规格值
$temp_spec_value = [];
$temp_spec_base = [];
// 处理规格数据
if ( ! empty ( $data [ 'spec' ]) && ! empty ( $data [ 'spec' ][ 'data' ]))
{
// 规格基础字段默认数据
$spec_field_defult_value = [ 'price' => '0.00' , 'original_price' => '0.00' , 'weight' => '0.00' , 'volume' => '0.00' , 'buy_min_number' => 0 , 'buy_max_number' => 0 ];
// 基础字段
$count = count ( $data [ 'spec' ][ 'data' ][ 0 ]);
$temp_key = self :: GoodsSpecBaseFields ();
$key_count = count ( $temp_key );
// 等于key总数则只有一列基础规格
if ( $count == $key_count )
{
$temp_spec_base_item = [];
for ( $i = 0 ; $i < $count ; $i ++ )
{
if ( in_array ( $temp_key [ $i ], [ 'price' , 'original_price' , 'weight' , 'volume' ]))
{
$temp_spec_base_item [ $temp_key [ $i ]] = PriceNumberFormat ( $data [ 'spec' ][ 'data' ][ 0 ][ $i ]);
} else if ( in_array ( $temp_key [ $i ], [ 'buy_min_number' , 'buy_max_number' ]))
{
$temp_spec_base_item [ $temp_key [ $i ]] = intval ( $data [ 'spec' ][ 'data' ][ 0 ][ $i ]);
} else {
$temp_spec_base_item [ $temp_key [ $i ]] = $data [ 'spec' ][ 'data' ][ 0 ][ $i ];
}
}
$temp_spec_base [] = $temp_spec_base_item ;
// 多规格
} else {
$base_start = $count - $key_count ;
foreach ( $data [ 'spec' ][ 'data' ] as $v )
{
$temp_spec_base_item = [];
for ( $i = 0 ; $i < $count ; $i ++ )
{
if ( $i < $base_start )
{
$temp_spec_value [] = $v [ $i ];
} else {
if ( in_array ( $temp_key [ $i - $base_start ], [ 'price' , 'original_price' , 'weight' , 'volume' ]))
{
$temp_spec_base_item [ $temp_key [ $i - $base_start ]] = PriceNumberFormat ( $v [ $i ]);
} else if ( in_array ( $temp_key [ $i - $base_start ], [ 'buy_min_number' , 'buy_max_number' ]))
{
$temp_spec_base_item [ $temp_key [ $i - $base_start ]] = intval ( $v [ $i ]);
} else {
$temp_spec_base_item [ $temp_key [ $i - $base_start ]] = $v [ $i ];
}
}
}
$temp_spec_base [] = $temp_spec_base_item ;
}
}
if ( ! empty ( $temp_spec_base ))
{
$temp_spec_base = array_map ( function ( $item )
{
return implode ( ';' , $item );
}, array_values ( $temp_spec_base ));
}
}
// 查询规格数据
$spec_base = Db :: name ( 'GoodsSpecBase' ) -> where ([ 'goods_id' => $goods_id ]) -> field ( $temp_key ) -> order ( 'id asc' ) -> select () -> toArray ();
if ( ! empty ( $spec_base ))
{
$spec_base = array_map ( function ( $item )
{
return implode ( ';' , $item );
}, array_values ( $spec_base ));
}
$spec_value = Db :: name ( 'GoodsSpecValue' ) -> where ([ 'goods_id' => $goods_id ]) -> order ( 'id asc' ) -> column ( 'value' );
// 规格基础
$diff1 = array_diff ( $temp_spec_base , $spec_base );
$diff2 = array_diff ( $spec_base , $temp_spec_base );
$is_spec_base = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 规格值
$diff1 = array_diff ( $temp_spec_value , $spec_value );
$diff2 = array_diff ( $spec_value , $temp_spec_value );
$is_spec_value = ( count ( $diff1 ) == 0 && count ( $diff2 ) == 0 ) ? 0 : 1 ;
// 规格是否修改
$result [ 'is_spec' ] = ( $is_spec_title + $is_spec_base + $is_spec_value > 0 ) ? 1 : 0 ;
}
return $result ;
}
2018-12-28 18:58:37 +08:00
}
?>