422 lines
13 KiB
PHP
422 lines
13 KiB
PHP
<?php
|
|
|
|
namespace App\Services\System;
|
|
|
|
use App\Models\System\SystemDictData;
|
|
use App\Models\System\SystemDictType;
|
|
use App\Services\BaseService;
|
|
use App\Exceptions\BusinessException;
|
|
use App\Helpers\ResponseEnum;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* 字典数据服务类
|
|
*/
|
|
class SystemDictDataService extends BaseService
|
|
{
|
|
/**
|
|
* 获取字典数据列表(分页)
|
|
*
|
|
* @param array $params
|
|
* @return LengthAwarePaginator
|
|
*/
|
|
public function getList(array $params): LengthAwarePaginator
|
|
{
|
|
$query = SystemDictData::query();
|
|
|
|
// 字典标签搜索
|
|
if (!empty($params['label'])) {
|
|
$query->where('label', 'like', '%' . $params['label'] . '%');
|
|
}
|
|
|
|
// 字典值搜索
|
|
if (!empty($params['value'])) {
|
|
$query->where('value', 'like', '%' . $params['value'] . '%');
|
|
}
|
|
|
|
// 字典类型筛选
|
|
if (!empty($params['dict_type'])) {
|
|
$query->where('dict_type', $params['dict_type']);
|
|
}
|
|
|
|
// 状态筛选
|
|
if (isset($params['status']) && $params['status'] !== '') {
|
|
$query->where('status', $params['status']);
|
|
}
|
|
|
|
// 颜色类型筛选
|
|
if (!empty($params['color_type'])) {
|
|
$query->where('color_type', $params['color_type']);
|
|
}
|
|
|
|
// 创建时间范围
|
|
if (!empty($params['create_time_start'])) {
|
|
$query->where('create_time', '>=', $params['create_time_start']);
|
|
}
|
|
if (!empty($params['create_time_end'])) {
|
|
$query->where('create_time', '<=', $params['create_time_end']);
|
|
}
|
|
|
|
return $query->with('dictType')
|
|
->orderBy('sort')
|
|
->orderBy('id', 'desc')
|
|
->paginate($params['page_size'] ?? 15);
|
|
}
|
|
|
|
/**
|
|
* 根据字典类型获取数据列表
|
|
*
|
|
* @param string $dictType
|
|
* @param bool $onlyActive
|
|
* @return \Illuminate\Database\Eloquent\Collection
|
|
*/
|
|
public function getByType(string $dictType, bool $onlyActive = true)
|
|
{
|
|
$query = SystemDictData::where('dict_type', $dictType);
|
|
|
|
if ($onlyActive) {
|
|
$query->where('status', SystemDictData::STATUS_NORMAL);
|
|
}
|
|
|
|
return $query->orderBy('sort')->get();
|
|
}
|
|
|
|
/**
|
|
* 根据ID获取字典数据详情
|
|
*
|
|
* @param int $id
|
|
* @return SystemDictData
|
|
* @throws BusinessException
|
|
*/
|
|
public function getById(int $id): SystemDictData
|
|
{
|
|
$dictData = SystemDictData::with('dictType')->find($id);
|
|
|
|
if (!$dictData) {
|
|
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR, '字典数据不存在');
|
|
}
|
|
|
|
return $dictData;
|
|
}
|
|
|
|
/**
|
|
* 根据字典类型和值获取字典数据
|
|
*
|
|
* @param string $dictType
|
|
* @param string $value
|
|
* @return SystemDictData
|
|
* @throws BusinessException
|
|
*/
|
|
public function getByTypeAndValue(string $dictType, string $value): SystemDictData
|
|
{
|
|
$dictData = SystemDictData::findByTypeAndValue($dictType, $value);
|
|
|
|
if (!$dictData) {
|
|
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR, '字典数据不存在');
|
|
}
|
|
|
|
return $dictData;
|
|
}
|
|
|
|
/**
|
|
* 创建字典数据
|
|
*
|
|
* @param array $data
|
|
* @return SystemDictData
|
|
* @throws BusinessException
|
|
*/
|
|
public function create(array $data): SystemDictData
|
|
{
|
|
// 检查字典类型是否存在
|
|
$dictType = SystemDictType::findByType($data['dict_type']);
|
|
if (!$dictType) {
|
|
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR, '字典类型不存在');
|
|
}
|
|
|
|
// 检查字典值是否已存在
|
|
if (SystemDictData::valueExists($data['value'], $data['dict_type'])) {
|
|
throw new BusinessException(ResponseEnum::CLIENT_PARAMETER_ERROR, '字典值已存在');
|
|
}
|
|
|
|
// 如果没有设置排序,自动获取下一个排序值
|
|
if (!isset($data['sort']) || $data['sort'] === '') {
|
|
$data['sort'] = SystemDictData::getNextSort($data['dict_type']);
|
|
}
|
|
|
|
try {
|
|
$dictData = SystemDictData::create($data);
|
|
|
|
Log::info('字典数据创建成功', ['id' => $dictData->id, 'dict_type' => $dictData->dict_type, 'value' => $dictData->value]);
|
|
|
|
return $dictData;
|
|
} catch (\Exception $e) {
|
|
Log::error('字典数据创建失败', ['error' => $e->getMessage(), 'data' => $data]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '创建字典数据失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新字典数据
|
|
*
|
|
* @param int $id
|
|
* @param array $data
|
|
* @return SystemDictData
|
|
* @throws BusinessException
|
|
*/
|
|
public function update(int $id, array $data): SystemDictData
|
|
{
|
|
$dictData = $this->getById($id);
|
|
|
|
// 如果更新了字典类型,检查新类型是否存在
|
|
if (isset($data['dict_type']) && $data['dict_type'] !== $dictData->dict_type) {
|
|
$dictType = SystemDictType::findByType($data['dict_type']);
|
|
if (!$dictType) {
|
|
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR, '字典类型不存在');
|
|
}
|
|
}
|
|
|
|
// 检查字典值是否已存在(排除当前记录)
|
|
if (isset($data['value']) || isset($data['dict_type'])) {
|
|
$checkType = $data['dict_type'] ?? $dictData->dict_type;
|
|
$checkValue = $data['value'] ?? $dictData->value;
|
|
|
|
if (SystemDictData::valueExists($checkValue, $checkType, $id)) {
|
|
throw new BusinessException(ResponseEnum::CLIENT_PARAMETER_ERROR, '字典值已存在');
|
|
}
|
|
}
|
|
|
|
try {
|
|
$dictData->update($data);
|
|
|
|
Log::info('字典数据更新成功', ['id' => $id, 'data' => $data]);
|
|
|
|
return $dictData->refresh();
|
|
} catch (\Exception $e) {
|
|
Log::error('字典数据更新失败', ['id' => $id, 'error' => $e->getMessage(), 'data' => $data]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '更新字典数据失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除字典数据
|
|
*
|
|
* @param int $id
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function delete(int $id): bool
|
|
{
|
|
$dictData = $this->getById($id);
|
|
|
|
try {
|
|
DB::transaction(function () use ($dictData) {
|
|
$dictData->delete();
|
|
});
|
|
|
|
Log::info('字典数据删除成功', ['id' => $id, 'dict_type' => $dictData->dict_type, 'value' => $dictData->value]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('字典数据删除失败', ['id' => $id, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '删除字典数据失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 批量删除字典数据
|
|
*
|
|
* @param array $ids
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function batchDelete(array $ids): bool
|
|
{
|
|
// 检查所有字典数据是否存在
|
|
$dictDataList = SystemDictData::whereIn('id', $ids)->get();
|
|
if ($dictDataList->count() !== count($ids)) {
|
|
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR, '部分字典数据不存在');
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($ids) {
|
|
SystemDictData::whereIn('id', $ids)->delete();
|
|
});
|
|
|
|
Log::info('批量删除字典数据成功', ['ids' => $ids]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('批量删除字典数据失败', ['ids' => $ids, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '批量删除字典数据失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新字典数据状态
|
|
*
|
|
* @param int $id
|
|
* @param int $status
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function updateStatus(int $id, int $status): bool
|
|
{
|
|
$dictData = $this->getById($id);
|
|
|
|
if (!in_array($status, [SystemDictData::STATUS_NORMAL, SystemDictData::STATUS_DISABLED])) {
|
|
throw new BusinessException(ResponseEnum::CLIENT_PARAMETER_ERROR, '无效的状态值');
|
|
}
|
|
|
|
try {
|
|
$dictData->update(['status' => $status]);
|
|
|
|
Log::info('字典数据状态更新成功', ['id' => $id, 'status' => $status]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('字典数据状态更新失败', ['id' => $id, 'status' => $status, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '更新状态失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 批量更新状态
|
|
*
|
|
* @param array $ids
|
|
* @param int $status
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function batchUpdateStatus(array $ids, int $status): bool
|
|
{
|
|
if (!in_array($status, [SystemDictData::STATUS_NORMAL, SystemDictData::STATUS_DISABLED])) {
|
|
throw new BusinessException(ResponseEnum::CLIENT_PARAMETER_ERROR, '无效的状态值');
|
|
}
|
|
|
|
try {
|
|
SystemDictData::whereIn('id', $ids)->update(['status' => $status]);
|
|
|
|
Log::info('批量更新字典数据状态成功', ['ids' => $ids, 'status' => $status]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('批量更新字典数据状态失败', ['ids' => $ids, 'status' => $status, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '批量更新状态失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新排序
|
|
*
|
|
* @param int $id
|
|
* @param int $sort
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function updateSort(int $id, int $sort): bool
|
|
{
|
|
$dictData = $this->getById($id);
|
|
|
|
try {
|
|
$dictData->update(['sort' => $sort]);
|
|
|
|
Log::info('字典数据排序更新成功', ['id' => $id, 'sort' => $sort]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('字典数据排序更新失败', ['id' => $id, 'sort' => $sort, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '更新排序失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 批量更新排序
|
|
*
|
|
* @param array $sortData 格式:[['id' => 1, 'sort' => 1], ['id' => 2, 'sort' => 2]]
|
|
* @return bool
|
|
* @throws BusinessException
|
|
*/
|
|
public function batchUpdateSort(array $sortData): bool
|
|
{
|
|
try {
|
|
DB::transaction(function () use ($sortData) {
|
|
foreach ($sortData as $item) {
|
|
SystemDictData::where('id', $item['id'])->update(['sort' => $item['sort']]);
|
|
}
|
|
});
|
|
|
|
Log::info('批量更新字典数据排序成功', ['sort_data' => $sortData]);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::error('批量更新字典数据排序失败', ['sort_data' => $sortData, 'error' => $e->getMessage()]);
|
|
throw new BusinessException(ResponseEnum::SYSTEM_ERROR, '批量更新排序失败');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 根据字典类型获取选项列表
|
|
*
|
|
* @param string $dictType
|
|
* @param bool $onlyActive
|
|
* @return array
|
|
*/
|
|
public function getOptions(string $dictType, bool $onlyActive = true): array
|
|
{
|
|
return SystemDictData::getOptionsByType($dictType, $onlyActive);
|
|
}
|
|
|
|
/**
|
|
* 根据字典类型和值获取标签
|
|
*
|
|
* @param string $dictType
|
|
* @param string $value
|
|
* @return string|null
|
|
*/
|
|
public function getLabel(string $dictType, string $value): ?string
|
|
{
|
|
return SystemDictData::getLabelByTypeAndValue($dictType, $value);
|
|
}
|
|
|
|
/**
|
|
* 获取字典数据的统计信息
|
|
*
|
|
* @param string|null $dictType
|
|
* @return array
|
|
*/
|
|
public function getStatistics(?string $dictType = null): array
|
|
{
|
|
$query = SystemDictData::query();
|
|
|
|
if ($dictType) {
|
|
$query->where('dict_type', $dictType);
|
|
}
|
|
|
|
$total = $query->count();
|
|
$normal = $query->clone()->where('status', SystemDictData::STATUS_NORMAL)->count();
|
|
$disabled = $query->clone()->where('status', SystemDictData::STATUS_DISABLED)->count();
|
|
|
|
return [
|
|
'total' => $total,
|
|
'normal' => $normal,
|
|
'disabled' => $disabled,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 根据字典类型获取字典数据分组统计
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getGroupStatistics(): array
|
|
{
|
|
return SystemDictData::select('dict_type', DB::raw('count(*) as total'))
|
|
->groupBy('dict_type')
|
|
->with('dictType:type,name')
|
|
->get()
|
|
->toArray();
|
|
}
|
|
}
|