签入版本
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
# 6.5 职级管理
|
||||
|
||||
:::tip 概述
|
||||
职级管理维护用户的职级属性数据,支持 Excel 导入导出。继承 BaseTenantLogic 实现租户隔离。
|
||||
职级管理维护用户的职级属性数据,支持 Excel 导入导出。`LevelService` 继承 `BaseTenantService` 实现租户隔离,是"属性配置 + 导入导出扩展方法"的标准组合示例。
|
||||
:::
|
||||
|
||||
## 模块特点
|
||||
|
||||
| 特性 | 说明 |
|
||||
|------|------|
|
||||
| 基类 | BaseTenantLogic(租户隔离) |
|
||||
| 唯一校验 | name 全局唯一 |
|
||||
| 枚举映射 | status → level_status 字典(1=在用 2=停用) |
|
||||
| 导入导出 | 支持 Excel 导入导出 |
|
||||
| 基类 | `BaseTenantService`(租户隔离) |
|
||||
| 唯一校验 | `name` 按租户分组唯一(`['name','tenant_id']`) |
|
||||
| 枚举映射 | `status` → level_status 字典(1=在用 2=停用) |
|
||||
| 删除保护 | `beforeDelete` 检查业务约束 |
|
||||
| 导入导出 | 支持 Excel 导入导出(`export` / `import` 扩展方法) |
|
||||
|
||||
## API 接口
|
||||
|
||||
@@ -19,82 +20,52 @@
|
||||
|------|------|--------|------|
|
||||
| GET | `/api/level/page` | sys:level:page | 分页列表 |
|
||||
| GET | `/api/level/list` | sys:level:list | 全量列表 |
|
||||
| GET | `/api/level/detail/:id` | sys:level:detail | 详情 |
|
||||
| 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/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 | 导入 |
|
||||
|
||||
## 核心代码
|
||||
|
||||
### Logic 配置
|
||||
## Service 配置(来自项目实际代码)
|
||||
|
||||
```php
|
||||
// app/logic/LevelLogic.php
|
||||
|
||||
class LevelLogic extends BaseTenantLogic
|
||||
class LevelService extends BaseTenantService
|
||||
{
|
||||
/**
|
||||
* 关联的模型类
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
use HasCrudOperations, HasQueryScopes, HasSerializeMaps, HasUniqueCheck;
|
||||
|
||||
protected string $modelClass = Level::class;
|
||||
|
||||
/**
|
||||
* LIKE 模糊匹配字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $pageLikeFields = ['name'];
|
||||
|
||||
/**
|
||||
* 精确匹配字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $pageEqFields = ['status'];
|
||||
|
||||
/**
|
||||
* 默认排序规则
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $pageOrderBy = [
|
||||
['field' => 'tenant_id', 'type' => 'asc'],
|
||||
['field' => 'sort', 'type' => 'asc'],
|
||||
];
|
||||
|
||||
/**
|
||||
* 唯一性校验字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $uniqueFields = ['name'];
|
||||
// name 在同一租户内唯一
|
||||
protected array $uniqueFields = [['name', 'tenant_id']];
|
||||
|
||||
/**
|
||||
* 枚举显示名映射
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
// 字典翻译
|
||||
protected array $serializeMaps = [
|
||||
'status' => 'level_status',
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### 导出方法
|
||||
## 导出方法
|
||||
|
||||
```php
|
||||
// app/Services/LevelService.php(来自项目实际代码)
|
||||
|
||||
public function export(array $params = []): string
|
||||
{
|
||||
$list = $this->allList($params);
|
||||
|
||||
$headers = [
|
||||
'name' => '职级名称',
|
||||
'statusText' => '状态', // 枚举显示名
|
||||
'statusText' => '状态', // 枚举显示名(serializeMaps 已补全)
|
||||
'sort' => '排序',
|
||||
'create_user' => '创建人',
|
||||
'create_time' => '创建时间',
|
||||
@@ -104,9 +75,11 @@ public function export(array $params = []): string
|
||||
}
|
||||
```
|
||||
|
||||
### 导入方法
|
||||
## 导入方法
|
||||
|
||||
```php
|
||||
// app/Services/LevelService.php(来自项目实际代码)
|
||||
|
||||
public function import(string $filePath): array
|
||||
{
|
||||
$headerMap = [
|
||||
@@ -119,8 +92,8 @@ public function import(string $filePath): array
|
||||
|
||||
// 枚举字段反向映射:文字转数字
|
||||
foreach ($data as &$row) {
|
||||
if (!empty($row['status']) && !is_numeric($row['status'])) {
|
||||
$row['status'] = DictService::getValue('level_status', $row['status']);
|
||||
if (! empty($row['status']) && ! is_numeric($row['status'])) {
|
||||
$row['status'] = DictCacheService::getValue('level_status', $row['status']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,11 +101,11 @@ public function import(string $filePath): array
|
||||
$errors = [];
|
||||
foreach ($data as $index => $row) {
|
||||
try {
|
||||
$this->add($row);
|
||||
$this->add($row); // 走完整 add 流程(钩子/唯一校验/事务)
|
||||
$count++;
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = [
|
||||
'row' => $index + 2,
|
||||
'row' => $index + 2, // +2:表头占第 1 行
|
||||
'name' => $row['name'] ?? '',
|
||||
'reason' => $e->getMessage(),
|
||||
];
|
||||
@@ -143,6 +116,21 @@ public function import(string $filePath): array
|
||||
}
|
||||
```
|
||||
|
||||
:::tip 导入导出模式
|
||||
LevelLogic 是导入导出的标准实现示例。导出使用 `allList()` 获取全量数据,导入使用 `ExcelService::importWithMap()` 解析文件,枚举字段通过 `DictService::getValue()` 反向映射。
|
||||
:::
|
||||
:::tip 导入导出标准模板
|
||||
LevelService 是导入导出的标准实现示例:导出用 `allList()` 取全量数据 + `ExcelService::export()`;导入用 `ExcelService::importWithMap()` 表头映射 + 字典反查 + 逐条 `add()`(单条失败不中断,明细汇总返回)。与 `ExampleService` 同构。
|
||||
:::
|
||||
|
||||
## 导入导出流程
|
||||
|
||||
```text
|
||||
导出:
|
||||
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[] }
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user