新增用户商品购物车查看、新增商品规格模板

This commit is contained in:
gongfuxiang
2022-08-25 18:13:28 +08:00
parent 5143490563
commit 002fe9538d
35 changed files with 1797 additions and 655 deletions

View File

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

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

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

View 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;
}
}
?>

View 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',
],
],
];
}
}
?>

View File

@ -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}}

View File

@ -4,9 +4,21 @@
<div class="am-alert am-alert-warning am-radius" data-am-alert>
<button type="button" class="am-close">&times;</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}}>

View File

@ -0,0 +1,2 @@
<!-- 继承公共的 form -->
{{extend name="public/module/detail" /}}

View File

@ -0,0 +1,2 @@
<!-- 继承公共的 form -->
{{extend name="public/module/form" /}}

View 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}}

View 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>

View File

@ -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}}

View File

@ -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>

View File

@ -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 -->

View File

@ -0,0 +1,2 @@
<!-- 继承公共的 form -->
{{extend name="public/module/detail" /}}

View 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}}

View 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>

View 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 -->

View File

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

View File

@ -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,

View File

@ -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];

View File

@ -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]),
);
// 返回数据

View File

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

View File

@ -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'];
// 收藏商品

View File

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

View File

@ -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

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

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

View File

@ -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']]);
}
// 列表

View File

@ -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;',

View File

@ -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,

View File

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

View File

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

View File

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

View File

@ -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;
}
}
/**