Accept Merge Request #68: (feature/hant -> develop)
Merge Request: 退款数据 Created By: @todayswind Accepted By: @todayswind URL: https://g-bcrc3009.coding.net/p/allocatr/d/allocatr/git/merge/68?initial=true
This commit is contained in:
commit
5d1a7d95f4
|
|
@ -6,6 +6,7 @@ namespace app\admin\controller\statistics;
|
||||||
use app\admin\model\Admin;
|
use app\admin\model\Admin;
|
||||||
use app\admin\model\Order;
|
use app\admin\model\Order;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
|
use think\Db;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use function Symfony\Component\Clock\now;
|
use function Symfony\Component\Clock\now;
|
||||||
|
|
||||||
|
|
@ -17,10 +18,23 @@ use function Symfony\Component\Clock\now;
|
||||||
class Aftersale extends Backend
|
class Aftersale extends Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $relationSearch = true;
|
protected $relationSearch = true,$items,$itemsformattedTree;
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$items = Db::name('item')
|
||||||
|
->where('status', 1)
|
||||||
|
->field(['id', 'title', 'key_word', 'pid'])
|
||||||
|
->order('pid', 'asc')
|
||||||
|
->order('sort', 'desc')
|
||||||
|
->select();
|
||||||
|
$tree = $this->buildTree($items);
|
||||||
|
$formattedTree = $this->formatTree($tree);
|
||||||
|
|
||||||
|
$this->items = $items;
|
||||||
|
$this->itemsformattedTree = $formattedTree;
|
||||||
|
$this->view->assign("items", $formattedTree);
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,15 +53,45 @@ class Aftersale extends Backend
|
||||||
{
|
{
|
||||||
$build = new Admin();
|
$build = new Admin();
|
||||||
$build->alias('a')
|
$build->alias('a')
|
||||||
->join('order b','a.id = b.admin_id','right')
|
->join('order b', 'a.id = b.admin_id', 'right')
|
||||||
->join('aftersale c','b.id = c.admin_id','left')
|
->join('aftersale c', 'b.id = c.admin_id', 'left')
|
||||||
->where('b.status',Order::STATUS_FINISHED);
|
->where('b.status', Order::STATUS_FINISHED);
|
||||||
|
|
||||||
|
|
||||||
|
$start = now()->modify('-30 days')->format('Y-m-d');
|
||||||
|
$end_at = now()->format('Y-m-d 23:29:59');
|
||||||
|
|
||||||
|
|
||||||
|
$filter = request()->get('range', '');
|
||||||
|
if (!empty($filter)) {
|
||||||
|
$arr = explode(' - ', $filter);
|
||||||
|
if (trim($arr[0])) {
|
||||||
|
$start = trim($arr[0]);
|
||||||
|
}
|
||||||
|
if (trim($arr[1])) {
|
||||||
|
$end_at = trim($arr[1]) . ' 23:29:59';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$keyword = request()->get('keyword');
|
||||||
|
|
||||||
|
|
||||||
|
$build->where('audit_time', '>=', $start);
|
||||||
|
$build->where('audit_time', '<=', $end_at);
|
||||||
|
|
||||||
|
if (!is_null($keyword)) {
|
||||||
|
$build->where(function ($q) use ($keyword) {
|
||||||
|
$q->where('nickname', 'like', '%' . $keyword . '%')
|
||||||
|
->whereor('mobile', 'like', '%' . $keyword . '%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$build->group('a.id');
|
$build->group('a.id');
|
||||||
$build->field(
|
$build->field(
|
||||||
[
|
[
|
||||||
'a.id',
|
'a.id',
|
||||||
'a.nickname',
|
'a.nickname',
|
||||||
|
'a.mobile',
|
||||||
'count(b.id) order_total',
|
'count(b.id) order_total',
|
||||||
'count(c.id) after_total',
|
'count(c.id) after_total',
|
||||||
]
|
]
|
||||||
|
|
@ -57,31 +101,146 @@ class Aftersale extends Backend
|
||||||
$total = $res->total();
|
$total = $res->total();
|
||||||
$ress = $res->items();
|
$ress = $res->items();
|
||||||
// dd(Admin::getLastSql());
|
// dd(Admin::getLastSql());
|
||||||
|
$data = [];
|
||||||
|
foreach ($ress as $res) {
|
||||||
|
$item = $res->toArray();
|
||||||
|
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
|
||||||
|
$data [] = $item;
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
'rows' => $ress,
|
'rows' => $data,
|
||||||
'total' => $total
|
'total' => $total
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function city()
|
||||||
|
{
|
||||||
|
$build = new Order();
|
||||||
|
$build->alias('a')
|
||||||
|
->join('aftersale c', 'a.id = c.order_id', 'left')
|
||||||
|
->where('a.status', Order::STATUS_FINISHED);
|
||||||
|
|
||||||
|
$start = now()->modify('-30 days')->format('Y-m-d');
|
||||||
|
$end_at = now()->format('Y-m-d 23:29:59');
|
||||||
|
$area_code = request()->get('area_id');
|
||||||
|
$filter = request()->get('range', '');
|
||||||
|
if (!empty($filter)) {
|
||||||
|
$arr = explode(' - ', $filter);
|
||||||
|
if (trim($arr[0])) {
|
||||||
|
$start = trim($arr[0]);
|
||||||
|
}
|
||||||
|
if (trim($arr[1])) {
|
||||||
|
$end_at = trim($arr[1]) . ' 23:29:59';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$build->where('audit_time', '>=', $start);
|
||||||
|
$build->where('audit_time', '<=', $end_at);
|
||||||
|
$build->group('a.area_id');
|
||||||
|
|
||||||
|
|
||||||
|
if ($area_code) {
|
||||||
|
$build->where('area_id', 'like', $this->getSelectAreaCode($area_code) . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
$build->field(
|
||||||
|
[
|
||||||
|
'a.area_id',
|
||||||
|
'count(a.id) order_total',
|
||||||
|
'count(c.id) after_total',
|
||||||
|
]
|
||||||
|
)->with([
|
||||||
|
'area' => function ($q) {
|
||||||
|
$q->field('id,area_code,merge_name');
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
$res = $build->paginate();
|
||||||
|
$total = $res->total();
|
||||||
|
$ress = $res->items();
|
||||||
|
// dd(Admin::getLastSql());
|
||||||
|
$data = [];
|
||||||
|
foreach ($ress as $res) {
|
||||||
|
$item = $res->toArray();
|
||||||
|
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
|
||||||
|
$data [] = $item;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'rows' => $data,
|
||||||
|
'total' => $total
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function item()
|
||||||
|
{
|
||||||
|
$build = new Order();
|
||||||
|
$build->alias('a')
|
||||||
|
->join('aftersale c', 'a.id = c.order_id', 'left')
|
||||||
|
->where('a.status', Order::STATUS_FINISHED);
|
||||||
|
|
||||||
|
$start = now()->modify('-30 days')->format('Y-m-d');
|
||||||
|
$end_at = now()->format('Y-m-d 23:29:59');
|
||||||
|
$area_code = request()->get('area_id');
|
||||||
|
$filter = request()->get('range', '');
|
||||||
|
if (!empty($filter)) {
|
||||||
|
$arr = explode(' - ', $filter);
|
||||||
|
if (trim($arr[0])) {
|
||||||
|
$start = trim($arr[0]);
|
||||||
|
}
|
||||||
|
if (trim($arr[1])) {
|
||||||
|
$end_at = trim($arr[1]) . ' 23:29:59';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$build->where('audit_time', '>=', $start);
|
||||||
|
$build->where('audit_time', '<=', $end_at);
|
||||||
|
$build->group('a.item_title');
|
||||||
|
|
||||||
|
|
||||||
|
if ($area_code) {
|
||||||
|
$build->where('area_id', 'like', $this->getSelectAreaCode($area_code) . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
$build->field(
|
||||||
|
[
|
||||||
|
'a.item_title',
|
||||||
|
'count(a.id) order_total',
|
||||||
|
'count(c.id) after_total',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$res = $build->paginate();
|
||||||
|
$total = $res->total();
|
||||||
|
$ress = $res->items();
|
||||||
|
// dd(Admin::getLastSql());
|
||||||
|
$data = [];
|
||||||
|
foreach ($ress as $res) {
|
||||||
|
$item = $res->toArray();
|
||||||
|
$item['rate'] = $this->mydiv($item['after_total'],$item['order_total']) . '%';
|
||||||
|
$data [] = $item;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'rows' => $data,
|
||||||
|
'total' => $total
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mydiv($a, $b, int $scale = 4, $is_percent = true): int|string
|
||||||
|
{
|
||||||
|
$val = $b > 0 ? bcdiv($a, $b, $scale) : 0;
|
||||||
|
|
||||||
|
if ($is_percent) {
|
||||||
|
|
||||||
|
return bcmul($val, 100, 2);
|
||||||
|
}
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,6 @@ class Item extends Backend
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,189 +7,193 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form id="add-form" class="row" role="form" data-toggle="validator" method="POST" action="">
|
<form id="add-form" class="row" role="form" data-toggle="validator" method="POST" action="">
|
||||||
<div class="form-group col-xs-6">
|
<div class="col-lg-4">
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Customer')}:</label>
|
<div class="form-group col-xs-12">
|
||||||
<div class="col-xs-12 col-sm-8">
|
<label class="control-label col-xs-12 col-lg-4">{:__('Customer')}:</label>
|
||||||
<input id="c-customer" data-rule="required" class="form-control" name="row[customer]" type="text">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input id="c-customer" data-rule="required" class="form-control" name="row[customer]" type="text">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group col-xs-12">
|
||||||
<div class="form-group col-xs-6">
|
<label class="control-label col-xs-12 col-lg-4">{:__('Tel')}:</label>
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Tel')}:</label>
|
<div class="col-xs-12 col-sm-8">
|
||||||
<div class="col-xs-12 col-sm-8">
|
<input id="c-tel" data-rule="required" class="form-control" name="row[tel]" type="number">
|
||||||
<input id="c-tel" data-rule="required" class="form-control" name="row[tel]" type="number">
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Source')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<select id="c-source" data-live-search="true" title="请选择" data-rule="required" name="row[source]" class="form-control selectpicker show-tick">
|
|
||||||
{foreach $sources as $item}
|
|
||||||
<option data-subtext="{$item['ptitle']}" value="{$item['id']}">{$item['title']}</option>
|
|
||||||
{/foreach}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
<div class="form-group col-xs-6">
|
<label class="control-label col-xs-12 col-lg-4">{:__('Area_id')}:</label>
|
||||||
<label class="control-label col-xs-12 col-sm-3">来源订单ID:</label>
|
<div class='col-xs-12 col-sm-8'>
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input id="c-source-id" name="row[source_uid]" type="text" class="form-control">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">录单员:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<select id="c-users" data-live-search="true" title="不选择默认当前登陆账号" name="row[admin_id]" class="form-control selectpicker show-tick">
|
|
||||||
<option value="-1">不选择默认当前登陆账号</option>
|
|
||||||
{foreach $users as $item}
|
|
||||||
<option value="{$item['id']}">{$item['nickname']}</option>
|
|
||||||
{/foreach}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">派单方式:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<select data-live-search="true" name="row[dispatch_type]" class="form-control selectpicker show-tick">
|
|
||||||
<option value="1">手动派单</option>
|
|
||||||
<option selected value="2">自动派单</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">收款方式:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<select name="row[receive_type]" class="form-control selectpicker">
|
|
||||||
<option selected value="1">已收定金</option>
|
|
||||||
<option value="2">已收全款</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">收款金额:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input data-rule="required" name="row[online_amount]" class="form-control" type="number">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Area_id')}:</label>
|
|
||||||
<div class='col-xs-12 col-sm-8'>
|
|
||||||
<input id="c-city" data-rule="required" class="form-control" data-toggle="city-picker" type="text" value="" />
|
<input id="c-city" data-rule="required" class="form-control" data-toggle="city-picker" type="text" value="" />
|
||||||
<input id="area_id" style="display: none" class="form-control" name="row[area_id]" hidden type="text" value="" />
|
<input id="area_id" style="display: none" class="form-control" name="row[area_id]" hidden type="text" value="" />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Address')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input id="c-address" data-rule="required"
|
|
||||||
class="form-control"
|
|
||||||
readonly
|
|
||||||
name="row[address]"
|
|
||||||
type="text">
|
|
||||||
<div class="btn btn-primary" style="margin-top: 20px" id="area_map"
|
|
||||||
data-input-id="c-address"
|
|
||||||
data-lng-id="lng"
|
|
||||||
data-lat-id="lat">地图查找</div>
|
|
||||||
<input type="text" style="display: none"
|
|
||||||
name="row[lng]" id="lng" >
|
|
||||||
<input type="text" style="display: none"
|
|
||||||
name="row[lat]" id="lat">
|
|
||||||
<input type="text" style="display: none" id="area_name">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div class="col-xs-6">-->
|
|
||||||
<!-- <p style="display: inline-block" class="control-label col-xs-12 col-sm-3">-->
|
|
||||||
<!-- 未能找到使用-->
|
|
||||||
<!-- </p>-->
|
|
||||||
<!-- <div class="col-xs-12 col-sm-8" >-->
|
|
||||||
<!-- <span class="btn btn-primary" data-toggle="addresspicker"-->
|
|
||||||
<!-- data-input-id="c-address"-->
|
|
||||||
<!-- data-lng-id="lng"-->
|
|
||||||
<!-- data-lat-id="lat">地图查找</span>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Coupons')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<select id="c-coupon" data-live-search="true" title="请选择" data-rule="required" name="row[coupon_id]" class="form-control selectpicker show-tick">
|
|
||||||
<option selected value="0">不使用优惠</option>
|
|
||||||
{foreach $coupons as $item}
|
|
||||||
<option data-subtext="{$item['description']}" value="{$item['id']}">{$item['code']}</option>
|
|
||||||
{/foreach}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">上门时间:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input data-rule="required" name="row[plan_time]" class="form-control datetimepicker">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Item_title')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<input type="text" id="item_id" class="zd-input__inner">
|
|
||||||
<input type="text" id="item_id_value" style="display: none" name="row[item_id]" class="zd-input__inner">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Detail')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<textarea id="c-detail" rows="4" style="width: 100%;resize: vertical" class="form-control" name="row[detail]"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Remark')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
|
|
||||||
<textarea id="c-remark" rows="4" style="width: 100%;resize: vertical" class="form-control" name="row[remark]" ></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-6">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3">{:__('Images')}:</label>
|
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<div class="input-group">
|
|
||||||
<input id="c-images" class="form-control" size="50" name="row[images]" type="text">
|
|
||||||
<div class="input-group-addon no-border no-padding">
|
|
||||||
<span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
|
||||||
<span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
|
||||||
</div>
|
|
||||||
<span class="msg-box n-right" for="c-images"></span>
|
|
||||||
</div>
|
</div>
|
||||||
<ul class="row list-inline faupload-preview" id="p-images"></ul>
|
</div>
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Address')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<div class="myform-group">
|
||||||
|
<input id="c-address" data-rule="required"
|
||||||
|
class="form-control"
|
||||||
|
readonly
|
||||||
|
name="row[address]"
|
||||||
|
type="text">
|
||||||
|
<div class="btn btn-primary" id="area_map"
|
||||||
|
data-input-id="c-address"
|
||||||
|
data-lng-id="lng"
|
||||||
|
data-lat-id="lat">地图查找</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" style="display: none"
|
||||||
|
name="row[lng]" id="lng" >
|
||||||
|
<input type="text" style="display: none"
|
||||||
|
name="row[lat]" id="lat">
|
||||||
|
<input type="text" style="display: none" id="area_name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Item_title')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input type="text" id="item_id" class="zd-input__inner">
|
||||||
|
<input type="text" id="item_id_value" style="display: none" name="row[item_id]" class="zd-input__inner">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Detail')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<textarea id="c-detail" placeholder="待填" rows="8" style="width: 100%;resize: vertical" class="form-control" name="row[detail]"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">上门时间:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input data-rule="required" name="row[plan_time]" class="form-control datetimepicker">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Images')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="c-images" class="form-control" size="50" name="row[images]" type="text">
|
||||||
|
<div class="input-group-addon no-border no-padding">
|
||||||
|
<span><button type="button" id="faupload-images" class="btn btn-danger faupload" data-input-id="c-images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||||
|
<span><button type="button" id="fachoose-images" class="btn btn-primary fachoose" data-input-id="c-images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||||
|
</div>
|
||||||
|
<span class="msg-box n-right" for="c-images"></span>
|
||||||
|
</div>
|
||||||
|
<ul class="row list-inline faupload-preview" id="p-images"></ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-xs-6 layer-footer">
|
|
||||||
<label class="control-label col-xs-12 col-sm-3"></label>
|
<div class="col-lg-4">
|
||||||
<div class="col-xs-12 col-sm-8">
|
|
||||||
<button id="mysubmit" class="btn btn-primary btn-embossed">录入并清空</button>
|
<div class="form-group col-xs-12">
|
||||||
<button id="mybuttom" class="btn btn-primary btn-embossed">录入并保留信息</button>
|
<label class="control-label col-xs-12 col-lg-4">{:__('Source')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<select id="c-source" data-live-search="true" title="请选择" data-rule="required" name="row[source]" class="form-control selectpicker show-tick">
|
||||||
|
{foreach $sources as $item}
|
||||||
|
<option data-subtext="{$item['ptitle']}" value="{$item['id']}">{$item['title']}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">来源订单ID:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input id="c-source-id" name="row[source_uid]" type="text" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">派单方式:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<select data-live-search="true" name="row[dispatch_type]" class="form-control selectpicker show-tick">
|
||||||
|
<option value="1">手动派单</option>
|
||||||
|
<option selected value="2">自动派单</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">收款方式:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<select name="row[receive_type]" class="form-control selectpicker">
|
||||||
|
<option selected value="1">已收定金</option>
|
||||||
|
<option value="2">已收全款</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">收款金额:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input data-rule="required" name="row[online_amount]" class="form-control" type="number">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Coupons')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<select id="c-coupon" data-live-search="true" title="请选择" data-rule="required" name="row[coupon_id]" class="form-control selectpicker show-tick">
|
||||||
|
<option selected value="0">不使用优惠</option>
|
||||||
|
{foreach $coupons as $item}
|
||||||
|
<option data-subtext="{$item['description']}" value="{$item['id']}">{$item['code']}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">录单员:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<select id="c-users" data-live-search="true" title="不选择默认当前登陆账号" name="row[admin_id]" class="form-control selectpicker show-tick">
|
||||||
|
<option value="-1">不选择默认当前登陆账号</option>
|
||||||
|
{foreach $users as $item}
|
||||||
|
<option value="{$item['id']}">{$item['nickname']}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12">
|
||||||
|
<label class="control-label col-xs-12 col-lg-4">{:__('Remark')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
||||||
|
<textarea id="c-remark" placeholder="待填" rows="8" style="width: 100%;resize: vertical" class="form-control" name="row[remark]" ></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-xs-12 layer-footer text-right">
|
||||||
|
<div class="col-xs-12 col-sm-12">
|
||||||
|
<button id="mysubmit" class="btn btn-primary btn-embossed">录入并清空</button>
|
||||||
|
<button id="mybuttom" class="btn btn-primary btn-embossed">录入并保留信息</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<h5 class=" col-md-12 text-left">快速输入:</h5>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-floating">
|
||||||
|
<textarea rows="8" style="width: 100%;resize: vertical" class="form-control" placeholder="复制内容,快速输入" id="smart_text"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 mt-2">
|
||||||
|
<button id="smart" class="btn btn-primary btn-embossed">智能识别</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h5 class="text-left">快速输入</h5>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-floating">
|
|
||||||
<textarea rows="8" style="width: 100%;resize: vertical" class="form-control" placeholder="复制内容,快速输入" id="smart_text"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button id="smart" class="btn btn-primary btn-embossed">智能识别</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -202,6 +206,9 @@
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
.myform-group{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -227,6 +234,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.function-area {
|
.function-area {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
@ -254,7 +263,7 @@
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
}
|
}
|
||||||
.control-label{
|
.control-label{
|
||||||
text-align: right;
|
text-align: left;
|
||||||
}
|
}
|
||||||
.col-xs-12{
|
.col-xs-12{
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
|
|
||||||
|
|
@ -175,26 +175,57 @@
|
||||||
<div class="panel-body" style="height: 100%">
|
<div class="panel-body" style="height: 100%">
|
||||||
<div id="myTabContent" class="tab-content" style="height: 100%">
|
<div id="myTabContent" class="tab-content" style="height: 100%">
|
||||||
<div class="tab-pane fade active in" style="height: 100%" id="first">
|
<div class="tab-pane fade active in" style="height: 100%" id="first">
|
||||||
|
|
||||||
<div id="chart-filter-table" style="margin-top:20px;margin-bottom: 30px;">
|
<div id="chart-filter-table" style="margin-top:20px;margin-bottom: 30px;">
|
||||||
<div style="display: inline-block;width: 200px;position: relative">
|
<div style="display: flex;position: relative" class="col-sm-6 row">
|
||||||
|
<input type="text" class="form-control mr-2" id="keyword" placeholder="名称/电话号码" >
|
||||||
<input type="text" class="form-control datetimerange" data-locale='{"format":"YYYY-MM-DD"}'
|
<input type="text" class="form-control datetimerange" data-locale='{"format":"YYYY-MM-DD"}'
|
||||||
placeholder="指定日期" name="filter[daterange]" id="daterange-table" autocomplete="off" style="width: 180px;">
|
placeholder="指定日期" name="filter[daterange]" id="daterange-table" autocomplete="off" style="width: 180px;">
|
||||||
|
<button class="btn btn-default ml-2" id="first-search">查询</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 查询按钮 -->
|
<!-- 查询按钮 -->
|
||||||
<button class="btn btn-default" id="first-search" style="margin-left: 15px;">查询</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
</div>
|
||||||
<section class="connectedSortable" style="height: 100%">
|
<section class="connectedSortable" style="height: 100%">
|
||||||
<table id="table1" class="table table-striped table-bordered table-hover" width="100%">
|
<table id="table1" class="table table-striped table-bordered table-hover" width="100%">
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="second">
|
<div class="tab-pane fade" id="second">
|
||||||
|
|
||||||
|
<div id="chart-filter-table2" style="margin-top:20px;margin-bottom: 30px;">
|
||||||
|
<div style="display: flex;position: relative" class="col-sm-6 row">
|
||||||
|
|
||||||
|
<div style="display: inline-block;width: 300px;position: absolute">
|
||||||
|
<input id="city-search" data-rule="required" class="form-control" data-toggle="city-picker" type="text" />
|
||||||
|
<input id="area_id" style="display: none" class="form-control" name="area_id" hidden type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="text" class="form-control datetimerange" data-locale='{"format":"YYYY-MM-DD"}'
|
||||||
|
placeholder="指定日期" name="filter[daterange]" id="daterange-table2" autocomplete="off" style="position: absolute;left: 320px;width: 180px;">
|
||||||
|
<button class="btn btn-default ml-2" id="first-search2" style="position: absolute;left: 500px;">查询</button>
|
||||||
|
</div>
|
||||||
|
<!-- 查询按钮 -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<table id="table2" class="table table-striped table-bordered table-hover" width="100%">
|
<table id="table2" class="table table-striped table-bordered table-hover" width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="third">
|
<div class="tab-pane fade" id="third">
|
||||||
|
|
||||||
|
<div id="chart-filter-table3" style="margin-top:20px;margin-bottom: 30px;">
|
||||||
|
<div style="display: flex;position: relative" class="col-sm-6 row">
|
||||||
|
|
||||||
|
<input type="text" id="item_id" class="zd-input__inner mr-2" style="width: 275px">
|
||||||
|
<input type="text" id="item_id_value" style="display: none" name="row[item_id]">
|
||||||
|
<input type="text" class="form-control datetimerange ml-2" data-locale='{"format":"YYYY-MM-DD"}'
|
||||||
|
placeholder="指定日期" name="filter[daterange]" id="daterange-table3" autocomplete="off" style="width: 180px;">
|
||||||
|
<button class="btn btn-default ml-2" id="first-search3">查询</button>
|
||||||
|
</div>
|
||||||
|
<!-- 查询按钮 -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<table id="table3" class="table table-striped table-bordered table-hover" width="100%">
|
<table id="table3" class="table table-striped table-bordered table-hover" width="100%">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -210,3 +241,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<link rel="stylesheet" href="/assets/css/select.css">
|
||||||
|
<script>
|
||||||
|
var items = {:json_encode($items); };
|
||||||
|
</script>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-theme', 'template', 'addtabs', 'moment','citypicker'], function ($, undefined, Backend, Table, Form, echarts, undefined, Template, Datatable, Moment) {
|
define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'addtabs', 'moment','citypicker','cascader'], function
|
||||||
|
($, undefined, Backend, Table, Form,Template,undefined, Moment) {
|
||||||
|
|
||||||
var Controller = {
|
var Controller = {
|
||||||
|
|
||||||
|
|
@ -10,7 +11,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
if (tabVal === 'first') {
|
if (tabVal === 'first') {
|
||||||
Controller.api.first();
|
Controller.api.first();
|
||||||
}else if (tabVal === 'second') {
|
}else if (tabVal === 'second') {
|
||||||
|
console.log(3333);
|
||||||
Controller.api.second();
|
Controller.api.second();
|
||||||
|
}else if (tabVal === 'third'){
|
||||||
|
Controller.api.third();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Controller.api.first();
|
Controller.api.first();
|
||||||
|
|
@ -37,11 +41,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
searchFormVisible: true,
|
searchFormVisible: true,
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{field: 'nickname', title: '项目类型', operate: false},
|
{field: 'nickname', title: '名称', operate: false},
|
||||||
|
{field: 'mobile', title: '电话', operate: false},
|
||||||
{field: 'order_total', title: '订单总数', operate: false},
|
{field: 'order_total', title: '订单总数', operate: false},
|
||||||
{field: 'after_total', title: '退款订单数', operate: false},
|
{field: 'after_total', title: '退款订单数', operate: false},
|
||||||
{field: 'after_total', title: '退款率', operate: false},
|
{field: 'rate', title: '退款率', operate: false},
|
||||||
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -51,10 +55,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
$('#first-search').on('click', function () {
|
$('#first-search').on('click', function () {
|
||||||
|
|
||||||
const range = $('#daterange-table').val();
|
const range = $('#daterange-table').val();
|
||||||
|
const keyword = $('#keyword').val();
|
||||||
let data = '';
|
let data = '';
|
||||||
if (range !== ''){
|
if (range !== ''){
|
||||||
data += 'range=' + range;
|
data += 'range=' + range;
|
||||||
}
|
}
|
||||||
|
if (keyword !== ''){
|
||||||
|
data += '&keyword=' + keyword;
|
||||||
|
}
|
||||||
// data = encodeURIComponent(data);
|
// data = encodeURIComponent(data);
|
||||||
$("#table1").bootstrapTable('refresh',{
|
$("#table1").bootstrapTable('refresh',{
|
||||||
url:'statistics/aftersale/dispatch?' + data,
|
url:'statistics/aftersale/dispatch?' + data,
|
||||||
|
|
@ -67,7 +75,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
// 表格2
|
// 表格2
|
||||||
var table = $("#table2");
|
var table = $("#table2");
|
||||||
table.bootstrapTable({
|
table.bootstrapTable({
|
||||||
url: 'statistics/aftersale/dispatch',
|
url: 'statistics/aftersale/city',
|
||||||
sortName: 'id',
|
sortName: 'id',
|
||||||
search: false,
|
search: false,
|
||||||
commonSearch: false,
|
commonSearch: false,
|
||||||
|
|
@ -78,10 +86,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
searchFormVisible: true,
|
searchFormVisible: true,
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{field: 'nickname', title: '项目类型', operate: false},
|
{field: 'area.merge_name', title: '城市', operate: false},
|
||||||
{field: 'order_total', title: '订单总数', operate: false},
|
{field: 'order_total', title: '订单总数', operate: false},
|
||||||
{field: 'after_total', title: '退款订单数', operate: false},
|
{field: 'after_total', title: '退款订单数', operate: false},
|
||||||
{field: 'after_total', title: '退款率', operate: false},
|
{field: 'rate', title: '退款率', operate: false},
|
||||||
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
@ -89,19 +97,70 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
// 为表格2绑定事件
|
// 为表格2绑定事件
|
||||||
Table.api.bindevent(table);
|
Table.api.bindevent(table);
|
||||||
|
|
||||||
$('#first-search').on('click', function () {
|
$('#first-search2').on('click', function () {
|
||||||
|
|
||||||
const range = $('#daterange-table').val();
|
const range = $('#daterange-table2').val();
|
||||||
|
const area_id = $('#area_id').val();
|
||||||
let data = '';
|
let data = '';
|
||||||
if (range !== ''){
|
if (range !== ''){
|
||||||
data += 'range=' + range;
|
data += 'range=' + range;
|
||||||
}
|
}
|
||||||
|
if (area_id !== ''){
|
||||||
|
data += 'area_id=' + area_id;
|
||||||
|
}
|
||||||
// data = encodeURIComponent(data);
|
// data = encodeURIComponent(data);
|
||||||
$("#table1").bootstrapTable('refresh',{
|
$("#table2").bootstrapTable('refresh',{
|
||||||
url:'statistics/aftersale/dispatch?' + data,
|
url:'statistics/aftersale/city?' + data,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Controller.api.areapicker();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
third: function (){
|
||||||
|
Table.api.init();
|
||||||
|
// 表格2
|
||||||
|
var table = $("#table3");
|
||||||
|
table.bootstrapTable({
|
||||||
|
url: 'statistics/aftersale/item',
|
||||||
|
sortName: 'id',
|
||||||
|
search: false,
|
||||||
|
commonSearch: false,
|
||||||
|
visible: false,
|
||||||
|
showToggle: false,
|
||||||
|
showColumns: false,
|
||||||
|
showExport: true,
|
||||||
|
searchFormVisible: true,
|
||||||
|
columns: [
|
||||||
|
[
|
||||||
|
{field: 'item_title', title: '服务项目', operate: false},
|
||||||
|
{field: 'order_total', title: '订单总数', operate: false},
|
||||||
|
{field: 'after_total', title: '退款订单数', operate: false},
|
||||||
|
{field: 'rate', title: '退款率', operate: false},
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
// 为表格2绑定事件
|
||||||
|
Table.api.bindevent(table);
|
||||||
|
|
||||||
|
$('#first-search3').on('click', function () {
|
||||||
|
|
||||||
|
const range = $('#daterange-table3').val();
|
||||||
|
const item_id = $('#item_id_value').val();
|
||||||
|
let data = '';
|
||||||
|
if (range !== ''){
|
||||||
|
data += 'range=' + range;
|
||||||
|
}
|
||||||
|
if (item_id !== ''){
|
||||||
|
data += 'item_id=' + item_id;
|
||||||
|
}
|
||||||
|
// data = encodeURIComponent(data);
|
||||||
|
$("#table3").bootstrapTable('refresh',{
|
||||||
|
url:'statistics/aftersale/item?' + data,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Controller.api.itemspicker();
|
||||||
},
|
},
|
||||||
datepicker: function () {
|
datepicker: function () {
|
||||||
var ranges = {};
|
var ranges = {};
|
||||||
|
|
@ -143,6 +202,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
areapicker: function () {
|
||||||
|
$("#city-search").citypicker();
|
||||||
|
|
||||||
|
$("#city-search").on("cp:updated", function() {
|
||||||
|
var citypicker = $(this).data("citypicker");
|
||||||
|
var code = citypicker.getCode("district") || citypicker.getCode("city") || citypicker.getCode("province");
|
||||||
|
// table.bootstrapTable('refresh',{query: {area_code: code}});
|
||||||
|
$('#area_id').val(code);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
itemspicker: function () {
|
||||||
|
var _data = items;
|
||||||
|
$('#item_id').zdCascader({
|
||||||
|
data: _data,
|
||||||
|
onChange: function ($this, data, allPathData) {
|
||||||
|
// console.log(data,allPathData);
|
||||||
|
$('#item_id_value').val(data.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Controller;
|
return Controller;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
function ZdCascader(el, options) {
|
function ZdCascader(el, options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
if (options.search) this.getLabelList();
|
||||||
this.CLASS = ZdCascader.CLASS;
|
this.CLASS = ZdCascader.CLASS;
|
||||||
this.$el = $(el); //input
|
this.$el = $(el); //input
|
||||||
this.$el_ = this.$el.clone();
|
this.$el_ = this.$el.clone();
|
||||||
|
|
@ -49,8 +50,8 @@
|
||||||
ZdCascader.DEFAULTS = {
|
ZdCascader.DEFAULTS = {
|
||||||
data: null, //支持格式[{value:"",label:"",children:[{value:"",label:""}]}]
|
data: null, //支持格式[{value:"",label:"",children:[{value:"",label:""}]}]
|
||||||
range: ' / ', //分割符
|
range: ' / ', //分割符
|
||||||
onChange: function (data) {},
|
search: true, //搜索
|
||||||
defaultValue: null // 新增 defaultValue 属性
|
onChange: function (data) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZdCascader.METHODS = ['reload', 'destroy'];
|
ZdCascader.METHODS = ['reload', 'destroy'];
|
||||||
|
|
@ -68,8 +69,7 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
//最外层容器
|
//最外层容器
|
||||||
this.$container = this.$el.wrap(`<div class="${this.CLASS.wrap}"></div>`)
|
this.$container = this.$el.wrap(`<div class="${this.CLASS.wrap}"></div>`)
|
||||||
.wrap(`<div class="${this.CLASS.inputwrap}"></div>`).addClass(this.CLASS.input).prop('readonly', true)
|
.wrap(`<div class="${this.CLASS.inputwrap}"></div>`).addClass(this.CLASS.input).prop('readonly', !this.options.search).closest('.' + this.CLASS.wrap);
|
||||||
.closest('.' + this.CLASS.wrap);
|
|
||||||
|
|
||||||
//文本框右侧图标
|
//文本框右侧图标
|
||||||
this.$arrow = $(`<span class="zd-input__suffix">
|
this.$arrow = $(`<span class="zd-input__suffix">
|
||||||
|
|
@ -85,7 +85,6 @@
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
</span>`).insertAfter(this.$el);
|
</span>`).insertAfter(this.$el);
|
||||||
|
|
||||||
//下拉列表
|
//下拉列表
|
||||||
this.$dropdownWrap = $(`<div class="${this.CLASS.dropdownPanel}"></div>`).appendTo(this.$container).wrap(`<div class="${this.CLASS.dropdownWrap}"></div>`);
|
this.$dropdownWrap = $(`<div class="${this.CLASS.dropdownPanel}"></div>`).appendTo(this.$container).wrap(`<div class="${this.CLASS.dropdownWrap}"></div>`);
|
||||||
|
|
||||||
|
|
@ -107,9 +106,14 @@
|
||||||
this.$container.removeClass(this.CLASS.checkClass.wrapFocus);
|
this.$container.removeClass(this.CLASS.checkClass.wrapFocus);
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
this.$container.on('click.item', '.' + this.CLASS.menuNode, $.proxy(this._nodeClick, this));
|
this.$container.on('click.item', '.' + this.CLASS.menuNode, $.proxy(this._nodeClick, this))
|
||||||
|
.on('dblclick.item', '.' + this.CLASS.menuNode, $.proxy(this._nodeDoubleClick, this));
|
||||||
|
|
||||||
this.$el.on('keyup.wrap', $.proxy(this._keyup, this));
|
this.$el.on('keyup.wrap', $.proxy(this._keyup, this));
|
||||||
|
|
||||||
|
this.$el.on('input', $.proxy(function (event) {
|
||||||
|
this.search(this.$el.val())
|
||||||
|
}, this));
|
||||||
}
|
}
|
||||||
ZdCascader.prototype._wrapClick = function () {
|
ZdCascader.prototype._wrapClick = function () {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -147,13 +151,38 @@
|
||||||
$that.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
|
$that.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
|
||||||
this.$el.data('bindData', data);
|
this.$el.data('bindData', data);
|
||||||
this.$el.data('bindPathData', allPathData);
|
this.$el.data('bindPathData', allPathData);
|
||||||
console.log(allPathData);
|
|
||||||
if (this.options.onChange && typeof this.options.onChange === "function")
|
if (this.options.onChange && typeof this.options.onChange === "function")
|
||||||
this.options.onChange(this, data, allPathData);
|
this.options.onChange(this, data, allPathData);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
} else
|
} else
|
||||||
this._loadChildren($that);
|
this._loadChildren($that);
|
||||||
}
|
}
|
||||||
|
ZdCascader.prototype._nodeDoubleClick = function (event) {
|
||||||
|
var $that = event.currentTarget ? $(event.currentTarget) : $(event); // li
|
||||||
|
var $wrap = $that.closest('.' + this.CLASS.menuWrap);
|
||||||
|
$that.addClass(this.CLASS.checkClass.menuNodeSelected).siblings().removeClass(this.CLASS.checkClass.menuNodeSelected);
|
||||||
|
var data = $that.data('bindData');
|
||||||
|
$wrap.nextAll().remove(); // 移除所有后续级别
|
||||||
|
var prevWrap = $wrap.prevAll();
|
||||||
|
var value = data.label;
|
||||||
|
var allPathData = [data];
|
||||||
|
$.each(prevWrap, (i, m) => {
|
||||||
|
var selectedData = $(m).find('li.' + this.CLASS.checkClass.menuNodeSelected).data('bindData');
|
||||||
|
value = selectedData.label + this.options.range + value;
|
||||||
|
allPathData.push(selectedData);
|
||||||
|
});
|
||||||
|
this.$el.val(value).focus();
|
||||||
|
this.$container.removeClass(this.CLASS.checkClass.wrapFocus);
|
||||||
|
this.$dropdownWrap.find('.' + this.CLASS.checkClass.nodeSelectedIcon).remove();
|
||||||
|
$that.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
|
||||||
|
this.$el.data('bindData', data);
|
||||||
|
this.$el.data('bindPathData', allPathData);
|
||||||
|
if (this.options.onChange && typeof this.options.onChange === "function") {
|
||||||
|
this.options.onChange(this, data, allPathData);
|
||||||
|
}
|
||||||
|
event.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
ZdCascader.prototype._loadChildren = function ($parentNode) {
|
ZdCascader.prototype._loadChildren = function ($parentNode) {
|
||||||
this.$el.focus();
|
this.$el.focus();
|
||||||
$parentNode.addClass(this.CLASS.checkClass.menuNodeSelected).siblings().removeClass(this.CLASS.checkClass.menuNodeSelected);
|
$parentNode.addClass(this.CLASS.checkClass.menuNodeSelected).siblings().removeClass(this.CLASS.checkClass.menuNodeSelected);
|
||||||
|
|
@ -214,12 +243,105 @@
|
||||||
$(this.$el).insertAfter(this.$el_);
|
$(this.$el).insertAfter(this.$el_);
|
||||||
this.$el.remove();
|
this.$el.remove();
|
||||||
}
|
}
|
||||||
|
//获取名称列表
|
||||||
|
ZdCascader.prototype.getLabelList = function () {
|
||||||
|
var datas = [];
|
||||||
|
this.options.data.forEach(function(prov) {
|
||||||
|
if (prov.children) {
|
||||||
|
prov.children.forEach(function(city) {
|
||||||
|
if (city.children) {
|
||||||
|
city.children.forEach(function(area) {
|
||||||
|
datas.push({
|
||||||
|
label: `${prov.label} / ${city.label} / ${area.label}`,
|
||||||
|
labels: [prov.label, city.label, area.label],
|
||||||
|
value: [prov.value, city.value, area.value],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
datas.push({
|
||||||
|
label: `${prov.label} / ${city.label}`,
|
||||||
|
labels: [prov.label, city.label],
|
||||||
|
value: [prov.value, city.value],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
datas.push({
|
||||||
|
label: prov.label,
|
||||||
|
labels: [prov.label],
|
||||||
|
value: prov.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.labelList = datas
|
||||||
|
}
|
||||||
|
//搜索
|
||||||
|
ZdCascader.prototype.search = function (keyword) {
|
||||||
|
if (keyword) keyword = keyword.trim();
|
||||||
|
if (!keyword) {
|
||||||
|
this.options.keyword = keyword;
|
||||||
|
this.reload(null, true)
|
||||||
|
return
|
||||||
|
};
|
||||||
|
var keywords = keyword.replace(' ','').replace('/','').split('')
|
||||||
|
var data = this.labelList.filter(function(item) {
|
||||||
|
item.num = 0
|
||||||
|
keywords.forEach(function(key) {
|
||||||
|
if (item.label.includes(key)) item.num++
|
||||||
|
})
|
||||||
|
if (item.label.includes(keyword)) item.num += 2
|
||||||
|
return item.num>(keywords.length==1?0:1)
|
||||||
|
}).sort(function(a, b) {
|
||||||
|
return b.num - a.num
|
||||||
|
}).slice(0, 10)
|
||||||
|
this.reload(data, true)
|
||||||
|
}
|
||||||
|
//关键词筛选数据(暂不用)
|
||||||
|
ZdCascader.prototype.searchData = function (keyword) {
|
||||||
|
var data = [];
|
||||||
|
this.options.data.forEach(function(prov){
|
||||||
|
if(prov.label.indexOf(keyword) >= 0){
|
||||||
|
data.push(prov)
|
||||||
|
} else {
|
||||||
|
if(prov.children){
|
||||||
|
var citys = []
|
||||||
|
prov.children.forEach(function(city){
|
||||||
|
if(city.label.indexOf(keyword) >= 0){
|
||||||
|
citys.push(city)
|
||||||
|
} else {
|
||||||
|
if(city.children){
|
||||||
|
var areas = []
|
||||||
|
city.children.forEach(function(area){
|
||||||
|
if(area.label.indexOf(keyword) >= 0){
|
||||||
|
areas.push(area)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(areas.length > 0){
|
||||||
|
citys.push({
|
||||||
|
value: city.value,
|
||||||
|
label: city.label,
|
||||||
|
children: areas
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (citys.length > 0) {
|
||||||
|
data.push({
|
||||||
|
label: prov.label,
|
||||||
|
value: prov.value,
|
||||||
|
children: citys
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
//重新加载下拉数据
|
//重新加载下拉数据
|
||||||
ZdCascader.prototype.reload = function (data,clear = false) {
|
ZdCascader.prototype.reload = function (data, search) {
|
||||||
data = data || this.options.data;
|
data = data || this.options.data;
|
||||||
if (clear){
|
this.$el.removeData('bindData').removeData('bindPathData');
|
||||||
this.$el.val('').removeData('bindData').removeData('bindPathData');
|
if (!search) this.$el.val('');
|
||||||
}
|
|
||||||
this.$dropdownWrap.empty();
|
this.$dropdownWrap.empty();
|
||||||
var selectedData = this.$el.data('bindData');
|
var selectedData = this.$el.data('bindData');
|
||||||
var $firstWrap = $(`<div class="zd-scrollbar ${this.CLASS.menuWrap}">
|
var $firstWrap = $(`<div class="zd-scrollbar ${this.CLASS.menuWrap}">
|
||||||
|
|
@ -245,16 +367,16 @@
|
||||||
</svg>`);
|
</svg>`);
|
||||||
$li.append($label).data('bindData', m);
|
$li.append($label).data('bindData', m);
|
||||||
if (m.children && m.children.length > 0) $li.append($icon);
|
if (m.children && m.children.length > 0) $li.append($icon);
|
||||||
else if (this.options.defaultValue && m.value == this.options.defaultValue) {
|
else if (selectedData && m.value == selectedData.value) {
|
||||||
this.$dropdownWrap.find('.' + this.CLASS.checkClass.nodeSelectedIcon).remove();
|
this.$dropdownWrap.find('.' + this.CLASS.checkClass.nodeSelectedIcon).remove();
|
||||||
$li.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
|
$li.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
|
||||||
this.$el.val(m.label);
|
|
||||||
}
|
}
|
||||||
$ul.append($li);
|
$ul.append($li);
|
||||||
});
|
});
|
||||||
this.$dropdownWrap.append($firstWrap);
|
this.$dropdownWrap.find('li.' + this.CLASS.checkClass.nodeAnchor).removeClass(this.CLASS.checkClass.nodeAnchor);
|
||||||
|
this.$dropdownWrap.append($firstWrap).find(this.CLASS.menuNode).eq(0).focus().addClass(this.CLASS.checkClass
|
||||||
|
.nodeAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZdCascader.prototype._keyup = function (event) {
|
ZdCascader.prototype._keyup = function (event) {
|
||||||
var keycode = event.which;
|
var keycode = event.which;
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
|
|
@ -364,22 +486,38 @@
|
||||||
this.$el.focus();
|
this.$el.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
$.fn.zdCascader = function (options) {
|
$.fn.zdCascader = function (option) {
|
||||||
options = $.extend({}, ZdCascader.DEFAULTS, options);
|
var value,
|
||||||
return this.each(function () {
|
args = Array.prototype.slice.call(arguments, 1);
|
||||||
var $this = $(this);
|
|
||||||
var data = $this.data('zdCascader');
|
this.each(function () {
|
||||||
if (!data) {
|
var $this = $(this),
|
||||||
data = new ZdCascader(this, options);
|
data = $this.data('zdCascader'),
|
||||||
$this.data('zdCascader', data);
|
options = $.extend({}, ZdCascader.DEFAULTS, $this.data(),
|
||||||
}
|
typeof option === 'object' && option);
|
||||||
if (typeof options === 'string') {
|
|
||||||
if (ZdCascader.METHODS.indexOf(options) > -1) {
|
if (typeof option === 'string') {
|
||||||
data[options]();
|
if ($.inArray(option, ZdCascader.METHODS) < 0) {
|
||||||
|
throw new Error("Unknown method: " + option);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = data[option].apply(data, args);
|
||||||
|
|
||||||
|
if (option === 'destroy') {
|
||||||
|
$this.removeData('zdCascader');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
$this.data('zdCascader', (data = new ZdCascader(this, options)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return typeof value === 'undefined' ? this : value;
|
||||||
|
};
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
Loading…
Reference in New Issue
Block a user