邮费模板 开发

This commit is contained in:
Anyon 2020-09-16 19:28:26 +08:00
parent 6a298cf7ac
commit 147a64dc7f
7 changed files with 589 additions and 0 deletions

View File

@ -0,0 +1,101 @@
<?php
namespace app\data\controller;
use app\data\service\TruckService;
use think\admin\Controller;
use think\admin\extend\CodeExtend;
use think\admin\extend\DataExtend;
/**
* 配送运费模板管理
* Class ShopTruckTemplate
* @package app\data\controller
*/
class ShopTruckTemplate extends Controller
{
/**
* 绑定数据表
* @var string
*/
private $table = 'ShopTruckTemplate';
/**
* 快递邮费配置
* @auth true
* @menu true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$this->title = '快递邮费配置';
$query = $this->_query($this->table)->like('name');
$query->where(['deleted' => 0])->order('sort desc,id desc')->page();
}
/**
* 添加配送邮费模板
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add()
{
$this->title = '添加配送邮费模板';
$this->_form($this->table, 'form');
}
/**
* 表单数据处理
* @param array $data
*/
protected function _form_filter(array &$data)
{
if (empty($data['code'])) {
$data['code'] = CodeExtend::uniqidDate(12, 'T');
}
if ($this->request->isGet()) {
$this->citys = TruckService::instance()->region(2);
}
}
public function region()
{
$this->citys = TruckService::instance()->region(2);
$this->fetch('form_region');
}
/**
* 修改快递模板
* @auth true
* @throws \think\db\exception\DbException
*/
public function edit()
{
[$list, $idxs, $post] = [[], [], $this->request->post()];
foreach (array_keys($post) as $key) if (stripos($key, 'order_reduction_state_') !== false) {
$idxs[] = str_replace('order_reduction_state_', '', $key);
}
foreach (array_unique($idxs) as $index) if (!empty($post["rule_{$index}"])) $list[] = [
'rule' => ',' . join(',', $post["rule_{$index}"]) . ',',
// 订单满减配置
'order_reduction_state' => $post["order_reduction_state_{$index}"],
'order_reduction_price' => $post["order_reduction_price_{$index}"],
// 首件邮费配置
'first_number' => $post["first_number_{$index}"],
'first_price' => $post["first_price_{$index}"],
// 首件邮费配置
'next_number' => $post["next_number_{$index}"],
'next_price' => $post["next_price_{$index}"],
// 默认邮费规则
'is_default' => $post["is_default_{$index}"],
];
if (empty($list)) $this->error('请配置有效的邮费规则');
$this->app->db->name($this->table)->where('1=1')->delete();
$this->app->db->name($this->table)->insertAll($list);
$this->success('邮费规则配置成功!');
}
}

View File

