permissions
This commit is contained in:
parent
31b0a2fb44
commit
655a043712
@ -32,7 +32,7 @@ class AccountController extends Controller
|
||||
$conditions['role_id'] = $this->request->get('role_id');
|
||||
|
||||
$accounts = $this->accountService->index($conditions);
|
||||
|
||||
|
||||
return res($accounts, '账号列表', 201);
|
||||
}
|
||||
|
||||
@ -46,10 +46,6 @@ class AccountController extends Controller
|
||||
{
|
||||
$attributes = $this->request->all();
|
||||
|
||||
// if (!$this->request->user()->can('api.accounts.root')) {
|
||||
// $attributes['parent_id'] = $this->account->id;
|
||||
// }
|
||||
|
||||
$account = $this->accountService->store($attributes);
|
||||
|
||||
return res($account, '创建成功');
|
||||
|
@ -29,7 +29,7 @@ class PermissionController extends Controller
|
||||
{
|
||||
$conditions = [];
|
||||
|
||||
if (!$this->account->can('api.permissions.create')) {
|
||||
if (!$this->account->can('permissions.create')) {
|
||||
$conditions['role_ids'] = $this->account->roles->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ class RoleController extends Controller
|
||||
{
|
||||
$conditions = [];
|
||||
$conditions['limit'] = $this->request->get('limit', 20);
|
||||
|
||||
|
||||
$roles = $this->roleService->index($conditions);
|
||||
|
||||
return res($roles, '角色列表', 201);
|
||||
|
@ -45,7 +45,7 @@ class PermissionRepository extends Repository
|
||||
});
|
||||
}
|
||||
|
||||
$this->model = $this->model->orderBy('displayorder', 'desc');
|
||||
$this->model = $this->model->orderBy('displayorder', 'desc')->orderBy('id', 'asc');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -3,17 +3,20 @@ namespace App\Domains\Stats\Http\Controllers;
|
||||
|
||||
use App\Core\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Domains\Stats\Services\CompanyReportService;
|
||||
|
||||
class CompanyReportController extends Controller
|
||||
{
|
||||
protected $request;
|
||||
protected $companyReportService;
|
||||
|
||||
/**
|
||||
* 构造函数,自动注入.
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
public function __construct(Request $request, CompanyReportService $companyReportService)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->companyReportService = $companyReportService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,37 +26,26 @@ class CompanyReportController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
$conditions = $this->request->all();
|
||||
$conditions['type'] = $this->request->ids('type');
|
||||
|
||||
$res = $this->companyReportService->index($conditions);
|
||||
|
||||
return res($res, '企业月报表', 201);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建.
|
||||
* 统计明细.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
public function detail()
|
||||
{
|
||||
//
|
||||
}
|
||||
$conditions = $this->request->all();
|
||||
|
||||
/**
|
||||
* 编辑.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
$res = $this->companyReportService->detail($conditions);
|
||||
|
||||
/**
|
||||
* 删除.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
//
|
||||
return res($res, '统计明细', 201);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class OrderController extends Controller
|
||||
$conditions = $this->request->all();
|
||||
|
||||
$res = $this->orderService->index($conditions);
|
||||
|
||||
|
||||
return res($res, '订单统计', 201);
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ class OrderController extends Controller
|
||||
$conditions = $this->request->all();
|
||||
|
||||
$res = $this->orderService->detail($conditions);
|
||||
|
||||
|
||||
return res($res, '统计明细', 201);
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class OrderController extends Controller
|
||||
$export = new OrderDetailExport($conditions);
|
||||
|
||||
$queue = $total > 6000;
|
||||
|
||||
|
||||
$url = ExportService::store($export, $this->disk, $queue);
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
|
@ -12,4 +12,7 @@ $router->group(['prefix' => 'stats', 'as' => 'stats', 'middleware' => ['adminAut
|
||||
$router->get('/order/detail', ['as' => 'order.detail', 'uses' => 'OrderController@detail']);
|
||||
$router->get('/order/detail/export', ['as' => 'order.detail.export', 'uses' => 'OrderController@detailExport']);
|
||||
|
||||
// 企业月报表
|
||||
$router->get('/company-report', ['as' => 'company-report.index', 'uses' => 'CompanyReportController@index']);
|
||||
$router->get('/company-report/detail', ['as' => 'company-report.detail', 'uses' => 'CompanyReportController@detail']);
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ class CompanyCountService extends Service
|
||||
$groupBy = 'company_id';
|
||||
|
||||
$select = [$groupBy, DB::raw('count(*) as counts')];
|
||||
|
||||
|
||||
$model = OrderCard::select($select)->whereIn('company_id', $companies->pluck('id')->toArray())->groupBy($groupBy);
|
||||
|
||||
$total = $this->orderCardRepository->setModel(clone $model)->get()->pluck('counts', 'company_id')->toArray();
|
||||
|
@ -1,18 +1,106 @@
|
||||
<?php
|
||||
namespace App\Domains\Stats\Services;
|
||||
|
||||
use App\Dicts;
|
||||
use App\Core\Service;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Domains\Virtual\Services\CompanyService;
|
||||
use App\Domains\Virtual\Services\PackageService;
|
||||
use App\Domains\Virtual\Services\ProductService;
|
||||
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
|
||||
|
||||
class CompanyReportService extends Service
|
||||
{
|
||||
protected $orderCardPartitionRepository;
|
||||
|
||||
protected static $typeNames = ['首年', '非首年', '续费包', '流量包'];
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(OrderCardPartitionRepository $orderCardPartitionRepository)
|
||||
{
|
||||
//
|
||||
$this->orderCardPartitionRepository = $orderCardPartitionRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业月报表
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index(array $conditions = [])
|
||||
{
|
||||
$select = [
|
||||
'company_id',
|
||||
'package_id',
|
||||
'type',
|
||||
DB::raw("MAX(order_id) as order_id"),
|
||||
DB::raw('COUNT(id) as counts'),
|
||||
];
|
||||
|
||||
$query = $this->orderCardPartitionRepository->select($select)
|
||||
->withConditions($conditions)
|
||||
->groupBy(['company_id', 'package_id', 'type'])
|
||||
->orderBy('type')->orderBy('company_id')->orderBy('package_id');
|
||||
|
||||
$res = $query->paginate($conditions['limit']);
|
||||
|
||||
$res->load('order:id,unit_price');
|
||||
|
||||
$res->map(function ($item) {
|
||||
$company = app(CompanyService::class)->load($item->company_id);
|
||||
$package = app(PackageService::class)->load($item->package_id);
|
||||
$item->company_name = $company['name'];
|
||||
$item->package_name = $package['name'];
|
||||
$item->service_months = $package['service_months'] ?? 1;
|
||||
$item->unit_price = sprintf('%.02f', $item->order['unit_price']/100);
|
||||
$item->month_price = sprintf('%.02f', $item->unit_price/$item->service_months);
|
||||
$item->total_price = sprintf('%.02f', $item->month_price*$item->counts);
|
||||
$item->type_name = self::$typeNames[$item->type];
|
||||
unset($item->order);
|
||||
});
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业月报表明细
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function detail(array $conditions = [])
|
||||
{
|
||||
$select = [
|
||||
'sim',
|
||||
'company_id',
|
||||
'package_id',
|
||||
'order_id',
|
||||
'type',
|
||||
];
|
||||
|
||||
$query = $this->orderCardPartitionRepository->select($select)
|
||||
->withConditions($conditions)
|
||||
->orderBy('id', 'desc');
|
||||
|
||||
$res = $query->paginate($conditions['limit']);
|
||||
|
||||
$res->load('order:id,unit_price');
|
||||
|
||||
$carrierOperators = app(Dicts::class)->get('carrier_operator');
|
||||
|
||||
$res->map(function ($item) use ($carrierOperators) {
|
||||
$company = app(CompanyService::class)->load($item->company_id);
|
||||
$package = app(PackageService::class)->load($item->package_id);
|
||||
$item->company_name = $company['name'];
|
||||
$item->package_name = $package['name'];
|
||||
$item->carrier_operator_name = $carrierOperators[$package['carrier_operator']];
|
||||
$month_price = $item->order['unit_price'] / $package['service_months'];
|
||||
$item->month_price = sprintf('%.02f', $month_price/100);
|
||||
unset($item->order);
|
||||
});
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use App\Domains\Virtual\Repositories\PackageRepository;
|
||||
use App\Domains\Virtual\Repositories\ProductRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderCardRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderRenewalCardRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderFlowPackageCardsRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderRenewalPackageCardRepository;
|
||||
|
||||
@ -161,6 +162,7 @@ class LogSyncJob implements ShouldQueue
|
||||
app(OrderRenewalCardRepository::class)->forgetCached();
|
||||
app(OrderRenewalPackageCardRepository::class)->forgetCached();
|
||||
app(OrderFlowPackageCardsRepository::class)->forgetCached();
|
||||
app(OrderCardPartitionRepository::class)->forgetCached();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,54 +18,66 @@ trait OrderCardConcern
|
||||
$conditions['id'] = array_wrap($conditions['id']);
|
||||
$query->whereIn('id', $conditions['id']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['type'])) {
|
||||
$conditions['type'] = array_wrap($conditions['type']);
|
||||
$query->whereIn('type', $conditions['type']);
|
||||
}
|
||||
|
||||
if (isset($conditions['order_id'])) {
|
||||
$conditions['order_id'] = array_wrap($conditions['order_id']);
|
||||
$query->whereIn('order_id', $conditions['order_id']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['sim'])) {
|
||||
$conditions['sim'] = array_wrap($conditions['sim']);
|
||||
$query->whereIn('sim', $conditions['sim']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['company_id'])) {
|
||||
$query->where('company_id', $conditions['company_id']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['package_id'])) {
|
||||
$query->where('package_id', $conditions['package_id']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['carrier_operator'])) {
|
||||
$query->whereHas('package', function ($relation) use ($conditions) {
|
||||
$relation->withTrashed()->where('carrier_operator', $conditions['carrier_operator']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['pay_channel'])) {
|
||||
$query->where('pay_channel', $conditions['pay_channel']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['company_name'])) {
|
||||
$query->whereHas('company', function ($relation) use ($conditions) {
|
||||
$relation->withTrashed()->where('name', $conditions['company_name']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['package_name'])) {
|
||||
$query->whereHas('package', function ($relation) use ($conditions) {
|
||||
$relation->withTrashed()->where('name', $conditions['package_name']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['starttime'])) {
|
||||
$query->where('created_at', '>=', Carbon::parse($conditions['starttime']));
|
||||
}
|
||||
|
||||
|
||||
if (isset($conditions['endtime'])) {
|
||||
$query->where('created_at', '<=', Carbon::parse($conditions['endtime']));
|
||||
}
|
||||
|
||||
if (isset($conditions['month'])) {
|
||||
$query->where(function ($subQuery) use ($conditions) {
|
||||
$subQuery->where('service_start_at', '<=', Carbon::parse($conditions['month']))
|
||||
->where('service_end_at', '>=', Carbon::parse($conditions['month']));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this;
|
||||
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Virtual\Repositories;
|
||||
|
||||
use App\Core\Repository;
|
||||
use App\Models\Virtual\OrderCardPartition as Model;
|
||||
use App\Domains\Virtual\Repositories\Concerns\OrderCardConcern;
|
||||
|
||||
class OrderCardPartitionRepository extends Repository
|
||||
{
|
||||
use OrderCardConcern;
|
||||
|
||||
/**
|
||||
* 是否关闭缓存
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
@ -127,7 +127,7 @@ class CompanyAddressService extends Service
|
||||
}
|
||||
|
||||
app(CompanyRepository::class)->forgetCached();
|
||||
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ class CompanyService extends Service
|
||||
|
||||
$this->companyRepository->setModel($node)->update($attributes);
|
||||
}
|
||||
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ class OrderService extends Service
|
||||
{
|
||||
$this->orderRepository = $orderRepository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单列表
|
||||
*
|
||||
@ -67,7 +67,7 @@ class OrderService extends Service
|
||||
DB::raw('SUM(custom_price) as total_price'),
|
||||
DB::raw('SUM(CASE WHEN transaction_status=1 THEN custom_price ELSE 0 END) as transacted_price'),
|
||||
];
|
||||
|
||||
|
||||
$res = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()->first()->toArray();
|
||||
|
||||
$res['total_price'] = $res['total_price'] ?? 0;
|
||||
@ -123,12 +123,12 @@ class OrderService extends Service
|
||||
}
|
||||
|
||||
Validator::validate($attributes, $rule, $message);
|
||||
|
||||
|
||||
if (!$attributes['id']) {
|
||||
if (!$product = app(ProductRepository::class)->withConditions(['id' => $attributes['product_id']])->first()) {
|
||||
throw new NotExistException('套餐不存在或已删除');
|
||||
}
|
||||
|
||||
|
||||
if ($product->company_id != $attributes['company_id']) {
|
||||
throw new NotAllowedException('非法操作');
|
||||
}
|
||||
@ -153,7 +153,7 @@ class OrderService extends Service
|
||||
|
||||
$this->orderRepository->setModel($node)->update($attributes);
|
||||
}
|
||||
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class PackageService extends Service
|
||||
->applyConditions()->paginate($limit);
|
||||
|
||||
$carrierOperators = app(Dicts::class)->get('carrier_operator');
|
||||
|
||||
|
||||
$packages->map(function ($item) use ($carrierOperators) {
|
||||
$item->cost_price = sprintf('%.02f', $item->cost_price/100);
|
||||
$item->guide_price = sprintf('%.02f', $item->guide_price/100);
|
||||
@ -50,7 +50,7 @@ class PackageService extends Service
|
||||
$item->renewal_guide_price = sprintf('%.02f', $item->renewal_guide_price/100);
|
||||
$item->carrier_operator_name = $carrierOperators[$item->carrier_operator];
|
||||
});
|
||||
|
||||
|
||||
return $packages;
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ class PackageService extends Service
|
||||
|
||||
$this->packageRepository->setModel($node)->update($attributes);
|
||||
}
|
||||
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@ class ProductService extends Service
|
||||
{
|
||||
protected $productRepository;
|
||||
|
||||
protected $products;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
@ -122,4 +124,14 @@ class ProductService extends Service
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function load($id)
|
||||
{
|
||||
if (!$this->products) {
|
||||
$this->products = $this->productRepository->select(['id', 'name', 'company_id', 'package_id', 'base_price', 'renewal_price'])
|
||||
->withTrashed()->get()->keyBy('id');
|
||||
}
|
||||
|
||||
return $this->products[$id];
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +158,8 @@ class PermissionSeeder extends Seeder
|
||||
['name' => 'stats.order.1', 'title' => '续费订单统计', 'path' => '/stats/order/1', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
|
||||
['name' => 'stats.order.2', 'title' => '续费包订单统计', 'path' => '/stats/order/2', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
|
||||
['name' => 'stats.order.3', 'title' => '加油包订单统计', 'path' => '/stats/order/3', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
|
||||
['name' => 'stats.company-report.1', 'title' => '用户月报表', 'path' => '/stats/company-report/1', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
|
||||
['name' => 'stats.company-report.2', 'title' => '增值包月报表', 'path' => '/stats/company-report/2', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
|
||||
],
|
||||
],
|
||||
[
|
||||
|
@ -26,7 +26,8 @@ const routes = [
|
||||
{ path: '/exports', name: 'StatsExports', component: load('exports/index'), meta: { title: '导出记录' } },
|
||||
{ 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/order/detail/:type', name: 'StatsOrderDetail', component: load('stats/order/detail'), meta: { title: '订单明细' } }
|
||||
{ path: '/stats/company-report/1', name: 'StatsOrderDetail', component: load('stats/company-report/index'), meta: { title: '用户月报表', type: [0, 1] } },
|
||||
{ path: '/stats/company-report/2', name: 'StatsOrderDetail', component: load('stats/company-report/index'), meta: { title: '增值包月报表', type: [2, 3] } }
|
||||
]
|
||||
},
|
||||
{ path: '*', redirect: { path: '/home' } }
|
||||
|
36
frontend/src/views/stats/company-report/detail.vue
Normal file
36
frontend/src/views/stats/company-report/detail.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<Modal :footer-hide="true" :mask-closable="false" @on-visible-change="visibleChange" title="详情" v-model="my_show" width="1200">
|
||||
<div class="page-detail-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="index(1)" icon="md-refresh">刷新</Button>
|
||||
</div>
|
||||
|
||||
<div class="handle-item">
|
||||
<Button @click="exportExcel" icon="md-download">导出</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="page-list-wrap">
|
||||
<Table :columns="columns" :data="list_data ? list_data.data : []" stripe width="1150"></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>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script src="./js/detail.js"></script>
|
126
frontend/src/views/stats/company-report/index.vue
Normal file
126
frontend/src/views/stats/company-report/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<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="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>
|
||||
|
||||
<div class="handle-item">
|
||||
<Button @click="exportExcel" icon="md-download">导出</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="options.company_name">
|
||||
<Option :key="item.id" :value="item.name" v-for="item in completeHandledCompanies">{{ item.name }}</Option>
|
||||
</AutoComplete>
|
||||
</li>
|
||||
|
||||
<li class="handle-item w-250">
|
||||
<AutoComplete @on-search="handleCompletePackages" icon="ios-search" placeholder="套餐名称" v-model.trim="options.package_name">
|
||||
<Option :key="item.id" :value="item.name" v-for="item in completeHandledPackages">{{ item.name }}</Option>
|
||||
</AutoComplete>
|
||||
</li>
|
||||
|
||||
<li class="handle-item w-250">
|
||||
<Select multiple clearable placeholder="类型" v-model="options.type">
|
||||
<Option :value="0" v-if="types.indexOf(0) !== -1">首年</Option>
|
||||
<Option :value="1" v-if="types.indexOf(1) !== -1">非首年</Option>
|
||||
<Option :value="2" v-if="types.indexOf(2) !== -1">续费包</Option>
|
||||
<Option :value="3" v-if="types.indexOf(3) !== -1">加油包</Option>
|
||||
</Select>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="handle-wraper">
|
||||
<li class="handle-item w-250">
|
||||
<DatePicker :editable="false" placeholder="请选择时间" placement="bottom-start" type="month" v-model.trim="options.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="columns" :data="data" :height="page.limit > 12 ? 610 : ''" ref="table" stripe>
|
||||
<template class="table-footer" slot="footer">
|
||||
<colgroup class="table-footer-colgroup"></colgroup>
|
||||
<thead class="ivu-table" v-show="data.length">
|
||||
<tr>
|
||||
<th>
|
||||
<div class="ivu-table-cell">总计</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell">{{stats.counts}}</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell">{{Number(stats.total_price).toFixed(2)}}</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="ivu-table-cell"></div>
|
||||
</th>
|
||||
<th rowspan="1" v-if="page.limit > 12"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<div class="page-turn-wrap">
|
||||
<Page
|
||||
:current="Number(page.page)"
|
||||
:page-size="Number(page.limit)"
|
||||
:page-size-opts="[10, 20, 100, Infinity]"
|
||||
:total="Number(page.total)"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changeLimit"
|
||||
show-elevator
|
||||
show-sizer
|
||||
show-total
|
||||
></Page>
|
||||
</div>
|
||||
|
||||
<ui-detail :list="detailObj.list" :options="detailObj.options" :show.sync="detailObj.show"></ui-detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./js/index.js"></script>
|
107
frontend/src/views/stats/company-report/js/detail.js
Normal file
107
frontend/src/views/stats/company-report/js/detail.js
Normal file
@ -0,0 +1,107 @@
|
||||
export default {
|
||||
name: 'StatsCompanyReportDetail',
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: {
|
||||
month: null,
|
||||
type: null,
|
||||
company_id: null,
|
||||
package_id: null
|
||||
}
|
||||
},
|
||||
list: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(bool) {
|
||||
this.my_show = bool;
|
||||
},
|
||||
list(obj) {
|
||||
this.list_data = obj;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
my_show: false,
|
||||
list_data: null,
|
||||
columns: [{
|
||||
title: 'SIM',
|
||||
key: 'sim',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '运营商',
|
||||
key: 'carrier_operator_name',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '企业名称',
|
||||
key: 'company_name',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: '套餐名称',
|
||||
key: 'package_name',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '套餐单价(元/月)',
|
||||
key: 'month_price',
|
||||
width: 120
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
visibleChange(bool) {
|
||||
this.$emit('update:show', bool);
|
||||
},
|
||||
/**
|
||||
* [index 列表]
|
||||
* @param {Number} page [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
index(page) {
|
||||
this.isShowLoading(true);
|
||||
let params = this.options;
|
||||
params.page = page;
|
||||
|
||||
service.get('api/stats/company-report/detail', { params }).then(res => {
|
||||
this.isShowLoading(false);
|
||||
if (res.code == 0) {
|
||||
this.list_data = res.data;
|
||||
}
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
},
|
||||
exportExcel() {
|
||||
this.isShowLoading(true);
|
||||
let params = this.options;
|
||||
|
||||
service.get('api/stats/company-report/detail/export', { params }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
if (res.data) {
|
||||
this.downloadFile(res.data);
|
||||
} else {
|
||||
this.$Modal.success({
|
||||
title: '提示',
|
||||
content: '当前导出数据量大,已进入后台队列导出模式,请稍后至导出列表查看下载。'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.isShowLoading(false);
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
266
frontend/src/views/stats/company-report/js/index.js
Normal file
266
frontend/src/views/stats/company-report/js/index.js
Normal file
@ -0,0 +1,266 @@
|
||||
import {
|
||||
sumBy
|
||||
} from 'service/util';
|
||||
export default {
|
||||
name: 'StatsCompanyReport',
|
||||
components: {
|
||||
UiDetail: resolve => require(['views/stats/order/detail'], resolve)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
detailObj: {
|
||||
type: null,
|
||||
options: {}
|
||||
},
|
||||
types: [],
|
||||
options: {
|
||||
company_name: null,
|
||||
package_name: null,
|
||||
type: [],
|
||||
month: this.moment().subtract('2', 'months').startOf('month').format('YYYY-MM')
|
||||
},
|
||||
data: [],
|
||||
list: [],
|
||||
stats: {},
|
||||
page: {
|
||||
total: 0,
|
||||
limit: 10,
|
||||
page: 1
|
||||
},
|
||||
columns: [{
|
||||
title: '企业名称',
|
||||
key: 'company_name',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: '套餐名称',
|
||||
key: 'package_name',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '套餐周期(月)',
|
||||
key: 'service_months',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '套餐价格(元/周期)',
|
||||
key: 'unit_price',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '套餐单价(元/月)',
|
||||
key: 'month_price',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '收费用户数',
|
||||
key: 'counts',
|
||||
width: 130
|
||||
},
|
||||
{
|
||||
title: '收费总价(元)',
|
||||
key: 'total_price',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '收费类型',
|
||||
key: 'type_name',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
render: (h, {
|
||||
row,
|
||||
column,
|
||||
index
|
||||
}) => {
|
||||
let html = [];
|
||||
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
click: (event) => {
|
||||
this.isShowLoading(true);
|
||||
|
||||
let params = {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
type: row.type,
|
||||
company_id: row.company_id,
|
||||
month: this.options.month,
|
||||
package_id: row.package_id
|
||||
};
|
||||
|
||||
service.get('api/stats/company-report/detail', {
|
||||
params
|
||||
}).then(res => {
|
||||
this.isShowLoading(false);
|
||||
if (res.code == 0) {
|
||||
this.detailObj = {
|
||||
show: true,
|
||||
options: params,
|
||||
list: res.data
|
||||
};
|
||||
}
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, '查看明细'));
|
||||
|
||||
if (html.length) {
|
||||
return h('div', html);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.types = this.$route.meta.type;
|
||||
this.options.type = this.types;
|
||||
this.index();
|
||||
},
|
||||
mounted() {
|
||||
window.onresize = () => {
|
||||
this.tableFooter();
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* [index 列表]
|
||||
* @param {Number} page [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
index() {
|
||||
this.isShowLoading(true);
|
||||
|
||||
this.data = [];
|
||||
|
||||
let params = Object.assign(this.options, {
|
||||
limit: 0
|
||||
});
|
||||
|
||||
if (!params.month) {
|
||||
params.month = this.moment().subtract('2', 'months').startOf('month').format('YYYY-MM');
|
||||
} else {
|
||||
params.month = this.moment(params.month).format('YYYY-MM');
|
||||
}
|
||||
|
||||
if (params.type.length === 0) {
|
||||
params.type = this.types;
|
||||
}
|
||||
|
||||
service.get('api/stats/company-report', {
|
||||
params
|
||||
}).then(res => {
|
||||
this.isShowLoading(false);
|
||||
if (res.code == 0) {
|
||||
this.list = res.data;
|
||||
this.page.total = this.list.length;
|
||||
this.changePage(1);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* [request 刷新]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
request() {
|
||||
let page = this.page.page;
|
||||
|
||||
if (this.data.length == 1) {
|
||||
page = this.returnPage(this.page.total, this.page.page, this.page.limit);
|
||||
}
|
||||
|
||||
this.index();
|
||||
this.changePage(page);
|
||||
},
|
||||
|
||||
resetSearch() {
|
||||
for (let k in this.options) {
|
||||
if (k === 'month') {
|
||||
this.options[k] = this.moment().subtract('2', 'months').startOf('month').format('YYYY-MM');
|
||||
} else if (k === 'type') {
|
||||
this.options[k] = [];
|
||||
} else {
|
||||
this.options[k] = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.page = {
|
||||
total: 0,
|
||||
limit: 10,
|
||||
page: 1
|
||||
};
|
||||
|
||||
this.index();
|
||||
},
|
||||
changeLimit(limit) {
|
||||
this.page.limit = limit;
|
||||
this.changePage(1);
|
||||
},
|
||||
changePage(page) {
|
||||
this.page.page = page;
|
||||
this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit);
|
||||
|
||||
this.stats = {
|
||||
counts: sumBy(this.list, 'counts'),
|
||||
total_price: sumBy(this.list, 'total_price')
|
||||
};
|
||||
|
||||
this.tableFooter();
|
||||
},
|
||||
tableFooter() {
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
let html = $('.ivu-table-header colgroup').html();
|
||||
$('.table-footer-colgroup').html(html);
|
||||
}, 10);
|
||||
});
|
||||
},
|
||||
exportExcel() {
|
||||
this.isShowLoading(true);
|
||||
|
||||
let params = Object.assign(this.options, {
|
||||
limit: 0
|
||||
});
|
||||
|
||||
if (!params.month) {
|
||||
params.month = this.moment().subtract('2', 'months').startOf('month').format('YYYY-MM');
|
||||
} else {
|
||||
params.month = this.moment(params.month).format('YYYY-MM');
|
||||
}
|
||||
|
||||
if (params.type.length === 0) {
|
||||
params.type = this.types;
|
||||
}
|
||||
|
||||
service.get('api/stats/company-report/export', {
|
||||
params
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.downloadFile(res.data);
|
||||
}
|
||||
|
||||
this.isShowLoading(false);
|
||||
}).catch(() => {
|
||||
this.isShowLoading(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user