354 lines
12 KiB
PHP
354 lines
12 KiB
PHP
<?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' => '套餐类型',
|
|
'agent' => '代理商设置',
|
|
];
|
|
|
|
public static $default = [
|
|
'product' => '',
|
|
'vehicle' => '',
|
|
'commercial_vehicle' => '',
|
|
'company' => '',
|
|
'platform' => '',
|
|
'customer' => '',
|
|
'package' => '',
|
|
'province' => null,
|
|
'province_status' => 0,
|
|
'agent' => null,
|
|
'agent_status' => 0,
|
|
'created_at' => null,
|
|
'updated_at' => null,
|
|
];
|
|
|
|
protected static $properties;
|
|
|
|
/**
|
|
* 构造函数
|
|
*
|
|
* @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();
|
|
|
|
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($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');
|
|
|
|
$settings = $this->propertySettingRepository->getAll(true);
|
|
|
|
return $settings;
|
|
}
|
|
|
|
/**
|
|
* 客户套餐配置列表
|
|
*
|
|
* @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();
|
|
|
|
// $actives = app(OrderCardPartitionRepository::class)->selectRaw('company_id, package_id, count(*) as counts')
|
|
// ->withConditions(['type' => 0, 'card_status' => 2])->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, $actives, $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']];
|
|
$active = $actives[$item['company_id'] . '_' . $item['package_id']];
|
|
$item['counts'] = $sell ? $sell['counts'] : 0;
|
|
$item['actives'] = $active ? $active['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', 'agent'];
|
|
$checks = ['product', 'vehicle', 'company', 'customer'];
|
|
|
|
$settings = $this->propertySettingRepository->getAll();
|
|
$agents = app(AgentService::class)->listGroupByCompanyId();
|
|
|
|
$data = [];
|
|
|
|
foreach ($values as $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 (!is_null($value['agent'])) {
|
|
$itemAgents = $agents[$value['company_id']];
|
|
|
|
$index = [];
|
|
foreach ($value['agent'] as $agent) {
|
|
if (in_array($agent['company_id'] . '_' . $agent['platform'], $index)) {
|
|
throw new InvalidArgumentException('代理商平台重复配置');
|
|
} else {
|
|
array_push($index, $agent['company_id'] . '_' . $agent['platform']);
|
|
}
|
|
|
|
if (!in_array($agent['agent'], array_pluck($itemAgents, 'id'))) {
|
|
throw new InvalidArgumentException('代理商配置不正确');
|
|
}
|
|
|
|
if (!in_array($agent['platform'], array_keys($settings['platform']))) {
|
|
throw new InvalidArgumentException('代理商平台配置不正确');
|
|
}
|
|
}
|
|
|
|
if (array_sum(array_pluck($value['agent'], 'percentages')) != 0 && sprintf("%.2f", array_sum(array_pluck($value['agent'], 'percentages'))) != 100) {
|
|
throw new InvalidArgumentException('代理商百分比配置不正确');
|
|
}
|
|
|
|
$value['agent'] = json_encode($value['agent'], 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['company_id'] . '_' . $value['package_id']] = $value;
|
|
}
|
|
|
|
if (empty($data)) {
|
|
throw new NotAllowedException('数据未修改');
|
|
}
|
|
|
|
$values = array_values($data);
|
|
|
|
$this->propertyRepository->upsert($values, ['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;
|
|
}
|
|
|
|
public static function load($company_id, $package_id)
|
|
{
|
|
if (!self::$properties) {
|
|
$properties = app(PropertyRepository::class)
|
|
->select(['company_id', 'package_id', 'product', 'package'])->get();
|
|
|
|
self::$properties = $properties->keyBy(function ($item) {
|
|
return $item['company_id'] . '_' . $item['package_id'];
|
|
})->toArray();
|
|
}
|
|
|
|
return self::$properties[$company_id . '_' . $package_id];
|
|
}
|
|
}
|