163 lines
5.1 KiB
PHP
163 lines
5.1 KiB
PHP
<?php
|
||
|
||
namespace App\Service\business;
|
||
|
||
use App\BaseApp\BaseService;
|
||
use App\Models\business\EnterpriseModel;
|
||
use App\Models\business\WxUserModel;
|
||
use App\Service\common\MediaUrlService;
|
||
use Exception;
|
||
use Psr\Container\ContainerExceptionInterface;
|
||
use Psr\Container\NotFoundExceptionInterface;
|
||
|
||
/**
|
||
* 企业管理
|
||
*
|
||
* 老项目里企业只是微信用户管理页顺手塞的两个字段(name/logo),
|
||
* 没有独立模块,也没有联系人、税号、默认倍率,做不了对公结算。
|
||
*/
|
||
class EnterpriseService extends BaseService
|
||
{
|
||
private MediaUrlService $media;
|
||
|
||
public function __construct()
|
||
{
|
||
parent::__construct();
|
||
$this->model = EnterpriseModel::class;
|
||
$this->selectField = [
|
||
'id', 'name', 'logo', 'contact_name', 'phone', 'address',
|
||
'tax_no', 'settle_type', 'price_number', 'status', 'remark',
|
||
'created_at', 'updated_at',
|
||
];
|
||
$this->queryField = [
|
||
'name' => 'like',
|
||
'contact_name' => 'like',
|
||
'phone' => 'like',
|
||
'status' => '=',
|
||
];
|
||
$this->media = MediaUrlService::getInstance();
|
||
}
|
||
|
||
/**
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
*/
|
||
public function list(): array
|
||
{
|
||
$result = $this->getPageList();
|
||
$ids = array_column($result['items'], 'id');
|
||
$counts = empty($ids)
|
||
? []
|
||
: WxUserModel::whereIn('enterprise_id', $ids)
|
||
->where('deleted_at', 0)
|
||
->selectRaw('enterprise_id, COUNT(*) as total')
|
||
->groupBy('enterprise_id')
|
||
->pluck('total', 'enterprise_id')
|
||
->all();
|
||
|
||
foreach ($result['items'] as &$item) {
|
||
$item['logo'] = $this->media->toPublic($item['logo'] ?? '');
|
||
$item['user_count'] = (int) ($counts[$item['id']] ?? 0);
|
||
}
|
||
unset($item);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 下拉:SearchSelect 组件按关键词模糊搜索,所以支持 keyword 入参
|
||
*/
|
||
public function option(): mixed
|
||
{
|
||
$keyword = trim((string) request()->get('keyword', ''));
|
||
$limit = (int) request()->get('limit', 30);
|
||
$limit = $limit > 0 && $limit <= 100 ? $limit : 30;
|
||
|
||
return EnterpriseModel::where('deleted_at', 0)
|
||
->where('status', 0)
|
||
->when($keyword !== '', function ($q) use ($keyword) {
|
||
$q->where(function ($sub) use ($keyword) {
|
||
$sub->where('name', 'like', "%{$keyword}%")
|
||
->orWhere('contact_name', 'like', "%{$keyword}%")
|
||
->orWhere('phone', 'like', "%{$keyword}%");
|
||
});
|
||
})
|
||
->orderBy('id', 'desc')
|
||
->limit($limit)
|
||
->get(['id', 'name', 'logo', 'contact_name', 'phone', 'price_number'])
|
||
->map(function ($row) {
|
||
$row->logo = $this->media->toPublic($row->logo);
|
||
return $row;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 详情:带企业下的微信用户
|
||
* @throws Exception
|
||
*/
|
||
public function detail($id): mixed
|
||
{
|
||
$info = $this->getDetail($id);
|
||
$info->logo = $this->media->toPublic($info->logo);
|
||
$info->users = WxUserModel::where('enterprise_id', $id)
|
||
->where('deleted_at', 0)
|
||
->orderBy('id', 'desc')
|
||
->get(['id', 'nick_name', 'phone', 'is_p', 'show_price', 'price_number', 'created_at'])
|
||
->toArray();
|
||
$info->user_count = count($info->users);
|
||
return $info;
|
||
}
|
||
|
||
public function create($params): mixed
|
||
{
|
||
$params = $this->normalize($params);
|
||
return $this->insert($params);
|
||
}
|
||
|
||
/**
|
||
* @throws Exception
|
||
*/
|
||
public function update($id, $params): mixed
|
||
{
|
||
$params = $this->normalize($params);
|
||
return $this->save($id, $params);
|
||
}
|
||
|
||
/**
|
||
* 删除企业前先解绑用户,否则用户会挂在一个查不到的企业上
|
||
* @throws Exception
|
||
*/
|
||
public function delete($id): mixed
|
||
{
|
||
$ids = array_values(array_filter(array_map('intval', is_array($id) ? $id : [$id])));
|
||
if (empty($ids)) {
|
||
$this->utils->errorThrow('参数错误');
|
||
}
|
||
if (WxUserModel::whereIn('enterprise_id', $ids)->where('deleted_at', 0)->exists()) {
|
||
$this->utils->errorThrow('该企业下仍有微信用户,请先解绑用户');
|
||
}
|
||
return $this->del($ids);
|
||
}
|
||
|
||
/**
|
||
* @throws Exception
|
||
*/
|
||
public function status($id, $status): mixed
|
||
{
|
||
return $this->save($id, ['status' => (int) $status]);
|
||
}
|
||
|
||
private function normalize(array $params): array
|
||
{
|
||
if (array_key_exists('logo', $params)) {
|
||
$params['logo'] = $this->media->firstOf($params['logo']);
|
||
}
|
||
if (array_key_exists('price_number', $params)) {
|
||
$number = $params['price_number'];
|
||
$params['price_number'] = !is_numeric($number) || (float) $number <= 0
|
||
? '1'
|
||
: (string) $number;
|
||
}
|
||
return $params;
|
||
}
|
||
}
|