ITPub博客

首页 > 应用开发 > Javascript > Rime小狼毫和雾凇拼音方案是两个非常不错的项目

Rime小狼毫和雾凇拼音方案是两个非常不错的项目

投稿 Javascript 作者:ecclw459 时间:2026-01-14 09:36:52 0 删除 编辑
customization:
  distribution_code_name: Weasel
  distribution_version: 0.16.3
  generator: "Rime::SwitcherSettings"
  modified_time: "Wed Dec 31 08:34:49 2025"
  rime_version: 1.11.2
patch:  "menu/page_size": 9
  schema_list:
    - {schema: rime_ice}  "switcher/hotkeys":
    - "Control+grave"
    - "Control+F3"
  key_binder:
    bindings:
      - { when: composing, accept: comma,  send: Page_Up }  #翻页
      - { when: composing, accept: period, send: Page_Down } #翻页

rime_ice.dict.yaml

import_tables:
  - cn_dicts/8105     # 字表
  # - cn_dicts/41448  # 大字表(按需启用)(启用时和 8105 同时启用并放在 8105 下面)
  - cn_dicts/base     # 基础词库
  - cn_dicts/ext      # 扩展词库
  - cn_dicts/tencent  # 腾讯词向量(大词库,部署时间较长)
  - cn_dicts/others   # 一些杂项
  - cn_dicts/myqq     #你的词库

把qq词库放在
Rime\cn_dicts下myqq.dict.yam

转换python程序

import re
input_file = "QQPinyin_2025_12_31.txt"output_file = "myqq.dict.yaml"def read_lines(path):    for enc in ("utf-16", "utf-8", "gbk"):        try:            with open(path, encoding=enc) as f:                return f.readlines()        except UnicodeDecodeError:            pass
    raise RuntimeError("无法识别文件编码")
lines = read_lines(input_file)
entries = []for line in lines:
    line = line.strip()    if not line:        continue
    m = re.match(r"([a-z']+)\s+([\u4e00-\u9fa5]+)\s+(\d+)", line)    if not m:        continue
    code, word, weight = m.groups()
    pinyin = code.replace("'", " ")
    entries.append(f"{word}\t{pinyin}\t{weight}")with open(output_file, "w", encoding="utf-8") as f:
    f.write(        "---\n"
        "name: my_qq\n"
        "version: \"1.0\"\n"
        "sort: by_weight\n"
        "...\n\n"
    )
    f.write("\n".join(entries))print(f"转换完成:{len(entries)} 条")
    
    架构设计
语言解析优先级
Cookie(用户手动切换)
    ↓ (未设置)
User Settings(用户偏好)
    ↓ (未设置)
Tenant Settings(租户默认)
    ↓ (未设置)
Global Settings(系统默认)
    ↓ (未设置)
zh-CN(最终回退)
Settings 存储结构
// 全局默认语言Module: "Localization"Key: "DefaultLanguage"Value: "zh-CN"Scope: Global// 租户默认语言Module: "Localization"Key: "DefaultLanguage"Value: "en"Scope: Tenant
ScopeId: "{tenantId}"// 用户偏好语言Module: "Localization"Key: "PreferredLanguage"Value: "en"Scope: User
ScopeId: "{userId}"
🚀 快速开始
1. 配置已完成
本地化服务已在 ServiceDefaults 中自动注册,无需额外配置。
2. 后端使用
在 Controller 中使用本地化
using CodeSpirit.Localization.Resources;using Microsoft.Extensions.Localization;public class MyController : ApiControllerBase{    private readonly IStringLocalizer<SharedResources> _localizer;    
    public MyController(IStringLocalizer<SharedResources> localizer)
    {
        _localizer = localizer;
    }
    
    [HttpPost]    public IActionResult Create()
    {        return Ok(new ApiResponse 
        { 
            Status = 1, 
            Msg = _localizer["Common.Save"].Value 
        });
    }
}
抛出本地化异常
// 使用资源键throw new BusinessException("Errors.InvalidStartTime");// 带参数throw new ValidationException("Errors.NotFound", resourceId);
3. DTO 验证特性多语言
using CodeSpirit.Localization.Resources;public class CreateQuestionDto{
    [Display(Name = "Content", ResourceType = typeof(DisplayResources))]
    [Required(ErrorMessageResourceType = typeof(ValidationResources), 
             ErrorMessageResourceName = "Required")]
    [StringLength(2000, 
        ErrorMessageResourceType = typeof(ValidationResources),
        ErrorMessageResourceName = "StringLengthMax")]    public string Content { get; set; } = string.Empty;
}

