This commit is contained in:
邓皓元 2019-04-11 17:57:40 +08:00
parent bcb4ba39bb
commit 912bd76967
22 changed files with 418 additions and 364 deletions

View File

@ -64,8 +64,8 @@ class CardController extends Controller
$product = ProductService::load($package['type'], $this->account->company_id, $item->package_id); $product = ProductService::load($package['type'], $this->account->company_id, $item->package_id);
$item->price = $product['price'] ?? 9999; $item->price = $product['price'] ? sprintf('%.02f', $product['price']/100) : 9999;
$item->renew_price = $product['renew_price'] ?? 9999; $item->renew_price = $product['renew_price'] ? sprintf('%.02f', $product['renew_price']/100) : 9999;
}); });
return res($cards, '卡列表', 201); return res($cards, '卡列表', 201);

View File

@ -33,7 +33,6 @@ class OrderController extends Controller
{ {
$conditions = $this->request->all(); $conditions = $this->request->all();
$conditions['company_id'] = $this->account->company_id; $conditions['company_id'] = $this->account->company_id;
$conditions['source'] = 0;
$conditions['type'] = $conditions['type'] ?? 0; $conditions['type'] = $conditions['type'] ?? 0;
$res = $this->orderService->paginate($conditions); $res = $this->orderService->paginate($conditions);
@ -48,7 +47,7 @@ class OrderController extends Controller
'sn' => $item->sn, 'sn' => $item->sn,
'package_name' => $item->package['name'], 'package_name' => $item->package['name'],
'pay_channel' => CommonService::namePayChannel($item->pay_channel), 'pay_channel' => CommonService::namePayChannel($item->pay_channel),
'carrier_operator' => $carrierOperators[$item->package->carrier_operator], 'carrier_operator' => $carrierOperators[$item->package['carrier_operator']],
'unit_price' => $item->unit_price, 'unit_price' => $item->unit_price,
'counts' => $item->counts, 'counts' => $item->counts,
'total_price' => $item->total_price, 'total_price' => $item->total_price,

View File

@ -193,9 +193,7 @@ class FlowPoolController extends Controller
if ($flowPool->setting_status) { if ($flowPool->setting_status) {
$repository = app(OrderCardPartitionRepository::class); $repository = app(OrderCardPartitionRepository::class);
$minimum_settings = $flowPool['settings'][0]['minimum_settings'] ?? []; $package_ids = $flowPool->package_ids;
$package_ids = array_pluck($minimum_settings, 'package_id');
$conditions = [ $conditions = [
'type' => [0, 1, 2], 'type' => [0, 1, 2],
@ -208,11 +206,7 @@ class FlowPoolController extends Controller
$cards = $repository->select([ $cards = $repository->select([
'package_id', 'package_id',
DB::raw('count(distinct sim) as total'), DB::raw('count(distinct sim) as total'),
])->withConditions($conditions)->groupBy('package_id')->get(); ])->withConditions($conditions)->groupBy('package_id')->get()->pluck('total', 'package_id');
$cards->map(function ($item) {
$item->package_name = PackageService::load($item->package_id)['name'];
});
} else { } else {
$cards = collect(); $cards = collect();
} }
@ -230,31 +224,39 @@ class FlowPoolController extends Controller
$settings = array_keyBy($flowPoolData['settings'], 'package_id'); $settings = array_keyBy($flowPoolData['settings'], 'package_id');
foreach ($cards as $card) { $newSettings = [];
if (!isset($settings[$card['package_id']])) {
$settings[$card['package_id']] = [ foreach ($package_ids as $package_id) {
'package_id' => $card['package_id'], if (!isset($settings[$package_id])) {
'package_name' => $card['package_name'], $newSettings[] = [
'total' => $card['total'], 'package_id' => $package_id,
'news' => $card['total'], 'package_name' => PackageService::load($package_id)['name'],
'total' => $cards[$package_id] ?? 0,
'news' => $cards[$package_id] ?? 0,
]; ];
} else { } else {
$chunk = $settings[$card['package_id']]['cards']; $setting = $settings[$package_id];
$chunk = $setting['cards'];
foreach ($chunk as &$value) { foreach ($chunk as &$value) {
$value['flow_range'][0] = sprintf('%.02f', $value['flow_range'][0]/1024); $value['flow_range'][0] = sprintf('%.02f', $value['flow_range'][0]/1024);
$value['flow_range'][1] = sprintf('%.02f', $value['flow_range'][1]/1024); $value['flow_range'][1] = sprintf('%.02f', $value['flow_range'][1]/1024);
} }
$settings[$card['package_id']]['cards'] = $chunk; $setting['cards'] = $chunk;
$settings[$card['package_id']]['news'] = $card['total'] - array_sum(array_pluck($settings[$card['package_id']]['cards'], 'counts')); $news = $cards[$package_id] ?? 0 - array_sum(array_pluck($setting['cards'], 'counts'));
$setting['news'] = $news < 0 ? 0 : $news;
$newSettings[] = $setting;
} }
} }
$flowPoolData['total_flows'] = sprintf('%.02f', $flowPoolData['total_flows']/1024); $flowPoolData['total_flows'] = sprintf('%.02f', $flowPoolData['total_flows']/1024);
return res(['flowPool' => $flowPool, 'settings' => array_values($settings), 'total' => array_sum(array_pluck($cards, 'total')), 'total_flows' => $flowPoolData['total_flows']], '数据设置'); return res(['flowPool' => $flowPool, 'settings' => $newSettings, 'total' => $cards->values()->sum(), 'total_flows' => $flowPoolData['total_flows']], '数据设置');
} }
$conditions = $this->request->all(); $conditions = $this->request->all();

View File

@ -60,7 +60,8 @@ class ProductRepository extends Repository
} }
if (isset($conditions['type'])) { if (isset($conditions['type'])) {
$query->where('type', $conditions['type']); $conditions['type'] = array_wrap($conditions['type']);
$query->whereIn('type', $conditions['type']);
} }
if (isset($conditions['company_id'])) { if (isset($conditions['company_id'])) {

View File

@ -633,10 +633,13 @@ class FlowPoolService extends Service
$packages = []; $packages = [];
foreach ($item->package_ids as $value) { foreach ($item->package_ids as $value) {
$package = PackageService::load($value);
$packages[] = [ $packages[] = [
'type' => $package['type'],
'package_id' => $value, 'package_id' => $value,
'type' => PackageService::load($value)['type'], 'package_name' => $package['name'],
'package_name' => PackageService::load($value)['name'], 'carrier_operator' => $package['carrier_operator'],
]; ];
} }

View File

@ -6,24 +6,25 @@ use App\Core\Service;
use App\Models\Card\Card; use App\Models\Card\Card;
use App\Models\Virtual\Order; use App\Models\Virtual\Order;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use App\Models\Virtual\OrderCard;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use App\Exceptions\ExistedException;
use App\Exceptions\NotExistException; use App\Exceptions\NotExistException;
use App\Exceptions\NotAllowedException; use App\Exceptions\NotAllowedException;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use App\Domains\Card\Services\CardService; use App\Domains\Card\Services\CardService;
use App\Models\Virtual\OrderCardPartition;
use App\Exceptions\InvalidArgumentException; use App\Exceptions\InvalidArgumentException;
use Dipper\Foundation\Exceptions\HttpException; use Dipper\Foundation\Exceptions\HttpException;
use App\Domains\Virtual\Services\CompanyService; use App\Domains\Virtual\Services\CompanyService;
use App\Domains\Virtual\Services\PackageService; use App\Domains\Virtual\Services\PackageService;
use App\Domains\Virtual\Services\ProductService;
use App\Domains\Virtual\Repositories\OrderRepository; use App\Domains\Virtual\Repositories\OrderRepository;
use App\Domains\Virtual\Repositories\ProductRepository; use App\Domains\Virtual\Repositories\ProductRepository;
use App\Models\Real\OrderCardPartition as RealOrderCardPartition; use App\Models\Real\OrderCardPartition as RealOrderCardPartition;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository; use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
use App\Domains\Real\Repositories\OrderRepository as RealOrderRepository; use App\Domains\Real\Repositories\OrderRepository as RealOrderRepository;
use App\Domains\Real\Repositories\OrderCardPartitionRepository as RealOrderCardPartitionRepository; use App\Domains\Real\Repositories\OrderCardPartitionRepository as RealOrderCardPartitionRepository;
use App\Exceptions\ExistedException;
use App\Models\Virtual\OrderCardPartition;
use App\Models\Virtual\OrderCard;
class OrderService extends Service class OrderService extends Service
{ {
@ -231,7 +232,7 @@ class OrderService extends Service
} }
$attributes['order_status'] = (isset($attributes['selected']) && count($attributes['selected']) === $node->counts) ? 5 : ($attributes['order_status'] ?? 0); $attributes['order_status'] = (isset($attributes['selected']) && count($attributes['selected']) === $node->counts) ? 5 : ($attributes['order_status'] ?? 0);
$attributes['transaction_status'] = isset($attributes['selected']) ? 1 : ($attributes['transaction_status'] ?? 1); $attributes['transaction_status'] = isset($attributes['selected']) ? 1 : ($attributes['transaction_status'] ?? 0);
if ($attributes['order_status'] === 1) { if ($attributes['order_status'] === 1) {
$count = $this->orderCardPartitionRepository->where('type', $node['type'])->where('order_id', $node['id'])->count(); $count = $this->orderCardPartitionRepository->where('type', $node['type'])->where('order_id', $node['id'])->count();
@ -241,8 +242,8 @@ class OrderService extends Service
} }
// 改企业 // 改企业
if ($attributes['company_id'] != $node->company_id) { if (isset($attributes['company_id']) && $attributes['company_id'] != $node->company_id) {
if ($attributes['type'] !== 0) { if ($node->type !== 0) {
throw new NotAllowedException('只允许修改销售订单'); throw new NotAllowedException('只允许修改销售订单');
} }
@ -409,6 +410,8 @@ class OrderService extends Service
return !in_array($item->sim, array_pluck($value, 'sim')); return !in_array($item->sim, array_pluck($value, 'sim'));
}); });
$product = ProductService::load(0, $attributes['company_id'], $value[0]['package_id']);
$counts = array_sum(array_pluck($realCards, 'counts')); $counts = array_sum(array_pluck($realCards, 'counts'));
$orders[$key] = [ $orders[$key] = [
@ -420,10 +423,10 @@ class OrderService extends Service
'package_id' => $value[0]['package_id'], 'package_id' => $value[0]['package_id'],
'transaction_no' => $this->generateTransactionNo($attributes['pay_channel']), 'transaction_no' => $this->generateTransactionNo($attributes['pay_channel']),
'pay_channel' => $attributes['pay_channel'], 'pay_channel' => $attributes['pay_channel'],
'unit_price' => $value[0]['unit_price'], 'unit_price' => $product['renew_price'],
'counts' => $counts, 'counts' => $counts,
'total_price' => $value[0]['unit_price'] * $counts, 'total_price' => $product['renew_price'] * $counts,
'custom_price' => $value[0]['unit_price'] * $counts, 'custom_price' => $product['renew_price'] * $counts,
'order_at' => $order_at, 'order_at' => $order_at,
'created_at' => $order_at, 'created_at' => $order_at,
'updated_at' => $order_at, 'updated_at' => $order_at,

View File

@ -153,7 +153,7 @@ class PackageService extends Service
{ {
if (!self::$packages) { if (!self::$packages) {
self::$packages = app(PackageRepository::class) self::$packages = app(PackageRepository::class)
->select(['id', 'type', 'sn', 'name', 'carrier_operator', 'flows', 'service_months', 'status']) ->select(['id', 'type', 'sn', 'name', 'carrier_operator', 'flows', 'flowed', 'service_months', 'status'])
->withTrashed()->get()->keyBy('id')->toArray(); ->withTrashed()->get()->keyBy('id')->toArray();
} }

View File

@ -155,7 +155,7 @@ class ProductService extends Service
} else { } else {
$attributes['sn'] = self::sn($package['sn'], $attributes['company_id']); $attributes['sn'] = self::sn($package['sn'], $attributes['company_id']);
$node = $this->productRepository->create($attributes); $node = $this->productRepository->upsert($attributes, ['sn', 'deleted_at']);
} }
DB::commit(); DB::commit();
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -1,5 +1,5 @@
import * as FETCH from 'api/virtual/fetch'; import * as FETCH from "api/virtual/fetch";
import PinyinEngine from 'pinyin-engine'; import PinyinEngine from "pinyin-engine";
export default { export default {
data() { data() {
@ -15,8 +15,8 @@ export default {
}; };
}, },
methods: { methods: {
handleComplete(array, value = '', key = 'name', indexKey = 'id') { handleComplete(array, value = "", key = "name", indexKey = "id") {
if (value === '' || value === null) { if (value === "" || value === null) {
return array; return array;
} }
@ -27,9 +27,12 @@ export default {
res = pinyinEngine.query(value); res = pinyinEngine.query(value);
res = array.filter(item => { res = array.filter(item => {
return (item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) || (res.find(element => { return (
return element[indexKey] === item[indexKey]; item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1 ||
})); res.find(element => {
return element[indexKey] === item[indexKey];
})
);
}); });
return res; return res;
@ -54,7 +57,10 @@ export default {
handleCompleteCompanies(value) { handleCompleteCompanies(value) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.initCompleteCompanies().then(() => { this.initCompleteCompanies().then(() => {
this.completeHandledCompanies = this.handleComplete(this.completeCompanies, value); this.completeHandledCompanies = this.handleComplete(
this.completeCompanies,
value
);
resolve(this.completeHandledCompanies); resolve(this.completeHandledCompanies);
}); });
}); });
@ -65,8 +71,10 @@ export default {
FETCH.packages().then(res => { FETCH.packages().then(res => {
if (res.code === 0) { if (res.code === 0) {
this.completePackageInitialized = true; this.completePackageInitialized = true;
type = type instanceof Array ? type : [type];
this.completePackages = res.data.filter(el => { this.completePackages = res.data.filter(el => {
if (type !== null && el.type !== type) { if (type !== null && type.indexOf(el.type) === -1) {
return false; return false;
} }
return true; return true;
@ -84,7 +92,10 @@ export default {
handleCompletePackages(type = 0, value) { handleCompletePackages(type = 0, value) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.initCompletePackages(type).then(() => { this.initCompletePackages(type).then(() => {
this.completeHandledPackages = this.handleComplete(this.completePackages, value); this.completeHandledPackages = this.handleComplete(
this.completePackages,
value
);
resolve(this.completeHandledPackages); resolve(this.completeHandledPackages);
}); });
}); });

View File

@ -143,9 +143,20 @@ export function objectDot(object, prepend = '') {
* @param {String} key * @param {String} key
*/ */
export function sumBy(array, key) { export function sumBy(array, key) {
return array.map((item) => { return array.reduce((acc, cur) => {
return Number(item[key]); return add(acc, Number(cur[key]));
}).reduce((acc, cur) => { }, 0);
return acc + cur; };
});
/**
* 精确加法
* @param {Number} num1
* @param {Number} num2
*/
export function add(num1, num2) {
var r1, r2, m;
try { r1 = num1.toString().split(".")[1].length; } catch (e) { r1 = 0; }
try { r2 = num2.toString().split(".")[1].length; } catch (e) { r2 = 0; }
m = Math.pow(10, Math.max(r1, r2));
return (num1 * m + num2 * m) / m;
}; };

View File

@ -73,31 +73,7 @@
:height="page.limit > 12 ? 610 : ''" :height="page.limit > 12 ? 610 : ''"
ref="table" ref="table"
stripe stripe
> ></Table>
<template class="table-footer" slot="footer">
<colgroup class="table-footer-colgroup"></colgroup>
<thead class="ivu-table">
<tr>
<th>
<div class="ivu-table-cell">总计</div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell">{{stats.total}}</div>
</th>
<th>
<div class="ivu-table-cell">{{stats.counts}}</div>
</th>
<th>
<div class="ivu-table-cell">{{stats.renewed_counts}}</div>
</th>
<th v-if="page.limit > 12" rowspan="1"></th>
</tr>
</thead>
</template>
</Table>
</div> </div>
<div class="page-turn-wrap"> <div class="page-turn-wrap">

View File

@ -119,17 +119,11 @@ export default {
this.page.page = page; this.page.page = page;
this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit); this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit);
this.stats = { this.data.push({
total: sumBy(this.list, 'total'), id: "总计",
counts: sumBy(this.list, 'counts'), total: sumBy(this.list, "total"),
renewed_counts: sumBy(this.list, 'renewed_counts') counts: sumBy(this.list, "counts"),
}; renewed_counts: sumBy(this.list, "renewed_counts")
this.$nextTick(() => {
setTimeout(() => {
let html = $('.ivu-table-header colgroup').html();
$('.table-footer-colgroup').html(html);
}, 10);
}); });
}, },

View File

@ -27,14 +27,32 @@
<div class="search-wrap" v-show="search.show"> <div class="search-wrap" v-show="search.show">
<ul class="handle-wraper"> <ul class="handle-wraper">
<li class="handle-item w-250"> <li class="handle-item w-250">
<AutoComplete @on-search="handleCompleteCompanies" icon="ios-search" placeholder="企业名称" v-model.trim="options.company_name"> <AutoComplete
<Option :key="item.id" :value="item.name" v-for="item in completeHandledCompanies">{{ item.name }}</Option> @on-search="handleCompleteCompanies"
icon="ios-search"
placeholder="企业名称"
v-model.trim="options.company_name"
>
<Option
:key="item.id"
:value="item.name"
v-for="item in completeHandledCompanies"
>{{ item.name }}</Option>
</AutoComplete> </AutoComplete>
</li> </li>
<li class="handle-item w-250"> <li class="handle-item w-250">
<AutoComplete @on-search="handleCompletePackages(options.type, $event)" icon="ios-search" placeholder="套餐名称" v-model.trim="options.package_name"> <AutoComplete
<Option :key="item.id" :value="item.name" v-for="item in completeHandledPackages">{{ item.name }}</Option> @on-search="handleCompletePackages(options.type, $event)"
icon="ios-search"
placeholder="套餐名称"
v-model.trim="options.package_name"
>
<Option
:key="item.id"
:value="item.name"
v-for="item in completeHandledPackages"
>{{ item.name }}</Option>
</AutoComplete> </AutoComplete>
</li> </li>
@ -50,7 +68,13 @@
<ul class="handle-wraper"> <ul class="handle-wraper">
<li class="handle-item w-250"> <li class="handle-item w-250">
<DatePicker :editable="false" placeholder="请选择时间" placement="bottom-start" type="month" v-model.trim="options.month"></DatePicker> <DatePicker
:editable="false"
placeholder="请选择时间"
placement="bottom-start"
type="month"
v-model.trim="options.month"
></DatePicker>
</li> </li>
<li class="f-r"> <li class="f-r">
@ -66,46 +90,13 @@
</div> </div>
<div class="page-list-wrap"> <div class="page-list-wrap">
<Table :columns="columns" :data="data" :height="page.limit > 12 ? 610 : ''" ref="table" stripe> <Table
<template class="table-footer" slot="footer"> :columns="columns"
<colgroup class="table-footer-colgroup"></colgroup> :data="data"
<thead class="ivu-table" v-show="data.length"> :height="page.limit > 12 ? 610 : ''"
<tr> ref="table"
<th> stripe
<div class="ivu-table-cell">总计</div> ></Table>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell">{{stats.members}}</div>
</th>
<th>
<div class="ivu-table-cell">{{stats.counts}}</div>
</th>
<th>
<div class="ivu-table-cell">{{Number(stats.total_price).toFixed(2)}}</div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th rowspan="1" v-if="page.limit > 12"></th>
</tr>
</thead>
</template>
</Table>
</div> </div>
<div class="page-turn-wrap"> <div class="page-turn-wrap">

View File

@ -1,10 +1,8 @@
import { import { sumBy } from "service/util";
sumBy
} from 'service/util';
export default { export default {
name: 'StatsCompanyReport', name: "StatsCompanyReport",
components: { components: {
UiDetail: resolve => require(['views/stats/company-report/detail'], resolve) UiDetail: resolve => require(["views/stats/company-report/detail"], resolve)
}, },
data() { data() {
return { return {
@ -17,10 +15,13 @@ export default {
}, },
types: [], types: [],
options: { options: {
company_name: '', company_name: "",
package_name: '', package_name: "",
type: [], type: [],
month: this.moment().subtract('1', 'months').startOf('month').format('YYYY-MM') month: this.moment()
.subtract("1", "months")
.startOf("month")
.format("YYYY-MM")
}, },
data: [], data: [],
list: [], list: [],
@ -32,102 +33,114 @@ export default {
}, },
columns: [ columns: [
{ {
title: '企业名称', title: "企业名称",
key: 'company_name', key: "company_name",
width: 300 width: 300
}, },
{ {
title: '套餐名称', title: "套餐名称",
key: 'package_name' key: "package_name",
width: 170
}, },
{ {
title: '套餐周期(月)', title: "套餐周期(月)",
key: 'service_months', key: "service_months",
width: 150 width: 150
}, },
{ {
title: '套餐价格(元/周期)', title: "套餐价格(元/周期)",
key: 'unit_price', key: "unit_price",
width: 150 width: 150
}, },
{ {
title: '套餐单价(元/月)', title: "套餐单价(元/月)",
key: 'month_price', key: "month_price",
width: 150 width: 150
}, },
{ {
title: '收费人数', title: "收费人数",
key: 'members', key: "members",
width: 130 width: 130
}, },
{ {
title: '收费数', title: "收费数",
key: 'counts', key: "counts",
width: 130 width: 130
}, },
{ {
title: '收费总价(元)', title: "收费总价(元)",
key: 'total_price', key: "total_price",
width: 150 width: 150
}, },
{ {
title: '收费类型', title: "收费类型",
key: 'type_name', key: "type_name",
width: 120 width: 120
}, },
{ {
title: '操作', title: "操作",
key: 'action', key: "action",
width: 170, width: 150,
render: (h, { render: (h, { row, column, index }) => {
row, if (index == this.data.length - 1) {
column, return;
index }
}) => {
let html = []; let html = [];
html.push(h('Button', { html.push(
props: { h(
type: 'primary', "Button",
size: 'small', {
disabled: false, props: {
icon: 'md-create' type: "primary",
}, size: "small",
class: ['btn'], disabled: false,
on: { icon: "md-eye"
click: (event) => { },
this.isShowLoading(true); class: ["btn"],
on: {
click: event => {
this.isShowLoading(true);
let params = { let params = {
page: 1, page: 1,
limit: 10, limit: 10,
type: row.type, type: row.type,
company_id: row.company_id, company_id: row.company_id,
month: this.moment(this.options.month).format('YYYY-MM'), month: this.moment(this.options.month).format(
package_id: row.package_id, "YYYY-MM"
unit_price: Number(row.unit_price * 100) ),
}; package_id: row.package_id,
unit_price: Number(row.unit_price * 100)
service.get('api/stats/company-report/detail', {
params
}).then(res => {
this.isShowLoading(false);
if (res.code == 0) {
this.detailObj = {
show: true,
options: params,
list: res.data
}; };
service
.get("api/stats/company-report/detail", {
params
})
.then(res => {
this.isShowLoading(false);
if (res.code == 0) {
this.detailObj = {
show: true,
options: params,
list: res.data
};
}
})
.catch(() => {
this.isShowLoading(false);
});
} }
}).catch(() => { }
this.isShowLoading(false); },
}); "明细"
} )
} );
}, '查看明细'));
if (html.length) { if (html.length) {
return h('div', html); return h("div", html);
} }
} }
} }
@ -135,14 +148,9 @@ export default {
}; };
}, },
created() { created() {
this.types = (this.$route.params.type == 1) ? [0, 1] : [2, 3]; this.types = this.$route.params.type == 1 ? [0, 1] : [2, 3];
this.index(); this.index();
}, },
mounted() {
window.onresize = () => {
this.tableFooter();
};
},
methods: { methods: {
/** /**
* [index 列表] * [index 列表]
@ -154,50 +162,59 @@ export default {
this.data = []; this.data = [];
service.get('api/stats/company-report', { service
params: this.params() .get("api/stats/company-report", {
}).then(res => { params: this.params()
this.isShowLoading(false); })
if (res.code == 0) { .then(res => {
this.list = res.data; this.isShowLoading(false);
this.page.total = this.list.length; if (res.code == 0) {
this.changePage(1); this.list = res.data;
} this.page.total = this.list.length;
}).catch(() => { this.changePage(1);
this.isShowLoading(false); }
}); })
.catch(() => {
this.isShowLoading(false);
});
}, },
exportExcel() { exportExcel() {
this.isShowLoading(true); this.isShowLoading(true);
service.get('api/stats/company-report/export', { service
params: this.params() .get("api/stats/company-report/export", {
}).then((res) => { params: this.params()
if (res.code === 0) { })
this.downloadFile(res.data); .then(res => {
} if (res.code === 0) {
this.downloadFile(res.data);
}
this.isShowLoading(false); this.isShowLoading(false);
}).catch(() => { })
this.isShowLoading(false); .catch(() => {
}); this.isShowLoading(false);
});
}, },
params() { params() {
if (!this.options.month) { if (!this.options.month) {
this.options.month = this.moment().subtract('1', 'months').startOf('month').format('YYYY-MM'); this.options.month = this.moment()
.subtract("1", "months")
.startOf("month")
.format("YYYY-MM");
} }
if (!this.options.type.length) { if (!this.options.type.length) {
this.options.type = this.types; this.options.type = this.types;
} }
this.options.month = this.moment(this.options.month).format('YYYY-MM'); this.options.month = this.moment(this.options.month).format("YYYY-MM");
let params = { let params = {
limit: 0, limit: 0,
type: this.options.type, type: this.options.type,
month: this.moment(this.options.month).format('YYYY-MM'), month: this.moment(this.options.month).format("YYYY-MM"),
company_name: this.options.company_name, company_name: this.options.company_name,
package_name: this.options.package_name package_name: this.options.package_name
}; };
@ -213,7 +230,11 @@ export default {
let page = this.page.page; let page = this.page.page;
if (this.data.length == 1) { if (this.data.length == 1) {
page = this.returnPage(this.page.total, this.page.page, this.page.limit); page = this.returnPage(
this.page.total,
this.page.page,
this.page.limit
);
} }
this.index(); this.index();
@ -222,12 +243,15 @@ export default {
resetSearch() { resetSearch() {
for (let k in this.options) { for (let k in this.options) {
if (k === 'month') { if (k === "month") {
this.options[k] = this.moment().subtract('1', 'months').startOf('month').format('YYYY-MM'); this.options[k] = this.moment()
} else if (k === 'type') { .subtract("1", "months")
.startOf("month")
.format("YYYY-MM");
} else if (k === "type") {
this.options[k] = []; this.options[k] = [];
} else { } else {
this.options[k] = ''; this.options[k] = "";
} }
} }
@ -245,22 +269,19 @@ export default {
}, },
changePage(page) { changePage(page) {
this.page.page = page; this.page.page = page;
this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit); this.data = this.list.slice(
(page - 1) * this.page.limit,
this.stats = { page * this.page.limit
members: sumBy(this.list, 'members'), );
counts: sumBy(this.list, 'counts'),
total_price: sumBy(this.list, 'total_price')
};
this.tableFooter(); this.tableFooter();
}, },
tableFooter() { tableFooter() {
this.$nextTick(() => { this.data.push({
setTimeout(() => { company_name: "总计",
let html = $('.ivu-table-header colgroup').html(); members: sumBy(this.list, "members"),
$('.table-footer-colgroup').html(html); counts: sumBy(this.list, "counts"),
}, 10); total_price: Number(sumBy(this.list, "total_price")).toFixed(2)
}); });
} }
} }

View File

@ -96,40 +96,7 @@
:height="page.limit > 12 ? 610 : ''" :height="page.limit > 12 ? 610 : ''"
ref="table" ref="table"
stripe stripe
> ></Table>
<template class="table-footer" slot="footer">
<colgroup class="table-footer-colgroup"></colgroup>
<thead class="ivu-table" v-show="data.length">
<tr>
<th>
<div class="ivu-table-cell">总计</div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th>
<div class="ivu-table-cell">{{stats.members}}</div>
</th>
<th>
<div class="ivu-table-cell">{{stats.counts}}</div>
</th>
<th>
<div class="ivu-table-cell">{{Number(stats.custom_price).toFixed(2)}}</div>
</th>
<th>
<div class="ivu-table-cell"></div>
</th>
<th rowspan="1" v-if="page.limit > 12"></th>
</tr>
</thead>
</template>
</Table>
</div> </div>
<div class="page-turn-wrap"> <div class="page-turn-wrap">

View File

@ -75,6 +75,10 @@ export default {
column, column,
index index
}) => { }) => {
if (index == this.data.length - 1) {
return;
}
let html = []; let html = [];
html.push(h('Button', { html.push(h('Button', {
@ -82,7 +86,7 @@ export default {
type: 'primary', type: 'primary',
size: 'small', size: 'small',
disabled: false, disabled: false,
icon: 'md-create' icon: 'md-eye'
}, },
class: ['btn'], class: ['btn'],
on: { on: {
@ -114,7 +118,7 @@ export default {
}); });
} }
} }
}, '查看明细')); }, '明细'));
if (html.length) { if (html.length) {
return h('div', html); return h('div', html);
@ -127,11 +131,6 @@ export default {
created() { created() {
this.index(); this.index();
}, },
mounted() {
window.onresize = () => {
this.tableFooter();
};
},
methods: { methods: {
/** /**
* [index 列表] * [index 列表]
@ -211,20 +210,14 @@ export default {
this.page.page = page; this.page.page = page;
this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit); this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit);
this.stats = {
members: sumBy(this.list, 'members'),
counts: sumBy(this.list, 'counts'),
custom_price: sumBy(this.list, 'custom_price')
};
this.tableFooter(); this.tableFooter();
}, },
tableFooter() { tableFooter() {
this.$nextTick(() => { this.data.push({
setTimeout(() => { company_name: "总计",
let html = $('.ivu-table-header colgroup').html(); members: sumBy(this.list, "members"),
$('.table-footer-colgroup').html(html); counts: sumBy(this.list, "counts"),
}, 10); custom_price: Number(sumBy(this.list, "custom_price")).toFixed(2)
}); });
}, },
exportExcel() { exportExcel() {

View File

@ -1,4 +1,4 @@
import * as API from 'api/virtual/flow_pools'; import * as API from "api/virtual/flow_pools";
export default { export default {
props: { props: {
@ -8,7 +8,7 @@ export default {
}, },
data: { data: {
type: Object, type: Object,
default () { default() {
return null; return null;
} }
} }
@ -16,8 +16,8 @@ export default {
data() { data() {
return { return {
listStyle: { listStyle: {
width: '230px', width: "230px",
height: '300px' height: "300px"
}, },
companies: [], companies: [],
packages: [], packages: [],
@ -30,14 +30,16 @@ export default {
isUpdate: false, isUpdate: false,
loading: false, loading: false,
params: { params: {
name: '', name: "",
carrier_operator: '', carrier_operator: "",
company_id: '', company_id: "",
real_pool_ids: [], real_pool_ids: [],
package_ids: [], package_ids: [],
status: 0, status: 0,
remark: '', remark: "",
start_at: this.moment().subtract('1', 'months').format('YYYY-MM') start_at: this.moment()
.subtract("1", "months")
.format("YYYY-MM")
} }
}; };
}, },
@ -67,11 +69,11 @@ export default {
if (res.code == 0) { if (res.code == 0) {
this.reals = res.data.map(item => { this.reals = res.data.map(item => {
return { return {
'key': item.id, key: item.id,
'label': item.sn + ' - ' + item.name, label: item.sn + " - " + item.name,
'disabled': false, disabled: false,
'virtual_pool_id': item.virtual_pool_id, virtual_pool_id: item.virtual_pool_id,
'carrier_operator': item.carrier_operator carrier_operator: item.carrier_operator
}; };
}); });
@ -85,17 +87,42 @@ export default {
if (!this.packages.length) { if (!this.packages.length) {
API.packages().then(res => { API.packages().then(res => {
if (res.code == 0) { if (res.code == 0) {
this.packages = res.data.map(item => { let packages = res.data.map(item => {
return { return {
'key': item.id, key: item.id,
'label': item.name + (item.type === 0 ? '(基础)' : '(续费包)'), label: item.name + (item.type === 0 ? "(基础)" : "(续费包)"),
'disabled': false, disabled: false,
'company_ids': item.company_ids, company_ids: item.company_ids,
'virtual_pool_id': item.virtual_pool_id, virtual_pool_id: item.virtual_pool_id,
'carrier_operator': item.carrier_operator carrier_operator: item.carrier_operator
}; };
}); });
if (this.data) {
for (
let index = 0;
index < this.data.packages.length;
index++
) {
const item = this.data.packages[index];
if (packages.findIndex(el => { return el.key === item.package_id; }) === -1) {
packages.push({
key: item.package_id,
label:
item.package_name +
(item.type === 0 ? "(基础)" : "(续费包)"),
disabled: false,
company_ids: [this.data.company_id],
virtual_pool_id: this.data.id,
carrier_operator: item.carrier_operator
});
}
}
}
this.packages = packages;
this.filterPackages(); this.filterPackages();
} }
}); });
@ -108,7 +135,11 @@ export default {
methods: { methods: {
filterReals() { filterReals() {
this.realFilters = this.reals.filter(item => { this.realFilters = this.reals.filter(item => {
if ((this.params.carrier_operator !== '' && this.params.carrier_operator !== undefined) && this.params.carrier_operator !== item.carrier_operator) { if (
this.params.carrier_operator !== "" &&
this.params.carrier_operator !== undefined &&
this.params.carrier_operator !== item.carrier_operator
) {
return false; return false;
} }
@ -124,8 +155,12 @@ export default {
}); });
}, },
filterPackages() { filterPackages() {
this.packageFilters = this.packages.filter(item => { let packages = this.packages.filter(item => {
if ((this.params.carrier_operator !== '' && this.params.carrier_operator !== undefined) && this.params.carrier_operator !== item.carrier_operator) { if (
this.params.carrier_operator !== "" &&
this.params.carrier_operator !== undefined &&
this.params.carrier_operator !== item.carrier_operator
) {
return false; return false;
} }
@ -133,11 +168,18 @@ export default {
return true; return true;
} }
if (this.data && item.company_ids.indexOf(this.data.company_id) !== -1) { if (
this.data &&
item.company_ids.indexOf(this.data.company_id) !== -1
) {
return true; return true;
} }
if ((this.params.company_id !== '' && this.params.company_id !== undefined) && item.company_ids.indexOf(this.params.company_id) !== -1) { if (
this.params.company_id !== "" &&
this.params.company_id !== undefined &&
item.company_ids.indexOf(this.params.company_id) !== -1
) {
let index = this.params.package_ids.indexOf(item.id); let index = this.params.package_ids.indexOf(item.id);
if (index !== -1) { if (index !== -1) {
@ -149,64 +191,74 @@ export default {
return true; return true;
}); });
this.packageFilters = packages;
}, },
selectCO() { selectCO() {
this.filterReals(); this.filterReals();
this.filterPackages(); this.filterPackages();
}, },
ok() { ok() {
if (this.params.company_id === '') { if (this.params.company_id === "") {
this.$Message.info('请选择企业'); this.$Message.info("请选择企业");
} }
if (this.params.carrier_operator === '') { if (this.params.carrier_operator === "") {
this.$Message.info('请选择运营商'); this.$Message.info("请选择运营商");
} }
this.params.start_at = this.moment(this.params.start_at).format('YYYY-MM'); this.params.start_at = this.moment(this.params.start_at).format(
"YYYY-MM"
);
if (this.data) { if (this.data) {
// 编辑 // 编辑
API.update(this.params, this.data.id).then(res => { API.update(this.params, this.data.id)
this.loading = false; .then(res => {
if (res.code == 0) { this.loading = false;
this.$emit('update-success'); if (res.code == 0) {
this.$Message.success('更新成功'); this.$emit("update-success");
this.clear(); this.$Message.success("更新成功");
} this.clear();
}).catch(err => { }
this.loading = false; })
}); .catch(err => {
this.loading = false;
});
} else { } else {
// 添加 // 添加
API.create(this.params).then(res => { API.create(this.params)
this.loading = false; .then(res => {
if (res.code == 0) { this.loading = false;
this.$emit('add-success'); if (res.code == 0) {
this.$Message.success('添加成功'); this.$emit("add-success");
this.clear(); this.$Message.success("添加成功");
} this.clear();
}).catch(err => { }
this.loading = false; })
}); .catch(err => {
this.loading = false;
});
} }
}, },
visibleChange(bool) { visibleChange(bool) {
if (!bool) { if (!bool) {
this.$emit('update:show', false); this.$emit("update:show", false);
} }
}, },
clear() { clear() {
for (let k in this.params) { for (let k in this.params) {
if (k == 'status') { if (k == "status") {
this.params[k] = 0; this.params[k] = 0;
} else if (k == 'real_pool_ids' || k == 'package_ids') { } else if (k == "real_pool_ids" || k == "package_ids") {
this.params[k] = []; this.params[k] = [];
} else if (k == 'start_at') { } else if (k == "start_at") {
this.params[k] = this.moment().subtract('1', 'months').format('YYYY-MM'); this.params[k] = this.moment()
.subtract("1", "months")
.format("YYYY-MM");
} else { } else {
this.params[k] = ''; this.params[k] = "";
} }
} }
@ -226,8 +278,8 @@ export default {
if (this.package_ids.length > ids.length) { if (this.package_ids.length > ids.length) {
this.$Modal.confirm({ this.$Modal.confirm({
title: '请谨慎操作!', title: "请谨慎操作!",
content: '移除已选套餐,可能会引起已有数据的变化。', content: "移除已选套餐,可能会引起已有数据的变化。",
onOk: () => { onOk: () => {
this.package_ids = ids; this.package_ids = ids;
this.params.package_ids = ids; this.params.package_ids = ids;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=\favicon.ico><script src=\config.js></script><title></title><link href=/css/chunk-77b548cf.c0895d74.css rel=prefetch><link href=/css/chunk-996b1e80.5cadf3d0.css rel=prefetch><link href=/js/chunk-00ae0766.d130b440.js rel=prefetch><link href=/js/chunk-07a274ec.55e1b3b0.js rel=prefetch><link href=/js/chunk-77b548cf.10ad475b.js rel=prefetch><link href=/js/chunk-996b1e80.92847c4e.js rel=prefetch><link href=/css/app.8e379248.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.e27ceaab.js rel=preload as=script><link href=/js/chunk-vendors.ed6443e8.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e379248.css rel=stylesheet></head><body><noscript><strong>很抱歉如果没有启用JavaScript程序不能正常工作若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ed6443e8.js></script><script src=/js/app.e27ceaab.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=\favicon.ico><script src=\config.js></script><title></title><link href=/css/chunk-77b548cf.c0895d74.css rel=prefetch><link href=/css/chunk-996b1e80.5cadf3d0.css rel=prefetch><link href=/js/chunk-00ae0766.d130b440.js rel=prefetch><link href=/js/chunk-07a274ec.55e1b3b0.js rel=prefetch><link href=/js/chunk-77b548cf.c72d66a3.js rel=prefetch><link href=/js/chunk-996b1e80.92847c4e.js rel=prefetch><link href=/css/app.8e379248.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.6a83c72f.js rel=preload as=script><link href=/js/chunk-vendors.ed6443e8.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e379248.css rel=stylesheet></head><body><noscript><strong>很抱歉如果没有启用JavaScript程序不能正常工作若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ed6443e8.js></script><script src=/js/app.6a83c72f.js></script></body></html>