@ -2,6 +2,7 @@
namespace app\data\service;
use think\admin\extend\DataExtend;
use think\admin\Service;
use think\admin\service\InterfaceService;
@ -31,6 +32,12 @@ class TruckService extends Service
}
public function region($level = 3)
{
$items = $this->app->db->name('ShopTruckRegion')->where('level', '<=', $level)->column('id,pid,name', 'id');
return DataExtend::arr2tree($items, 'id', 'pid', 'subs');
}
/**
* 楚才开放平台快递查询
* @param string $code 快递公司编号

View File

@ -0,0 +1,234 @@
{extend name="../../admin/view/main"}
{block name="content"}
<div id="TruckForm">
<form onsubmit="return false;" action="{:url('')}" method="post" class='layui-form layui-card' autocomplete="off">
<div class="layui-card-body padding-40">
<label class="layui-form-item block relative">
<span class="color-green font-w7 margin-right-5">邮费模板名称</span><span class="color-desc">Name</span>
<input name="name" required value='{$vo.name|default=""}' placeholder="请输入邮费模板名称" class="layui-input">
<p class="color-desc">必填,邮费模板名称用于区分邮费模板规则,仅在后台选择邮费模板时使用。</p>
</label>
<table class="layui-table">
<thead>
<tr>
<th>可配送区域</th>
<th>首件(个)</th>
<th>运费(元)</th>
<th>续件(个)</th>
<th>续费(元)</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in rules">
<td>
<span class="margin-right-5" ng-repeat="city in item.city" ng-if="checkShowOne(city)">
<b class="font-w7" ng-bind="city.name"></b>
<b ng-repeat="x in city.subs" ng-if="x.status" class="color-desc">{{x.name}}</b>
</span>
<a class="margin-left-5" ng-click="editRuleItem(item)">编辑</a>
<a class="margin-left-5" ng-click="removeRuleItem(item)">删除</a>
</td>
<td><input class="layui-input" ng-model="item.rule.firstNumber"></td>
<td><input class="layui-input" ng-model="item.rule.firstAmount"></td>
<td><input class="layui-input" ng-model="item.rule.repeatNumber"></td>
<td><input class="layui-input" ng-model="item.rule.repeatAmount"></td>
</tr>
<tr>
<td colspan="5"><a ng-click="addRuleItem()">添加可配送区域和运费</a></td>
</tr>
</tbody>
</table>
<div class="hr-line-dashed"></div>
{if auth('edit')}
<div class="layui-form-item text-center">
<button class="layui-btn" type='submit'>保存数据</button>
</div>
{/if}
</div>
</form>
<div class='layui-form layui-card layui-hide' id="RegionContainer">
<div class="layui-card-body padding-20 padding-bottom-0">
<div class="layui-row layui-col-space10">
<div class="layui-col-xs8">
<div class="layui-textarea" style="height:360px;overflow:auto">
<div>
<span class="pointer notselect margin-right-10" ng-click="setCheckAllItem(true)">全选</span>
<span class="pointer notselect margin-right-10" ng-click="setCheckAllItem(false)">取消</span>
</div>
<hr class="hr-line-dashed margin-top-5 margin-bottom-5">
<div class="layui-row layui-col-space5">
<div class="layui-col-xs3 nowrap" ng-repeat="x in citys" ng-if="checkShowCity(x)">
<label class="think-checkbox margin-right-0">
<input type="checkbox" ng-model="x.status" ng-change="setCheckActiveCity(x)" ng-value="x.name" lay-ignore>
</label>
<span class="pointer notselect" ng-click="setCheckActiveCity(x)">{{x.name}}</span>
</div>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-textarea" style="height:360px;overflow:auto">
<div>
<span class="pointer notselect margin-right-10" ng-click="setCheckCityItem(true)">全选</span>
<span class="pointer notselect margin-right-10" ng-click="setCheckCityItem(false)">取消</span>
<b class="pull-right color-blue" ng-bind="city.name"></b>
</div>
<hr class="hr-line-dashed margin-top-5 margin-bottom-5">
<label ng-repeat="x in city.subs" class="think-checkbox nowrap layui-elip" ng-if="x.show">
<input type="checkbox" ng-model="x.status" ng-value="x.name" value="" lay-ignore> {{x.name}}
</label>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
<button class="layui-btn" ng-click="setItem()">确定选择</button>
<button class="layui-btn layui-btn-danger" data-close>取消编辑</button>
</div>
</div>
</div>
</div>
<label class="layui-hide">
<textarea id="CityData">{$citys|json_encode|raw}</textarea>
</label>
<script>
Array.prototype.inArray = function (e) {
for (let i = 0; i < this.length; i++) {
if (this[i] === e) return true;
}
return false;
}
require(['angular'], function () {
var app = angular.module("TruckForm", []).run(callback);
angular.bootstrap(document.getElementById(app.name), [app.name]);
function callback($rootScope) {
$rootScope.rule = {city: [], rule: {}};
$rootScope.rules = [];
$rootScope.city = {subs: []};
$rootScope.citys = angular.fromJson($('#CityData').val()) || [];
// 默认显示所有城市
$rootScope.citys.forEach(function (item) {
item.show = true
delete item.id, delete item.pid;
item.subs.forEach(function (item) {
item.show = true;
delete item.id, delete item.pid;
});
});
// 添加规格选项
$rootScope.addRuleItem = function () {
$rootScope.rule = angular.fromJson(angular.toJson({city: [], rule: {firstNumber: 1, firstAmount: 1.00, repeatNumber: 1, repeatAmount: 1.00}}));
$rootScope.rules.push($rootScope.rule);
$rootScope.showDailog();
};
// 编辑规则选项
$rootScope.editRuleItem = function (rule) {
rule.city.forEach(function (item) {
item.subs.forEach(function (item) {
item.show = true;
});
});
rule.city = [];
$rootScope.rule = rule;
$rootScope.showDailog();
}
// 删除规则选项
$rootScope.removeRuleItem = function (rule) {
rule.city.forEach(function (item) {
item.subs.forEach(function (item) {
item.show = true;
item.status = false;
});
});
var rules = [];
$rootScope.rules.forEach(function (item) {
if (item !== rule) rules.push(item);
})
$rootScope.rules = rules;
}
// 检查是否还拥有可以选择的项目
$rootScope.checkShowCity = function (city) {
return city.subs.some(function (item) {
if (item.show) return true;
})
}
$rootScope.checkShowOne = function (city) {
return city.subs.some(function (item) {
if (item.status) return true;
});
};
/*! 省份全选或取消 */
$rootScope.setCheckAllItem = function (status) {
$rootScope.citys.forEach(function (item) {
if (item.show) item.status = !!status;
item.subs.forEach(function (item) {
if (item.show) item.status = !!status;
})
});
};
/*! 城市全选或取消 */
$rootScope.setCheckCityItem = function (status) {
$rootScope.city.subs.forEach(function (item) {
if (item.show) item.status = !!status;
});
};
/*! 展开省份下的城市 */
$rootScope.setCheckActiveCity = function (city) {
$rootScope.city = city;
city.subs.forEach(function (item) {
item.status = !!city.status;
});
};
$rootScope.$watch('citys', function () {
// 子集联动上级选择
$rootScope.city.status = $rootScope.city.subs.some(function (item) {
if (item.show && item.status) return true;
});
// 记录当前操作值
var cache = {};
$rootScope.rule.city.forEach(function (item) {
cache[item.name] = item;
});
$rootScope.citys.forEach(function (item) {
var subs = [];
item.subs.forEach(function (item) {
if (item.status && item.show) subs.push(item);
})
if (item.show && item.status && subs.length > 0) {
if (cache[item.name]) subs = cache[item.name].subs.concat(subs);
else $rootScope.rule.city.push({name: item.name, subs: subs});
cache[item.name] = subs;
}
});
console.log(JSON.stringify($rootScope.rule.city))
}, true);
$rootScope.setItem = function () {
layui.layer.closeAll();
$rootScope.rules.forEach(function (rule) {
rule.city.forEach(function (item) {
item.subs.forEach(function (item) {
item.show = false;
});
});
});
};
$rootScope.showDailog = function () {
layui.layer.open({
type: 1, shade: false, area: '800px', title: '选择配送区域',
content: $('#RegionContainer').removeClass('layui-hide'),
end: function () {
$('#RegionContainer').addClass('layui-hide')
}
});
};
}
});
</script>
{/block}