DTO 字段的描述信息(Description)也支持多语言,通过  LocalizedDescriptionAttribute 实现。

4.1 创建服务资源文件

各服务应创建自己的资源文件,保持服务独立性:

资源文件结构:

CodeSpirit.ExamApi/Resources/
  ├── ExamDisplayResources.cs    # 资源占位类(包含ResourceManager)
  ├── ExamDisplay.resx           # 中文资源
  └── ExamDisplay.en.resx        # 英文资源

资源键命名规范:

  • DTO字段描述: Description.{EntityName}.{PropertyName}
  • 示例: Description.Question.Options、 Description.Question.CorrectAnswer

4.2 在DTO中使用

using CodeSpirit.Core.Attributes;using CodeSpirit.ExamApi.Resources;public class CreateQuestionDto{
    [LocalizedDescription(        "根据题目内容生成合适的选项",  // 回退文本(可选)
        ResourceKey = "Description.Question.Options",
        ResourceType = typeof(ExamDisplayResources)
    )]    public List<string> Options { get; set; }
}

使用方式:

  • 方式1:仅使用资源键(推荐)
  • 方式2:带回退文本(更安全,资源不可用时显示回退文本)
  • 方式3:使用共享资源(仅适用于通用描述)

4.3 向后兼容

现有的  DescriptionAttribute 仍然可以正常使用,系统会优先检查  LocalizedDescriptionAttribute,如果不存在则回退到  DescriptionAttribute。

4.4 资源文件组织原则

  • 共享资源: CodeSpirit.Localization/Resources/ - 存放真正通用的、跨服务的资源
  • 服务资源: ApiServices/{ServiceName}/Resources/ - 存放服务特有的业务资源

最佳实践:

  • 各服务管理自己的资源文件,避免在共享资源中放置服务特定内容
  • 遵循  Description.{EntityName}.{PropertyName} 命名约定
  • 建议提供回退文本,确保资源不可用时仍能显示

4.5 技术实现

描述多语言的资源解析由 AMIS 表单生成时统一处理:

  • CultureResolver:从 HttpContext Features、Cookie 等多个来源获取当前语言
  • 统一解析: GetLocalizedDescription 方法在表单生成时解析资源
  • 回退机制:英文环境下确保正确加载英文资源,避免回退到中文
  • 缓存优化:在同一请求中复用已解析的文化信息

5. 前端使用

JavaScript

// 获取翻译文本const message = CodeSpirit.i18n.t('Common.Save');// 带参数const message = CodeSpirit.i18n.t('Validation.Required', { 0: '用户名' });// 切换语言CodeSpirit.i18n.switchLanguage('en');

Razor 页面

@using CodeSpirit.Localization.Resources@using Microsoft.Extensions.Localization@inject IStringLocalizer<SharedResources> Localizer<h1>@Localizer["Common.Save"]</h1>

🎛️ 语言配置管理

通过 API 设置语言

系统已自动集成 Settings 组件,可以通过 Settings API 管理语言配置:

设置用户语言偏好

await _settingsService.SetUserSettingAsync(
    module: "Localization",
    key: "PreferredLanguage",    value: "en",
    userId: currentUserId
);

设置租户默认语言

await _settingsService.SetTenantSettingAsync(
    module: "Localization",
    key: "DefaultLanguage",    value: "en",
    tenantId: currentTenantId
);

设置全局默认语言

await _settingsService.SetGlobalSettingAsync(
    module: "Localization",
    key: "DefaultLanguage",    value: "en");

通过 UI 切换语言

用户可以在导航栏的语言切换器中选择语言,切换后会:

  1. 设置 Cookie( .AspNetCore.Culture)
  2. 刷新页面
  3. 所有界面文本、错误消息自动切换为对应语言

📚 资源文件说明

共享资源(Localization组件)

资源文件 用途 示例键
Shared.resx 通用 UI 文本 Common.Save,  Common.Cancel
Errors.resx 错误消息 Errors.NotFound,  Errors.Unauthorized
Validation.resx 验证消息模板 Required,  StringLengthMax
Display.resx 字段显示名称 Content,  Type,  Difficulty

每个资源文件都有对应的英文版本(如  Shared.en.resx)。

服务特定资源(各API服务)

各服务应创建自己的资源文件,保持服务独立性:

命名规范:

  • 占位类: {ServiceName}DisplayResources.cs
  • 资源文件: {ServiceName}Display.resx、 {ServiceName}Display.en.resx

示例:

