普通视图
贵州茅台:尽最大努力防止价格炒作
2连板泰尔股份:内外部经营环境未发生重大变化,不存在应披露而未披露的重大事项
9天6板浙江世宝:公司经营正常,无应披露而未披露的重大事项
王府井:中标北京首都国际机场免税项目02标段,首年保底经营费1.13亿元
锋龙股份:优必选暂无在未来12个月内改变公司主营业务或者对公司主营业务做出重大调整的明确计划
Flutter限制输入框只能输入中文,iOS拼音打不出来?
中文输入必踩的 Flutter 坑合集:iOS 拼音打不出来,其实是你 Formatter 写错了
如果你在 Flutter 里做过「只允许中文 / 中英文校验」,并且只在 iOS 上翻过车,那这篇文章大概率能帮你节省半天 Debug 时间。
这不是 iOS 的锅,也不是 Flutter 的 Bug,而是 TextInputFormatter 和中文输入法(IME)之间的理解偏差。
一、血iOS 上拼音怎么都打不出来
常见反馈包括:
- iOS 中文拼音键盘
- 输入
bei jing - 键盘有拼音显示
- 输入框内容完全不变
- 无法选词、无法上屏
👉 Android 正常
👉 模拟器正常
👉 真机 iOS 不行
很多人第一反应是:
“Flutter 对中文支持不好?”
结论先行:不是。
二、罪魁祸首:TextInputFormatter 的「中文校验」
下面这种 Formatter,你一定写过或见过:
class NameInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
final chineseOnly = RegExp(r'^[\u4E00-\u9FFF]+$');
if (newValue.text.isEmpty) return newValue;
if (!chineseOnly.hasMatch(newValue.text)) {
return oldValue; //
}
return TextEditingValue(
text: newValue.text,
selection: TextSelection.collapsed(
offset: newValue.text.length,
),
);
}
}
逻辑看起来非常合理:
- 只允许中文
- 非法字符直接回退
但在 iOS 上,这段代码等于封死了中文输入法的入口。
三、核心原理:iOS 中文输入法有「组字阶段」
1️ composing 是什么?
iOS 拼音输入法的输入过程分为两步:
-
组字(composing)
- 输入:
bei - 输入框里是拼音(未确认)
- 输入:
-
提交
- 选择「北」
- 中文字符真正上屏
在组字阶段:
newValue.text == "bei"
newValue.composing.isCollapsed == false
而 "bei" 必然无法通过「只允许中文」的正则校验。
2️ Formatter 提前“否决”了输入
当 Formatter 在 composing 阶段做了以下任意一件事:
return oldValue- 修改
text - 强制重置
selection
iOS 输入法就会认为:
「当前输入不合法,终止组字」
于是出现经典现象:
拼音能打,但永远无法选字
四、隐藏更深的坑:selection 会杀死输入法
很多 Formatter 里都有这行:
selection: TextSelection.collapsed(offset: text.length),
在普通输入下没问题,但在中文输入中:
- selection 是 IME 状态的一部分
- 每次重置 selection = 重启组字流程
哪怕你放行了拼音,也可能出现:
- 候选词异常
- 游标跳动
- 输入体验极差
五、那为什么 Android 没这个问题?
这是一个非常关键、也最容易误判的点。
Android 的行为差异
- Android 输入法对 composing 的暴露不一致
- 很多键盘在 字符提交后才触发 Formatter
- 即使 composing 存在,也更“宽容”
结果就是:
错误的 Formatter 在 Android 上“看起来能用”
但这并不代表代码是对的,只是 Android 没那么严格。
真相
Android 是侥幸没炸,iOS 是严格把问题暴露出来。
六、正确原则
1. composing 阶段必须放行
if (!newValue.composing.isCollapsed) {
return newValue;
}
2. 校验只在 composing 结束后做
3. 不要无脑重置 selection
4. Formatter ≠ 表单最终校验
七、正确示例
下面是一个安全、可扩展、iOS / Android 双端稳定的 Formatter 示例:
class UniversityNameInputFormatter extends TextInputFormatter {
UniversityNameInputFormatter({this.maxLength = 40});
final int maxLength;
static final RegExp _disallowed =
RegExp(r'[^a-zA-Z0-9\u4E00-\u9FFF-\s]');
static final RegExp _multiHyphen = RegExp(r'-{2,}');
static final RegExp _leadingHyphen = RegExp(r'^-+');
static final RegExp _trailingHyphen = RegExp(r'-+$');
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
// iOS 中文拼音组字阶段
if (!newValue.composing.isCollapsed) {
return newValue;
}
var text = newValue.text;
if (text.isEmpty) return newValue;
text = text.replaceAll(_disallowed, '');
text = text.replaceAll(_multiHyphen, '-');
text = text.replaceAll(_leadingHyphen, '');
text = text.replaceAll(_trailingHyphen, '');
if (text.length > maxLength) {
text = text.substring(0, maxLength);
}
if (text == newValue.text) return newValue;
int clamp(int o) => o.clamp(0, text.length);
return TextEditingValue(
text: text,
selection: TextSelection(
baseOffset: clamp(newValue.selection.baseOffset),
extentOffset: clamp(newValue.selection.extentOffset),
),
composing: TextRange.empty,
);
}
}
八、中文输入必踩的 Flutter 坑合集(Checklist)
❌ 坑 1:Formatter 里直接做中文正则校验
后果:iOS 拼音无法输入
❌ 坑 2:忽略 newValue.composing
后果:IME 组字被打断
❌ 坑 3:每次都把 selection 移到末尾
后果:候选词异常、游标乱跳
❌ 坑 4:以为 Android 正常 = 代码正确
后果:iOS 真机翻车
九、一句话总结
TextInputFormatter 是 IME 输入流程的一部分,不是简单的字符串过滤器。
读《疯狂的尿酸》
《疯狂的尿酸》是一本关于健康的科普书,来自于美国医学博士:戴维·珀尔马特,他是一位畅销书作家,写过《谷物大脑》和《菌群大脑》。
什么是尿酸
正常人体中的尿酸,2/3 是内源性的。尿酸是嘌呤的代谢产物,而嘌呤是细胞的重要组成部分,可以用来合成 DNA 和 RNA,人类的细胞因为不停地在分裂和衰老,死亡的细胞在被处理的时候就会产生尿酸。
另外 1/3 的尿酸来自于外部摄入的食物,包括动物内脏,海鲜,啤酒等。
果糖是一种特别的糖,它虽然不会造成血糖上升,但是会在代谢的时候产生尿酸。
尿酸会促进脂肪的产生
因为高尿酸与肥胖相关性很高,为了研究他们之间的因果关系,人们发现了“尿酸氧化酶”。这是一种存在于大多数动物体内的酶,能够迅速将尿酸排出体外,但是我们的人类祖先在几百万年的进化过程中,产生这个酶的基因被破坏了,变成了“假基因”。这就使得我们人类血液中的尿酸含量是其他哺乳动物的 3-10 倍。
当远古时代的人类吃下果糖后,果糖会在代谢过程中产生尿酸,而尿酸会打开人体的“脂肪开关”,帮助人体把果糖转化为脂肪。“从水果到脂肪”的生理机制帮助古代的灵长类动物能够度过漫长的、食物匮乏的冬天。
果糖
果糖是所有天然的碳水化合物中最甜的一种,天然的果糖只存在于水果和蜂蜜中,所以人类摄入得很少。而且水果中富含膳食纤维,可以延缓果糖被吸收的速度;而水果中富含的维生素 C 还有降低尿酸及促进尿酸排出的功能,所以吃水果对果糖的提升是很低的,代谢产生的尿酸也很少。
纯葡萄糖和果糖都是单糖(糖的最简单形式),而蔗糖是葡萄糖和果糖的组合,是一种双糖(两个分子连接在一起)。蔗糖进入人体后在小肠被分解,释放果糖和葡萄糖,然后被吸收。
果葡糖浆是一种以果糖为主的糖浆制品,果糖占比约 55%,葡萄糖占比 42%。最早是 1957 年由美国生物化学家 理查德·O 马歇尔 和 厄尔·R 科伊 生产出来,他们创造了一种酶,可以通过化学方法使玉米糖浆中的葡萄糖的结构重新排列,将其转化为果糖。
果葡糖浆从 20 世纪 70 年代开始流行,主要是因为其甜度比蔗糖高,价格又比蔗糖低,所以逐渐取代了蔗糖。到了 1984 年,可口可乐和百事可乐也都把各自品牌的饮料从添加蔗糖改为添加果葡糖浆。
果糖的升糖指数是所有天然糖中最低的,这意味着它不会直接导致血糖升高,也就不会刺激胰岛素的分泌,所以在一段时间内,人们把果糖视为一种“更安全”和“健康”的糖。但后来人们发现,相比于葡萄糖参与能量生成,果糖则参与能量储存,所以更容易让人肥胖。
果糖的代谢过程
果糖和葡萄糖除了一些化学键不同,其他结构几乎完全一样。然后,正是这微小的差异使得它们的代谢过程完全不同。
葡萄糖代谢的第一步(葡萄糖的磷酸化)是在葡萄糖激酶催化下分解,分解所释放的 ATP 也会在细胞中维持稳定的水平。ATP(三磷酸腺苷)是人体能量的来源。
果糖的代谢与葡萄糖完全不同。果糖在进入人体后,会迅速被血液吸收,然后被运输到肝脏中进行代谢。在肝细胞内,果糖激酶会开始工作,做出包括消耗 ATP 在内的一系列事情。果糖会消耗 ATP 的过程会带来一些下游效应,它会导致血液中的尿酸水平快速上升。由于果糖消耗了 ATP,细胞会发出信号:我们的能量快用完了。这会促使身体减缓新陈代谢以减少静息能量消耗。
除了消耗能量外,果糖还会触发脂肪的生成过程:肝脏中的果糖代谢会直接导致脂肪的产生:主要是以甘油三酯的形式存在,这是人体中最常见的脂肪存在形式。
AMP 活化蛋白激酶
AMP 活化蛋白激酶被激活时,它会向你的身体发出“狩猎状况良好”(即食物充足)的信号,你的身体就会让自己从储存脂肪转换为燃烧脂肪,帮助身体保持良好的狩猎状态。
AMP 活化蛋白激酶还可以帮助身体减少葡萄糖生成。二甲双胍就利用了这一点来实现降血糖。
与AMP 活化蛋白激酶对应的,还有一种让身体储存脂肪的酶,叫做腺苷单磷酸脱氨酶 2。动物在准备冬眠的时候,就会激活腺苷单磷酸脱氨酶 2 用于储存脂肪;在冬眠的时候,则切换到AMP 活化蛋白激酶用于燃烧脂肪。
而果糖代谢过程产生的尿酸,就是这两种酶的调节剂,尿酸能够抑制AMP 活化蛋白激酶,同时激活腺苷单磷酸脱氨酶 2 。
断食
作者推荐大家可以尝试 24 小时的断食,即:24 小时内不吃任何东西,且大量饮水。如果正在服用药物,务必继续服用。
我也见过一种 16:8 的轻断食方法:即 16 小时断食,8 小时进食。通常时间设置为中午 12 点-下午 8 点,或者上午 10 点到晚 6 点。
小结
本书主要揭示了果糖和尿酸在人体代谢中的核心原理,让我们更加关注饮食和内分泌的健康。
11连板胜通能源:如未来股票价格进一步上涨 公司可能向交易所申请停牌核查
1600亿 , 宜春首富要IPO了
作者/吴琼 王露
报道/投资界PEdaily
“易中天”又要IPO了。
近日,天孚通信发布公告,公司计划发行H股股票并在香港联合交易所主板上市。站在聚光灯下的,是即将再次敲钟的创始人——邹支农。
出生于江西农村家庭,邹支农本科毕业于吉林工业大学。2005年,在制造业摸爬滚打多年的他创立天孚通信,凭借一颗陶瓷套管打破外企垄断。2015年天孚通信成功登陆创业板,如今乘着AI算力东风爆红,市值突破千亿。
回望2025年,“易中天”三剑客一路扶摇直上。有人赚得盆满钵满,亦有人过早离场错失红利。
宜春首富发家史
一手缔造天孚通信的是邹支农。
1968年,他出生于江西宜春一个普通农村家庭,后来成为那个年代少有的大学生。1991年,从吉林工业大学机械设计与制造专业毕业后,他被分配到吉林省四平市鼓风机厂工作,捧上“铁饭碗”。
1995年,改革春风吹遍神州,27岁的邹支农毅然投入商海。后来他与妻子欧洋来到苏州,创办豪亿数码网络有限公司,专攻综合布线工程。
期间,邹支农又发现一个新难点——布线工程中大量使用的陶瓷套管,对光纤的精准对接有着至关重要的作用,如果陶瓷套管质量不过关,通信信号就会受影响。但是,当时这一材料几乎被日本企业垄断,价格居高不下。
于是,2005年邹支农与朱国栋、欧洋三人在苏州工业园区,创立天孚精密陶瓷有限公司,这便是我们如今看到的天孚通信。起家的产品,正是一颗米粒大小的陶瓷套管。
创业之初,仅仅是为了摸索出烧结曲线图,研发团队就花了大半年时间。直到攻克纳米陶瓷烧结技术难关,并通过改进工艺,降低成本,逐步实现了对日本产品的进口替代。
以陶瓷套管产品线的突破为契机,天孚通信逐渐形成了无源光器件整体解决方案业务和光电先进封装业务两大核心业务板块,产品可应用于AI人工智能算力中心、数据中心、电信通信、光学传感等领域。
伴随着出海浪潮,天孚通信还构建了一个清晰的全球化布局:在苏州和新加坡分别设立海内外总部,在日本、深圳、苏州设立研发中心,在江西和泰国建立量产基地。如今,天孚通信的产品已经卖到海外20多个国家和地区,每年向全世界提供数亿只光通信元器件。
2015年,天孚通信成功在创业板上市,成为国内光通信元器件行业的第一家上市公司。
自2016年开始,邹支农便开始凭借天孚通信商业版图登上富豪榜单,此后随着分红、减持收益、股价上涨等,身价一路水涨船高。根据《2025年胡润百富榜》,邹支农家族财富达655亿元,位列宜春首富。
搭上英伟达快车,今年卖爆
天孚通信暴涨一幕历历在目。
今年以来,天孚通信股价涨幅超220%,已经5次登上龙虎榜,最新市值超1600亿元。
若将时间线拉长,天孚通信创业板上市时发行价仅在20元左右,此后几年市值曾长期不足百亿元。但从2023年开始,天孚通信股价连涨三年。尤其今年以来,从4月股价尚不足40元,到8月末突破200元,市值正式突破千亿,幅度惊人。
那么,天孚通信到底经历了什么?
其实答案并不难猜到。2023年,在Chat GPT引发的AI革命中,AI算力需求激增,CPO(光电共封装)概念引爆光模块行业,天孚通信股价大幅上涨。
到了今年,AI竞赛愈演愈烈,这也给“易中天”们加了一把油。我们都知道,英伟达靠GPU为AI训练提供算力赚得盆满钵满,但是光模块负责的运输同样重要。“如果数据传输跟不上,就像是在高速上堵了车,算力再强也白搭”,一位行业人士如此解释。因此,作为搭档,GPU与光模块缺一不可。
于是,搭着“英伟达概念股”,“易中天”们起飞了。
值得一提的是,天孚通信并不直接生产光模块,而是提供光模块的核心部件——光引擎。邹支农曾在采访时明确表示:坚持不做自有品牌的光模块。永远不会和客户竞争。而是为全球优质光模块厂商提供光器件产品和服务配套。
正是这种定位,意外为天孚通信造就了通吃的格局:既是英伟达的核心供应商。当其他同行们争夺光模块市场时,天孚通信提供的是它们都需要的核心组件。由此避开竞争,享受行业整体增长红利。
据公司2025年第三季度财报,其营业收入本年累计达39亿元,同比增加63.63% 。天孚通信在公告中解释,“增长主要是受益于人工智能的发展和算力需求的增加,全球数据中心建设带动高速光器件产品需求的持续稳定增长影响。”
故事还在继续。当“光模块”的故事讲的差不多了,大洋彼岸,谷歌的 TPU 芯片又从半路杀出。简单理解,在纸面算力相等时,TPU 集群所需的光模块数量比GPU 集群更多。当谷歌冲击英伟达霸主地位,“易中天”们又有了新的增长预期。
据最新调研显示,天孚通信已成功锁定Lumentum(谷歌供应商)的高端光芯片产能。12月9日,天孚通信股价创下242元历史新高,总市值一度超1850亿元。
针对公司股票异常波动情况,天孚通信发布公告,最新计划由此浮出水面:为持续推进公司国际化战略和全球化布局,打造国际化资本运作平台,进一步提升公司治理水平和核心竞争力,助力公司高质量发展,公司目前正筹划在香港联交所发行H股上市事项。
一场财富盛宴
今年的超级黑马,当数“易中天”。
被称为光模块三剑客的新易盛、中际旭创、天孚通信,自今年四月以来,股价齐头并进,无一例外地站上历史高点:
新易盛从年初不足百元一路冲至400元以上,翻了近4倍,市值一举突破4000亿元;
中际旭创不甘示弱,市值一度突破7000亿元大关;
就连相对低调的天孚通信也连涨数倍,市值超1600亿元。
盛宴之下,最先尝到甜头的,自然是那些站在船头的人。中际旭创实控人王伟修,此前以持股市值近600亿,对比《2025胡润全球富豪榜》数据,成功登顶山东烟台首富。
此外,天孚通信控股股东天孚仁和在11月抛出减持计划,落袋约13亿元。还有新易盛实控人高光荣,10月以328元/股的价格,通过询价转让向机构投资者出售1143.07万股,套现约37.49亿元。
财富的涟漪阵阵,公司员工亦在这轮浪潮中分得一杯羹。
据财报显示,中际旭创三期员工持股计划覆盖员工约250人,在今年二季度减持249.68万股,若以6月末145元/股计算,该员工持股计划可套现约3.6亿元——人均账面收益约145万元。
值得一提的是,中际旭创还在今年4月推出第四期限制性股票激励计划,向752名激励对象,以54元/股的对价,授予合计888万股公司股份。以如今股价计算已翻了数倍,新一轮财富效应正在酝酿。
令人稍微遗憾的是,那些曾在公司青涩岁月里坚定押注的早期投资人,终究没能等到这场高光时刻。
外人或许不知,早在天孚通信2015年登陆资本市场之前,便已有投资机构悄然布局。苏州天特、深圳乾振、杭州丰泰、重庆麒厚等机构曾一路陪伴,共度成长的漫长岁月。
然而,在这场跨越十年的长跑中,它们大多已悄然退场,陆续淡出公司主要股东行列,只留下早期押注的背影,隐入产业崛起的注脚中。
回望这一波AI造富潮,势如潮涌。有人凭远见兑现了红利,有人携重金匆匆入席。只是,资本市场的剧本向来复杂:高潮未必是终章,入场亦未必赶得上最后一曲。
本文来自微信公众号“投资界”,作者:吴琼 王露,36氪经授权发布。
国务院拟放开放宽除个别超大城市外的落户限制
钧达股份:与尚翼光电相关合作事项不会对公司当期经营业绩产生重大影响
通宇通讯:公司股价短期上涨幅度较大 存在市场情绪过热、非理性炒作风险
老黄200亿“钞能力”回应谷歌:联手Groq,补上推理短板
Jay 发自 凹非寺量子位 | 公众号 QbitAI
老黄稳准狠,谷歌的TPU威胁刚至,就钞能力回应了。
200亿美元说砸就砸,只为拉拢一家炙手可热的「铲子新工厂」——Groq。
这无疑也标志这家芯片巨头,面向AI新时代的一次重大布局。但在某种程度上,也的确反映出老黄对包括TPU在内等一众新芯片范式的担忧。
所以,Groq究竟能为英伟达带来什么?
针对这个问题,知名科技投资人Gavin Baker发表了自己的观点。
而他的这一连串技术剖析,纷纷指向了英伟达帝国防守最薄弱的那块领土——推理。
推理方面,Groq LPU的速度远超GPU、TPU,以及目前所见的任何ASIC。
![]()
Gavin Baker
这一观点得到大量网友点赞:
GPU架构根本无法满足推理市场对低延迟的需求,片外HBM显存速度实在太慢了。
![]()
网友观点
但也有网友指出,LPU所采用的SRAM,或许并不能胜任长下文decode。
对此,Gavin认为英伟达可以通过产品「混搭」的方式解决。
![]()
Gavin Baker
下面具体来看——
Groq:英伟达斥200亿美元购入的一剂疫苗
Gavin认为,GPU在新时代水土不服的根本原因在于——推理过程的两个阶段,prefill和decode,对芯片能力有截然不同的要求。
先看prefill:
这一步,简单来说就是让模型「读题」,把用户提供的关键信息在脑子里记好,用于后续调用。
读题过程中,模型会一次性吃下用户所给的上下文,所有输入token都可以同时计算。
这正是GPU最擅长的舞台,其为图形处理而生,可以一次性计算数千个像素,天生适合处理并行任务。
在这个准备阶段,模型不用急着响应用户问题。即便有延迟,模型也完全可以通过显示「思考中」来掩盖等待时间。
因此,相比「速度」,prefiil需要芯片有更大的上下文容量。
但到了decode,这套逻辑不再适用。
decode是串行任务,必须得一个一个token挨着算。更重要的是,用户还会亲眼看到token被一个个「打」出来的过程。这种情况下,延迟对用户体验来说是致命的。
然而,GPU的数据主要存放在HBM,而不是紧贴算力核心的片上存储。这意味着,每生成一个token,GPU都需要重新从内存中读取数据。
这时候,GPU的问题就暴露出来了——大部分算力都处于闲置,FLOPs根本用不满,常常在等内存把数据搬过来,实际计算量远小于prefill。
相比之下,Groq有更好的解决方案——LPU。
比起HBM,LPU使用直接集成在芯片硅片中的SRAM。这种片上存储的模式不需要读取数据,这让其速度比GPU快100倍。即使只处理单个用户,它也能跑出每秒300–500个token的速度,并能始终保持满负荷运转。
事实证明,在速度这一块,LPU几乎打遍天下无敌手——不仅是GPU,就连TPU,以及市面上绝大多数ASIC都难以望其项背。
但这并非没有代价的。
相比GPU,LPU的内存容量小的多。单颗Groq的LPU芯片,片上SRAM只有230MB。
作为对比,即便是英伟达的H200 GPU,也配备了高达141GB的HBM3e显存。
结果就是:你必须把成百上千颗LPU芯片连在一起,才能跑起一个模型。
以Llama-3 70B为例,用英伟达GPU的话,只需要两到四张卡,塞进一个小型服务器盒子里就能搞定。而同样的模型,需要数百颗LPU,占地面积也将远大于使用GPU的数据中心。
这意味着,即便单颗LPU价格更低,整体硬件投资依然会非常巨大。
因此,AI公司在考虑LPU时,最重要的问题是——
用户是否愿意为「速度」付费?
对于这个问题,一年前的市场还不无法给出答案。但从Groq如今的业绩情况来看已经非常明确:「速度」是个真实存在的巨大需求,并且仍在高速成长。
而对英伟达而言,这不仅是一个新的业务盘,更是一个颠覆者暗流涌动的高风险地带。倘若错失这个风口,英伟达在AI时代的机会可能会被新玩家颠覆,就像英伟达当年通过游戏业务颠覆其他竞争对手一样。
为了抵抗这些竞争者蚕食自己的护城河,英伟达选择注射名为Groq的疫苗。希望通过人才收购引入新血液,补齐这块低延迟场景的推理短板,帮助英伟达这艘巨舰摆脱创新者窘境。
「铲子」进入新时代
TPU的崛起,给英伟达的金钟罩撕开了一道裂缝。
通过自研芯片,谷歌成功摆脱了对英伟达天价GPU的依赖,这在很大程度上帮助谷歌削薄了训练和推理成本,这让谷歌在服务大量免费用户的情况下,依然能维持相当健康的财务账面。
谷歌通过Gemini 3 Pro的绝地翻盘,证明了GPU并非AI时代的唯一解。在技术周期高速迭代的背景下,作为AI「心脏」的芯片,也需要根据不同的发展阶段做出相应的调整。
随着基础模型的进展放缓,AI竞争的重点开始从训练层转向应用层。而在AI应用市场,「速度」对用户体验而言至关重要。
而这次人才收购Groq,虽然也是变相承认了公司在推理赛道的不足,但同样标志着英伟达帝国的又一次扩张。
称霸预训练的英伟达,这次要借Groq的东风,入局竞争对手喷涌而出的「推理大陆」。
而在这个新市场,英伟达或许不再能像如今这样风光。
正如Groq CEO所言,推理芯片是项高销量、低利润的苦活。这与即便炒到天价也有客户抢着要,毛利率高达70-80%的GPU截然不同。
参考链接:[1]https://x.com/gavinsbaker/status/2004562536918598000[2]https://www.uncoveralpha.com/p/the-20-billion-admission-why-nvidia
本文来自微信公众号“量子位”,作者:关注前沿科技,36氪经授权发布。
3天2板中超控股:公司补缴税款828.81万元
航天发展:下属公司主要从事商业低轨卫星运营及数据应用服务,前三季度营业收入低于1%
基于 Nuxt 4 + Strapi 5 构建高性能 AI 导航站
摘要:在 AI 工具爆发的今天,如何快速构建一个既具备内容深度(CMS 管理),又有极致交互体验(SSR + 现代化 UI)的导航平台?本文将复盘 Creator AI Hub 的从零开发历程,深度解析 Monorepo 架构设计、Strapi v5 无头 CMS 的灵活应用以及 Nuxt 4 的全栈实践。
🚀 引言:为什么选择这套技术栈?
在构建 Creator AI Hub 时,我们面临几个核心需求:
- 内容为王:需要频繁更新 AI 工具、解决方案和 SOP,且内容结构复杂(包含会员专属字段)。
- SEO 友好:作为导航站,搜索引擎优化至关重要,服务端渲染 (SSR) 是必选项。
- 开发效率:前后端需紧密配合,但又要保持独立部署和维护的灵活性。
基于此,我们采用了 TurboRepo + Nuxt 4 + Strapi 5 的黄金组合。这不仅是一次技术选型的胜利,更是对现代 Web 开发最佳实践的一次完整探索。
![]()
![]()
1. 系统架构概览 (System Architecture)
本项目采用 Monorepo 策略管理全栈代码,基于 TurboRepo 构建高效的工作流。前端采用 Nuxt 4 进行服务端渲染 (SSR),后端使用 Strapi v5 作为 Headless CMS 提供 RESTful API,数据存储在 MySQL 中。
1.1 技术栈 (Tech Stack)
| 领域 | 技术选型 | 版本 | 说明 |
|---|---|---|---|
| Monorepo | TurboRepo | ^2.7.2 |
高性能构建系统,统一管理 apps |
| Package Manager | pnpm | 9.0.0 |
高效的磁盘空间利用与依赖管理 |
| Frontend | Nuxt | ^4.2.2 |
基于 Vue 3 的全栈框架,负责 SSR 与交互 |
| Styling | Tailwind CSS | ^3.4 |
原子化 CSS 框架,通过 @nuxtjs/tailwindcss 集成 |
| Backend | Strapi | 5.33.0 |
灵活的 Headless CMS,提供 API 服务 |
| Database | MySQL | 8.0 |
关系型数据库,通过 mysql2 驱动连接 |
| Docs | VitePress | Latest | 静态文档生成器 |
1.2 目录结构 (Directory Structure)
.
├── apps/
│ ├── api/ # Strapi 后端应用 (Port: 1337)
│ │ ├── src/api/ # 业务逻辑 (Content Types, Controllers, Services)
│ │ └── config/ # 数据库与插件配置
│ ├── web/ # Nuxt 前端应用 (Port: 3000)
│ │ ├── components/ # Vue 组件
│ │ ├── composables/# 组合式函数 (Data Fetching, State)
│ │ └── pages/ # 路由页面
│ └── docs/ # 项目文档 (VitePress)
├── package.json # Workspace 根配置
├── turbo.json # Turbo 构建管线配置
└── pnpm-workspace.yaml
2.3 会员权限设计 (Membership System)
为了区分普通用户与付费会员,我们在 Strapi 后端扩展了 Membership 和 Order 模型。
核心逻辑
-
用户注册: 默认分配为
Authenticated角色,无会员权益。 -
订阅支付: 用户购买会员(月/年/终身)后,后端更新
Membership表,记录过期时间。 -
权限校验: 在获取 Tool 详情时,Controller 会校验当前用户的 Membership 状态。如果过期或未订阅,则剔除
tool.member字段(包含 SOP 和敏感数据)。
// apps/api/src/api/tool/controllers/tool.ts (伪代码示例)
async findOne(ctx) {
const { id } = ctx.params;
const user = ctx.state.user;
// 1. 获取工具完整数据
const entity = await strapi.service('api::tool.tool').findOne(id, { populate: ['member'] });
// 2. 检查用户会员状态
const isMember = await strapi.service('api::membership.membership').checkStatus(user?.id);
// 3. 数据清洗:非会员移除 member 字段
if (!isMember && entity.member) {
delete entity.member;
}
return this.transformResponse(entity);
}
3. 后端设计 (Backend Design) - Strapi v5
后端核心职责是提供结构化的内容管理与 API 服务。
2.1 数据模型 (Content Modeling)
我们定义了多维度的内容类型 (Content Types) 来支撑业务:
-
Collection Types:
-
Tool: AI 工具核心数据(名称、描述、URL、Logo)。 -
Category: 工具分类。 -
Solution: 解决方案文章。
-
-
Single Types:
-
Global: 全局配置(站点标题、SEO 信息、社群二维码)。
-
-
Components:
-
tool.member: 付费会员专属字段(SOP、避坑指南),利用 Strapi 组件功能实现灵活的数据结构。
-
Schema 示例 (Global Config)
// apps/api/src/api/global/content-types/global/schema.json
{
"kind": "singleType",
"collectionName": "globals",
"info": {
"singularName": "global",
"pluralName": "globals",
"displayName": "Global"
},
"attributes": {
"communityGroupTitle": {
"type": "string",
"default": "加入官方交流群"
},
"communityGroupQrCode": {
"type": "media",
"multiple": false,
"allowedTypes": ["images"]
}
}
}
2.2 API 扩展与权限
-
权限控制: 使用
@strapi/plugin-users-permissions管理 Public 与 Authenticated 角色权限。 -
自定义逻辑: 通过覆写 Core Controllers 或增加 Middleware 实现更细粒度的权限控制(如:非会员请求 Tool 详情时过滤掉
tool.member字段)。
3. 前端设计 (Frontend Design) - Nuxt 4
前端应用专注于高性能渲染与极致的用户体验。
3.1 核心特性实现
- 服务端渲染 (SSR): 提升 SEO 表现,首屏加载速度快。
- 组合式开发: 利用 Nuxt Composables 封装业务逻辑。
3.2 关键代码解析
🔐 身份认证与状态管理 (useAuth.ts)
为了保证用户体验,我们封装了统一的认证逻辑,支持注册、登录及 JWT Token 持久化。
// apps/web/composables/useAuth.ts
export const useAuth = () => {
const user = useState<User | null>('user', () => null)
const token = useCookie('auth_token')
const { $strapi } = useNuxtApp()
// 登录逻辑
const login = async (credentials: LoginInput) => {
try {
const { user: userData, jwt } = await $strapi.login(credentials)
token.value = jwt
user.value = userData
return true
} catch (e) {
return false
}
}
// 注册逻辑 (自动关联默认角色)
const register = async (input: RegisterInput) => {
const { user: newUser, jwt } = await $strapi.register(input)
token.value = jwt
user.value = newUser
}
return { user, login, register }
}
全局配置获取 (useGlobal.ts)
为了实现配置动态化,我们封装了 useGlobalConfig,它在应用初始化时从 Strapi 获取配置,并适配 Strapi v5 的响应结构。
// apps/web/composables/useGlobal.ts
export const useGlobalConfig = () => {
return useState('global-config', () => null)
}
export const fetchGlobalConfig = async () => {
const config = useGlobalConfig()
const { find } = useStrapi() // 封装的 Strapi Fetcher
try {
// 适配 Strapi v5 API 响应结构 (dataunwrap)
const response = await find('global', {
populate: '*' // 连表查询所有关联字段 (如图片)
})
config.value = response.data || {}
} catch (error) {
console.error('Failed to fetch global config:', error)
}
}
动态组件渲染 (profile.vue)
![]()
在个人中心页,我们直接绑定从后端获取的配置数据,实现运营内容的实时更新。
<!-- apps/web/pages/profile.vue -->
<script setup lang="ts">
const globalConfig = useGlobalConfig()
// 处理图片 URL 的辅助函数
const getQrCodeUrl = (qrCodeObj: any) => {
// 兼容 Strapi 上传插件的 URL 格式
return qrCodeObj?.url ? `${useStrapiUrl()}${qrCodeObj.url}` : '/default-qr.png'
}
</script>
<template>
<div class="community-card">
<h3>{{ globalConfig?.communityGroupTitle }}</h3>
<img
:src="getQrCodeUrl(globalConfig?.communityGroupQrCode)"
alt="Community QR"
/>
</div>
</template>
5. 部署与运维 (Deployment & DevOps)
4.1 环境变量管理
项目使用 .env 文件管理敏感信息,区分开发与生产环境:
# .env (Root)
STRAPI_URL=http://localhost:1337
NUXT_PUBLIC_API_URL=http://localhost:1337/api
DATABASE_HOST=localhost
DATABASE_PORT=3306
4.2 构建流程
利用 TurboRepo 的缓存机制加速构建:
# 并行构建所有应用
pnpm build
# Turbo 智能缓存示例
# apps/web: cache miss, executing 345ms
# apps/api: cache hit, replaying output 50ms
4.3 生产环境建议
- Process Manager: 使用 PM2 管理 Node.js 进程。
- Reverse Proxy: Nginx 反向代理,配置 SSL 证书与 Gzip 压缩。
- Storage: Strapi 上传文件建议对接 AWS S3 或阿里云 OSS 对象存储。
6. 开发效能与 AI 赋能 (AI-Driven Development)
Creator AI Hub 的诞生本身就是 AI 赋能开发的最佳实践。
⏱️ 惊人的速度:从 0 到 1,仅用 48 小时
如果不借助 AI 工具,这样一个包含全栈架构、CMS 后台、会员系统和 SSR 前端的项目,通常需要 2-3 周的开发周期。但在 AI 辅助下,我们实现了 10 倍提效。
6.1 AI 辅助全流程
- 架构设计: AI 协助选型 TurboRepo + Nuxt 4,并生成了初始的 Monorepo 目录结构。
- Schema 生成: Strapi 的复杂 Content Types(如嵌套组件、关联关系)JSON 配置,由 AI 一键生成,节省了大量手动配置时间。
-
代码编写:
- 前端
useAuth、useGlobal等核心 Composable 逻辑由 AI 快速实现。 - Tailwind CSS 的响应式布局和微交互效果,通过 AI 提示词快速调整。
- 前端
- 文案与文档: 项目文档(包括本文)、SEO 描述、初始测试数据,均由 AI 辅助撰写。
7. 架构扩展性:从导航站到无限可能 (Scalability)
Creator AI Hub 的这套 "Monorepo + Headless CMS + SSR Frontend" 架构,本质上是一个通用的内容变现与知识付费基座。它不仅限于导航站,只需微调数据模型,即可快速裂变出多种应用:
7.1 💡 变体一:付费课程平台
-
改动点: 将
Tool模型改为Course(课程),tool.member改为CourseChapter(课程章节)。 - 功能复用: 会员订阅系统、订单支付、CMS 章节管理、前端视频播放页。
7.2 🛒 变体二:虚拟资源商城
-
改动点: 将
Category细化为资源类型(PPT模板/设计素材/Prompt),增加DownloadLink字段。 - 功能复用: 搜索过滤、资源详情页、下载权限控制(仅会员或单次购买可下载)。
7.3 🏢 变体三:企业内部知识库
- 改动点: 开启 Strapi 的 SSO 单点登录,关闭公开注册。
- 功能复用: 文档层级管理、SOP 标准化流程展示、全站全文检索。
这套架构的最大价值在于**“一次构建,处处复用”**。Monorepo 使得我们可以在 apps/ 目录下轻松添加新的前端应用(如 apps/mobile 或 apps/admin-dashboard),共享同一套后端 API 和 TypeScript 类型定义,极大地降低了多业务线的维护成本。
8. 结语
通过 Nuxt 4 + Strapi 5 的黄金组合,配合 AI 结对编程模式,我们快速构建了一个既有内容深度,又有良好交互体验的 AI 导航平台。这不仅验证了技术栈的先进性,更证明了在 AI 时代,个人的开发潜能可以被无限放大。