套餐管理

This commit is contained in:
邓皓元 2018-12-20 16:22:10 +08:00
parent 4ef06721e1
commit 870d8c473b
16 changed files with 200 additions and 122 deletions

View File

@ -28,7 +28,7 @@ class PackageController extends Controller
*/ */
public function index() public function index()
{ {
$conditions = []; $conditions = $this->request->all();
$conditions['limit'] = $this->request->get('limit', 20); $conditions['limit'] = $this->request->get('limit', 20);
$packages = $this->packageService->index($conditions); $packages = $this->packageService->index($conditions);

View File

@ -25,9 +25,11 @@ class PackageRepository extends Repository
* @var array * @var array
*/ */
protected $fieldSearchable = [ protected $fieldSearchable = [
'id' => '=', 'id' => '=',
'name' => 'like', 'type' => '=',
'created_at' => 'like', 'sn' => 'like',
'name' => 'like',
'carrier_operator' => '=',
]; ];
public function model() public function model()
@ -59,6 +61,22 @@ class PackageRepository extends Repository
$this->model = $this->model->whereIn('id', $conditions['id']); $this->model = $this->model->whereIn('id', $conditions['id']);
} }
if (isset($conditions['type'])) {
$this->model = $this->model->where('type', $conditions['type']);
}
if (isset($conditions['sn'])) {
$this->model = $this->model->where('sn', "%{$conditions['sn']}%");
}
if (isset($conditions['name'])) {
$this->model = $this->model->where('name', "%{$conditions['name']}%");
}
if (isset($conditions['carrier_operator'])) {
$this->model = $this->model->where('carrier_operator', $conditions['carrier_operator']);
}
return $this; return $this;
} }
} }

View File

@ -11,6 +11,29 @@ class Package extends PackageBase
public $incrementing = false; public $incrementing = false;
protected $fillable = [
'id',
'parent_id',
'sn',
'name',
'type',
'carrier_operator',
'cost_price',
'guide_price',
'renewal_cost_price',
'renewal_guide_price',
'flows',
'voices',
'messages',
'has_messages',
'has_lbs',
'reset_months',
'service_months',
'effect_months',
'delay_months',
'description',
];
public function cards() public function cards()
{ {
return $this->hasMany(Card::class, 'virtual_package_id', 'id'); return $this->hasMany(Card::class, 'virtual_package_id', 'id');

View File

@ -30,6 +30,7 @@
"@vue/cli-service": "^3.0.1", "@vue/cli-service": "^3.0.1",
"@vue/eslint-config-standard": "^3.0.0-beta.10", "@vue/eslint-config-standard": "^3.0.0-beta.10",
"chai": "^4.1.2", "chai": "^4.1.2",
"iview-loader": "^1.2.2",
"less": "^2.7.3", "less": "^2.7.3",
"less-loader": "^4.0.5", "less-loader": "^4.0.5",
"lint-staged": "^6.0.0", "lint-staged": "^6.0.0",

View File

@ -58,14 +58,7 @@
</div> </div>
<div class="page-turn-wrap" v-if="list_data"> <div class="page-turn-wrap" v-if="list_data">
<Page <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>
: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> </div>
<ui-edit :data="editObj.data" :show.sync="editObj.show" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit> <ui-edit :data="editObj.data" :show.sync="editObj.show" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit>

View File

@ -10,7 +10,7 @@ export default {
params: { params: {
name: '' name: ''
}, },
trashed: '', trashed: null,
list_data: null, list_data: null,
editObj: { editObj: {
show: false, show: false,
@ -192,7 +192,7 @@ export default {
for (let k in this.params) { for (let k in this.params) {
this.params[k] = ''; this.params[k] = '';
} }
this.trashed = ''; this.trashed = null;
this.index(1); this.index(1);
} }
} }

View File

@ -51,23 +51,10 @@
</div> </div>
<div class="page-turn-wrap" v-if="list_data"> <div class="page-turn-wrap" v-if="list_data">
<Page <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>
: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> </div>
<ui-edit <ui-edit :data="editObj.data" :isUpdate.sync="editObj.isUpdate" :show.sync="editObj.show" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit>
:data="editObj.data"
:isUpdate.sync="editObj.isUpdate"
:show.sync="editObj.show"
@add-success="index"
@update-success="index(list_data.current_page)"
></ui-edit>
</div> </div>
</template> </template>

View File

@ -14,7 +14,6 @@ export default {
username: '' username: ''
} }
}, },
trashed: '',
list_data: null, list_data: null,
editObj: { editObj: {
show: false, show: false,
@ -221,7 +220,6 @@ export default {
for (let k in this.params) { for (let k in this.params) {
this.params[k] = ''; this.params[k] = '';
} }
this.trashed = '';
this.index(1); this.index(1);
} }
} }

View File

