vd/app/Domains/Virtual/Services/ProductService.php
2019-02-26 21:36:49 +08:00

183 lines
5.7 KiB
PHP

<?php
namespace App\Domains\Virtual\Services;
use App\Dicts;
use App\Core\Service;
use App\Models\Virtual\Product;
use Illuminate\Validation\Rule;
use App\Exceptions\NotExistException;
use App\Exceptions\NotAllowedException;
use Illuminate\Support\Facades\Validator;
use App\Domains\Virtual\Services\CompanyService;
use App\Domains\Virtual\Services\PackageService;
use App\Domains\Virtual\Repositories\PackageRepository;
use App\Domains\Virtual\Repositories\ProductRepository;
class ProductService extends Service
{
protected $productRepository;
protected static $products;
/**
* 构造函数
*
* @return void
*/
public function __construct(ProductRepository $productRepository)
{
$this->productRepository = $productRepository;
}
/**
* 获取企业定价列表
*
* @param array $conditions
* @return Collection
*/
public function index(array $conditions = [])
{
$list = $this->productRepository->whereHas('package', function ($query) {
$query->whereNull('deleted_at');
})->whereHas('company', function ($query) {
$query->whereNull('deleted_at');
})->withConditions($conditions)->applyConditions()->get();
$carrierOperators = app(Dicts::class)->get('carrier_operator');
$list->map(function ($item) use ($carrierOperators) {
$item->company = CompanyService::load($item->company_id);
$item->package = PackageService::load($item->package_id);
$item->price = sprintf('%.02f', $item->price/100);
$item->status = $item['package']['status'] ? 1 : $item->status;
$item->carrier_operator = $item['package']['carrier_operator'];
$item->carrier_operator_name = $carrierOperators[$item->carrier_operator] ?? '未知';
});
return $list;
}
/**
* 存储企业定价
*
* @param array $attributes
* @return Product
*/
public function store(array $attributes = [])
{
$attributes['price'] = intval($attributes['price'] * 100);
$rule = [
'name' => ['required', 'between:2,32', Rule::unique($this->productRepository->getTable(), 'name')->ignore($attributes['id'])->whereNUll('deleted_at')->where('company_id', $attributes['company_id'])],
'company_id' => ['required', 'exists:virtual_companies,id'],
'package_id' => ['required'],
'price' => [],
'remark' => [],
];
$message = [
'name.required' => '请输入定价名称',
'name.between' => '请输入2-32个字符',
'name.unique' => '定价名称已存在,请更新输入',
'company_id.required' => '请输入企业ID',
'company_id.exists' => '企业不存在或已删除',
'package_id.required' => '请输入套餐ID',
];
Validator::validate($attributes, $rule, $message);
if (!$package = app(PackageRepository::class)->find($attributes['package_id'])) {
throw new NotExistException('套餐不存在或已删除');
}
$attributes['sn'] = self::sn($package['sn'], $attributes['company_id'], $attributes['price']);
if (!$attributes['id']) {
if ($this->productRepository->where('sn', $attributes['sn'])->count()) {
throw new NotAllowedException('已存在相同定价,请勿重复添加');
}
$node = $this->productRepository->create($attributes);
}
if ($attributes['id']) {
if (!$node = $this->productRepository->find($attributes['id'])) {
throw new NotExistException('定价不存在或已删除');
}
if ($attributes['status'] == 0) {
$node->load(['package:id,status']);
if ($node['package']['status'] === 1) {
throw new NotAllowedException('套餐已被禁用,不能启用');
}
}
if ($this->productRepository->where('sn', $attributes['sn'])->where('id', '<>', $attributes['id'])->count()) {
throw new NotAllowedException('已存在相同定价,请核对后重试');
}
$this->productRepository->setModel($node)->update($attributes);
}
return $node;
}
/**
* 删除
*
* @return bool
*/
public function destroy($ids)
{
$ids = is_array($ids) ? $ids : [$ids];
$this->productRepository->destroy($ids);
return true;
}
public static function load($id)
{
if (!self::$products) {
self::$products = app(ProductRepository::class)->select(['id', 'type', 'name', 'company_id', 'package_id', 'price', 'status'])
->withTrashed()->get()->keyBy('id');
}
return self::$products[$id];
}
public static function sn($packageSn, $companyId, $price)
{
return strtoupper($packageSn . '_' . $companyId . '_' . $price);
}
/**
* 获取定价
*
* @param string $sn
* @return void
*/
public static function getProduct($companyId, $packageId, $price)
{
$package = PackageService::load($packageId);
$product = app(ProductRepository::class)->withConditions([
'company_id' => $companyId,
'package_id' => $packageId,
'price' => $price,
])->first();
if (!$product) {
$product = app(ProductService::class)->store([
'name' => $package['name'] . ' ' . $price,
'company_id' => $companyId,
'package_id' => $package['id'],
'price' => $price/100,
]);
}
return $product;
}
}