流量池配置
This commit is contained in:
parent
a3a3856fbb
commit
f703863e4e
16
app/Core/AbstractImport.php
Normal file
16
app/Core/AbstractImport.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
use Dipper\Excel\Concerns\Importable;
|
||||
|
||||
abstract class AbstractImport
|
||||
{
|
||||
use Importable;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
set_time_limit(-1);
|
||||
ini_set('memory_limit', '4096m');
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace App\Domains\Account\Repositories;
|
||||
use App\Core\Repository;
|
||||
use App\Models\Account\Account as Model;
|
||||
use App\Domains\Account\Services\AccountService;
|
||||
use function App\account_avatar;
|
||||
|
||||
class AccountRepository extends Repository
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ class ConfigController extends Controller
|
||||
{
|
||||
$key = $this->request->get('key');
|
||||
$config = $this->configService->get($key);
|
||||
|
||||
|
||||
return res($config, '获取配置', 201);
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ class ExportService extends Service
|
||||
$url = Storage::disk($disk)->url($export->filename);
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
Excel::queue($export, $export->filename, $disk);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class FileService extends Service
|
||||
protected $user;
|
||||
|
||||
protected $fileRepository;
|
||||
|
||||
|
||||
protected $fileWithRepository;
|
||||
|
||||
public static $types = ['account/avatar'];
|
||||
@ -132,7 +132,7 @@ class FileService extends Service
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $fileModel;
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ class FileService extends Service
|
||||
if (empty($news)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ($cover) {
|
||||
$this->detach($type, $typeid);
|
||||
}
|
||||
@ -264,7 +264,7 @@ class FileService extends Service
|
||||
}
|
||||
|
||||
list($width, $height) = ($imageInfo = @getimagesize($file->getRealPath())) === false ? [null, null] : $imageInfo;
|
||||
|
||||
|
||||
if (($filename = $file->storeAs($path, '', $disk)) === false) {
|
||||
throw new UploadFailedException('上传失败');
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class FlowPoolSync extends Command
|
||||
$companies = app(CompanyRepository::class)->withTrashed()->get()->keyBy('sn');
|
||||
$packages = app(PackageRepository::class)->withTrashed()->get()->keyBy('sn');
|
||||
|
||||
$select = ['id', 'shared_type as shared', "level_type as level", 'custom_no', 'cell_number as sn', 'name', 'flows', 'status', 'del', 'create_time'];
|
||||
$select = ['id', 'type_id', 'shared_type as shared', "level_type as level", 'custom_no', 'cell_number as sn', 'name', 'flows', 'status', 'del', 'create_time'];
|
||||
|
||||
$types = DB::connection('real')->table('jxc_flow_cell_type')->select(['id', 'carrieroperator'])->get()->pluck('carrieroperator', 'id')->toArray();
|
||||
|
||||
@ -59,7 +59,7 @@ class FlowPoolSync extends Command
|
||||
$data = [];
|
||||
|
||||
foreach ($flowPools as $value) {
|
||||
$carrier_operator = $types[$value['typeid']] ?? 3;
|
||||
$carrier_operator = $types[$value['type_id']] ?? 3;
|
||||
$package_ids = $flowPackages[$value['id']] ?? [];
|
||||
|
||||
$data[] = [
|
||||
|
@ -3,8 +3,11 @@ namespace App\Domains\Virtual\Http\Controllers;
|
||||
|
||||
use App\Core\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Dipper\Excel\Facades\Excel;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Exceptions\InvalidArgumentException;
|
||||
use App\Domains\Virtual\Imports\FlowCardImport;
|
||||
use App\Domains\Virtual\Services\FlowPoolService;
|
||||
use App\Domains\Real\Repositories\FlowPoolRepository as RealFlowPoolRepository;
|
||||
|
||||
class FlowPoolController extends Controller
|
||||
{
|
||||
@ -27,7 +30,7 @@ class FlowPoolController extends Controller
|
||||
*/
|
||||
public function real()
|
||||
{
|
||||
$list = app(RealFlowPoolRepository::class)->get();
|
||||
$list = $this->flowPoolService->real();
|
||||
return res($list, 'RD流量池列表', 201);
|
||||
}
|
||||
|
||||
@ -88,4 +91,59 @@ class FlowPoolController extends Controller
|
||||
|
||||
return res(true, '删除成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加卡.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function addCards()
|
||||
{
|
||||
if (!$this->request->file('file')) {
|
||||
throw new InvalidArgumentException('上传的文件错误');
|
||||
}
|
||||
|
||||
$cards = (new FlowCardImport)->toArray($this->request->file('file'));
|
||||
|
||||
if (empty($cards)) {
|
||||
throw new InvalidArgumentException('上传的文件错误');
|
||||
}
|
||||
|
||||
$sheet = $cards[0];
|
||||
|
||||
$simArray = [];
|
||||
|
||||
foreach ($sheet as $row) {
|
||||
if (is_numeric($row[0])) {
|
||||
$simArray[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$simArray = array_unique($simArray);
|
||||
|
||||
if (empty($simArray)) {
|
||||
throw new InvalidArgumentException('流量卡张数为空');
|
||||
}
|
||||
|
||||
$pool_id = $this->request->get('pool_id', 0);
|
||||
|
||||
$this->flowPoolService->addCards($pool_id, $simArray);
|
||||
|
||||
return res(true, '添加成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function setting()
|
||||
{
|
||||
$attributes = $this->request->all();
|
||||
|
||||
$setting = $this->flowPoolService->setting($attributes);
|
||||
|
||||
return res($setting, $attributes['id'] ? '修改成功' : '添加成功');
|
||||
}
|
||||
|
||||
}
|
||||
|
9
app/Domains/Virtual/Imports/FlowCardImport.php
Normal file
9
app/Domains/Virtual/Imports/FlowCardImport.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Virtual\Imports;
|
||||
|
||||
use App\Core\AbstractImport;
|
||||
|
||||
class FlowCardImport extends AbstractImport
|
||||
{
|
||||
}
|
@ -16,7 +16,7 @@ class FlowPoolCardRepository extends Repository
|
||||
|
||||
/**
|
||||
* 是否开启数据转化
|
||||
*
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $needTransform = false;
|
||||
@ -24,12 +24,10 @@ class FlowPoolCardRepository extends Repository
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldSearchable = [
|
||||
'id' => '=',
|
||||
'created_at' => 'like',
|
||||
];
|
||||
protected $fieldSearchable = [];
|
||||
|
||||
public function model() {
|
||||
public function model()
|
||||
{
|
||||
return Model::class;
|
||||
}
|
||||
|
||||
@ -52,11 +50,21 @@ class FlowPoolCardRepository extends Repository
|
||||
*/
|
||||
public function withConditions(array $conditions = [])
|
||||
{
|
||||
if (isset($conditions['id'])) {
|
||||
$conditions['id'] = array_wrap($conditions['id']);
|
||||
$this->model = $this->model->whereIn('id', $conditions['id']);
|
||||
if (isset($conditions['pool_id'])) {
|
||||
$conditions['pool_id'] = array_wrap($conditions['pool_id']);
|
||||
$this->model = $this->model->whereIn('pool_id', $conditions['pool_id']);
|
||||
}
|
||||
|
||||
if (isset($conditions['sim'])) {
|
||||
$conditions['sim'] = array_wrap($conditions['sim']);
|
||||
$this->model = $this->model->whereIn('sim', $conditions['sim']);
|
||||
}
|
||||
|
||||
if (isset($conditions['package_id'])) {
|
||||
$conditions['package_id'] = array_wrap($conditions['package_id']);
|
||||
$this->model = $this->model->whereIn('package_id', $conditions['package_id']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Virtual\Repositories;
|
||||
|
||||
use App\Core\Repository;
|
||||
use App\Models\Virtual\FlowPoolPackage as Model;
|
||||
|
||||
class FlowPoolPackageRepository 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']);
|
||||
}
|
||||
|
||||
if (isset($conditions['pool_id'])) {
|
||||
$conditions['pool_id'] = array_wrap($conditions['pool_id']);
|
||||
$this->model = $this->model->whereIn('pool_id', $conditions['pool_id']);
|
||||
}
|
||||
|
||||
if (isset($conditions['package_id'])) {
|
||||
$conditions['package_id'] = array_wrap($conditions['package_id']);
|
||||
$this->model = $this->model->whereIn('package_id', $conditions['package_id']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -59,4 +59,6 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
|
||||
$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']);
|
||||
$router->post('/flow-pools/add-cards', ['as' => 'flow-pools.add-cards', 'uses' => 'FlowPoolController@addCards']);
|
||||
$router->post('/flow-pools/setting', ['as' => 'flow-pools.setting', 'uses' => 'FlowPoolController@setting']);
|
||||
});
|
||||
|
@ -2,23 +2,30 @@
|
||||
namespace App\Domains\Virtual\Services;
|
||||
|
||||
use App\Dicts;
|
||||
use Carbon\Carbon;
|
||||
use App\Core\Service;
|
||||
use Illuminate\Validation\Rule;
|
||||
use App\Models\Virtual\FlowPool;
|
||||
use App\Models\Virtual\OrderCard;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Exceptions\NotExistException;
|
||||
use App\Exceptions\NotAllowedException;
|
||||
use App\Models\Virtual\FlowPoolSetting;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Domains\Virtual\Services\CompanyService;
|
||||
use App\Domains\Virtual\Services\PackageService;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolRepository;
|
||||
use App\Domains\Virtual\Repositories\OrderCardRepository;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolCardRepository;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolMonthRepository;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolPackageRepository;
|
||||
use App\Domains\Virtual\Repositories\FlowPoolSettingRepository;
|
||||
use App\Domains\Real\Repositories\FlowPoolRepository as RealFlowPoolRepository;
|
||||
use App\Exceptions\InvalidArgumentException;
|
||||
use function App\range_compare;
|
||||
|
||||
class FlowPoolService extends Service
|
||||
{
|
||||
protected $realFlowPoolRepository;
|
||||
protected $flowPoolRepository;
|
||||
protected $flowPoolPackageRepository;
|
||||
protected $flowPoolSettingRepository;
|
||||
@ -33,19 +40,47 @@ class FlowPoolService extends Service
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
RealFlowPoolRepository $realFlowPoolRepository,
|
||||
FlowPoolRepository $flowPoolRepository,
|
||||
FlowPoolPackageRepository $flowPoolPackageRepository,
|
||||
FlowPoolSettingRepository $flowPoolSettingRepository,
|
||||
FlowPoolCardRepository $flowPoolCardRepository,
|
||||
FlowPoolMonthRepository $flowPoolMonthRepository
|
||||
) {
|
||||
$this->realFlowPoolRepository = $realFlowPoolRepository;
|
||||
$this->flowPoolRepository = $flowPoolRepository;
|
||||
$this->flowPoolPackageRepository = $flowPoolPackageRepository;
|
||||
$this->flowPoolSettingRepository = $flowPoolSettingRepository;
|
||||
$this->flowPoolCardRepository = $flowPoolCardRepository;
|
||||
$this->flowPoolMonthRepository = $flowPoolMonthRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* RD流量池列表
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function real()
|
||||
{
|
||||
$used = $this->flowPoolRepository->select(['id', 'real_pool_ids'])->get();
|
||||
|
||||
$array = [];
|
||||
|
||||
foreach ($used as $item) {
|
||||
$item['real_pool_ids'] = $item['real_pool_ids'] ?? [];
|
||||
|
||||
foreach ($item['real_pool_ids'] as $key => $value) {
|
||||
$array[$value] = $item['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$list = $this->realFlowPoolRepository->get();
|
||||
|
||||
$list->map(function ($item) use ($array) {
|
||||
$item->virtual_pool_id = $array[$item['id']] ?? 0;
|
||||
});
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 流量池列表
|
||||
*
|
||||
@ -59,19 +94,51 @@ class FlowPoolService extends Service
|
||||
$flowPools = $this->flowPoolRepository->withConditions($conditions)
|
||||
->applyConditions()->paginate($limit);
|
||||
|
||||
$packages = $this->flowPoolPackageRepository->withConditions([
|
||||
'pool_id' => $flowPools->pluck('id')->toArray(),
|
||||
])->get()->groupBy('pool_id');
|
||||
$packages = $this->flowPoolCardRepository->select([
|
||||
'pool_id',
|
||||
'package_id',
|
||||
])->withConditions(['pool_id' => $flowPools->pluck('id')->toArray()])->groupBy(['pool_id', 'package_id'])->get();
|
||||
|
||||
$packages->map(function ($item) {
|
||||
$item->package_name = app(PackageService::class)->load($item->package_id)['name'];
|
||||
});
|
||||
|
||||
$packages = $packages->groupBy('pool_id');
|
||||
|
||||
$settings = $this->flowPoolSettingRepository->withConditions(['pool_id' => $flowPools->pluck('id')->toArray()])->orderBy('start_at', 'desc')->get();
|
||||
|
||||
$settings->map(function ($item) use ($packages) {
|
||||
$itemPackages = $packages[$item->pool_id] ?? [];
|
||||
|
||||
$minimum_settings = $item->minimum_settings ?? [];
|
||||
|
||||
foreach ($itemPackages as $package) {
|
||||
if (!in_array($package['package_id'], array_pluck($minimum_settings, 'package_id'))) {
|
||||
$minimum_settings[] = [
|
||||
'package_id' => $package['package_id'],
|
||||
'package_name' => $package['package_name'],
|
||||
'flows' => 0,
|
||||
'price' => 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$item->minimum_settings = $minimum_settings;
|
||||
});
|
||||
|
||||
$settings = $settings->groupBy('pool_id');
|
||||
|
||||
$carrierOperators = app(Dicts::class)->get('carrier_operator');
|
||||
$shares = app(Dicts::class)->get('shares');
|
||||
|
||||
$flowPools->map(function ($item) use ($carrierOperators, $shares, $packages) {
|
||||
$flowPools->map(function ($item) use ($carrierOperators, $shares, $packages, $settings) {
|
||||
$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']];
|
||||
$item->package_ids = $packages[$item->id] ? array_pluck($packages[$item->id], 'package_id') : [];
|
||||
$item->real_pool_ids = empty($item->real_pool_ids) ? [] : $item->real_pool_ids;
|
||||
$item->status = $item->end_at ? 1 : 0;
|
||||
$item->packages = $packages[$item->id] ?? [];
|
||||
$item->settings = $settings[$item->id] ?? [];
|
||||
});
|
||||
|
||||
return $flowPools;
|
||||
@ -85,6 +152,11 @@ class FlowPoolService extends Service
|
||||
*/
|
||||
public function store(array $attributes = [])
|
||||
{
|
||||
$attributes['start_at'] = $attributes['start_at'] ? Carbon::parse($attributes['start_at'])->startOfMonth()->format('Y-m-d H:i:s') : Carbon::now()->startOfMonth()->format('Y-m-d H:i:s');
|
||||
$attributes['end_at'] = $attributes['status'] ? Carbon::now()->endOfMonth()->format('Y-m-d H:i:s') : null;
|
||||
|
||||
$attributes = array_only($attributes, ['id', 'company_id', 'name', 'flows', 'carrier_operator', 'shared', 'real_pool_ids', 'remark', 'start_at', 'end_at']);
|
||||
|
||||
$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'],
|
||||
@ -103,25 +175,12 @@ class FlowPoolService extends Service
|
||||
|
||||
Validator::validate($attributes, $rule, $message);
|
||||
|
||||
if (empty($attributes['package_ids'])) {
|
||||
throw new NotAllowedException('请至少加入一个套餐');
|
||||
}
|
||||
|
||||
if (!$attributes['id']) {
|
||||
$maxId = FlowPool::withTrashed()->max('id');
|
||||
$attributes['id'] = $maxId ? $maxId + 1 : 1;
|
||||
$attributes['sn'] = self::sn($attributes['id']);
|
||||
|
||||
DB::transaction(function () use ($attributes) {
|
||||
$node = $this->flowPoolRepository->create(array_except($attributes, ['package_ids']));
|
||||
|
||||
foreach ($attributes['package_ids'] as $package_id) {
|
||||
$this->flowPoolPackageRepository->create([
|
||||
'pool_id' => $node->id,
|
||||
'package_id' => $package_id,
|
||||
]);
|
||||
}
|
||||
});
|
||||
$node = $this->flowPoolRepository->create($attributes);
|
||||
}
|
||||
|
||||
if ($attributes['id']) {
|
||||
@ -131,25 +190,7 @@ class FlowPoolService extends Service
|
||||
throw new NotExistException('流量池不存在或已删除');
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($attributes, $node) {
|
||||
$exists = $this->flowPoolPackageRepository->withConditions([
|
||||
'pool_id' => $node->id,
|
||||
])->get()->pluck('package_id')->toArray();
|
||||
|
||||
$this->flowPoolRepository->setModel($node)->update(array_except($attributes, ['package_ids']));
|
||||
|
||||
foreach ($exists as $package_id) {
|
||||
if (!in_array($package_id, $attributes['package_ids'])) {
|
||||
$this->flowPoolPackageRepository->withConditions(['package_id' => $package_id])->delete();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($attributes['package_ids'] as $package_id) {
|
||||
if (!in_array($package_id, $exists)) {
|
||||
$this->flowPoolPackageRepository->create(['pool_id' => $node->id, 'package_id' => $package_id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
$this->flowPoolRepository->setModel($node)->update($attributes);
|
||||
}
|
||||
|
||||
return $node;
|
||||
@ -169,6 +210,168 @@ class FlowPoolService extends Service
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加卡
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addCards($poolId, array $simArray)
|
||||
{
|
||||
if (!$this->flowPoolRepository->find($poolId)) {
|
||||
throw new NotExistException('流量池不存在或已删除');
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($poolId, $simArray) {
|
||||
foreach (array_chunk($simArray, 20000) as $chunk) {
|
||||
$array = app(OrderCardRepository::class)->select(['sim', 'package_id'])->withConditions(['sim' => $chunk])
|
||||
->get()->pluck('package_id', 'sim')->toArray();
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($chunk as $key => $value) {
|
||||
if (!isset($array[$value])) {
|
||||
throw new NotAllowedException("卡 {$value} 不存在销售记录");
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
'pool_id' => $poolId,
|
||||
'sim' => $value,
|
||||
'package_id' => $array[$value],
|
||||
];
|
||||
}
|
||||
|
||||
$this->flowPoolCardRepository->upsert($data, 'sim');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$this->flowPoolCardRepository->forgetCached();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定价管理
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return FlowPool
|
||||
*/
|
||||
public function setting(array $attributes = [])
|
||||
{
|
||||
$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');
|
||||
|
||||
if ($attributes['start_at'] > $attributes['end_at']) {
|
||||
throw new InvalidArgumentException('开始时间必须小于结束时间');
|
||||
}
|
||||
|
||||
$rule = [
|
||||
'pool_id' => ['required', Rule::exists($this->flowPoolRepository->getTable(), 'id')],
|
||||
'first_month_price' => ['required', 'integer'],
|
||||
'other_month_price' => ['required', 'integer'],
|
||||
'gradient' => ['required', 'integer'],
|
||||
'gradient_unit' => ['required', 'in:0,1'],
|
||||
];
|
||||
|
||||
$message = [
|
||||
'pool_id.required' => '请输入流量池ID',
|
||||
'first_month_price.required' => '请输入首月单价',
|
||||
'other_month_price.required' => '请输入次月单价',
|
||||
'gradient.required' => '请输入梯度',
|
||||
'gradient_unit.required' => '请选择梯度单位',
|
||||
];
|
||||
|
||||
Validator::validate($attributes, $rule, $message);
|
||||
|
||||
if (!$attributes['id']) {
|
||||
DB::transaction(function () use ($attributes) {
|
||||
$settings = $this->flowPoolSettingRepository->withConditions(['pool_id' => $attributes['pool_id']])->get();
|
||||
|
||||
if (empty($settings)) {
|
||||
$attributes['start_at'] = '2000-01-01 00:00:00';
|
||||
$attributes['end_at'] !== '3000-01-01 23:59:59';
|
||||
}
|
||||
|
||||
$creates = [];
|
||||
|
||||
if (!empty($settings)) {
|
||||
foreach ($settings as $item) {
|
||||
$result = range_compare([$attributes['start_at'], $attributes['end_at']], [$item['start_at'], $item['end_at']]);
|
||||
switch ($result) {
|
||||
case 0:
|
||||
$this->flowPoolSettingRepository->where(['id' => $item['id']])->update($attributes);
|
||||
$creates = [];
|
||||
break 2;
|
||||
case 1:
|
||||
$this->flowPoolSettingRepository->destroy($item['id']);
|
||||
$creates[0] = $attributes;
|
||||
break;
|
||||
case 2:
|
||||
$this->flowPoolSettingRepository->destroy($item['id']);
|
||||
$creates[0] = $attributes;
|
||||
unset($item['id']);
|
||||
$creates[1] = $item->toArray();
|
||||
$creates[1]['end_at'] = Carbon::parse($attributes['start_at'])->subMonth()->endOfMonth()->format('Y-m-d H:i:s');
|
||||
$creates[2] = $item->toArray();
|
||||
$creates[2]['start_at'] = Carbon::parse($attributes['end_at'])->addMonth()->startOfMonth()->format('Y-m-d H:i:s');
|
||||
break 2;
|
||||
case 3:
|
||||
case 4:
|
||||
$creates[0] = $attributes;
|
||||
break;
|
||||
case 5:
|
||||
$creates[0] = $attributes;
|
||||
$item['start_at'] = Carbon::parse($attributes['end_at'])->addMonth()->startOfMonth()->format('Y-m-d H:i:s');
|
||||
$this->flowPoolSettingRepository->where(['id' => $item['id']])->update($item);
|
||||
break;
|
||||
case 6:
|
||||
$creates[0] = $attributes;
|
||||
$item['end_at'] = Carbon::parse($attributes['start_at'])->subMonth()->startOfMonth()->format('Y-m-d H:i:s');
|
||||
$this->flowPoolSettingRepository->where(['id' => $item['id']])->update($item);
|
||||
break;
|
||||
|
||||
default:
|
||||
$creates[0] = $attributes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$creates[0] = $attributes;
|
||||
$creates[0]['start_at'] = '2000-01-01 00:00:00';
|
||||
$creates[0]['end_at'] !== '3000-01-01 23:59:59';
|
||||
}
|
||||
|
||||
$maxId = FlowPoolSetting::withTrashed()->max('id') ?? 0;
|
||||
|
||||
foreach ($creates as $key => $create) {
|
||||
$create['id'] = ++$maxId;
|
||||
if ($key) {
|
||||
$this->flowPoolSettingRepository->create($create);
|
||||
} else {
|
||||
$node =$this->flowPoolSettingRepository->create($create);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ($attributes['id']) {
|
||||
$node = $this->flowPoolSettingRepository->find($attributes['id']);
|
||||
|
||||
if (!$node) {
|
||||
throw new NotExistException('规则不存在或已删除');
|
||||
}
|
||||
|
||||
if ($node->start_at !== $attributes['start_at'] || $node->end_at !== $attributes['end_at']) {
|
||||
throw new InvalidArgumentException('起止时间不能修改');
|
||||
}
|
||||
|
||||
$this->flowPoolSettingRepository->setModel($node)->update($attributes);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
||||
public static function sn($id)
|
||||
{
|
||||
return sprintf('FP%011d', $id);
|
||||
|
@ -27,4 +27,9 @@ class FlowPool extends Model
|
||||
{
|
||||
return $this->belongsToMany(Package::class, 'virtual_flow_pool_packages', 'pool_id', 'package_id');
|
||||
}
|
||||
|
||||
public function settings()
|
||||
{
|
||||
return $this->hasMany(FlowPoolSetting::class, 'pool_id', 'id');
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,28 @@
|
||||
namespace App\Models\Virtual;
|
||||
|
||||
use App\Core\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class FlowPoolCard extends Model
|
||||
{
|
||||
protected $table = 'virtual_flow_pool_cards';
|
||||
|
||||
protected $primaryKey = ['pool_id', 'sim'];
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
/**
|
||||
* Set the keys for a save update query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function setKeysForSaveQuery(Builder $query)
|
||||
{
|
||||
foreach ($this->getKeyName() as $key) {
|
||||
$query->where($key, '=', $this->original[$key] ?? $this->getAttribute($key));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Virtual;
|
||||
|
||||
use App\Core\Model;
|
||||
use App\Models\Virtual\Package;
|
||||
use App\Models\Virtual\FlowPool;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class FlowPoolPackage extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'virtual_flow_pool_packages';
|
||||
|
||||
public function package()
|
||||
{
|
||||
return $this->belongsTo(Package::class, 'package_id');
|
||||
}
|
||||
|
||||
public function pool()
|
||||
{
|
||||
return $this->belongsTo(FlowPool::class, 'pool_id');
|
||||
}
|
||||
}
|
@ -3,8 +3,15 @@
|
||||
namespace App\Models\Virtual;
|
||||
|
||||
use App\Core\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class FlowPoolSetting extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'virtual_flow_pool_settings';
|
||||
|
||||
protected $casts = [
|
||||
'minimum_settings' => 'array',
|
||||
];
|
||||
}
|
||||
|
@ -67,9 +67,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
});
|
||||
|
||||
// excel
|
||||
$this->app->singleton('excel', function ($app) {
|
||||
return $app->loadComponent('excel', \Dipper\Excel\ExcelServiceProvider::class);
|
||||
});
|
||||
$this->app->register(\Dipper\Excel\ExcelServiceProvider::class);
|
||||
|
||||
// 全局代理
|
||||
$this->app->singleton('dipper', function ($app) {
|
||||
|
@ -1,9 +1,11 @@
|
||||
<?php
|
||||
namespace App;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Events\FileUploadEvent;
|
||||
use Dipper\Foundation\Support\Time;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Domains\Account\Services\AccountService;
|
||||
|
||||
if (! function_exists('cdn')) {
|
||||
/**
|
||||
@ -179,3 +181,67 @@ if (! function_exists('human_filesize')) {
|
||||
return sprintf("%.{$decimals}f", $int / pow(1024, $factor)) . @$size[$factor];
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('range_compare')) {
|
||||
/**
|
||||
* 区间比较
|
||||
* 0:两区间完全相等
|
||||
* 1:区间包含 区间1包含区间2
|
||||
* 2:区间包含 区间2包含区间1
|
||||
* 3:区间不相交 区间1在左,区间2在右
|
||||
* 4:区间不相交 区间1在右,区间2在左
|
||||
* 5:区间相交 区间1在左,区间2在右
|
||||
* 6:区间相交 区间1在右,区间2在左
|
||||
*
|
||||
* 情况二:区间不相交 区间1在右,区间2在左 2
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $array
|
||||
*/
|
||||
function range_compare(array $array1, array $array2)
|
||||
{
|
||||
$array1 = array_values($array1);
|
||||
$array2 = array_values($array2);
|
||||
|
||||
// 数组必须是两个值
|
||||
if (count($array1) !== 2 || count($array2) !== 2) {
|
||||
throw new \Exception('array count error.');
|
||||
}
|
||||
|
||||
// 数组第一个值要小于第二个值
|
||||
if ($array1[1] < $array1[0] || $array2[1] < $array2[0]) {
|
||||
throw new \Exception('array values error.');
|
||||
}
|
||||
|
||||
if ($array1 === $array2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($array1[0] <= $array2[0] && $array1[1] >= $array2[1]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($array1[0] >= $array2[0] && $array1[1] <= $array2[1]) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
if ($array1[1] < $array2[0]) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if ($array2[1] < $array1[0]) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
if ($array1[0] < $array2[0]) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if ($array2[0] < $array1[0]) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ 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->text('package_ids')->nullable()->comment('RD套餐ID');
|
||||
$table->text('real_pool_ids')->nullable()->comment('RD流量池ID');
|
||||
$table->text('remark')->nullable()->comment('流量池备注');
|
||||
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
|
||||
$table->timestamp('start_at')->nullable()->comment('开始时间');
|
||||
$table->timestamp('end_at')->nullable()->comment('结束时间');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
@ -54,20 +54,6 @@ 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');
|
||||
@ -75,8 +61,11 @@ class CreateFlowPoolTables extends Migration
|
||||
$table->text('minimum_settings')->nullable()->comment('套餐保底配置');
|
||||
$table->integer('first_month_price')->unsigned()->default(0)->comment('首月单价');
|
||||
$table->integer('other_month_price')->unsigned()->default(0)->comment('次月单价');
|
||||
$table->timestamp('start_at');
|
||||
$table->timestamp('end_at');
|
||||
$table->integer('gradient')->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('结束时间');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('pool_id');
|
||||
@ -88,10 +77,13 @@ class CreateFlowPoolTables extends Migration
|
||||
if (!Schema::hasTable('virtual_flow_pool_cards')) {
|
||||
Schema::create('virtual_flow_pool_cards', function (Blueprint $table) {
|
||||
$table->integer('pool_id')->unsigned()->default(0)->comment('流量池ID');
|
||||
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
|
||||
$table->bigInteger('sim')->unsigned()->default(0)->comment('SIM号');
|
||||
$table->comment('VD流量池卡关联表');
|
||||
|
||||
$table->primary(['pool_id', 'sim']);
|
||||
|
||||
$table->unique('sim');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -58,3 +58,12 @@ export function update(data, id) {
|
||||
export function destroy(data) {
|
||||
return service.post('api/virtual/flow-pools/destroy', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* [setting 流量池计费规则]
|
||||
* @param {[type]} data [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function setting(data) {
|
||||
return service.post('api/virtual/flow-pools/setting', data);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Color
|
||||
@primary-color : #2d8cf0;
|
||||
@info-color : #b3b3b3;
|
||||
@info-color : #2db7f5;
|
||||
@success-color : #19be6b;
|
||||
@processing-color : @primary-color;
|
||||
@warning-color : #ff9900;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,9 +16,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleComplete(array, value = '', key = 'name', indexKey = 'id') {
|
||||
console.log(1);
|
||||
console.log(value);
|
||||
|
||||
if (value === '') {
|
||||
return array;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
} from 'vuex';
|
||||
import { objectDot } from 'service/util';
|
||||
import default_head from 'images/head.png';
|
||||
import { getToken } from 'service/auth';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -35,6 +36,9 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
token: () => {
|
||||
return getToken();
|
||||
},
|
||||
...mapGetters(['apps_info', 'left_menu', 'top_menu', 'permissions_array', 'permissions_object', 'account', 'page_nodes', 'tagnavs', 'cache_page', 'breadcrumb'])
|
||||
},
|
||||
methods: {
|
||||
|
@ -49,7 +49,7 @@
|
||||
type="primary"
|
||||
v-if="this.status === 'wait'"
|
||||
:disabled="disabled"
|
||||
>下一步</Button>
|
||||
>{{ current ? '下一步' : '开始同步'}}</Button>
|
||||
<Button
|
||||
:loading="loading"
|
||||
@click="clear"
|
||||
|
@ -30,13 +30,13 @@ export default {
|
||||
},
|
||||
{
|
||||
'title': '同步企业',
|
||||
'content': '所有下级企业的数据',
|
||||
'content': '所有企业数据',
|
||||
'command': 'real:sync-company',
|
||||
'max': 10
|
||||
},
|
||||
{
|
||||
'title': '同步套餐',
|
||||
'content': '所有套餐的数据',
|
||||
'content': '所有套餐数据',
|
||||
'command': 'real:sync-package',
|
||||
'max': 25
|
||||
},
|
||||
|
@ -91,7 +91,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -82,7 +82,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -179,7 +179,7 @@
|
||||
<div class="ui-list">
|
||||
<div class="ui-list-title"></div>
|
||||
<div class="ui-list-content">
|
||||
<Button type="primary" class="btn w-80 umar-r10" icon="ios-create" :disabled="id?false:true" :loading="loading" @click="save">修改</Button>
|
||||
<Button type="primary" class="btn w-80 umar-r10" icon="md-create" :disabled="id?false:true" :loading="loading" @click="save">修改</Button>
|
||||
<Button type="primary" ghost class="btn w-80" @click="clear">重置</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -92,7 +92,7 @@ export default{
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -60,7 +60,7 @@ export default{
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -104,7 +104,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -101,7 +101,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -11,6 +11,22 @@
|
||||
<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>
|
||||
<DatePicker
|
||||
type="month"
|
||||
placeholder="请选择月份"
|
||||
:style="'width:' + listStyle.width"
|
||||
v-model.trim="params.start_at"
|
||||
></DatePicker>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="ui-list">
|
||||
<div class="ui-list-title">
|
||||
<span class="title-require">*</span>流量池名称:
|
||||
@ -39,6 +55,7 @@
|
||||
:disabled="data ? true : false"
|
||||
v-model="params.carrier_operator"
|
||||
:style="'width:' + listStyle.width"
|
||||
@on-change="selectCo"
|
||||
>
|
||||
<Option :value="0">联通</Option>
|
||||
<Option :value="1">移动</Option>
|
||||
@ -81,31 +98,15 @@
|
||||
</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-title">流量池编号:</div>
|
||||
<div class="ui-list-content">
|
||||
<Transfer
|
||||
:titles="['备选流量池编号', '已选流量池编号']"
|
||||
:list-style="listStyle"
|
||||
:data="reals"
|
||||
:data="realFilters"
|
||||
:target-keys="real_pool_ids"
|
||||
@on-change="transferRealFlowPools"
|
||||
filterable
|
||||
></Transfer>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="page-wrap">
|
||||
<ui-loading :show="page_loading.show"></ui-loading>
|
||||
<ui-loading :show="page_loading.show" :msg="page_loading.msg"></ui-loading>
|
||||
|
||||
<div class="page-handle-wrap">
|
||||
<ul class="handle-wraper bd-b">
|
||||
@ -103,6 +103,50 @@
|
||||
></ui-edit>
|
||||
|
||||
<ui-detail :data="detailObj.data" :show.sync="detailObj.show"></ui-detail>
|
||||
|
||||
<ui-setting
|
||||
:show.sync="settingObj.show"
|
||||
:data="settingObj.data"
|
||||
@add-success="index"
|
||||
@update-success="index(list_data.current_page)"
|
||||
></ui-setting>
|
||||
|
||||
<Modal v-model="addCardObj.show" title="添加流量卡" :mask-closable="false" :footer-hide="true">
|
||||
<div class="add-card-handle-wrap">
|
||||
<ul class="handle-wraper">
|
||||
<li class="f-l">
|
||||
<div class="text-exp">
|
||||
<b>请上传xls、xlsx、csv格式的表格文件</b>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="f-r">
|
||||
<div class="handle-item">
|
||||
<Button
|
||||
type="primary"
|
||||
icon="ios-download-outline"
|
||||
:to="CONFIG.url + '/storage/templates/add-cards.xls'"
|
||||
target="_blank"
|
||||
>下载导入模板</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<Upload
|
||||
type="drag"
|
||||
:action="CONFIG.url + '/api/virtual/flow-pools/add-cards?pool_id=' + addCardObj.pool_id"
|
||||
:format="['xls', 'xlsx', 'csv']"
|
||||
:on-success="addCardSuccess"
|
||||
:on-error="addCardError"
|
||||
:before-upload="addCardStart"
|
||||
:headers="{Authorization: 'Bearer ' + token}"
|
||||
>
|
||||
<div style="padding: 20px 0">
|
||||
<Icon type="ios-cloud-upload" size="52" class="primary-color"></Icon>
|
||||
<p>点击或拖拽文件上上传</p>
|
||||
</div>
|
||||
</Upload>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -8,7 +8,7 @@ export default {
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
default () {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -20,9 +20,8 @@ export default {
|
||||
height: '300px'
|
||||
},
|
||||
companies: [],
|
||||
packages: [],
|
||||
package_ids: [],
|
||||
reals: [],
|
||||
realFilters: [],
|
||||
real_pool_ids: [],
|
||||
my_show: false,
|
||||
isUpdate: false,
|
||||
@ -32,10 +31,10 @@ export default {
|
||||
carrier_operator: '',
|
||||
shared: '',
|
||||
company_id: '',
|
||||
package_ids: [],
|
||||
real_pool_ids: [],
|
||||
status: 0,
|
||||
remark: ''
|
||||
remark: '',
|
||||
start_at: this.moment().format('YYYY-MM')
|
||||
}
|
||||
};
|
||||
},
|
||||
@ -50,11 +49,17 @@ export default {
|
||||
return {
|
||||
'key': item.id,
|
||||
'label': item.sn + ' - ' + item.name,
|
||||
'disabled': false
|
||||
'disabled': false,
|
||||
'virtual_pool_id': item.virtual_pool_id,
|
||||
'carrier_operator': item.carrier_operator
|
||||
};
|
||||
});
|
||||
|
||||
this.filterReals();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.filterReals();
|
||||
}
|
||||
|
||||
this.initCompleteCompanies().then(companies => {
|
||||
@ -63,18 +68,6 @@ export default {
|
||||
});
|
||||
});
|
||||
|
||||
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) {
|
||||
@ -82,13 +75,32 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
this.package_ids = this.data.package_ids;
|
||||
this.real_pool_ids = this.data.real_pool_ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterReals() {
|
||||
this.realFilters = this.reals.filter(item => {
|
||||
if (this.params.carrier_operator !== '' && this.params.carrier_operator !== item.carrier_operator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.virtual_pool_id === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.data && item.virtual_pool_id === this.data.id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
selectCo() {
|
||||
this.filterReals();
|
||||
},
|
||||
ok() {
|
||||
if (this.params.company_id === '') {
|
||||
this.$Message.info('请选择企业');
|
||||
@ -105,6 +117,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.params.start_at = this.moment(this.params.start_at).format('YYYY-MM');
|
||||
|
||||
if (this.data) {
|
||||
// 编辑
|
||||
API.update(this.params, this.data.id).then(res => {
|
||||
@ -141,21 +155,18 @@ export default {
|
||||
for (let k in this.params) {
|
||||
if (k == 'status') {
|
||||
this.params[k] = 0;
|
||||
} else if (k == 'real_pool_ids' || k == 'package_ids') {
|
||||
} else if (k == 'real_pool_ids') {
|
||||
this.params[k] = [];
|
||||
} else if (k == 'start_at') {
|
||||
this.params[k] = this.moment().format('YYYY-MM');
|
||||
} else {
|
||||
this.params[k] = '';
|
||||
}
|
||||
}
|
||||
|
||||
this.my_show = false;
|
||||
this.package_ids = [];
|
||||
this.real_pool_ids = [];
|
||||
},
|
||||
transferPackages(ids) {
|
||||
this.package_ids = ids;
|
||||
this.params.package_ids = ids;
|
||||
},
|
||||
transferRealFlowPools(ids) {
|
||||
this.real_pool_ids = ids;
|
||||
this.params.real_pool_ids = ids;
|
||||
|
@ -3,7 +3,8 @@ export default {
|
||||
name: 'FlowPools',
|
||||
components: {
|
||||
UiEdit: resolve => require(['views/virtual/flow_pools/edit'], resolve),
|
||||
UiDetail: resolve => require(['views/virtual/flow_pools/detail'], resolve)
|
||||
UiDetail: resolve => require(['views/virtual/flow_pools/detail'], resolve),
|
||||
UiSetting: resolve => require(['views/virtual/flow_pools/setting'], resolve)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -19,10 +20,18 @@ export default {
|
||||
show: false,
|
||||
data: null
|
||||
},
|
||||
settingObj: {
|
||||
show: false,
|
||||
data: null
|
||||
},
|
||||
detailObj: {
|
||||
show: false,
|
||||
data: null
|
||||
},
|
||||
addCardObj: {
|
||||
show: false,
|
||||
pool_id: 0
|
||||
},
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
@ -30,7 +39,7 @@ export default {
|
||||
{
|
||||
title: 'ID',
|
||||
key: 'id',
|
||||
width: 80
|
||||
width: 75
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
@ -40,12 +49,12 @@ export default {
|
||||
{
|
||||
title: '运营商',
|
||||
key: 'carrier_operator_name',
|
||||
width: 110
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '共享类型',
|
||||
key: 'shared_name',
|
||||
width: 110
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '客户名称',
|
||||
@ -86,7 +95,11 @@ export default {
|
||||
title: '状态',
|
||||
key: '',
|
||||
width: 100,
|
||||
render: (h, { row, column, index }) => {
|
||||
render: (h, {
|
||||
row,
|
||||
column,
|
||||
index
|
||||
}) => {
|
||||
return h('Button', {
|
||||
props: {
|
||||
type: row.status ? 'error' : 'primary',
|
||||
@ -103,7 +116,7 @@ export default {
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 110,
|
||||
width: 400,
|
||||
render: (h, {
|
||||
row,
|
||||
column,
|
||||
@ -112,7 +125,11 @@ export default {
|
||||
let html = [];
|
||||
|
||||
if (row.deleted_at) {
|
||||
return h('Tag', { props: { color: 'default' } }, '该企业已被删除');
|
||||
return h('Tag', {
|
||||
props: {
|
||||
color: 'default'
|
||||
}
|
||||
}, '该流量池已被删除');
|
||||
}
|
||||
|
||||
if (this.haveJurisdiction('show')) {
|
||||
@ -141,7 +158,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
@ -152,6 +169,41 @@ export default {
|
||||
}, '编辑'));
|
||||
}
|
||||
|
||||
if (this.haveJurisdiction('update')) {
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
type: 'info',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'md-card'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
click: (event) => {
|
||||
this.addCardObj.show = true;
|
||||
this.addCardObj.pool_id = row.id;
|
||||
}
|
||||
}
|
||||
}, '添加卡'));
|
||||
}
|
||||
|
||||
if (this.haveJurisdiction('update')) {
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
type: 'warning',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'logo-yen'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
click: (event) => {
|
||||
this.openSetting(true, row);
|
||||
}
|
||||
}
|
||||
}, '计费规则'));
|
||||
}
|
||||
|
||||
if (this.haveJurisdiction('destroy')) {
|
||||
html.push(h('Button', {
|
||||
props: {
|
||||
@ -200,7 +252,9 @@ export default {
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
index(page = 1) {
|
||||
let data = this.searchDataHandle({}, { page }, this.params());
|
||||
let data = this.searchDataHandle({}, {
|
||||
page, orderBy: 'id', sortedBy: 'asc'
|
||||
}, this.params());
|
||||
this.isShowLoading(true);
|
||||
API.index(data).then(res => {
|
||||
this.isShowLoading(false);
|
||||
@ -238,6 +292,17 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* [openSetting 打开编辑弹窗]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
openSetting(bool, data = null) {
|
||||
this.settingObj = {
|
||||
show: bool,
|
||||
data: data
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* [request 刷新]
|
||||
* @return {[type]} [description]
|
||||
@ -263,6 +328,22 @@ export default {
|
||||
}
|
||||
|
||||
this.index(1);
|
||||
},
|
||||
addCardSuccess(res) {
|
||||
this.$Message.success(res.message);
|
||||
this.page_loading.show = false;
|
||||
this.page_loading.msg = '加载中...';
|
||||
this.index(this.list_data.current_page);
|
||||
},
|
||||
addCardError(error, res, files) {
|
||||
this.$Message.error(res.message);
|
||||
this.page_loading.show = false;
|
||||
this.page_loading.msg = '加载中...';
|
||||
},
|
||||
addCardStart() {
|
||||
this.addCardObj.show = false;
|
||||
this.page_loading.show = true;
|
||||
this.page_loading.msg = '数据处理中...';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
170
frontend/src/views/virtual/flow_pools/js/setting.js
Normal file
170
frontend/src/views/virtual/flow_pools/js/setting.js
Normal file
@ -0,0 +1,170 @@
|
||||
import * as API from 'api/virtual/flow_pools';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
my_show: false,
|
||||
loading: false,
|
||||
settings: [],
|
||||
params: {},
|
||||
start_at: this.moment('2000-01-01 00:00:00').format('YYYY-MM'),
|
||||
end_at: this.moment('3000-01-01 23:59:59').format('YYYY-MM'),
|
||||
monthOptions: {
|
||||
shortcuts: [
|
||||
{
|
||||
text: '最早',
|
||||
value: () => {
|
||||
return this.start_at;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '至今',
|
||||
value: () => {
|
||||
return this.end_at;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '本月',
|
||||
value: () => {
|
||||
return this.moment().format('YYYY-MM');
|
||||
}
|
||||
}
|
||||
],
|
||||
disabledDate(date) {
|
||||
return date && (date.valueOf() < this.start_at || date.valueOf() > this.end_at);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show(bool) {
|
||||
this.my_show = bool;
|
||||
if (bool) {
|
||||
this.settings = this.data.settings;
|
||||
if (this.data.settings.length) {
|
||||
this.set(this.data.settings[0]['id']);
|
||||
} else {
|
||||
this.set(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
ok() {
|
||||
if (this.params.pool_id === '') {
|
||||
this.$Message.info('参数错误');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.params.start_at === '') {
|
||||
this.$Message.info('请选择开始时间');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.params.end_at === '') {
|
||||
this.$Message.info('请选择结束时间');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.params.gradient < 1) {
|
||||
this.$Message.info('梯度必须大于等于1');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.params.gradient_unit === '') {
|
||||
this.$Message.info('请选择梯度单位');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in this.params.minimum_settings) {
|
||||
let minimum_setting = this.params.minimum_settings[key];
|
||||
|
||||
if (minimum_setting.flows === 0 && minimum_setting.price) {
|
||||
this.$Message.info('保底流量配置不正确');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.params.start_at = this.moment(this.params.start_at).format('YYYY-MM');
|
||||
this.params.end_at = this.moment(this.params.end_at).format('YYYY-MM');
|
||||
|
||||
if (this.params.id) {
|
||||
// 编辑
|
||||
API.setting(this.params).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.setting(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() {
|
||||
this.params = {};
|
||||
|
||||
this.my_show = false;
|
||||
},
|
||||
set(id) {
|
||||
if (id) {
|
||||
this.params = this.settings.filter(item => {
|
||||
return item.id == id;
|
||||
})[0];
|
||||
|
||||
this.params.id = id;
|
||||
} else {
|
||||
let minimum_settings = [];
|
||||
|
||||
this.data.packages.map(item => {
|
||||
minimum_settings.push({
|
||||
package_id: item.package_id,
|
||||
package_name: item.package_name,
|
||||
flows: 0,
|
||||
price: 0
|
||||
});
|
||||
});
|
||||
|
||||
this.params = {
|
||||
pool_id: this.data.id,
|
||||
start_at: this.data.settings.length ? this.moment().format('YYYY-MM') : this.start_at,
|
||||
end_at: this.data.settings.length ? this.moment().format('YYYY-MM') : this.end_at,
|
||||
first_month_price: 0,
|
||||
other_month_price: 0,
|
||||
gradient: 0,
|
||||
gradient_unit: 0,
|
||||
minimum_settings: minimum_settings
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
137
frontend/src/views/virtual/flow_pools/setting.vue
Normal file
137
frontend/src/views/virtual/flow_pools/setting.vue
Normal file
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<Drawer
|
||||
:closable="false"
|
||||
:mask-closable="false"
|
||||
:title="'计费规则'"
|
||||
@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>
|
||||
<Row>
|
||||
<Col span="6">
|
||||
<Timeline>
|
||||
<div v-for="(item, index) in settings" :key="index">
|
||||
<TimelineItem>
|
||||
<p class="time">{{moment(item.end_at).format('YYYY-MM')}}</p>
|
||||
</TimelineItem>
|
||||
|
||||
<TimelineItem>
|
||||
<span slot="dot"></span>
|
||||
<Button type="text" shape="circle" icon="md-build" @click="set(item.id)">修改规则</Button>
|
||||
</TimelineItem>
|
||||
|
||||
<TimelineItem>
|
||||
<p class="time">{{moment(item.start_at).format('YYYY-MM')}}</p>
|
||||
</TimelineItem>
|
||||
</div>
|
||||
|
||||
<TimelineItem>
|
||||
<span slot="dot"></span>
|
||||
<Button type="text" shape="circle" icon="md-add" @click="set(0)">添加规则</Button>
|
||||
</TimelineItem>
|
||||
</Timeline>
|
||||
</Col>
|
||||
<Col span="18">
|
||||
<Form :model="params" :label-width="100">
|
||||
<FormItem label="起止时间:" required>
|
||||
<Col span="11">
|
||||
<FormItem prop="start_at">
|
||||
<DatePicker
|
||||
type="month"
|
||||
placeholder="请选择月份"
|
||||
v-model="params.start_at"
|
||||
:options="monthOptions"
|
||||
:disabled="Boolean(params.id)"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="2">
|
||||
<span class="ta-c lh-32 uinn-lr10">至</span>
|
||||
</Col>
|
||||
<Col span="11">
|
||||
<FormItem prop="end_at">
|
||||
<DatePicker
|
||||
type="month"
|
||||
placeholder="请选择月份"
|
||||
v-model="params.end_at"
|
||||
:options="monthOptions"
|
||||
:disabled="Boolean(params.id)"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
</Col>
|
||||
</FormItem>
|
||||
<FormItem label="超出流量:" :label-width="100" required>
|
||||
<Col span="12">
|
||||
<FormItem prop="first_month_price" label="首月单价" :label-width="80">
|
||||
<InputNumber
|
||||
:max="99999"
|
||||
:min="0"
|
||||
v-model="params.first_month_price"
|
||||
:style="'width:110px'"
|
||||
></InputNumber>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="12">
|
||||
<FormItem prop="other_month_price" label="次月单价" :label-width="80">
|
||||
<InputNumber
|
||||
:max="99999"
|
||||
:min="0"
|
||||
v-model="params.other_month_price"
|
||||
:style="'width:110px'"
|
||||
></InputNumber>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="12">
|
||||
<FormItem prop="gradient" label="梯度" :label-width="80">
|
||||
<InputNumber
|
||||
:max="99999"
|
||||
:min="1"
|
||||
v-model="params.gradient"
|
||||
:style="'width:110px'"
|
||||
></InputNumber>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="12">
|
||||
<FormItem prop="gradient_unit" label="梯度单位" :label-width="80">
|
||||
<Select v-model="params.gradient_unit" :style="'width:110px'">
|
||||
<Option :value="0">M</Option>
|
||||
<Option :value="1">G</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Col>
|
||||
</FormItem>
|
||||
<FormItem label="保底流量:" :label-width="100">
|
||||
<Row>
|
||||
<Col span="8">套餐名称</Col>
|
||||
<Col span="8">月保底流量(M/月)</Col>
|
||||
<Col span="8">月保底价格(元)</Col>
|
||||
</Row>
|
||||
|
||||
<Row v-for="(item, index) in params.minimum_settings" :key="index">
|
||||
<Col span="8">{{item.package_name}}</Col>
|
||||
<Col span="8">
|
||||
<FormItem>
|
||||
<InputNumber :max="99999" :min="0" v-model="params.minimum_settings[index]['flows']"></InputNumber>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="8">
|
||||
<FormItem>
|
||||
<InputNumber :max="99999" :min="0" v-model="params.minimum_settings[index]['price']"></InputNumber>
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button @click="clear" class="w-80 umar-r5" ghost type="primary">取消</Button>
|
||||
<Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Drawer>
|
||||
</template>
|
||||
|
||||
<script src="./js/setting.js"></script>
|
@ -128,7 +128,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -102,7 +102,7 @@ export default {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
icon: 'ios-create'
|
||||
icon: 'md-create'
|
||||
},
|
||||
class: ['btn'],
|
||||
on: {
|
||||
|
@ -140,7 +140,7 @@ INSERT INTO vd.virtual_orders ("type", sn, "source", company_id, package_id, pro
|
||||
logs
|
||||
GROUP BY
|
||||
order_type, order_sn
|
||||
) ON CONFLICT (sn, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO NOTHING;
|
||||
) ON CONFLICT (sn, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET counts = excluded.counts, total_price = excluded.total_price, custom_price = excluded.custom_price;
|
||||
|
||||
-- 第五步:同步订单详情数据
|
||||
INSERT INTO vd.virtual_order_cards ("type", sim, order_id, company_id, package_id, counts, unit_price, service_start_at, service_end_at, created_at, updated_at)
|
||||
@ -162,7 +162,7 @@ INSERT INTO vd.virtual_order_cards ("type", sim, order_id, company_id, package_i
|
||||
LEFT JOIN vd.virtual_orders ON virtual_orders.sn = logs.order_sn
|
||||
WHERE
|
||||
logs.order_type = 0
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET counts = excluded.counts, service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
|
||||
INSERT INTO vd.virtual_order_renewal_cards ("type", sim, order_id, company_id, package_id, counts, unit_price, service_start_at, service_end_at, created_at, updated_at)
|
||||
(
|
||||
@ -183,7 +183,7 @@ INSERT INTO vd.virtual_order_renewal_cards ("type", sim, order_id, company_id, p
|
||||
LEFT JOIN vd.virtual_orders ON virtual_orders.sn = logs.order_sn
|
||||
WHERE
|
||||
logs.order_type = 1
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET counts = excluded.counts, service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
|
||||
INSERT INTO vd.virtual_order_renewal_package_cards ("type", sim, order_id, company_id, package_id, counts, unit_price, service_start_at, service_end_at, created_at, updated_at)
|
||||
(
|
||||
@ -204,7 +204,7 @@ INSERT INTO vd.virtual_order_renewal_package_cards ("type", sim, order_id, compa
|
||||
LEFT JOIN vd.virtual_orders ON virtual_orders.sn = logs.order_sn
|
||||
WHERE
|
||||
logs.order_type = 2
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET counts = excluded.counts, service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
|
||||
INSERT INTO vd.virtual_order_flows_package_cards ("type", sim, order_id, company_id, package_id, counts, unit_price, service_start_at, service_end_at, created_at, updated_at)
|
||||
(
|
||||
@ -225,5 +225,5 @@ INSERT INTO vd.virtual_order_flows_package_cards ("type", sim, order_id, company
|
||||
LEFT JOIN vd.virtual_orders ON virtual_orders.sn = logs.order_sn
|
||||
WHERE
|
||||
logs.order_type = 3
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
) ON CONFLICT (sim, order_id, COALESCE(deleted_at::TIMESTAMP, '1970-01-01 08:00:00'::TIMESTAMP)) DO UPDATE SET counts = excluded.counts, service_start_at = excluded.service_start_at, service_end_at = excluded.service_end_at;
|
||||
|
||||
|
BIN
storage/app/public/templates/add-cards.xls
Normal file
BIN
storage/app/public/templates/add-cards.xls
Normal file
Binary file not shown.
@ -24,7 +24,7 @@ function call($command)
|
||||
Artisan::queue($command, [
|
||||
'month' => $datetime->format('Y-m'),
|
||||
]);
|
||||
|
||||
|
||||
$datetime->addMonth();
|
||||
|
||||
if ($datetime > Carbon::now()) {
|
||||
|
@ -1,17 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use function App\account_avatar;
|
||||
|
||||
require_once realpath(dirname(__FILE__) . '/TestCase.php');
|
||||
|
||||
Schema::table('virtual_companies', function ($table) {
|
||||
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
|
||||
});
|
||||
|
||||
Schema::table('virtual_packages', function ($table) {
|
||||
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
|
||||
});
|
||||
|
||||
Schema::table('virtual_products', function ($table) {
|
||||
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
|
||||
});
|
||||
|
79
tests/MysqlTest.php
Normal file
79
tests/MysqlTest.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
require_once realpath(dirname(__FILE__) . '/TestCase.php');
|
||||
|
||||
$sql = "SELECT
|
||||
id,
|
||||
custom_no ,
|
||||
company,
|
||||
content ,
|
||||
valid_start_time,
|
||||
valid_end_time,
|
||||
create_time
|
||||
FROM
|
||||
ckb_custom_handle_log
|
||||
WHERE
|
||||
type = 11
|
||||
AND custom_no IN ( SELECT custom_no FROM ckb_custom_handle_log WHERE type = 11 GROUP BY custom_no, valid_start_time HAVING count( * ) > 1 )
|
||||
ORDER BY
|
||||
custom_no;";
|
||||
|
||||
$res = DB::connection('vd_old')->select($sql);
|
||||
|
||||
$array = [];
|
||||
|
||||
foreach ($res as &$item) {
|
||||
$item = (array)$item;
|
||||
}
|
||||
|
||||
$res = array_groupBy($res, 'custom_no');
|
||||
|
||||
foreach ($res as $custom_no => $group) {
|
||||
$group = array_groupBy($group, 'valid_start_time');
|
||||
|
||||
foreach ($group as $arr) {
|
||||
if (count($arr) < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = $arr[0];
|
||||
|
||||
$rows = DB::connection('vd_old')->table('ckb_custom_handle_log')
|
||||
->where('company', $item['company'])
|
||||
->where('content', $item['content'])
|
||||
->whereNotIn('custom_no', array_pluck($array, 'custom_no'))
|
||||
->groupBy('custom_no')
|
||||
->havingRaw(DB::raw("MAX(valid_end_time) < {$item['valid_start_time']}"))
|
||||
->orderBy('valid_end_time', 'desc')
|
||||
->limit(count($arr) - 1)
|
||||
->get();
|
||||
|
||||
|
||||
foreach ($arr as $key => $item) {
|
||||
if ($key === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$rows[$key - 1]) {
|
||||
throw new \Exception('未找到卡 #:'. $item['custom_no']);
|
||||
}
|
||||
|
||||
echo $key . ',' . $item['custom_no'] . ',' . date('Y-m-d H:i:s', $item['valid_start_time']) . ',' . $rows[$key - 1]->custom_no . PHP_EOL;
|
||||
|
||||
$array[] = [
|
||||
'id' => $item['id'],
|
||||
'custom_no' => $rows[$key - 1]->custom_no,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($array) {
|
||||
foreach ($array as $item) {
|
||||
DB::connection('vd_old')->table('ckb_custom_handle_log')->where('id', $item['id'])->update(['custom_no' => $item['custom_no']]);
|
||||
}
|
||||
});
|
||||
|
||||
dd($array);
|
Loading…
x
Reference in New Issue
Block a user