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:
todayswind 2025-05-27 00:04:26 +08:00 committed by Coding
commit 5d1a7d95f4
6 changed files with 655 additions and 236 deletions

View File

@ -6,6 +6,7 @@ namespace app\admin\controller\statistics;
use app\admin\model\Admin;
use app\admin\model\Order;
use app\common\controller\Backend;
use think\Db;
use think\Model;
use function Symfony\Component\Clock\now;
@ -17,10 +18,23 @@ use function Symfony\Component\Clock\now;
class Aftersale extends Backend
{
protected $relationSearch = true;
protected $relationSearch = true,$items,$itemsformattedTree;
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();
}
@ -39,15 +53,45 @@ class Aftersale extends Backend
{
$build = new Admin();
$build->alias('a')
->join('order b','a.id = b.admin_id','right')
->join('aftersale c','b.id = c.admin_id','left')
->where('b.status',Order::STATUS_FINISHED);
->join('order b', 'a.id = b.admin_id', 'right')
->join('aftersale c', 'b.id = c.admin_id', 'left')
->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->field(
[
'a.id',
'a.nickname',
'a.mobile',
'count(b.id) order_total',
'count(c.id) after_total',
]
@ -57,31 +101,146 @@ class Aftersale extends Backend
$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' => $ress,
'total' => $total
];
'rows' => $data,
'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;
}
}

View File

@ -206,8 +206,6 @@ class Item extends Backend
];
}
return $result;
}

View File