CodeSpirit.ExamApi/Resources/
  ├── ExamDisplayResources.cs    # 资源占位类(包含ResourceManager)
  ├── ExamDisplay.resx           # 中文资源
  └── ExamDisplay.en.resx        # 英文资源CodeSpirit.SurveyApi/Resources/
  ├── SurveyDisplayResources.cs
  ├── SurveyDisplay.resx
  └── SurveyDisplay.en.resx

资源键命名约定:

  • DTO字段描述: Description.{EntityName}.{PropertyName}
  • 示例: Description.Question.Options、 Description.Survey.Title

🔧 常见场景

场景 1:用户切换语言

  1. 用户在导航栏选择 "English"

  2. JavaScript 调用  CodeSpirit.i18n.switchLanguage('en')

  3. 设置 Cookie 并刷新页面

导航组件使用专用的资源文件:

资源文件位置:

CodeSpirit.Navigation/Resources/
  ├── NavigationResources.cs         # 资源占位类
  ├── NavigationResources.resx       # 中文资源
  └── NavigationResources.en.resx    # 英文资源

资源键命名规范:

  • 模块名称: Module.{ModuleName}(如  Module.Identity、 Module.Survey)
  • 控制器名称: Controller.{ControllerName}(如  Controller.Users、 Controller.Roles)

在控制器中使用

导航组件支持两种特性来配置多语言: Module 特性和  NavigationAttribute 特性。

使用 Module 特性(推荐)

Module 特性用于定义模块级别的多语言配置,通常放在  ApiControllerBase 上:

using CodeSpirit.Core.Attributes;using CodeSpirit.Core.Enums;using CodeSpirit.Navigation.Resources;// 模块级配置(在 ApiControllerBase 上)[Module("identity", 
    displayName: "用户中心",  // 回退文本
    DisplayNameResourceKey = "Module.Identity",           // 资源键
    DisplayNameResourceType = typeof(NavigationResources), // 资源类型
    Icon = "fa-solid fa-user-group")]
[Navigation(
    Icon = "fa-solid fa-user-group", 
    PlatformType = PlatformType.Both,
    TitleResourceKey = "Module.Identity",           // 与 Module 的资源键保持一致
    TitleResourceType = typeof(NavigationResources)
)]public abstract class ApiControllerBase : CodeSpirit.Shared.Controllers.ApiControllerBase{
}

使用 NavigationAttribute 特性

NavigationAttribute 用于控制器级别的多语言配置:

using CodeSpirit.Core.Attributes;using CodeSpirit.Navigation.Resources;using System.ComponentModel;// 控制器级配置[DisplayName("用户管理")]
[Navigation(
    Icon = "fa-solid fa-users", 
    PlatformType = PlatformType.Tenant,
    TitleResourceKey = "Controller.Users",
    TitleResourceType = typeof(NavigationResources)
)]public class UsersController : ApiControllerBase{
}

配置要点

Module 特性:

  1. DisplayNameResourceKey:指定模块名称的资源键(必填)
  2. DisplayNameResourceType:指定资源类型,通常为  typeof(NavigationResources)(必填)
  3. displayName:回退文本,当资源不可用时显示(必填,建议提供)

NavigationAttribute 特性:

  1. TitleResourceKey:指定资源键名称(推荐填写,与 Module 的 DisplayNameResourceKey 保持一致)
  2. TitleResourceType:指定资源类型,通常为  typeof(NavigationResources)(推荐填写)
  3. Title:回退文本,当资源不可用时显示(可选,建议提供)

最佳实践:在模块级配置中,建议在  Navigation 特性中也设置  TitleResourceKey 和  TitleResourceType,与  Module 特性的资源键保持一致,确保导航多语言功能完整可靠。

工作原理

  1. 自动扫描:系统启动时,导航组件自动扫描所有控制器的  NavigationAttribute
  2. 资源解析:根据当前语言( CultureInfo.CurrentUICulture)解析对应的资源文本
  3. 缓存机制:解析后的导航树缓存到分布式缓存(Redis),提升性能
  4. 动态切换:用户切换语言后,导航菜单会自动显示对应语言

⚠️ 重要注意事项

1. 缓存问题

导航组件使用分布式缓存来提升性能,但在以下情况下可能导致多语言不生效:

症状:切换语言后,导航菜单仍显示旧语言

原因:导航树已缓存,未重新解析多语言资源

解决方案:清空导航缓存

