流量池初版

This commit is contained in:
邓皓元 2019-02-15 11:23:55 +08:00
parent 7d0c9d0249
commit 7bf7664bf9
26 changed files with 1460 additions and 75 deletions

View File

@ -30,6 +30,7 @@ class Dicts extends Repository
'company_transaction_status' => ['未收款', '已收款', '已退款'],
'logistics' => ['sf' => '顺丰速运', 'sto' => '申通快递','yto' => '圆通速递', 'zto' => '中通快递', 'best' => '百世快递', 'yunda' => '韵达快递', 'ttkd'=> '天天快递', 'ems' => 'EMS邮政特快专递'],
'export_status' => ['准备中', '写入中', '保存中', '已完成', '导出失败', '文件丢失'],
'shares' => ['未知', '纵向共享', '横向共享'],
];
public function __construct()

View File

@ -0,0 +1,91 @@
<?php
namespace App\Domains\Virtual\Http\Controllers;
use App\Core\Controller;
use Illuminate\Http\Request;
use App\Domains\Virtual\Services\FlowPoolService;
use App\Domains\Real\Repositories\FlowPoolRepository as RealFlowPoolRepository;
class FlowPoolController extends Controller
{
protected $request;
protected $flowPoolService;
/**
* 构造函数,自动注入.
*/
public function __construct(Request $request, FlowPoolService $flowPoolService)
{
$this->request = $request;
$this->flowPoolService = $flowPoolService;
}
/**
* RD流量池列表
*
* @return void
*/
public function real()
{
$list = app(RealFlowPoolRepository::class)->get();
return res($list, 'RD流量池列表', 201);
}
/**
* 列表.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$conditions = $this->request->all();
$flowPools = $this->flowPoolService->index($conditions);
return res($flowPools, '流量池列表', 201);
}
/**
* 创建.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$attributes = $this->request->all();
$flowPool = $this->flowPoolService->store($attributes);
return res($flowPool, '创建成功');
}
/**
* 编辑.
*
* @return \Illuminate\Http\Response
*/
public function update($id)
{
$attributes = $this->request->all();
$attributes['id'] = $id;
$flowPool = $this->flowPoolService->store($attributes);
return res($flowPool, '修改成功');
}
/**
* 删除.
*
* @return \Illuminate\Http\Response
*/
public function destroy()
{
$ids = $this->request->ids();
$this->flowPoolService->destroy($ids);
return res(true, '删除成功');
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Domains\Virtual\Repositories;
use App\Core\Repository;
use App\Models\Virtual\FlowPoolCard as Model;
class FlowPoolCardRepository extends Repository
{
/**
* 是否关闭缓存
*
* @var boolean
*/
protected $cacheSkip = false;
/**
* 是否开启数据转化
*
* @var bool
*/
protected $needTransform = false;
/**
* @var array
*/
protected $fieldSearchable = [
'id' => '=',
'created_at' => 'like',
];
public function model() {
return Model::class;
}
/**
* 数据格式化
*
* @param mixed $result
*
* @return mixed
*/
public function transform($model)
{
return $model->toArray();
}
/**
* 查询条件
*
* @return void
*/
public function withConditions(array $conditions = [])
{
if (isset($conditions['id'])) {
$conditions['id'] = array_wrap($conditions['id']);
$this->model = $this->model->whereIn('id', $conditions['id']);
}
return $this;
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Domains\Virtual\Repositories;
use App\Core\Repository;
use App\Models\Virtual\FlowPoolMonth as Model;
class FlowPoolMonthRepository extends Repository
{
/**
* 是否关闭缓存
*
* @var boolean
*/
protected $cacheSkip = false;
/**
* 是否开启数据转化
*
* @var bool
*/
protected $needTransform = false;
/**
* @var array
*/
protected $fieldSearchable = [
'id' => '=',
'created_at' => 'like',
];
public function model() {
return Model::class;
}
/**
* 数据格式化
*
* @param mixed $result
*
* @return mixed
*/
public function transform($model)
{
return $model->toArray();
}
/**
* 查询条件
*
* @return void
*/
public function withConditions(array $conditions = [])
{
if (isset($conditions['id'])) {
$conditions['id'] = array_wrap($conditions['id']);
$this->model = $this->model->whereIn('id', $conditions['id']);
}
return $this;
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Domains\Virtual\Repositories;
use App\Core\Repository;
use App\Models\Virtual\FlowPool as Model;
class FlowPoolRepository extends Repository
{
/**
* 是否关闭缓存
*
* @var boolean
*/
protected $cacheSkip = false;
/**
* 是否开启数据转化
*
* @var bool
*/
protected $needTransform = false;
/**
* @var array
*/
protected $fieldSearchable = [
'id' => '=',
'created_at' => 'like',
];
public function model() {
return Model::class;
}
/**
* 数据格式化
*
* @param mixed $result
*
* @return mixed
*/
public function transform($model)
{
return $model->toArray();
}
/**
* 查询条件
*
* @return void
*/
public function withConditions(array $conditions = [])
{
if (isset($conditions['id'])) {
$conditions['id'] = array_wrap($conditions['id']);
$this->model = $this->model->whereIn('id', $conditions['id']);
}
return $this;
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Domains\Virtual\Repositories;
use App\Core\Repository;
use App\Models\Virtual\FlowPoolSetting as Model;
class FlowPoolSettingRepository extends Repository
{
/**
* 是否关闭缓存
*
* @var boolean
*/
protected $cacheSkip = false;
/**
* 是否开启数据转化
*
* @var bool
*/
protected $needTransform = false;
/**
* @var array
*/
protected $fieldSearchable = [
'id' => '=',
'created_at' => 'like',
];
public function model() {
return Model::class;
}
/**
* 数据格式化
*
* @param mixed $result
*
* @return mixed
*/
public function transform($model)
{
return $model->toArray();
}
/**
* 查询条件
*
* @return void
*/
public function withConditions(array $conditions = [])
{
if (isset($conditions['id'])) {
$conditions['id'] = array_wrap($conditions['id']);
$this->model = $this->model->whereIn('id', $conditions['id']);
}
return $this;
}
}

View File

@ -52,4 +52,11 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
// 客户管理
$router->get('/cards/index', ['as' => 'cards.index', 'uses' => 'CardController@index']);
$router->get('/cards/export', ['as' => 'cards.export', 'uses' => 'CardController@export']);
// 流量池管理
$router->get('/flow-pools/real', ['as' => 'flow-pools.real', 'uses' => 'FlowPoolController@real']);
$router->get('/flow-pools/index', ['as' => 'flow-pools.index', 'uses' => 'FlowPoolController@index']);
$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']);
});

View File

@ -0,0 +1,117 @@
<?php
namespace App\Domains\Virtual\Services;
use App\Dicts;
use App\Core\Service;
use Illuminate\Validation\Rule;
use App\Models\Virtual\FlowPool;
use Illuminate\Support\Facades\Validator;
use App\Domains\Virtual\Repositories\FlowPoolRepository;
class FlowPoolService extends Service
{
protected $flowPoolRepository;
protected $realFlowPoolRepository;
/**
* 构造函数
*
* @return void
*/
public function __construct(FlowPoolRepository $flowPoolRepository)
{
$this->flowPoolRepository = $flowPoolRepository;
$this->realFlowPoolRepository = $realFlowPoolRepository;
}
/**
* 流量池列表
*
* @param array $conditions
* @return mixed
*/
public function index(array $conditions = [])
{
$limit = $conditions['limit'] ?? 20;
$flowPools = $this->flowPoolRepository->withConditions($conditions)
->applyConditions()->paginate($limit);
$carrierOperators = app(Dicts::class)->get('carrier_operator');
$shares = app(Dicts::class)->get('shares');
$flowPools->map(function ($item) use ($carrierOperators, $shares) {
$item->company_name = app(CompanyService::class)->load($item->company_id)['name'];
$item->carrier_operator_name = $carrierOperators[$item->carrier_operator];
$item->shared_name = $shares[$item->shared];
});
return $flowPools;
}
/**
* 存储流量池
*
* @param array $attributes
* @return FlowPool
*/
public function store(array $attributes = [])
{
$rule = [
'name' => ['required', 'between:2,32', Rule::unique($this->flowPoolRepository->getTable(), 'name')->ignore($attributes['id'])->whereNUll('deleted_at')],
'carrier_operator' => ['required', 'in:0,1,2,3'],
'shared' => ['required', 'in:1,2'],
];
$message = [
'name.required' => '请输入流量池名称',
'name.between' => '流量池名称长度不合法',
'name.unique' => '流量池名称已经被其他用户所使用',
'carrier_operator.required' => '请选择运营商',
'carrier_operator.in' => '运营商不合法',
'shared.required' => '请选择共享类型',
'shared.in' => '共享类型不合法',
];
Validator::validate($attributes, $rule, $message);
if (!$attributes['id']) {
$maxId = FlowPool::withTrashed()->max('id');
$attributes['id'] = $maxId ? $maxId + 1 : 1;
$attributes['sn'] = self::sn($attributes['id']);
$node = $this->flowPoolRepository->create($attributes);
}
if ($attributes['id']) {
$node = $this->flowPoolRepository->find($attributes['id']);
if (!$node) {
throw new NotExistException('流量池不存在或已删除');
}
$this->flowPoolRepository->setModel($node)->update($attributes);
}
return $node;
}
/**
* 删除
*
* @return bool
*/
public function destroy($ids)
{
$ids = is_array($ids) ? $ids : [$ids];
$this->flowPoolRepository->destroy($ids);
return true;
}
public static function sn($id)
{
return sprintf('FP%011d', $id);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Domains\Virtual\Tests\Services;
use App\Core\TestCase;
use App\Domains\Virtual\Services\FlowPoolService;
class FlowPoolServiceTest extends TestCase
{
public function testFlowPoolServiceTest()
{
$this->assertTrue(true);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Models\Virtual;
use App\Core\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class FlowPool extends Model
{
use SoftDeletes;
protected $table = 'virtual_flow_pools';
protected $casts = [
'package_ids' => 'array',
'real_pool_ids' => 'array',
];
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Models\Virtual;
use App\Core\Model;
class FlowPoolCard extends Model
{
protected $table = 'virtual_flow_pool_cards';
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Models\Virtual;
use App\Core\Model;
class FlowPoolMonth extends Model
{
protected $table = 'virtual_flow_pool_months';
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Models\Virtual;
use App\Core\Model;
class FlowPoolSetting extends Model
{
protected $table = 'virtual_flow_pool_settings';
}

View File

@ -41,9 +41,9 @@ class CreateFlowPoolTables extends Migration
$table->integer('flows')->default(255)->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->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
$table->text('package_ids')->nullable()->comment('包含套餐');
$table->text('real_pool_ids')->nullable()->comment('RD流量池ID');
$table->text('remark')->nullable()->comment('流量池备注');
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
$table->timestamps();
$table->softDeletes();
@ -53,6 +53,20 @@ class CreateFlowPoolTables extends Migration
});
}
if (!Schema::hasTable('virtual_flow_pool_packages')) {
Schema::create('virtual_flow_pools', function (Blueprint $table) {
$table->increments('id')->comment('自增ID');
$table->integer('pool_id')->comment('流量池ID');
$table->integer('package_id')->comment('套餐ID');
$table->timestamps();
$table->softDeletes();
$table->unique(['pool_id', 'package_id', 'deleted_at']);
$table->comment('VD流量池');
});
}
if (!Schema::hasTable('virtual_flow_pool_settings')) {
Schema::create('virtual_flow_pool_settings', function (Blueprint $table) {
$table->increments('id')->comment('自增ID');

View File

@ -172,6 +172,25 @@ class PermissionSeeder extends Seeder
],
],
],
[
'name' => 'virtual_flow_pool_ctrl',
'title' => '流量池',
'path' => '#',
'icon' => 'md-wifi',
'type' => 0,
'open' => 3,
'children' => [
[
'name' => 'virtual.flow-pools.index', 'title' => '流量池管理', 'path' => '/flow-pools', 'icon' => 'md-swap', 'type' => 0, 'open' => 3,
'children' => [
['name' => 'virtual.flow-pools.show', 'title' => '查看', 'description' => 'show', 'type' => 1],
['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' => 'stats_ctrl',
'title' => '数据统计',

View File

@ -0,0 +1,60 @@
/**
* 流量池管理
*/
/**
* [real RD流量池列表]
* @param {[type]} data [description]
* @return {[type]} [description]
*/
export function real() {
return service.get('api/virtual/flow-pools/real');
}
/**
* [index 流量池列表]
* @param {[type]} data [description]
* @return {[type]} [description]
*/
export function index(data) {
return service.get('api/virtual/flow-pools/index', {
params: data
});
}
/**
* [show 流量池详情]
* @param {[type]} id [description]
* @return {[type]} [description]
*/
export function show(id) {
return service.get(`api/virtual/flow-pools/show/${id}`);
}
/**
* [create 创建流量池]
* @param {[type]} data [description]
* @return {[type]} [description]
*/
export function create(data) {
return serviceForm.post('api/virtual/flow-pools/create', data);
}
/**
* [update 修改流量池]
* @param {[type]} data [description]
* @param {[type]} id [角色id]
* @return {[type]} [description]
*/
export function update(data, id) {
return serviceForm.post(`api/virtual/flow-pools/update/${id}`, data);
}
/**
* [destroy 删除流量池]
* @param {[type]} data [description]
* @return {[type]} [description]
*/
export function destroy(data) {
return service.post('api/virtual/flow-pools/destroy', data);
}

View File

@ -15,67 +15,77 @@ export default {
};
},
methods: {
handleComplete(array, value = '', key = 'name', indexKey = 'id') {
console.log(1);
console.log(value);
if (value === '') {
return array;
}
const pinyinEngine = new PinyinEngine(array, [key]);
let res = [];
res = pinyinEngine.query(value);
res = array.filter(item => {
return (item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) || (res.find(element => {
return element[indexKey] === item[indexKey];
}));
});
return res;
},
initCompleteCompanies() {
return new Promise((resolve, reject) => {
this.completeCompanyInitialized = true;
FETCH.companies(null, 0).then(res => {
if (res.code === 0) {
this.completeCompanies = res.data;
this.completeCompaniesPinyinEngine = new PinyinEngine(res.data, ['name']);
resolve(res.data);
}
if (!this.completeCompanyInitialized) {
this.completeCompanyInitialized = true;
FETCH.companies(null, 0).then(res => {
if (res.code === 0) {
this.completeCompanies = res.data;
resolve(res.data);
}
reject(res);
});
reject(res);
});
} else {
resolve(this.completeCompanies);
}
});
},
handleCompleteCompanies(value) {
if (!this.completeCompanyInitialized) {
this.initCompleteCompanies();
}
let companies = [];
if (this.completeCompaniesPinyinEngine) {
companies = this.completeCompaniesPinyinEngine.query(value);
}
companies = this.completeCompanies.filter(function(item) {
return (item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) || (companies.find(element => { return element.id === item.id; }));
});
this.completeHandledCompanies = companies;
},
initCompletePackages() {
return new Promise((resolve, reject) => {
this.completePackageInitialized = true;
FETCH.packages(null, 0).then(res => {
if (res.code === 0) {
this.completePackages = res.data;
this.completePackagesPinyinEngine = new PinyinEngine(res.data, ['name']);
resolve(res.data);
}
reject(res);
this.initCompleteCompanies().then(() => {
this.completeHandledCompanies = this.handleComplete(this.completeCompanies, value);
resolve(this.completeHandledCompanies);
});
});
},
handleCompletePackages(value) {
if (!this.completePackageInitialized) {
this.initCompletePackages();
}
initCompletePackages() {
return new Promise((resolve, reject) => {
if (!this.completePackageInitialized) {
this.completePackageInitialized = true;
FETCH.packages(null, 0).then(res => {
if (res.code === 0) {
this.completePackages = res.data;
resolve(res.data);
}
let packages = [];
if (this.completePackagesPinyinEngine) {
packages = this.completePackagesPinyinEngine.query(value);
}
packages = this.completePackages.filter(function(item) {
return (item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) || (packages.find(element => { return element.id === item.id; }));
reject(res);
});
} else {
resolve(this.completePackages);
}
});
},
handleCompletePackages(value) {
return new Promise((resolve, reject) => {
this.initCompletePackages().then(() => {
this.completeHandledPackages = this.handleComplete(this.completePackages, value);
resolve(this.completeHandledPackages);
});
});
this.completeHandledPackages = packages;
}
}
};

View File

@ -27,7 +27,8 @@ const routes = [
{ path: '/stats/company-count', name: 'StatsCompanyCount', component: load('stats/company-count/index'), meta: { title: '企业统计' } },
{ path: '/stats/order/:type', name: 'StatsOrder', component: load('stats/order/index'), meta: { title: '订单统计' } },
{ path: '/stats/company-report/:type', name: 'StatsCompanyReport', component: load('stats/company-report/index'), meta: { title: '月报表' } },
{ path: '/artisan/real-sync', name: 'RealSync', component: load('artisan/real-sync/index'), meta: { title: 'RD数据同步' } }
{ path: '/artisan/real-sync', name: 'RealSync', component: load('artisan/real-sync/index'), meta: { title: 'RD数据同步' } },
{ path: '/flow-pools', name: 'FlowPools', component: load('virtual/flow_pools/index'), meta: { title: '流量池管理' } }
]
},
{ path: '*', redirect: { path: '/home' } }

View File

@ -0,0 +1,92 @@
<template>
<Modal :footer-hide="true" :mask-closable="false" @on-visible-change="visibleChange" title="企业详情" v-model="my_show" width="900">
<div class="page-detail-wrap" v-if="data">
<Row>
<Col span="12">
<Divider>基础信息</Divider>
<ul>
<li class="ui-list">
<div class="ui-list-title">企业编号:</div>
<div class="ui-list-content">{{data.id}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">企业名称:</div>
<div class="ui-list-content">{{data.name}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">联系人:</div>
<div class="ui-list-content">{{data.contacts}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">手机号:</div>
<div class="ui-list-content">{{data.mobile}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">企业地址:</div>
<div class="ui-list-content">{{data.address}}</div>
</li>
</ul>
</Col>
<Col offset="1" span="11">
<Divider>账号信息</Divider>
<ul>
<li class="ui-list">
<div class="ui-list-title">银行账号:</div>
<div class="ui-list-content">{{data.extends.bank_account}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">微信账号:</div>
<div class="ui-list-content">{{data.extends.wechat_account}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">支付宝账号:</div>
<div class="ui-list-content">{{data.extends.alipay_account}}</div>
</li>
</ul>
<Divider>其他信息</Divider>
<ul>
<li class="ui-list">
<div class="ui-list-title">备注:</div>
<div class="ui-list-content">{{data.remark}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">创建时间:</div>
<div class="ui-list-content">{{data.created_at}}</div>
</li>
<li class="ui-list">
<div class="ui-list-title">更新时间:</div>
<div class="ui-list-content">{{data.updated_at}}</div>
</li>
</ul>
</Col>
</Row>
<Divider>物流信息</Divider>
<Row>
<div v-for="item in data.addresses">
<Col class="umar-b10" offset="1" span="11">
<Card>
<p slot="title">
{{item.contacts}}
<Tag class="f-r" color="error" v-if="item.default">默认</Tag>
</p>
<p>地址: {{item.area + '' +item.address}}</p>
<p>电话: {{item.mobile}}</p>
</Card>
</Col>
</div>
</Row>
</div>
</Modal>
</template>
<script src="./js/detail.js"></script>

View File

@ -0,0 +1,131 @@
<template>
<Drawer
:closable="false"
:mask-closable="false"
:title="data ? '编辑流量池' : '添加流量池'"
@on-visible-change="visibleChange"
v-model="my_show"
width="750"
>
<div class="page-edit-wrap uinn-lr5">
<ui-loading :show="page_loading.show"></ui-loading>
<ul>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>流量池名称:
</div>
<div class="ui-list-content">
<p>
<Input
:disabled="data?true:false"
v-model.trim="params.name"
:style="'width:' + listStyle.width"
></Input>
</p>
<ul class="common-tips-wraper umar-t5">
<li class="t-title">提示</li>
<li class="t-content">长度在2-32之间</li>
</ul>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>运营商:
</div>
<div class="ui-list-content">
<Select
:disabled="data ? true : false"
v-model="params.carrier_operator"
:style="'width:' + listStyle.width"
>
<Option :value="0">联通</Option>
<Option :value="1">移动</Option>
<Option :value="2">电信</Option>
</Select>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>共享类型:
</div>
<div class="ui-list-content">
<Select
:disabled="data ? true : false"
v-model="params.shared"
:style="'width:' + listStyle.width"
>
<Option :value="1">纵向共享</Option>
<Option :value="2">横向共享</Option>
</Select>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>企业名称:
</div>
<div class="ui-list-content">
<Select
filterable
icon="ios-search"
placeholder="企业名称"
v-model.trim="params.company_id"
:style="'width:' + listStyle.width"
>
<Option :value="item.id" :key="item.id" v-for="item in companies">{{ item.name }}</Option>
</Select>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>套餐:
</div>
<div class="ui-list-content">
<Transfer
:titles="['备选套餐', '已选套餐']"
:list-style="listStyle"
:data="packages"
:target-keys="package_ids"
@on-change="transferPackages"
></Transfer>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">
<span class="title-require">*</span>流量池编号:
</div>
<div class="ui-list-content">
<Transfer
:titles="['备选流量池编号', '已选流量池编号']"
:list-style="listStyle"
:data="reals"
:target-keys="real_pool_ids"
@on-change="transferRealFlowPools"
></Transfer>
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">状态</div>
<div class="ui-list-content lh-32">
<Switch size="large" :true-value="0" :false-value="1" v-model="params.status">
<span slot="open">启用</span>
<span slot="close">禁用</span>
</Switch>
</div>
</li>
</ul>
</div>
<div class="ta-c">
<Button @click="clear" class="w-80 umar-r5" ghost type="primary">取消</Button>
<Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button>
</div>
</Drawer>
</template>
<script src="./js/edit.js"></script>

View File

@ -0,0 +1,109 @@
<template>
<div class="page-wrap">
<ui-loading :show="page_loading.show"></ui-loading>
<div class="page-handle-wrap">
<ul class="handle-wraper bd-b">
<li class="f-l">
<div class="text-exp">
<b>全部信息</b>
</div>
</li>
<li class="f-r">
<div class="handle-item">
<Button
@click="openEdit(true, null)"
icon="md-add"
type="primary"
v-has="'create'"
>添加流量池</Button>
</div>
<div class="handle-item">
<Button @click="search.show=!search.show" ghost icon="ios-search" type="primary">搜索</Button>
</div>
<div class="handle-item">
<Button @click="index(1)" icon="md-refresh">刷新</Button>
</div>
</li>
</ul>
<div class="search-wrap" v-show="search.show">
<ul class="handle-wraper">
<li class="handle-item w-250">
<AutoComplete
@on-search="handleCompleteCompanies"
icon="ios-search"
placeholder="请输入企业名称"
v-model.trim="params.name"
>
<Option
:key="item.id"
:value="item.name"
v-for="item in completeHandledCompanies"
>{{ item.name }}</Option>
</AutoComplete>
</li>
<li class="handle-item w-250">
<Input clearable placeholder="流量池名称" v-model.trim="params.name"></Input>
</li>
<li class="handle-item w-250">
<Select clearable placeholder="运营商" v-model="params.carrier_operator">
<Option :value="0">联通</Option>
<Option :value="1">移动</Option>
<Option :value="2">电信</Option>
</Select>
</li>
<li class="handle-item w-250">
<DatePicker
:editable="false"
placeholder="请选择时间"
placement="bottom-start"
type="month"
v-model.trim="params.month"
></DatePicker>
</li>
<li class="f-r">
<div class="handle-item">
<Button @click="index(1)" ghost type="primary">立即搜索</Button>
</div>
<div class="handle-item">
<Button @click="resetSearch" ghost type="warning">重置搜索</Button>
</div>
</li>
</ul>
</div>
</div>
<div class="page-list-wrap">
<Table :columns="table_titles" :data="list_data ? list_data.data : []"></Table>
</div>
<div class="page-turn-wrap" v-if="list_data">
<Page
:current="Number(list_data.current_page)"
:page-size="Number(list_data.per_page)"
:total="Number(list_data.total)"
@on-change="index"
show-elevator
show-total
></Page>
</div>
<ui-edit
:data="editObj.data"
:show.sync="editObj.show"
@add-success="index"
@update-success="index(list_data.current_page)"
></ui-edit>
<ui-detail :data="detailObj.data" :show.sync="detailObj.show"></ui-detail>
</div>
</template>
<script src="./js/index.js"></script>

View File

@ -0,0 +1,29 @@
export default{
props: {
show: {
type: Boolean,
default: false
},
data: {
type: Object,
default() {
return null;
}
}
},
watch: {
show(bool) {
this.my_show = bool;
}
},
data() {
return {
my_show: false
};
},
methods: {
visibleChange(bool) {
this.$emit('update:show', bool);
}
}
};

View File

@ -0,0 +1,160 @@
import * as API from 'api/virtual/flow_pools';
export default {
props: {
show: {
type: Boolean,
default: false
},
data: {
type: Object,
default() {
return null;
}
}
},
data() {
return {
listStyle: {
width: '230px',
height: '300px'
},
companies: [],
packages: [],
package_ids: [],
reals: [],
real_pool_ids: [],
my_show: false,
isUpdate: false,
loading: false,
params: {
name: '',
carrier_operator: '',
shared: '',
company_id: '',
package_ids: '',
real_pool_ids: '',
status: 0,
remark: ''
}
};
},
watch: {
show(bool) {
this.my_show = bool;
if (bool) {
if (!this.reals.length) {
API.real().then(res => {
if (res.code == 0) {
this.reals = res.data.map(item => {
return {
'key': item.id,
'label': item.sn + ' - ' + item.name,
'disabled': false
};
});
}
});
}
this.initCompleteCompanies().then(companies => {
this.companies = companies.filter(item => {
return item.status === 0;
});
});
this.initCompletePackages().then(packages => {
this.packages = packages.filter(item => {
return item.status === 0;
}).map(item => {
return {
'key': item.id,
'label': item.name,
'disabled': false
};
});
});
if (this.data) {
for (let k in this.data) {
if (k in this.params) {
this.params[k] = this.data[k];
}
}
this.package_ids = this.data.package_ids;
this.real_pool_ids = this.data.real_pool_ids;
}
}
}
},
methods: {
ok() {
if (this.params.company_id === '') {
this.$Message.info('请选择企业');
return;
}
if (this.params.carrier_operator === '') {
this.$Message.info('请选择运营商');
return;
}
if (this.params.shared === '') {
this.$Message.info('请选择共享类型');
return;
}
if (this.data) {
// 编辑
API.update(this.params, this.data.id).then(res => {
this.loading = false;
if (res.code == 0) {
this.$emit('update-success');
this.$Message.success('更新成功');
this.clear();
}
}).catch(err => {
this.loading = false;
});
} else {
// 添加
API.create(this.params).then(res => {
this.loading = false;
if (res.code == 0) {
this.$emit('add-success');
this.$Message.success('添加成功');
this.clear();
}
}).catch(err => {
this.loading = false;
});
}
},
visibleChange(bool) {
if (!bool) {
this.$emit('update:show', false);
}
},
clear() {
for (let k in this.params) {
if (k == 'status') {
this.params[k] = 0;
} else {
this.params[k] = '';
}
}
this.my_show = false;
},
transferPackages(ids) {
this.package_ids = ids;
this.params.package_ids = ids;
},
transferRealFlowPools(ids) {
this.real_pool_ids = ids;
this.params.real_pool_ids = ids;
}
}
};

View File

@ -0,0 +1,252 @@
import * as API from 'api/virtual/flow_pools';
export default {
name: 'FlowPools',
components: {
UiEdit: resolve => require(['views/virtual/flow_pools/edit'], resolve),
UiDetail: resolve => require(['views/virtual/flow_pools/detail'], resolve)
},
data() {
return {
params: {
name: ''
},
trashed: null,
list_data: null,
reals: [],
editObj: {
show: false,
data: null
},
detailObj: {
show: false,
data: null
},
search: {
show: false
},
table_titles: [
{
title: 'ID',
key: 'id',
width: 80
},
{
title: '运营商',
key: 'carrier_operator_name',
width: 110
},
{
title: '编号',
key: 'sn',
width: 150
},
{
title: '名称',
key: 'name',
width: 110
},
{
title: '共享类型',
key: 'shared_name',
width: 110
},
{
title: '客户名称',
key: 'company_name',
width: 300
},
{
title: '保底流量',
key: '',
width: 110
},
{
title: '超出流量',
key: '',
width: 110
},
{
title: '保底收入',
key: '',
width: 110
},
{
title: '超出收入',
key: '',
width: 110
},
{
title: '收费用户数',
key: '',
width: 110
},
{
title: '总收入',
key: '',
width: 110
},
{
title: '状态',
key: '',
width: 100,
render: (h, { row, column, index }) => {
return h('Button', {
props: {
type: row.status ? 'error' : 'primary',
size: 'small'
}
}, row.status ? '已禁用' : '启用中');
}
},
{
title: '更新时间',
key: 'created_at',
width: 170
},
{
title: '操作',
key: 'action',
width: 110,
render: (h, {
row,
column,
index
}) => {
let html = [];
if (row.deleted_at) {
return h('Tag', { props: { color: 'default' } }, '该企业已被删除');
}
if (this.haveJurisdiction('show')) {
html.push(h('Button', {
props: {
type: 'success',
size: 'small',
disabled: false,
icon: 'md-eye'
},
class: ['btn'],
on: {
click: (event) => {
this.detailObj = {
show: true,
data: row
};
}
}
}, '查看'));
}
if (this.haveJurisdiction('update')) {
html.push(h('Button', {
props: {
type: 'primary',
size: 'small',
disabled: false,
icon: 'ios-create'
},
class: ['btn'],
on: {
click: (event) => {
this.openEdit(true, row);
}
}
}, '编辑'));
}
if (this.haveJurisdiction('destroy')) {
html.push(h('Button', {
props: {
type: 'error',
size: 'small',
disabled: false,
icon: 'md-trash'
},
class: ['btn'],
on: {
click: () => {
this.$Modal.confirm({
title: '提示',
content: '删除后该企业不可使用,请谨慎操作',
onOk: () => {
API.destroy({
ids: row.id
}).then(res => {
if (res.code == 0) {
this.$Message.success('删除成功');
this.request();
}
});
}
});
}
}
}, '删除'));
}
if (html.length) {
return h('div', html);
}
}
}
]
};
},
created() {
this.index(1);
},
methods: {
/**
* [index 列表]
* @param {Number} page [description]
* @return {[type]} [description]
*/
index(page = 1) {
let data = this.searchDataHandle(this.params, { page }, { 'trashed': this.trashed, 'orderBy': 'id', 'sortedBy': 'asc' });
this.isShowLoading(true);
API.index(data).then(res => {
this.isShowLoading(false);
if (res.code == 0) {
this.list_data = res.data;
}
}).catch(() => {
this.isShowLoading(false);
});
},
/**
* [openEdit 打开编辑弹窗]
* @return {[type]} [description]
*/
openEdit(bool, data = null) {
this.editObj = {
show: bool,
data
};
},
/**
* [request 刷新]
* @return {[type]} [description]
*/
request() {
const result = this.list_data;
let page = result.current_page;
if (this.list_data.data.length == 1) {
page = this.returnPage(result.total, result.current_page, result.per_page);
}
this.index(page);
},
resetSearch() {
for (let k in this.params) {
this.params[k] = '';
}
this.trashed = null;
this.index(1);
}
}
};

View File

@ -46,13 +46,11 @@ export default {
}
}
if (!this.completePackageInitialized) {
this.initCompletePackages().then(packages => {
this.completePackagesFilter = packages.filter(function(item) {
return item.status === 0;
});
this.initCompletePackages().then(packages => {
this.completePackagesFilter = packages.filter(function(item) {
return item.status === 0;
});
}
});
}
},
methods: {

View File

@ -156,8 +156,6 @@ export default {
this.companies = res.filter(function(item) {
return item.status === 0;
});
}).catch(err => {
this.$Message.error(err.message);
});
},
methods: {
@ -222,24 +220,11 @@ export default {
this.index();
},
handleSearchCompanies(value) {
if (value === '') {
this.companies = this.completeCompanies.filter(function(item) {
this.handleCompleteCompanies(value).then(res => {
this.companies = res.filter(item => {
return item.status === 0;
});
return;
}
let companies = [];
if (this.completeCompaniesPinyinEngine) {
companies = this.completeCompaniesPinyinEngine.query(value);
}
companies = this.completeCompanies.filter(function(item) {
return (item.status === 0) && ((item.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) || (companies.find(element => { return element.id === item.id; })));
});
this.companies = companies;
},
handleSearchPackages(value) {
this.params.package_id = value;