Humanizer 命名空间 API 全览:从字符串、枚举到日期与数量的 .NET 人性化扩展
开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载Humanizer 是一个将字符串、枚举、日期、时间、时间跨度、数字、数量与集合转换为人类友好文本的 .NET 库。本篇以 2.10.1 版 API 参考文档为骨架逐一拆解Humanizer命名空间下的全部公开类型类、接口、枚举并结合仓库源码与测试用例说明每个核心扩展方法的能力边界与典型用法帮助你快速定位「哪种文本需求该调用哪个 API」。命名空间全景一张表看懂全部公开类型Humanizer命名空间是库的全部扩展方法的汇聚点。2.10.1 版 API 参考文档 Humanizer.md 将其划分为三大类类Classes、接口Interfaces与枚举Enums。从文档的类清单可以看出Humanizer 的公开面几乎全部是静态扩展类static classthis参数这是它「面向用法」的 API 设计你不需要构造任何对象直接对string、int、DateTime、IEnumerableT等调用扩展方法即可。类型说明源自 2.10.1 API 文档ByteSizeExtensions为ByteSize提供扩展方法CasingExtensions通过ApplyCase方法轻松改变句子的字母大小写CollectionHumanizeExtensions将IEnumerable人性化为可读列表DateHumanizeExtensions将DateTime人性化为可读句子DateToOrdinalWordsExtensions将DateTime人性化为可读句子序数词风格如 1st of JanuaryEnglishArticle提供移除、追加与前置冠词前缀的方法用于忽略冠词的字符串排序EnumDehumanizeExtensions将人性化的枚举字符串值还原为枚举EnumHumanizeExtensions人性化枚举HeadingExtensions将表示方向的数字转换为方向的文本表示InflectorExtensions词形变化复数化、单数化等扩展MetricNumeralExtensions数字到公制表示ToMetric与公制表示还原数字FromMetricNoMatchFoundException当字符串无法映射到目标枚举时由DehumanizeTo抛出NumberToNumberExtensions数字到数字扩展NumberToTimeSpanExtensions数字到TimeSpan扩展NumberToWordsExtension将数字转换为单词例如1 oneOrdinalizeExtensions序数化扩展PrepositionsExtensions与空间或时间关系相关的DateTime扩展RomanNumeralExtensions数字到罗马表示ToRoman与罗马表示还原数字FromRomanStringDehumanizeExtensions字符串反人性化扩展StringExtensionsString类型扩展方法StringHumanizeExtensions人性化字符串值TimeSpanHumanizeExtensions将TimeSpan人性化为可读形式To使用IStringTransformer进行字符串变换的入口ToQuantityExtensions将单词格式化为带数量的形式TruncateExtensions允许截断字符串Truncator获取ITruncator的工厂TupleizeExtensions将int转换为具名元组字符串1 - single、2 - double等仅 1-10、100、1000 有专名其余返回n-tuple字符串人性化StringHumanizeExtensions 的核心规则StringHumanizeExtensions 是使用频率最高的扩展类它把 PascalCase、camelCase、下划线、连字符混合的标识符转换成带空格的自然语句。从源码看Humanize(this string input)StringHumanizeExtensions.cs按顺序应用多条规则若整个输入全大写如HTML直接返回原样但会经过Vocabularies.ApplyAcronyms处理已注册的缩写调用Vocabularies.NormalizeAcronyms规范化已注册缩写如将IOS规范为iOS若存在两侧有空白的游离下划线/连字符HasFreestandingSpacingChar先替换为空格再走 PascalCase 分词否则按分隔符拆分或直接用正则PascalCaseWordPartsPattern对 PascalCase/camelCase 分词最终结果首字母大写并再次应用已注册缩写。文档注释中的典型结果PascalCaseInputString.Humanize() Pascal case input string Underscored_input_String_is_turned_INTO_sentence.Humanize() Underscored input String is turned INTO sentence dash-separated-string.Humanize() Dash separated string HTML.Humanize() HTML camelCaseText.Humanize() Camel case text RockRoll.Humanize() Rock roll对应的测试用例可在 StringHumanizeTests.cs 中找到例如PascalCaseInputStringIsTurnedIntoSentence→Pascal case input string is turned into sentence、HTMLIsTheLanguage→HTML is the language、HTML5→HTML 5。测试还验证了土耳其语等区域下的特殊行为如istanbul在tr-TR文化下被转为İstanbul说明人性化结果依赖当前文化的TextInfo。Humanize还支持LetterCasing重载StringHumanizeExtensions.cs本质是先Humanize()再调用CasingExtensions.ApplyCasePascalCaseInputString.Humanize(LetterCasing.AllCaps) PASCAL CASE INPUT STRING PascalCaseInputString.Humanize(LetterCasing.LowerCase) pascal case input string PascalCaseInputString.Humanize(LetterCasing.Title) Pascal Case Input String大小写与变换CasingExtensions、To 与转换器接口CasingExtensions 是大小写变换的统一点ApplyCase(this string input, LetterCasing casing)将LetterCasing枚举映射到 To 门户下的具体转换器To.TitleCase、To.LowerCase、To.UpperCase、To.SentenceCase非法枚举值会抛出ArgumentOutOfRangeExceptionsome string.ApplyCase(LetterCasing.Title) Some String SOME STRING.ApplyCase(LetterCasing.LowerCase) some string some string.ApplyCase(LetterCasing.AllCaps) SOME STRING some string.ApplyCase(LetterCasing.Sentence) Some stringTo类To.cs是「字符串变换门户」返回IStringTransformer实现。API 文档中与它配套的两个接口是IStringTransformer可变换字符串无文化参数ICulturedStringTransformer可在给定文化下变换字符串。具体实现位于 Transformer 目录ToTitleCase、ToSentenceCase、ToLowerCase、ToUpperCase对应测试见 TransformersTests.cs。枚举人性化与反人性化双向转换EnumHumanizeExtensions 的泛型HumanizeT(this T input)EnumHumanizeExtensions.cs按以下优先级输出若枚举成员带DescriptionAttribute等元数据则原样返回若枚举带[Flags]且多标志被置位则输出逗号分隔的人性化标志列表否则将成员名 PascalCase 转空格文本。源码示例enum UserType { AnonymousUser, RegisteredUser } UserType.AnonymousUser.Humanize() Anonymous user [Flags] enum Permission { None 0, Read 1, Write 2, Delete 4 } (Permission.Read | Permission.Write).Humanize() Read, Write enum Status { [Description(Currently active)] Active } Status.Active.Humanize() Currently activeHumanize的LetterCasing重载会对「由成员名派生的输出」应用大小写但对「作者书写的元数据文本」保持原样返回。反向操作由 EnumDehumanizeExtensions 承担DehumanizeToTTargetEnum(this string input)EnumDehumanizeExtensions.cs按「精确成员名 → 人性化成员名 →DisplayAttribute的 Name/Description/ShortName → 作者描述的DescriptionAttribute」顺序匹配匹配大小写不敏感无匹配时默认抛出 NoMatchFoundException也可通过 OnNoMatch 选择ReturnsNull。它还提供非泛型DehumanizeTo(Type, ...)重载供运行时才知枚举类型的场景使用反射类型安全弱于泛型版本。数字转单词与序数词NumberToWordsExtensionNumberToWordsExtension 提供ToWords、ToOrdinalWords、ToTuple、ToIndianWords等扩展。所有方法最终委托给Configurator.GetNumberToWordsConverter(culture)返回的区域化转换器INumberToWordsConverterculture参数为null时使用当前文化。基数词1.ToWords() one对支持词形变化的语言可传WordForm如西班牙语21.ToWords(WordForm.Abbreviation) veintiún对支持性别的语言可传GrammaticalGender俄语1.ToWords(GrammaticalGender.Masculine) один阴性为одна还可用addAnd控制末尾是否加连词。序数词1.ToOrdinalWords() first巴西葡萄牙语1.ToOrdinalWords(GrammaticalGender.Feminine) primeira西班牙语3.ToOrdinalWords(WordForm.Abbreviation) tercer。印度英语大数ToIndianWords支持IndianScaleStyle.NamedScales使用 en-IN 命名级与IndianScaleStyle.CroreBased使用 crore/lakh 表达的常用级两种词汇表后者对应的CroreBasedIndianScales常量定义在 NumberToWordsExtension.cs。元组名1.ToTuple() single仅 1-10、100、1000 有专名。区域化转换器实现位于 Localisation/NumberToWords40 个文件每种文化一个转换器类。数量词ToQuantityExtensions 与 ShowQuantityAsToQuantityExtensions 将单词与数量组合并自动单复数化ToQuantityExtensions.cs 中quantity为1或-1时调用Singularize否则调用Pluralize。ShowQuantityAs枚举决定数量如何显示None只输出变换后的单词不含数量Numeric以数字形式输出默认Words以单词形式输出如1200 one thousand two hundred。文档与源码示例request.ToQuantity(0) 0 requests request.ToQuantity(1) 1 request request.ToQuantity(2) 2 requests men.ToQuantity(2) 2 men process.ToQuantity(1200, ShowQuantityAs.Words) one thousand two hundred processes request.ToQuantity(10000, format: N0) 10,000 requests request.ToQuantity(0.2) 0.2 requestsint与long重载支持format标准或自定义数字格式字符串与formatProvider文化相关的格式提供者double重载会在数量为±1.0且为有限值时输出单数形式。集合人性化CollectionHumanizeExtensionsCollectionHumanizeExtensions 把IEnumerableT转成符合自然语言习惯的列表默认使用当前文化的分隔符英语通常为, 并在最后一项前加andnew[] { 1, 2, 3 }.Humanize() 1, 2 and 3 new[] { Alice, Bob, Charlie }.Humanize() Alice, Bob and Charlie new[] { single }.Humanize() single new string[] { }.Humanize() 它提供多种重载指定文化Humanize(new CultureInfo(en-GB))、自定义元素格式化函数people.Humanize(p p.Name)、自定义分隔符numbers.Humanize( | )输出1 | 2 | 3以及格式化函数 分隔符的组合。底层通过Configurator.CollectionFormatter与Configurator.CollectionFormatters.ResolveForCulture(culture)获取区域化格式器CollectionFormatters对应测试见 CollectionHumanizeTests.cs。日期人性化与流式日期DateHumanizeExtensions、In、OnDateHumanizeExtensions 将DateTime转成「多久之前/之后」的可读句子如 2 hours ago、in 3 days是构建动态时间显示消息时间戳、日志时间的常用工具。而In系列In.One、In.Two…In.Ten与On系列On.January…On.December提供流式日期访问器。In系列文档描述为空On系列文档则明确标注为 Provides fluent date accessors for …如 On.January其实现代码由 T4 模板生成位于 FluentDate/On.Days.cs 与 FluentDate/In.Months.cs模板源文件为对应的.tt文件。相关测试见 FluentDate。时间跨度人性化TimeSpanHumanizeExtensionsTimeSpanHumanizeExtensions 将TimeSpan人性化为可读形式。2.10.1 版已有若干策略类参与DefaultTimeSpanHumanizeStrategy、IFractionalTimeSpanHumanizeStrategy、IGrammaticalCaseTimeSpanHumanizeStrategy、ITimeSpanHumanizeStrategy实现位于 TimeSpanHumanizeStrategy。策略化设计意味着你可以通过Configurator替换默认的人性化策略例如启用带小数精度的输出相关测试见 TimeSpanHumanizeTests.cs 与 FractionalTimeSpanHumanizeTests.cs。截断与变换基础设施TruncateExtensions、Truncator、ITruncatorTruncateExtensions 允许按长度或单词数截断字符串Truncator 是获取ITruncator的工厂入口ITruncator 定义截断能力。截断实现位于 Truncation 目录FixedLengthTruncator、FixedNumberOfCharactersTruncator、FixedNumberOfWordsTruncator等并由 TruncateFrom 枚举指定从左侧还是右侧截断。测试见 TruncatorTests.cs。其余值得关注的类型RomanNumeralExtensionsToRoman()/FromRoman()实现见 RomanNumeralExtensions.cs测试见 RomanNumeralTests.cs。MetricNumeralExtensions与MetricNumeralFormats数字与公制前缀k、M、G 等互转。OrdinalizeExtensions数字序数化1.Ordinalize() 1st与NumberToWordsExtension的ToOrdinalWords互为补充数字后缀 vs 单词。NumberToNumberExtensions、NumberToTimeSpanExtensions前者提供数值之间的便捷转换后者如5.Days()、3.Hours()返回TimeSpan。InflectorExtensionsPluralize、Singularize、Pascalize、Camelize、Underscore、Dasherize等词形变换是ToQuantityExtensions单复数化的底层依赖。EnglishArticle与EnglishArticles忽略冠词的排序如把 The Beatles 按 Beatles 参与排序。HeadingExtensions与HeadingStyle罗盘方向数字转文本如 0/360 → North。NoMatchFoundExceptionDehumanizeTo无匹配时的默认异常类型。PrepositionsExtensions与空间或时间关系相关的DateTime扩展如In、On之外的前置词辅助。配套枚举与接口速查文档列出的Enums中除前文已涉及的ShowQuantityAs、OnNoMatch、LetterCasing、TruncateFrom、HeadingStyle、MetricNumeralFormats外还有EnglishArticles定冠词与不定冠词GrammaticalCase输出单词的期望语法格如主格、与格GrammaticalGender输出单词的期望语法性别阳性/阴性/中性Plurality向 Humanizer 提示单词是单数、复数还是未知。Interfaces仅有三个ICulturedStringTransformer、IStringTransformer、ITruncator它们与To门户、截断工厂共同构成库的两条可扩展点字符串变换、字符串截断。小结如何按需选择 API面对「文本需要更人性化」的需求可以按输入类型快速定位字符串Humanize()拆词ApplyCase(LetterCasing)大小写Truncate()截断Pluralize()/Singularize()单复数枚举Humanize()/DehumanizeToT()无匹配时用OnNoMatch.ReturnsNull或捕获NoMatchFoundException数字ToWords()/ToOrdinalWords()/Ordinalize()/ToRoman()/ToMetric()/ToTuple()数量word.ToQuantity(n, ShowQuantityAs.Numeric/Words)日期/时间DateTime.Humanize()、TimeSpan.Humanize()、流式的In/On系列集合IEnumerableT.Humanize()支持分隔符、格式化函数与文化参数。所有类型均可在 2.10.1 版 API 文档目录 中查看各自独立的参考页当前仓库主库源码位于 src/Humanizer测试位于 tests/Humanizer.Tests安装使用只需dotnet add package Humanizer见 readme.md。赞分享开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载相关推荐Humanizer 命名空间全解析.NET 字符串、枚举、日期与数字人性化处理的 API 总览Humanizer 命名空间全解析.NET 字符串、枚举、日期与数字人性化处理的 API 总览 Humanizer 是一个把字符串、枚举、日期、时间、时长、数开发工具Humanizer 命名空间全解析从字符串、枚举到日期与数字的 API 全景图Humanizer 命名空间全解析从字符串、枚举到日期与数字的 API 全景图 导读 Humanizer 是一个面向 .NET 的人性化工具库其核心价值开发工具Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本 Humanizer 是一个面向 .NET 的文本人性化库专门把字符串开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

