Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_AntdVue/zh/core/dict.md
T
2026-10-08 17:50:29 +08:00

12 KiB
Raw Blame History

5.10 字典模块

:::tip 概述 字典体系由三个服务组成:DictService(字典 CRUD,DictController 注入)、DictItemService(字典项 CRUD)、DictCacheService(字典项读取、正反向转换与缓存管理,本页主体)。读取侧采用两级缓存(请求级 + 持久缓存),同一请求内不重复查库,跨请求复用持久缓存;字典项变更时 DictItemObserver 自动失效对应缓存。 :::

字典体系架构

┌─────────────────────────────────────────────────────────────────────┐
│                         字典体系                                     │
│                                                                     │
│  ┌──────────────────┐    ┌──────────────────┐                      │
│  │ laravel_dict     │    │ laravel_dict_item│                      │
│  │ 字典主表         │    │ 字典项表         │                      │
│  │                  │    │                  │                      │
│  │ id               │◄───│ dict_id          │                      │
│  │ name (字典名称)  │    │ name (项名称)    │                      │
│  │ code (字典编码)  │    │ value (项值)     │                      │
│  │ remark           │    │ sort (排序)      │                      │
│  └──────────────────┘    │ note (备注)      │                      │
│                          └──────────────────┘                      │
│                                                                     │
│  ┌──────────────────┐    ┌──────────────────┐                      │
│  │ DictCacheService      │    │ Service 层        │                      │
│  │ 字典服务         │    │ serializeMaps     │                      │
│  │                  │    │ 自动翻译          │                      │
│  │ getText()        │    │                  │                      │
│  │ getValue()       │◄───│ 'status' =>      │                      │
│  │ getOptions()     │    │   'user_status'  │                      │
│  │ clearCache()     │    │                  │                      │
│  └──────────────────┘    └──────────────────┘                      │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │ DictItemObserver(字典项变更 → 自动清除所属字典缓存)          │  │
│  └──────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

缓存架构

请求级缓存(静态变量)              ← 同一请求内不重复查库
        │ 未命中
        ▼
持久缓存(cache() 门面,1小时)      ← 跨请求复用(Redis)
        │ 未命中
        ▼
数据库查询(dict → dict_item)       ← 查询后写入两级缓存

缓存 Key 格式

缓存类型 Key 格式 存储内容
请求级 $localCache['gender'] ['1'=>'男', '2'=>'女']
持久缓存 dict_gender(前缀 CACHE_PREFIX='dict_') ['1'=>'男', '2'=>'女']

缓存生命周期

1. 首次查询 → 数据库 → 写入持久缓存 + 请求级缓存
2. 同一请求再次命中 → 直接返回请求级缓存(最快)
3. 不同请求命中 → 读取持久缓存(不查库)
4. 缓存过期(TTL 见 DictCacheService::CACHE_TTL)→ 重新查库 → 更新两级缓存
5. 字典项变更 → DictItemObserver 自动调用 clearCache() → 下次查询重新加载

核心方法

getText — 根据值获取名称(最常用)

DictCacheService::getText('gender', 1);          // '男'
DictCacheService::getText('user_status', 1);     // '正常'
DictCacheService::getText('gender', '');         // ''(空值返回空字符串)
DictCacheService::getText('gender', null);       // ''(空值返回空字符串)

用途: 列表展示时将数据库值转换为可读名称。

getValue — 根据名称反向获取值

DictCacheService::getValue('gender', '男');          // '1'
DictCacheService::getValue('user_status', '正常');    // '1'
DictCacheService::getValue('gender', '');            // ''(空值返回空字符串)

用途: Excel 导入时将中文文字转换为数据库存储的数值(ExampleService::import() 即用此方法反查状态文本)。

getOptions — 获取下拉框选项

DictCacheService::getOptions('gender');
// [
//     ['label' => '男', 'value' => '1'],
//     ['label' => '女', 'value' => '2'],
// ]

用途: 前端下拉框、单选框、复选框组件的数据源。

getItems — 获取值→名称映射

DictCacheService::getItems('gender');
// ['1' => '男', '2' => '女']

getBatchTextMaps — 批量获取多个字典的映射

DictCacheService::getBatchTextMaps(['gender', 'user_status']);
// [
//     'gender'      => ['1' => '男', '2' => '女'],
//     'user_status' => ['1' => '正常', '2' => '禁用'],
// ]

用途: 列表翻译时一次取多个字典,避免逐个查询。

clearCache / clearAllCache — 缓存管理

DictCacheService::clearCache('gender');    // 清除指定字典的缓存
DictCacheService::clearCache();            // 仅清空请求级缓存
DictCacheService::clearAllCache();         // 清除所有字典持久缓存

方法清单