@ -67,9 +67,9 @@
<li class="handle-item w-250"> <li class="handle-item w-250">
<Select clearable placeholder="运营商" v-model="params.carrier_operator"> <Select clearable placeholder="运营商" v-model="params.carrier_operator">
<Option :value="'0'">联通</Option> <Option :value="0">联通</Option>
<Option :value="'1'">移动</Option> <Option :value="1">移动</Option>
<Option :value="'2'">电信</Option> <Option :value="2">电信</Option>
</Select> </Select>
</li> </li>
@ -90,14 +90,7 @@
</div> </div>
<div class="page-turn-wrap" v-if="list_data"> <div class="page-turn-wrap" v-if="list_data">
<Page <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>
: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> </div>
<ui-edit :data="editObj.data" :show.sync="editObj.show" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit> <ui-edit :data="editObj.data" :show.sync="editObj.show" @add-success="index" @update-success="index(list_data.current_page)"></ui-edit>

View File

@ -1,18 +1,16 @@
<template> <template>
<Modal :closable="false" :mask-closable="false" :title="data ? '编辑套餐' : '添加套餐'" @on-visible-change="visibleChange" v-model="my_show"> <Drawer :closable="false" :mask-closable="false" :title="data ? '编辑套餐' : '添加套餐'" @on-visible-change="visibleChange" v-model="my_show" width="500">
<div class="page-edit-wrap uinn-lr20"> <div class="page-edit-wrap">
<ui-loading :show="page_loading.show"></ui-loading> <ui-loading :show="page_loading.show"></ui-loading>
<ul> <ul>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐编号:</div> <div class="ui-list-title">套餐编号:</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <Input :disabled="data ? true : false" v-model.trim="params.sn"></Input>
<Input :disabled="data?true:false" v-model.trim="params.sn"></Input>
</p>
<ul class="common-tips-wraper umar-t5"> <ul class="common-tips-wraper umar-t5">
<li class="t-title">提示</li> <li class="t-title">提示</li>
<li class="t-content">仅能输入[A-Z0-9-_]的字符,如未输入将根据规则自动生成</li> <li class="t-content">如未输入将根据规则自动生成</li>
</ul> </ul>
</div> </div>
</li> </li>
@ -21,9 +19,7 @@
<span class="title-require">*</span>套餐名称: <span class="title-require">*</span>套餐名称:
</div> </div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <Input v-model.trim="params.name"></Input>
<Input :disabled="data?true:false" v-model.trim="params.name"></Input>
</p>
<ul class="common-tips-wraper umar-t5"> <ul class="common-tips-wraper umar-t5">
<li class="t-title">提示</li> <li class="t-title">提示</li>
<li class="t-content">长度在2-32之间</li> <li class="t-content">长度在2-32之间</li>
@ -35,94 +31,118 @@
<span class="title-require">*</span>运营商: <span class="title-require">*</span>运营商:
</div> </div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <Select :disabled="data ? true : false" v-model="params.carrier_operator">
<Select v-model="params.carrier_operator"> <Option :value="0">联通</Option>
<Option :value="'0'">联通</Option> <Option :value="1">移动</Option>
<Option :value="'1'">移动</Option> <Option :value="2">电信</Option>
<Option :value="'2'">电信</Option> </Select>
</Select>
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐成本价:</div> <div class="ui-list-title">套餐成本价:</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :formatter="value => Number(value/100).toFixed(2)" :max="99999" :min="0" :step="0.01" v-model="params.cost_price"></InputNumber>&nbsp;
<InputNumber :max="99999" :min="0" :step="0.01" v-model="params.cost_price"></InputNumber>()
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐指导价:</div> <div class="ui-list-title">套餐指导价:</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :formatter="value => Number(value/100).toFixed(2)" :max="99999" :min="0" :step="0.01" v-model="params.guide_price"></InputNumber>&nbsp;
<InputNumber :max="99999" :min="0" :step="0.01" v-model="params.guide_price"></InputNumber>() </div>
</p> </li>
<li class="ui-list">
<div class="ui-list-title">续费成本价:</div>
<div class="ui-list-content">
<InputNumber :formatter="value => Number(value/100).toFixed(2)" :max="99999" :min="0" :step="0.01" v-model="params.renewal_cost_price"></InputNumber>&nbsp;
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">续费指导价:</div>
<div class="ui-list-content">
<InputNumber :formatter="value => Number(value/100).toFixed(2)" :max="99999" :min="0" :step="0.01" v-model="params.renewal_guide_price"></InputNumber>&nbsp;
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐流量</div> <div class="ui-list-title">套餐流量</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :disabled="data ? true : false" :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.flows"></InputNumber>&nbsp;(M)
<InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.flows"></InputNumber>(M)
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐语音</div> <div class="ui-list-title">套餐语音</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.voices"></InputNumber>&nbsp;分钟
<InputNumber :max="99999" :min="0" :step="1" v-model="params.voices"></InputNumber>(分钟)
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">套餐短信</div> <div class="ui-list-title">套餐短信</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.messages"></InputNumber>&nbsp;分钟
<InputNumber :max="99999" :min="0" :step="1" v-model="params.messages"></InputNumber>(分钟)
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">短信服务</div> <div class="ui-list-title">短信服务</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <Switch :false-value="0" :true-value="1" v-model="params.has_messages"/>
<Switch @on-change="switchChange" v-model="params.has_messages"/>
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">LBS服务</div> <div class="ui-list-title">LBS服务</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <Switch :false-value="0" :true-value="1" v-model="params.has_lbs"/>
<Switch @on-change="switchChange" v-model="params.has_lbs"/>
</p>
</div> </div>
</li> </li>
<li class="ui-list"> <li class="ui-list">
<div class="ui-list-title">备注:</div> <div class="ui-list-title">重置周期</div>
<div class="ui-list-content"> <div class="ui-list-content">
<p> <InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.reset_months"></InputNumber>&nbsp;
<Input :maxlength="32" v-model.trim="params.remark"></Input> </div>
</p> </li>
<li class="ui-list">
<div class="ui-list-title">套餐周期</div>
<div class="ui-list-content">
<InputNumber :disabled="data ? true : false" :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.service_months"></InputNumber>&nbsp;
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">生效延迟</div>
<div class="ui-list-content">
<InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.effect_months"></InputNumber>&nbsp;
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">服务延长</div>
<div class="ui-list-content">
<InputNumber :formatter="value => Number(value).toFixed(0)" :max="99999" :min="0" :step="1" v-model="params.delay_months"></InputNumber>&nbsp;
</div>
</li>
<li class="ui-list">
<div class="ui-list-title">说明:</div>
<div class="ui-list-content">
<Input :maxlength="255" v-model.trim="params.description"></Input>
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
<footer class="ta-c" slot="footer"> <div class="ta-c">
<Button @click="clear" class="w-80" ghost type="primary">取消</Button> <Button @click="clear" class="w-80 umar-r5" ghost type="primary">取消</Button>
<Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button> <Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button>
</footer> </div>
</Modal> </Drawer>
</template> </template>
<script src="./js/edit.js"></script> <script src="./js/edit.js"></script>

