mirror of
https://gitee.com/zongzhige/shopxo.git
synced 2026-06-06 16:21:54 +08:00
新增用户商品购物车查看、新增商品规格模板
This commit is contained in:
@ -13,11 +13,12 @@ namespace app\admin\controller;
|
||||
use app\admin\controller\Base;
|
||||
use app\service\ApiService;
|
||||
use app\service\SystemBaseService;
|
||||
use app\service\ResourcesService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\RegionService;
|
||||
use app\service\BrandService;
|
||||
use app\service\GoodsParamsService;
|
||||
use app\service\ResourcesService;
|
||||
use app\service\GoodsSpecService;
|
||||
|
||||
/**
|
||||
* 商品管理
|
||||
@ -111,6 +112,10 @@ class Goods extends Base
|
||||
|
||||
// 获取商品编辑参数
|
||||
$assign['parameters'] = GoodsService::GoodsEditParameters($data['id']);
|
||||
|
||||
// 商品规格模板
|
||||
$spec_template = GoodsSpecService::GoodsCategorySpecTemplateList(['category_ids'=>$data['category_ids']]);
|
||||
$assign['goods_spec_template_list'] = $spec_template['data'];
|
||||
}
|
||||
|
||||
// 规格扩展数据
|
||||
@ -127,8 +132,8 @@ class Goods extends Base
|
||||
],
|
||||
'field' => 'id,name',
|
||||
];
|
||||
$template = GoodsParamsService::GoodsParamsTemplateList($data_params);
|
||||
$assign['goods_template_list'] = $template['data'];
|
||||
$params_template = GoodsParamsService::GoodsParamsTemplateList($data_params);
|
||||
$assign['goods_params_template_list'] = $params_template['data'];
|
||||
|
||||
// 是否拷贝
|
||||
$assign['is_copy'] = (isset($params['is_copy']) && $params['is_copy'] == 1) ? 1 : 0;
|
||||
@ -216,5 +221,26 @@ class Goods extends Base
|
||||
$params['admin'] = $this->admin;
|
||||
return ApiService::ApiDataReturn(GoodsService::GoodsStatusUpdate($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格模板
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 0.0.1
|
||||
* @datetime 2017-01-12T22:23:06+0800
|
||||
*/
|
||||
public function SpecTemplate()
|
||||
{
|
||||
// 是否ajax
|
||||
if(!IS_AJAX)
|
||||
{
|
||||
return $this->error('非法访问');
|
||||
}
|
||||
|
||||
// 开始操作
|
||||
$params = $this->data_post;
|
||||
$params['admin'] = $this->admin;
|
||||
return ApiService::ApiDataReturn(GoodsSpecService::GoodsCategorySpecTemplateList($params));
|
||||
}
|
||||
}
|
||||
?>
|
||||
75
app/admin/controller/Goodscart.php
Normal file
75
app/admin/controller/Goodscart.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\controller\Base;
|
||||
use app\service\ApiService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 商品购物车管理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsCart extends Base
|
||||
{
|
||||
/**
|
||||
* 列表
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
*/
|
||||
public function Index()
|
||||
{
|
||||
return MyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
*/
|
||||
public function Detail()
|
||||
{
|
||||
return MyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
*/
|
||||
public function Delete()
|
||||
{
|
||||
// 是否ajax请求
|
||||
if(!IS_AJAX)
|
||||
{
|
||||
return $this->error('非法访问');
|
||||
}
|
||||
|
||||
// 开始处理
|
||||
$params = $this->data_request;
|
||||
$params['user_type'] = 'admin';
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartDelete($params));
|
||||
}
|
||||
}
|
||||
?>
|
||||
161
app/admin/controller/Goodsspectemplate.php
Normal file
161
app/admin/controller/Goodsspectemplate.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\controller\Base;
|
||||
use app\service\ApiService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\GoodsSpecService;
|
||||
|
||||
/**
|
||||
* 商品规格管理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsSpecTemplate extends Base
|
||||
{
|
||||
/**
|
||||
* 列表
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function Index()
|
||||
{
|
||||
return MyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function Detail()
|
||||
{
|
||||
return MyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑页面
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function SaveInfo()
|
||||
{
|
||||
// 参数
|
||||
$params = $this->data_request;
|
||||
|
||||
// 数据
|
||||
$data = $this->data_detail;
|
||||
|
||||
// 模板数据
|
||||
$assign = [
|
||||
// 商品分类
|
||||
'goods_category_list' => GoodsService::GoodsCategoryList(['where'=>[['pid', '=', 0]]]),
|
||||
];
|
||||
|
||||
// 编辑页面钩子
|
||||
$hook_name = 'plugins_view_admin_goods_spec_template_save';
|
||||
MyViewAssign($hook_name.'_data', MyEventTrigger($hook_name,
|
||||
[
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'data_id' => isset($params['id']) ? $params['id'] : 0,
|
||||
'data' => &$data,
|
||||
'params' => &$params,
|
||||
]));
|
||||
|
||||
// 数据/参数
|
||||
unset($params['id']);
|
||||
$assign['data'] = $data;
|
||||
$assign['params'] = $params;
|
||||
|
||||
// 数据赋值
|
||||
MyViewAssign($assign);
|
||||
return MyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function Save()
|
||||
{
|
||||
// 是否ajax请求
|
||||
if(!IS_AJAX)
|
||||
{
|
||||
return $this->error('非法访问');
|
||||
}
|
||||
|
||||
// 开始处理
|
||||
$params = $this->data_request;
|
||||
return ApiService::ApiDataReturn(GoodsSpecService::GoodsSpecTemplateSave($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function Delete()
|
||||
{
|
||||
// 是否ajax请求
|
||||
if(!IS_AJAX)
|
||||
{
|
||||
return $this->error('非法访问');
|
||||
}
|
||||
|
||||
// 开始处理
|
||||
$params = $this->data_request;
|
||||
$params['user_type'] = 'admin';
|
||||
return ApiService::ApiDataReturn(GoodsSpecService::GoodsSpecTemplateDelete($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态更新
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
public function StatusUpdate()
|
||||
{
|
||||
// 是否ajax请求
|
||||
if(!IS_AJAX)
|
||||
{
|
||||
return $this->error('非法访问');
|
||||
}
|
||||
|
||||
// 开始处理
|
||||
$params = $this->data_request;
|
||||
return ApiService::ApiDataReturn(GoodsSpecService::GoodsSpecTemplateStatusUpdate($params));
|
||||
}
|
||||
}
|
||||
?>
|
||||
165
app/admin/form/Goodscart.php
Normal file
165
app/admin/form/Goodscart.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\form;
|
||||
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 商品购物车管理动态表格
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsCart
|
||||
{
|
||||
// 基础条件
|
||||
public $condition_base = [];
|
||||
|
||||
/**
|
||||
* 入口
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public function Run($params = [])
|
||||
{
|
||||
return [
|
||||
// 基础配置
|
||||
'base' => [
|
||||
'key_field' => 'id',
|
||||
'is_search' => 1,
|
||||
'is_delete' => 1,
|
||||
'delete_url' => MyUrl('admin/goodscart/delete'),
|
||||
'delete_key' => 'ids',
|
||||
],
|
||||
// 表单配置
|
||||
'form' => [
|
||||
[
|
||||
'view_type' => 'checkbox',
|
||||
'is_checked' => 0,
|
||||
'checked_text' => '反选',
|
||||
'not_checked_text' => '全选',
|
||||
'align' => 'center',
|
||||
'width' => 80,
|
||||
],
|
||||
[
|
||||
'label' => '用户信息',
|
||||
'view_type' => 'module',
|
||||
'view_key' => 'lib/module/user',
|
||||
'grid_size' => 'sm',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'input',
|
||||
'form_name' => 'c.user_id',
|
||||
'where_type_custom' => 'in',
|
||||
'where_value_custom' => 'WhereValueUserInfo',
|
||||
'placeholder' => '请输入用户名/昵称/手机/邮箱',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '商品信息',
|
||||
'view_type' => 'module',
|
||||
'view_key' => 'goodscart/module/goods',
|
||||
'grid_size' => 'lg',
|
||||
'is_sort' => 1,
|
||||
'sort_field' => 'g.title',
|
||||
'search_config' => [
|
||||
'form_type' => 'input',
|
||||
'form_name' => 'g.title|g.model|g.simple_desc|g.seo_title|g.seo_keywords|g.seo_keywords',
|
||||
'where_type' => 'like',
|
||||
'placeholder' => '请输入商品名称/简述/SEO信息'
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '销售价格(元)',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'price',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'section',
|
||||
'form_name' => 'g.min_price',
|
||||
'is_point' => 1,
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '原价(元)',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'original_price',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'section',
|
||||
'form_name' => 'g.min_original_price',
|
||||
'is_point' => 1,
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '创建时间',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'add_time',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'datetime',
|
||||
'form_name' => 'c.add_time',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '操作',
|
||||
'view_type' => 'operate',
|
||||
'view_key' => 'goodscart/module/operate',
|
||||
'align' => 'center',
|
||||
'fixed' => 'right',
|
||||
],
|
||||
],
|
||||
// 数据配置
|
||||
'data' => [
|
||||
'table_obj' => Db::name('Cart')->alias('c')->join('goods g', 'g.id=c.goods_id'),
|
||||
'select_field' => 'c.*, g.title, g.original_price, g.price, g.min_price, g.images',
|
||||
'order_by' => 'c.id desc',
|
||||
'detail_dkey' => 'c.id',
|
||||
'data_handle' => 'GoodsCartService::GoodsCartListHandle',
|
||||
'is_page' => 1,
|
||||
'data_params' => [
|
||||
'is_public' => 0,
|
||||
'user_type' => 'admin',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息条件处理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-30
|
||||
* @desc description
|
||||
* @param [string] $value [条件值]
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public function WhereValueUserInfo($value, $params = [])
|
||||
{
|
||||
if(!empty($value))
|
||||
{
|
||||
// 获取用户 id
|
||||
$ids = Db::name('User')->where('username|nickname|mobile|email', 'like', '%'.$value.'%')->column('id');
|
||||
|
||||
// 避免空条件造成无效的错觉
|
||||
return empty($ids) ? [0] : $ids;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
?>
|
||||
167
app/admin/form/Goodsspectemplate.php
Normal file
167
app/admin/form/Goodsspectemplate.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\admin\form;
|
||||
|
||||
use app\service\GoodsService;
|
||||
|
||||
/**
|
||||
* 商品规格动态表格
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-19
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsSpecTemplate
|
||||
{
|
||||
// 基础条件
|
||||
public $condition_base = [];
|
||||
|
||||
// 商品分类
|
||||
public $goods_category_list;
|
||||
|
||||
/**
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public function __construct($params = [])
|
||||
{
|
||||
// 商品分类
|
||||
$res = GoodsService::GoodsCategoryList(['where'=>[['pid', '=', 0]]]);
|
||||
$this->goods_category_list = empty($res) ? [] : array_column($res, 'name', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 入口
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-06-18
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public function Run($params = [])
|
||||
{
|
||||
return [
|
||||
// 基础配置
|
||||
'base' => [
|
||||
'key_field' => 'id',
|
||||
'status_field' => 'is_enable',
|
||||
'is_search' => 1,
|
||||
'is_delete' => 1,
|
||||
'delete_url' => MyUrl('admin/goodsspectemplate/delete'),
|
||||
'delete_key' => 'ids',
|
||||
],
|
||||
// 表单配置
|
||||
'form' => [
|
||||
[
|
||||
'view_type' => 'checkbox',
|
||||
'is_checked' => 0,
|
||||
'checked_text' => '反选',
|
||||
'not_checked_text' => '全选',
|
||||
'align' => 'center',
|
||||
'width' => 80,
|
||||
],
|
||||
[
|
||||
'label' => '商品分类',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'category_id',
|
||||
'view_data' => $this->goods_category_list,
|
||||
'search_config' => [
|
||||
'form_type' => 'select',
|
||||
'form_name' => 'category_id',
|
||||
'where_type' => 'in',
|
||||
'data' => $this->goods_category_list,
|
||||
'is_multiple' => 1,
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '名称',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'name',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'input',
|
||||
'where_type' => 'like',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '是否启用',
|
||||
'view_type' => 'status',
|
||||
'view_key' => 'is_enable',
|
||||
'post_url' => MyUrl('admin/goodsspectemplate/statusupdate'),
|
||||
'is_form_su' => 1,
|
||||
'align' => 'center',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'select',
|
||||
'where_type' => 'in',
|
||||
'data' => MyConst('common_is_enable_list'),
|
||||
'data_key' => 'id',
|
||||
'data_name' => 'name',
|
||||
'is_multiple' => 1,
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '规格值',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'content',
|
||||
'grid_size' => 'sm',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'input',
|
||||
'where_type' => 'like',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '创建时间',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'add_time',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'datetime',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '更新时间',
|
||||
'view_type' => 'field',
|
||||
'view_key' => 'upd_time',
|
||||
'is_sort' => 1,
|
||||
'search_config' => [
|
||||
'form_type' => 'datetime',
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => '操作',
|
||||
'view_type' => 'operate',
|
||||
'view_key' => 'goodsspectemplate/module/operate',
|
||||
'align' => 'center',
|
||||
'fixed' => 'right',
|
||||
],
|
||||
],
|
||||
// 数据配置
|
||||
'data' => [
|
||||
'table_name' => 'GoodsSpecTemplate',
|
||||
'data_handle' => 'GoodsSpecService::GoodsSpecTemplateListHandle',
|
||||
'is_page' => 1,
|
||||
'data_params' => [
|
||||
'is_public' => 0,
|
||||
'user_type' => 'admin',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -206,15 +206,15 @@
|
||||
<!-- 通过配置生成商品参数 -->
|
||||
<div class="am-dropdown" id="parameters-quick-container" data-am-dropdown>
|
||||
<span class="business-operations-submit am-dropdown-toggle parameters-quick-add">
|
||||
<span>快捷操作</span>
|
||||
<span>商品参数模板</span>
|
||||
<i class="am-icon-caret-down"></i>
|
||||
</span>
|
||||
<div class="am-dropdown-content parameters-quick-config">
|
||||
<div class="am-margin-bottom-sm">
|
||||
<select class="am-radius chosen-select goods-template-params-select" data-placeholder="请选择模板..." data-validation-message="选择商品参数模板">
|
||||
{{if !empty($goods_template_list) and is_array($goods_template_list)}}
|
||||
<option value="">请选择模板...</option>
|
||||
{{foreach $goods_template_list as $v}}
|
||||
<option value="">请选择模板...</option>
|
||||
{{if !empty($goods_params_template_list) and is_array($goods_params_template_list)}}
|
||||
{{foreach $goods_params_template_list as $v}}
|
||||
<option value="{{:urlencode(json_encode($v['config_data'], JSON_UNESCAPED_UNICODE))}}">{{$v.name}}</option>
|
||||
{{/foreach}}
|
||||
{{/if}}
|
||||
|
||||
@ -4,9 +4,21 @@
|
||||
<div class="am-alert am-alert-warning am-radius" data-am-alert>
|
||||
<button type="button" class="am-close">×</button>
|
||||
<p>1. 批量添加规格可以快速创建商品SKU,大量节省SKU编辑时间,快捷操作数据不影响SKU数据,仅生成的时候重新覆盖SKU。</p>
|
||||
<p>2. 商品添加成功后,仓库管理->仓库商品中添加并配置库存</p>
|
||||
<p>2. 可以后台 商品管理->商品规格 中配置规格模板、选择商品规格模块快速生成对应规格数据、有效的提供效率</p>
|
||||
<p>3. 商品添加成功后,仓库管理->仓库商品中添加并配置库存</p>
|
||||
</div>
|
||||
<span class="business-operations-submit quick-spec-title-add">+ 批量添加规格</span>
|
||||
<!-- 规格模板 -->
|
||||
<div class="am-inline-block business-operations-submit" id="specifications-quick-container" data-url="{{:MyUrl('admin/goods/spectemplate')}}">
|
||||
<select class="am-radius chosen-select goods-template-spec-select" data-placeholder="商品规格模板..." data-validation-message="请选择商品规格模板">
|
||||
<option value="">商品规格模板...</option>
|
||||
{{if !empty($goods_spec_template_list)}}
|
||||
{{foreach $goods_spec_template_list as $v}}
|
||||
<option value="{{$v.content}}">{{$v.name}}</option>
|
||||
{{/foreach}}
|
||||
{{/if}}
|
||||
</select>
|
||||
</div>
|
||||
<span class="business-operations-submit am-margin-left-sm quick-spec-title-add">+ 批量添加规格</span>
|
||||
<span class="business-operations-submit am-margin-left-sm am-icon-gg quick-spec-created"> 生成规格</span>
|
||||
</div>
|
||||
<div class="goods-specifications am-margin-top-sm" {{if empty($data['spec_base'])}}style="display: none;"{{/if}}>
|
||||
|
||||
2
app/admin/view/default/goodscart/detail.html
Normal file
2
app/admin/view/default/goodscart/detail.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!-- 继承公共的 form -->
|
||||
{{extend name="public/module/detail" /}}
|
||||
2
app/admin/view/default/goodscart/index.html
Executable file
2
app/admin/view/default/goodscart/index.html
Executable file
@ -0,0 +1,2 @@
|
||||
<!-- 继承公共的 form -->
|
||||
{{extend name="public/module/form" /}}
|
||||
18
app/admin/view/default/goodscart/module/goods.html
Normal file
18
app/admin/view/default/goodscart/module/goods.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- 商品基础信息 -->
|
||||
{{if !empty($module_data)}}
|
||||
<div class="am-nbfc">
|
||||
<a href="{{$module_data.goods_url}}" target="_blank" title="{{$module_data.title}}">
|
||||
<img src="{{$module_data['images']}}" class="am-img-thumbnail am-radius am-margin-right-xs am-fl" width="60" height="60" />
|
||||
</a>
|
||||
<a href="{{$module_data.goods_url}}" target="_blank" title="{{$module_data.title}}" {{if !empty($module_data['title_color'])}} style="color:{{$module_data.title_color}};" {{/if}} class="am-nowrap-initial">{{$module_data.title}}</a>
|
||||
{{if !empty($module_data['simple_desc'])}}
|
||||
<p class="am-text-danger am-nowrap-initial">{{$module_data.simple_desc}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="am-margin-top-xs">
|
||||
{{if !empty($module_data['spec_text'])}}
|
||||
<span class="am-nowrap-initial">{{$module_data.spec_text}}</span>
|
||||
{{/if}}
|
||||
<span class="am-fr">x{{$module_data.stock}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
9
app/admin/view/default/goodscart/module/operate.html
Normal file
9
app/admin/view/default/goodscart/module/operate.html
Normal file
@ -0,0 +1,9 @@
|
||||
<!-- 操作栏 -->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-xs am-radius am-btn-block submit-popup" data-url="{{:MyUrl('admin/goodscart/detail', ['id'=>$module_data['id']])}}">
|
||||
<i class="am-icon-eye"></i>
|
||||
<span>详情</span>
|
||||
</button>
|
||||
<button type="button" class="am-btn am-btn-danger am-btn-xs am-radius am-btn-block submit-delete" data-url="{{:MyUrl('admin/goodscart/delete')}}" data-id="{{$module_data.id}}" data-key="ids">
|
||||
<i class="am-icon-trash-o"></i>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
<!-- 表单顶部操作栏 -->
|
||||
{{block name="form_operate_top"}}
|
||||
<a href="{{:MyUrl('admin/goodsparamstemplate/saveinfo')}}" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-plus"> 新增</a>
|
||||
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-plus submit-popup" data-url="{{:MyUrl('admin/goodsparamstemplate/saveinfo')}}"> 新增</button>
|
||||
<!-- 父级内容 -->
|
||||
{__block__}
|
||||
{{/block}}
|
||||
@ -3,10 +3,10 @@
|
||||
<i class="am-icon-eye"></i>
|
||||
<span>详情</span>
|
||||
</button>
|
||||
<a class="am-btn am-btn-secondary am-btn-xs am-radius am-btn-block" href="{{:MyUrl('admin/goodsparamstemplate/saveinfo', array_merge($params, ['id'=>$module_data['id']]))}}">
|
||||
<button type="button" class="am-btn am-btn-secondary am-btn-xs am-radius am-btn-block submit-popup" data-url="{{:MyUrl('admin/goodsparamstemplate/saveinfo', array_merge($params, ['id'=>$module_data['id']]))}}">
|
||||
<i class="am-icon-edit"></i>
|
||||
<span>编辑</span>
|
||||
</a>
|
||||
</button>
|
||||
<button type="button" class="am-btn am-btn-danger am-btn-xs am-radius am-btn-block submit-delete" data-url="{{:MyUrl('admin/goodsparamstemplate/delete')}}" data-id="{{$module_data.id}}" data-key="ids">
|
||||
<i class="am-icon-trash-o"></i>
|
||||
<span>删除</span>
|
||||
|
||||
@ -4,23 +4,19 @@
|
||||
<div class="content-right">
|
||||
<div class="content">
|
||||
<!-- form start -->
|
||||
<form class="am-form form-validation" action="{{:MyUrl('admin/goodsparamstemplate/save')}}" method="POST" request-type="ajax-url" request-value="{{:MyUrl('admin/goodsparamstemplate/index', $params)}}" enctype="multipart/form-data">
|
||||
<legend>
|
||||
<span class="am-text-default">商品参数{{if empty($data['id'])}}添加{{else /}}编辑{{/if}}</span>
|
||||
<a href="{{:MyUrl('admin/goodsparamstemplate/index', $params)}}" class="am-fr am-text-sm am-margin-top-sm am-icon-mail-reply"> 返回</a>
|
||||
</legend>
|
||||
<form class="am-form form-validation am-form-full-screen" action="{{:MyUrl('admin/goodsparamstemplate/save')}}" method="POST" request-type="ajax-reload" request-value="parent">
|
||||
<div class="am-form-group">
|
||||
<label>名称</label>
|
||||
<label>名称<span class="am-form-group-label-tips-must">必填</span></label>
|
||||
<input type="text" name="name" placeholder="名称" minlength="2" maxlength="30" data-validation-message="名称格式 2~30 个字符" class="am-radius" {{if !empty($data['name'])}} value="{{$data.name}}"{{/if}} required />
|
||||
</div>
|
||||
|
||||
<div class="am-margin-top-lg">
|
||||
<label class="block">参数配置</label>
|
||||
<div class="business-form-group">
|
||||
<label class="block">参数配置<span class="am-form-group-label-tips-must">必填</span></label>
|
||||
{{include file="public/goodsparamstemplate/tips" /}}
|
||||
<!-- 通过配置生成商品参数 -->
|
||||
<div class="am-dropdown" id="parameters-quick-container" data-am-dropdown>
|
||||
<span class="business-operations-submit am-dropdown-toggle parameters-quick-add">
|
||||
<span>快捷操作</span>
|
||||
<span>商品参数模板</span>
|
||||
<i class="am-icon-caret-down"></i>
|
||||
</span>
|
||||
<div class="am-dropdown-content parameters-quick-config">
|
||||
@ -38,6 +34,7 @@
|
||||
<i class="am-icon-times"></i>
|
||||
<span>清空参数</span>
|
||||
</span>
|
||||
<span class="am-text-warning am-margin-left-sm">可直接点中参数行拖拽排序或点击上下移动</span>
|
||||
{{include file="public/goodsparamstemplate/table" /}}
|
||||
</div>
|
||||
|
||||
@ -56,7 +53,7 @@
|
||||
<div class="am-alert am-alert-secondary">
|
||||
<label class="am-text-sm am-text-warning">该区域为插件扩展数据,请按照插件文档填写相应的值</label>
|
||||
<div>
|
||||
{{foreach $plugins_view_admin_brand_save_data as $hook}}
|
||||
{{foreach $plugins_view_admin_goods_params_template_save_data as $hook}}
|
||||
{{if is_string($hook) or is_int($hook)}}
|
||||
{{$hook|raw}}
|
||||
{{/if}}
|
||||
@ -66,9 +63,11 @@
|
||||
{{/if}}
|
||||
<!-- 插件扩展数据 end -->
|
||||
|
||||
<div class="am-form-group am-form-group-refreshing am-margin-top-lg am-padding-left-0">
|
||||
<input type="hidden" name="id" {{if !empty($data['id'])}} value="{{$data.id}}"{{/if}} />
|
||||
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'处理中...'}">保存</button>
|
||||
<div class="am-form-group am-form-group-refreshing am-margin-top-lg">
|
||||
<div class="am-padding-bottom-sm">
|
||||
<input type="hidden" name="id" {{if !empty($data['id'])}} value="{{$data.id}}"{{/if}} />
|
||||
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'处理中...'}">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<!-- form end -->
|
||||
|
||||
2
app/admin/view/default/goodsspectemplate/detail.html
Normal file
2
app/admin/view/default/goodsspectemplate/detail.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!-- 继承公共的 form -->
|
||||
{{extend name="public/module/detail" /}}
|
||||
9
app/admin/view/default/goodsspectemplate/index.html
Executable file
9
app/admin/view/default/goodsspectemplate/index.html
Executable file
@ -0,0 +1,9 @@
|
||||
<!-- 继承公共的 form -->
|
||||
{{extend name="public/module/form" /}}
|
||||
|
||||
<!-- 表单顶部操作栏 -->
|
||||
{{block name="form_operate_top"}}
|
||||
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-icon-plus submit-popup" data-url="{{:MyUrl('admin/goodsspectemplate/saveinfo')}}"> 新增</button>
|
||||
<!-- 父级内容 -->
|
||||
{__block__}
|
||||
{{/block}}
|
||||
13
app/admin/view/default/goodsspectemplate/module/operate.html
Normal file
13
app/admin/view/default/goodsspectemplate/module/operate.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!-- 操作栏 -->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-xs am-radius am-btn-block submit-popup" data-url="{{:MyUrl('admin/goodsspectemplate/detail', ['id'=>$module_data['id']])}}">
|
||||
<i class="am-icon-eye"></i>
|
||||
<span>详情</span>
|
||||
</button>
|
||||
<button type="button" class="am-btn am-btn-secondary am-btn-xs am-radius am-btn-block submit-popup" data-url="{{:MyUrl('admin/goodsspectemplate/saveinfo', array_merge($params, ['id'=>$module_data['id']]))}}">
|
||||
<i class="am-icon-edit"></i>
|
||||
<span>编辑</span>
|
||||
</button>
|
||||
<button type="button" class="am-btn am-btn-danger am-btn-xs am-radius am-btn-block submit-delete" data-url="{{:MyUrl('admin/goodsspectemplate/delete')}}" data-id="{{$module_data.id}}" data-key="ids">
|
||||
<i class="am-icon-trash-o"></i>
|
||||
<span>删除</span>
|
||||
</button>
|
||||
69
app/admin/view/default/goodsspectemplate/save_info.html
Executable file
69
app/admin/view/default/goodsspectemplate/save_info.html
Executable file
@ -0,0 +1,69 @@
|
||||
{{include file="public/header" /}}
|
||||
|
||||
<!-- right content start -->
|
||||
<div class="content-right">
|
||||
<div class="content">
|
||||
<!-- form start -->
|
||||
<form class="am-form form-validation am-form-full-screen" action="{{:MyUrl('admin/goodsspectemplate/save')}}" method="POST" request-type="ajax-reload" request-value="parent">
|
||||
<div class="am-form-group">
|
||||
<label>商品分类<span class="am-form-group-label-tips-must">必选、包含子级</span></label>
|
||||
<br />
|
||||
<select name="category_id" class="am-radius chosen-select" data-placeholder="请选择..." data-validation-message="请选择商品分类" required>
|
||||
{{if !empty($goods_category_list)}}
|
||||
<option value="">请选择...</option>
|
||||
{{foreach $goods_category_list as $v}}
|
||||
<option value="{{$v.id}}" {{if isset($data['category_id']) and $data['category_id'] eq $v['id']}}selected{{/if}}>{{$v.name}}</option>
|
||||
{{/foreach}}
|
||||
{{/if}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="am-form-group">
|
||||
<label>规格名称<span class="am-form-group-label-tips-must">必填</span></label>
|
||||
<input type="text" name="name" placeholder="规格名称" minlength="1" maxlength="30" data-validation-message="规格名称格式1~30个字符" class="am-radius" {{if !empty($data['name'])}} value="{{$data.name}}"{{/if}} required />
|
||||
</div>
|
||||
|
||||
<div class="am-form-group">
|
||||
<label>规格值<span class="am-form-group-label-tips-must">必填</span></label>
|
||||
<input type="text" name="content" placeholder="规格值(输入回车可实现多个)" minlength="1" maxlength="1000" data-validation-message="规格值格式1~1000个字符" class="am-radius" {{if !empty($data['content'])}} value="{{$data.content}}"{{/if}} required data-am-tagsinput />
|
||||
</div>
|
||||
|
||||
<div class="am-form-group">
|
||||
<label class="block">是否启用</label>
|
||||
<input name="is_enable" value="1" type="checkbox" data-off-text="否" data-on-text="是" data-size="xs" data-on-color="success" data-off-color="default" data-handle-width="50" data-am-switch {{if (isset($data['is_enable']) and $data['is_enable'] eq 1) or !isset($data['is_enable'])}}checked="true"{{/if}} />
|
||||
</div>
|
||||
|
||||
<!-- 插件扩展数据 start -->
|
||||
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
|
||||
<div class="plugins-tag">
|
||||
<span>plugins_view_admin_goods_spec_template_save</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{if !empty($plugins_view_admin_goods_spec_template_save_data) and is_array($plugins_view_admin_goods_spec_template_save_data)}}
|
||||
<div class="am-alert am-alert-secondary">
|
||||
<label class="am-text-sm am-text-warning">该区域为插件扩展数据,请按照插件文档填写相应的值</label>
|
||||
<div>
|
||||
{{foreach $plugins_view_admin_goods_spec_template_save_data as $hook}}
|
||||
{{if is_string($hook) or is_int($hook)}}
|
||||
{{$hook|raw}}
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<!-- 插件扩展数据 end -->
|
||||
|
||||
<div class="am-form-group am-form-group-refreshing am-margin-top-lg">
|
||||
<div class="am-padding-bottom-sm">
|
||||
<input type="hidden" name="id" {{if !empty($data['id'])}} value="{{$data.id}}"{{/if}} />
|
||||
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'处理中...'}">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<!-- form end -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- right content end -->
|
||||
|
||||
<!-- footer start -->
|
||||
{{include file="public/footer" /}}
|
||||
<!-- footer end -->
|
||||
@ -12,7 +12,7 @@ namespace app\api\controller;
|
||||
|
||||
use app\service\ApiService;
|
||||
use app\service\SystemBaseService;
|
||||
use app\service\BuyService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 购物车
|
||||
@ -48,10 +48,10 @@ class Cart extends Common
|
||||
*/
|
||||
public function Index()
|
||||
{
|
||||
$ret = BuyService::CartList(['user'=>$this->user]);
|
||||
$ret = GoodsCartService::GoodsCartList(['user'=>$this->user]);
|
||||
$result = [
|
||||
'data' => $ret['data'],
|
||||
'common_cart_total' => BuyService::UserCartTotal(['user'=>$this->user]),
|
||||
'common_cart_total' => GoodsCartService::UserGoodsCartTotal(['user'=>$this->user]),
|
||||
];
|
||||
|
||||
return ApiService::ApiDataReturn(SystemBaseService::DataReturn($result));
|
||||
@ -69,7 +69,7 @@ class Cart extends Common
|
||||
{
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartSave($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartSave($params));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,7 +84,7 @@ class Cart extends Common
|
||||
{
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartDelete($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartDelete($params));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +99,7 @@ class Cart extends Common
|
||||
{
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartStock($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartStock($params));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -11,6 +11,7 @@
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\service\ApiService;
|
||||
use app\service\AppService;
|
||||
use app\service\SystemBaseService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\BuyService;
|
||||
@ -18,7 +19,7 @@ use app\service\GoodsCommentsService;
|
||||
use app\service\ResourcesService;
|
||||
use app\service\GoodsFavorService;
|
||||
use app\service\GoodsBrowseService;
|
||||
use app\service\AppService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 商品
|
||||
@ -122,7 +123,7 @@ class Goods extends Common
|
||||
// 数据返回
|
||||
$result = [
|
||||
'goods' => $goods,
|
||||
'common_cart_total' => BuyService::UserCartTotal(['user'=>$this->user]),
|
||||
'common_cart_total' => GoodsCartService::UserGoodsCartTotal(['user'=>$this->user]),
|
||||
'buy_button' => $buy_button,
|
||||
'middle_tabs_nav' => $middle_tabs_nav,
|
||||
'nav_more_list' => $nav_more_list,
|
||||
|
||||
@ -21,6 +21,7 @@ use app\service\ArticleService;
|
||||
use app\service\MessageService;
|
||||
use app\service\AppService;
|
||||
use app\service\PluginsService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
@ -62,7 +63,7 @@ class Index extends Common
|
||||
}
|
||||
|
||||
// 购物车数量
|
||||
$common_cart_total = BuyService::UserCartTotal(['user'=>$this->user]);
|
||||
$common_cart_total = GoodsCartService::UserGoodsCartTotal(['user'=>$this->user]);
|
||||
|
||||
// 未读消息总数
|
||||
$params = ['user'=>$this->user, 'is_more'=>1, 'is_read'=>0];
|
||||
|
||||
@ -22,6 +22,7 @@ use app\service\GoodsFavorService;
|
||||
use app\service\GoodsBrowseService;
|
||||
use app\service\IntegralService;
|
||||
use app\service\AppMiniUserService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
@ -271,7 +272,7 @@ class User extends Common
|
||||
'user_goods_browse_count' => $user_goods_browse_count,
|
||||
'common_message_total' => $common_message_total,
|
||||
'navigation' => AppCenterNavService::AppCenterNav(),
|
||||
'common_cart_total' => BuyService::UserCartTotal(['user'=>$this->user]),
|
||||
'common_cart_total' => GoodsCartService::UserGoodsCartTotal(['user'=>$this->user]),
|
||||
);
|
||||
|
||||
// 返回数据
|
||||
|
||||
@ -12,7 +12,7 @@ namespace app\index\controller;
|
||||
|
||||
use app\service\ApiService;
|
||||
use app\service\SeoService;
|
||||
use app\service\BuyService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 购物车
|
||||
@ -49,12 +49,12 @@ class Cart extends Common
|
||||
public function Index()
|
||||
{
|
||||
// 购物车列表
|
||||
$cart_list = BuyService::CartList(['user'=>$this->user]);
|
||||
$cart_list = GoodsCartService::GoodsCartList(['user'=>$this->user]);
|
||||
|
||||
// 基础信息
|
||||
$base = [
|
||||
'total_price' => empty($cart_list['data']) ? 0 : array_sum(array_column($cart_list['data'], 'total_price')),
|
||||
'buy_count' => empty($cart_list['data']) ? 0 : array_sum(array_column($cart_list['data'], 'stock')),
|
||||
'buy_count' => empty($cart_list['data']) ? 0 : array_sum(array_column($cart_list['data'], 'stock')),
|
||||
];
|
||||
|
||||
// 数据赋值
|
||||
@ -85,7 +85,7 @@ class Cart extends Common
|
||||
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartSave($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartSave($params));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +106,7 @@ class Cart extends Common
|
||||
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartDelete($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartDelete($params));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +127,7 @@ class Cart extends Common
|
||||
|
||||
$params = $this->data_post;
|
||||
$params['user'] = $this->user;
|
||||
return ApiService::ApiDataReturn(BuyService::CartStock($params));
|
||||
return ApiService::ApiDataReturn(GoodsCartService::GoodsCartStock($params));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -15,12 +15,12 @@ use app\service\SystemService;
|
||||
use app\service\OrderService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\UserService;
|
||||
use app\service\BuyService;
|
||||
use app\service\SeoService;
|
||||
use app\service\MessageService;
|
||||
use app\service\NavigationService;
|
||||
use app\service\GoodsBrowseService;
|
||||
use app\service\GoodsFavorService;
|
||||
use app\service\GoodsCartService;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
@ -134,7 +134,7 @@ class User extends Common
|
||||
$assign['order_list'] = $order['data'];
|
||||
|
||||
// 获取购物车
|
||||
$cart_list = BuyService::CartList(['user'=>$this->user]);
|
||||
$cart_list = GoodsCartService::GoodsCartList(['user'=>$this->user]);
|
||||
$assign['cart_list'] = $cart_list['data'];
|
||||
|
||||
// 收藏商品
|
||||
|
||||
@ -132,18 +132,12 @@ class AdminPowerService
|
||||
$data['add_time'] = time();
|
||||
if(Db::name('Power')->insertGetId($data) > 0)
|
||||
{
|
||||
// 清除用户权限数据
|
||||
self::PowerCacheDelete();
|
||||
|
||||
return DataReturn(MyLang('common.insert_success'), 0);
|
||||
}
|
||||
return DataReturn(MyLang('common.insert_fail'), -100);
|
||||
} else {
|
||||
if(Db::name('Power')->where(['id'=>intval($params['id'])])->update($data) !== false)
|
||||
{
|
||||
// 清除用户权限数据
|
||||
self::PowerCacheDelete();
|
||||
|
||||
return DataReturn(MyLang('common.update_success'), 0);
|
||||
}
|
||||
return DataReturn(MyLang('common.update_fail'), -100);
|
||||
|
||||
@ -12,8 +12,9 @@ namespace app\service;
|
||||
|
||||
use think\facade\Db;
|
||||
use app\service\SystemBaseService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\UserService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\GoodsCartService;
|
||||
use app\service\UserAddressService;
|
||||
use app\service\ResourcesService;
|
||||
use app\service\PaymentService;
|
||||
@ -31,488 +32,6 @@ use app\service\OrderCurrencyService;
|
||||
*/
|
||||
class BuyService
|
||||
{
|
||||
/**
|
||||
* 购物车添加/更新
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-08-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function CartSave($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'goods_id',
|
||||
'error_msg' => '商品id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'stock',
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'min',
|
||||
'key_name' => 'stock',
|
||||
'checked_data' => 1,
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 查询用户状态是否正常
|
||||
$ret = UserService::UserStatusCheck('id', $params['user']['id']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 获取商品
|
||||
$goods_id = intval($params['goods_id']);
|
||||
$goods = Db::name('Goods')->where(['id'=>$goods_id, 'is_shelves'=>1, 'is_delete_time'=>0])->find();
|
||||
if(empty($goods))
|
||||
{
|
||||
return DataReturn('商品不存在或已删除', -2);
|
||||
}
|
||||
|
||||
// 无封面图片
|
||||
if(empty($goods['images']))
|
||||
{
|
||||
$goods['images'] = ResourcesService::AttachmentPathHandle(GoodsService::GoodsImagesCoverHandle($goods_id));
|
||||
}
|
||||
|
||||
// 是否支持购物车操作
|
||||
$ret = GoodsService::IsGoodsSiteTypeConsistent($goods_id, $goods['site_type']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 规格处理
|
||||
$spec = self::GoodsSpecificationsHandle($params);
|
||||
|
||||
// 获取商品基础信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $goods_id,
|
||||
'spec' => $spec,
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
if($goods_base['code'] != 0)
|
||||
{
|
||||
return $goods_base;
|
||||
}
|
||||
|
||||
// 是否存在规格
|
||||
if(!empty($spec))
|
||||
{
|
||||
// 获取商品规格图片
|
||||
$images = self::BuyGoodsSpecImages($goods_id, $spec);
|
||||
if(!empty($images))
|
||||
{
|
||||
$goods['images'] = $images;
|
||||
$goods['images_old'] = ResourcesService::AttachmentPathViewHandle($images);
|
||||
}
|
||||
|
||||
// 规格库存赋值
|
||||
$goods['inventory'] = $goods_base['data']['spec_base']['inventory'];
|
||||
}
|
||||
|
||||
// 数量
|
||||
$stock = ($goods['buy_max_number'] > 0 && $params['stock'] > $goods['buy_max_number']) ? $goods['buy_max_number'] : $params['stock'];
|
||||
|
||||
// 库存
|
||||
if($stock > $goods['inventory'])
|
||||
{
|
||||
return DataReturn('库存不足', -1);
|
||||
}
|
||||
|
||||
// 添加购物车
|
||||
$data = [
|
||||
'user_id' => $params['user']['id'],
|
||||
'goods_id' => $goods_id,
|
||||
'title' => $goods['title'],
|
||||
'images' => $goods['images'],
|
||||
'original_price'=> $goods_base['data']['spec_base']['original_price'],
|
||||
'price' => $goods_base['data']['spec_base']['price'],
|
||||
'stock' => $stock,
|
||||
'spec' => empty($spec) ? '' : json_encode($spec, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
|
||||
// 存在则更新
|
||||
$where = ['user_id'=>$data['user_id'], 'goods_id'=>$data['goods_id'], 'spec'=>$data['spec']];
|
||||
$temp = Db::name('Cart')->where($where)->find();
|
||||
if(empty($temp))
|
||||
{
|
||||
$data['add_time'] = time();
|
||||
if(Db::name('Cart')->insertGetId($data) > 0)
|
||||
{
|
||||
return DataReturn(MyLang('common.join_success'), 0, self::UserCartTotal($params));
|
||||
}
|
||||
} else {
|
||||
$data['upd_time'] = time();
|
||||
$data['stock'] += $temp['stock'];
|
||||
if($data['stock'] > $goods['inventory'])
|
||||
{
|
||||
$data['stock'] = $goods['inventory'];
|
||||
}
|
||||
if($goods['buy_max_number'] > 0 && $data['stock'] > $goods['buy_max_number'])
|
||||
{
|
||||
$data['stock'] = $goods['buy_max_number'];
|
||||
}
|
||||
if(Db::name('Cart')->where($where)->update($data))
|
||||
{
|
||||
return DataReturn(MyLang('common.join_success'), 0, self::UserCartTotal($params));
|
||||
}
|
||||
}
|
||||
|
||||
return DataReturn(MyLang('common.join_fail'), -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品规格解析
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-21
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecificationsHandle($params = [])
|
||||
{
|
||||
$spec = '';
|
||||
if(!empty($params['spec']))
|
||||
{
|
||||
if(!is_array($params['spec']))
|
||||
{
|
||||
$spec = json_decode(htmlspecialchars_decode($params['spec']), true);
|
||||
} else {
|
||||
$spec = $params['spec'];
|
||||
}
|
||||
}
|
||||
return empty($spec) ? '' : $spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取购物车列表
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-08-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function CartList($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 基础参数
|
||||
$where = (!empty($params['where']) && is_array($params['where'])) ? $params['where'] : [];
|
||||
$where[] = ['c.user_id', '=', $params['user']['id']];
|
||||
$field = 'c.*, g.inventory_unit, g.is_shelves, g.is_delete_time, g.buy_min_number, g.buy_max_number, g.model, g.site_type';
|
||||
|
||||
// 购物车列表读取前钩子
|
||||
$hook_name = 'plugins_service_cart_goods_list_begin';
|
||||
MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => &$params,
|
||||
'where' => &$where,
|
||||
'field' => &$field,
|
||||
]);
|
||||
|
||||
// 获取购物车数据
|
||||
$data = Db::name('Cart')->alias('c')->leftJoin('goods g', 'g.id=c.goods_id')->where($where)->field($field)->order('c.id desc')->select()->toArray();
|
||||
|
||||
// 数据处理
|
||||
$data = self::CartListDataHandle($data, $params);
|
||||
return DataReturn(MyLang('common.operate_success'), 0, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车列表数据处理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2022-04-05
|
||||
* @desc description
|
||||
* @param [array] $data [购物车数据]
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function CartListDataHandle($data, $params = [])
|
||||
{
|
||||
if(!empty($data))
|
||||
{
|
||||
// 商品处理
|
||||
$res = GoodsService::GoodsDataHandle($data, ['data_key_field'=>'goods_id']);
|
||||
$data = $res['data'];
|
||||
foreach($data as &$v)
|
||||
{
|
||||
// 规格
|
||||
$v['spec'] = empty($v['spec']) ? null : json_decode($v['spec'], true);
|
||||
|
||||
// 获取商品基础信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $v['goods_id'],
|
||||
'spec' => $v['spec'],
|
||||
'stock' => $v['stock'],
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
$v['is_invalid'] = 0;
|
||||
if($goods_base['code'] == 0)
|
||||
{
|
||||
$v['inventory'] = $goods_base['data']['spec_base']['inventory'];
|
||||
$v['price'] = $goods_base['data']['spec_base']['price'];
|
||||
$v['original_price'] = $goods_base['data']['spec_base']['original_price'];
|
||||
$v['spec_weight'] = $goods_base['data']['spec_base']['weight'];
|
||||
$v['spec_volume'] = $goods_base['data']['spec_base']['volume'];
|
||||
$v['spec_coding'] = $goods_base['data']['spec_base']['coding'];
|
||||
$v['spec_barcode'] = $goods_base['data']['spec_base']['barcode'];
|
||||
$v['extends'] = $goods_base['data']['spec_base']['extends'];
|
||||
} else {
|
||||
$v['is_invalid'] = 1;
|
||||
$v['inventory'] = 0;
|
||||
$v['spec_weight'] = 0;
|
||||
$v['spec_volume'] = 0;
|
||||
$v['spec_coding'] = '';
|
||||
$v['spec_barcode'] = '';
|
||||
$v['extends'] = '';
|
||||
}
|
||||
|
||||
// 基础信息
|
||||
$v['total_price'] = PriceNumberFormat($v['stock']* $v['price']);
|
||||
$v['buy_max_number'] = ($v['buy_max_number'] <= 0) ? $v['inventory']: $v['buy_max_number'];
|
||||
|
||||
// 错误处理
|
||||
$v['is_error'] = 0;
|
||||
$v['error_msg'] = '';
|
||||
if($v['is_delete_time'] != 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已作废';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['is_invalid'] == 1)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已失效';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['is_shelves'] != 1)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已下架';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['inventory'] <= 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '没货了';
|
||||
}
|
||||
if(empty($v['error_msg']))
|
||||
{
|
||||
$ret = GoodsService::IsGoodsSiteTypeConsistent($v['goods_id'], $v['site_type']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = $ret['msg'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车删除
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-14
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function CartDelete($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'id',
|
||||
'error_msg' => '删除数据id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 查询用户状态是否正常
|
||||
$ret = UserService::UserStatusCheck('id', $params['user']['id']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 删除
|
||||
$where = [
|
||||
'id' => is_array($params['id']) ? $params['id'] : explode(',', $params['id']),
|
||||
'user_id' => $params['user']['id']
|
||||
];
|
||||
if(Db::name('Cart')->where($where)->delete())
|
||||
{
|
||||
return DataReturn(MyLang('common.delete_success'), 0, self::UserCartTotal($params));
|
||||
}
|
||||
return DataReturn('删除失败或资源不存在', -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车数量保存
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-14
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function CartStock($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'id',
|
||||
'error_msg' => '数据id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'goods_id',
|
||||
'error_msg' => '商品id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'stock',
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'min',
|
||||
'key_name' => 'stock',
|
||||
'checked_data' => 1,
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 查询用户状态是否正常
|
||||
$ret = UserService::UserStatusCheck('id', $params['user']['id']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 条件
|
||||
$where = [
|
||||
'id' => intval($params['id']),
|
||||
'goods_id' => intval($params['goods_id']),
|
||||
'user_id' => intval($params['user']['id']),
|
||||
];
|
||||
|
||||
// 数量
|
||||
$stock = intval($params['stock']);
|
||||
|
||||
// 获取购物车数据
|
||||
$data = Db::name('Cart')->where($where)->field('goods_id,title,price,stock,spec')->find();
|
||||
if(empty($data))
|
||||
{
|
||||
return DataReturn('请先加入购物车', -1);
|
||||
}
|
||||
$data['stock'] = $stock;
|
||||
$data['spec'] = empty($data['spec']) ? null : json_decode($data['spec'], true);
|
||||
|
||||
// 商品校验
|
||||
$ret = self::BuyGoodsCheck(['goods'=>[$data]]);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
$upd_data = [
|
||||
'stock' => $stock,
|
||||
'upd_time' => time(),
|
||||
];
|
||||
if(Db::name('Cart')->where($where)->update($upd_data))
|
||||
{
|
||||
// 获取商品基础信息、更新商品价格信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $data['goods_id'],
|
||||
'spec' => $data['spec'],
|
||||
'stock' => $data['stock'],
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
if($goods_base['code'] == 0)
|
||||
{
|
||||
$data['price'] = $goods_base['data']['spec_base']['price'];
|
||||
$data['original_price'] = $goods_base['data']['spec_base']['original_price'];
|
||||
}
|
||||
|
||||
// 增加价格总计
|
||||
$data['total_price'] = PriceNumberFormat($data['stock']*$data['price']);
|
||||
|
||||
// 购物车更新成功钩子
|
||||
$hook_name = 'plugins_service_cart_update_success';
|
||||
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => $params,
|
||||
'data' => &$data,
|
||||
'goods_id' => $params['goods_id']
|
||||
]));
|
||||
if(isset($ret['code']) && $ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return DataReturn(MyLang('common.update_success'), 0, $data);
|
||||
}
|
||||
return DataReturn(MyLang('common.update_fail'), -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下订单 - 正常购买
|
||||
* @author Devil
|
||||
@ -616,6 +135,30 @@ class BuyService
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品规格解析
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-21
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecificationsHandle($params = [])
|
||||
{
|
||||
$spec = '';
|
||||
if(!empty($params['spec']))
|
||||
{
|
||||
if(!is_array($params['spec']))
|
||||
{
|
||||
$spec = json_decode(htmlspecialchars_decode($params['spec']), true);
|
||||
} else {
|
||||
$spec = $params['spec'];
|
||||
}
|
||||
}
|
||||
return empty($spec) ? '' : $spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下订单 - 购物车
|
||||
* @author Devil
|
||||
@ -652,7 +195,7 @@ class BuyService
|
||||
['g.is_shelves', '=', 1],
|
||||
['c.id', 'in', explode(',', $params['ids'])],
|
||||
];
|
||||
return self::CartList($params);
|
||||
return GoodsCartService::GoodsCartList($params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1637,64 +1180,6 @@ class BuyService
|
||||
return DataReturn('订单地址添加失败', -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车总数
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-29
|
||||
* @desc description
|
||||
* @param [array] $where [条件]
|
||||
*/
|
||||
public static function CartTotal($where = [])
|
||||
{
|
||||
return (int) Db::name('Cart')->where($where)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户购物车总数
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
* @return [int|string] [超过99则返回 99+]
|
||||
*/
|
||||
public static function UserCartTotal($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 条件
|
||||
$where = [
|
||||
['user_id', '=', $params['user']['id']]
|
||||
];
|
||||
|
||||
// 购物车总数读取前钩子
|
||||
$hook_name = 'plugins_service_user_cart_total_begin';
|
||||
MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => $params,
|
||||
'where' => &$where,
|
||||
]);
|
||||
|
||||
$total = self::CartTotal($where);
|
||||
return ($total > 99) ? '99+' : $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个订单支付前校验
|
||||
* @author Devil
|
||||
|
||||
572
app/service/GoodsCartService.php
Normal file
572
app/service/GoodsCartService.php
Normal file
@ -0,0 +1,572 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\service;
|
||||
|
||||
use think\facade\Db;
|
||||
use app\service\UserService;
|
||||
use app\service\BuyService;
|
||||
use app\service\GoodsService;
|
||||
use app\service\ResourcesService;
|
||||
|
||||
/**
|
||||
* 商品购物车服务层
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-10-09
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsCartService
|
||||
{
|
||||
/**
|
||||
* 获取购物车列表
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-08-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCartList($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 基础参数
|
||||
$where = (!empty($params['where']) && is_array($params['where'])) ? $params['where'] : [];
|
||||
$where[] = ['c.user_id', '=', $params['user']['id']];
|
||||
$field = 'c.*, g.inventory_unit, g.is_shelves, g.is_delete_time, g.buy_min_number, g.buy_max_number, g.model, g.site_type';
|
||||
|
||||
// 购物车列表读取前钩子
|
||||
$hook_name = 'plugins_service_cart_goods_list_begin';
|
||||
MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => &$params,
|
||||
'where' => &$where,
|
||||
'field' => &$field,
|
||||
]);
|
||||
|
||||
// 获取购物车数据
|
||||
$data = Db::name('Cart')->alias('c')->leftJoin('goods g', 'g.id=c.goods_id')->where($where)->field($field)->order('c.id desc')->select()->toArray();
|
||||
if(!empty($data))
|
||||
{
|
||||
// 商品处理
|
||||
$res = GoodsService::GoodsDataHandle($data, ['data_key_field'=>'goods_id']);
|
||||
$data = $res['data'];
|
||||
foreach($data as &$v)
|
||||
{
|
||||
// 规格
|
||||
$v['spec'] = empty($v['spec']) ? null : json_decode($v['spec'], true);
|
||||
|
||||
// 获取商品基础信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $v['goods_id'],
|
||||
'spec' => $v['spec'],
|
||||
'stock' => $v['stock'],
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
$v['is_invalid'] = 0;
|
||||
if($goods_base['code'] == 0)
|
||||
{
|
||||
$v['inventory'] = $goods_base['data']['spec_base']['inventory'];
|
||||
$v['price'] = $goods_base['data']['spec_base']['price'];
|
||||
$v['original_price'] = $goods_base['data']['spec_base']['original_price'];
|
||||
$v['spec_weight'] = $goods_base['data']['spec_base']['weight'];
|
||||
$v['spec_volume'] = $goods_base['data']['spec_base']['volume'];
|
||||
$v['spec_coding'] = $goods_base['data']['spec_base']['coding'];
|
||||
$v['spec_barcode'] = $goods_base['data']['spec_base']['barcode'];
|
||||
$v['extends'] = $goods_base['data']['spec_base']['extends'];
|
||||
} else {
|
||||
$v['is_invalid'] = 1;
|
||||
$v['inventory'] = 0;
|
||||
$v['spec_weight'] = 0;
|
||||
$v['spec_volume'] = 0;
|
||||
$v['spec_coding'] = '';
|
||||
$v['spec_barcode'] = '';
|
||||
$v['extends'] = '';
|
||||
}
|
||||
|
||||
// 基础信息
|
||||
$v['total_price'] = PriceNumberFormat($v['stock']* $v['price']);
|
||||
$v['buy_max_number'] = ($v['buy_max_number'] <= 0) ? $v['inventory']: $v['buy_max_number'];
|
||||
|
||||
// 错误处理
|
||||
$v['is_error'] = 0;
|
||||
$v['error_msg'] = '';
|
||||
if($v['is_delete_time'] != 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已作废';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['is_invalid'] == 1)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已失效';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['is_shelves'] != 1)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '已下架';
|
||||
}
|
||||
if(empty($v['error_msg']) && $v['inventory'] <= 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = '没货了';
|
||||
}
|
||||
if(empty($v['error_msg']))
|
||||
{
|
||||
$ret = GoodsService::IsGoodsSiteTypeConsistent($v['goods_id'], $v['site_type']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
$v['is_error'] = 1;
|
||||
$v['error_msg'] = $ret['msg'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DataReturn(MyLang('common.operate_success'), 0, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据处理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2022-08-01
|
||||
* @desc description
|
||||
* @param [array] $data [数据列表]
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCartListHandle($data, $params = [])
|
||||
{
|
||||
if(!empty($data))
|
||||
{
|
||||
// 商品数据处理
|
||||
$ret = GoodsService::GoodsDataHandle($data, ['data_key_field'=>'goods_id']);
|
||||
$data = $ret['data'];
|
||||
|
||||
// 是否公共读取
|
||||
$is_public = (isset($params['is_public']) && $params['is_public'] == 0) ? 0 : 1;
|
||||
$users = [];
|
||||
foreach($data as &$v)
|
||||
{
|
||||
// 用户信息
|
||||
if(isset($v['user_id']) && $is_public == 0)
|
||||
{
|
||||
if(!array_key_exists($v['user_id'], $users))
|
||||
{
|
||||
$users[$v['user_id']] = UserService::GetUserViewInfo($v['user_id']);
|
||||
}
|
||||
$v['user'] = $users[$v['user_id']];
|
||||
}
|
||||
|
||||
// 规格
|
||||
$v['spec_text'] = null;
|
||||
if(!empty($v['spec']))
|
||||
{
|
||||
$v['spec'] = json_decode($v['spec'], true);
|
||||
if(!empty($v['spec']) && is_array($v['spec']))
|
||||
{
|
||||
$v['spec_text'] = implode(',', array_map(function($spec)
|
||||
{
|
||||
return $spec['type'].':'.$spec['value'];
|
||||
}, $v['spec']));
|
||||
}
|
||||
} else {
|
||||
$v['spec'] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车添加/更新
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-08-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCartSave($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'goods_id',
|
||||
'error_msg' => '商品id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'stock',
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'min',
|
||||
'key_name' => 'stock',
|
||||
'checked_data' => 1,
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 查询用户状态是否正常
|
||||
$ret = UserService::UserStatusCheck('id', $params['user']['id']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 获取商品
|
||||
$goods_id = intval($params['goods_id']);
|
||||
$goods = Db::name('Goods')->where(['id'=>$goods_id, 'is_shelves'=>1, 'is_delete_time'=>0])->find();
|
||||
if(empty($goods))
|
||||
{
|
||||
return DataReturn('商品不存在或已删除', -2);
|
||||
}
|
||||
|
||||
// 无封面图片
|
||||
if(empty($goods['images']))
|
||||
{
|
||||
$goods['images'] = ResourcesService::AttachmentPathHandle(GoodsService::GoodsImagesCoverHandle($goods_id));
|
||||
}
|
||||
|
||||
// 是否支持购物车操作
|
||||
$ret = GoodsService::IsGoodsSiteTypeConsistent($goods_id, $goods['site_type']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 规格处理
|
||||
$spec = BuyService::GoodsSpecificationsHandle($params);
|
||||
|
||||
// 获取商品基础信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $goods_id,
|
||||
'spec' => $spec,
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
if($goods_base['code'] != 0)
|
||||
{
|
||||
return $goods_base;
|
||||
}
|
||||
|
||||
// 是否存在规格
|
||||
if(!empty($spec))
|
||||
{
|
||||
// 获取商品规格图片
|
||||
$images = BuyService::BuyGoodsSpecImages($goods_id, $spec);
|
||||
if(!empty($images))
|
||||
{
|
||||
$goods['images'] = $images;
|
||||
$goods['images_old'] = ResourcesService::AttachmentPathViewHandle($images);
|
||||
}
|
||||
|
||||
// 规格库存赋值
|
||||
$goods['inventory'] = $goods_base['data']['spec_base']['inventory'];
|
||||
}
|
||||
|
||||
// 数量
|
||||
$stock = ($goods['buy_max_number'] > 0 && $params['stock'] > $goods['buy_max_number']) ? $goods['buy_max_number'] : $params['stock'];
|
||||
|
||||
// 库存
|
||||
if($stock > $goods['inventory'])
|
||||
{
|
||||
return DataReturn('库存不足', -1);
|
||||
}
|
||||
|
||||
// 添加购物车
|
||||
$data = [
|
||||
'user_id' => $params['user']['id'],
|
||||
'goods_id' => $goods_id,
|
||||
'title' => $goods['title'],
|
||||
'images' => $goods['images'],
|
||||
'original_price'=> $goods_base['data']['spec_base']['original_price'],
|
||||
'price' => $goods_base['data']['spec_base']['price'],
|
||||
'stock' => $stock,
|
||||
'spec' => empty($spec) ? '' : json_encode($spec, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
|
||||
// 存在则更新
|
||||
$where = ['user_id'=>$data['user_id'], 'goods_id'=>$data['goods_id'], 'spec'=>$data['spec']];
|
||||
$temp = Db::name('Cart')->where($where)->find();
|
||||
if(empty($temp))
|
||||
{
|
||||
$data['add_time'] = time();
|
||||
if(Db::name('Cart')->insertGetId($data) > 0)
|
||||
{
|
||||
return DataReturn(MyLang('common.join_success'), 0, self::UserGoodsCartTotal($params));
|
||||
}
|
||||
} else {
|
||||
$data['upd_time'] = time();
|
||||
$data['stock'] += $temp['stock'];
|
||||
if($data['stock'] > $goods['inventory'])
|
||||
{
|
||||
$data['stock'] = $goods['inventory'];
|
||||
}
|
||||
if($goods['buy_max_number'] > 0 && $data['stock'] > $goods['buy_max_number'])
|
||||
{
|
||||
$data['stock'] = $goods['buy_max_number'];
|
||||
}
|
||||
if(Db::name('Cart')->where($where)->update($data))
|
||||
{
|
||||
return DataReturn(MyLang('common.join_success'), 0, self::UserGoodsCartTotal($params));
|
||||
}
|
||||
}
|
||||
return DataReturn(MyLang('common.join_fail'), -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车数量保存
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-14
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCartStock($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'id',
|
||||
'error_msg' => '数据id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'goods_id',
|
||||
'error_msg' => '商品id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'stock',
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'min',
|
||||
'key_name' => 'stock',
|
||||
'checked_data' => 1,
|
||||
'error_msg' => '购买数量有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 查询用户状态是否正常
|
||||
$ret = UserService::UserStatusCheck('id', $params['user']['id']);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 条件
|
||||
$where = [
|
||||
'id' => intval($params['id']),
|
||||
'goods_id' => intval($params['goods_id']),
|
||||
'user_id' => intval($params['user']['id']),
|
||||
];
|
||||
|
||||
// 数量
|
||||
$stock = intval($params['stock']);
|
||||
|
||||
// 获取购物车数据
|
||||
$data = Db::name('Cart')->where($where)->field('goods_id,title,price,stock,spec')->find();
|
||||
if(empty($data))
|
||||
{
|
||||
return DataReturn('请先加入购物车', -1);
|
||||
}
|
||||
$data['stock'] = $stock;
|
||||
$data['spec'] = empty($data['spec']) ? null : json_decode($data['spec'], true);
|
||||
|
||||
// 商品校验
|
||||
$ret = self::BuyGoodsCheck(['goods'=>[$data]]);
|
||||
if($ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
$upd_data = [
|
||||
'stock' => $stock,
|
||||
'upd_time' => time(),
|
||||
];
|
||||
if(Db::name('Cart')->where($where)->update($upd_data))
|
||||
{
|
||||
// 获取商品基础信息、更新商品价格信息
|
||||
$spec_params = array_merge($params, [
|
||||
'id' => $data['goods_id'],
|
||||
'spec' => $data['spec'],
|
||||
'stock' => $data['stock'],
|
||||
]);
|
||||
$goods_base = GoodsService::GoodsSpecDetail($spec_params);
|
||||
if($goods_base['code'] == 0)
|
||||
{
|
||||
$data['price'] = $goods_base['data']['spec_base']['price'];
|
||||
$data['original_price'] = $goods_base['data']['spec_base']['original_price'];
|
||||
}
|
||||
|
||||
// 增加价格总计
|
||||
$data['total_price'] = PriceNumberFormat($data['stock']*$data['price']);
|
||||
|
||||
// 购物车更新成功钩子
|
||||
$hook_name = 'plugins_service_cart_update_success';
|
||||
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => $params,
|
||||
'data' => &$data,
|
||||
'goods_id' => $params['goods_id']
|
||||
]));
|
||||
if(isset($ret['code']) && $ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return DataReturn(MyLang('common.update_success'), 0, $data);
|
||||
}
|
||||
return DataReturn(MyLang('common.update_fail'), -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车总数
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-29
|
||||
* @desc description
|
||||
* @param [array] $where [条件]
|
||||
*/
|
||||
public static function GoodsCartTotal($where = [])
|
||||
{
|
||||
return (int) Db::name('Cart')->where($where)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户购物车总数
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-29
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
* @return [int|string] [超过99则返回 99+]
|
||||
*/
|
||||
public static function UserGoodsCartTotal($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'user',
|
||||
'error_msg' => '用户信息有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 条件
|
||||
$where = [
|
||||
['user_id', '=', $params['user']['id']]
|
||||
];
|
||||
|
||||
// 购物车总数读取前钩子
|
||||
$hook_name = 'plugins_service_user_cart_total_begin';
|
||||
MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => $params,
|
||||
'where' => &$where,
|
||||
]);
|
||||
|
||||
$total = self::GoodsCartTotal($where);
|
||||
return ($total > 99) ? '99+' : $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品购物车删除
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-09-14
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCartDelete($params = [])
|
||||
{
|
||||
// 参数处理
|
||||
$ids = empty($params['ids']) ? (empty($params['id']) ? [] : $params['id']) : $params['ids'];
|
||||
if(empty($ids))
|
||||
{
|
||||
return DataReturn('操作id有误', -1);
|
||||
}
|
||||
// 是否数组
|
||||
if(!is_array($ids))
|
||||
{
|
||||
$ids = explode(',', $ids);
|
||||
}
|
||||
|
||||
// 条件
|
||||
$where = [
|
||||
['id', 'in', $ids],
|
||||
];
|
||||
|
||||
// 用户id
|
||||
if(!empty($params['user']))
|
||||
{
|
||||
$where[] = ['user_id', '=', $params['user']['id']];
|
||||
}
|
||||
|
||||
// 删除
|
||||
if(Db::name('Cart')->where($where)->delete())
|
||||
{
|
||||
return DataReturn(MyLang('common.delete_success'), 0, self::UserGoodsCartTotal($params));
|
||||
}
|
||||
return DataReturn(MyLang('common.delete_fail'), -100);
|
||||
}
|
||||
}
|
||||
?>
|
||||
262
app/service/GoodsSpecService.php
Normal file
262
app/service/GoodsSpecService.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\service;
|
||||
|
||||
use think\facade\Db;
|
||||
use app\service\GoodsService;
|
||||
|
||||
/**
|
||||
* 商品规格服务层
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2020-11-27
|
||||
* @desc description
|
||||
*/
|
||||
class GoodsSpecService
|
||||
{
|
||||
/**
|
||||
* 商品分类规格模板
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2022-08-25
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsCategorySpecTemplateList($params = [])
|
||||
{
|
||||
// 请求类型
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'category_ids',
|
||||
'error_msg' => '请选择商品分类',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 获取分类下所有分类id
|
||||
$data = [];
|
||||
$ids = GoodsService::GoodsCategoryParentIds($params['category_ids']);
|
||||
if(!empty($ids))
|
||||
{
|
||||
$where = [
|
||||
['category_id', 'in', $ids],
|
||||
['is_enable', '=', 1],
|
||||
];
|
||||
$data = self::GoodsSpecTemplateListHandle(Db::name('GoodsSpecTemplate')->where($where)->field('id,name,content')->order('id desc')->select()->toArray());
|
||||
}
|
||||
return DataReturn(MyLang('common.operate_success'), 0, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据处理
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2022-08-01
|
||||
* @desc description
|
||||
* @param [array] $data [数据列表]
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecTemplateListHandle($data, $params = [])
|
||||
{
|
||||
if(!empty($data))
|
||||
{
|
||||
foreach($data as &$v)
|
||||
{
|
||||
// 时间
|
||||
if(array_key_exists('add_time', $v))
|
||||
{
|
||||
$v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
|
||||
}
|
||||
if(array_key_exists('upd_time', $v))
|
||||
{
|
||||
$v['upd_time'] = empty($v['upd_time']) ? '' : date('Y-m-d H:i:s', $v['upd_time']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-12-18
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecTemplateSave($params = [])
|
||||
{
|
||||
// 请求类型
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'category_id',
|
||||
'error_msg' => '请选择商品分类',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'length',
|
||||
'key_name' => 'name',
|
||||
'checked_data' => '1,30',
|
||||
'error_msg' => '规格名称格式2~30个字符',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'content',
|
||||
'error_msg' => '请填写规格值',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 数据
|
||||
$data = [
|
||||
'category_id' => intval($params['category_id']),
|
||||
'name' => $params['name'],
|
||||
'content' => $params['content'],
|
||||
'is_enable' => isset($params['is_enable']) ? intval($params['is_enable']) : 0,
|
||||
];
|
||||
|
||||
// 保存处理钩子
|
||||
$hook_name = 'plugins_service_goods_spec_template_save_handle';
|
||||
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
|
||||
'hook_name' => $hook_name,
|
||||
'is_backend' => true,
|
||||
'params' => &$params,
|
||||
'data' => &$data,
|
||||
'data_id' => isset($params['id']) ? intval($params['id']) : 0,
|
||||
]));
|
||||
if(isset($ret['code']) && $ret['code'] != 0)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// 捕获异常
|
||||
try {
|
||||
// 添加/编辑
|
||||
if(empty($params['id']))
|
||||
{
|
||||
$data['add_time'] = time();
|
||||
$template_id = Db::name('GoodsSpecTemplate')->insertGetId($data);
|
||||
if($template_id <= 0)
|
||||
{
|
||||
throw new \Exception('添加失败');
|
||||
}
|
||||
} else {
|
||||
$data['upd_time'] = time();
|
||||
if(Db::name('GoodsSpecTemplate')->where(['id'=>intval($params['id'])])->update($data) === false)
|
||||
{
|
||||
throw new \Exception('更新失败');
|
||||
} else {
|
||||
$template_id = $params['id'];
|
||||
}
|
||||
}
|
||||
|
||||
// 完成
|
||||
return DataReturn(MyLang('common.operate_success'), 0);
|
||||
} catch(\Exception $e) {
|
||||
return DataReturn($e->getMessage(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-12-18
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecTemplateDelete($params = [])
|
||||
{
|
||||
// 参数是否有误
|
||||
if(empty($params['ids']))
|
||||
{
|
||||
return DataReturn('操作id有误', -1);
|
||||
}
|
||||
// 是否数组
|
||||
if(!is_array($params['ids']))
|
||||
{
|
||||
$params['ids'] = explode(',', $params['ids']);
|
||||
}
|
||||
|
||||
// 捕获异常
|
||||
try {
|
||||
// 模板删除
|
||||
if(!Db::name('GoodsSpecTemplate')->where(['id'=>$params['ids']])->delete())
|
||||
{
|
||||
throw new \Exception('模板删除失败');
|
||||
}
|
||||
|
||||
// 完成
|
||||
return DataReturn(MyLang('common.delete_success'), 0);
|
||||
} catch(\Exception $e) {
|
||||
return DataReturn($e->getMessage(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态更新
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-12-18
|
||||
* @desc description
|
||||
* @param [array] $params [输入参数]
|
||||
*/
|
||||
public static function GoodsSpecTemplateStatusUpdate($params = [])
|
||||
{
|
||||
// 请求参数
|
||||
$p = [
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'id',
|
||||
'error_msg' => '操作id有误',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'empty',
|
||||
'key_name' => 'field',
|
||||
'error_msg' => '未指定操作字段',
|
||||
],
|
||||
[
|
||||
'checked_type' => 'in',
|
||||
'key_name' => 'state',
|
||||
'checked_data' => [0,1],
|
||||
'error_msg' => '状态有误',
|
||||
],
|
||||
];
|
||||
$ret = ParamsChecked($params, $p);
|
||||
if($ret !== true)
|
||||
{
|
||||
return DataReturn($ret, -1);
|
||||
}
|
||||
|
||||
// 数据更新
|
||||
if(Db::name('GoodsSpecTemplate')->where(['id'=>intval($params['id'])])->update([$params['field']=>intval($params['state']), 'upd_time'=>time()]))
|
||||
{
|
||||
return DataReturn(MyLang('common.operate_success'), 0);
|
||||
}
|
||||
return DataReturn(MyLang('common.operate_fail'), -100);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -12,7 +12,7 @@ namespace app\service;
|
||||
|
||||
use think\facade\Db;
|
||||
use app\service\SystemService;
|
||||
use app\service\BuyService;
|
||||
use app\service\GoodsCartService;
|
||||
use app\service\MessageService;
|
||||
use app\service\OrderService;
|
||||
use app\service\GoodsService;
|
||||
@ -648,7 +648,7 @@ class NavigationService
|
||||
if(!empty($params['user']))
|
||||
{
|
||||
// 购物车商品总数
|
||||
$common_cart_total = BuyService::UserCartTotal(['user'=>$params['user']]);
|
||||
$common_cart_total = GoodsCartService::UserGoodsCartTotal(['user'=>$params['user']]);
|
||||
|
||||
// 未读消息总数
|
||||
$message_params = ['user'=>$params['user'], 'is_more'=>1, 'is_read'=>0, 'user_type'=>'user'];
|
||||
@ -1002,7 +1002,7 @@ class NavigationService
|
||||
if(!empty($params['user']))
|
||||
{
|
||||
// 购物车商品总数
|
||||
$common_cart_total = BuyService::UserCartTotal(['user'=>$params['user']]);
|
||||
$common_cart_total = GoodsCartService::UserGoodsCartTotal(['user'=>$params['user']]);
|
||||
}
|
||||
|
||||
// 列表
|
||||
|
||||
@ -584,7 +584,7 @@ class ResourcesService
|
||||
'<td',
|
||||
];
|
||||
$replace = [
|
||||
'<img style="max-width:100%;height:100%;margin:0;padding:0;display:block;" ',
|
||||
'<img style="max-width:100%;height:auto;margin:0;padding:0;display:block;" ',
|
||||
'<div',
|
||||
'/div>',
|
||||
'<p style="margin:0;',
|
||||
|
||||
@ -61,7 +61,7 @@ select {height:28px !important;}
|
||||
.t-l {text-align:left;}
|
||||
.t-r {text-align:right;}
|
||||
.o-h { overflow: hidden; }
|
||||
input:hover, select:hover, textarea:hover, .chosen-choices:hover, .chosen-single:hover,.am-tagsinput:hover, button.colorpicker-submit:hover { border-style:solid; border-width:1px; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; border:1px solid #4FACF5 !important; box-shadow:0 0 5px #4FACF5 !important; }
|
||||
input:hover, select:hover, textarea:hover, .chosen-choices:hover, .chosen-single:hover,.am-tagsinput:hover, button.colorpicker-submit:hover { border-style:solid; border-width:1px; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; border:1px solid #4FACF5 !important; -webkit-box-shadow: 0 0 5px #4FACF5 !important; box-shadow:0 0 5px #4FACF5 !important; }
|
||||
.am-input-group-sm > .am-input-group-btn > .am-btn,
|
||||
.am-input-group-sm > .am-form-field,
|
||||
.am-input-group-sm > .am-input-group-label,
|
||||
|
||||
@ -222,4 +222,30 @@ ul li {
|
||||
.spec-quick-td-value .value-item {
|
||||
width: calc(50% - 12px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格模板快捷操作
|
||||
*/
|
||||
#specifications-quick-container {
|
||||
padding: 0;
|
||||
}
|
||||
#specifications-quick-container .chosen-container {
|
||||
min-width: 120px;
|
||||
}
|
||||
#specifications-quick-container .chosen-container-single .chosen-default,
|
||||
#specifications-quick-container .chosen-container-single .chosen-single {
|
||||
border-color: transparent !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
height: 29px;
|
||||
line-height: 29px;
|
||||
}
|
||||
#specifications-quick-container .chosen-container .chosen-drop {
|
||||
border-style: dashed;
|
||||
left: -1px;
|
||||
width: calc(100% + 2px);
|
||||
}
|
||||
#specifications-quick-container:hover .chosen-container .chosen-drop {
|
||||
border-color: #666 !important;
|
||||
}
|
||||
@ -721,4 +721,82 @@ $(function()
|
||||
}
|
||||
$('#parameters-quick-container textarea').val(value || '');
|
||||
});
|
||||
|
||||
// 商品规格模板数据获取、选择商品分类后异步读取
|
||||
var $spec_quick = $('#specifications-quick-container');
|
||||
$('select[name="category_id"]').on('change', function()
|
||||
{
|
||||
var value = $(this).val() || '';
|
||||
$.ajax({
|
||||
url: RequestUrlHandle($spec_quick.data('url')),
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
timeout: 305000,
|
||||
data: {"category_ids": value},
|
||||
success: function(result)
|
||||
{
|
||||
if((result.data || null) != null && result.data.length > 0)
|
||||
{
|
||||
var html = '';
|
||||
for(var i in result.data)
|
||||
{
|
||||
html += '<option value="'+result.data[i]['content']+'">'+result.data[i]['name']+'</option>';
|
||||
}
|
||||
$spec_quick.find('select').append(html);
|
||||
} else {
|
||||
$spec_quick.find('select option').each(function(k, v)
|
||||
{
|
||||
if(k > 0)
|
||||
{
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
$spec_quick.find('select').trigger('chosen:updated');
|
||||
},
|
||||
error: function(xhr, type)
|
||||
{
|
||||
Prompt(HtmlToString(xhr.responseText) || (window['lang_error_text'] || '异常错误'));
|
||||
}
|
||||
});
|
||||
});
|
||||
// 规格模板选择
|
||||
$(document).on('click', '#specifications-quick-container select option, #specifications-quick-container .chosen-container .chosen-results li.active-result', function()
|
||||
{
|
||||
var value = $spec_quick.find('select').val() || null;
|
||||
if(value == null)
|
||||
{
|
||||
Prompt($spec_quick.data('spec-template-tips') || '规格模板数据有误');
|
||||
return false;
|
||||
}
|
||||
value = value.split(',');
|
||||
var name = $spec_quick.find('select').find('option:selected').text();
|
||||
|
||||
// 名称是否已存在
|
||||
var status = true;
|
||||
$('.spec-quick .goods-specifications table tbody tr').each(function()
|
||||
{
|
||||
var temp_name = $(this).find('td:first').find('input').val();
|
||||
if(temp_name == name)
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
});
|
||||
if(!status)
|
||||
{
|
||||
Prompt(($spec_quick.data('spec-template-name-tips') || '相同规格名称已经存在')+'('+name+')');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 模拟点击添加一个规格类型
|
||||
$('.quick-spec-title-add').trigger('click');
|
||||
// 填入规格名称
|
||||
$('.spec-quick .goods-specifications table tbody tr:last td:first input').val(name);
|
||||
// 加入规格值
|
||||
for(var i in value)
|
||||
{
|
||||
$('.spec-quick .goods-specifications table tbody tr:last td:last .quick-spec-value-add').trigger('click');
|
||||
$('.spec-quick .goods-specifications table tbody tr:last td:last .value-item:eq(-2) input').val(value[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,13 +1,20 @@
|
||||
$(function()
|
||||
{
|
||||
/**
|
||||
* url加载
|
||||
*/
|
||||
// 左侧菜单箭头方向回调处理
|
||||
$('#admin-offcanvas li.admin-parent').on('open.collapse.amui', function()
|
||||
{
|
||||
$(this).find('a i').toggleClass('left-menu-more-ico-rotate');
|
||||
}).on('close.collapse.amui', function()
|
||||
{
|
||||
$(this).find('a i').toggleClass('left-menu-more-ico-rotate');
|
||||
});
|
||||
|
||||
// url加载
|
||||
$(document).on('click', '.common-left-menu li a, .common-nav-top li a, .menu-mini-container-popup ul li a', function()
|
||||
{
|
||||
var link = $(this).data('url');
|
||||
var link = $(this).data('url') || null;
|
||||
var type = $(this).data('type');
|
||||
if(link != undefined)
|
||||
if(link != null)
|
||||
{
|
||||
// 打开url地址
|
||||
$('#ifcontent').attr('src', link);
|
||||
@ -28,30 +35,17 @@ $(function()
|
||||
{
|
||||
$('#admin-offcanvas').offCanvas('close');
|
||||
}
|
||||
} else {
|
||||
// 左侧菜单剪头方向处理
|
||||
if(type == 'menu')
|
||||
{
|
||||
if($(this).find('i').length > 0)
|
||||
{
|
||||
$(this).find('i').toggleClass('left-menu-more-ico-rotate');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 菜单选择
|
||||
*/
|
||||
// 菜单选择
|
||||
$('.common-left-menu li a').on('click', function()
|
||||
{
|
||||
$('.common-left-menu a').removeClass('common-left-menu-active');
|
||||
$(this).addClass('common-left-menu-active');
|
||||
});
|
||||
|
||||
/**
|
||||
* mini伸缩开关
|
||||
*/
|
||||
// mini伸缩开关
|
||||
$('.menu-scaling-submit').on('click', function()
|
||||
{
|
||||
var status = $(this).attr('data-status') || 0;
|
||||
@ -60,18 +54,18 @@ $(function()
|
||||
$('.menu-mini-container-tips').hide();
|
||||
if(status == 0)
|
||||
{
|
||||
$(this).animate({left: "59px"}, 300);
|
||||
$(this).animate({left: '59px'}, 300);
|
||||
$(this).removeClass('am-icon-angle-double-left').addClass('am-icon-angle-double-right');
|
||||
$('#admin-offcanvas').addClass('menu-mini').addClass('menu-mini-event');
|
||||
$('#admin-offcanvas').animate({width: "55px"}, 300);
|
||||
$('#ifcontent').animate({paddingLeft: "55px"}, 300);
|
||||
$('header.admin-header').animate({left: "54px"}, 300);
|
||||
$('#admin-offcanvas').animate({width: '55px'}, 300);
|
||||
$('#ifcontent').animate({paddingLeft: '55px'}, 300);
|
||||
$('header.admin-header').animate({left: '54px'}, 300);
|
||||
} else {
|
||||
$(this).animate({left: "164px"}, 300);
|
||||
$(this).animate({left: '164px'}, 300);
|
||||
$(this).removeClass('am-icon-angle-double-right').addClass('am-icon-angle-double-left');
|
||||
$('#admin-offcanvas').animate({width: "160px"}, 300);
|
||||
$('#ifcontent').animate({paddingLeft: "160px"}, 300);
|
||||
$('header.admin-header').animate({left: "159px"}, 300);
|
||||
$('#admin-offcanvas').animate({width: '160px'}, 300);
|
||||
$('#ifcontent').animate({paddingLeft: '160px'}, 300);
|
||||
$('header.admin-header').animate({left: '159px'}, 300);
|
||||
$('#admin-offcanvas').removeClass('menu-mini-event');
|
||||
setTimeout(function() {
|
||||
$('#admin-offcanvas').removeClass('menu-mini');
|
||||
@ -81,9 +75,7 @@ $(function()
|
||||
$(this).attr('data-status', status == 0 ? 1 : 0);
|
||||
});
|
||||
|
||||
/**
|
||||
* mini菜单操作
|
||||
*/
|
||||
// mini菜单操作
|
||||
var timer_menu = null;
|
||||
$(document).on('mouseenter', '.menu-mini-event li', function()
|
||||
{
|
||||
@ -91,29 +83,30 @@ $(function()
|
||||
var html = $(this).find('ul.admin-sidebar-sub').html() || null;
|
||||
var top = $(this).offset().top;
|
||||
var win_height = $(window).height();
|
||||
var $popup = $('.menu-mini-container-popup');
|
||||
var $tips = $('.menu-mini-container-tips');
|
||||
if(html == null)
|
||||
{
|
||||
$('.menu-mini-container-popup').hide();
|
||||
$('.menu-mini-container-tips').show();
|
||||
$('.menu-mini-container-tips').text($(this).find('.nav-name').text());
|
||||
$('.menu-mini-container-tips').css('top', top);
|
||||
$popup.hide();
|
||||
$tips.show();
|
||||
$tips.text($(this).find('.nav-name').text());
|
||||
$tips.css('top', top);
|
||||
} else {
|
||||
$('.menu-mini-container-popup ul').html(html);
|
||||
$('.menu-mini-container-tips').hide();
|
||||
$('.menu-mini-container-popup').show();
|
||||
$popup.find('ul').html(html);
|
||||
$tips.hide();
|
||||
$popup.show();
|
||||
|
||||
// 容器是否超出底部
|
||||
var h = $('.menu-mini-container-popup').height();
|
||||
var h = $popup.height();
|
||||
if(h+top > win_height)
|
||||
{
|
||||
var t = win_height-h;
|
||||
$('.menu-mini-container-popup').css('top', t);
|
||||
$('.menu-mini-container-popup .mui-mbar-tab-tip').css('top', top-t+12);
|
||||
$popup.css('top', t);
|
||||
$popup.find('.mui-mbar-tab-tip').css('top', top-t+12);
|
||||
} else {
|
||||
$('.menu-mini-container-popup').css('top', top);
|
||||
$('.menu-mini-container-popup .mui-mbar-tab-tip').css('top', '10px');
|
||||
$popup.css('top', top);
|
||||
$popup.find('.mui-mbar-tab-tip').css('top', '10px');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
$(document).on('mouseleave', '.menu-mini-event li', function()
|
||||
@ -139,9 +132,7 @@ $(function()
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
/**
|
||||
* mini菜单选择
|
||||
*/
|
||||
// mini菜单选择
|
||||
$(document).on('click', '.menu-mini-container-popup ul li a', function()
|
||||
{
|
||||
$('.admin-sidebar-list li a').removeClass('common-left-menu-active');
|
||||
@ -162,18 +153,18 @@ $(function()
|
||||
if($(document).width() <= 640)
|
||||
{
|
||||
$('.menu-scaling-submit').attr('data-status', 0);
|
||||
$('.menu-scaling-submit').css({"left": "164px"});
|
||||
$('.menu-scaling-submit').css({'left': '164px'});
|
||||
$('.menu-scaling-submit').removeClass('am-icon-angle-double-right').addClass('am-icon-angle-double-left');
|
||||
$('#admin-offcanvas').css({"width": "inherit"});
|
||||
$('#admin-offcanvas').css({'width': 'inherit'});
|
||||
$('#admin-offcanvas').removeClass('menu-mini').removeClass('menu-mini-event');
|
||||
$('#ifcontent').css({"padding-left":0});
|
||||
$('header.admin-header').css({"left": 0});
|
||||
$('#ifcontent').css({'padding-left':0});
|
||||
$('header.admin-header').css({'left': 0});
|
||||
} else {
|
||||
if(($('.menu-scaling-submit').attr('data-status') || 0) == 0)
|
||||
{
|
||||
$('#admin-offcanvas').css({"width": "160px"});
|
||||
$('#ifcontent').css({"padding-left":"160px"});
|
||||
$('header.admin-header').css({"left": "159px"});
|
||||
$('#admin-offcanvas').css({'width': '160px'});
|
||||
$('#ifcontent').css({'padding-left':'160px'});
|
||||
$('header.admin-header').css({'left': '159px'});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -104,11 +104,13 @@ form.am-form .am-form-group-refreshing,
|
||||
.plug-file-upload-view {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
form.am-form-full-screen .am-form-group,
|
||||
form.am-form-full-screen .plug-file-upload-view,
|
||||
form.am-form-full-screen .business-form-group,
|
||||
form.am-form-full-screen .business-form-block {
|
||||
padding-right: 5px !important;
|
||||
@media only screen and (min-width: 641px) {
|
||||
form.am-form-full-screen .am-form-group,
|
||||
form.am-form-full-screen .plug-file-upload-view,
|
||||
form.am-form-full-screen .business-form-group,
|
||||
form.am-form-full-screen .business-form-block {
|
||||
padding-right: 5px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user