diff --git a/app/Domains/Company/Http/Controllers/CardController.php b/app/Domains/Company/Http/Controllers/CardController.php index edd51896..d5e418d3 100644 --- a/app/Domains/Company/Http/Controllers/CardController.php +++ b/app/Domains/Company/Http/Controllers/CardController.php @@ -49,7 +49,10 @@ class CardController extends Controller $packages = $this->orderCardPartitionRepository->selectRaw('distinct on (sim) sim, package_id') ->whereIn('type', $conditions['type']) ->whereIn('sim', $cards->pluck('sim')->toArray()) - ->where('service_start_at', '<=', $time)->orderBy('sim')->orderBy('service_start_at', 'desc') + ->where(function($query) use ($time){ + $query->where('service_start_at', '<=', $time)->orWhereNull('service_start_at'); + }) + ->orderBy('sim')->orderBy('service_start_at', 'desc') ->get()->keyBy('sim'); $cards->map(function ($item) use ($services, $packages) { diff --git a/app/Domains/Stats/Services/OrderService.php b/app/Domains/Stats/Services/OrderService.php index 6f1efe13..29df3522 100644 --- a/app/Domains/Stats/Services/OrderService.php +++ b/app/Domains/Stats/Services/OrderService.php @@ -44,8 +44,6 @@ class OrderService extends Service { $repository = $this->orderCardPartitionRepository->where('type', $conditions['type']); - $conditions['source'] = 1; - $companies = $this->companyRepository->withTrashed()->get()->pluck('name', 'id')->toArray(); $packages = $this->packageRepository->withTrashed()->get()->pluck('name', 'id')->toArray(); diff --git a/app/Domains/Virtual/Commands/Sync/FlowPoolMonthSync.php b/app/Domains/Virtual/Commands/Sync/FlowPoolMonthSync.php index 266eb15f..3fd776d0 100644 --- a/app/Domains/Virtual/Commands/Sync/FlowPoolMonthSync.php +++ b/app/Domains/Virtual/Commands/Sync/FlowPoolMonthSync.php @@ -65,7 +65,7 @@ class FlowPoolMonthSync extends Command 'sim' => intval($item['sim']), 'package_id' => $packages[$item['vd_package_sn']]['id'], 'pool_id' => $pool_id, - 'kilobyte' => ceil($item['flows_used'] * 1024), + 'mebibyte' => floatval($item['flows_used']), ]; }, $items); @@ -74,7 +74,7 @@ class FlowPoolMonthSync extends Command foreach ($items as $sim => $group) { if (count($group) > 1) { $temp = $group[0]; - $temp['kilobyte'] = array_sum(array_pluck($group, 'kilobyte')); + $temp['mebibyte'] = array_sum(array_pluck($group, 'mebibyte')); $items[$sim] = [$temp]; } } diff --git a/app/Domains/Virtual/Commands/Sync/FlowPoolSync.php b/app/Domains/Virtual/Commands/Sync/FlowPoolSync.php index c1554688..1d44018a 100644 --- a/app/Domains/Virtual/Commands/Sync/FlowPoolSync.php +++ b/app/Domains/Virtual/Commands/Sync/FlowPoolSync.php @@ -75,31 +75,33 @@ class FlowPoolSync extends Command $dp_billing_rules = json_decode($item['dp_billing_rules'], true); $dp_min_cost_rules = json_decode($item['dp_min_cost_rules'], true); + $month = Carbon::parse(substr_replace($item['year_month'], '-', 4, 0)); + if (count($settings) === 1) { $start_at = '2000-01-01 00:00:00'; $end_at = '3000-01-01 23:59:59'; } else { if ($i === 0) { $start_at = '2000-01-01 00:00:00'; - $end_at = Carbon::parse($item['year_month'])->endOfMonth()->format('Y-m-d H:i:s'); + $end_at = $month->copy()->endOfMonth()->format('Y-m-d H:i:s'); } elseif ($i === count($settings) - 1) { - $start_at = Carbon::parse($item['year_month'])->startOfMonth()->format('Y-m-d H:i:s'); + $start_at = $month->copy()->startOfMonth()->format('Y-m-d H:i:s'); $end_at = '3000-01-01 23:59:59'; } else { - $start_at = Carbon::parse($item['year_month'])->startOfMonth()->format('Y-m-d H:i:s'); - $end_at = Carbon::parse($item['year_month'])->endOfMonth()->format('Y-m-d H:i:s'); + $start_at = $month->copy()->startOfMonth()->format('Y-m-d H:i:s'); + $end_at = $month->copy()->endOfMonth()->format('Y-m-d H:i:s'); } } $settingData = [ 'pool_id' => $id, 'gradient_price' => intval($dp_billing_rules['first_month_price']) * 100, - 'gradient' => $dp_billing_rules['data_step_num'] * 1024, + 'gradient' => floatval($dp_billing_rules['data_step_num']), 'gradient_unit' => $dp_billing_rules['data_step_num_unit'] === 'M' ? 0 : 1, 'start_at' => $start_at, 'end_at' => $end_at, - 'created_at' => Carbon::parse($item['year_month'])->startOfMonth()->format('Y-m-d H:i:s'), - 'updated_at' => Carbon::parse($item['year_month'])->startOfMonth()->format('Y-m-d H:i:s'), + 'created_at' => $month->copy()->startOfMonth()->format('Y-m-d H:i:s'), + 'updated_at' => $month->copy()->startOfMonth()->format('Y-m-d H:i:s'), ]; $minimum_settings = []; @@ -108,7 +110,7 @@ class FlowPoolSync extends Command $sn = explode('---', $package)[0]; $minimum_settings[] = [ 'package_id' => $packages[$sn]['id'], - 'flows' => $rule['dp_min_cost_data'] * 1024, + 'flows' => floatval($rule['dp_min_cost_data']), 'price' => $rule['dp_min_cost_money'] * 100, ]; } @@ -120,9 +122,9 @@ class FlowPoolSync extends Command $real_pool_ids = []; - foreach ( json_decode($value['dp_td_data_pool_sn'], true) as $pool_sn) { + foreach (json_decode($value['dp_td_data_pool_sn'], true) as $pool_sn) { $pool_sn = explode('---', $pool_sn)[0]; - if(isset($realFlowPools[$pool_sn])){ + if (isset($realFlowPools[$pool_sn])) { array_push($real_pool_ids, $realFlowPools[$pool_sn]['id']); } } @@ -149,8 +151,10 @@ class FlowPoolSync extends Command FlowPool::upsert($array, 'id'); $maxId = FlowPoolSetting::withoutTrashed()->max('id'); - FlowPoolSetting::whereIn('pool_id', array_pluck($array, 'id'))->forceDelete(); - DB::statement("select setval('virtual_flow_pool_settings_id_seq', {$maxId})"); + if ($maxId) { + FlowPoolSetting::whereIn('pool_id', array_pluck($array, 'id'))->forceDelete(); + DB::statement("select setval('virtual_flow_pool_settings_id_seq', {$maxId})"); + } FlowPoolSetting::insert($settingArray); app(FlowPoolRepository::class)->forgetCached(); diff --git a/app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php b/app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php index 0b6291d6..4070d079 100644 --- a/app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php +++ b/app/Domains/Virtual/Exports/FlowPoolExportDetailExport.php @@ -35,7 +35,7 @@ class FlowPoolExportDetailExport extends AbstractExport implements FromQuery, Wi $table = app(FlowPoolMonth::class)->getTable() . '_' . $month->format('Ym'); - return app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id)->select(['package_id', 'sim', 'kilobyte']); + return app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id)->select(['package_id', 'sim', 'mebibyte']); } public function headings(): array @@ -43,8 +43,8 @@ class FlowPoolExportDetailExport extends AbstractExport implements FromQuery, Wi $headings = [ 'SIM', '套餐名称', - '保底流量', - '已用流量', + '保底流量(M)', + '已用流量(M)', ]; return $headings; @@ -76,8 +76,8 @@ class FlowPoolExportDetailExport extends AbstractExport implements FromQuery, Wi $array[] = [ $item['sim'], PackageService::load($item['package_id'])['name'], - FlowPoolService::humanFlows($minimum_flows[$item['package_id']] ?? 0), - FlowPoolService::humanFlows($item['kilobyte']), + $minimum_flows[$item['package_id']] ?? 0, + $item['mebibyte'], ]; } diff --git a/app/Domains/Virtual/Http/Controllers/FlowPoolController.php b/app/Domains/Virtual/Http/Controllers/FlowPoolController.php index 7167d5a6..49a03b13 100644 --- a/app/Domains/Virtual/Http/Controllers/FlowPoolController.php +++ b/app/Domains/Virtual/Http/Controllers/FlowPoolController.php @@ -245,8 +245,8 @@ class FlowPoolController extends Controller $chunk = $setting['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); + $value['flow_range'][0] = sprintf('%.02f', $value['flow_range'][0]); + $value['flow_range'][1] = sprintf('%.02f', $value['flow_range'][1]); } $setting['cards'] = $chunk; @@ -259,7 +259,7 @@ class FlowPoolController extends Controller } } - $flowPoolData['total_flows'] = sprintf('%.02f', $flowPoolData['total_flows']/1024); + $flowPoolData['total_flows'] = sprintf('%.02f', $flowPoolData['total_flows']); return res(['flowPool' => $flowPool, 'settings' => $newSettings, 'total' => $cards->values()->sum(), 'total_flows' => $flowPoolData['total_flows']], '数据设置'); } @@ -299,13 +299,13 @@ class FlowPoolController extends Controller public function importFlows() { $file = $this->request->file('file'); - $data = ImportService::load($file, ['month', 'pool_id', 'sim', 'kilobyte']); + $data = ImportService::load($file, ['month', 'pool_id', 'sim', 'mebibyte']); Validator::validate($data, [ '*.month' => ['required'], '*.pool_id' => ['required'], '*.sim' => ['required'], - '*.kilobyte' => ['required'], + '*.mebibyte' => ['required'], ]); $flowPools = app(FlowPoolRepository::class)->withConditions(['id' => array_unique(array_pluck($data, 'pool_id'))])->get()->keyBy('id')->toArray(); @@ -349,7 +349,7 @@ class FlowPoolController extends Controller foreach ($simGroupBy as $sim => $group) { if (count($group) > 1) { $temp = $group[0]; - $temp['kilobyte'] = array_sum(array_pluck($group, 'kilobyte')); + $temp['mebibyte'] = array_sum(array_pluck($group, 'mebibyte')); $simGroupBy[$sim] = [$temp]; } } diff --git a/app/Domains/Virtual/Services/FlowPoolService.php b/app/Domains/Virtual/Services/FlowPoolService.php index c158ccc2..839b2d7c 100644 --- a/app/Domains/Virtual/Services/FlowPoolService.php +++ b/app/Domains/Virtual/Services/FlowPoolService.php @@ -126,18 +126,12 @@ class FlowPoolService extends Service $flowPools = $this->transformer($flowPools, $month); - $table = app(FlowPoolMonth::class)->getTable() . '_' . $month->format('Ym'); + $flows = DB::select('select * from get_flow_pool_month_stat(?)', [$month->format('Ym')]); - if (Schema::hasTable($table)) { - $flows = app(FlowPoolMonth::class)->setTable($table) - ->select(['sim', 'package_id', 'pool_id', 'kilobyte']) - ->whereIn('pool_id', $flowPools->pluck('id')->toArray())->get()->groupBy('pool_id'); - } else { - $flows = []; - } + $flows = collect($flows)->collect()->keyBy('pool_id')->toArray(); // 流量统计 - $flowPools->map(function ($flowPool) use ($month, $flows) { + $flowPools->map(function ($flowPool) use ($flows) { $flowArry = $flows[$flowPool->id]; // 无使用流量 @@ -151,52 +145,12 @@ class FlowPoolService extends Service 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']); - $gradient_price = $setting['gradient_price'] / pow(1024, $setting['gradient_unit'] + 1); - - $minimum_settings = array_keyBy($setting['minimum_settings'], 'package_id'); - - $flowGroup = $flowArry->groupBy('package_id'); - - $flowPool->members = $flowArry->count(); - - $minimum_flows = 0; - $excess_flows = 0; - $minimum_price = 0; - $excess_price = 0; - - foreach ($flowGroup as $package_id => $flowItems) { - $minimum_setting = $minimum_settings[$package_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; - $excess_price += $excess_flow * $gradient_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); + $flowPool->members = $flowArry['members']; + $flowPool->minimum_flows = $this->humanFlows($flowArry['minimum_flows']); + $flowPool->excess_flows = $this->humanFlows($flowArry['excess_flows']); + $flowPool->minimum_price = sprintf('%.02f', $flowArry['minimum_price'] / 100); + $flowPool->excess_price = sprintf('%.02f', $flowArry['excess_price'] / 100); + $flowPool->total_price = sprintf('%.02f', $flowPool->minimum_price + $flowPool->excess_price); return $flowPool; }); @@ -285,7 +239,7 @@ 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['gradient_price'] = intval($attributes['gradient_price'] * 100); - $attributes['gradient'] = intval($attributes['gradient'] * 1024); + $attributes['gradient'] = floatval($attributes['gradient']); if (!is_array($attributes['minimum_settings'])) { throw new InvalidArgumentException('保底流量设置必须为数组'); @@ -296,7 +250,7 @@ class FlowPoolService extends Service foreach ($minimum_settings as &$item) { $item = array_only($item, ['package_id', 'price', 'flows']); $item['price'] = intval($item['price'] * 100); - $item['flows'] = intval($item['flows'] * 1024); + $item['flows'] = floatval($item['flows']); } $attributes['minimum_settings'] = $minimum_settings; @@ -422,7 +376,7 @@ 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); + $conditions['total_flows'] = floatval($conditions['total_flows']); $settings = $conditions['settings']; @@ -436,8 +390,8 @@ 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); + $card['flow_range'][0] = floatval($card['flow_range'][0]); + $card['flow_range'][1] = floatval($card['flow_range'][1]); $min_total_flows += $card['counts'] * $card['flow_range'][0]; $max_total_flows += $card['counts'] * $card['flow_range'][1]; } @@ -466,11 +420,15 @@ class FlowPoolService extends Service throw new NotAllowedException('当前月份计费规则未设置或套餐保底流量未设置'); } - $cards = app(OrderCardPartitionRepository::class)->selectRaw('distinct sim as sim, package_id')->withConditions([ + $cardConditions = [ + 'type' => [0, 1, 2], 'month' => $month, 'company_id' => $flowPool->company_id, 'package_id' => array_keys($settings), - ])->get(); + 'unit_price' => 0 + ]; + + $cards = app(OrderCardPartitionRepository::class)->selectRaw('distinct sim as sim, package_id')->withConditions($cardConditions)->get(); $allTotal = $cards->count(); @@ -506,24 +464,26 @@ class FlowPoolService extends Service $flows = $conditions['total_flows'] * $cardSetting['counts'] / $allTotal; foreach ($simArray as $sim) { - $kilobyte = rand($range_start, $range_end); + $mebibyte = rand($range_start * 100, $range_end * 100) / 100; - $dataItems[] = [ - 'month' => $month->format('Ym'), - 'sim' => $sim['sim'], - 'package_id' => $package_id, - 'pool_id' => $pool_id, - 'kilobyte' => $kilobyte, - ]; + $rowObj = [ + 'month' => $month->format('Ym'), + 'sim' => $sim['sim'], + 'package_id' => $package_id, + 'pool_id' => $pool_id, + 'mebibyte' => $mebibyte, + ]; + + $dataItems[] = $rowObj; } - $itemKilobyte = array_sum(array_pluck($dataItems, 'kilobyte')); + $itemMebibyte = array_sum(array_pluck($dataItems, 'mebibyte')); - if ($itemKilobyte) { - $k = $flows/$itemKilobyte; + if ($itemMebibyte) { + $k = $flows/$itemMebibyte; foreach ($dataItems as &$value) { - $value['kilobyte'] = round($value['kilobyte'] * $k); + $value['mebibyte'] = round($value['mebibyte'] * $k); } } @@ -581,14 +541,14 @@ class FlowPoolService extends Service $query = app(FlowPoolMonth::class)->setTable($table)->where('pool_id', $pool_id); if (Schema::hasTable($table) && $total = $query->count()) { - $cards = $query->select(['package_id', 'sim', 'kilobyte'])->forPage($page, $limit)->get(); + $cards = $query->select(['package_id', 'sim', 'mebibyte'])->forPage($page, $limit)->get(); } else { $cards = collect(); } $cards->map(function ($item) use ($minimum_flows) { $item->package_name = PackageService::load($item->package_id)['name']; - $item->kilobyte = $this->humanFlows($item->kilobyte); + $item->mebibyte = $this->humanFlows($item->mebibyte); $item->minimum_flows = $this->humanFlows($minimum_flows[$item->package_id] ?? 0); }); @@ -697,12 +657,12 @@ class FlowPoolService extends Service foreach ($settings as &$setting) { $setting['gradient_price'] = sprintf('%.02f', $setting['gradient_price']/100); - $setting['gradient'] = sprintf('%d', $setting['gradient']/1024); + $setting['gradient'] = sprintf('%.02f', $setting['gradient']); $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); + $minimum_setting['flows'] = floatval($minimum_setting['flows']); } $setting['minimum_settings'] = $minimum_settings; @@ -729,7 +689,7 @@ class FlowPoolService extends Service public static function humanFlows($int) { - return human_filesize($int, 2, ['unit' => 'KB', 'min' => 'MB', 'max' => 'PB']); + return human_filesize($int, 2, ['unit' => 'MB', 'min' => 'MB', 'max' => 'MB']); } /** diff --git a/app/Models/Virtual/FlowPoolMonth.php b/app/Models/Virtual/FlowPoolMonth.php index 6132e14c..d4f8bbf3 100644 --- a/app/Models/Virtual/FlowPoolMonth.php +++ b/app/Models/Virtual/FlowPoolMonth.php @@ -13,13 +13,13 @@ use App\Models\Card\Card; * @property int $sim SIM号 * @property int $package_id 套餐ID * @property int $pool_id 流量池ID - * @property int $kilobyte 使用流量 单位KB + * @property int $mebibyte 使用流量 单位MB * @property-read \App\Models\Card\Card $card * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth query() * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth whereId($value) - * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth whereKilobyte($value) + * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth wheremebibyte($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth whereMonth($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth wherePoolId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Virtual\FlowPoolMonth whereProductId($value) diff --git a/app/helpers.php b/app/helpers.php index e3511193..3d4d2e84 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -177,7 +177,9 @@ if (! function_exists('human_filesize')) { $factor = $factor > array_search($options['max'], $size) ? array_search($options['max'], $size) : $factor; } - return sprintf("%.{$decimals}f", $int / pow(1024, $factor)) . @$size[$factor]; + $result = $int / pow(1024, $factor); + + return sprintf("%.{$decimals}f", $result) . @$size[$factor]; } } diff --git a/database/migrations/2019_01_24_175246_create_flow_pool_tables.php b/database/migrations/2019_01_24_175246_create_flow_pool_tables.php index 3136fd70..e9fbe8dc 100644 --- a/database/migrations/2019_01_24_175246_create_flow_pool_tables.php +++ b/database/migrations/2019_01_24_175246_create_flow_pool_tables.php @@ -38,7 +38,7 @@ class CreateFlowPoolTables extends Migration $table->string('sn', 32)->default('')->comment('编号'); $table->integer('company_id')->unsigned()->default(0)->comment('关联企业ID'); $table->string('name', 32)->unsigned()->default(0)->comment('名称'); - $table->integer('flows')->default(255)->comment('流量值 -1不限流量 单位MB'); + $table->integer('flows')->default(-1)->comment('流量值 -1不限流量 单位MB'); $table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)'); $table->tinyInteger('shared')->unsigned()->default(0)->comment('共享类型 0:未知 1纵向共享 2横向共享'); $table->text('package_ids')->nullable()->comment('包含套餐'); @@ -61,7 +61,7 @@ class CreateFlowPoolTables extends Migration $table->integer('pool_id')->unsigned()->default(0)->comment('流量池ID'); $table->text('minimum_settings')->nullable()->comment('套餐保底配置'); $table->integer('gradient_price')->unsigned()->default(0)->comment('梯度单价'); - $table->integer('gradient')->unsigned()->default(0)->comment('梯度'); + $table->decimal('gradient', 10, 2)->unsigned()->default(0)->comment('梯度'); $table->tinyInteger('gradient_unit')->unsigned()->default(0)->comment('梯度单位 0:M 1:G'); $table->timestamp('start_at')->nullable()->comment('开始时间'); $table->timestamp('end_at')->nullable()->comment('结束时间'); @@ -79,7 +79,7 @@ class CreateFlowPoolTables extends Migration $table->increments('id')->comment('自增ID'); $table->integer('pool_id')->unsigned()->default(0)->comment('流量池ID'); $table->integer('month')->unsigned()->default(0)->comment('月份'); - $table->integer('total_flows')->unsigned()->default(0)->comment('总使用流量 单位KB'); + $table->decimal('total_flows', 10, 2)->unsigned()->default(0)->comment('总使用流量 单位MB'); $table->text('settings')->nullable()->comment('配置'); $table->timestamps(); @@ -96,12 +96,14 @@ class CreateFlowPoolTables extends Migration $table->bigInteger('sim')->unsigned()->default(0)->comment('SIM号'); $table->integer('package_id')->unsigned()->default(0)->comment('套餐ID'); $table->integer('pool_id')->unsigned()->default(0)->comment('流量池ID'); - $table->integer('kilobyte')->unsigned()->default(0)->comment('使用流量 单位KB'); + $table->decimal('mebibyte', 10, 2)->unsigned()->default(0)->comment('使用流量 单位MB'); $table->comment('VD卡月流量'); $table->partition('month', 'list'); }); } + + DB::unprepared(File::get(__DIR__ . '/create_flow_pool_settings_view.pgsql')); } /** diff --git a/database/migrations/create_flow_pool_settings_view.pgsql b/database/migrations/create_flow_pool_settings_view.pgsql new file mode 100644 index 00000000..7c794a9c --- /dev/null +++ b/database/migrations/create_flow_pool_settings_view.pgsql @@ -0,0 +1,64 @@ +CREATE OR REPLACE VIEW virtual_flow_pool_settings_view AS + SELECT pool_id, + json_array_elements(minimum_settings::json) ->> 'package_id' AS package_id, + json_array_elements(minimum_settings::json) ->> 'flows' AS flows, + json_array_elements(minimum_settings::json) ->> 'price' AS price, + gradient * pow(1024, gradient_unit) as gradient, + gradient_price / pow(1024, gradient_unit) as gradient_price, + start_at, + end_at + FROM virtual_flow_pool_settings + +CREATE OR REPLACE FUNCTION GET_FLOW_POOL_MONTH_STAT(INT) + RETURNS TABLE + ( + pool_id INT, + members NUMERIC, + minimum_flows NUMERIC, + minimum_price NUMERIC, + excess_flows NUMERIC, + excess_price NUMERIC + ) +AS +$$ +DECLARE + query TEXT; +BEGIN + query := 'SELECT virtual_flow_pool_months.pool_id, + virtual_flow_pool_months.package_id, + COUNT(*) as members, + SUM(virtual_flow_pool_settings_view.flows::NUMERIC) AS minimum_flows, + SUM(virtual_flow_pool_settings_view.price::NUMERIC) AS minimum_price, + CASE WHEN SUM(virtual_flow_pool_months.mebibyte) - SUM(virtual_flow_pool_settings_view.flows::NUMERIC) < 0 THEN 0 + ELSE SUM(virtual_flow_pool_months.mebibyte) - SUM(virtual_flow_pool_settings_view.flows::NUMERIC) END AS excess_flows, + AVG(virtual_flow_pool_settings_view.gradient::int) AS gradient, + AVG(virtual_flow_pool_settings_view.gradient_price::NUMERIC) AS gradient_price +FROM virtual_flow_pool_months + JOIN virtual_flow_pool_settings_view ON + virtual_flow_pool_settings_view.package_id::int = virtual_flow_pool_months.package_id AND + virtual_flow_pool_settings_view.pool_id::int = virtual_flow_pool_months.pool_id AND + virtual_flow_pool_settings_view.start_at <= + (overlay($1::text placing ''-'' from 5 for 0) || ''-01 00:00:00'')::TIMESTAMP AND + (virtual_flow_pool_settings_view.end_at >= + (overlay($1::text placing ''-'' from 5 for 0) || ''-01 23:59:59'')::TIMESTAMP OR + virtual_flow_pool_settings_view.end_at IS NULL) + WHERE virtual_flow_pool_months.month = $1 + GROUP BY virtual_flow_pool_months.pool_id, virtual_flow_pool_months.package_id + '; + + query := 'SELECT pool_id, + SUM(members) as members, + SUM(minimum_flows) as minimum_flows, + SUM(minimum_price) as minimum_price, + SUM(excess_flows) as excess_flows, + CEIL(SUM(excess_flows) / AVG(gradient)) * AVG(gradient) * AVG(gradient_price) as excess_price + FROM (' || query || ') AS t GROUP BY pool_id'; + + RAISE NOTICE '%s', query; + + RETURN QUERY EXECUTE query USING $1; +END; +$$ LANGUAGE plpgsql; + + + diff --git a/database/seeds/PermissionSeeder.php b/database/seeds/PermissionSeeder.php index f59da866..1d8101df 100644 --- a/database/seeds/PermissionSeeder.php +++ b/database/seeds/PermissionSeeder.php @@ -246,6 +246,8 @@ class PermissionSeeder extends Seeder ['name' => 'virtual.flow-pools.create', 'title' => '创建', 'description' => 'create', 'type' => 1], ['name' => 'virtual.flow-pools.update', 'title' => '编辑', 'description' => 'update', 'type' => 1], ['name' => 'virtual.flow-pools.destroy', 'title' => '删除', 'description' => 'destroy', 'type' => 1], + ['name' => 'virtual.flow-pools.import', 'title' => '导入', 'description' => 'input', 'type' => 1], + ['name' => 'virtual.flow-pools.export', 'title' => '导出', 'description' => 'output', 'type' => 1], ], ], ], @@ -266,6 +268,12 @@ class PermissionSeeder extends Seeder ['name' => 'stats.company-report.1', 'title' => '用户月报表', 'path' => '/stats/company-report/1', 'icon' => 'ios-contacts', 'type' => 0, 'open' => 3], ['name' => 'stats.company-report.2', 'title' => '增值包月报表', 'path' => '/stats/company-report/2', 'icon' => 'md-bonfire', 'type' => 0, 'open' => 3], ['name' => 'stats.sold-activated', 'title' => '销售激活统计', 'path' => '/stats/sold-activated', 'icon' => 'md-timer', 'type' => 0, 'open' => 3], + [ + 'name' => 'stats.flow-pools', 'title' => '流量池统计', 'path' => '/flow-pools', 'icon' => 'md-swap', 'type' => 0, 'open' => 3, + 'children' => [ + ['name' => 'stats.flow-pools.show', 'title' => '明细', 'description' => 'show', 'type' => 1], + ] + ], ], ], [ diff --git a/database/seeds/PropertySettingSeeder.php b/database/seeds/PropertySettingSeeder.php index 460c1947..157e08d5 100644 --- a/database/seeds/PropertySettingSeeder.php +++ b/database/seeds/PropertySettingSeeder.php @@ -25,6 +25,10 @@ class PropertySettingSeeder extends Seeder */ public function run() { + if (app(PropertySettingRepository::class)->count()) { + return; + }; + app(PropertySettingRepository::class)->truncate(); $data = []; diff --git a/frontend/src/views/virtual/flow_pools/index.vue b/frontend/src/views/virtual/flow_pools/index.vue index 427e6896..1f42ca34 100644 --- a/frontend/src/views/virtual/flow_pools/index.vue +++ b/frontend/src/views/virtual/flow_pools/index.vue @@ -27,11 +27,11 @@ -