View File

@ -28,9 +28,9 @@
<ul class="handle-wraper"> <ul class="handle-wraper">
<li class="handle-item w-250"> <li class="handle-item w-250">
<Select clearable placeholder="运营商" v-model="params.carrier_operator"> <Select clearable placeholder="运营商" v-model="params.carrier_operator">
<Option :value="'0'">联通</Option> <Option :value="0">联通</Option>
<Option :value="'1'">移动</Option> <Option :value="1">移动</Option>
<Option :value="'2'">电信</Option> <Option :value="2">电信</Option>
</Select> </Select>
</li> </li>

View File

@ -1,4 +1,4 @@
import * as API from 'api/virtual/companies'; import * as API from 'api/virtual/packages';
export default { export default {
props: { props: {
@ -8,7 +8,7 @@ export default {
}, },
data: { data: {
type: Object, type: Object,
default () { default() {
return null; return null;
} }
} }
@ -21,14 +21,21 @@ export default {
params: { params: {
sn: '', sn: '',
name: '', name: '',
carrier_operator: '', carrier_operator: 255,
cost_price: 0, cost_price: 0,
guide_price: 0, guide_price: 0,
renewal_cost_price: 0,
renewal_guide_price: 0,
flows: 0, flows: 0,
voices: 0, voices: 0,
messages: 0, messages: 0,
has_messages: 0, has_messages: 0,
has_lbs: 0 has_lbs: 0,
reset_months: 0,
service_months: 0,
effect_months: 0,
delay_months: 0,
description: ''
} }
}; };
}, },
@ -49,15 +56,29 @@ export default {
methods: { methods: {
ok() { ok() {
if (!this.params.name) { if (!this.params.name) {
this.$Message.info('请填写企业名称'); this.$Message.info('请填写套餐名称');
return; return;
} }
if (!(/[\s\S]{2,32}/.test(this.params.contacts))) { if (this.params.sn && !/^[A-Z0-9_]{2,32}$/.test(this.params.sn)) {
this.$Message.info('联系人长度在2-32之间'); this.$Message.info('套餐编码为大写字母、数字、下划线的2-32位字符');
return; return;
} }
if (this.params.carrier_operator === 255) {
this.$Message.info('请选择运营商');
return;
}
let type = this.$route.query.type;
if (typeof (type) === 'undefined') {
this.$Message.error('非法请求');
return;
}
this.params.type = type;
if (this.data) { if (this.data) {
// 编辑 // 编辑
API.update(this.params, this.data.id).then(res => { API.update(this.params, this.data.id).then(res => {
@ -92,14 +113,19 @@ export default {
}, },
clear() { clear() {
let strKeys = ['sn', 'name', 'carrier_operator', 'description'];
for (let k in this.params) { for (let k in this.params) {
this.params[k] = ''; if (strKeys.indexOf(k) === -1) {
this.params[k] = 0;
} else {
this.params[k] = '';
}
} }
this.my_show = false; this.my_show = false;
}, },
switchChange(status) { switchChange(status) {
console.log(status); console.log(this.params);
} }
} }
}; };

View File

@ -9,7 +9,7 @@ export default {
params: { params: {
name: '' name: ''
}, },
trashed: '', trashed: null,
list_data: null, list_data: null,
editObj: { editObj: {
show: false, show: false,
@ -54,23 +54,31 @@ export default {
{ {
title: '套餐编号', title: '套餐编号',
key: 'sn', key: 'sn',
width: 300 width: 200
}, },
{ {
title: '套餐名称', title: '套餐名称',
key: 'name' key: 'name',
width: 120
}, },
{ {
title: '运营商', title: '运营商',
key: 'carrier_operator_name' key: 'carrier_operator_name',
width: 100
}, },
{ {
title: '流量值M', title: '流量值M',
key: 'flows' key: 'flows',
width: 120
}, },
{ {
title: '套餐周期(月)', title: '套餐周期(月)',
key: 'service_months' key: 'service_months',
width: 120
},
{
title: '说明',
key: 'description'
}, },
{ {
title: '创建时间', title: '创建时间',
@ -80,6 +88,7 @@ export default {
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
width: 170,
render: (h, { render: (h, {
row, row,
column, column,
@ -167,13 +176,7 @@ export default {
}; };
}, },
created() { created() {
let type = this.$route.query.type; this.index(1);
if (typeof(type) === 'undefined') {
return this.$Message.error('非法请求');
}
this.index(1, type);
}, },
methods: { methods: {
/** /**
@ -181,8 +184,15 @@ export default {
* @param {Number} page [description] * @param {Number} page [description]
* @return {[type]} [description] * @return {[type]} [description]
*/ */
index(page = 1, type = 0) { index(page = 1) {
let data = this.searchDataHandle(this.params, { page }, { 'trashed': this.trashed, 'orderBy': 'id', 'sortedBy': 'asc' }); let type = this.$route.query.type;
if (typeof(type) === 'undefined') {
this.$Message.error('非法请求');
return;
}
let data = this.searchDataHandle(this.params, { page }, { 'type': type, 'trashed': this.trashed, 'orderBy': 'id', 'sortedBy': 'asc' });
this.isShowLoading(true); this.isShowLoading(true);
API.index(data).then(res => { API.index(data).then(res => {
this.isShowLoading(false); this.isShowLoading(false);
@ -224,7 +234,7 @@ export default {
for (let k in this.params) { for (let k in this.params) {
this.params[k] = ''; this.params[k] = '';
} }
this.trashed = ''; this.trashed = null;
this.index(1); this.index(1);
} }
} }

View File

@ -39,9 +39,9 @@
<ul class="handle-wraper"> <ul class="handle-wraper">
<li class="handle-item w-250"> <li class="handle-item w-250">
<Select clearable placeholder="运营商" v-model="params.carrier_operator"> <Select clearable placeholder="运营商" v-model="params.carrier_operator">
<Option :value="'0'">联通</Option> <Option :value="0">联通</Option>
<Option :value="'1'">移动</Option> <Option :value="1">移动</Option>
<Option :value="'2'">电信</Option> <Option :value="2">电信</Option>
</Select> </Select>
</li> </li>

View File

@ -13,7 +13,6 @@ export default {
name: null, name: null,
package_name: null package_name: null
}, },
trashed: '',
editObj: { editObj: {
show: false, show: false,
isUpdate: false, isUpdate: false,

View File

@ -24,9 +24,19 @@ module.exports = {
.set('service', resolve('src/service')) .set('service', resolve('src/service'))
.set('util', resolve('src/service/util')) .set('util', resolve('src/service/util'))
.set('validate', resolve('src/service/validate')); .set('validate', resolve('src/service/validate'));
},
runtimeCompiler: true, config.module
productionSourceMap: true .rule('vue')
.use('iview-loader')
.loader('iview-loader')
.tap(options => {
options = {
prefix: true
};
return options;
});
}
// 这里写你调用接口的基础路径来解决跨域如果设置了代理那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串 // 这里写你调用接口的基础路径来解决跨域如果设置了代理那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
// devServer: { // devServer: {
// proxy: 'localhost:3000' // proxy: 'localhost:3000'