@ -7,189 +7,193 @@
<div>
<div class="card-body">
<form id="add-form" class="row" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group col-xs-6">
<label class="control-label col-xs-12 col-sm-3">{:__('Customer')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-customer" data-rule="required" class="form-control" name="row[customer]" type="text">
<div class="col-lg-4">
<div class="form-group col-xs-12">
<label class="control-label col-xs-12 col-lg-4">{:__('Customer')}:</label>
<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 class="form-group col-xs-6">
<label class="control-label col-xs-12 col-sm-3">{:__('Tel')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-tel" data-rule="required" class="form-control" name="row[tel]" type="number">
<div class="form-group col-xs-12">
<label class="control-label col-xs-12 col-lg-4">{:__('Tel')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-tel" data-rule="required" class="form-control" name="row[tel]" type="number">
</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-6">
<label class="control-label col-xs-12 col-sm-3">来源订单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-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'>
<div class="form-group col-xs-12">
<label class="control-label col-xs-12 col-lg-4">{:__('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="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>
<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 class="form-group col-xs-6 layer-footer">
<label class="control-label col-xs-12 col-sm-3"></label>
<div class="col-xs-12 col-sm-8">
<button id="mysubmit" class="btn btn-primary btn-embossed">录入并清空</button>
<button id="mybuttom" class="btn btn-primary btn-embossed">录入并保留信息</button>
<div class="col-lg-4">
<div class="form-group col-xs-12">
<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 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>
<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>
@ -202,6 +206,9 @@
width: 100vw;
background: #fff;
}
.myform-group{
display: flex;
}
.overlay {
position: absolute;
top: 0;
@ -227,6 +234,8 @@
display: flex;
justify-content: center;
align-items: flex-start;
height: 100vh;
overflow-y: auto;
}
.function-area {
flex: 1;
@ -254,7 +263,7 @@
background-color: #f0f0f0;
}
.control-label{
text-align: right;
text-align: left;
}
.col-xs-12{
margin: 5px 0;

View File

@ -175,26 +175,57 @@
<div class="panel-body" 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 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"}'
placeholder="指定日期" name="filter[daterange]" id="daterange-table" autocomplete="off" style="width: 180px;">
<button class="btn btn-default ml-2" id="first-search">查询</button>
</div>
<!-- 查询按钮 -->
<button class="btn btn-default" id="first-search" style="margin-left: 15px;">查询</button>
</div>
</div>
<section class="connectedSortable" style="height: 100%">
<table id="table1" class="table table-striped table-bordered table-hover" width="100%">
</table>
</section>
</div>
<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>
</div>
<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>
</div>
@ -210,3 +241,7 @@
</div>
</div>
</div>
<link rel="stylesheet" href="/assets/css/select.css">
<script>
var items = {:json_encode($items); };
</script>

View File

@ -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 = {
@ -10,7 +11,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
if (tabVal === 'first') {
Controller.api.first();
}else if (tabVal === 'second') {
console.log(3333);
Controller.api.second();
}else if (tabVal === 'third'){
Controller.api.third();
}
});
Controller.api.first();
@ -37,11 +41,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
searchFormVisible: true,
columns: [
[
{field: 'nickname', title: '项目类型', operate: false},
{field: 'nickname', title: '名称', operate: false},
{field: 'mobile', title: '电话', operate: false},
{field: 'order_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 () {
const range = $('#daterange-table').val();
const keyword = $('#keyword').val();
let data = '';
if (range !== ''){
data += 'range=' + range;
}
if (keyword !== ''){
data += '&keyword=' + keyword;
}
// data = encodeURIComponent(data);
$("#table1").bootstrapTable('refresh',{
url:'statistics/aftersale/dispatch?' + data,
@ -67,7 +75,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
// 表格2
var table = $("#table2");
table.bootstrapTable({
url: 'statistics/aftersale/dispatch',
url: 'statistics/aftersale/city',
sortName: 'id',
search: false,
commonSearch: false,
@ -78,10 +86,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-t
searchFormVisible: true,
columns: [
[
{field: 'nickname', title: '项目类型', operate: false},
{field: 'area.merge_name', title: '城市', operate: false},
{field: 'order_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绑定事件
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 = '';
if (range !== ''){
data += 'range=' + range;
}
if (area_id !== ''){
data += 'area_id=' + area_id;
}
// data = encodeURIComponent(data);
$("#table1").bootstrapTable('refresh',{
url:'statistics/aftersale/dispatch?' + data,
$("#table2").bootstrapTable('refresh',{
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 () {
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;

View File

@ -19,6 +19,7 @@
function ZdCascader(el, options) {
this.options = options;
if (options.search) this.getLabelList();
this.CLASS = ZdCascader.CLASS;
this.$el = $(el); //input
this.$el_ = this.$el.clone();
@ -49,8 +50,8 @@
ZdCascader.DEFAULTS = {
data: null, //支持格式[{value:"",label:"",children:[{value:"",label:""}]}]
range: ' / ', //分割符
onChange: function (data) {},
defaultValue: null // 新增 defaultValue 属性
search: true, //搜索
onChange: function (data) {}
}
ZdCascader.METHODS = ['reload', 'destroy'];
@ -68,8 +69,7 @@
var self = this;
//最外层容器
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)
.closest('.' + this.CLASS.wrap);
.wrap(`<div class="${this.CLASS.inputwrap}"></div>`).addClass(this.CLASS.input).prop('readonly', !this.options.search).closest('.' + this.CLASS.wrap);
//文本框右侧图标
this.$arrow = $(`<span class="zd-input__suffix">
@ -85,7 +85,6 @@
</svg>
</span>
</span>`).insertAfter(this.$el);
//下拉列表
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));
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('input', $.proxy(function (event) {
this.search(this.$el.val())
}, this));
}
ZdCascader.prototype._wrapClick = function () {
event.stopPropagation();
@ -147,13 +151,38 @@
$that.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
this.$el.data('bindData', data);
this.$el.data('bindPathData', allPathData);
console.log(allPathData);
if (this.options.onChange && typeof this.options.onChange === "function")
this.options.onChange(this, data, allPathData);
event.stopPropagation();
} else
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) {
this.$el.focus();
$parentNode.addClass(this.CLASS.checkClass.menuNodeSelected).siblings().removeClass(this.CLASS.checkClass.menuNodeSelected);
@ -214,12 +243,105 @@
$(this.$el).insertAfter(this.$el_);
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;
if (clear){
this.$el.val('').removeData('bindData').removeData('bindPathData');
}
this.$el.removeData('bindData').removeData('bindPathData');
if (!search) this.$el.val('');
this.$dropdownWrap.empty();
var selectedData = this.$el.data('bindData');
var $firstWrap = $(`<div class="zd-scrollbar ${this.CLASS.menuWrap}">
@ -245,16 +367,16 @@
</svg>`);
$li.append($label).data('bindData', m);
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();
$li.prepend($(`<span class="${this.CLASS.checkClass.nodeSelectedIcon}">√</span>`));
this.$el.val(m.label);
}
$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) {
var keycode = event.which;
switch (keycode) {
@ -364,22 +486,38 @@
this.$el.focus();
}
$.fn.zdCascader = function (options) {
options = $.extend({}, ZdCascader.DEFAULTS, options);
return this.each(function () {
var $this = $(this);
var data = $this.data('zdCascader');
if (!data) {
data = new ZdCascader(this, options);
$this.data('zdCascader', data);
}
if (typeof options === 'string') {
if (ZdCascader.METHODS.indexOf(options) > -1) {
data[options]();
$.fn.zdCascader = function (option) {
var value,
args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
var $this = $(this),
data = $this.data('zdCascader'),
options = $.extend({}, ZdCascader.DEFAULTS, $this.data(),
typeof option === 'object' && option);
if (typeof option === 'string') {
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);