属性管理
This commit is contained in:
parent
94450bafd2
commit
da88e826c9
@ -41,7 +41,7 @@ class AutoActivate extends Command
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
$sql = "WITH sim_array AS (
|
$sql = "WITH sim_array AS (
|
||||||
SELECT sim FROM virtual_order_cards WHERE created_at >= '%s' AND created_at <= '%s' AND service_start_at IS NULL
|
SELECT sim FROM virtual_order_cards WHERE created_at >= '%s' AND created_at <= '%s' AND service_start_at IS NULL ORDER BY created_at DESC
|
||||||
), activate_updates AS (
|
), activate_updates AS (
|
||||||
UPDATE cards SET virtual_activated_at='%s' WHERE sim IN (SELECT * FROM sim_array) AND virtual_activated_at IS NULL
|
UPDATE cards SET virtual_activated_at='%s' WHERE sim IN (SELECT * FROM sim_array) AND virtual_activated_at IS NULL
|
||||||
)
|
)
|
||||||
|
83
app/Domains/Virtual/Http/Controllers/PropertyController.php
Normal file
83
app/Domains/Virtual/Http/Controllers/PropertyController.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Domains\Virtual\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Core\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Domains\Virtual\Services\PropertyService;
|
||||||
|
|
||||||
|
class PropertyController extends Controller
|
||||||
|
{
|
||||||
|
protected $request;
|
||||||
|
protected $propertyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,自动注入.
|
||||||
|
*/
|
||||||
|
public function __construct(Request $request, PropertyService $propertyService)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
$this->propertyService = $propertyService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function settings()
|
||||||
|
{
|
||||||
|
if ($this->request->isMethod('POST')) {
|
||||||
|
$values = $this->request->get('data');
|
||||||
|
$res = $this->propertyService->settingsStore($values);
|
||||||
|
return res($res, '修改成功');
|
||||||
|
} else {
|
||||||
|
$conditions = $this->request->all();
|
||||||
|
$res = $this->propertyService->settings($conditions);
|
||||||
|
return res($res, '配置分类', 201);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$conditions = $this->request->all();
|
||||||
|
$list = $this->propertyService->index($conditions);
|
||||||
|
return res($list, '客户套餐属性配置列表', 201);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
$values = $this->request->get('data');
|
||||||
|
$res = $this->propertyService->store($values);
|
||||||
|
return res($res, '修改成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function export()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function import()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
62
app/Domains/Virtual/Repositories/PropertyRepository.php
Normal file
62
app/Domains/Virtual/Repositories/PropertyRepository.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Domains\Virtual\Repositories;
|
||||||
|
|
||||||
|
use App\Core\Repository;
|
||||||
|
use App\Models\Virtual\Property as Model;
|
||||||
|
|
||||||
|
class PropertyRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 是否关闭缓存
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $cacheSkip = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启数据转化
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $needTransform = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fieldSearchable = [
|
||||||
|
'id' => '=',
|
||||||
|
'created_at' => 'like',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function model() {
|
||||||
|
return Model::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据格式化
|
||||||
|
*
|
||||||
|
* @param mixed $result
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function transform($model)
|
||||||
|
{
|
||||||
|
return $model->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询条件
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function withConditions(array $conditions = [])
|
||||||
|
{
|
||||||
|
if (isset($conditions['id'])) {
|
||||||
|
$conditions['id'] = array_wrap($conditions['id']);
|
||||||
|
$this->model = $this->model->whereIn('id', $conditions['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Domains\Virtual\Repositories;
|
||||||
|
|
||||||
|
use App\Core\Repository;
|
||||||
|
use App\Models\Virtual\PropertySetting as Model;
|
||||||
|
|
||||||
|
class PropertySettingRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 是否关闭缓存
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $cacheSkip = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启数据转化
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $needTransform = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fieldSearchable = [
|
||||||
|
'id' => '=',
|
||||||
|
'created_at' => 'like',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function model()
|
||||||
|
{
|
||||||
|
return Model::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据格式化
|
||||||
|
*
|
||||||
|
* @param mixed $result
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function transform($model)
|
||||||
|
{
|
||||||
|
return $model->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询条件
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function withConditions(array $conditions = [])
|
||||||
|
{
|
||||||
|
if (isset($conditions['id'])) {
|
||||||
|
$conditions['id'] = array_wrap($conditions['id']);
|
||||||
|
$this->model = $this->model->whereIn('id', $conditions['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAll($force = false)
|
||||||
|
{
|
||||||
|
if ($force) {
|
||||||
|
$this->forgetCached();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->get()->pluck('value', 'name');
|
||||||
|
}
|
||||||
|
}
|
@ -36,13 +36,20 @@ $router->group(['prefix' => 'virtual', 'as' => 'virtual', 'middleware' => ['admi
|
|||||||
// $router->post('/company/addresses/update/{id}', ['as' => 'company.addresses.update', 'uses' => 'CompanyAddressController@update']);
|
// $router->post('/company/addresses/update/{id}', ['as' => 'company.addresses.update', 'uses' => 'CompanyAddressController@update']);
|
||||||
// $router->post('/company/addresses/destroy', ['as' => 'company.addresses.destroy', 'uses' => 'CompanyAddressController@destroy']);
|
// $router->post('/company/addresses/destroy', ['as' => 'company.addresses.destroy', 'uses' => 'CompanyAddressController@destroy']);
|
||||||
|
|
||||||
// 企业定价管理
|
// 定价管理
|
||||||
$router->get('/products/index', ['as' => 'products.index', 'uses' => 'ProductController@index']);
|
$router->get('/products/index', ['as' => 'products.index', 'uses' => 'ProductController@index']);
|
||||||
$router->get('/products/history', ['as' => 'products.history', 'uses' => 'ProductController@history']);
|
$router->get('/products/history', ['as' => 'products.history', 'uses' => 'ProductController@history']);
|
||||||
$router->post('/products/create', ['as' => 'products.create', 'uses' => 'ProductController@create']);
|
$router->post('/products/create', ['as' => 'products.create', 'uses' => 'ProductController@create']);
|
||||||
$router->post('/products/update/{id}', ['as' => 'products.update', 'uses' => 'ProductController@update']);
|
$router->post('/products/update/{id}', ['as' => 'products.update', 'uses' => 'ProductController@update']);
|
||||||
$router->post('/products/destroy', ['as' => 'products.destroy', 'uses' => 'ProductController@destroy']);
|
$router->post('/products/destroy', ['as' => 'products.destroy', 'uses' => 'ProductController@destroy']);
|
||||||
|
|
||||||
|
// 属性管理
|
||||||
|
$router->addRoute(['GET', 'POST'], '/properties/settings', ['as' => 'properties.settings', 'uses' => 'PropertyController@settings']);
|
||||||
|
$router->get('/properties/index', ['as' => 'properties.index', 'uses' => 'PropertyController@index']);
|
||||||
|
$router->post('/properties/store', ['as' => 'properties.store', 'uses' => 'PropertyController@store']);
|
||||||
|
$router->get('/properties/export', ['as' => 'properties.export', 'uses' => 'PropertyController@export']);
|
||||||
|
$router->post('/properties/import', ['as' => 'properties.import', 'uses' => 'PropertyController@import']);
|
||||||
|
|
||||||
// 订单管理
|
// 订单管理
|
||||||
$router->get('/orders/index', ['as' => 'orders.index', 'uses' => 'OrderController@index']);
|
$router->get('/orders/index', ['as' => 'orders.index', 'uses' => 'OrderController@index']);
|
||||||
$router->get('/orders/show/{id}', ['as' => 'orders.show', 'uses' => 'OrderController@show']);
|
$router->get('/orders/show/{id}', ['as' => 'orders.show', 'uses' => 'OrderController@show']);
|
||||||
|
@ -154,7 +154,7 @@ class PackageService extends Service
|
|||||||
if (!self::$packages) {
|
if (!self::$packages) {
|
||||||
self::$packages = app(PackageRepository::class)
|
self::$packages = app(PackageRepository::class)
|
||||||
->select(['id', 'type', 'sn', 'name', 'carrier_operator', 'flows', 'service_months', 'status'])
|
->select(['id', 'type', 'sn', 'name', 'carrier_operator', 'flows', 'service_months', 'status'])
|
||||||
->withTrashed()->get()->keyBy('id');
|
->withTrashed()->get()->keyBy('id')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$packages[$id];
|
return self::$packages[$id];
|
||||||
|
304
app/Domains/Virtual/Services/PropertyService.php
Normal file
304
app/Domains/Virtual/Services/PropertyService.php
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Domains\Virtual\Services;
|
||||||
|
|
||||||
|
use App\Dicts;
|
||||||
|
use App\Core\Service;
|
||||||
|
use App\Exceptions\NotExistException;
|
||||||
|
use App\Exceptions\NotAllowedException;
|
||||||
|
use App\Models\Virtual\PropertySetting;
|
||||||
|
use App\Exceptions\InvalidArgumentException;
|
||||||
|
use App\Domains\Virtual\Repositories\ProductRepository;
|
||||||
|
use App\Domains\Virtual\Repositories\PropertyRepository;
|
||||||
|
use App\Domains\Virtual\Repositories\PropertySettingRepository;
|
||||||
|
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
|
||||||
|
|
||||||
|
class PropertyService extends Service
|
||||||
|
{
|
||||||
|
protected $productRepository;
|
||||||
|
protected $propertyRepository;
|
||||||
|
protected $propertySettingRepository;
|
||||||
|
|
||||||
|
public static $property_types = [
|
||||||
|
'product' => '产品类型',
|
||||||
|
'vehicle' => '车辆类型',
|
||||||
|
'commercial_vehicle' => '商用车分类',
|
||||||
|
'company' => '公司类型',
|
||||||
|
'platform' => '平台/API类型',
|
||||||
|
'customer' => '客户类型',
|
||||||
|
'package' => '套餐分类',
|
||||||
|
'province' => '省份设置',
|
||||||
|
'package_type' => '套餐类型'
|
||||||
|
];
|
||||||
|
|
||||||
|
public static $default = [
|
||||||
|
'product' => '',
|
||||||
|
'vehicle' => '',
|
||||||
|
'commercial_vehicle' => '',
|
||||||
|
'company' => '',
|
||||||
|
'platform' => '',
|
||||||
|
'customer' => '',
|
||||||
|
'package' => '',
|
||||||
|
'province' => null,
|
||||||
|
'province_status' => 0,
|
||||||
|
'created_at' => null,
|
||||||
|
'updated_at' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(ProductRepository $productRepository, PropertyRepository $propertyRepository, PropertySettingRepository $propertySettingRepository)
|
||||||
|
{
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
$this->propertyRepository = $propertyRepository;
|
||||||
|
$this->propertySettingRepository = $propertySettingRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置设置查看
|
||||||
|
*
|
||||||
|
* @param array $conditions
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function settings($conditions = [])
|
||||||
|
{
|
||||||
|
$settings = $this->propertySettingRepository->getAll();
|
||||||
|
|
||||||
|
$products = $settings['product'];
|
||||||
|
|
||||||
|
foreach ($settings as $key => $setting) {
|
||||||
|
if ($setting['name'] === 'package') {
|
||||||
|
$values = $setting['value'];
|
||||||
|
foreach ($values as $k => $value) {
|
||||||
|
foreach ($value as $i => $v) {
|
||||||
|
if (!in_array($v, $products)) {
|
||||||
|
unset($settings[$key]['value'][$k][$i]);
|
||||||
|
$settings[$key]['value'][$k] = array_values($settings[$key]['value'][$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($conditions['names']) {
|
||||||
|
$conditions['names'] = array_wrap($conditions['names']);
|
||||||
|
|
||||||
|
$settings = array_where($settings, function ($value) use ($conditions) {
|
||||||
|
return in_array($value['name'], $conditions['names']);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置设置写入
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function settingsStore(array $values)
|
||||||
|
{
|
||||||
|
$settings = $this->propertySettingRepository->getAll();
|
||||||
|
|
||||||
|
if (isset($values['product'])) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
if (!in_array($key, array_keys(self::$property_types))) {
|
||||||
|
throw new NotExistException("分类{$key}不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($key !== 'province' && $key !== 'package') {
|
||||||
|
$value = array_values(array_unique(array_merge($settings[$key] ?: [], $value)));
|
||||||
|
$value = array_map(function ($item) {
|
||||||
|
return is_string($item) ? trim($item) : $item;
|
||||||
|
}, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$values[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($values['package'])) {
|
||||||
|
$packages = $values['package'];
|
||||||
|
$products = $values['product'];
|
||||||
|
foreach ($packages as $k => $v) {
|
||||||
|
if (!is_array($v)) {
|
||||||
|
throw new InvalidArgumentException('传入的产品参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($v as $m) {
|
||||||
|
if (!in_array($m, $products)) {
|
||||||
|
throw new NotExistException("产品({$m})未配置或已删除");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($packages as $i => $j) {
|
||||||
|
if ($i !== $k && in_array($m, $j)) {
|
||||||
|
throw new NotAllowedException('一个产品仅能归属一个套餐');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$data[] = [
|
||||||
|
'name' => $key,
|
||||||
|
'value' => json_encode($value, 256),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertySetting::upsert($data, 'name');
|
||||||
|
|
||||||
|
$this->propertySettingRepository->forgetCached();
|
||||||
|
|
||||||
|
$settings = $this->propertySettingRepository->getAll();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户套餐配置列表
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function index($conditions = [])
|
||||||
|
{
|
||||||
|
$product = $this->productRepository->whereHas('package', function ($query) {
|
||||||
|
$query->whereNull('deleted_at');
|
||||||
|
})->whereHas('company', function ($query) {
|
||||||
|
$query->whereNull('deleted_at');
|
||||||
|
})->withConditions($conditions)->applyConditions()->get();
|
||||||
|
|
||||||
|
$properties = $this->propertyRepository->whereHas('package', function ($query) {
|
||||||
|
$query->whereNull('deleted_at');
|
||||||
|
})->whereHas('company', function ($query) {
|
||||||
|
$query->whereNull('deleted_at');
|
||||||
|
})->withConditions($conditions)->applyConditions()->get()->keyBy(function ($item) {
|
||||||
|
return $item->company_id . '_' . $item->package_id;
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$sells = app(OrderCardPartitionRepository::class)->selectRaw('company_id, package_id, count(*) as counts')
|
||||||
|
->where('type', 0)->groupBy(['company_id', 'package_id'])->get()->keyBy(function ($item) {
|
||||||
|
return $item->company_id . '_' . $item->package_id;
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
$carrierOperators = app(Dicts::class)->get('carrier_operator');
|
||||||
|
|
||||||
|
$list = $product->map(function ($item) use ($properties, $sells, $carrierOperators) {
|
||||||
|
$item = $item->toArray();
|
||||||
|
$package = PackageService::load($item['package_id']);
|
||||||
|
$item['company_name'] = CompanyService::load($item['company_id'])['name'] ?? '';
|
||||||
|
$item['package_name'] = $package['name'] ?? '';
|
||||||
|
$item['flows'] = $package['flows'] ?? 0;
|
||||||
|
$item['carrier_operator'] = $package['carrier_operator'];
|
||||||
|
$item['carrier_operator_name'] = $carrierOperators[$item['carrier_operator']] ?? '未知';
|
||||||
|
$property = $properties[$item['company_id'] . '_' . $item['package_id']];
|
||||||
|
$sell = $sells[$item['company_id'] . '_' . $item['package_id']];
|
||||||
|
$item['counts'] = $sell ? $sell['counts'] : 0;
|
||||||
|
return array_merge($item, $property ?: self::$default);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户套餐配置修改
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function store(array $values)
|
||||||
|
{
|
||||||
|
if (! is_array(reset($values))) {
|
||||||
|
$values = [$values];
|
||||||
|
}
|
||||||
|
|
||||||
|
$only = ['company_id', 'package_id', 'product', 'vehicle', 'commercial_vehicle', 'company', 'platform', 'customer', 'province'];
|
||||||
|
$checks = ['product', 'vehicle', 'company', 'customer'];
|
||||||
|
|
||||||
|
$settings = $this->propertySettingRepository->getAll();
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
if (!isset($value['company_id']) || !isset($value['package_id'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value['platform'] = $value['platform'] ?: '';
|
||||||
|
$value['commercial_vehicle'] = $value['commercial_vehicle'] ?: '';
|
||||||
|
$value = array_only($value, $only);
|
||||||
|
|
||||||
|
foreach ($value as $k => $v) {
|
||||||
|
if (in_array($k, $checks) && empty($v)) {
|
||||||
|
throw new InvalidArgumentException(self::$property_types[$k] . '值不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($k, $checks) && !in_array($v, $settings[$k])) {
|
||||||
|
throw new InvalidArgumentException(self::$property_types[$k] . '值不正确');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($k, ['commercial_vehicle', 'platform']) && !in_array($v, $settings[$k]) && ($v !== '')) {
|
||||||
|
throw new InvalidArgumentException(self::$property_types[$k] . '值不正确');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($value['province'])) {
|
||||||
|
if (!empty(array_diff(array_keys($value['province']), $settings['province']))) {
|
||||||
|
throw new InvalidArgumentException('省份配置不正确');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_sum($value['province']) != 0 && sprintf("%.2f", array_sum($value['province'])) != 100) {
|
||||||
|
throw new InvalidArgumentException('百分比配置不正确');
|
||||||
|
}
|
||||||
|
|
||||||
|
$value['province'] = json_encode($value['province'], 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$package = $this->getPackage($value['product'])) {
|
||||||
|
throw new NotExistException('产品套餐关系未配置');
|
||||||
|
}
|
||||||
|
|
||||||
|
$value['package'] = $package;
|
||||||
|
|
||||||
|
$value['created_at'] = date('Y-m-d H:i:s');
|
||||||
|
$value['updated_at'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$data[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
throw new NotAllowedException('数据未修改');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->propertyRepository->upsert($data, ['company_id', 'package_id']);
|
||||||
|
|
||||||
|
$this->propertyRepository->forgetCached();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPackage($product)
|
||||||
|
{
|
||||||
|
if (!$package = $this->package) {
|
||||||
|
$settings = $this->propertySettingRepository->getAll();
|
||||||
|
$packages = $settings['package'];
|
||||||
|
$this->package = $package;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($packages as $key => $products) {
|
||||||
|
if (in_array($product, $products)) {
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
13
app/Domains/Virtual/Tests/Services/PropertyServiceTest.php
Normal file
13
app/Domains/Virtual/Tests/Services/PropertyServiceTest.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Domains\Virtual\Tests\Services;
|
||||||
|
|
||||||
|
use App\Core\TestCase;
|
||||||
|
use App\Domains\Virtual\Services\PropertyService;
|
||||||
|
|
||||||
|
class PropertyServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testPropertyServiceTest()
|
||||||
|
{
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
24
app/Models/Virtual/Property.php
Normal file
24
app/Models/Virtual/Property.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Virtual;
|
||||||
|
|
||||||
|
use App\Core\Model;
|
||||||
|
|
||||||
|
class Property extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'virtual_properties';
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'province' => 'array',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function company()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Company::class, 'company_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function package()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Package::class, 'package_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
17
app/Models/Virtual/PropertySetting.php
Normal file
17
app/Models/Virtual/PropertySetting.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Virtual;
|
||||||
|
|
||||||
|
use App\Core\Model;
|
||||||
|
|
||||||
|
class PropertySetting extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'virtual_property_settings';
|
||||||
|
protected $primaryKey = 'name';
|
||||||
|
protected $keyType = 'string';
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'value' => 'array',
|
||||||
|
];
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePropertyTables extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (!Schema::hasTable('virtual_properties')) {
|
||||||
|
Schema::create('virtual_properties', function (Blueprint $table) {
|
||||||
|
$table->increments('id')->comment('自增ID');
|
||||||
|
$table->integer('company_id')->unsigned()->default(0)->comment('企业ID');
|
||||||
|
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
|
||||||
|
$table->string('product', 100)->default('')->comment('产品类型');
|
||||||
|
$table->string('vehicle', 100)->default('')->comment('车辆类型');
|
||||||
|
$table->string('commercial_vehicle', 100)->default('')->comment('商用车分类');
|
||||||
|
$table->string('company', 100)->default('')->comment('公司类型');
|
||||||
|
$table->string('platform', 100)->default('')->comment('平台/API类型');
|
||||||
|
$table->string('customer', 100)->default('')->comment('客户类型');
|
||||||
|
$table->string('package', 100)->default('')->comment('套餐分类');
|
||||||
|
$table->text('province', 100)->nullable()->comment('省份设置');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->unique(['company_id', 'package_id']);
|
||||||
|
|
||||||
|
$table->comment('企业套餐卡属性配置');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Schema::hasTable('virtual_property_settings')) {
|
||||||
|
Schema::create('virtual_property_settings', function (Blueprint $table) {
|
||||||
|
$table->string('name', 20)->default('');
|
||||||
|
$table->text('value', 100)->nullable();
|
||||||
|
|
||||||
|
$table->primary('name');
|
||||||
|
$table->comment('卡属性分类配置');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('virtual_property_settings');
|
||||||
|
Schema::dropIfExists('virtual_properties');
|
||||||
|
}
|
||||||
|
}
|
@ -150,6 +150,14 @@ class PermissionSeeder extends Seeder
|
|||||||
['name' => 'virtual.products.3.destroy', 'title' => '删除', 'description' => 'destroy', 'type' => 1],
|
['name' => 'virtual.products.3.destroy', 'title' => '删除', 'description' => 'destroy', 'type' => 1],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'virtual.properties.index', 'title' => '属性管理', 'path' => '/properties', 'icon' => 'md-cube', 'type' => 0, 'open' => 3,
|
||||||
|
'children' => [
|
||||||
|
['name' => 'virtual.properties.create', 'title' => '设置', 'description' => 'create', 'type' => 1],
|
||||||
|
['name' => 'virtual.properties.update', 'title' => '修改', 'description' => 'update', 'type' => 1],
|
||||||
|
['name' => 'virtual.properties.output', 'title' => '导出', 'description' => 'output', 'type' => 1],
|
||||||
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"pinyin-engine": "^1.1.0",
|
"pinyin-engine": "^1.1.0",
|
||||||
"vue": "^2.5.2",
|
"vue": "^2.5.2",
|
||||||
"vue-router": "^3.0.1",
|
"vue-router": "^3.0.1",
|
||||||
|
"vuedraggable": "^2.20.0",
|
||||||
"vuex": "^3.0.1",
|
"vuex": "^3.0.1",
|
||||||
"xlsx": "^0.13.5"
|
"xlsx": "^0.13.5"
|
||||||
},
|
},
|
||||||
|
63
frontend/src/api/virtual/properties.js
Normal file
63
frontend/src/api/virtual/properties.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* 属性管理
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [settings 属性设置]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function settings(data) {
|
||||||
|
return service.get('api/virtual/properties/settings', {
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [settingsStore 属性设置存储]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function settingsStore(data) {
|
||||||
|
return service.post('api/virtual/properties/settings', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [index 属性列表]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function index(data) {
|
||||||
|
return service.get('api/virtual/properties/index', {
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [store 属性存储]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function store(data) {
|
||||||
|
return serviceForm.post('api/virtual/properties/store', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [export 属性导出]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function exportExcel(data) {
|
||||||
|
return service.get('api/virtual/properties/export', {
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [import 属性导入]
|
||||||
|
* @param {[type]} data [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
export function importExcel(data) {
|
||||||
|
return service.post('api/virtual/properties/import', data);
|
||||||
|
}
|
@ -20,8 +20,6 @@ export default {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(array);
|
|
||||||
|
|
||||||
const pinyinEngine = new PinyinEngine(array, [key]);
|
const pinyinEngine = new PinyinEngine(array, [key]);
|
||||||
|
|
||||||
let res = [];
|
let res = [];
|
||||||
|
@ -21,6 +21,7 @@ const routes = [
|
|||||||
{ path: '/company/accounts', name: 'CompanyAccounts', component: load('virtual/company_accounts/index'), meta: { title: '账号管理' } },
|
{ path: '/company/accounts', name: 'CompanyAccounts', component: load('virtual/company_accounts/index'), meta: { title: '账号管理' } },
|
||||||
{ path: '/packages/:type', name: 'Packages', component: load('virtual/packages/index'), meta: { title: '套餐管理' } },
|
{ path: '/packages/:type', name: 'Packages', component: load('virtual/packages/index'), meta: { title: '套餐管理' } },
|
||||||
{ path: '/products/:type', name: 'Products', component: load('virtual/products/index'), meta: { title: '定价管理' } },
|
{ path: '/products/:type', name: 'Products', component: load('virtual/products/index'), meta: { title: '定价管理' } },
|
||||||
|
{ path: '/properties', name: 'Properties', component: load('virtual/properties/index'), meta: { title: '属性管理' } },
|
||||||
{ path: '/cards', name: 'Cards', component: load('virtual/cards/index'), meta: { title: '客户列表' } },
|
{ path: '/cards', name: 'Cards', component: load('virtual/cards/index'), meta: { title: '客户列表' } },
|
||||||
{ path: '/orders/:type', name: 'Orders', component: load('virtual/orders/index'), meta: { title: '订单列表' } },
|
{ path: '/orders/:type', name: 'Orders', component: load('virtual/orders/index'), meta: { title: '订单列表' } },
|
||||||
{ path: '/exports', name: 'StatsExports', component: load('exports/index'), meta: { title: '导出记录' } },
|
{ path: '/exports', name: 'StatsExports', component: load('exports/index'), meta: { title: '导出记录' } },
|
||||||
|
@ -51,13 +51,7 @@
|
|||||||
|
|
||||||
<ul class="handle-wraper">
|
<ul class="handle-wraper">
|
||||||
<li class="handle-item w-250">
|
<li class="handle-item w-250">
|
||||||
<Select
|
<Select placeholder="企业名称" v-model.trim="params.company_name" clearable filterable>
|
||||||
icon="ios-search"
|
|
||||||
placeholder="企业名称"
|
|
||||||
v-model.trim="params.company_name"
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
>
|
|
||||||
<Option
|
<Option
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="item ? item : ''"
|
:value="item ? item : ''"
|
||||||
@ -75,13 +69,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="handle-item w-250">
|
<li class="handle-item w-250">
|
||||||
<Select
|
<Select placeholder="套餐名称" v-model.trim="params.package_name" clearable filterable>
|
||||||
icon="ios-search"
|
|
||||||
placeholder="套餐名称"
|
|
||||||
v-model.trim="params.package_name"
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
>
|
|
||||||
<Option
|
<Option
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="item ? item : ''"
|
:value="item ? item : ''"
|
||||||
@ -134,7 +122,11 @@
|
|||||||
</a>
|
</a>
|
||||||
</Row>
|
</Row>
|
||||||
<Row v-else>
|
<Row v-else>
|
||||||
<b class="umar-r10">共 {{filterNoUsedTotal}} <i>(可用)</i> / {{filterTotal}} 张</b>
|
<b class="umar-r10">
|
||||||
|
共 {{filterNoUsedTotal}}
|
||||||
|
<i>(可用)</i>
|
||||||
|
/ {{filterTotal}} 张
|
||||||
|
</b>
|
||||||
<a @click="selectAll">
|
<a @click="selectAll">
|
||||||
<b>全选</b>
|
<b>全选</b>
|
||||||
</a>
|
</a>
|
||||||
|
@ -30,7 +30,6 @@ export default {
|
|||||||
name: '',
|
name: '',
|
||||||
company_id: '',
|
company_id: '',
|
||||||
package_id: '',
|
package_id: '',
|
||||||
flowed: 0,
|
|
||||||
price: 0,
|
price: 0,
|
||||||
renew_price: 0,
|
renew_price: 0,
|
||||||
remark: '',
|
remark: '',
|
||||||
@ -75,11 +74,6 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.params.flowed && (this.params.price !== 0)) {
|
|
||||||
this.$Message.info('后向套餐的价格必须为零');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.params.type = this.type;
|
this.params.type = this.type;
|
||||||
|
|
||||||
if (this.isUpdate) {
|
if (this.isUpdate) {
|
||||||
@ -116,7 +110,7 @@ export default {
|
|||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
for (let k in this.params) {
|
for (let k in this.params) {
|
||||||
if (k === 'price' || k === 'status' || k === 'flowed' || k === 'renew_price') {
|
if (k === 'price' || k === 'status' || k === 'renew_price') {
|
||||||
this.params[k] = 0;
|
this.params[k] = 0;
|
||||||
} else {
|
} else {
|
||||||
this.params[k] = '';
|
this.params[k] = '';
|
||||||
|
20
frontend/src/views/virtual/properties/edit.vue
Normal file
20
frontend/src/views/virtual/properties/edit.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<Drawer
|
||||||
|
:mask-closable="false"
|
||||||
|
@on-visible-change="visibleChange"
|
||||||
|
title="省份设置"
|
||||||
|
v-model="my_show"
|
||||||
|
width="450"
|
||||||
|
>
|
||||||
|
<div class="page-edit-wrap uinn-lr20">
|
||||||
|
<Table :columns="columns" :data="dataProvince"></Table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ta-c">
|
||||||
|
<Button @click="clear" class="w-80 umar-r5" ghost type="primary">取消</Button>
|
||||||
|
<Button v-if="isUpdate" :loading="loading" @click="ok" class="w-80" type="primary">确认</Button>
|
||||||
|
</div>
|
||||||
|
</Drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./js/edit.js"></script>
|
109
frontend/src/views/virtual/properties/index.vue
Normal file
109
frontend/src/views/virtual/properties/index.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-wrap">
|
||||||
|
<ui-loading :show="page_loading.show"></ui-loading>
|
||||||
|
|
||||||
|
<div class="page-handle-wrap">
|
||||||
|
<ul class="handle-wraper bd-b">
|
||||||
|
<li class="f-l">
|
||||||
|
<div class="text-exp">
|
||||||
|
<b>全部信息</b>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="f-r">
|
||||||
|
<div class="handle-item lh-32">
|
||||||
|
<b class="umar-r10">编辑模式</b>
|
||||||
|
<Switch v-model="editModel" size="large">
|
||||||
|
<span slot="open">开</span>
|
||||||
|
<span slot="close">关</span>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="handle-item">
|
||||||
|
<Button
|
||||||
|
v-if="editModel"
|
||||||
|
@click="ok"
|
||||||
|
icon="md-checkmark"
|
||||||
|
type="primary"
|
||||||
|
v-has="'update'"
|
||||||
|
>保存修改</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="handle-item">
|
||||||
|
<Button @click="settingsShow = true" icon="md-add" type="primary" v-has="'create'">配置管理</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="handle-item">
|
||||||
|
<Button @click="search.show=!search.show" ghost icon="ios-search" type="primary">搜索</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="handle-item">
|
||||||
|
<Button @click="index(1)" icon="md-refresh">刷新</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="search-wrap" v-show="search.show">
|
||||||
|
<ul class="handle-wraper">
|
||||||
|
<li class="handle-item w-250">
|
||||||
|
<Select placeholder="企业名称" v-model.trim="params.company_id" clearable filterable>
|
||||||
|
<Option
|
||||||
|
:key="index"
|
||||||
|
:value="item.id"
|
||||||
|
v-for="(item, index) in companies"
|
||||||
|
>{{ item.name }}</Option>
|
||||||
|
</Select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="handle-item w-250">
|
||||||
|
<Select placeholder="套餐名称" v-model.trim="params.package_id" clearable filterable>
|
||||||
|
<Option
|
||||||
|
:key="index"
|
||||||
|
:value="item.id"
|
||||||
|
v-for="(item, index) in companies"
|
||||||
|
>{{ item.name }}</Option>
|
||||||
|
</Select>
|
||||||
|
</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 ref="table" :columns="columns" :data="showData ? showData : []"></Table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-turn-wrap" v-if="showData">
|
||||||
|
<Page
|
||||||
|
:current="Number(page.page)"
|
||||||
|
:page-size="Number(page.limit)"
|
||||||
|
:page-size-opts="[10, 20, 50, 100]"
|
||||||
|
:total="Number(page.total)"
|
||||||
|
@on-change="changePage"
|
||||||
|
@on-page-size-change="changeLimit"
|
||||||
|
show-elevator
|
||||||
|
show-total
|
||||||
|
show-sizer
|
||||||
|
></Page>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ui-edit
|
||||||
|
:data="editObj.data"
|
||||||
|
:isUpdate="editObj.isUpdate"
|
||||||
|
:show.sync="editObj.show"
|
||||||
|
:provinces="settingsData.province ? settingsData.province : []"
|
||||||
|
@province-success="handleProvinceSuccess"
|
||||||
|
></ui-edit>
|
||||||
|
|
||||||
|
<ui-settings :data="settingsData" :show.sync="settingsShow" @store-success="updateSettings"></ui-settings>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./js/index.js"></script>
|
106
frontend/src/views/virtual/properties/js/edit.js
Normal file
106
frontend/src/views/virtual/properties/js/edit.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isUpdate: {
|
||||||
|
type: Boolean,
|
||||||
|
default () {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
provinces: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
my_show: false,
|
||||||
|
loading: false,
|
||||||
|
dataProvince: [],
|
||||||
|
edits: [],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '省份',
|
||||||
|
key: 'province',
|
||||||
|
minWidth: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '占比',
|
||||||
|
minWidth: 120,
|
||||||
|
render: (h, context) => {
|
||||||
|
return h('InputNumber', {
|
||||||
|
props: {
|
||||||
|
max: 100,
|
||||||
|
min: 0,
|
||||||
|
value: context.row.percentages,
|
||||||
|
disabled: !this.isUpdate
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
input: (val) => {
|
||||||
|
this.edits = JSON.parse(JSON.stringify(this.dataProvince));
|
||||||
|
this.edits[context.index]['percentages'] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show(bool) {
|
||||||
|
this.my_show = bool;
|
||||||
|
if (bool) {
|
||||||
|
if (this.data) {
|
||||||
|
this.dataProvince = this.provinces.map(el => {
|
||||||
|
let percentages = (this.data.province && this.data.province[el]) ? Number(this.data.province[el]) : 0;
|
||||||
|
return { province: el, percentages };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ok() {
|
||||||
|
let total = this.edits.reduce((acc, cur) => {
|
||||||
|
return acc + cur.percentages;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (total !== 100) {
|
||||||
|
return this.$Message.error('占比总和必须为100');
|
||||||
|
}
|
||||||
|
|
||||||
|
let province = {};
|
||||||
|
|
||||||
|
for (const key in this.edits) {
|
||||||
|
const element = this.edits[key];
|
||||||
|
province[element.province] = element.percentages;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = JSON.parse(JSON.stringify(this.data));
|
||||||
|
data.province = province;
|
||||||
|
this.$emit('province-success', data);
|
||||||
|
this.clear();
|
||||||
|
},
|
||||||
|
visibleChange(bool) {
|
||||||
|
if (!bool) {
|
||||||
|
this.$emit('update:show', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
this.dataProvince = [];
|
||||||
|
this.my_show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
359
frontend/src/views/virtual/properties/js/index.js
Normal file
359
frontend/src/views/virtual/properties/js/index.js
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
import * as API from 'api/virtual/properties';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Products',
|
||||||
|
components: {
|
||||||
|
UiEdit: resolve => require(['views/virtual/properties/edit'], resolve),
|
||||||
|
UiSettings: resolve => require(['views/virtual/properties/settings'], resolve)
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
properties: [],
|
||||||
|
showData: [],
|
||||||
|
params: {
|
||||||
|
company_id: '',
|
||||||
|
package_id: ''
|
||||||
|
},
|
||||||
|
only: ['company_id', 'package_id', 'product', 'vehicle', 'commercial_vehicle', 'company', 'platform', 'customer', 'province'],
|
||||||
|
updates: [],
|
||||||
|
settingsShow: false,
|
||||||
|
settingsData: {},
|
||||||
|
editModel: false,
|
||||||
|
editObj: {
|
||||||
|
show: false,
|
||||||
|
isUpdate: false,
|
||||||
|
data: null
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
total: 0,
|
||||||
|
limit: 10,
|
||||||
|
page: 1
|
||||||
|
},
|
||||||
|
companies: [],
|
||||||
|
companyFilters: [],
|
||||||
|
packages: [],
|
||||||
|
packageFilters: [],
|
||||||
|
data: [],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
key: '',
|
||||||
|
width: 80,
|
||||||
|
render: (h, context) => {
|
||||||
|
return h('span', context.row._index + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '企业名称',
|
||||||
|
key: 'company_name',
|
||||||
|
width: 210,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '套餐名称',
|
||||||
|
key: 'package_name',
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '月流量',
|
||||||
|
key: 'flows',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '销售数量',
|
||||||
|
key: 'counts',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '公司类型',
|
||||||
|
key: 'company',
|
||||||
|
minWidth: 170,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('company', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品类型',
|
||||||
|
key: 'product',
|
||||||
|
minWidth: 130,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('product', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '套餐类型',
|
||||||
|
key: 'package_type',
|
||||||
|
width: 100,
|
||||||
|
render: (h, context) => {
|
||||||
|
return h('span', this.productPackageTypes[context.row.product]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '平台/API',
|
||||||
|
key: 'platform',
|
||||||
|
minWidth: 120,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('platform', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '车辆类型',
|
||||||
|
key: 'vehicle',
|
||||||
|
minWidth: 120,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('vehicle', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '商用车分类',
|
||||||
|
key: 'commercial_vehicle',
|
||||||
|
minWidth: 120,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('commercial_vehicle', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '客户类型',
|
||||||
|
key: 'customer',
|
||||||
|
minWidth: 120,
|
||||||
|
render: (h, context) => {
|
||||||
|
return this.editRender('customer', h, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '销售省份',
|
||||||
|
key: 'action',
|
||||||
|
width: 150,
|
||||||
|
render: (h, {
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
index
|
||||||
|
}) => {
|
||||||
|
let html = [];
|
||||||
|
|
||||||
|
if (this.haveJurisdiction('update')) {
|
||||||
|
let button = h('Button', {
|
||||||
|
props: {
|
||||||
|
type: row.province ? 'primary' : 'error',
|
||||||
|
size: 'small'
|
||||||
|
},
|
||||||
|
class: ['btn'],
|
||||||
|
on: {
|
||||||
|
click: (event) => {
|
||||||
|
this.editObj = { show: true, data: row, isUpdate: this.editModel };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this.editModel ? '设置' : '查看');
|
||||||
|
|
||||||
|
html.push(h('Tooltip', {
|
||||||
|
props: {
|
||||||
|
content: row.province ? '已设置' : '省份未设置'
|
||||||
|
}
|
||||||
|
}, [button]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (html.length) {
|
||||||
|
return h('div', html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
editModel(value) {
|
||||||
|
this.columns = this.columns;
|
||||||
|
this.$refs.table.handleResize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
productPackageTypes() {
|
||||||
|
let obj = {};
|
||||||
|
|
||||||
|
let packages = this.settingsData.package ? this.settingsData.package : {};
|
||||||
|
|
||||||
|
for (const key in packages) {
|
||||||
|
const element = packages[key];
|
||||||
|
|
||||||
|
for (let index = 0; index < element.length; index++) {
|
||||||
|
const value = element[index];
|
||||||
|
obj[value] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.index();
|
||||||
|
this.settings();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editRender(key, h, context) {
|
||||||
|
if (!this.editModel) {
|
||||||
|
return h('span', context.row[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = [];
|
||||||
|
|
||||||
|
for (let index = 0; index < this.settingsData[key].length; index++) {
|
||||||
|
const element = this.settingsData[key][index];
|
||||||
|
options.push(h('Option', {
|
||||||
|
props: {
|
||||||
|
value: element
|
||||||
|
}
|
||||||
|
}, element));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h('Select', {
|
||||||
|
props: {
|
||||||
|
value: context.row[key],
|
||||||
|
size: 'small'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
input: (value) => {
|
||||||
|
let index = (this.page.page - 1) * this.page.limit + context.index;
|
||||||
|
this.properties[index][key] = value;
|
||||||
|
this.changePage(this.page.page);
|
||||||
|
this.updates[index] = this.properties[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* [index 列表]
|
||||||
|
* @param {Number} company_id [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
index(page = 1) {
|
||||||
|
if (!this.properties.length) {
|
||||||
|
this.isShowLoading(true);
|
||||||
|
API.index().then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.properties = res.data;
|
||||||
|
this.changePage(page);
|
||||||
|
this.complete();
|
||||||
|
}
|
||||||
|
this.isShowLoading(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.changePage(page);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete() {
|
||||||
|
let companies = {};
|
||||||
|
|
||||||
|
this.properties.map(function(item) {
|
||||||
|
companies[item.company_id] = item.company_name;
|
||||||
|
});
|
||||||
|
|
||||||
|
let companyArray = [];
|
||||||
|
|
||||||
|
for (const key in companies) {
|
||||||
|
companyArray.push({ id: key, name: companies[key] });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.companies = companyArray;
|
||||||
|
|
||||||
|
let packages = {};
|
||||||
|
|
||||||
|
this.properties.map(function(item) {
|
||||||
|
packages[item.package_id] = item.package_name;
|
||||||
|
});
|
||||||
|
|
||||||
|
let packageArray = [];
|
||||||
|
|
||||||
|
for (const key in packages) {
|
||||||
|
packageArray.push({ id: key, name: packages[key] });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.packages = packageArray;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* [request 刷新]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
request() {
|
||||||
|
this.index();
|
||||||
|
},
|
||||||
|
resetSearch() {
|
||||||
|
for (let k in this.params) {
|
||||||
|
this.params[k] = '';
|
||||||
|
}
|
||||||
|
this.index(1);
|
||||||
|
},
|
||||||
|
changeLimit(limit) {
|
||||||
|
this.page.limit = limit;
|
||||||
|
this.changePage(1);
|
||||||
|
},
|
||||||
|
changePage(page) {
|
||||||
|
this.page.page = page;
|
||||||
|
|
||||||
|
let properties = JSON.parse(JSON.stringify(this.properties));
|
||||||
|
|
||||||
|
if (this.params.company_id !== '' && this.params.company_id !== undefined) {
|
||||||
|
properties = properties.filter(el => { return el.company_id == this.params.company_id; });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.params.package_id !== '' && this.params.package_id !== undefined) {
|
||||||
|
properties = properties.filter(el => { return el.package_id == this.params.package_id; });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.page.total = properties.length;
|
||||||
|
|
||||||
|
this.showData = properties.slice((page - 1) * this.page.limit, page * this.page.limit);
|
||||||
|
},
|
||||||
|
settings() {
|
||||||
|
if (!this.settingsData.length) {
|
||||||
|
API.settings().then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.settingsData = res.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateSettings(values) {
|
||||||
|
this.settingsData = values;
|
||||||
|
},
|
||||||
|
|
||||||
|
ok() {
|
||||||
|
if (!this.updates.length) {
|
||||||
|
this.$Message.warning('数据未修改');
|
||||||
|
this.editModel = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isShowLoading(true);
|
||||||
|
|
||||||
|
let updates = [];
|
||||||
|
|
||||||
|
for (let index = 0; index < this.updates.length; index++) {
|
||||||
|
const element = this.updates[index];
|
||||||
|
let obj = {};
|
||||||
|
for (const key in element) {
|
||||||
|
if (this.only.indexOf(key) !== -1) {
|
||||||
|
obj[key] = element[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updates.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
API.store({ data: updates }).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.updates = [];
|
||||||
|
this.editModel = false;
|
||||||
|
}
|
||||||
|
this.isShowLoading(false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleProvinceSuccess(data) {
|
||||||
|
let index = (this.page.page - 1) * this.page.limit + data._index;
|
||||||
|
this.properties[index] = data;
|
||||||
|
this.changePage(this.page.page);
|
||||||
|
this.updates[index] = this.properties[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
213
frontend/src/views/virtual/properties/js/settings.js
Normal file
213
frontend/src/views/virtual/properties/js/settings.js
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import * as API from 'api/virtual/properties';
|
||||||
|
import draggable from 'vuedraggable';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
draggable
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
my_show: false,
|
||||||
|
loading: false,
|
||||||
|
settings: {},
|
||||||
|
selectedTab: '',
|
||||||
|
completePackagesFilter: [],
|
||||||
|
dragOptions: {
|
||||||
|
animation: 0,
|
||||||
|
group: "description",
|
||||||
|
ghostClass: "ghost"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
packages: {
|
||||||
|
get() {
|
||||||
|
return this.settings.package ? this.settings.package : {};
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
console.log('packages', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
products: {
|
||||||
|
get() {
|
||||||
|
let products = this.settings.product ? this.settings.product : [];
|
||||||
|
let packages = this.settings.package ? this.settings.package : {};
|
||||||
|
|
||||||
|
let values = [];
|
||||||
|
|
||||||
|
for (const key in packages) {
|
||||||
|
values = values.concat(packages[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return products.filter(v => {
|
||||||
|
return !values.includes(v);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
set(array) {
|
||||||
|
let products = this.settings.product ? this.settings.product : [];
|
||||||
|
|
||||||
|
let values = products.filter(v => {
|
||||||
|
return !array.includes(v);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.product = values.concat(array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show(bool) {
|
||||||
|
this.my_show = bool;
|
||||||
|
if (bool) {
|
||||||
|
if (this.data) {
|
||||||
|
this.settings = JSON.parse(JSON.stringify(this.data));
|
||||||
|
|
||||||
|
if (this.settings.package_type && this.settings.package_type.length) {
|
||||||
|
this.selectedTab = this.settings.package_type[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
settings(obj) {
|
||||||
|
if (JSON.stringify(obj) != "{}") {
|
||||||
|
this.isShowLoading(false);
|
||||||
|
} else {
|
||||||
|
this.isShowLoading(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ok() {
|
||||||
|
this.loading = true;
|
||||||
|
API.settingsStore({ data: this.settings }).then(res => {
|
||||||
|
this.loading = false;
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$Message.success('修改成功');
|
||||||
|
this.clear();
|
||||||
|
this.$emit('store-success', this.settings);
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
visibleChange(bool) {
|
||||||
|
if (!bool) {
|
||||||
|
this.$emit('update:show', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
this.my_show = false;
|
||||||
|
},
|
||||||
|
handelRemove(key, value) {
|
||||||
|
this.$Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '已设置的属性值不会因删除改变,确认是否还要删除',
|
||||||
|
onOk: () => {
|
||||||
|
let node = key === 'package' ? this.settings[key][this.selectedTab] : this.settings[key];
|
||||||
|
let index = node.indexOf(value);
|
||||||
|
node.splice(index, 1);
|
||||||
|
|
||||||
|
if (key === 'package') {
|
||||||
|
this.settings[key][this.selectedTab] = node;
|
||||||
|
this.settings.product.splice(this.settings.product.indexOf(value), 1);
|
||||||
|
} else {
|
||||||
|
this.settings[key] = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleAdd(key) {
|
||||||
|
let value = '';
|
||||||
|
let node = key === 'package' ? this.settings[key][this.selectedTab] : this.settings[key];
|
||||||
|
|
||||||
|
this.$Modal.confirm({
|
||||||
|
render: (h) => {
|
||||||
|
return h('Input', {
|
||||||
|
props: {
|
||||||
|
value: value,
|
||||||
|
autofocus: true,
|
||||||
|
placeholder: '请输入名称'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
input: (val) => {
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onOk: () => {
|
||||||
|
if (value === '') {
|
||||||
|
return this.$Message.error('名称不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
node.push(value);
|
||||||
|
|
||||||
|
if (key === 'package') {
|
||||||
|
this.settings[key][this.selectedTab] = node;
|
||||||
|
this.settings.product.push(value);
|
||||||
|
} else {
|
||||||
|
this.settings[key] = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleRemovePackageType(val) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '删除套餐分类将同时删除分类及分类下的产品,但已设置的属性值不会因删除改变,请谨慎操作',
|
||||||
|
onOk: () => {
|
||||||
|
resolve(true);
|
||||||
|
},
|
||||||
|
onCannel: () => {
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleAddPackageType() {
|
||||||
|
let value = '';
|
||||||
|
|
||||||
|
this.$Modal.confirm({
|
||||||
|
render: (h) => {
|
||||||
|
return h('Input', {
|
||||||
|
props: {
|
||||||
|
value: value,
|
||||||
|
autofocus: true,
|
||||||
|
placeholder: '请输入套餐分类名称'
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
input: (val) => {
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onOk: () => {
|
||||||
|
if (value === '') {
|
||||||
|
return this.$Message.error('名称不能为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
let package_type = this.settings.package_type ? this.settings.package_type : [];
|
||||||
|
|
||||||
|
package_type.push(value);
|
||||||
|
|
||||||
|
this.settings.package_type = package_type;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChange(event) {
|
||||||
|
let packages = this.packages[this.selectedTab];
|
||||||
|
this.settings.package[this.selectedTab] = packages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
185
frontend/src/views/virtual/properties/settings.vue
Normal file
185
frontend/src/views/virtual/properties/settings.vue
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
:closable="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:title="'配置管理'"
|
||||||
|
@on-visible-change="visibleChange"
|
||||||
|
v-model="my_show"
|
||||||
|
width="750"
|
||||||
|
>
|
||||||
|
<div class="page-edit-wrap uinn-lr20">
|
||||||
|
<ui-loading :show="page_loading.show"></ui-loading>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">车辆类型:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tag
|
||||||
|
v-for="item in settings.vehicle ? settings.vehicle : []"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('vehicle', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('vehicle')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">商用车分类:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tag
|
||||||
|
v-for="item in settings.commercial_vehicle ? settings.commercial_vehicle : []"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('commercial_vehicle', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
<Button
|
||||||
|
icon="ios-add"
|
||||||
|
type="dashed"
|
||||||
|
size="small"
|
||||||
|
@click="handleAdd('commercial_vehicle')"
|
||||||
|
>添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">公司类型:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tag
|
||||||
|
v-for="item in settings.company ? settings.company : []"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('company', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('company')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">平台/API类型:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tag
|
||||||
|
v-for="item in settings.platform ? settings.platform : []"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('platform', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('platform')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">客户类型:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tag
|
||||||
|
v-for="item in settings.customer ? settings.customer : []"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('customer', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('customer')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">套餐分类:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<Tabs
|
||||||
|
type="card"
|
||||||
|
closable
|
||||||
|
v-model="selectedTab"
|
||||||
|
:before-remove="handleRemovePackageType"
|
||||||
|
>
|
||||||
|
<TabPane
|
||||||
|
v-for="item in settings.package_type ? settings.package_type : []"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:name="item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="package-content"
|
||||||
|
:class="item === selectedTab ? 'package-content-active' : ''"
|
||||||
|
>
|
||||||
|
<draggable
|
||||||
|
draggable=".item"
|
||||||
|
v-bind="dragOptions"
|
||||||
|
:list="packages[item]"
|
||||||
|
@change="onChange"
|
||||||
|
>
|
||||||
|
<Tag
|
||||||
|
class="item"
|
||||||
|
v-for="pitem in packages[item]"
|
||||||
|
:key="pitem"
|
||||||
|
:name="pitem"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('package', pitem)"
|
||||||
|
>{{pitem}}</Tag>
|
||||||
|
</draggable>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('package')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
<Button
|
||||||
|
@click="handleAddPackageType"
|
||||||
|
icon="ios-add"
|
||||||
|
type="dashed"
|
||||||
|
size="small"
|
||||||
|
slot="extra"
|
||||||
|
>添加</Button>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="ui-list">
|
||||||
|
<div class="ui-list-title">未分类产品:</div>
|
||||||
|
<div class="ui-list-content lh-32">
|
||||||
|
<draggable draggable=".item" v-bind="dragOptions" v-model="products">
|
||||||
|
<Tag
|
||||||
|
class="item"
|
||||||
|
v-for="item in products"
|
||||||
|
:key="item"
|
||||||
|
:name="item"
|
||||||
|
closable
|
||||||
|
@on-close="handelRemove('product', item)"
|
||||||
|
>{{item}}</Tag>
|
||||||
|
</draggable>
|
||||||
|
<Button icon="ios-add" type="dashed" size="small" @click="handleAdd('product')">添加</Button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<footer class="ta-c" slot="footer">
|
||||||
|
<Button @click="clear" class="w-80" ghost type="primary">取消</Button>
|
||||||
|
<Button :loading="loading" @click="ok" class="w-80" type="primary">提交</Button>
|
||||||
|
</footer>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./js/settings.js"></script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
>>> .ivu-tabs-bar {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
>>> .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab-active {
|
||||||
|
border-color: #2d8cf0;
|
||||||
|
border-bottom-color: #dcdee2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.package-content {
|
||||||
|
border: 1px solid #dcdee2;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-content-active {
|
||||||
|
border-color: #2d8cf0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
3
vendor/composer/autoload_classmap.php
vendored
3
vendor/composer/autoload_classmap.php
vendored
@ -11,12 +11,11 @@ return array(
|
|||||||
'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
|
'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
|
||||||
'CompanyAccountSeeder' => $baseDir . '/database/seeds/CompanyAccountSeeder.php',
|
'CompanyAccountSeeder' => $baseDir . '/database/seeds/CompanyAccountSeeder.php',
|
||||||
'ConfigSeeder' => $baseDir . '/database/seeds/ConfigSeeder.php',
|
'ConfigSeeder' => $baseDir . '/database/seeds/ConfigSeeder.php',
|
||||||
'CreateBlocsTable' => $baseDir . '/database/migrations/2018_12_24_164210_create_blocs_table.php',
|
|
||||||
'CreateCardsTable' => $baseDir . '/database/migrations/2018_12_24_164218_create_cards_table.php',
|
'CreateCardsTable' => $baseDir . '/database/migrations/2018_12_24_164218_create_cards_table.php',
|
||||||
'CreateCompanyRelations' => $baseDir . '/database/migrations/2019_03_08_110806_create_company_relations.php',
|
|
||||||
'CreateFailedJobsTable' => $baseDir . '/database/migrations/0000_00_00_000000_create_failed_jobs_table.php',
|
'CreateFailedJobsTable' => $baseDir . '/database/migrations/0000_00_00_000000_create_failed_jobs_table.php',
|
||||||
'CreateFlowPoolTables' => $baseDir . '/database/migrations/2019_01_24_175246_create_flow_pool_tables.php',
|
'CreateFlowPoolTables' => $baseDir . '/database/migrations/2019_01_24_175246_create_flow_pool_tables.php',
|
||||||
'CreateJobsTable' => $baseDir . '/database/migrations/0000_00_00_000000_create_jobs_table.php',
|
'CreateJobsTable' => $baseDir . '/database/migrations/0000_00_00_000000_create_jobs_table.php',
|
||||||
|
'CreatePropertyTables' => $baseDir . '/database/migrations/2019_04_02_101740_create_property_tables.php',
|
||||||
'CreateRealCompaniesTable' => $baseDir . '/database/migrations/2018_12_24_164318_create_real_companies_table.php',
|
'CreateRealCompaniesTable' => $baseDir . '/database/migrations/2018_12_24_164318_create_real_companies_table.php',
|
||||||
'CreateRealOrderCardsTable' => $baseDir . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php',
|
'CreateRealOrderCardsTable' => $baseDir . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php',
|
||||||
'CreateRealOrdersTable' => $baseDir . '/database/migrations/2018_12_24_164430_create_real_orders_table.php',
|
'CreateRealOrdersTable' => $baseDir . '/database/migrations/2018_12_24_164430_create_real_orders_table.php',
|
||||||
|
3
vendor/composer/autoload_static.php
vendored
3
vendor/composer/autoload_static.php
vendored
@ -730,12 +730,11 @@ class ComposerStaticInite79258a3e34ad3e251999111d9f334d9
|
|||||||
'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
|
'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
|
||||||
'CompanyAccountSeeder' => __DIR__ . '/../..' . '/database/seeds/CompanyAccountSeeder.php',
|
'CompanyAccountSeeder' => __DIR__ . '/../..' . '/database/seeds/CompanyAccountSeeder.php',
|
||||||
'ConfigSeeder' => __DIR__ . '/../..' . '/database/seeds/ConfigSeeder.php',
|
'ConfigSeeder' => __DIR__ . '/../..' . '/database/seeds/ConfigSeeder.php',
|
||||||
'CreateBlocsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164210_create_blocs_table.php',
|
|
||||||
'CreateCardsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164218_create_cards_table.php',
|
'CreateCardsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164218_create_cards_table.php',
|
||||||
'CreateCompanyRelations' => __DIR__ . '/../..' . '/database/migrations/2019_03_08_110806_create_company_relations.php',
|
|
||||||
'CreateFailedJobsTable' => __DIR__ . '/../..' . '/database/migrations/0000_00_00_000000_create_failed_jobs_table.php',
|
'CreateFailedJobsTable' => __DIR__ . '/../..' . '/database/migrations/0000_00_00_000000_create_failed_jobs_table.php',
|
||||||
'CreateFlowPoolTables' => __DIR__ . '/../..' . '/database/migrations/2019_01_24_175246_create_flow_pool_tables.php',
|
'CreateFlowPoolTables' => __DIR__ . '/../..' . '/database/migrations/2019_01_24_175246_create_flow_pool_tables.php',
|
||||||
'CreateJobsTable' => __DIR__ . '/../..' . '/database/migrations/0000_00_00_000000_create_jobs_table.php',
|
'CreateJobsTable' => __DIR__ . '/../..' . '/database/migrations/0000_00_00_000000_create_jobs_table.php',
|
||||||
|
'CreatePropertyTables' => __DIR__ . '/../..' . '/database/migrations/2019_04_02_101740_create_property_tables.php',
|
||||||
'CreateRealCompaniesTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164318_create_real_companies_table.php',
|
'CreateRealCompaniesTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164318_create_real_companies_table.php',
|
||||||
'CreateRealOrderCardsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php',
|
'CreateRealOrderCardsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php',
|
||||||
'CreateRealOrdersTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164430_create_real_orders_table.php',
|
'CreateRealOrdersTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164430_create_real_orders_table.php',
|
||||||
|
@ -179,7 +179,7 @@ class DatabaseServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function macroUpsert()
|
public function macroUpsert()
|
||||||
{
|
{
|
||||||
return function (array $values, $fields = ['id'], $doNoting = false) {
|
return function (array $values, $fields = ['id'], $only = null) {
|
||||||
if (empty($values)) {
|
if (empty($values)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ class DatabaseServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->connection->affectingStatement(
|
return $this->connection->affectingStatement(
|
||||||
$this->grammar->compileUpsert($this, $values, $fields, $doNoting),
|
$this->grammar->compileUpsert($this, $values, $fields, $only),
|
||||||
$this->cleanBindings(Arr::flatten($values, 1))
|
$this->cleanBindings(Arr::flatten($values, 1))
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user