npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ruovea/dict

v1.1.0

Published

KeGie.Admin 字典管理模块

Readme

@ruovea/dict

KeGie.Admin 字典管理模块(字典类型 / 字典值常规/动态/定制/图片),以 pnpm 源码包 形式提供给各宿主项目复用。

  • 不打 dist、不发 npm——exports 直指 ./src/*,由宿主 Vite 编译
  • 内置字典兜底——包内自带 38 个常用枚举常量(GenderEnum / AccountTypeEnum / StatusEnum / MenuTypeEnum / DataScopeEnum 等),宿主零配置即可使用
  • 依赖注入解耦——request / auth / i18n / ModifyRecord / userApi 由宿主装配时注入
  • 零侵入——包内不含 /@/ 等宿主别名引用,可脱离 KeGie.Admin 运行

一、目录结构

src/
├─ index.ts              # 入口:导出 DictPlugin + API + 类型 + 路由
├─ plugin.ts             # Vue install(校验必填项 / provide / 全局注册 GSysDict / mergeLocaleMessage)
├─ context.ts            # InjectionKey + useDictContext() + mergeDictList 合并逻辑
├─ types.ts              # DictPluginOptions / DictEndpoints / DictContext
├─ builtinDictList.ts    # 内置字典常量(38 个枚举,3000+ 条目,零配置兜底)
├─ routes.ts             # 路由 + dictDynamicComponents 动态组件映射
├─ api/
│  ├─ index.ts           # dict-type + dict-data
│  ├─ http.ts            # request 注入点
│  ├─ endpoints.ts       # URL 前缀(可覆盖)
│  ├─ dict-type.ts       # 字典类型 API
│  └─ dict-data.ts       # 字典值 API
├─ components/
│  ├─ SysDict.vue        # 字典显示组件(全局注册为 GSysDict)
│  ├─ dictForm.vue       # 字典类型新增弹窗
│  └─ dictData.vue       # 字典值查看弹窗
├─ i18n/locales/         # 6 语言(en / fr-fr / ja-jp / vi-vn / zh-cn / zh-tw)
└─ views/dicttyp/
   ├─ index.vue                          # 字典类型+字典值双栏管理
   ├─ component/editDictType.vue          # 字典类型编辑弹窗
   ├─ component/editDictData.vue          # 字典值编辑弹窗
   └─ values/
      ├─ normal/                          # 常规字典值
      ├─ dynamic/                         # 动态字典值
      ├─ custom/                          # 定制字典值
      └─ image/                           # 图片字典值

二、字典数据策略(核心设计)

2.1 内置常量兜底

src/builtinDictList.ts 内置 38 个常用枚举的完整字典数据(从历史项目硬编码常量恢复),包括但不限于:

| Code | 说明 | |------|------| | GenderEnum | 性别 | | AccountTypeEnum | 账号类型 | | StatusEnum | 启用/禁用状态 | | MenuTypeEnum | 菜单类型 | | DataScopeEnum | 数据范围 | | YesNoEnum | 是/否 | | NoticeTypeEnum | 通知类型 | | JobStatusEnum | 任务状态 | | ... | (共 38 个) |

宿主即使不注入任何字典数据,<g-sys-dict> 也能用内置常量渲染——零配置可用。

2.2 合并策略:已有则更新,没有则补充,多余则删除

context.ts 的 buildDictContext 自动合并两层数据,宿主后端数据为权威来源:

getDictList() → mergeDictList(宿主注入的 dictList)
                 ├─ 内置 builtinDictList 作为基底(始终保留)
                 └─ 遍历宿主数据,逐 code 合并

| 场景 | 结果 | |------|------| | 内置有 GenderEnum,宿主也有 | 用宿主数据(更新为最新) | | 内置没有 CustomCode,宿主有 | 补充宿主数据 | | 内置有 GenderEnum,宿主没有 | 保留内置(兜底) | | 内置有 SomeEnum,宿主返回空数组 | 删除该 code(宿主要求清空) | | 宿主未注入 getDictList | 全部用内置 |

2.3 引用内置常量

宿主可直接导入内置常量,用于自定义视图:

import { builtinDictList } from '@ruovea/dict/builtinDictList';

// 查看某 code 是否有内置数据
console.log(builtinDictList['GenderEnum']);

三、宿主接入

3.1 安装

{
  "dependencies": {
    "@ruovea/dict": "link:../../module/dict-module/packages/dict"
  }
}

3.2 Vite 预构建排除

宿主 vite.config.ts 必须将包加入 optimizeDeps.exclude,否则预构建产物与源码各持一份模块级 _request,导致 request 未注入 运行时报错:

optimizeDeps: {
    exclude: ['vue-demi', '@ruovea/dict'],
},

3.3 装配插件

// plugins/dict.ts
import { defineAsyncComponent, type App } from 'vue';
import { DictPlugin } from '@ruovea/dict';
import request from '/@/utils/request';
import { auth } from '/@/utils/authFunction';
import { i18n } from '/@/i18n/index';
import { useUserInfo } from '/@/stores/userInfo';

export function setupDict(app: App) {
    const userStore = useUserInfo();
    app.use(DictPlugin, {
        request: request as any,
        auth,
        i18n: i18n as any,
        components: {
            ModifyRecord: defineAsyncComponent(() => import('/@/components/table/modifyRecord.vue')),
        },
        userApi: {
            getUserInfo: () => userStore.userInfos,
            refreshDict: () => userStore.setDictList(),
            getDictList: () => userStore.dictList,  // 可选,缺失时用内置常量兜底
        },
    });
}
// main.ts
import { setupDict } from '/@/plugins/dict';
// ... app.use(pinia) 之后
setupDict(app);

3.4 最小化接入(零配置)

如果宿主只需 <g-sys-dict> 组件显示字典,不需要字典管理页面,最小化配置如下:

app.use(DictPlugin, {
    request: request as any,
    components: {
        ModifyRecord: defineAsyncComponent(() => import('...')),
    },
});

不传 userApi.getDictList 时,<g-sys-dict> 自动用内置常量渲染。


四、DictPluginOptions 说明

| 字段 | 必填 | 说明 | |------|------|------| | request | ✅ | 宿主 axios 实例(已配 baseURL / token / 拦截器) | | components.ModifyRecord | ✅ | 修改记录展示组件 | | components.GSysDict | ➖ | 字典显示组件(已下沉到包内,插件自动全局注册。仅需要自定义覆盖时传入) | | auth | ➖ | (code: string) => boolean,按钮权限校验,缺省 () => true | | i18n | ➖ | 宿主 vue-i18n 实例(传入后自动合并模块语言包) | | registerI18n | ➖ | 是否自动注册 i18n,默认 true | | userApi.getUserInfo | ➖ | 获取当前用户信息(含 accountType,用于判断超管) | | userApi.refreshDict | ➖ | 刷新字典缓存 | | userApi.getDictList | ➖ | 获取字典全量数据(按 typeCode 分组)。缺失时用内置常量兜底 | | endpoints | ➖ | 覆盖 API URL 前缀 |


五、GSysDict 组件

5.1 全局注册

DictPlugin.install 执行 app.component('GSysDict', SysDict) 全局注册,宿主模板中直接使用,无需手动注册:

<g-sys-dict v-model="row.status" code="StatusEnum" />

5.2 Props

| Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | any | — | 绑定值(必填) | | code | string | — | 字典类型编码,如 GenderEnum(必填) | | renderAs | 'tag'\|'select'\|'radio'\|'checkbox' | 'tag' | 渲染方式 | | propLabel | string | 'label' | 显示文字字段名 | | propValue | string | 'value' | 值字段名 | | onItemFilter | (dict) => boolean | () => true | 过滤字典项 | | onItemFormatter | (dict) => string | — | 自定义显示文字 | | multiple | boolean | false | 多选(仅 select / checkbox) |

5.3 使用示例

<!-- tag 显示(表格列内) -->
<g-sys-dict v-model="scope.row.isDisable" code="StatusEnum" />

<!-- 下拉选择(搜索栏) -->
<g-sys-dict v-model="queryParams.type" code="MenuTypeEnum" render-as="select"
    placeholder="请选择" clearable />

<!-- 单选(表单) -->
<g-sys-dict v-model="form.sex" code="GenderEnum" render-as="radio" />

<!-- 带过滤 -->
<g-sys-dict v-model="form.adminType" code="AccountTypeEnum" render-as="select"
    :on-item-filter="(data) => data.code !== 'SuperAdmin'" />

六、路由

6.1 路由清单

| path | name | isHide | keepAlive | 说明 | |------|------|--------|-----------|------| | /system/dicttyp | dicttyp | ❌ | ✅ | 字典类型+字典值双栏(主页) | | /system/dicttyp/values/normal | dictValueNomal | ✅ | ✅ | 常规字典值 | | /system/dicttyp/values/dynamic | dictValueDynamic | ✅ | ✅ | 动态字典值 | | /system/dicttyp/values/custom | dictValueCustom | ✅ | ✅ | 定制字典值 | | /system/dicttyp/values/image | dictValueImage | ✅ | ✅ | 图片字典值 |

6.2 dictDynamicComponents(后端动态路由映射)

// router/backEnd.ts
import { dictDynamicComponents } from '@ruovea/dict';

export function dynamicImport(dynamicViewsModules, component) {
    if (dictDynamicComponents[component]) return dictDynamicComponents[component];
    // ...
}

6.3 dictValueRoutes(4 条隐藏子页)

4 条子页由 dicttyp 主页 router.push 带 query 跳转,不由后端菜单下发。宿主必须在静态路由中展开:

// router/route.ts
import { dictValueRoutes } from '@ruovea/dict';

export const notFoundAndNoPower = [
    // ... 404 / 401 / dashboard / userCenter
    ...dictValueRoutes,
];

七、权限编码清单

| 编码 | 位置 | 说明 | |------|------|------| | sysDictType:pages | 字典类型列表 | 查询 | | sysDictType:addData | 字典类型列表 | 新增 | | sysDictType:updateData | 字典类型列表 | 编辑 | | sysDictType:deleteData | 字典类型列表 | 删除 | | sysDictValue:pages | 字典值列表 | 查询 | | sysDictValue:addData | 字典值列表 | 新增 | | sysDictValue:updateData | 字典值列表 | 编辑 | | sysDictValue:deleteData | 字典值列表 | 删除 |


八、i18n 注入约定

包内视图使用 message.dict.xxx、message.dicttyp.xxx、message.dictValueNomal.xxx 等 key。插件双层 merge(顶层 + message 层),菜单翻译资源自包含。

支持 6 种语言:zh-cn / zh-tw / en / ja-jp / fr-fr / vi-vn。


九、被其他包依赖

@ruovea/dict 可被其他 @ruovea/* 包作为 peerDependencies 引用。例如 @ruovea/system 的视图内大量使用 <g-sys-dict code="GenderEnum">,只要宿主已装配 DictPlugin,这些视图就能正常渲染——字典数据来自内置常量或宿主注入,无需额外配置。


十、License

MIT