流量池列表

This commit is contained in:
邓皓元 2019-02-26 15:24:46 +08:00
parent 92a9421159
commit 3c362d54ed
22 changed files with 437 additions and 62 deletions

View File

@ -24,6 +24,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\Stats\Exports\CompanyCountExport::class => '企业统计',
\App\Domains\Stats\Exports\OrderExport::class => '订单统计',
\App\Domains\Stats\Exports\OrderDetailExport::class => '订单明细',
@ -154,6 +155,10 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize
$title .= Carbon::parse($conditions['starttime'])->format('Ymd') . '-' . Carbon::parse($conditions['endtime'])->format('Ymd');
}
if (($conditions = $this->conditions) && $conditions['month']) {
$title .= Carbon::parse($conditions['month'])->format('Ym');
}
return $title ?? '列表';
}

View File

@ -0,0 +1,87 @@
<?php
namespace App\Domains\Virtual\Exports;
use App\Core\AbstractExport;
use Illuminate\Support\Carbon;
use Dipper\Excel\Concerns\WithHeadings;
use Dipper\Excel\Concerns\FromCollection;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use App\Domains\Virtual\Services\FlowPoolService;
class FlowPoolExport extends AbstractExport implements FromCollection, WithHeadings
{
public $conditions;
public function __construct(array $conditions = [])
{
$this->conditions = $conditions;
parent::__construct();
}
public function collection()
{
$this->conditions['limit'] = 0;
$list = app(FlowPoolService::class)->index($this->conditions)->map(function ($item) {
return collect([
'id' => $item->id,
'name' => $item->name,
'carrier_operator_name' => $item->carrier_operator_name,
'shared_name' => $item->shared_name,
'company_name' => $item->company_name,
'minimum_flows' => $item->minimum_flows,
'excess_flows' => $item->excess_flows,
'minimum_price' => $item->minimum_price,
'excess_price' => $item->excess_price,
'members' => $item->members,
'total_price' => $item->total_price,
]);
});
$list->push([
'总计',
'',
'',
'',
'',
'',
'',
array_sum($list->pluck('minimum_price')->toArray()) ?: 0,
array_sum($list->pluck('excess_price')->toArray()) ?: 0,
array_sum($list->pluck('members')->toArray()) ?: 0,
array_sum($list->pluck('total_price')->toArray()) ?: 0,
]);
return $list;
}
public function headings(): array
{
return [
'ID',
'名称',
'运营商',
'共享类型',
'客户名称',
'保底流量',
'超出流量',
'保底收入(元)',
'超出收入(元)',
'收费用户数',
'总收入(元)',
];
}
/**
* @return array
*/
public function columnFormats(): array
{
return [
'H' => NumberFormat::FORMAT_NUMBER_00,
'I' => NumberFormat::FORMAT_NUMBER_00,
'K' => NumberFormat::FORMAT_NUMBER_00,
];
}
}

View File

@ -10,6 +10,8 @@ use App\Exceptions\NotExistException;
use Illuminate\Support\Facades\Validator;
use App\Models\Virtual\OrderCardPartition;
use App\Exceptions\InvalidArgumentException;
use App\Domains\Export\Services\ExportService;
use App\Domains\Virtual\Exports\FlowPoolExport;
use App\Domains\Virtual\Imports\FlowCardImport;
use App\Domains\Virtual\Services\ProductService;
use App\Domains\Virtual\Services\FlowPoolService;
@ -175,7 +177,7 @@ class FlowPoolController extends Controller
$cards->map(function ($item) {
$item->product_name = ProductService::load($item->product_id)['name'];
});
}else{
} else {
$cards = collect();
}
@ -201,10 +203,21 @@ class FlowPoolController extends Controller
'news' => $card['total'],
];
} else {
$chunk = $settings[$card['product_id']]['cards'];
foreach ($chunk as &$value) {
$value['flow_range'][0] = sprintf('%.02f', $value['flow_range'][0]/1024);
$value['flow_range'][1] = sprintf('%.02f', $value['flow_range'][1]/1024);
}
$settings[$card['product_id']]['cards'] = $chunk;
$settings[$card['product_id']]['news'] = $card['total'] - array_sum(array_pluck($settings[$card['product_id']]['cards'], 'counts'));
}
}
$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']], '数据设置');
}
@ -214,4 +227,24 @@ class FlowPoolController extends Controller
return res($res, '设置成功');
}
/**
* 导出.
*
* @return \Illuminate\Http\Response
*/
public function export()
{
$conditions = $this->request->except(['page', 'limit']);
$conditions['limit'] = 0;
try {
$export = new FlowPoolExport($conditions);
$url = ExportService::store($export, $disk = 'public');
} catch (\Exception $e) {
throw $e;
}
return res($url, '导出成功', 201);
}
}

