提交 c465b614 编写于 作者: D devil

商品参数管理,部分bug修复,细节优化

上级 9301c54e
......@@ -244,8 +244,17 @@ class Common extends Controller
$module_js .= file_exists(ROOT_PATH.'static'.DS.$module_js.'.'.$this->action_name.'.js') ? '.'.$this->action_name.'.js' : '.js';
$this->assign('module_js', file_exists(ROOT_PATH.'static'.DS.$module_js) ? $module_js : '');
// 图片host地址
$this->assign('attachment_host', config('shopxo.attachment_host'));
// 附件host地址
$this->assign('attachment_host', config('shopxo.attachment_host'));
// css/js引入host地址
$this->assign('public_host', config('shopxo.public_host'));
// 当前url地址
$this->assign('my_url', __MY_URL__);
// 当前http类型
$this->assign('my_http', __MY_HTTP__);
// 开发模式
$this->assign('shopxo_is_develop', config('shopxo.is_develop'));
......
......@@ -100,13 +100,32 @@ class Goods extends Common
// 获取列表
$data_params = [
'm' => 0,
'n' => 1,
'where' => $where,
'is_category' => 1,
'm' => 0,
'n' => 1,
'where' => $where,
'is_photo' => 1,
'is_content_app' => 1,
'is_category' => 1,
];
$ret = GoodsService::GoodsList($data_params);
$data = (empty($ret['data']) || empty($ret['data'][0])) ? [] : $ret['data'][0];
$data = [];
if(!empty($ret['data']) && !empty($ret['data'][0]))
{
$data = $ret['data'][0];
// 获取商品编辑规格
$specifications = GoodsService::GoodsEditSpecifications($data['id']);
$this->assign('specifications', $specifications);
// 获取商品编辑参数
$parameters = GoodsService::GoodsEditParameters($data['id']);
// 商品参数类型
$this->assign('common_goods_parameters_type_list', lang('common_goods_parameters_type_list'));
$this->assign('parameters', $parameters);
}
$this->assign('data', $data);
}
return $this->fetch();
......@@ -152,7 +171,11 @@ class Goods extends Common
// 获取商品编辑规格
$specifications = GoodsService::GoodsEditSpecifications($ret['data'][0]['id']);
$this->assign('specifications', $specifications);
$this->assign('specifications', $specifications);
// 获取商品编辑参数
$parameters = GoodsService::GoodsEditParameters($ret['data'][0]['id']);
$this->assign('parameters', $parameters);
}
// 地区信息
......@@ -173,6 +196,9 @@ class Goods extends Common
// 当前系统设置的站点类型
$this->assign('common_site_type', MyC('common_site_type', 0, true));
// 商品参数类型
$this->assign('common_goods_parameters_type_list', lang('common_goods_parameters_type_list'));
// 是否拷贝
$this->assign('is_copy', (isset($params['is_copy']) && $params['is_copy'] == 1) ? 1 : 0);
......
......@@ -182,6 +182,16 @@ class Orderaftersale
'where_type' => 'like',
],
],
[
'label' => '拒绝原因',
'view_type' => 'field',
'view_key' => 'refuse_reason',
'grid_size' => 'sm',
'search_config' => [
'form_type' => 'input',
'where_type' => 'like',
],
],
[
'label' => '申请时间',
'view_type' => 'field',
......
......@@ -5,13 +5,161 @@
{{block name="detail_data"}}
<!-- 父级内容 -->
{__block__}
<!-- 商品视频 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品视频</div>
<div class="am-panel-bd">
{{if !empty($data['video'])}}
<video src="{{$data.video}}" class="am-img-responsive" controls="controls" preload="auto">
your browser does not support the video tag
</video>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 商品相册 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品相册</div>
<div class="am-panel-bd">
{{if !empty($data['photo']) and is_array($data['photo'])}}
<div class="am-scrollable-vertical am-nowrap-initial">
<div data-am-widget="slider" class="am-slider am-slider-default" data-am-slider='{"animation":"slide","animationLoop":false,"itemWidth":200,"itemMargin":5}'>
<ul class="am-slides">
{{foreach $data.photo as $v}}
<li>
<a href="{{$v.images}}" target="_blank">
<img src="{{$v.images}}" height="225" />
</a>
</li>
{{/foreach}}
</ul>
</div>
</div>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 商品规格 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品规格</div>
<div class="am-panel-bd">
{{if !empty($specifications) and is_array($specifications)}}
<div class="am-scrollable-vertical am-scrollable-horizontal">
<table class="am-table am-table-bordered am-table-striped am-text-nowrap">
<thead>
<tr>
{{foreach $specifications.type as $line_k=>$line_v}}
<th>{{$line_v.name}}</th>
{{/foreach}}
<th>销售金额</th>
<th>重量</th>
<th>编码</th>
<th>条形码</th>
<th>原价</th>
</tr>
</thead>
<tbody>
{{foreach $specifications.value as $line_k=>$line_v}}
<tr>
{{foreach $line_v as $v}}
{{if isset($v['data_type'])}}
{{switch v.data_type}}
{{case spec}}
<td class="am-text-middle">{{$v.data.value}}</td>
{{/case}}
{{case base}}
<td class="am-text-middle">{{$v.data.price}}</td>
<td class="am-text-middle">{{if $v['data']['weight'] gt 0}}{{$v.data.weight}}{{/if}}</td>
<td class="am-text-middle">{{$v.data.coding}}</td>
<td class="am-text-middle">{{$v.data.barcode}}</td>
<td class="am-text-middle">{{if $v['data']['original_price'] gt 0}}{{$v.data.original_price}}{{/if}}</td>
{{/case}}
{{/switch}}
{{/if}}
{{/foreach}}
</tr>
{{/foreach}}
</tbody>
</table>
</div>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 商品规格图片 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品规格图片</div>
<div class="am-panel-bd am-padding-xs">
{{if !empty($specifications) and is_array($specifications)}}
<div class="am-scrollable-vertical">
<ul data-am-widget="gallery" class="am-gallery am-avg-sm-2 am-avg-md-4 am-avg-lg-6 am-gallery-bordered am-padding-0">
{{foreach $specifications.type as $line_k=>$line_v}}
{{foreach $line_v.value as $v}}
{{if !empty($v['images'])}}
<li>
<div class="am-gallery-item">
<a href="{{$v.images}}" target="_blank">
<img src="{{$v.images}}" alt="{{$v.name}}"/>
<h3 class="am-gallery-title am-text-center">{{$v.name}}</h3>
</a>
</div>
</li>
{{/if}}
{{/foreach}}
{{/foreach}}
</ul>
</div>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 商品参数 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">商品参数</div>
<div class="am-panel-bd">
{{if !empty($parameters) and is_array($parameters)}}
<div class="am-scrollable-vertical am-scrollable-horizontal">
<table class="am-table am-table-bordered am-table-striped am-text-nowrap">
<thead>
<tr>
<th>展示范围</th>
<th>参数名称</th>
<th>参数值</th>
</tr>
</thead>
<tbody>
{{foreach $parameters as $v}}
<tr>
<td class="am-text-middle">{{if isset($common_goods_parameters_type_list[$v['type']])}}{{$common_goods_parameters_type_list[$v['type']]['name']}}{{/if}}</td>
<td class="am-text-middle">{{$v.name}}</td>
<td class="am-text-middle">{{$v.value}}</td>
</tr>
{{/foreach}}
</tbody>
</table>
</div>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 电脑端详情 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">电脑端详情</div>
<div class="am-panel-bd">
{{if !empty($data['content_web'])}}
<div class="am-scrollable-vertical am-nowrap-initial">
<div class="am-scrollable-vertical am-nowrap-initial am-img-responsive">
{{$data.content_web|raw}}
</div>
{{else /}}
......@@ -20,12 +168,41 @@
</div>
</div>
<!-- 手机端详情 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">手机端详情</div>
<div class="am-panel-bd">
{{if !empty($data['content_app']) and is_array($data['content_app'])}}
<div class="am-scrollable-vertical am-nowrap-initial am-img-responsive">
<ul>
{{foreach $data.content_app as $v}}
<li class="am-margin-bottom-sm">
<a href="{{$v.images}}" target="_blank">
<img src="{{$v.images}}" />
</a>
{{if !empty($v['content']) and is_array($v['content'])}}
<div class="am-margin-top-sm">
{{foreach $v.content as $text}}
<p>{{$text}}</p>
{{/foreach}}
</div>
{{/if}}
</li>
{{/foreach}}
</ul>
</div>
{{else /}}
<div class="table-no"><i class="am-icon-warning"></i> 没有相关数据</div>
{{/if}}
</div>
</div>
<!-- 虚拟商品展示数据 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">虚拟商品展示数据</div>
<div class="am-panel-bd">
{{if !empty($data['fictitious_goods_value'])}}
<div class="am-scrollable-vertical am-nowrap-initial">
<div class="am-scrollable-vertical am-nowrap-initial am-img-responsive">
{{$data.fictitious_goods_value|raw}}
</div>
{{else /}}
......
......@@ -18,6 +18,9 @@
<li>
<a href="javascript:;" data-value="#goods-nav-operations">商品规格</a>
</li>
<li>
<a href="javascript:;" data-value="#goods-nav-parameters">商品参数</a>
</li>
<li>
<a href="javascript:;" data-value="#goods-nav-photo">商品相册</a>
</li>
......@@ -25,10 +28,10 @@
<a href="javascript:;" data-value="#goods-nav-video">商品视频</a>
</li>
<li>
<a href="javascript:;" data-value="#goods-nav-app">手机详情</a>
<a href="javascript:;" data-value="#goods-nav-app">手机详情</a>
</li>
<li>
<a href="javascript:;" data-value="#goods-nav-web">电脑详情</a>
<a href="javascript:;" data-value="#goods-nav-web">电脑详情</a>
</li>
<li>
<a href="javascript:;" data-value="#goods-nav-fictitious">虚拟商品</a>
......@@ -52,7 +55,7 @@
<label>标题名称</label>
<div class="am-input-group am-input-group-sm">
<input type="hidden" name="title_color" value="{{if !empty($data['title_color'])}}{{$data.title_color}}{{/if}}" />
<input type="text" name="title" placeholder="标题名称" minlength="2" maxlength="60" data-validation-message="标题名称格式 2~60 个字符" class="am-form-field am-radius" {{if !empty($data)}} value="{{$data.title}}" {{/if}} {{if !empty($data['title_color'])}} style="color:{{$data.title_color}};" {{/if}} required />
<input type="text" name="title" placeholder="标题名称" minlength="2" maxlength="160" data-validation-message="标题名称格式 2~160 个字符" class="am-form-field am-radius" {{if !empty($data)}} value="{{$data.title}}" {{/if}} {{if !empty($data['title_color'])}} style="color:{{$data.title_color}};" {{/if}} required />
<span class="am-input-group-btn">
<button type="button" class="am-btn am-btn-default am-btn-xs colorpicker-submit" data-input-tag="input[name='title']" data-color-tag="input[name='title_color']">
<img src="{{$attachment_host}}/static/common/images/colorpicker.png" />
......@@ -62,7 +65,7 @@
</div>
<div class="am-form-group">
<label>商品简述</label>
<input type="text" name="simple_desc" placeholder="商品简述" maxlength="160" data-validation-message="商品简述格式 最多160个字符" class="am-radius" {{if !empty($data)}} value="{{$data.simple_desc}}"{{/if}} />
<input type="text" name="simple_desc" placeholder="商品简述" maxlength="230" data-validation-message="商品简述格式 最多230个字符" class="am-radius" {{if !empty($data)}} value="{{$data.simple_desc}}"{{/if}} />
</div>
<div class="am-form-group">
<label>商品型号</label>
......@@ -226,7 +229,7 @@
<!-- 规格常规操作 -->
<span class="business-operations-submit specifications-nav-title-add">+添加规格</span>
<span class="business-operations-submit am-margin-left-sm specifications-nav-set-all am-icon-cogs" data-am-modal="{target: '#spec-popup-all-operation'}"> 高级批量设置</span>
<div class="goods-specifications business-form-group am-padding-top-sm">
<div class="goods-specifications business-form-group am-form-group-refreshing am-padding-top-sm">
<!-- 所有规格批量操作弹层 -->
<div class="am-popup" id="spec-popup-all-operation">
<div class="am-popup-inner">
......@@ -268,7 +271,7 @@
<div class="am-modal am-modal-no-btn" tabindex="-1" id="spec-modal-all-operation">
<div class="am-modal-dialog">
<div class="am-modal-hd">批量操作
<a href="javascript: void(0)" class="am-close am-close-spin" data-am-modal-close>&times;</a>
<a href="javascript: void(0)" class="am-close" data-am-modal-close>&times;</a>
</div>
<div class="am-modal-bd">
<div class="am-input-group am-input-group-sm">
......@@ -320,26 +323,26 @@
<tbody>
{{if empty($specifications['value'])}}
<tr class="line-0" data-line-tag=".line-0">
<td class="value-start">
<td class="am-text-middle value-start">
<input type="text" name="specifications_price[]" placeholder="价格" class="am-radius" pattern="^([0-9]{1}\d{0,6})(\.\d{1,2})?$" data-validation-message="请填写有效的销售金额" required />
</td>
<td>
<td class="am-text-middle">
<input type="number" name="specifications_weight[]" placeholder="重量" class="am-radius" maxlength="80" min="0.00" max="100000000.00" step="0.01" data-validation-message="规格重量 0.00~100000000.00" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_coding[]" placeholder="编码" class="am-radius" maxlength="80" data-validation-message="规格编码最多80个字符" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_barcode[]" placeholder="条形码" class="am-radius" maxlength="80" data-validation-message="条形码最多80个字符" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_original_price[]" placeholder="原价" class="am-radius" pattern="^([0-9]{1}\d{0,6})(\.\d{1,2})?$" data-validation-message="请填写有效的原价" />
</td>
<td>
<td class="am-text-middle">
<input type="hidden" name="specifications_extends[]" value="" class="line-extend-input" />
<span class="am-text-xs cr-blue c-p line-extend-btn">编辑</span>
</td>
<td>
<td class="am-text-middle">
<!--operation-->
</td>
</tr>
......@@ -352,32 +355,32 @@
{{if isset($v['data_type'])}}
{{switch v.data_type}}
{{case spec}}
<td class="table-value table-value-{{$v.data.key}}">
<td class="am-text-middle table-value table-value-{{$v.data.key}}">
<input type="text" name="specifications_value_{{$v.data.key}}[]" placeholder="规格值" value="{{$v.data.value}}" data-validation-message="请填写规格值" required />
</td>
{{/case}}
{{case base}}
<td class="value-start">
<td class="am-text-middle value-start">
<input type="text" name="specifications_price[]" placeholder="价格" class="am-radius" pattern="^([0-9]{1}\d{0,6})(\.\d{1,2})?$" data-validation-message="请填写有效的销售金额" value="{{$v.data.price}}" required />
</td>
<td>
<td class="am-text-middle">
<input type="number" name="specifications_weight[]" placeholder="重量" class="am-radius" min="0.00" max="100000000.00" step="0.01" data-validation-message="规格重量 0.00~100000000.00" value="{{if $v['data']['weight'] gt 0}}{{$v.data.weight}}{{/if}}" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_coding[]" placeholder="编码" class="am-radius" maxlength="80" data-validation-message="规格编码最多80个字符" value="{{$v.data.coding}}" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_barcode[]" placeholder="条形码" class="am-radius" maxlength="80" data-validation-message="条形码最多80个字符" value="{{$v.data.barcode}}" />
</td>
<td>
<td class="am-text-middle">
<input type="text" name="specifications_original_price[]" placeholder="原价" class="am-radius" pattern="^([0-9]{1}\d{0,6})(\.\d{1,2})?$" data-validation-message="请填写有效的原价" value="{{if $v['data']['original_price'] gt 0}}{{$v.data.original_price}}{{/if}}" />
</td>
<td>
<td class="am-text-middle">
<input type="hidden" name="specifications_extends[]" value="{{$v.data.extends}}" class="line-extend-input" />
<span class="am-text-xs cr-blue c-p line-extend-btn">编辑</span>
</td>
<td>
<td class="am-text-middle">
{{if $line_k gt 0}}
<span class="am-text-xs cr-blue c-p am-margin-right-xs line-copy">复制</span>
<span class="am-text-xs cr-red c-p line-remove">移除</span>
......@@ -426,6 +429,95 @@
</div>
</div>
<!-- 参数 -->
<div id="goods-nav-parameters" class="division-block">
<label class="block nav-detail-title">商品参数</label>
<div class="am-alert am-alert-warning am-radius" data-am-alert="">
<p>1. 展示范围</p>
<div class="am-padding-left-sm">
<p>1.1 全部(在商品基础信息和详情参数下都展示)</p>
<p>1.2 详情(仅在商品详情参数下都展示)</p>
<p>1.3 基础(仅在商品基础信息下都展示)</p>
</div>
<p>2. 快捷操作将会清除原来的数据、重载页面便可恢复原来的数据(仅保存商品后生效)</p>
</div>
<!-- 通过配置生成商品参数 -->
<div class="am-dropdown" id="parameters-quick-container" data-am-dropdown>
<span class="business-operations-submit am-dropdown-toggle parameters-quick-add">
<span>快捷操作</span>
<i class="am-icon-caret-down"></i>
</span>
<div class="am-dropdown-content parameters-quick-config">
<textarea rows="5" placeholder="粘贴商品参数配置信息"></textarea>
<button type="button" class="am-btn am-btn-secondary am-btn-xs am-radius am-btn-block am-margin-top-sm">确认</button>
</div>
</div>
<!-- 复制操作 -->
<span class="business-operations-submit am-margin-left-sm parameters-quick-copy">
<i class="am-icon-copy"></i>
<span>复制配置</span>
</span>
<!-- 复制弹窗、仅复制操作失败的时候显示让用户手动复制 -->
<div class="am-modal am-modal-no-btn" tabindex="-1" id="parameters-quick-copy-modal">
<div class="am-modal-dialog">
<div class="am-modal-hd">
<a href="javascript: void(0)" class="am-close" data-am-modal-close>&times;</a>
</div>
<div class="am-modal-bd">
<div class="am-padding-sm">
<textarea rows="5" placeholder="商品参数配置信息"></textarea>
</div>
</div>
</div>
</div>
<!-- 清空操作 -->
<span class="business-operations-submit am-margin-left-sm parameters-quick-remove">
<i class="am-icon-times"></i>
<span>清空参数</span>
</span>
<div class="parameters-content business-form-group am-form-group-refreshing am-padding-top-0 am-margin-top-sm">
<table class="am-table am-table-bordered am-table-centered am-table-striped am-table-hover am-margin-bottom-sm parameters-table">
<thead>
<tr>
<th class="spec-quick-th-title">展示范围</th>
<th class="spec-quick-th-title">参数名称</th>
<th class="spec-quick-th-value">参数值</th>
<th class="spec-quick-th-value">操作</th>
</tr>
</thead>
<tbody>
{{if !empty($parameters)}}
{{foreach $parameters as $pv}}
<tr>
<td class="am-text-middle">
<select name="parameters_type[]" class="am-radius chosen-select" data-validation-message="请选择商品参数展示类型">
{{if !empty($common_goods_parameters_type_list)}}
{{foreach $common_goods_parameters_type_list as $v}}
<option value="{{$v.value}}" {{if $pv['type'] eq $v['value']}}selected{{/if}}>{{$v.name}}</option>
{{/foreach}}
{{/if}}
</select>
</td>
<td class="am-text-middle">
<input type="text" name="parameters_name[]" placeholder="参数名称" value="{{$pv.name}}" data-validation-message="请填写参数名称" maxlength="160" required />
</td>
<td class="am-text-middle">
<input type="text" name="parameters_value[]" placeholder="参数值" value="{{$pv.value}}" maxlength="200" data-validation-message="请填写参数值" />
</td>
<td class="am-text-middle">
<span class="am-text-xs cr-blue c-p am-margin-right-sm line-move" data-type="top">上移</span>
<span class="am-text-xs cr-blue c-p am-margin-right-sm line-move" data-type="bottom">下移</span>
<span class="am-text-xs cr-red c-p line-remove">移除</span>
</td>
</tr>
{{/foreach}}
{{/if}}
</tbody>
</table>
<span class="business-operations-submit parameters-line-add">+添加一行</span>
</div>
</div>
<!-- 相册 -->
<div id="goods-nav-photo" class="division-block">
<label class="block nav-detail-title">商品相册<span class="am-form-group-label-tips">可拖拽图片进行排序,建议图片尺寸一致</span></label>
......@@ -446,7 +538,7 @@
<!-- 视频 -->
<div id="goods-nav-video" class="division-block">
<label class="block nav-detail-title">商品视频</label>
<div class="am-form-group am-form-file">
<div class="am-form-group am-form-file am-form-group-refreshing">
<label class="block">短视频<span class="am-form-group-label-tips">视频比图文更有具带入感,仅支持 mp4 格式</span></label>
<ul class="plug-file-upload-view plug-file-upload-view-video goods-video-view" data-form-name="video" data-max-number="1" data-dialog-type="video">
{{if !empty($data['video'])}}
......@@ -463,8 +555,8 @@
<!-- app内容 -->
<div id="goods-nav-app" class="division-block">
<label class="block nav-detail-title">手机详情</label>
<ul class="content-app-items business-form-group" data-max-count="10" data-required="1" data-images-name="content_app_images" data-content-name="content_app_text" data-images-text="图片" data-content-text="文本内容" data-delete-text="删除" data-drag-sort-text="拖拽排序">
<label class="block nav-detail-title">手机详情</label>
<ul class="content-app-items business-form-group am-form-group-refreshing" data-max-count="10" data-required="1" data-images-name="content_app_images" data-content-name="content_app_text" data-images-text="图片" data-content-text="文本内容" data-delete-text="删除" data-drag-sort-text="拖拽排序">
{{if !empty($data['content_app'])}}
{{foreach $data.content_app as $v}}
<li>
......@@ -498,8 +590,8 @@
<!-- web内容 -->
<div id="goods-nav-web" class="division-block">
<label class="block nav-detail-title">电脑详情</label>
<div class="am-form-group">
<label class="block nav-detail-title">电脑详情</label>
<div class="am-form-group am-form-group-refreshing">
<textarea class="am-radius am-validate" name="content_web" maxlength="105000" id="editor-tag" data-validation-message="电脑端详情内容最多 105000 个字符">{{if !empty($data)}}{{$data.content_web}}{{/if}}</textarea>
</div>
</div>
......
......@@ -7,7 +7,7 @@
<div class="am-modal am-modal-no-btn" tabindex="-1" id="order-take-modal">
<div class="am-modal-dialog">
<div class="am-modal-hd">
<a href="javascript: void(0)" class="am-close am-close-spin" data-am-modal-close>&times;</a>
<a href="javascript: void(0)" class="am-close" data-am-modal-close>&times;</a>
</div>
<div class="am-modal-bd">
<form class="am-form form-validation-take take-form" method="post" action="{{:MyUrl('admin/order/delivery')}}" request-type="ajax-reload">
......
<!-- 订单商品信息 -->
{{if !empty($module_data) and !empty($module_data['items'])}}
{{if $module_data['pay_status'] eq 1 and $module_data['pay_price'] lt $module_data['total_price']}}
<p class="am-text-danger am-animation-shake am-animation-delay-1">
<i class="am-icon-warning am-text-lg"></i>
<span class="am-text-lg">请注意、该订单支付金额小于总价金额</span>
</p>
<hr data-am-widget="divider" class="am-divider am-divider-dashed" />
{{/if}}
<p class="am-nbfc am-margin-bottom-sm">
<strong class="am-icon-bookmark-o"> {{$module_data.order_no}}</strong>
<strong class="am-icon-circle-thin am-margin-left-lg"> {{$module_data.id}}</strong>
......
......@@ -59,7 +59,7 @@
<div class="am-modal am-modal-no-btn" tabindex="-1" id="plugins-delete-modal">
<div class="am-modal-dialog">
<div class="am-modal-hd">
<a href="javascript: void(0)" class="am-close am-close-spin" data-am-modal-close>&times;</a>
<a href="javascript: void(0)" class="am-close" data-am-modal-close>&times;</a>
</div>
<div class="am-modal-bd am-margin-top-sm">
<div class="am-alert am-text-left" data-am-alert>
......
......@@ -14,38 +14,41 @@
</html>
<!-- 类库 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/jquery/jquery-2.1.0.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/assets/js/amazeui.min.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/jquery/jquery-2.1.0.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/assets/js/amazeui.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- echarts 图表 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/echarts/echarts.min.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/echarts/macarons.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/echarts/echarts.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/echarts/macarons.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- ueditor 编辑器 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/ueditor/ueditor.config.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/ueditor/ueditor.all.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/ueditor/lang/zh-cn/zh-cn.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/ueditor/ueditor.config.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/ueditor/ueditor.all.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/ueditor/lang/zh-cn/zh-cn.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 颜色选择器 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/colorpicker/jquery.colorpicker.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/colorpicker/jquery.colorpicker.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 元素拖拽排序插件 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/dragsort/jquery.dragsort-0.5.2.min.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/dragsort/jquery.dragsort-0.5.2.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 动画数数 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/animation-count-to/animation.count.to.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/animation-count-to/animation.count.to.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- amazeui插件 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-switch/amazeui.switch.min.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-chosen/amazeui.chosen.min.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-dialog/amazeui.dialog.js"></script>
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-tagsinput/amazeui.tagsinput.min.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/amazeui-switch/amazeui.switch.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/amazeui-chosen/amazeui.chosen.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/amazeui-dialog/amazeui.dialog.js?v={{:MyC('home_static_cache_version')}}"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/amazeui-tagsinput/amazeui.tagsinput.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 日期组件 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/My97DatePicker/WdatePicker.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/My97DatePicker/WdatePicker.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 元素拖动 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/tdrag/tdrag.min.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/lib/tdrag/tdrag.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 复制插件 -->
<script type='text/javascript' src="{{$public_host}}static/common/lib/clipboard/clipboard.min.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- baidu map -->
{{if isset($is_load_baidu_map_api) and $is_load_baidu_map_api eq 1}}
......@@ -68,27 +71,35 @@
</script>
<!-- 项目公共 -->
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/common/js/common.js"></script>
<script type='text/javascript' src="{{$public_host}}static/common/js/common.js?v={{:MyC('home_static_cache_version')}}"></script>
<!-- 应用插件公共js -->
{{if !empty($plugins_js)}}
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/{{$plugins_js}}"></script>
<script type='text/javascript' src="{{$public_host}}static/{{$plugins_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
<!-- 当前控制器js -->
{{if !empty($module_js)}}
<script type='text/javascript' src="{{$Think.__MY_ROOT_PUBLIC__}}static/{{$module_js}}"></script>
<script type='text/javascript' src="{{$public_host}}static/{{$module_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
<!-- js钩子 -->
{{if !empty($plugins_admin_js_data) and is_array($plugins_admin_js_data)}}
{{foreach $plugins_admin_js_data as $hook}}
{{if is_string($hook)}}
<script type='text/javascript' src="{{$hook}}"></script>
{{if substr($hook_js, 0, 4) eq 'http'}}
<script type='text/javascript' src="{{$hook_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{else /}}
<script type='text/javascript' src="{{$public_host}}{{$hook}}?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
{{elseif is_array($hook) /}}
{{foreach $hook as $hook_js}}
{{if is_string($hook_js)}}
<script type='text/javascript' src="{{$hook_js}}"></script>
{{if substr($hook_js, 0, 4) eq 'http'}}
<script type='text/javascript' src="{{$hook_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{else /}}
<script type='text/javascript' src="{{$public_host}}{{$hook_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
{{/if}}
{{/foreach}}
{{/if}}
......
......@@ -2,32 +2,40 @@
<html>
<head>
<meta charset="{{:config('shopxo.default_charset', 'utf-8')}}" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
<link rel="shortcut icon" type="image/x-icon" href="{{$public_host}}favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=1" />
<title>ShopXO后台管理系统</title>
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/assets/css/amazeui.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-switch/amazeui.switch.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-chosen/amazeui.chosen.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/common/lib/amazeui-tagsinput/amazeui.tagsinput.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/common/css/common.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/admin/{{$default_theme}}/css/common.css" />
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/admin/{{$default_theme}}/css/iconfontmenu.css" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/lib/assets/css/amazeui.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/lib/amazeui-switch/amazeui.switch.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/lib/amazeui-chosen/amazeui.chosen.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/lib/amazeui-tagsinput/amazeui.tagsinput.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/common/css/common.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/admin/{{$default_theme}}/css/common.css?v={{:MyC('home_static_cache_version')}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/admin/{{$default_theme}}/css/iconfontmenu.css?v={{:MyC('home_static_cache_version')}}" />
{{if !empty($plugins_css)}}
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/{{$plugins_css}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/{{$plugins_css}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{if !empty($module_css)}}
<link rel="stylesheet" type="text/css" href="{{$Think.__MY_ROOT_PUBLIC__}}static/{{$module_css}}" />
<link rel="stylesheet" type="text/css" href="{{$public_host}}static/{{$module_css}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
<!-- css钩子 -->
{{if !empty($plugins_admin_css_data) and is_array($plugins_admin_css_data)}}
{{foreach $plugins_admin_css_data as $hook}}
{{if is_string($hook)}}
<link rel="stylesheet" type="text/css" href="{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{if substr($hook_css, 0, 4) eq 'http'}}
<link rel="stylesheet" type="text/css" href="{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{else /}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{elseif is_array($hook) /}}
{{foreach $hook as $hook_css}}
{{if is_string($hook_css)}}
<link rel="stylesheet" type="text/css" href="{{$hook_css}}?v={{:MyC('home_static_cache_version')}}" />
{{if substr($hook_css, 0, 4) eq 'http'}}
<link rel="stylesheet" type="text/css" href="{{$hook_css}}?v={{:MyC('home_static_cache_version')}}" />
{{else /}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}{{$hook_css}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{/if}}
{{/foreach}}
{{/if}}
......@@ -44,6 +52,9 @@
{{/if}}
</head>
<script type="text/javascript">
var __root__ = '{{$public_host}}';
var __my_url__ = '{{$my_url}}';
var __public__ = '{{$public_host}}';
var __attachment_host__ = '{{$attachment_host}}';
var __price_symbol__ = '{{$price_symbol}}';
</script>
......
......@@ -103,7 +103,11 @@
{{if !empty($plugins_js_data) and is_array($plugins_js_data)}}
{{foreach $plugins_js_data as $hook}}
{{if !empty($hook) and is_string($hook)}}
<script type='text/javascript' src="{{$hook}}?v={{:MyC('home_static_cache_version')}}"></script>
{{if substr($hook_js, 0, 4) eq 'http'}}
<script type='text/javascript' src="{{$hook_js}}?v={{:MyC('home_static_cache_version')}}"></script>
{{else /}}
<script type='text/javascript' src="{{$public_host}}{{$hook}}?v={{:MyC('home_static_cache_version')}}"></script>
{{/if}}
{{elseif is_array($hook) /}}
{{foreach $hook as $hook_js}}
{{if !empty($hook_js) and is_string($hook_js)}}
......
......@@ -36,7 +36,11 @@
{{if !empty($plugins_css_data) and is_array($plugins_css_data)}}
{{foreach $plugins_css_data as $hook}}
{{if !empty($hook) and is_string($hook)}}
<link rel="stylesheet" type="text/css" href="{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{if substr($hook_css, 0, 4) eq 'http'}}
<link rel="stylesheet" type="text/css" href="{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{else /}}
<link rel="stylesheet" type="text/css" href="{{$public_host}}{{$hook}}?v={{:MyC('home_static_cache_version')}}" />
{{/if}}
{{elseif is_array($hook) /}}
{{foreach $hook as $hook_css}}
{{if !empty($hook_css) and is_string($hook_css)}}
......
......@@ -310,6 +310,13 @@ return array(
2 => array('value' => 2, 'name' => '已关闭'),
),
// 商品参数组件类型
'common_goods_parameters_type_list' => array(
0 => array('value' => 0, 'name' => '全部'),
1 => array('value' => 1, 'name' => '详情', 'checked' => true),
2 => array('value' => 2, 'name' => '基础'),
),
// 色彩值
'common_color_list' => array(
......
......@@ -1526,15 +1526,26 @@ class BuyService
}
// 是否扣除库存
if(MyC('common_is_deduction_inventory', 0) != 1)
$common_is_deduction_inventory = MyC('common_is_deduction_inventory', 0);
if($common_is_deduction_inventory != 1)
{
return DataReturn('未开启扣除库存', 0);
}
// 获取订单商品
$order_detail = Db::name('OrderDetail')->field('id,goods_id,buy_number,spec')->where(['order_id'=>$params['order_id']])->select();
if(!empty($order_detail))
// 扣除库存规则
$common_deduction_inventory_rules = MyC('common_deduction_inventory_rules', 1);
// 这里仅订单支付规则类型下校验
if($common_deduction_inventory_rules == 1)
{
// 获取订单商品
$order_detail = Db::name('OrderDetail')->field('id,goods_id,buy_number,spec')->where(['order_id'=>$params['order_id']])->select();
if(empty($order_detail))
{
return DataReturn('订单详情有误', -1);
}
// 数据校验
foreach($order_detail as $v)
{
$ret = self::BuyOrderPayBeginGoodsCheck($v);
......@@ -1543,9 +1554,8 @@ class BuyService
return $ret;
}
}
return DataReturn('校验成功', 0);
}
return DataReturn('没有需要扣除库存的数据', 0);
return DataReturn('校验成功', 0);
}
/**
......@@ -1579,49 +1589,57 @@ class BuyService
}
// 是否扣除库存
if(MyC('common_is_deduction_inventory', 0) != 1)
$common_is_deduction_inventory = MyC('common_is_deduction_inventory', 0);
if($common_is_deduction_inventory != 1)
{
return DataReturn('未开启扣除库存', 0);
}
// 数据集合
$detail = Db::name('OrderDetail')->field('id,order_id,goods_id,buy_number,spec')->where(['order_id'=>array_column($params['order_data'], 'id')])->select();
if(empty($detail))
{
return DataReturn('订单详情有误', -1);
}
// 扣除库存规则
$common_deduction_inventory_rules = MyC('common_deduction_inventory_rules', 1);
// 订单集合
$order_group = [];
foreach($params['order_data'] as $o)
{
$order_group[$o['id']] = $o['warehouse_id'];
}
// 订单详情
$data = [];
foreach($detail as $d)
// 这里仅订单支付规则类型下校验
if($common_deduction_inventory_rules == 1)
{
$key = md5(empty($d['spec']) ? 'default' : $d['spec']);
if(!isset($data[$order_group[$d['order_id']]][$d['goods_id']][$key]))
// 数据集合
$detail = Db::name('OrderDetail')->field('id,order_id,goods_id,buy_number,spec')->where(['order_id'=>array_column($params['order_data'], 'id')])->select();
if(empty($detail))
{
$data[$order_group[$d['order_id']]][$d['goods_id']][$key] = $d;
} else {
$data[$order_group[$d['order_id']]][$d['goods_id']][$key]['buy_number'] += $d['buy_number'];
return DataReturn('订单详情有误', -1);
}
}
// 数据校验
foreach($data as $w)
{
foreach($w as $g)
// 订单集合
$order_group = [];
foreach($params['order_data'] as $o)
{
foreach($g as $v)
$order_group[$o['id']] = $o['warehouse_id'];
}
// 订单详情
$data = [];
foreach($detail as $d)
{
$key = md5(empty($d['spec']) ? 'default' : $d['spec']);
if(!isset($data[$order_group[$d['order_id']]][$d['goods_id']][$key]))
{
$ret = self::BuyOrderPayBeginGoodsCheck($v);
if($ret['code'] != 0)
$data[$order_group[$d['order_id']]][$d['goods_id']][$key] = $d;
} else {
$data[$order_group[$d['order_id']]][$d['goods_id']][$key]['buy_number'] += $d['buy_number'];
}
}
// 数据校验
foreach($data as $w)
{
foreach($w as $g)
{
foreach($g as $v)
{
return $ret;
$ret = self::BuyOrderPayBeginGoodsCheck($v);
if($ret['code'] != 0)
{
return $ret;
}
}
}
}
......
......@@ -341,6 +341,7 @@ class GoodsService
$is_spec = (isset($params['is_spec']) && $params['is_spec'] == true) ? true : false;
$is_content_app = (isset($params['is_content_app']) && $params['is_content_app'] == true) ? true : false;
$is_category = (isset($params['is_category']) && $params['is_category'] == true) ? true : false;
$is_params = (isset($params['is_params']) && $params['is_params'] == true) ? true : false;
// 开始处理数据
foreach($data as &$v)
......@@ -460,13 +461,19 @@ class GoodsService
// 获取规格
if($is_spec && !empty($v['id']))
{
$v['specifications'] = self::GoodsSpecifications($v['id']);
$v['specifications'] = self::GoodsSpecificationsData($v['id']);
}
// 获取商品参数
if($is_params && !empty($v['id']))
{
$v['parameters'] = self::GoodsParametersData($v['id']);
}
// 获取app内容
if($is_content_app && !empty($v['id']))
{
$v['content_app'] = self::GoodsContentApp(['goods_id'=>$v['id']]);
$v['content_app'] = self::GoodsContentAppData(['goods_id'=>$v['id']]);
}
// 展示字段
......@@ -546,7 +553,7 @@ class GoodsService
* @param [array] $params [输入参数]
* @return [array] [app内容]
*/
public static function GoodsContentApp($params = [])
public static function GoodsContentAppData($params = [])
{
$data = Db::name('GoodsContentApp')->where(['goods_id'=>$params['goods_id']])->field('id,images,content')->order('sort asc')->select();
if(!empty($data))
......@@ -571,7 +578,7 @@ class GoodsService
* @desc description
* @param [int] $goods_id [商品id]
*/
public static function GoodsSpecifications($goods_id)
public static function GoodsSpecificationsData($goods_id)
{
// 条件
$where = ['goods_id'=>$goods_id];
......@@ -615,6 +622,48 @@ class GoodsService
return ['choose'=>$choose];
}
/**
* 获取商品参数
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-08-31
* @desc description
* @param [int] $goods_id [商品id]
*/
public static function GoodsParametersData($goods_id)
{
$base = [];
$detail = [];
$data = Db::name('GoodsParams')->where(['goods_id'=>$goods_id])->order('id asc')->select();
if(!empty($data))
{
foreach($data as $v)
{
$temp = [
'name' => $v['name'],
'value' => $v['value'],
];
// 基础
if(in_array($v['type'], [0,2]))
{
$base[] = $temp;
}
// 详情
if(in_array($v['type'], [0,1]))
{
$detail[] = $temp;
}
}
}
return [
'base' => $base,
'detail' => $detail,
];
}
/**
* 商品规格简洁的数据处理
* @author Devil
......@@ -751,15 +800,15 @@ class GoodsService
[
'checked_type' => 'length',
'key_name' => 'title',
'checked_data' => '2,60',
'error_msg' => '标题名称格式 2~60 个字符',
'checked_data' => '2,160',
'error_msg' => '标题名称格式 2~160 个字符',
],
[
'checked_type' => 'length',
'key_name' => 'simple_desc',
'checked_data' => '160',
'checked_data' => '230',
'is_checked' => 1,
'error_msg' => '商品简述格式 最多160个字符',
'error_msg' => '商品简述格式 最多230个字符',
],
[
'checked_type' => 'length',
......@@ -862,6 +911,9 @@ class GoodsService
// 赠送积分
$give_integral = max(0, (isset($params['give_integral']) && $params['give_integral'] <= 100) ? intval($params['give_integral']) : 0);
// 封面图片、默认相册第一张
$images = empty($attachment['data']['images']) ? (isset($photo['data'][0]) ? $photo['data'][0] : '') : $attachment['data']['images'];
// 基础数据
$data = [
'title' => $params['title'],
......@@ -876,17 +928,16 @@ class GoodsService
'is_deduction_inventory' => isset($params['is_deduction_inventory']) ? intval($params['is_deduction_inventory']) : 0,
'is_shelves' => isset($params['is_shelves']) ? intval($params['is_shelves']) : 0,
'content_web' => $content_web,
'images' => isset($photo['data'][0]) ? $photo['data'][0] : '',
'photo_count' => count($photo['data']),
'is_home_recommended' => isset($params['is_home_recommended']) ? intval($params['is_home_recommended']) : 0,
'images' => $attachment['data']['images'],
'images' => $images,
'brand_id' => isset($params['brand_id']) ? intval($params['brand_id']) : 0,
'video' => $attachment['data']['video'],
'seo_title' => empty($params['seo_title']) ? '' : $params['seo_title'],
'seo_keywords' => empty($params['seo_keywords']) ? '' : $params['seo_keywords'],
'seo_desc' => empty($params['seo_desc']) ? '' : $params['seo_desc'],
'is_exist_many_spec' => empty($specifications['data']['title']) ? 0 : 1,
'spec_base' => empty($specifications_base['data']) ? '' : json_encode($specifications_base['data']),
'spec_base' => empty($specifications_base['data']) ? '' : json_encode($specifications_base['data'], JSON_UNESCAPED_UNICODE),
'fictitious_goods_value' => $fictitious_goods_value,
'site_type' => isset($params['site_type']) ? $params['site_type'] : -1,
];
......@@ -971,6 +1022,15 @@ class GoodsService
return $ret;
}
// 商品参数
$ret = self::GoodsParametersInsert($params, $goods_id);
if($ret['code'] != 0)
{
// 回滚事务
Db::rollback();
return $ret;
}
// 提交事务
Db::commit();
return DataReturn('操作成功', 0);
......@@ -981,6 +1041,50 @@ class GoodsService
return DataReturn('操作失败', -100);
}
/**
* 商品参数添加
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-08-31
* @desc description
* @param [array] $params [输入参数]
* @param [int] $goods_id [商品id]
*/
private static function GoodsParametersInsert($params, $goods_id)
{
// 删除商品参数
Db::name('GoodsParams')->where(['goods_id'=>$goods_id])->delete();
// 展示范围、参数名称、参数值
if(!empty($params['parameters_type']) && !empty($params['parameters_name']) && !empty($params['parameters_value']) && is_array($params['parameters_type']) && is_array($params['parameters_name']) && is_array($params['parameters_value']))
{
$data = [];
$time = time();
foreach($params['parameters_type'] as $k=>$v)
{
if(isset($params['parameters_name'][$k]) && isset($params['parameters_value'][$k]))
{
$data[] = [
'type' => $v,
'name' => $params['parameters_name'][$k],
'value' => $params['parameters_value'][$k],
'goods_id' => $goods_id,
'add_time' => $time,
];
}
}
if(!empty($data))
{
if(Db::name('GoodsParams')->insertAll($data) < count($data))
{
return DataReturn('规格参数添加失败', -1);
}
}
}
return DataReturn('添加成功', 0);
}
/**
* 商品保存基础信息更新
* @author Devil
......@@ -1689,6 +1793,20 @@ class GoodsService
];
}
/**
* 获取商品编辑参数
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-08-31
* @desc description
* @param [int] $goods_id [商品id]
*/
public static function GoodsEditParameters($goods_id)
{
return Db::name('GoodsParams')->where(['goods_id'=>$goods_id])->order('id asc')->select();
}
/**
* 商品规格信息
* @author Devil
......
......@@ -72,11 +72,25 @@ class OrderService
return DataReturn('订单支付id有误', -1);
}
// 支付方式
$payment = [];
$payment_id = empty($params['payment_id']) ? Db::name('Order')->where(['id'=>$ids[0]])->value('payment_id') : intval($params['payment_id']);
if(!empty($payment_id))
{
$res = PaymentService::PaymentList(['where'=>['id'=>$payment_id]]);
if(!empty($res[0]))
{
$payment = $res[0];
}
}
if(empty($payment))
{
return DataReturn('支付方式有误', -1);
}
// 支付基础信息
$order_payment_id = 0;
$client_type = '';
$total_price = 0;
$success_count = 0;
$order_ids = [];
$order_nos = [];
......@@ -89,35 +103,18 @@ class OrderService
$order = Db::name('Order')->where($where)->find();
if(empty($order))
{
return DataReturn('资源不存在或已被删除', -1);
return DataReturn('订单不存在或已被删除', -1);
}
if($order['status'] != 1)
{
$status_text = lang('common_order_user_status')[$order['status']]['name'];
return DataReturn('状态不可操作['.$status_text.']'.$order['order_no'], -1);
return DataReturn('状态不可操作['.$status_text.'-'.$order['order_no'].']', -1);
}
// 金额为0、走直接支付成功
if($order['total_price'] <= 0.00)
{
$params['user']['user_name_view'] = '用户-'.$params['user']['user_name_view'];
$pay_result = self::OrderDirectSuccess([
'order' => $order,
'payment' => $payment[0],
'user' => $params['user'],
'params' => $params,
]);
if($pay_result['code'] == 0)
{
$success_count++;
}
return $pay_result;
}
// 订单id/号集合
// 订单数据集合
$order_data[] = $order;
$order_ids[] = $order['id'];
$order_nos[] = $order['order_no'];
$total_price += $order['total_price'];
// 仅第一个订单获取的数据
if($k == 0)
......@@ -125,9 +122,6 @@ class OrderService
$client_type = $order['client_type'];
$order_payment_id = $order['payment_id'];
}
// 订单数据集合
$order_data[] = $order;
}
// 订单支付前校验订单商品
......@@ -137,37 +131,55 @@ class OrderService
return $ret;
}
// 支付方式
$payment_id = empty($params['payment_id']) ? $order_payment_id : intval($params['payment_id']);
$payment = PaymentService::PaymentList(['where'=>['id'=>$payment_id]]);
if(empty($payment[0]))
{
return DataReturn('支付方式有误', -1);
}
// 更新订单支付方式信息
if($payment_id != $order_payment_id)
if($payment['id'] != $order_payment_id)
{
Db::name('Order')->where(['id'=>$ids])->update([
'payment_id' => $payment_id,
'is_under_line' => in_array($payment[0]['payment'], config('shopxo.under_line_list')) ? 1 : 0,
'payment_id' => $payment['id'],
'is_under_line' => in_array($payment['payment'], config('shopxo.under_line_list')) ? 1 : 0,
'upd_time' => time(),
]);
}
// 金额为0、走直接支付成功
$total_price = 0;
$success_count = 0;
foreach($order_data as $order)
{
if($order['total_price'] <= 0.00)
{
$pay_result = self::OrderDirectSuccess([
'order' => $order,
'payment' => $payment,
'user' => $params['user'],
'params' => $params,
]);
if($pay_result['code'] == 0)
{
// 已支付成功订单结束当前循环
$success_count++;
continue;
}
return $pay_result;
}
// 数据集合
$total_price += $order['total_price'];
}
// 是否直接跳转
if($success_count > 0 && $success_count == count($ids))
if($success_count > 0 && $success_count == count($order_data))
{
return DataReturn('支付成功', 0, ['data'=>MyUrl('index/order/respond', ['appoint_status'=>0])]);
}
// 支付入口文件检查
$pay_checked = PaymentService::EntranceFileChecked($payment[0]['payment'], 'order');
$pay_checked = PaymentService::EntranceFileChecked($payment['payment'], 'order');
if($pay_checked['code'] != 0)
{
// 入口文件不存在则创建
$payment_params = [
'payment' => $payment[0]['payment'],
'payment' => $payment['payment'],
'respond' => '/index/order/respond',
'notify' => '/api/ordernotify/notify',
];
......@@ -179,14 +191,14 @@ class OrderService
}
// 回调地址
$url = __MY_URL__.'payment_order_'.strtolower($payment[0]['payment']);
$url = __MY_URL__.'payment_order_'.strtolower($payment['payment']);
// url模式, pathinfo模式下采用自带url生成url, 避免非index.php多余
if(MyC('home_seo_url_model', 0) == 0)
{
$call_back_url = $url.'_respond.php';
} else {
$call_back_url = MyUrl('index/order/respond', ['paymentname'=>$payment[0]['payment']]);
$call_back_url = MyUrl('index/order/respond', ['paymentname'=>$payment['payment']]);
if(stripos($call_back_url, '?') !== false)
{
$call_back_url = $url.'_respond.php';
......@@ -199,8 +211,8 @@ class OrderService
'business_ids' => $order_ids,
'business_nos' => $order_nos,
'total_price' => $total_price,
'payment' => $payment[0]['payment'],
'payment_name' => $payment[0]['name'],
'payment' => $payment['payment'],
'payment_name' => $payment['name'],
]);
if($pay_log['code'] != 0)
{
......@@ -208,7 +220,7 @@ class OrderService
}
// 发起支付数据
$pay_data = array(
$pay_data = [
'user' => $params['user'],
'out_user' => md5($params['user']['id']),
'order_id' => $pay_log['data']['id'],
......@@ -221,7 +233,7 @@ class OrderService
'redirect_url' => MyUrl('index/order/index'),
'site_name' => MyC('home_site_name', 'ShopXO', true),
'ajax_url' => MyUrl('index/order/paycheck'),
);
];
// 发起支付处理钩子
$hook_name = 'plugins_service_order_pay_launch_handle';
......@@ -247,7 +259,7 @@ class OrderService
$weixin_params = [
'is_pay_auto' => 1,
'is_pay_submit' => 1,
'payment_id' => $payment_id,
'payment_id' => $payment['id'],
];
if(count($order_ids) == 1)
{
......@@ -263,8 +275,8 @@ class OrderService
}
// 发起支付
$pay_name = 'payment\\'.$payment[0]['payment'];
$ret = (new $pay_name($payment[0]['config']))->Pay($pay_data);
$pay_name = 'payment\\'.$payment['payment'];
$ret = (new $pay_name($payment['config']))->Pay($pay_data);
if(isset($ret['code']) && $ret['code'] == 0)
{
// 支付信息返回
......@@ -281,12 +293,12 @@ class OrderService
];
// 是否线下支付
if(in_array($payment[0]['payment'], config('shopxo.under_line_list')))
if(in_array($payment['payment'], config('shopxo.under_line_list')))
{
$ret['data']['is_payment_type'] = 1;
} else {
// 是否钱包支付
if($payment[0]['payment'] == 'WalletPay')
if($payment['payment'] == 'WalletPay')
{
$ret['data']['is_payment_type'] = 2;
}
......@@ -373,17 +385,19 @@ class OrderService
}
// 支付方式
$payment = [];
$payment_id = empty($params['payment_id']) ? $order['payment_id'] : intval($params['payment_id']);
$payment = PaymentService::PaymentList(['where'=>['id'=>$payment_id]]);
if(empty($payment[0]))
$res = PaymentService::PaymentList(['where'=>['id'=>$payment_id]]);
if(empty($res[0]))
{
return DataReturn('支付方式有误', -1);
}
$payment = $res[0];
// 线下支付处理
return self::OrderPaymentUnderLineSuccess([
'order' => $order,
'payment' => $payment[0],
'payment' => $payment,
'user' => $params['user'],
'params' => $params,
]);
......@@ -418,9 +432,6 @@ class OrderService
return $pay_log;
}
// 新增日志订单
$pay_log_data = [];
// 支付处理
$pay_params = [
'order' => [$params['order']],
......@@ -519,15 +530,17 @@ class OrderService
{
return DataReturn('支付方式标记异常', -1);
}
$payment = PaymentService::PaymentList(['where'=>['payment'=>$payment_name]]);
if(empty($payment[0]))
$payment = [];
$res = PaymentService::PaymentList(['where'=>['payment'=>$payment_name]]);
if(empty($res[0]))
{
return DataReturn('支付方式有误', -1);
}
$payment = $res[0];
// 支付数据校验
$pay_name = 'payment\\'.$payment_name;
$ret = (new $pay_name($payment[0]['config']))->Respond(array_merge(input('get.'), input('post.')));
$ret = (new $pay_name($payment['config']))->Respond(array_merge(input('get.'), input('post.')));
if(isset($ret['code']) && $ret['code'] == 0)
{
if(empty($ret['data']['out_trade_no']))
......@@ -559,15 +572,17 @@ class OrderService
public static function Notify($params = [])
{
// 支付方式
$payment = PaymentService::PaymentList(['where'=>['payment'=>PAYMENT_TYPE]]);
if(empty($payment[0]))
$payment = [];
$res = PaymentService::PaymentList(['where'=>['payment'=>PAYMENT_TYPE]]);
if(empty($res[0]))
{
return DataReturn('支付方式有误', -1);
}
$payment = $res[0];
// 支付数据校验
$pay_name = 'payment\\'.PAYMENT_TYPE;
$pay_ret = (new $pay_name($payment[0]['config']))->Respond(array_merge(input('get.'), input('post.')));
$pay_ret = (new $pay_name($payment['config']))->Respond(array_merge(input('get.'), input('post.')));
if(!isset($pay_ret['code']) || $pay_ret['code'] != 0)
{
return $pay_ret;
......@@ -612,7 +627,7 @@ class OrderService
// 支付处理
$pay_params = [
'order' => $order_list,
'payment' => $payment[0],
'payment' => $payment,
'pay_log_data' => $pay_log_data,
'pay' => [
'trade_no' => $pay_ret['data']['trade_no'],
......@@ -627,7 +642,7 @@ class OrderService
$pay_ret = HookReturnHandle(Hook::listen($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'payment' => $payment[0],
'payment' => $payment,
'order' => $order_list,
'pay_params' => &$pay_params,
]));
......
......@@ -60,16 +60,10 @@ class PayLogService
'error_msg' => '业务类型为空',
],
[
'checked_type' => 'empty',
'checked_type' => 'isset',
'key_name' => 'total_price',
'error_msg' => '业务金额为空',
],
[
'checked_type' => 'min',
'key_name' => 'total_price',
'checked_data' => 0.01,
'error_msg' => '业务金额必须大于0',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
......
......@@ -64,6 +64,7 @@ class ToutiaoService
// 头条需要的订单信息
$time = (string) time();
$valid_time = intval(MyC('common_order_close_limit_time', 30, true))*60;
$order_info = [
'merchant_id' => $merchant_id,
'app_id' => $app_id,
......@@ -74,13 +75,13 @@ class ToutiaoService
'product_code' => 'pay',
'payment_type' => 'direct',
'out_order_no' => $pay_log['log_no'],
'uid' => md5($params['user']['id']),
'uid' => $app_id,
'total_amount' => $pay_log['total_price']*100,
'currency' => 'CNY',
'subject' => '订单支付',
'body' => $pay_log['log_no'],
'trade_time' => $time,
'valid_time' => (string) intval(MyC('common_order_close_limit_time', 30, true))*60,
'valid_time' => (string) $valid_time,
'notify_url' => __MY_URL__,
'risk_info' => json_encode(['ip'=>GetClientIP()]),
];
......
......@@ -32,5 +32,25 @@ return array (
'log_write' =>
array (
),
'plugins_css' =>
array (
0 => 'app\\plugins\\share\\Hook',
),
'plugins_js' =>
array (
0 => 'app\\plugins\\share\\Hook',
),
'plugins_view_common_bottom' =>
array (
0 => 'app\\plugins\\share\\Hook',
),
'plugins_common_page_bottom' =>
array (
0 => 'app\\plugins\\share\\Hook',
),
'plugins_view_goods_detail_photo_bottom' =>
array (
0 => 'app\\plugins\\share\\Hook',
),
);
?>
\ No newline at end of file
......@@ -12,7 +12,7 @@
background:#f5f5f5;
top:100px;
right:0;
width:110px;
width:80px;
position:fixed;
z-index:1000;
border:1px solid #eee;
......@@ -41,7 +41,7 @@
background:#eee;
}
.goods-nav li.nav-shrink-submit {
background: #eaeaea;
background: #dadada;
cursor: pointer;
}
.goods-nav-retract .nav-shrink-submit {
......@@ -66,10 +66,11 @@
* 规格
*/
.specifications-table .title-nav th,
.spec-quick table thead th {
.spec-quick table thead th,
.parameters-table thead th {
background-color: #f5f7fa;
position: relative;
border-bottom: 0;
border-bottom: 0 !important;
}
.specifications-table .title-nav th input {
width: calc(100% - 25px);
......@@ -86,9 +87,6 @@
.specifications-table th.extend-btn {
width: 45px;
}
.specifications-table > tbody > tr > td {
vertical-align: middle;
}
#goods-nav-operations {
position: relative;
}
......@@ -200,4 +198,14 @@ ul li {
.spec-quick-td-value .value-item {
width: calc(50% - 12px) !important;
}
}
/**
* 商品参数
*/
#goods-nav-parameters textarea {
resize: none;
}
#parameters-quick-container .am-dropdown-content {
width: 260px;
}
\ No newline at end of file
......@@ -46,6 +46,53 @@ function SpecCartesian(arr1, arr2)
// 返回最终笛卡尔积
return result;
}
/**
* 商品参数数据创建
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-09-02
* @desc description
* @param {[int]} type [展示类型(0,1,2)]
* @param {[string]} name [参数名称]
* @param {[string]} value [参数值]
*/
function ParametersItemHtmlCreated(type, name, value)
{
var index = parseInt(Math.random()*1000001);
var html = '<tr class="parameters-line-'+index+'">';
html += '<td class="am-text-middle">';
html += '<select name="parameters_type[]" class="am-radius chosen-select" data-validation-message="请选择商品参数展示类型">';
html += '<option value="0" '+(type == 0 ? 'selected' : '')+'>全部</option>';
html += '<option value="1" '+(type == 1 || type == undefined ? 'selected' : '')+'>详情</option>';
html += '<option value="2" '+(type == 2 ? 'selected' : '')+'>基础</option>';
html += '</select>';
html += '</td>';
html += '<td class="am-text-middle">';
html += '<input type="text" name="parameters_name[]" placeholder="参数名称" value="'+(name || '')+'" data-validation-message="请填写参数名称" maxlength="160" required />';
html += '</td>';
html += '<td class="am-text-middle">';
html += '<input type="text" name="parameters_value[]" placeholder="参数值" value="'+(value || '')+'" maxlength="200" data-validation-message="请填写参数值" />';
html += '</td>';
html += '<td class="am-text-middle">';
html += '<span class="am-text-xs cr-blue c-p am-margin-right-sm line-move" data-type="top">上移</span>';
html += '<span class="am-text-xs cr-blue c-p am-margin-right-sm line-move" data-type="bottom">下移</span>';
html += '<span class="am-text-xs cr-red c-p line-remove">移除</span></td>';
html += '</tr>';
// 数据添加
var $parameters_table = $('.parameters-table');
$parameters_table.append(html);
// select组件初始化
$parameters_table.find('.parameters-line-'+index+' .chosen-select').chosen({
inherit_select_classes: true,
enable_split_word_search: true,
search_contains: true,
no_results_text: '没有匹配到结果'
});
}
$(function()
{
......@@ -73,7 +120,7 @@ $(function()
$(this).parents('.goods-nav').addClass('goods-nav-retract');
$('.goods-nav-retract').animate({right:'-110px'}, 500, function()
{
$('.goods-nav-retract li.nav-shrink-submit').animate({width: '50px', left:'-51px'});
$('.goods-nav-retract li.nav-shrink-submit').animate({width: '50px', left:'-80px'});
});
} else {
......@@ -534,7 +581,7 @@ $(function()
var spec_max = $('#goods-nav-operations').data('spec-add-max-number') || 3;
if($('.spec-quick table tbody tr').length >= spec_max)
{
Prompt('最多添加'+spec_max+'列规格');
Prompt('最多添加'+spec_max+'列规格,可在后台管理[系统设置-后台配置]中配置');
return false;
}
......@@ -665,6 +712,7 @@ $(function()
$('.specifications-table').find('tbody tr:last').find('td:eq('+k+') input').val(temp_spec[k]);
}
}
Prompt('生成成功', 'success');
},
onCancel: function(){}
});
......@@ -685,4 +733,144 @@ $(function()
$('.specifications-table tr').removeClass('am-primary');
$(this).addClass('am-primary');
});
// 参数添加
var $parameters_table = $('.parameters-table');
$('.parameters-line-add').on('click', function()
{
// 追加内容
ParametersItemHtmlCreated();
});
// 商品参数移动
$parameters_table.on('click', '.line-move', function()
{
// 类型
var type = $(this).data('type') || null;
if(type == null)
{
Prompt('操作类型配置有误');
return false;
}
// 索引
var count = $parameters_table.find('tbody tr').length;
var index = $(this).parents('tr').index() || 0;
var $parent = $(this).parents('tr');
switch(type)
{
// 上移
case 'top' :
if(index == 0)
{
Prompt('已到最顶部');
return false;
}
$parent.prev().insertAfter($parent);
break;
// 下移
case 'bottom' :
if(index >= count-1)
{
Prompt('已到最底部');
return false;
}
$parent.next().insertBefore($parent);
break;
// 默认
default :
Prompt('操作类型配置有误');
}
});
// 商品参数移除
$parameters_table.on('click', '.line-remove', function()
{
$(this).parents('tr').remove();
});
// 商品参数配置信息复制
var $parameters_copy_modal = $('#parameters-quick-copy-modal');
var clipboard = new ClipboardJS('.parameters-quick-copy',
{
text: function()
{
// 获取商品参数配置信息
var data = [];
$parameters_table.find('tbody tr').each(function(k, v)
{
data.push({
"type": $(this).find('td:eq(0) select').val(),
"name": $(this).find('td:eq(1) input').val(),
"value": $(this).find('td:eq(2) input').val(),
});
});
data = JSON.stringify(data);
$parameters_copy_modal.find('textarea').val(data);
return data;
}
});
clipboard.on('success', function(e)
{
Prompt('复制成功', 'success');
});
clipboard.on('error', function(e)
{
// 复制失败则开启复制窗口,让用户自己复制
$parameters_copy_modal.modal({
width: 200,
height: 135
});
});
// 点击选中复制的值
$parameters_copy_modal.find('textarea').on('click', function()
{
$(this).select();
});
// 商品参数快捷操作
var $parameters_quick_config = $('.parameters-quick-config');
$parameters_quick_config.find('button').on('click', function()
{
// 配置数据
var data = $parameters_quick_config.find('textarea').val() || null;
if(data == null)
{
Prompt('请先粘贴配置信息');
return false;
}
// 异常处理、防止json格式错误
try {
data = JSON.parse(data);
} catch(e) {
Prompt('配置格式错误');
return false;
}
if(data.length <= 0)
{
Prompt('配置为空');
return false;
}
// 数据生成
$parameters_table.find('tbody').html('');
for(var i in data)
{
var type = (data[i]['type'] == undefined) ? 1 : data[i]['type'];
var name = data[i]['name'] || '';
var value = data[i]['value'] || '';
ParametersItemHtmlCreated(type, name, value);
}
$('#parameters-quick-container').dropdown('close');
Prompt('生成成功', 'success');
});
// 商品参数清空
$('.parameters-quick-remove').on('click', function()
{
$parameters_table.find('tbody').html('');
});
});
\ No newline at end of file
......@@ -30,7 +30,7 @@ form.am-form .am-form-group-label-tips-must { color: #f00; }
.am-form-group:hover>label { color: #333 !important; }
.am-form-group:hover>label>.am-form-group-label-tips { color: #FF9800 !important; }
form.am-form .am-form-group, .plug-file-upload-view, .business-form-group, .business-form-block { border-bottom: 1px dashed #ccc; padding: 10px 20% 10px 5px; }
form.am-form .am-form-group-refreshing, .plug-file-upload-view, .content-app-items { border-bottom: 0px; }
form.am-form .am-form-group-refreshing, .plug-file-upload-view { border-bottom: 0px; }
/**
* 插件
......@@ -444,6 +444,14 @@ button.colorpicker-submit img {
margin: -3px;
}
/**
* 图片响应式支持子元素
*/
.am-img-responsive img,
.am-img-responsive video {
max-width: 100%;
}
/**
* 插件标记
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册