尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
手写识别+过程判定:HarmonyOS竖式计算应用开发全解析
1. 项目概述与需求解析1.1 为什么做这个“竖式计算达人”做数字口算练习类应用的人不少但绝大多数都在做选择题、填空题——给你一道题点几个选项判断对错。实际用下来你会发现一个问题孩子真正到了纸上做题的时候竖式怎么写、进位怎么处理、数位怎么对齐这些关键习惯学校里最看重的点在普通口算应用里根本练不到。这个“竖式计算达人”项目就是在这样的痛点下诞生的。它的核心不是出题而是让孩子用手指在屏幕上像写作业一样一横一竖地把完整的竖式过程写出来。应用拿到手写内容后做智能判定得数对不对进位有没有写数位对齐了没有哪一步哪一行出错判完还能直接指出问题在哪个位置。这个应用同时覆盖了两个重要场景第一个是给孩子提供模拟纸笔的练习环境解决“练口算不练笔算”的脱节问题第二个是给家长和老师提供自动批改能力省得每次都要人工去查孩子十几道题里到底哪一步出了问题。1.2 这个应用的用户对象和使用场景从定位上看这个应用的主要使用对象是小学一二年级的孩子也就是正在学习100以内加减法的那批学生。使用场景分两种家庭场景下孩子放学后用它做十分钟的定时练习家长在旁边看反馈课堂场景下老师布置指定数量的竖式题孩子在平板上用触控笔写写完直接提交给老师端查看汇总报告。开发这套应用的前期调研里我专门观察过十几个一年级孩子用普通口算App的状态孩子选了答案秒切下一题看着很开心但你如果让他在纸上写同样的题十有八九会出现对不齐数位、忘记进位标点、得数写错位这些问题。这中间缺的就是一个“能把纸上书写习惯模拟出来”的交互层。HarmonyOS应用实例22这个项目要找的正是这个平衡点既要像游戏一样让孩子愿意上手又要把书写习惯和运算规则完整地约束住。1.3 拿到标题后我做了什么拆解先聊聊拿到这个项目需求后我的整体拆解思路因为这对后面所有开发工作都起到决定性作用。标题里有三个关键词HarmonyOS、100以内加法、竖式计算。HarmonyOS决定了技术栈ArkTS语言、ArkUI声明式开发框架竖式计算决定了整个交互流程的约束条件100以内加法则限定了出题算法的取值范围和进位判断逻辑。实际操作中一个完整的竖式加法计算流程至少包含这么几步用户把两个加数按数位对齐写入或者系统在棋盘格上预填加数从个位开始往高位逐位相加每一位相加如果超过9需要在十位上标记进位“1”最后把每位的结果从低位到高位连起来形成最终得数这四个步骤每一步都可能出错也就意味着我们做判定的时候不能只盯着一个“最终答案”对不对而要把过程拆开逐步比对。这就是这个应用和普通学习类App最核心的区别它不是结果导向的是过程导向的。2. 技术与交互设计思路拆解2.1 手写输入怎么选型自绘棋盘格 vs 系统输入法关键决策手写数字的采集方式直接决定后面的判定准确率和用户体验。这个环节踩坑最多。第一版我图省事直接在TextInput组件上让用户输入数字用系统输入法点数字按键。开发速度快测试也方便但方案很快被否了。“竖式计算达人”模拟的是纸上竖式练习孩子在作业本上是把数字“写”出来的不是“打”出来的。系统输入法弹出来不仅遮挡半个屏幕数字键盘那几个键对一年级小朋友来说也没有物理书写感更关键的是——它没法收集笔迹数据你永远不知道孩子的数字是从上往下写还是从下往上画的这是过程性反馈最有价值的部分。最终我方案定为用ArkUI自绘棋盘格组件铺九宫格样式的底格配合HarmonyOS的Touch事件onTouch逐帧采集手指移动坐标再用Canvas把这些轨迹画出来。每个数字位对应一个独立格子孩子在格子里写数字写完自动进入下一个格子。这样做有几个直接收益书写轨迹能够完整采集存成坐标序列后续可以做笔顺分析书写区域被锁定在格子内不会出现两个数字叠在一起没法判定的事板面模拟真实作业本孩子的肌肉记忆能在触屏上得到延续2.2 工具链怎么选HarmonyOS开发环境搭建全流程开发这个应用用到的核心工具链包括DevEco StudioHarmonyOS官方IDE基于IntelliJ平台定制ArkTSHarmonyOS的应用开发语言在TypeScript基础上做了裁剪和扩展ArkUI声明式UI框架用自定义组件和状态变量驱动界面更新Canvas组件用于绘制网格、书写轨迹和判题标记环境搭建没有什么玄学去官方网站下载DevEco Studio装好之后配置好SDK路径。有几个实际经验分享给大家模拟器建议选phone形态分辨率不用太高272*340这类偏小屏反而更贴近真实手机场景手写判定调试时推荐用真机因为模拟器的触摸采样率和真机差异很大轨迹数据的坐标密度完全不同如果使用Previewer预览注意它对手写事件的模拟效果很差Previewer只能看静态布局别指望它做轨迹调试2.3 出题算法确保每道题都在“100以内”且值得练出题看似简单——随机取两个数相加小于100不就行了但做实操的时候你会发现如果完全随机会出现大量比如32这种一眼看穿的题练习价值很低孩子也会觉得无聊。真正合理的出题策略是分层设计快速口算层不进位两个加数都小于10或者一个两位数加一个一位数但个位相加不超过9。这类题用来培养数感。标准竖式层一次进位从个位相加刚好超过9比如3746。这类题是竖式练习的核心内容涉及进位标记的训练。连续进位层多次进位比如5863个位和十位都进位用来挑战孩子的进位思维。具体到100以内加法“100以内”这个条件约束的不仅是结果更要约束出题方式。我的做法是先设置目标结果的范围在50~99之间逆向拆出两个加数。这样做的直接好处是保证结果范围可控同时能够通过控制每一位的和来控制进位难度。出题参数示例我从实际体验中测出来的一个稳定配方不进位档十位随机1~4个位随机0~5一次进位档十位随机2~5个位固定取能触发进位的组合比如47、68这种两次进位档十位和个位的和都设计成超过9同时保证结果不超过992.4 过程判定机制为什么不能只看最终答案判定是整个项目的灵魂。前面说过孩子在学校里写竖式老师要看的是书写过程对不对。所以这个应用对每一道题建立了四道独立校验关卡数位结构校验、分步计算校验、进位标记校验、最终结果校验。这四道关卡的校验逻辑是数位结构检查两个加数是否按个位对齐十位对齐写在格子里分步计算第一位相加结果换算成个位数字第二位相加结果换算成十位数字进位标记检测十位位置上是否出现了“小1”标记这个可以通过手写识别判断也可以设计成按钮让用户点击加进位标记最终结果把各分步结果拼成完整数字与正确答案比对拿具体的题来举例如果出的是4738孩子计算时进位点对了但最终得数写成85系统应该判定为“分步计算正确、最终结果错误”在反馈里明确说“结果近对了检查一下个位5是不是写错了位置”。这种区分度是任何只判对错的App做不到的。3. 核心功能模块与实现细节3.1 棋盘格手写组件从网格绘制到轨迹采集这个棋盘格组件是整个UI的核心。我用Canvas绘制了一个5行3列的网格——为什么是5行3列因为100以内加法的竖式最多涉及三行加数、加数、进位标记加上一条横线再往下是结果行。每个人在纸上写竖式的顺序是从右往左逐位进行所以最右侧一列是个位中间一列是十位左侧再留一列给百位如果结果超过100就不出这种题但100以内加法允许刚好等于100比如5842所以左边这一列用于可能出现的百位。组件布局参数设计格宽设置响应式适配以设备可用宽度为基准取宽度的1/3格高固定值保证每组格子呈现文具盒的扁平感行高留白每行之间留出一定间隙用来放横线分隔符轨迹采集的代码要点是onTouch事件。在ArkUI里onTouch能拿到TouchEvent对象里面包含touches列表每个触点有x、y坐标和唯一id。在实际处理时要注意单指书写时以touches[0]为准另外一定要等ACTION_DOWN确认后才开始记录轨迹避免把滑动切页的误触也写进轨迹数据里。参考代码结构如下Entry Component struct GridBoard { State lineData: number[][] [] build() { Canvas(this.context) .width(100%) .height(60%) .onReady(() { // 初始化上下文绘制网格 this.drawGrid() }) .onTouch((event: TouchEvent) { if (event.type TouchType.Down) { this.lineData [[event.touches[0].x, event.touches[0].y]] } else if (event.type TouchType.Move) { this.lineData.push([event.touches[0].x, event.touches[0].y]) this.redraw() } else if (event.type TouchType.Up) { // 结束轨迹采集触发识别 this.recognizeDigit() } }) } }这里有个非常关键的细节onTouch的Move事件采样频率。在部分低端设备上Move事件的频率可能是每秒30帧左右如果你直接用点连成线会发现笔画有锯齿感。我的处理方案是在Move事件里主动做插值——当相邻两个点的欧氏距离大于2个像素时在中间补点保证线条连续。3.2 数字识别轻量级笔迹判定还是AI识别这是整个项目里技术选型上面临的最大分流点。第一反应是接入第三方OCR比如常见的通用文字识别服务直接返回数字。但实际操作下来发现几个致命问题OCR是为印刷体或者规范手写体优化的一年级孩子写的数字笔画歪歪扭扭OCR识别率并不高更致命的是接入云端会产生延迟一个数字识别要200~300毫秒整道题要写好多次体验会很差。我的最终选择是自研轻量级判定不走云端。判定策略不依赖复杂的神经网络而是基于几何特征设定格子的中心点坐标统计笔迹的像素覆盖率区分“1”和“7”笔画长短、倾斜方向不同利用最高点和最低点的相对偏移判断有没有写横线用联通域分析笔迹像素聚类区分“0”和“6”0的封闭区域在内部6的封闭区域在下部实际写下来差不多300行代码特征判定的准确率在常见数字上能到95%左右。如果孩子写得比较潦草识别不对我专门设计了一个“修改”按钮轻点写错的格子可以清空重写。试想一下如果没有这个兜底孩子一个数字识别错后面全部连环错心态就崩了。3.3 过程反馈状态机一个题目经历哪些状态每个练习题目从出题到结束经历的状态流转如下待书写初始状态出题完成后显示网格板书等待用户开始写书写中用户正在某个格子写数字界面提示当前激活的格子位置高亮边框已确认单个格子这个格子的数字确认识别完毕可以进行判定校验中四个校验关卡依次跑完通过全对显示绿色对勾、得分加成提醒重试部分错误红色标注出错步骤保留已写部分让孩子修改举个实践中遇到的情况如果孩子在某个格子里写了一个完全不属于数字的图形比如画了一个爱心识别器直接返回“无法识别”这时应用不应错误地进入判定而应停留在让用户重写状态。3.4 完整流程串联从出题到整题判定一道标准题的完整状态流系统出题 - 渲染两个加数的格子 - 孩子写入第一个加数 - 孩子写入第二个加数 - 依次计算每个位的相加结果并写入 -可选输入进位标记 - 点击提交 - 逐位校验 - 展示反馈注意这里有个设计细节先让孩子写两个加数题目本身不预填还是系统直接把加数印在格子里我前期和一线老师聊过这个问题得到的结论很一致练竖式的时候加数可以由题目给定也可以要求自己抄题。对于低年级孩子我更倾向于让系统直接给出加数预填因为这个应用的重点是培养列竖式和计算过程的习惯如果连抄题都让小孩做很容易抄错数字结果判定的时候系统会把它误判为列式错误打击孩子信心。预填加数用到的组件属性是这样的Text(${tens}) .fontSize(28) .textAlign(TextAlign.Center) .width(this.cellWidth) .height(this.cellHeight)加数数字预填用Text普通文本就行结果的格子则用Canvas采集笔迹。3.5 判定核心代码分步计算与结果校验判定逻辑的代码核心写得比较清晰这里放出关键部分供参考// 判定方法入参为十位和个位的用户手写结果与进位标记状态 function checkProcess(question: Question, userAns: UserAnswer): CheckResult { // 第一步拆分两个加数的十位和个位 const aTens Math.floor(question.a / 10) const aOnes question.a % 10 const bTens Math.floor(question.b / 10) const bOnes question.b % 10 // 第二步期望的个位相加可能涉及进位 const rawOnesSum aOnes bOnes const expectedCarry Math.floor(rawOnesSum / 10) const expectedOnesDigit rawOnesSum % 10 // 第三步期望的十位相加要加上进位 const rawTensSum aTens bTens expectedCarry const expectedTensDigit rawTensSum % 10 const expectedHundredsDigit Math.floor(rawTensSum / 10) // 第四步校验用户过程与期望是否一致 const errors [] if (userAns.onesDigit ! expectedOnesDigit) { errors.push({ pos: ones, type: digit_error, expect: expectedOnesDigit }) } if (expectedCarry 0 !userAns.carryMark) { errors.push({ pos: carry_missing, type: carry_missing }) } if (userAns.tensDigit ! expectedTensDigit) { errors.push({ pos: tens, type: digit_error, expect: expectedTensDigit }) } return new CheckResult(errors.length 0, errors) }这里补充说明一下为什么进位校验单独成一项在真实教学场景里孩子最常犯的错误就是忘记进位或者进位位置写错。如果应用把“进位缺失”和“结果错误”笼统地混在一起报错家长根本不知道问题出在哪个环节。拆开之后反馈信息就能很精确地定位。4. 实操过程与关键实现记录4.1 工程初始化与页面结构搭建创建新工程的步骤比较常规DevEco Studio新建Empty Ability项目选择Stage模型语言选ArkTSAPI版本按当时最新的稳定版来。项目名可以直接用竖式计算达人包名注意用符合规范的格式。工程创建完成后页面结构我规划了三个页面模式首页模式选择难度选择练习页核心棋盘格练习报告页结果统计这三个页面用一个主页面组件承载通过动态切换内容的方式跳转减少页面栈的压栈操作。核心区的组件树简明描述MainPage: Column: TitleBar: 标题栏 StatsBar: 题目进度显示的统计条 GridBoard: 自定义棋盘格组件 ActionBar: 按钮区提交/重写/下一题使用自定义组件注意父子通信。GridBoard内部状态比如当前激活格子要实时同步到父组件用于提交按钮的可用性控制。子组件用Link双向绑定状态这样可以避免状态分叉。4.2 界面适配不同屏幕尺寸下的棋盘格自适配这里必须提一个坑。HarmonyOS的ArkUI使用的是vp虚拟像素单位一套设计可以在不同密度的设备上等比缩放。但问题是平板的默认字体大小和手机差异很大如果棋盘格的高度用固定vp设置在平板上显示会偏小很多孩子点写会辛苦。建议方案是棋盘格宽度用百分比约束高度则通过宽高比计算。具体参数const cellWidth this.boardWidth / 3 const cellHeight cellWidth * 0.85 // 模拟作业本格子的略扁效果实测下来在手机典型宽度360vp上格子宽度约100vp高度约85vp对一年级孩子手指尺寸来说是够的。平板上格子更大书写更从容。还有个细节是横线该怎么画。竖式的横线我用Canvas的strokeRect绘制实现在两个加数行下方。如果有进位标记行水平线还要加一道加粗。横线的颜色不宜太深否则会和手写笔迹混淆。4.3 练习模式与计分策略练习模式分两种自由练习和计时挑战。自由练习不限制时间做完一道进入下一道重点在于过程的正确性。计时挑战限定时间比如3分钟过程中实时显示剩余时间和已完成进度。计分策略对孩子的激励影响很大。我设计的是基础正确分加过程分只要最终结果正确得基础分过程中进位标记、步骤全部正确再奖励过程分。如果进位漏了但结果对了就只能拿一半分这样向孩子传递的信息是“结果重要过程规范同样重要”。4.4 完成后的报告一日练了多少错在哪类做完一组题之后报告页展示的信息包括对错统计图用颜色分段错题明细每道题目标注错误类型分类单人平均用时。这样家长能直观看到孩子是“进位总是忘”还是“数位对不齐导致全盘乱”。这个报告不联网也能跑本地保存最近10次的练习记录。数据不用后端用首选项存储即可轻量不复杂。这里有个实现上的细节保存报告时同时记录题目版本号。一旦后续更新出题策略旧的报告不会混入新题型的统计里。5. 常见问题与排查技巧实录5.1 手写轨迹丢失或断线怎么办排查这类问题优先看onTouch事件的Move触发频率。部分设备在系统层面会对手指滑动轨迹做一些节流处理导致轨迹呈点状而非线状。解决方案就是上文提到的插值补点。还有一个隐蔽的问题是层叠遮挡如果棋盘格上面有任何不透明的兄弟组件哪怕只有1px覆盖到格子上Touch事件都会被上层组件截获导致轨迹进不来。检查方法很简单把棋盘格背景改成红色半透明看是否有其他组件挡住了。5.2 数字识别不准尤其4和9、6和8混淆我踩过的坑中最深的一个。4和9的差异在于封闭区域位置但孩子写的4上部如果不闭合特别容易和9混淆。后来我在识别逻辑里加了一个上下文约束如果识别结果导致当前位的算数过程超出100就自动把候选数字映射到相近的可用数字。比如个位识别为9但十位的结果已经溢出那结合格子的书写背景很大概率孩子写的是4就自动修正。这类纠错逻辑一定要放在判定之后做同时保留用户重写能力否则误判会产生“系统觉得我错但我觉得我没错”的困扰。5.3 孩子误触提交、误触清空怎么处理这是幼儿交互里绕不开的问题。低龄孩子在平板上很容易手掌根部碰到屏幕。处理方案有两条线第一条线是交互防错。提交按钮加入确认步骤轻点第一次弹出“确认提交”3秒内不二次确认则取消。清空按钮则必须长按1.5秒才触发避免误触。第二条线是掌触隔离利用onTouch事件里的sourceType字段若是手掌触摸触发的直接丢弃。HarmonyOS的触摸事件里有source字段可以用来区分手指的接触面积类型实际测试中能过滤掉约80%的无效掌触。5.4 在预览器里调试轨迹为什么完全不工作Previewer预览器的本质是渲染静态UI不模拟真实的触摸事件流。所以所有轨迹采集相关的逻辑都无法在Previewer里正常跑起来。调试手势和Canvas轨迹必须用真机或本地模拟器。我建议把CustomPaint的绘制逻辑和业务逻辑分离这样在Previewer里能展示网格和预填数字的静态界面真正的手势部分则留到真机联调。6. 进阶优化方向与后续扩展6.1 笔顺分析从“写对”到“会写”当前版本的判定只管“写出来的结果对不对”但以后可以升级为“笔顺对不对”。比如有些孩子会把数字8画成两个圆拼起来笔顺完全不对虽然最终看起来也是8但这个习惯会影响后续书写速度。笔顺分析需要建立真正的坐标时间序列数据库同时确定标准笔画的采样方向。这本质上是一个模板匹配问题实现要比数字识别更复杂但这是过程性反馈应用的发展方向。6.2 知识薄弱点多维分析现有报告只统计对错和错误类型其实可以更进一步把错误关联到对应的运算能力维度比如“进位理解不足”“个位加减法不熟”“数位对齐意识弱”。当累积数据足够多后这些维度可以做雷达图让老师和家长一眼看出孩子的能力结构。6.3 支持减法、乘法以及多位乘除100以内加法只是起点竖式的价值在于同一套交互框架能自然扩展到更大的数域。减法竖式只需要增加“退位标记”逻辑乘法竖式则需要处理中间过程的多行写法除法竖式涉及试商交互复杂度会显著提升。从技术架构上说只要棋盘格的单元格组织方案是数据驱动的扩展算法形态只需要换掉判定模块和出题策略模块。6.4 数据组卷与错题定制做题库的同学可能会考虑孩子连续错三题进位问题后系统自动把后续的题目全部调整为进位专项题。这种动态难度调节在HarmonyOS端本地就能完成不需要服务端智能推荐。出题策略模块会在原有的随机算法中增加权重控制每道题目的进位数、难度权重都做成可配置的。这样孩子练起来更有针对性不容易出现“练了十分钟十道题全是不进位”的低效情况。7. 写在最后的一些开发心得这个项目的核心收获是教育类应用的要义不在于做出多花哨的动画而在于是否能真正还原学习场景并在过程数据上给出有效反馈。做竖式计算练习的HarmonyOS应用“判定”和“反馈”这两件事占了80%的思考量。写数字识别要容忍孩子的书写不规范性过程判定要拆得够细给到精确归因反馈不能只打对错还得告诉孩子错在哪一步、怎么改。项目上线试用了两周几十个孩子的数据积累下来让我确信过程化、精细化的反馈才是这类练习应用最核心的价值。如果你的孩子也正在为进位老错发愁在真实纸上练竖式之前先让他用这套东西写几组错误定位效率会比直接刷一套题高得多。最后再分享一个实际测试中发现的技巧把棋盘格的底色设计成淡黄色接近作业本的颜色孩子在使用时注意集中度明显好于纯白底界面这算是一个小小的UI心理学应用做儿童教育软件时可以多用这类贴近真实场景的设计。
RELATED

相关推荐

CANN全链路算子开发体验提升:从选型到调优的实战指南

CANN全链路算子开发体验提升:从选型到调优的实战指南

做算子开发的人都知道,算子从“脑子里有个想法”到“真的在硬件上高效跑起来”,中间的路其实比想象中要长得多。CANN作为昇腾AI处理器配套的软件栈,这几年在算子开发全流程上的动作一直不少,尤其是在工具链、调试手段和性能分析这…

📅 2026/10/13 13:29:27
艺图Edraw Mind Map实战:从导图搭建到脚本批量生成与导出避坑

艺图Edraw Mind Map实战:从导图搭建到脚本批量生成与导出避坑

简介:艺图Edraw Mind Map是一款面向职场人士、教师学生及项目管理者的综合绘图工具,以思维导图为核心,兼顾流程图、组织架构图等多种图形表达需求,帮助用户快速梳理思路、规划项目与整理知识体系。资源以zip压缩包形式提供&#x…

📅 2026/10/13 13:29:27
SQL Server数据类型实用梳理:选型逻辑与踩坑指南

SQL Server数据类型实用梳理:选型逻辑与踩坑指南

写 SQL Server 数据类型的完整梳理,这类内容网上一搜一大把,但大多是文档翻译腔,看完还是不知道怎么选。我干这行十几年,建过不少表,也重构过不少被数据类型坑惨的库,今天不打算照着微软官方文档复读一遍&a…

📅 2026/10/13 13:29:27
MORE NEWS

更多资讯

📰

用Python+SQLite自建牛客刷题跟踪器:每日提醒与数据可视化

早上 8 点整,手机弹出一条 push:今天的恶魔果实已上线,敢不敢吃掉?点进去是牛客当日每日一题的链接。这个每天准时报到的家伙,就是我给自己写的刷题跟踪工具“恶魔果实”,本质是一个牛客tracker。它在本地维…

📰

自行车调度MATLAB实现:遗传算法建模、解码器与惩罚系数避坑指南

简介:面向数学建模竞赛选手的自行车调度MATLAB源码包,完整覆盖站点分布建模、需求预测、调度策略生成与运输成本优化等环节。包内以m脚本和函数为主,除数据预处理、模型定义、求解器调用等基础流程外,还实现了时间窗计算、距离矩阵…

📰

卷积神经网络(CNN)核心原理与参数设置实战解析

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

📰

足球数据下载搜索统计系统:从数据管道到可回溯分析的工程实践

简介:这套《足球数据下载搜索统计系统(套件)》面向足球爱好者与竞彩玩家,专注于赔率、盘口、竞彩数据的获取与统计分析,解决手工收集比赛信息效率低、难以对比历史趋势的问题。压缩包共18个文件、约1.53MB,含exe主程序、txt说明与…

📰

JVMTI Agent开发避坑指南:从加载失败到生产级稳定

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

📰

词达人工具zip解压到SQLite管理:伪加密修复与词库导入全指南

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

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