View File

@ -57,6 +57,7 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
$router->get('/flow-pools/real', ['as' => 'flow-pools.real', 'uses' => 'FlowPoolController@real']);
$router->get('/flow-pools/products', ['as' => 'flow-pools.products', 'uses' => 'FlowPoolController@products']);
$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->post('/flow-pools/create', ['as' => 'flow-pools.create', 'uses' => 'FlowPoolController@create']);
$router->post('/flow-pools/update/{id}', ['as' => 'flow-pools.update', 'uses' => 'FlowPoolController@update']);

View File

@ -123,6 +123,90 @@ class FlowPoolService extends Service
$flowPools = $this->transformer($flowPools, $month);
$table = app(FlowPoolMonth::class)->getTable() . '_' . $month->format('Ym');
$select = [
"$table.sim",
'product_id',
'pool_id',
'kilobyte',
'cards.virtual_activated_at'
];
$flows = app(FlowPoolMonth::class)->setTable($table)->leftJoin('cards', 'cards.sim', '=', "{$table}.sim")->select($select)
->whereIn('pool_id', $flowPools->pluck('id')->toArray())->get()->groupBy('pool_id');
// 流量统计
$flowPools->map(function ($flowPool) use ($month, $flows) {
$monthInt = $month->format('Ym');
$flowArry = $flows[$flowPool->id];
// 无使用流量
if (!$flowArry) {
$flowPool->members = 0;
$flowPool->minimum_flows = $this->humanFlows(0);
$flowPool->excess_flows = $this->humanFlows(0);
$flowPool->minimum_price = sprintf('%.02f', 0);
$flowPool->excess_price = sprintf('%.02f', 0);
$flowPool->total_price = sprintf('%.02f', 0);
return $flowPool;
}
$setting = $flowPool->settings->where('start_at', '<=', $month)->where('end_at', '>=', $month)->first();
// 无计费规则
if (!$setting) {
$flowPool->members = $flowArry->count();
$flowPool->minimum_flows = $this->humanFlows(0);
$flowPool->excess_flows = $this->humanFlows(array_sum($flowArry->pluck('kilobyte')));
$flowPool->minimum_price = sprintf('%.02f', 0);
$flowPool->excess_price = sprintf('%.02f', 0);
$flowPool->total_price = sprintf('%.02f', 0);
return $flowPool;
}
$gradient = $setting['gradient'] * pow(1024, $setting['gradient_unit']);
$first_month_price = $setting['first_month_price'] / pow(1024, $setting['gradient_unit'] + 1);
$other_month_price = $setting['other_month_price'] / pow(1024, $setting['gradient_unit'] + 1);
$minimum_settings = array_keyBy($setting['minimum_settings'], 'product_id');
$flowGroup = $flowArry->groupBy('product_id');
$flowPool->members = $flowArry->count();
$minimum_flows = 0;
$excess_flows = 0;
$minimum_price = 0;
$excess_price = 0;
foreach ($flowGroup as $product_id => $flowItems) {
$minimum_setting = $minimum_settings[$product_id];
foreach ($flowItems as $item) {
$itemMinimumFlows = $minimum_setting['flows'] ?? 0;
$minimum_flows += $itemMinimumFlows;
$minimum_price += $minimum_setting['price'] ?? 0;
$excess_flow = $item->kilobyte < $itemMinimumFlows ? 0 : $item->kilobyte - $itemMinimumFlows;
$excess_flows += ceil($excess_flow / $gradient) * $gradient;
$price = (date('Ym', strtotime($item->virtual_activated_at)) == $monthInt) ? $first_month_price : $other_month_price;
$excess_price += $excess_flow * $price;
}
}
$flowPool->minimum_flows = $this->humanFlows($minimum_flows);
$flowPool->excess_flows = $this->humanFlows($excess_flows);
$flowPool->minimum_price = sprintf('%.02f', $minimum_price / 100);
$flowPool->excess_price = sprintf('%.02f', $excess_price / 100);
$flowPool->total_price = sprintf('%.02f', ($minimum_price + $excess_price) / 100);
return $flowPool;
});
$flowPools->map(function ($item) {
$item = $this->transformerSettings($item);
});
return $flowPools;
}
@ -203,6 +287,23 @@ class FlowPoolService extends Service
{
$attributes['start_at'] = Carbon::parse($attributes['start_at'])->startOfMonth()->format('Y-m-d H:i:s');
$attributes['end_at'] = Carbon::parse($attributes['end_at'])->endOfMonth()->format('Y-m-d H:i:s');
$attributes['first_month_price'] = intval($attributes['first_month_price'] * 100);
$attributes['other_month_price'] = intval($attributes['other_month_price'] * 100);
$attributes['gradient'] = intval($attributes['gradient'] * 1024);
if (!is_array($attributes['minimum_settings'])) {
throw new InvalidArgumentException('保底流量设置必须为数组');
}
$minimum_settings = $attributes['minimum_settings'];
foreach ($minimum_settings as &$item) {
$item = array_only($item, ['product_id', 'price', 'flows']);
$item['price'] = intval($item['price'] * 100);
$item['flows'] = intval($item['flows'] * 1024);
}
$attributes['minimum_settings'] = $minimum_settings;
if ($attributes['start_at'] > $attributes['end_at']) {
throw new InvalidArgumentException('开始时间必须小于结束时间');
@ -327,9 +428,13 @@ class FlowPoolService extends Service
public function flows(array $conditions)
{
$conditions = array_only($conditions, ['pool_id', 'month', 'total_flows', 'settings']);
$conditions['total_flows'] = intval($conditions['total_flows'] * 1024);
$settings = $conditions['settings'];
$min_total_flows = 0;
$max_total_flows = 0;
foreach ($settings as &$setting) {
$setting = array_only($setting, ['product_id', 'product_name', 'total', 'cards']);
@ -337,13 +442,22 @@ class FlowPoolService extends Service
foreach ($cards as &$card) {
$card = array_only($card, ['counts', 'flow_range']);
$card['flow_range'][0] = intval($card['flow_range'][0] * 1024);
$card['flow_range'][1] = intval($card['flow_range'][1] * 1024);
$min_total_flows += $card['counts'] * $card['flow_range'][0];
$max_total_flows += $card['counts'] * $card['flow_range'][1];
}
$setting['cards'] = $cards;
}
unset($setting);
$conditions['settings'] = $settings;
if ($min_total_flows > $conditions['total_flows'] || $max_total_flows < $conditions['total_flows']) {
throw new NotAllowedException('流量范围设置不正确,最小流量大于总流量或最大流量小于总流量');
}
$pool_id = $conditions['pool_id'];
$month = Carbon::parse($conditions['month']);
$settings = array_keyBy($conditions['settings'], 'product_id');
@ -363,7 +477,11 @@ class FlowPoolService extends Service
])->withConditions([
'month' => $month,
'product_id' => array_keys($settings),
])->get()->groupBy('product_id')->toArray();
])->get();
$allTotal = $cards->count();
$cards = $cards->groupBy('product_id')->toArray();
$data = [];
@ -381,19 +499,23 @@ class FlowPoolService extends Service
$offset = 0;
foreach ($setting['cards'] as $cardSetting) {
$simArray = array_slice($array, $offset, $cardSetting['counts']);
$offset += $cardSetting['counts'];
$range_start = intval($cardSetting['flow_range'][0] * 1024);
$range_end = intval($cardSetting['flow_range'][1] * 1024);
$range_start = $cardSetting['flow_range'][0];
$range_end = $cardSetting['flow_range'][1];
if ($range_end < $range_start) {
throw new NotAllowedException("流量范围结束必须不小于开始");
}
$dataItems = [];
$flows = $conditions['total_flows'] * $cardSetting['counts'] / $allTotal;
foreach ($simArray as $sim) {
$kilobyte = rand($range_start, $range_end);
$data[] = [
$dataItems[] = [
'month' => $month->format('Ym'),
'sim' => $sim['sim'],
'product_id' => $product_id,
@ -401,6 +523,18 @@ class FlowPoolService extends Service
'kilobyte' => $kilobyte,
];
}
$itemKilobyte = array_sum(array_pluck($dataItems, 'kilobyte'));
if ($itemKilobyte) {
$k = $flows/$itemKilobyte;
foreach ($dataItems as &$value) {
$value['kilobyte'] = round($value['kilobyte'] * $k);
}
}
$data = array_merge($data, $dataItems);
}
}
@ -417,7 +551,7 @@ class FlowPoolService extends Service
FlowPoolData::updateOrCreate(array_only($flowPoolData, ['pool_id', 'month']), $flowPoolData);
DB::transaction(function () use ($table, $data) {
DB::transaction(function () use ($table, $data, $pool_id) {
try {
app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id)->delete();
@ -471,6 +605,8 @@ class FlowPoolService extends Service
$cards = new LengthAwarePaginator($cards, $total, $limit);
$flowPool = $this->transformerSettings($flowPool);
return ['flowPool' => $flowPool, 'cards' => $cards];
}
@ -510,31 +646,30 @@ class FlowPoolService extends Service
$item->products = $products;
if ($settings = $allSettings[$item->id]) {
foreach ($settings as $setting) {
if ($setting->start_at <= $month && $setting->end_at >= $month) {
$setting_status = 1;
$minimum_settings = $setting->minimum_settings ?? [];
$minimum_settings = array_keyBy($setting->minimum_settings ?? [], 'product_id');
foreach ($products as $product) {
if (!in_array($product['product_id'], array_pluck($minimum_settings, 'product_id'))) {
$setting_status = 0;
$minimum_settings[] = [
if (!isset($minimum_settings[$product['product_id']])) {
$minimum_settings[$product['product_id']] = [
'product_id' => $product['product_id'],
'product_name' => ProductService::load($value)['name'],
'product_name' => $product['product_name'],
'flows' => 0,
'price' => 0
];
} else {
$minimum_settings[$product['product_id']]['product_name'] = $product['product_name'];
}
}
$setting->minimum_settings = $minimum_settings;
$setting->minimum_settings = array_values($minimum_settings);
}
}
} else {
$settings = [];
$settings = collect();
$setting_status = 0;
}
@ -545,6 +680,35 @@ class FlowPoolService extends Service
return $flowPools;
}
/**
* 流量池格式转化
*
* @param mixed $item
* @return void
*/
public static function transformerSettings($item)
{
$settings = $item->settings;
foreach ($settings as &$setting) {
$setting['first_month_price'] = sprintf('%.02f', $setting['first_month_price']/100);
$setting['other_month_price'] = sprintf('%.02f', $setting['other_month_price']/100);
$setting['gradient'] = sprintf('%.02f', $setting['gradient']/1024);
$minimum_settings = $setting['minimum_settings'] ?? [];
foreach ($minimum_settings as &$minimum_setting) {
$minimum_setting['price'] = sprintf('%.02f', $minimum_setting['price']/100);
$minimum_setting['flows'] = floatval($minimum_setting['flows']/1024);
}
$setting['minimum_settings'] = $minimum_settings;
}
$item->settings = $settings;
return $item;
}
public static function sn($id)
{
return sprintf('FP%011d', $id);
@ -558,4 +722,11 @@ class FlowPoolService extends Service
return self::$pools[$id];
}
public static function humanFlows($int)
{
return human_filesize($int, 2, ['unit' => 'KB', 'min' => 'MB', 'max' => 'PB']);
}
}

View File

@ -0,0 +1,6 @@
<?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));

View File

@ -3,8 +3,14 @@
namespace App\Models\Virtual;
use App\Core\Model;
use App\Models\Card\Card;
class FlowPoolMonth extends Model
{
protected $table = 'virtual_flow_pool_months';
public function card()
{
return $this->hasOne(Card::class, 'sim', 'sim');
}
}

View File

@ -31,6 +31,17 @@ export function index(data) {
});
}
/**
* [exportList 流量池列表导出]
* @param {[type]} data [description]
* @return {[type]} [description]
*/
export function exportList(data) {
return service.get('api/virtual/flow-pools/export', {
params: data
});
}
/**
* [show 流量池详情]
* @param {[type]} id [description]

View File

@ -26,6 +26,10 @@
<div class="handle-item">
<Button @click="index(1)" icon="md-refresh">刷新</Button>
</div>
<div class="handle-item">
<Button @click="exportExcel" icon="md-download">导出</Button>
</div>
</li>
</ul>
@ -111,7 +115,7 @@
<ui-setting
:show.sync="settingObj.show"
:data="settingObj.data"
@add-success="index"
@add-success="index(list_data.current_page)"
@update-success="index(list_data.current_page)"
></ui-setting>
@ -119,6 +123,7 @@
:pool_id="flowsObj.pool_id"
:show.sync="flowsObj.show"
:month="moment(options.month).format('YYYY-MM')"
@add-success="index(list_data.current_page)"
></ui-flows>
</div>
</template>

View File

@ -12,7 +12,7 @@ export default {
},
data: {
type: Object,
default() {
default () {
return null;
}
}
@ -22,10 +22,6 @@ export default {
this.my_show = bool;
if (bool) {
if (this.flowPool && this.flowPool.id === this.data.id) {
return;
}
this.index(1);
}
}
@ -35,8 +31,7 @@ export default {
my_show: false,
flowPool: null,
cards: null,
settingsColumns: [
{
settingsColumns: [{
title: '首月单价',
key: 'first_month_price'
},
@ -58,8 +53,7 @@ export default {
}
}
],
minimumSettingsColumns: [
{
minimumSettingsColumns: [{
title: '套餐名称',
key: 'product_name'
},
@ -105,6 +99,16 @@ export default {
if (res.code == 0) {
this.flowPool = res.data.flowPool;
this.cards = res.data.cards;
this.flowPool.settings.map(setting => {
setting.first_month_price = Number(setting.first_month_price);
setting.other_month_price = Number(setting.other_month_price);
setting.gradient = Number(setting.gradient);
setting.minimum_settings.map(item => {
item.price = Number(item.price);
item.flow = Number(item.flow);
});
});
}
}).catch(() => {
this.isShowLoading(false);

View File

@ -59,7 +59,7 @@ export default {
API.getFlows(params).then(res => {
if (res.code === 0) {
this.flowPool = res.data.flowPool;
this.params.total_flows = res.data.total_flows;
this.params.total_flows = Number(res.data.total_flows);
this.data = {
pool_name: res.data.flowPool.name,
@ -76,6 +76,10 @@ export default {
flow_range: [0, 0]
}];
} else {
item.cards.map(value => {
value.flow_range[0] = Number(value.flow_range[0]);
value.flow_range[1] = Number(value.flow_range[1]);
});
cards = item.cards;
}
@ -115,7 +119,7 @@ export default {
this.loading = false;
if (res.code == 0) {
this.$emit('add-success');
this.$Message.success('添加成功');
this.$Message.success('设置成功');
this.clear();
}
}).catch(err => {

View File

@ -91,33 +91,33 @@ export default {
},
{
title: '保底流量',
key: '',
key: 'minimum_flows',
width: 110
},
{
title: '超出流量',
key: '',
key: 'excess_flows',
width: 110
},
{
title: '保底收入',
key: '',
width: 110
title: '保底收入(元)',
key: 'minimum_price',
width: 150
},
{
title: '超出收入',
key: '',
width: 110
title: '超出收入(元)',
key: 'excess_price',
width: 150
},
{
title: '收费用户数',
key: '',
key: 'members',
width: 110
},
{
title: '总收入',
key: '',
width: 110
title: '总收入(元)',
key: 'total_price',
width: 150
},
{
title: '状态',
@ -279,9 +279,7 @@ export default {
*/
index(page = 1) {
let data = this.searchDataHandle({}, {
page,
orderBy: 'id',
sortedBy: 'asc'
page
}, this.params());
this.isShowLoading(true);
API.index(data).then(res => {
@ -303,7 +301,9 @@ export default {
name: this.options.name,
company_name: this.options.company_name,
carrier_operator: this.options.carrier_operator,
month: this.moment(this.options.month).format('YYYY-MM')
month: this.moment(this.options.month).format('YYYY-MM'),
orderBy: 'id',
sortedBy: 'asc'
};
return params;
@ -367,6 +367,28 @@ export default {
}
this.index(1);
},
exportExcel() {
let data = this.searchDataHandle({}, { limit: 0 }, this.params());
this.isShowLoading(true);
API.exportList(data).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);
});
}
}
};

