Files
2026-10-08 17:50:29 +08:00

4.2 KiB
Raw Permalink Blame History

6.5 职级管理

:::tip 概述 职级管理维护用户的职级属性数据,支持 Excel 导入导出。LevelService 继承 BaseTenantService 实现租户隔离,是"属性配置 + 导入导出扩展方法"的标准组合示例。 :::

模块特点

特性 说明
基类 BaseTenantService(租户隔离)
唯一校验 name 按租户分组唯一(['name','tenant_id'])
枚举映射 status → level_status 字典(1=在用 2=停用)
删除保护 beforeDelete 检查业务约束
导入导出 支持 Excel 导入导出(export / import 扩展方法)

API 接口

方法 路径 权限码 说明
GET /api/level/page sys:level:page 分页列表
GET /api/level/list sys:level:list 全量列表
GET /api/level/detail/{id} sys:level:detail 详情
POST /api/level/add sys:level:add 新增
PUT /api/level/update sys:level:update 修改
DELETE /api/level/delete/{id} sys:level:delete 删除
DELETE /api/level/batchDelete sys:level:batchDelete 批量删除
GET /api/level/export sys:level:export 导出
POST /api/level/import sys:level:import 导入

Service 配置(来自项目实际代码)

class LevelService extends BaseTenantService
{
    use HasCrudOperations, HasQueryScopes, HasSerializeMaps, HasUniqueCheck;

    protected string $modelClass = Level::class;

    protected array $pageLikeFields = ['name'];
    protected array $pageEqFields = ['status'];
    protected array $pageOrderBy = [
        ['field' => 'tenant_id', 'type' => 'asc'],
        ['field' => 'sort', 'type' => 'asc'],
    ];

    // name 在同一租户内唯一
    protected array $uniqueFields = [['name', 'tenant_id']];

    // 字典翻译
    protected array $serializeMaps = [
        'status' => 'level_status',
    ];
}

导出方法

// app/Services/LevelService.php(来自项目实际代码)

public function export(array $params = []): string
{
    $list = $this->allList($params);

    $headers = [
        'name'        => '职级名称',
        'statusText'  => '状态',      // 枚举显示名(serializeMaps 已补全)
        'sort'        => '排序',
        'create_user' => '创建人',
        'create_time' => '创建时间',
    ];

    return ExcelService::export($list, $headers, '职级数据.xlsx');
}

导入方法

// app/Services/LevelService.php(来自项目实际代码)

public function import(string $filePath): array
{
    $headerMap = [
        '职级名称' => 'name',
        '状态'    => 'status',
        '排序'    => 'sort',
    ];

    $data = ExcelService::importWithMap($filePath, $headerMap);

    // 枚举字段反向映射:文字转数字
    foreach ($data as &$row) {
        if (! empty($row['status']) && ! is_numeric($row['status'])) {
            $row['status'] = DictCacheService::getValue('level_status', $row['status']);
        }
    }

    $count = 0;
    $errors = [];
    foreach ($data as $index => $row) {
        try {
            $this->add($row);        // 走完整 add 流程(钩子/唯一校验/事务)
            $count++;
        } catch (\Exception $e) {
            $errors[] = [
                'row'    => $index + 2,   // +2:表头占第 1 行
                'name'   => $row['name'] ?? '',
                'reason' => $e->getMessage(),
            ];
        }
    }

    return ['count' => $count, 'errors' => $errors];
}

:::tip 导入导出标准模板 LevelService 是导入导出的标准实现示例:导出用 allList() 取全量数据 + ExcelService::export();导入用 ExcelService::importWithMap() 表头映射 + 字典反查 + 逐条 add()(单条失败不中断,明细汇总返回)。与 ExampleService 同构。 :::

导入导出流程

导出:
GET /api/level/export → _export() → Service::export()
    → allList()(含字典翻译) → ExcelService::export() → 返回文件 URL

导入:
POST /api/level/import(FormData)
    → _import()(校验扩展名 xls/xlsx + MIME + 10MB 上限)
    → Service::import()
        → importWithMap 解析 → 字典反查 → 逐条 add()
    → 返回 { count, errors[] }