方法1:通过缓存管理界面
  1. 访问系统平台的 缓存管理页面(路由: /cacheManagement)
  2. 在缓存列表中搜索或找到导航缓存键: CodeSpirit:Navigation:All
  3. 点击该缓存项的"删除"按钮清空缓存

注意:缓存管理功能仅系统管理员可访问,属于系统平台功能。

方法2:通过代码 API 调用
// 清空所有导航缓存await _navigationService.ClearAllNavigationCacheAsync();// 清空特定模块缓存(实际上也会清空整个缓存)await _navigationService.ClearModuleNavigationCacheAsync("Identity");// 重新初始化导航树(清空并重建缓存)await _navigationService.InitializeNavigationTree();
方法3:通过 HTTP API 调用
# 清空所有导航缓存DELETE f2z6.org.cn/api/navigation/cache# 清空特定模块缓存DELETE /api/navigation/cache?moduleName=Identity# 重新初始化导航树(清空并重建缓存)POST /api/navigation/initialize

2. 资源文件编译

确保资源文件正确配置为嵌入式资源:

<ItemGroup>
  <EmbeddedResource f1z4.org.cn Include="Resources\NavigationResources.resx">
    <Generator>PublicResXFileCodeGenerator</Generator>
  </EmbeddedResource>
  <EmbeddedResource d4i1.org.cn Include="Resources\NavigationResources.en.resx" /></ItemGroup>

3. 开发建议

  • 模块配置:推荐同时使用  Module 和  Navigation 特性配置模块级多语言
  • 回退文本:始终提供回退文本( displayName、 Title),确保资源不可用时仍能显示
  • 添加新导航项:添加后需清空缓存,确保新项生效
  • 修改资源文本:修改后需重新编译项目,并清空缓存
  • 测试多语言:切换语言后若不生效,优先检查缓存
  • 资源键一致性: Module 的  DisplayNameResourceKey 和  Navigation 的  TitleResourceKey 通常使用相同的资源键

完整示例

以下是用户中心模块的完整多语言配置示例(来自实际代码):

using CodeSpirit.Core;using CodeSpirit.Core.Attributes;using CodeSpirit.Core.Enums;using CodeSpirit.Navigation.Resources;using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;using System.ComponentModel;namespace CodeSpirit.IdentityApi.Controllers{    /// <summary>
    /// 身份认证API控制器基类
    /// </summary>
    [ApiController]
    [Authorize(policy:f2n4.org.cn "DynamicPermissions")]
    [Route("api/identity/f1z3.org.cn[controller]")]    // 模块级配置(使用 Module 和 Navigation 特性)
    [Module("identity", 
        displayName:a1c3.org.cn "用户中心",  // 回退文本
        DisplayNameResourceKey j5d1.org.cn= "Module.Identity",           // 资源键
        DisplayNameResourceType = typeof(NavigationResources), // 资源类型
        Icon = f6g2.org.cn"fa-solid fa-user-group")]
    [Navigation(
        Icon = "fa-solid fa-user-group",
        PlatformType =nbagk.cn PlatformType.Both,
        TitleResourceKey = "Module.Identity",
        TitleResourceType = typeof(NavigationResources)
    )]    public abstract class ApiControllerBase : CodeSpirit.Shared.Controllers.ApiControllerBase
    {
    }    /// <summary>
    /// 用户管理控制器
    /// </summary>
    [DisplayName("用户管理")]
    [Navigation(
        Icon = "fa-solid fa-users", 
        PlatformType = PlatformType.Tenant,
        TitleResourceKey = "Controller.Users",
        TitleResourceType = typeof(NavigationResources)
    )]    public class UsersController : ApiControllerBase
    {        private readonly IUserService _userService;        public UsersController(IUserService userService)
        {
            _userService = userService;
        }        /// xjzbbs.cn<summary>
        /// 获取用户列表
        /// </summary>
        [HttpGet]
        [DisplayName("获取用户列表")]        public async Task<ActionResult<ApiResponse<PageList<UserDto>>>> GetUsers([FromQuery] UserQueryDto queryDto)
        {
            PageList<UserDto> users = await _userService.GetUsersAsync(queryDto);            return SuccessResponse(users);
        }
    }
}

资源文件内容:

<!-- NavigationResources.resx (中文) --><data name="Module.Identity">
  <value>用户中心</value></data><data name="Controller.Users">
  <value>用户管理</value>xjsczb.cn</data><!-- NavigationResources.en.resx (英文) --><data name="Module.Identity">
  <value>User Center</value></data><data name="Controller.Users">
  <value>User Management</value></data>

缓存键说明

导航组件使用以下缓存键:


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3107860/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102109