237 lines
7.7 KiB
PHP
237 lines
7.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 Illuminate\Support\Facades\DB;
|
|
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->renew_price = sprintf('%.02f', $item->renew_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] ?? '未知';
|
|
$item->status = $item->deleted_at ? 2 : $item->status;
|
|
});
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 获取历史定价列表
|
|
*
|
|
* @param array $conditions
|
|
* @return Collection
|
|
*/
|
|
public function history(array $conditions = [])
|
|
{
|
|
$select = ['id', 'company_id', 'package_id', 'price', 'renew_price', 'created_at', 'updated_at'];
|
|
|
|
$list = $this->productRepository->select($select)->withTrashed()->withConditions($conditions)->orderBy('created_at', 'desc')->get();
|
|
|
|
$list->map(function ($item) {
|
|
$item->price = sprintf('%.02f', $item->price/100);
|
|
$item->renew_price = sprintf('%.02f', $item->renew_price/100);
|
|
});
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 存储企业定价
|
|
*
|
|
* @param array $attributes
|
|
* @return Product
|
|
*/
|
|
public function store(array $attributes = [])
|
|
{
|
|
if (isset($attributes['price'])) {
|
|
$attributes['price'] = intval($attributes['price'] * 100);
|
|
}
|
|
|
|
if (isset($attributes['renew_price'])) {
|
|
$attributes['renew_price'] = intval($attributes['renew_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',
|
|
];
|
|
|
|
DB::beginTransaction();
|
|
|
|
if (!$package = app(PackageRepository::class)->find($attributes['package_id'])) {
|
|
throw new NotExistException('套餐不存在或已删除');
|
|
}
|
|
|
|
// 上一次定价
|
|
$newest = $this->productRepository->where('company_id', $attributes['company_id'])->where('package_id', $attributes['package_id'])->first();
|
|
|
|
if ($newest && (
|
|
(isset($attributes['price']) && $newest->price !== $attributes['price'])
|
|
||
|
|
(isset($attributes['renew_price']) && $newest->renew_price !== $attributes['renew_price'])
|
|
)) {
|
|
unset($attributes['id']);
|
|
$newest->delete();
|
|
|
|
$attributes['renew_price'] = $attributes['renew_price'] ?? $newest->renew_price;
|
|
$attributes['price'] = $attributes['price'] ?? $newest->price;
|
|
}
|
|
|
|
Validator::validate($attributes, $rule, $message);
|
|
|
|
try {
|
|
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('套餐已被禁用,不能启用');
|
|
}
|
|
}
|
|
|
|
$this->productRepository->setModel($node)->update($attributes);
|
|
return $node;
|
|
} else {
|
|
$attributes['sn'] = self::sn($package['sn'], $attributes['company_id']);
|
|
$attributes['created_at'] = date('Y-m-d H:i:s');
|
|
$attributes['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
$this->productRepository->upsert($attributes, ['sn', 'deleted_at']);
|
|
$this->productRepository->forgetCached();
|
|
$node = $this->productRepository->where('sn', $attributes['sn'])->first();
|
|
}
|
|
DB::commit();
|
|
} catch (\Exception $e) {
|
|
DB::rollback();
|
|
throw $e;
|
|
}
|
|
|
|
return $node;
|
|
}
|
|
|
|
/**
|
|
* 删除
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function destroy($ids)
|
|
{
|
|
$ids = is_array($ids) ? $ids : [$ids];
|
|
|
|
$this->productRepository->destroy($ids);
|
|
|
|
return true;
|
|
}
|
|
|
|
public static function load($type, $companyId, $packageId)
|
|
{
|
|
$type = $type === 1 ? 0 : $type;
|
|
|
|
if (!self::$products) {
|
|
self::$products = app(ProductRepository::class)
|
|
->select(['id', 'type', 'name', 'company_id', 'package_id', 'price', 'renew_price', 'status'])
|
|
->get();
|
|
}
|
|
|
|
return self::$products->filter(function ($item) use ($type, $companyId, $packageId) {
|
|
return $item->type === $type && $item->company_id === $companyId && $item->package_id === $packageId;
|
|
})->first();
|
|
}
|
|
|
|
public static function sn($packageSn, $companyId)
|
|
{
|
|
return strtoupper($packageSn . '_' . $companyId);
|
|
}
|
|
|
|
/**
|
|
* 获取定价
|
|
*
|
|
* @param int $type
|
|
* @param int $companyId
|
|
* @param int $packageId
|
|
* @param int $price
|
|
* @return void
|
|
*/
|
|
public static function getProduct($type, $companyId, $packageId, $price)
|
|
{
|
|
$package = PackageService::load($packageId);
|
|
|
|
$product = self::load($type, $companyId, $packageId);
|
|
|
|
$field = $type === 1 ? 'renew_price' : 'price';
|
|
|
|
if (!$product || $product[$field] !== $price) {
|
|
$product = app(ProductService::class)->store([
|
|
'type' => $type === 1 ? 0 : $type,
|
|
'name' => $package['name'],
|
|
'company_id' => $companyId,
|
|
'package_id' => $package['id'],
|
|
$field => $price/100,
|
|
]);
|
|
}
|
|
|
|
return $product;
|
|
}
|
|
}
|