方法 说明 返回值
getText($dictCode, $value) 值 → 名称 string
getValue($dictCode, $text) 名称 → 值 string
getItems($dictCode) 获取值→名称映射 array ['1'=>'男', '2'=>'女']
getOptions($dictCode) 获取下拉框选项 array [['label'=>'男','value'=>'1'], ...]
getBatchTextMaps($codes) 批量获取多个字典映射 array [code => map, ...]
clearCache($dictCode?) 清除指定/请求级缓存 void
clearAllCache() 清除所有字典缓存 void

在 Service 中使用

自动翻译(serializeMaps)

配置 serializeMaps 后(需 use HasSerializeMaps),查询数据时自动补全 {字段名}Text 字段,无需手动调用 DictCacheService:

class UserService extends BaseTenantService
{
    /**
     * 字典翻译配置:[字段 => 字典编码]
     *
     * @var array<string, string>
     */
    protected array $serializeMaps = [
        'gender' => 'gender',
        'status' => 'user_status',
    ];
}

效果:

数据库:{ gender: 1, status: 1 }
    │
    ▼ processSerializeMapsList()
    │ DictCacheService 批量取词(getBatchTextMaps,同一请求只查一次)
    │   getText('gender', 1) → '男'
    │   getText('user_status', 1) → '正常'
    ▼
前端接收:{ gender: 1, genderText: '男', status: 1, statusText: '正常' }

手动调用

// 在 Service 中手动调用
$genderText = DictCacheService::getText('gender', $user['gender']);
$options = DictCacheService::getOptions('gender');

在 Controller 中使用

获取字典项(前端下拉数据源)

# routes/api.php(认证组内)
GET /api/dict/item/getDictItemList/{code}

刷新字典缓存

/**
 * 刷新字典缓存
 *
 * GET /api/dict/refreshCache
 */
public function refreshCache(): JsonResponse
{
    DictCacheService::clearAllCache();
    return $this->success(null, '缓存刷新成功');
}

在导入导出中使用

导入时:文字转值

// ExampleService::import()(来自项目实际代码)
foreach ($data as &$row) {
    // Excel 中"在用" → 数据库中 1
    if (! empty($row['status']) && ! is_numeric($row['status'])) {
        $row['status'] = DictCacheService::getValue('example_status', $row['status']);
    }
}
unset($row);

导出时:值转文字

// 导出表头使用 Text 后缀字段(由 serializeMaps 自动补全)
$headers = [
    'name'       => '名称',
    'statusText' => '状态',      // 自动翻译后的字段
];

前端集成

获取字典选项

// API
export function getDictItemByCode(code: string) {
  return http.request({ url: `/dict/item/getDictItemList/${code}`, method: 'GET' });
}

// 使用
const genderOptions = ref([]);
onMounted(async () => {
  genderOptions.value = await getDictItemByCode('gender');
});

下拉框组件

<template>
  <el-select v-model="form.gender" placeholder="请选择性别">
    <el-option
      v-for="item in genderOptions"
      :key="item.value"
      :label="item.name"
      :value="item.value"
    />
  </el-select>
</template>

数据库表结构

laravel_dict(字典主表)

字段 类型 说明 示例
id INT 主键 1
name VARCHAR(50) 字典名称 性别
code VARCHAR(50) 字典编码(唯一) gender
remark VARCHAR(500) 备注 性别字典
... 公共字段

laravel_dict_item(字典项表)

字段 类型 说明 示例
id INT 主键 1
dict_id INT 字典 ID(外键) 1
name VARCHAR(50) 项名称(显示标签) 男
value VARCHAR(50) 项值 1
sort INT 排序 1
note VARCHAR(200) 备注
... 公共字段

字典编码规范

字典编码 名称 项值 用途
gender 性别 1=男, 2=女, 3=保密 用户性别
user_status 用户状态 1=正常, 2=禁用 用户账号状态
tenant_status 租户状态 1=启用, 0=禁用 租户状态
example_type 案例类型 1=类型1, 2=类型2, 3=类型3, 4=类型4 案例分类
example_status 案例状态 1=在用, 2=停用 案例状态

(项值以数据库初始化脚本中的实际字典项为准。)

缓存管理

缓存失效时机

时机 操作 说明
字典项新增/修改/删除 DictItemObserver 自动清除 模型事件触发,无需手动
手动刷新 GET /api/dict/refreshCache 清除所有字典缓存
命令行清理 php artisan dict:clear-cache 运维兜底
缓存过期 自动失效 TTL 见 CACHE_TTL

:::tip 缓存一致性已自动保障 字典项(DictItem)保存/删除时 DictItemObserver 自动调用 clearCache($code)——业务代码无需手动刷新;上面的手动接口与命令仅作兜底(如直接改库绕过模型事件)。 :::

安全特性

特性 说明
两级缓存 请求级 + 持久缓存,减少数据库压力
空值安全 getText/getValue 对 null/空字符串返回空字符串
类型安全 值统一转为字符串比较,避免类型松散比较问题
缓存隔离 每个字典编码独立缓存,互不影响
自动失效 Observer 保证数据变更后缓存不脏