风险情报驱动的数字供应链安全治理:从SBOM到运行时防护

风险情报驱动的数字供应链安全治理:从SBOM到运行时防护

过去这两年,做应用安全的人应该都有一个共同感受:漏洞已经不只是“修不修”的问题,而是根本来不及修。Log4j2漏洞爆出来的时候,很多企业连夜排查,最后发现内网躺着几百条调用链;XZ-utils后门事件又给整个行…

2026/9/25 9:45:44 阅读更多 →
Kali Linux无线渗透测试实战:从网卡选型到WPA2破解全流程

Kali Linux无线渗透测试实战:从网卡选型到WPA2破解全流程

1. 无线渗透的硬件门槛:网卡芯片、驱动与监听模式1.1 不是所有网卡都能干活:芯片选型的关键很多人刚接触Kali Linux时,装好系统就迫不及待地准备抓包,结果发现笔记本自带的无线网卡根本进不了监听模式,或者能开启监听但…

2026/9/25 9:45:44 阅读更多 →
Atlas 300V 24G推理卡详解:从入门到YOLO部署实战

Atlas 300V 24G推理卡详解:从入门到YOLO部署实战

在边缘AI推理这个圈子里,Atlas这个名字最近几年出现的频率越来越高。尤其当“atlas部署yolo”和“atlas 300v 24g 是运算加速卡吗”这两个问题被反复问到的时候,我就知道很多人其实已经拿到了卡,或者正在选型阶段,但对这套工具链还…