View File

@ -0,0 +1,55 @@
<fieldset class="margin-bottom-20 relative" data-item-boxs>
<legend class="color-green font-s14">
<span class="layui-badge">{$group|default='邮费规则分组'}</span>
<input type="hidden" name="group[]" value="{$group|default='邮费规则分组'}">
</legend>
{if $group neq '默认邮费模板'}
<a onclick="delRuleItem(this)" class="layui-btn layui-btn-sm layui-btn-danger absolute" style="top:15px;right:5px;padding:0 5px">
<i class="layui-icon layui-icon-close margin-left-5 margin-right-5"></i>
</a>
<input type="hidden" name="default[]" value="1">
{else}
<input type="hidden" name="default[]" value="0">
{/if}
<div class="layui-form-item block relative">
<div class="color-desc font-s14">订单总金额满足条件时将减免该订单的所有邮费(请谨慎配置)</div>
<div class="layui-inline">
<label class="layui-form-label font-s14 padding-left-0 padding-right-10" style="width:auto">订单总金额满</label>
<div class="layui-input-inline" style="width:100px;">
<input type="text" name="reduct_amount[]" placeholder="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label padding-left-5 padding-right-5" style="width:auto">元包邮</label>
</div>
</div>
<div data-city-box class="layui-form-item">
<div class="color-desc">
根据配送目的地的省份进行运费计算邮费(不在规则内的将使用默认邮费规则)
</div>
<div class="layui-row layui-col-space10 layui-bg-gray">
<div class="layui-col-xs3 text-center">首件(个)</div>
<div class="layui-col-xs3 text-center">运费(元)</div>
<div class="layui-col-xs3 text-center">续件(个)</div>
<div class="layui-col-xs3 text-center">续费(元)</div>
<label class="layui-col-xs3">
<input name="first_number[]" value="{$item.first_number|default='1'}" data-blur-number="0" class="layui-input text-center padding-left-0">
</label>
<label class="layui-col-xs3">
<input name="first_amount[]" value="{$item.first_amount|default='0.00'}" data-blur-number="2" class="layui-input text-center padding-left-0">
</label>
<label class="layui-col-xs3">
<input name="next_number[]" value="{$item.next_number|default='1'}" data-blur-number="0" class="layui-input text-center padding-left-0">
</label>
<label class="layui-col-xs3">
<input name="next_amount[]" value="{$item.next_amount|default='0.00'}" data-blur-number="2" class="layui-input text-center padding-left-0">
</label>
</div>
</div>
</fieldset>

