'产品类型', '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]; } }