流量池
This commit is contained in:
parent
3c362d54ed
commit
0ea764aeaf
@ -25,6 +25,7 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize
|
||||
public static $classes = [
|
||||
\App\Domains\Virtual\Exports\CardExport::class => '客户列表',
|
||||
\App\Domains\Virtual\Exports\FlowPoolExport::class => '流量池列表',
|
||||
\App\Domains\Virtual\Exports\FlowPoolExportDetailExport::class => '流量池明细',
|
||||
\App\Domains\Stats\Exports\CompanyCountExport::class => '企业统计',
|
||||
\App\Domains\Stats\Exports\OrderExport::class => '订单统计',
|
||||
\App\Domains\Stats\Exports\OrderDetailExport::class => '订单明细',
|
||||
|
97
app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php
Normal file
97
app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Virtual\Exports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Core\AbstractExport;
|
||||
use Dipper\Excel\Concerns\WithRows;
|
||||
use Dipper\Excel\Concerns\FromQuery;
|
||||
use App\Exceptions\NotExistException;
|
||||
use App\Models\Virtual\FlowPoolMonth;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Dipper\Excel\Concerns\WithHeadings;
|
||||
use Dipper\Excel\Concerns\WithColumnFormatting;
|
||||
use App\Domains\Virtual\Services\PackageService;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use App\Domains\Virtual\Services\FlowPoolService;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolRepository;
|
||||
|
||||
class FlowPoolExportDetailExport extends AbstractExport implements FromQuery, WithHeadings, WithRows, WithColumnFormatting
|
||||
{
|
||||
public $conditions;
|
||||
|
||||
public function __construct(array $conditions = [])
|
||||
{
|
||||
$this->conditions = $conditions;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$pool_id = $this->conditions['pool_id'];
|
||||
$month = Carbon::parse($this->conditions['month']);
|
||||
|
||||
$table = app(FlowPoolMonth::class)->getTable() . '_' . $month->format('Ym');
|
||||
|
||||
return app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id)->select(['product_id', 'sim', 'kilobyte']);
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
$headings = [
|
||||
'SIM',
|
||||
'套餐名称',
|
||||
'保底流量',
|
||||
'已用流量',
|
||||
];
|
||||
|
||||
return $headings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $row
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rows($rows)
|
||||
{
|
||||
$pool_id = $this->conditions['pool_id'];
|
||||
$month = Carbon::parse($this->conditions['month']);
|
||||
|
||||
if (!$flowPool = app(FlowPoolRepository::class)->find($pool_id)) {
|
||||
throw new NotExistException('流量池不存在或已删除');
|
||||
}
|
||||
|
||||
$flowPool = FlowPoolService::transformer(collect([$flowPool]), $month)->first();
|
||||
|
||||
$minimum_settings = $flowPool['settings'][0]['minimum_settings'] ?? [];
|
||||
|
||||
$minimum_flows = array_pluck($minimum_settings, 'flows', 'product_id');
|
||||
|
||||
$array = [];
|
||||
|
||||
foreach ($rows as $item) {
|
||||
$array[] = [
|
||||
$item['sim'],
|
||||
PackageService::load($item['product_id'])['name'],
|
||||
FlowPoolService::humanFlows($minimum_flows[$item['product_id']] ?? 0),
|
||||
FlowPoolService::humanFlows($item['kilobyte']),
|
||||
];
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function columnFormats(): array
|
||||
{
|
||||
return [
|
||||
'A' => NumberFormat::FORMAT_NUMBER,
|
||||
];
|
||||
}
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
<?php
|
||||
namespace App\Domains\Virtual\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Core\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Dipper\Excel\Facades\Excel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\Virtual\FlowPoolData;
|
||||
use App\Exceptions\NotExistException;
|
||||
use App\Models\Virtual\FlowPoolMonth;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Exceptions\NotAllowedException;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\Virtual\OrderCardPartition;
|
||||
use App\Exceptions\InvalidArgumentException;
|
||||
@ -16,6 +20,8 @@ use App\Domains\Virtual\Imports\FlowCardImport;
|
||||
use App\Domains\Virtual\Services\ProductService;
|
||||
use App\Domains\Virtual\Services\FlowPoolService;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolRepository;
|
||||
|
||||
use App\Domains\Virtual\Exports\FlowPoolExportDetailExport;
|
||||
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
|
||||
|
||||
class FlowPoolController extends Controller
|
||||
@ -75,11 +81,43 @@ class FlowPoolController extends Controller
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
$page = $this->request->get('page');
|
||||
$conditions = $this->request->all();
|
||||
$res = $this->flowPoolService->show($conditions);
|
||||
return res($res, '流量池详情', 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* 明细导出.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detailExport()
|
||||
{
|
||||
$conditions = $this->request->only(['pool_id', 'month']);
|
||||
|
||||
$pool_id = $conditions['pool_id'];
|
||||
$month = Carbon::parse($conditions['month']);
|
||||
|
||||
$table = app(FlowPoolMonth::class)->getTable() . '_' . $month->format('Ym');
|
||||
|
||||
if (!Schema::hasTable($table)) {
|
||||
throw new NotAllowedException('无该月数据');
|
||||
}
|
||||
|
||||
$total = app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id)->count();
|
||||
|
||||
try {
|
||||
$export = new FlowPoolExportDetailExport($conditions);
|
||||
$queue = $total > 30000;
|
||||
$url = ExportService::store($export, $disk = 'public', $queue);
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return res($url, '导出成功', 201);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建.
|
||||
@ -240,7 +278,7 @@ class FlowPoolController extends Controller
|
||||
|
||||
try {
|
||||
$export = new FlowPoolExport($conditions);
|
||||
$url = ExportService::store($export, $disk = 'public');
|
||||
$url = ExportService::store($export, $disk = 'public');
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
|
||||
$router->get('/flow-pools/index', ['as' => 'flow-pools.index', 'uses' => 'FlowPoolController@index']);
|
||||
$router->get('/flow-pools/export', ['as' => 'flow-pools.export', 'uses' => 'FlowPoolController@export']);
|
||||
$router->get('/flow-pools/show', ['as' => 'flow-pools.show', 'uses' => 'FlowPoolController@show']);
|
||||
$router->get('/flow-pools/detail/export', ['as' => 'flow-pools.detailExport', 'uses' => 'FlowPoolController@detailExport']);
|
||||
$router->post('/flow-pools/create', ['as' => 'flow-pools.create', 'uses' => 'FlowPoolController@create']);
|
||||
$router->post('/flow-pools/update/{id}', ['as' => 'flow-pools.update', 'uses' => 'FlowPoolController@update']);
|
||||
$router->post('/flow-pools/destroy', ['as' => 'flow-pools.destroy', 'uses' => 'FlowPoolController@destroy']);
|
||||
|
@ -575,6 +575,7 @@ class FlowPoolService extends Service
|
||||
public function show(array $conditions = [])
|
||||
{
|
||||
$limit = $conditions['limit'] ?? 20;
|
||||
$page = $conditions['page'] ?? 1;
|
||||
$pool_id = $conditions['pool_id'];
|
||||
$month = Carbon::parse($conditions['month']);
|
||||
|
||||
@ -593,14 +594,15 @@ class FlowPoolService extends Service
|
||||
$query = app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id);
|
||||
|
||||
if (Schema::hasTable($table) && $total = $query->count()) {
|
||||
$cards = $query->forPage($page, $limit)->get();
|
||||
$cards = $query->select(['product_id', 'sim', 'kilobyte'])->forPage($page, $limit)->get();
|
||||
} else {
|
||||
$cards = collect();
|
||||
}
|
||||
|
||||
$cards->map(function ($item) use ($minimum_flows) {
|
||||
$item->package_name = PackageService::load($item->product_id)['name'];
|
||||
$item->minimum_flows = $minimum_flows[$item->product_id] ?? 0;
|
||||
$item->product_name = PackageService::load($item->product_id)['name'];
|
||||
$item->kilobyte = $this->humanFlows($item->kilobyte);
|
||||
$item->minimum_flows = $this->humanFlows($minimum_flows[$item->product_id] ?? 0);
|
||||
});
|
||||
|
||||
$cards = new LengthAwarePaginator($cards, $total, $limit);
|
||||
@ -639,8 +641,9 @@ class FlowPoolService extends Service
|
||||
|
||||
foreach ($item->product_ids as $value) {
|
||||
$products[] = [
|
||||
'product_id' => $value,
|
||||
'product_name' => ProductService::load($value)['name'],
|
||||
'product_id' => $value,
|
||||
'type' => ProductService::load($value)['type'],
|
||||
'product_name' => ProductService::load($value)['name'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -727,6 +730,4 @@ class FlowPoolService extends Service
|
||||
{
|
||||
return human_filesize($int, 2, ['unit' => 'KB', 'min' => 'MB', 'max' => 'PB']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class ProductService extends Service
|
||||
public static function load($id)
|
||||
{
|
||||
if (!self::$products) {
|
||||
self::$products = app(ProductRepository::class)->select(['id', 'name', 'company_id', 'package_id', 'price', 'status'])
|
||||
self::$products = app(ProductRepository::class)->select(['id', 'type', 'name', 'company_id', 'package_id', 'price', 'status'])
|
||||
->withTrashed()->get()->keyBy('id');
|
||||
}
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
<?php
|
||||
$a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
var_dump(array_slice($a, 0, 2));
|
||||
|
||||
var_dump(array_slice($a, 2, 3));
|
@ -51,6 +51,17 @@ export function show(params) {
|
||||
return service.get('api/virtual/flow-pools/show', params);
|
||||
}
|
||||
|
||||
/**
|
||||
* [exportDetail 流量池详情导出]
|
||||
* @param {[type]} data [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function exportDetail(data) {
|
||||
return service.get('api/virtual/flow-pools/detail/export', {
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* [create 创建流量池]
|
||||
* @param {[type]} data [description]
|
||||
|
@ -8,10 +8,10 @@
|
||||
>
|
||||
<ui-loading :show="page_loading.show"></ui-loading>
|
||||
|
||||
<Card class="page-detail-wrap" v-if="flowPool">
|
||||
<div class="page-edit-wrap" v-if="flowPool">
|
||||
<Row>
|
||||
<Col span="8">
|
||||
<Divider>基础信息</Divider>
|
||||
<Divider>基础信息</Divider>
|
||||
<Col span="12">
|
||||
<ul>
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">统计年月:</div>
|
||||
@ -32,13 +32,27 @@
|
||||
<div class="ui-list-title">共享类型:</div>
|
||||
<div class="ui-list-content">{{flowPool.shared_name}}</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</Col>
|
||||
<Col span="12">
|
||||
<ul>
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">套餐包含:</div>
|
||||
<div class="ui-list-content">
|
||||
<Tag
|
||||
color="blue"
|
||||
v-for="(item,index) in flowPool.products"
|
||||
v-for="(item,index) in products"
|
||||
:key="index"
|
||||
>{{item.product_name}}</Tag>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">续费包包含:</div>
|
||||
<div class="ui-list-content">
|
||||
<Tag
|
||||
color="blue"
|
||||
v-for="(item,index) in renewPackageProducts"
|
||||
:key="index"
|
||||
>{{item.product_name}}</Tag>
|
||||
</div>
|
||||
@ -59,35 +73,36 @@
|
||||
</li>
|
||||
</ul>
|
||||
</Col>
|
||||
<Col offset="1" span="15">
|
||||
<Divider>计费规则</Divider>
|
||||
|
||||
<div v-if="flowPool.settings[0]">
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">超出流量:</div>
|
||||
<div class="ui-list-content">
|
||||
<Table size='small' :columns="settingsColumns" :data="flowPool.settings"></Table>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">保底流量:</div>
|
||||
<div class="ui-list-content">
|
||||
<Table size='small'
|
||||
:columns="minimumSettingsColumns"
|
||||
:data="flowPool.settings[0].minimum_settings"
|
||||
></Table>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div v-if="!flowPool.settings[0]">
|
||||
<Alert type="error">计费规则未配置</Alert>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row></Row>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Row>
|
||||
<ul>
|
||||
<li class="f-r">
|
||||
<div class="handle-item">
|
||||
<Button @click="exportExcel" icon="md-download">导出</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</Row>
|
||||
|
||||
<div class="page-list-wrap">
|
||||
<Table :columns="cardsColumns" :data="cards ? cards.data : []"></Table>
|
||||
</div>
|
||||
|
||||
<div class="page-turn-wrap" v-if="cards">
|
||||
<Page
|
||||
:current="Number(cards.current_page)"
|
||||
:page-size="Number(cards.per_page)"
|
||||
:total="Number(cards.total)"
|
||||
@on-change="index"
|
||||
:page-size-opts="[5, 10, 50, 100]"
|
||||
@on-page-size-change="changeLimit"
|
||||
show-elevator
|
||||
show-total
|
||||
show-sizer
|
||||
></Page>
|
||||
</div>
|
||||
</Drawer>
|
||||
</template>
|
||||
|
||||
|
@ -12,7 +12,7 @@ export default {
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default () {
|
||||
default() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -28,53 +28,28 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
limit: 5,
|
||||
my_show: false,
|
||||
flowPool: null,
|
||||
cards: null,
|
||||
settingsColumns: [{
|
||||
title: '首月单价',
|
||||
key: 'first_month_price'
|
||||
},
|
||||
{
|
||||
title: '次月单价',
|
||||
key: 'other_month_price'
|
||||
},
|
||||
{
|
||||
title: '梯度',
|
||||
key: 'gradient'
|
||||
},
|
||||
{
|
||||
title: '梯度单位',
|
||||
key: '',
|
||||
render: (h, {
|
||||
row
|
||||
}) => {
|
||||
return h('span', {}, row.gradient_unit ? 'M' : 'G');
|
||||
}
|
||||
}
|
||||
],
|
||||
minimumSettingsColumns: [{
|
||||
title: '套餐名称',
|
||||
key: 'product_name'
|
||||
},
|
||||
{
|
||||
title: '月保底流量',
|
||||
key: '',
|
||||
render: (h, {
|
||||
row
|
||||
}) => {
|
||||
return h('span', {}, row.flows + ' M/月');
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '月保底价格',
|
||||
key: '',
|
||||
render: (h, {
|
||||
row
|
||||
}) => {
|
||||
return h('span', {}, row.price + ' 元');
|
||||
}
|
||||
}
|
||||
products: [],
|
||||
renewPackageProducts: [],
|
||||
cardsColumns: [{
|
||||
title: 'SIM',
|
||||
key: 'sim'
|
||||
},
|
||||
{
|
||||
title: '套餐名称',
|
||||
key: 'product_name'
|
||||
},
|
||||
{
|
||||
title: '保底流量',
|
||||
key: 'minimum_flows'
|
||||
},
|
||||
{
|
||||
title: '已用流量',
|
||||
key: 'kilobyte'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
@ -89,7 +64,8 @@ export default {
|
||||
let params = {
|
||||
'pool_id': this.data.id,
|
||||
'month': this.month,
|
||||
'page': page
|
||||
'page': page,
|
||||
'limit': this.limit
|
||||
};
|
||||
|
||||
API.show({
|
||||
@ -99,6 +75,12 @@ export default {
|
||||
if (res.code == 0) {
|
||||
this.flowPool = res.data.flowPool;
|
||||
this.cards = res.data.cards;
|
||||
this.products = this.flowPool.products.filter(item => {
|
||||
return item.type === 0;
|
||||
});
|
||||
this.renewPackageProducts = this.flowPool.products.filter(item => {
|
||||
return item.type === 2;
|
||||
});
|
||||
|
||||
this.flowPool.settings.map(setting => {
|
||||
setting.first_month_price = Number(setting.first_month_price);
|
||||
@ -116,6 +98,34 @@ export default {
|
||||
},
|
||||
visibleChange(bool) {
|
||||
this.$emit('update:show', bool);
|
||||
},
|
||||
changeLimit(limit) {
|
||||
this.limit = limit;
|
||||
this.index(1);
|
||||
},
|
||||
exportExcel() {
|
||||
let params = {
|
||||
'pool_id': this.data.id,
|
||||
'month': this.month
|
||||
};
|
||||
|
||||
this.isShowLoading(true);
|
||||
|
||||
API.exportDetail(params).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (res.data) {
|
||||
this.downloadFile(res.data);
|
||||
} else {
|
||||
this.$Modal.success({
|
||||
title: '提示',
|
||||
content: '当前导出数据量大,已进入后台队列导出模式,请稍后至导出列表查看下载。'
|
||||
});
|
||||
}
|
||||
}
|
||||
this.isShowLoading(false);
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
2
public/js/app.2a86d87f.js
Normal file
2
public/js/app.2a86d87f.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/app.2a86d87f.js.map
Normal file
1
public/js/app.2a86d87f.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/chunk-caf89654.a53630b1.js
Normal file
2
public/js/chunk-caf89654.a53630b1.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/chunk-caf89654.a53630b1.js.map
Normal file
1
public/js/chunk-caf89654.a53630b1.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -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-caf89654.f97d0276.css rel=prefetch><link href=/js/chunk-00ae0766.9e6b7bf3.js rel=prefetch><link href=/js/chunk-caf89654.eb5414d4.js rel=prefetch><link href=/css/app.8e0e058f.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.fa7f1e81.js rel=preload as=script><link href=/js/chunk-vendors.02a4e5bc.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e0e058f.css rel=stylesheet></head><body><noscript><strong>很抱歉,如果没有启用JavaScript,程序不能正常工作,若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.02a4e5bc.js></script><script src=/js/app.fa7f1e81.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-caf89654.f97d0276.css rel=prefetch><link href=/js/chunk-00ae0766.9e6b7bf3.js rel=prefetch><link href=/js/chunk-caf89654.a53630b1.js rel=prefetch><link href=/css/app.8e0e058f.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.2a86d87f.js rel=preload as=script><link href=/js/chunk-vendors.02a4e5bc.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e0e058f.css rel=stylesheet></head><body><noscript><strong>很抱歉,如果没有启用JavaScript,程序不能正常工作,若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.02a4e5bc.js></script><script src=/js/app.2a86d87f.js></script></body></html>
|
Loading…
x
Reference in New Issue
Block a user