View File

@ -0,0 +1,98 @@
<div class='layui-form layui-card layui-hide' id="RegionContainer">
<div class="layui-card-body padding-20 padding-bottom-0">
<div class="layui-row layui-col-space10">
<div class="layui-col-xs8">
<div class="layui-textarea" style="height:360px;overflow:auto">
<div>
<span class="pointer notselect margin-right-10" ng-click="setCheckAll(true)">全选</span>
<span class="pointer notselect margin-right-10" ng-click="setCheckAll(false)">取消</span>
</div>
<hr class="hr-line-dashed margin-top-5 margin-bottom-5">
<div class="layui-row layui-col-space5">
<div class="layui-col-xs3 nowrap" data-city-left ng-repeat="x in citys">
<label class="think-checkbox margin-right-0">
<input type="checkbox" ng-model="x.status" ng-change="setActiveCity(x)" ng-value="x.name" lay-ignore>
</label>
<span class="pointer notselect" ng-click="setActiveCity(x)">{{x.name}}</span>
</div>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-textarea" style="height:360px;overflow:auto">
<div>
<span class="pointer notselect margin-right-10" ng-click="setCheckItem(true)">全选</span>
<span class="pointer notselect margin-right-10" ng-click="setCheckItem(false)">取消</span>
<b ng-bind="city.name"></b>
</div>
<hr class="hr-line-dashed margin-top-5 margin-bottom-5">
<label ng-repeat="x in city.sub" class="think-checkbox nowrap layui-elip">
<input type="checkbox" ng-model="x.status" ng-value="x.name" value="" lay-ignore> {{x.name}}
</label>
</div>
</div>
</div>
<div class="layui-form-item layui-hide">{{items}}</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
<button class="layui-btn" ng-click="submit()">确定选择</button>
<button class="layui-btn layui-btn-danger" data-close>取消编辑</button>
</div>
</div>
</div>
<label class="layui-hide">
<textarea id="CitysData">{$citys|json_encode|raw}</textarea>
</label>
<script>
require(['angular'], function () {
var app = angular.module("RegionContainer", []).run(callback);
angular.bootstrap(document.getElementById(app.name), [app.name]);
function callback($rootScope) {
$rootScope.items = [];
$rootScope.city = {sub: []};
$rootScope.citys = angular.fromJson($('#CitysData').val()) || [];
$rootScope.setCheckAll = function (status) {
$rootScope.citys.forEach(function (item) {
item.status = !!status;
item.sub.forEach(function (item) {
item.status = !!status;
});
})
};
$rootScope.submit = function () {
top.setCitys($rootScope.items);
};
$rootScope.setCheckItem = function (status) {
$rootScope.city.sub.forEach(function (item) {
item.status = !!status;
});
};
$rootScope.setActiveCity = function (city) {
$rootScope.city = city;
city.sub.forEach(function (item) {
item.status = city.status;
});
};
$rootScope.$watch('citys', function () {
let citys = [], full = 1;
$rootScope.citys.forEach(function (item) {
let subs = [];
item.sub.forEach(function (item) {
if (item.status) subs.push(item.name)
});
subs.length === item.sub.length ? subs = [] : full = 0;
item.status ? citys.push({name: item.name, subs: subs.join(',')}) : full = 0;
$rootScope.items = full ? [{name: '全国'}] : citys;
});
}, true);
$rootScope.$watch('city', function () {
$rootScope.city.status = $rootScope.city.sub.some(function (city) {
if (city.status) return true;
});
}, true);
}
});
</script>

