study-api-v2/app/Services/System/SystemDictDataService.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();
}
}