View File

@ -20,25 +20,24 @@ export default {
start_at: this.moment('2000-01-01 00:00:00').format('YYYY-MM'),
end_at: this.moment('3000-01-01 23:59:59').format('YYYY-MM'),
monthOptions: {
shortcuts: [
{
text: '最早',
value: () => {
return this.start_at;
}
},
{
text: '至今',
value: () => {
return this.end_at;
}
},
{
text: '本月',
value: () => {
return this.moment().format('YYYY-MM');
}
shortcuts: [{
text: '最早',
value: () => {
return this.start_at;
}
},
{
text: '至今',
value: () => {
return this.end_at;
}
},
{
text: '本月',
value: () => {
return this.moment().format('YYYY-MM');
}
}
],
disabledDate(date) {
return date && (date.valueOf() < this.start_at || date.valueOf() > this.end_at);
@ -165,6 +164,14 @@ export default {
minimum_settings: minimum_settings
};
}
this.params.first_month_price = Number(this.params.first_month_price);
this.params.other_month_price = Number(this.params.other_month_price);
this.params.gradient = Number(this.params.gradient);
this.params.minimum_settings.map(item => {
item.price = Number(item.price);
item.flows = Number(item.flows);
});
}
}
};

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

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-36cd36e2.6cd40709.css rel=prefetch><link href=/js/chunk-00ae0766.9e6b7bf3.js rel=prefetch><link href=/js/chunk-36cd36e2.17dd6236.js rel=prefetch><link href=/css/app.ce4b14dc.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.aa00184d.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.ce4b14dc.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.aa00184d.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.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>

View File

@ -6,6 +6,7 @@ use Dipper\Sms\Contracts\MessageInterface;
use Dipper\Sms\Exceptions\GatewayErrorException;
use Dipper\Sms\Support\Config;
use Dipper\Sms\Traits\HasHttpRequest;
use Illuminate\Support\Facades\Log;
class FxftGateway extends Gateway
{

View File

@ -6,6 +6,7 @@ use Dipper\Sms\Contracts\MessageInterface;
use Dipper\Sms\Exceptions\GatewayErrorException;
use Dipper\Sms\Support\Config;
use Dipper\Sms\Traits\HasHttpRequest;
use Illuminate\Support\Facades\Log;
class HuyiGateway extends Gateway
{