View File

@ -0,0 +1,66 @@
{extend name="../../admin/view/main"}
{block name="button"}
<!--{if auth("add")}-->
<button data-open='{:url("add")}' data-title="添加邮费模板" class='layui-btn layui-btn-sm layui-btn-primary'>添加邮费模板</button>
<!--{/if}-->
{/block}
{block name="content"}
<div class="layui-badge think-bg-red padding-5 padding-left-10 font-s15 layui-anim layui-anim-upbit">
注意:快递公司配置不能随意修改或删除,会影响到物流路径查询!如需添加新快递请联系客服!
</div>
<div class="layui-tab layui-tab-card think-bg-white">
<div class="layui-tab-content think-box-shadow">
{include file='shop_truck_company/index_search'}
<table class="layui-table" lay-skin="line">
{notempty name='list'}
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<label><input data-auto-none data-check-target='.list-check-box' type='checkbox'></label>
</th>
<th class='list-table-sort-td'>
<button type="button" data-reload class="layui-btn layui-btn-xs"> </button>
</th>
<th class='text-left nowrap'>模板名称</th>
<th class="text-center">创建时间</th>
<th></th>
</tr>
</thead>
{/notempty}
<tbody>
{foreach $list as $key=>$vo}
<tr data-dbclick>
<td class='list-table-check-td think-checkbox'>
<label><input class="list-check-box" value='{$vo.id}' type='checkbox'></label>
</td>
<td class='list-table-sort-td'>
<label>
<input data-action-blur="{:request()->url()}" data-value="id#{$vo.id};action#sort;sort#{value}" data-loading="false" value="{$vo.sort}" class="list-sort-input">
</label>
</td>
<td class='text-left nowrap'>{$vo.name|default=''}</td>
<td class='text-center nowrap'>{$vo.create_at|format_datetime}</td>
<td class='text-left nowrap'>
<!--{if auth("edit")}-->
<a data-dbclick class="layui-btn layui-btn-xs" data-title="编辑快递公司" data-open='{:url("edit")}?id={$vo.id}'> </a>
<!--{/if}-->
<!--{if $vo.status eq 1 and auth("state")}-->
<a class="layui-btn layui-btn-warm layui-btn-xs" data-action="{:url('state')}" data-value="id#{$vo.id};status#0"> </a>
<!--{elseif auth("state")}-->
<a class="layui-btn layui-btn-warm layui-btn-xs" data-action="{:url('state')}" data-value="id#{$vo.id};status#1"> </a>
<!--{/if}-->
<!--{if auth("remove")}-->
<a class="layui-btn layui-btn-danger layui-btn-xs" data-confirm="确定要删除数据吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}"> </a>
<!--{/if}-->
</td>
</tr>
{/foreach}
</tbody>
</table>
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
</div>
</div>
{/block}

View File

@ -0,0 +1,28 @@
<fieldset>
<legend>条件搜索</legend>
<form class="layui-form layui-form-pane form-search" action="{:url('')}" onsubmit="return false" method="get" autocomplete="off">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">快递名称</label>
<div class="layui-input-inline">
<input name="name" value="{:input('name','')}" placeholder="请输入快递名称" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">快递编码</label>
<div class="layui-input-inline">
<input name="code" value="{:input('code','')}" placeholder="请输入快递编码" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">添加时间</label>
<div class="layui-input-inline">
<input data-date-range name="create_at" value="{:input('create_at','')}" placeholder="请选择添加时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
</fieldset>
<script>form.render()</script>