2026/9/25 9:44:44 阅读更多 →

最新新闻

OpenCode 与 OpenCLAW 的 AI 模型配置:用 TaoToken 统一 Key 打通多工具调用

OpenCode 与 OpenCLAW 的 AI 模型配置:用 TaoToken 统一 Key 打通多工具调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
ORACLE 经验两则:Sys_Refcursor 与外部表 SKIP 的配置骨架

ORACLE 经验两则:Sys_Refcursor 与外部表 SKIP 的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
Claude 在得物 App 数仓的深度集成与效能演进:TaoToken 统一 Key 通道配置实战

Claude 在得物 App 数仓的深度集成与效能演进:TaoToken 统一 Key 通道配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
WorkBuddy Enterprise 企业级 Agent 平台架构与 MCP 落地实践

WorkBuddy Enterprise 企业级 Agent 平台架构与 MCP 落地实践

1. 从「超级个体」到「超级团队」:这个平台到底在解决什么问题第一次看到「WorkBuddy Enterprise」这个名字,我脑子里蹦出来的第一个念头是:腾讯云终于把 CodeBuddy 那套东西往企业级方向推了。如果你最近半年一直在关注 Agent 开发这条线&am…

2026/9/25 13:13:40 阅读更多 →
Atlas 300V 24G实战:AI推理加速卡部署YOLO全流程

Atlas 300V 24G实战:AI推理加速卡部署YOLO全流程

很多人都为一个词搜过来:atlas。准确讲,搜到atlas又能和部署yolo扯上关系的,多半是盯上了华为Atlas 300V 24G这块卡。今天我不绕圈子,先说结论:Atlas 300V 24G确实是一块运算加速卡,但它更准确的定位&#…

2026/9/25 13:13:40 阅读更多 →
MySQL表空间传输:从原理到实战,把大表迁移从小时级压缩到分钟级

MySQL表空间传输:从原理到实战,把大表迁移从小时级压缩到分钟级

老规矩,先给结论:MySQL自带的表空间传输(Transportable Tablespace)功能,是处理“单表或一批表快速换实例”最好用的手段之一,尤其在数据量已经上到几十GB、几百GB,mysqldump导出导入慢到让人抓…

2026/9/25 13:12:40 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →