Cocos Creator拖拽排序列表实现:坐标转换、Tween动画与数据持久化
简介这是一份基于Cocos Creator实现的拖拽排序列表Demo资源包面向需要构建可交互排序界面的游戏客户端或应用开发者。资源以拖拽移动、排序存储、状态更新三大核心功能为主线通过监听触摸与鼠标事件捕获拖拽的开始、移动和结束状态利用数组记录实时顺序并同步更新节点位置完成界面刷新兼顾了逻辑与视图的分离。适合希望掌握Creator事件系统、节点层级和UI组件配合使用的初中级开发者。压缩包内共16个文件包括3个ts脚本、5个json配置文件、4个meta资源索引以及fire工程文件整体仅243KB导入后可直接打开体验。目前已有114人学习使用。案例中保留了从拖拽触发到排序持久化的完整流程目录结构清晰脚本与配置分离便于二次修改同时资源描述还涉及对象池、批处理渲染等优化思路可帮助读者在此基础上扩展出背包整理、关卡编辑等更复杂的列表场景。1. 拖拽排序列表难点不在“拖”而在拖完之后的位置与顺序在 Cocos Creator 项目里做拖拽排序列表多数人一开始都以为只是“按住 Item、移动、松手”这么简单。真拆开做就会发现这一套交互其实被三个问题卡住手指位置怎么换算成列表坐标系里的节点位置列表项怎么判断该插到哪个索引还有排序结果怎么同步回数据层并且持久化。前两个决定用户拖起来顺不顺手第三个决定重进游戏后用户排好的顺序还在不在。这份资源给的是一个可以挂在任意容器节点上直接改的拖拽排序列表脚本适合背包、关卡选择、自定义工具栏这类需要手动排列顺序的界面。你需要会写 Cocos Creator 组件脚本对 Tween 有基本接触就可以上手。坑我先放在前面拖拽排序真正的难点都在松手之后而不是拖动途中。2. 触摸与坐标先把手指位置翻译成列表空间里的坐标2.1 事件注册先理解“立即拖”并不是最佳方案在 Cocos Creator 3.x 里绑定 Item 触摸事件我习惯直接挂在 Item 组件自身。这样每个列表项就是一个独立的拖拽单元不用在父容器上判断“这个触摸到底按到了哪个子项”。事件注册要覆盖四个TOUCH_START、TOUCH_MOVE、TOUCH_END、TOUCH_CANCEL。import { _decorator, Component, Node, EventTouch, Vec3, tween, Tween } from cc; const { ccclass, property } _decorator; ccclass(DragSortItem) export class DragSortItem extends Component { private startUIPos new Vec3(); private basePos new Vec3(); private dragged false; onEnable() { this.node.on(Node.EventType.TOUCH_START, this.onDragStart, this); this.node.on(Node.EventType.TOUCH_MOVE, this.onDragMove, this); this.node.on(Node.EventType.TOUCH_END, this.onDragFinish, this); this.node.on(Node.EventType.TOUCH_CANCEL, this.onDragFinish, this); } onDisable() { this.node.off(Node.EventType.TOUCH_START, this.onDragStart, this); this.node.off(Node.EventType.TOUCH_MOVE, this.onDragMove, this); this.node.off(Node.EventType.TOUCH_END, this.onDragFinish, this); this.node.off(Node.EventType.TOUCH_CANCEL, this.onDragFinish, this); } }这段代码的逻辑不复杂但有几个点要提前说清楚。TOUCH_CANCEL 必须接和 TOUCH_END 一样的处理函数因为当来电、系统手势或外部逻辑把触摸打断时引擎派发的是 CANCEL 而不是 END。如果不收尾Item 会永远停在“拖拽中”的半透明状态直到下一次触摸再唤醒它这就是个黑匣子问题。事件注册完成后接下来要决定“什么时候真正进入拖拽状态”。很多初版实现会在 TOUCH_START 里立刻把 Item 置顶并开始跟随这个方案在普通界面看着没问题一旦列表外层套了 ScrollView用户手指轻微一动 Item 就会飞起来滚动意图被完全吞掉。我一般保留一个 10px 以内的判定阈值超过以后才真正把 Item 从“可点击”切换成“正在拖拽”这个细节对后面的滚动冲突和第 4 章避坑都很关键。private onDragMove(event: EventTouch) { const uiPos event.getUILocation(); if (!this.dragged) { const dx uiPos.x - this.startUIPos.x; const dy uiPos.y - this.startUIPos.y; if (Math.hypot(dx, dy) 10) return; this.dragged true; this.setDragVisual(); } }判定阈值这段10px 不是拍脑袋定的。移动端手指在屏幕上有一定接触面积按下时轻微抖动很常见小于 10px 的位移应该被当成“误触”或“点击”。桌面端可以收紧到 5px硬要自适应的话用10 * view.getScaleX()也行。有一点要注意阈值判断只影响是否开启拖拽并不拦截事件本身所以即使用户想滚动列表只要位移没到阈值这套代码完全不做任何事ScrollView 仍然能正常工作。2.2 坐标链路getUILocation 与 convertToNodeSpaceAR 必须配对拖拽排序列表里最容易翻车的点是触摸坐标与节点坐标系混用。事件里getLocation()返回的是世界坐标实际像素值而节点position是相对父节点的本地坐标。两者之间隔着一层 Canvas 适配缩放以及节点层级变换。设计分辨率和真机像素不一致的时候直接拿getLocation().x填入setPositionItem 就会跟手方向错位、距离偏大这个问题我在某跨平台系统里真机调试时见过约 80px 的偏移。正确做法是走完整链路getUILocation()拿到 UI 坐标系下的触摸点再用“父节点”调用convertToNodeSpaceAR把它换算成 Item 的本地坐标。private onDragMove(event: EventTouch) { if (!this.dragged) { this.tryStartDrag(event); if (!this.dragged) return; } const parent this.node.parent!; const uiPos event.getUILocation(); const local parent.convertToNodeSpaceAR(new Vec3(uiPos.x, uiPos.y, 0)); this.node.setPosition(local); }这里有两个容易写错的地方。第一参考节点必须是 Item 的父节点因为 Item 的 position 是相对父节点的用 Item 自身去 convert等于在它自己的局部坐标系里找一个点再设置到父节点坐标系结果必然多套一个偏移。第二要用 AR 版本而不是普通convertToNodeSpace。普通版本以节点的左下角为原点AR 版本以锚点为原点而position本来就锚定在锚点上。如果列表容器锚点是 (0.5, 0.5)用错版本会让拖拽点整体偏半个列表宽度的高度看起来就是“抓不住”的玄学现象。3.x 的getUILocation()对应 2.4 里的touch.getUILocation()2.x 老项目里常见的getLocation()写法在这个场景下不推荐。如果你在维护老代码把坐标链路统一成“UI 坐标 → convertToNodeSpaceAR”后再谈其他优化否则后面调参数全部跑偏。2.3 拖起后的置顶与视觉反馈当 Item 进入拖拽状态需要立刻做两件视觉变化一是让它在兄弟节点里呈最高层级防止被其他 Item 遮挡二是给一点缩放和透明度变化让用户知道“我已经把它提起来了”。private setDragVisual() { const parent this.node.parent!; this.node.setSiblingIndex(parent.children.length - 1); this.node.setScale(1.08, 1.08, 1); } private resetDragVisual() { this.node.setScale(1, 1, 1); }setSiblingIndex(parent.children.length - 1)在 3.x 里会把当前节点移到 children 数组尾部绘制顺序随之排到最上层这个操作是即时生效的不需要等下一帧。需要注意的是setSiblingIndex 会直接改变 children 的顺序如果你后面依赖 children 顺序做数据同步这里就已经把顺序打乱了。我在第 5 章会专门展开讲这个问题先记住一个结论children 顺序是视图层的渲染顺序业务顺序应该依赖 dataId 而不是节点 index。置顶时机也应该放在“进入拖拽状态”之后而不是 TOUCH_START 立即执行。否则用户每次点击列表项节点都被送到顶层列表项在最上层叠着多次点击以后视觉顺序和实际逻辑顺序完全错开排查起来非常别扭。缩放 1.08 在常规 UI 上够明显如果 Item 本身带边框或阴影效果建议同时在拖起时加一层投影不加也不影响逻辑但视觉质感会差一点。2.4 松手后的归位与容错TOUCH_END 触发时拖拽列表项不能直接恢复原 scale 就完了。如果列表项最终位置不在手指当前位置动画要补一段“修正位移”如果光标位置和当前索引一致就直接复位。归位动画我习惯用 0.12 秒的 Tween配合 quadOut 缓动手感介于干脆和柔和之间。private onDragFinish(event: EventTouch) { if (!this.dragged) { return; } this.dragged false; this.resetDragVisual(); }代码里有个隐藏分支拖拽状态为 false 时直接 return这表示用户这次只是点了一下没有进入拖拽什么都不用做。真正的“归位 数据同步”逻辑不放在这个函数里而是放在列表排序管理器里统一处理。原因在 3.2 里会讲到每个 Item 的动画目标位置必须由“排序判定模块”给出单个 Item 自己只负责执行。3. 排序判定与重排动画中心点比较加 Tween 回位3.1 插入位置判定用中心点而不是边界相交拖动中的 Item 每帧都在改变位置需要实时算出“它当前应该插在第几个”。用边框相交判断是很多初版实现的习惯但列表项高度不一致时边框相交会在交界处反复跳动画看起来像抽搐。更稳定的是中心点判定把列表里除被拖项之外的所有 Item 的中心坐标取出来拿被拖项的中心点逐一比较方向越过谁就插到谁前面。private findTargetIndex(): number { const parent this.node.parent!; const children parent.children; const dragPos this.node.position; const dragCenterY dragPos.y this.anchorOffsetY; let targetIndex 0; for (let i 0; i children.length; i) { const child children[i]; if (child this.node) continue; const childPos child.position; const childCenterY childPos.y this.anchorOffsetOf(child); if (dragCenterY childCenterY) { targetIndex i 1; } } return targetIndex; }这里为什么要用中心点而不是直接用 position因为 Item 的锚点不一定在中心。很多列表的锚点是 (0.5, 0.5)但如果你遇到锚点在顶部或者底部的设计稿position.y 指的就是头部或者底部拿去和其他 Item 的中心比判定就会偏半个 Item 的高度。anchorOffsetY就是把锚点到几何中心的偏移补回来中心 Y position.y contentSize.height * (0.5 - anchorY)。这个公式在 Cocos Creator 2.x 和 3.x 里都成立前提是拿节点自己的contentSize而不是父容器的尺寸。方向系数也要注意如果列表是从上往下展开坐标会反向判断条件里的大于小于号需要跟着翻转。我建议在组件属性上暴露一个sortDirection: 1 | -1参数默认 1 表示 Y 轴向上往下排列时传 -1所有比较统一走这个系数不要在多个函数里各写一套正负逻辑那样后续维护很容易漏改。3.2 重排动画Tween 让位前必须先停止旧动画排序判定算出的 index 变化以后其他 Item 要立刻让出新位置。手动在 update 里改位置不是不行但多个 Item 同时移动时位置目标值会出现浮点累积误差最后对不齐坐标。用 Tween 的 to 方法是终值驱动不会累积误差这才是排序类动画的标准做法。private reorderItems() { const parent this.node.parent!; const children parent.children; const dragNode this.node; const targetIndex this.findTargetIndex(); const dragIndex children.indexOf(dragNode); if (dragIndex targetIndex) return; // 先停止所有 Item 上残留的 tween避免新旧动画叠加争夺 children.forEach((child) { Tween.stopAllByTarget(child); }); // 剩余 Item 按“不包含被拖项”的方式重新计算目标位置 const others children.filter((child) child ! dragNode); others.forEach((child, order) { const itemIndex this.getIndexByVisualOrder(child, others); const finalPos new Vec3(child.position.x, -itemIndex * this.itemHeight, 0); tween(child).to(0.15, { position: finalPos }, { easing: quadOut }).start(); }); }这段代码里最关键的一行是Tween.stopAllByTarget(child)。快速连续拖动时如果旧 Tween 还没执行完新的 Tween 又启动同一个 Item 在同一帧被两段动画分别写位置最后会飘到谁都不是的位置。我测试过一次手速快时 Item 会在一帧内被推进 200px 之外看起来像瞬移这就是新旧动画叠加造成的。目标位置的计算方式也要讲究。这里按“被拖项剔除之后剩余 Item 在整个列表中的视觉序号”来布置是用最终位置重新推每个 Item 的坐标而不是在每个 Item 原坐标上叠加一个偏移。按偏移叠加的方案只对单次拖动成立连续穿插时每个 Item 的局部偏移渐渐累计列表会出现不可控的漂移。这个是 0.15 秒加 quadOut 的组合是我在做模拟项目 X 时反复试出来的太快用户眼跟不上太慢给人松散感如果列表项很多超过 20 条时间拉到 0.2 秒更稳妥。3.3 让位顺序的重新计算不依赖 children 原生顺序重排动画里有个容易踩的细节因为拖动中的 Item 已经被 setSiblingIndex 置顶过children 的顺序早就不是业务顺序了。如果你在上面代码里直接用children.indexOf(child)作为目标 index结果一定是乱的。正确做法是维护一个“视觉顺序数组”这个数组由排序判定结果决定而不是从节点树读取。我在资源里定义了一个visualOrder: Node[]的数组每次 findTargetIndex 之后就把被拖项从这个数组里临时移除再按目标索引插回最后遍历数组给所有 Item 设置目标位置。private syncPositionsFromVisualOrder() { const itemHeight this.itemHeight; this.visualOrder.forEach((node, idx) { const finalPos new Vec3(node.position.x, -idx * itemHeight, 0); Tween.stopAllByTarget(node); tween(node).to(0.15, { position: finalPos }, { easing: quadOut }).start(); }); }这个做法的好处是把“排序逻辑”和“节点渲染层次”解耦。后面做数据同步时直接读取 visualOrder 对应的 dataId 数组就是最终排序结果不用再去 children 里猜。注意 visualOrder 数组要跟着每次排序计算同步更新否则它也会变成另一份过期数据。把 visualOrder 的更新放在 findTargetIndex 同一个函数里、紧跟在 index 计算之后可以避免它和真实位置不同步。3.4 首尾边界与空列表的兜底排序判定还有一个边界要兜住被拖到第一个 Item 上面或最后一个 Item 下面时会出现目标索引越界。clamp 一下就好const max this.visualOrder.length - 1; this.currentTargetIndex Math.max(0, Math.min(targetIndex, max));空列表的情况容易漏父节点 children 长度为 0 时被拖项没有参考对象直接把 visualOrder 清空并复位 Item 位置就够了。这两段边界代码看起来不起眼但一旦漏掉数据层同步时数组的下标访问会越界直接抛异常排查成本远高于这几行的维护成本。4. 避坑指南五个我在拖拽排序里真实踩过的坑4.1 坑一被拖 Item 动的时候外层 ScrollView 也在滚现象手指按住列表项往上滑整个列表跟着滚动Item 只是原地升高或者 Item 确实动了但松手后它被 ScrollView 的惯性带回原位。原因ScrollView 的触摸监听注册在外层容器TouchMove 事件冒泡遍历到了它它以为用户在滚动列表而 Item 上的拖拽逻辑也在这一帧执行两边同时修改 position最终结果是状态互相覆盖。解决在进入拖拽状态后立刻把事件冒泡停掉并给 ScrollView 加一个拖拽锁。if (this.dragged) { event.propagationStopped true; this.scrollView.enabled false; }注意propagationStopped必须放在 dragged 判断之后只有真正进入拖拽才拦截冒泡。如果用户只是轻划列表想滚动没到 10px 阈值这时拦截会导致整个列表无法滚动。4.2 坑二兄弟 Item 跟着一起动整个列表下饺子现象拖住任意一个 Item列表里其他 Item 也同时向同一个方向移动个别还重叠在一起。原因你把触摸事件绑定在了父容器节点上而不是每个 Item 自身。父容器收到一次 TouchMove遍历所有 children 给每一个都执行位置变更当然全列表一起动。解决把事件绑定在 Item 节点上也就是第 2 章的写法并且严格用event.target this.node过滤。如果业务上必须在父容器做事件委托那就要维护触摸点与具体 Item 的映射表靠触摸 id 来区分当前拖动对象事件触发的第一帧先查映射再决定动谁。4.3 坑三多分辨率真机上拖拽偏移看起来是玄学现象编辑器里拖拽完全跟手打安卓包偏移几十像素换一台宽高比不同的平板偏移更夸张。原因坐标空间用混了。getLocation()返回的是世界坐标单位随实际屏幕分辨率走而 Item 的 position 处于设计分辨率下的 UI 逻辑空间。设计分辨率 1280x720真机 2400x1080Canvas 适配后缩放比例约 1.87直接把返回数据塞给 setPosition偏移量就是缩放比例乘出来的差值。解决全程走getUILocation()parent.convertToNodeSpaceAR()这条链路任何地方都不要直接用 getLocation 参与 Item 位置计算。4.4 坑四快速来回拖时动画乱飞Item 瞬移现象手速快一点拖到一半反向拖Item 会突然跳到远离手指的地方或者松手以后跑向老位置。原因旧 Tween 没有停止新 Tween 已启动。同一个节点在同一帧被两段动画分别写 position写出来的坐标既不是旧动画的目标也不是新动画的目标看起来就是乱跳。我见过项目里只对“被拖项”做了停止 Tween没对让位项处理结果其他 Item 仍然在错误时间跑去旧位置。解决每次重排开启动画前统一停止列表内所有目标节点的 Tween。这行代码放在重排入口而不是动画启动处确保任何残留动画都被清理干净。4.5 坑五拖完 UI 顺序对但存完档顺序还原现象UI 上拖拽效果完全正常重新拉起列表顺序回到拖拽前或者第一次拖拽成功第二次保存后顺序错乱。原因数据层没有跟随拖拽结果同步。如果保存时用children.indexOf取顺序而 children 顺序被置顶操作改变过就会取到错误结果如果压根没同步数组下次构建列表又是按旧数组渲染UI 顺序自然回退。解决给每个 Item 绑定 dataId拖拽结束后按视觉顺序重建数据数组再写入本地存储。这个方案完整展开在下一章。5. 数据层同步与二次持久化拖完后的数组要重建5.1 用 dataId 做数据锚点别用 index拖拽排序的数据同步最安全的建模方式是Item 节点负责展示数据数组负责真相。Item 上挂一个dataId字段拖拽过程中不管节点层级的 index 怎么变数据查找都靠 dataId 完成。interface SortableListData { id: string; [key: string]: unknown; }不用 index 的原因在前面已经埋过伏笔setSiblingIndex 置顶操作改变了 children 顺序。你在 TOUCH_END 里用 children.indexOf 取到的顺序是“当前绘制顺序”不是业务顺序。尤其是动画还没跑完就松手indexOf 结果和最终视觉位置对不上保存进数据层就会错乱。dataId 方案让数据层完全不关心节点渲染顺序动画和逻辑彻底解耦。5.2 拖拽结束后的数组重排先删后插TOUCH_END 时把所有 Item 按当前视觉位置排序得到新的 id 数组然后重建数据数组。重建逻辑建议用“先移除再插入”而不是交换两个位置。private reorderData(sourceId: string, targetId: string) { const fromIndex this.dataList.findIndex((item) item.id sourceId); const toIndex this.dataList.findIndex((item) item.id targetId); if (fromIndex 0 || toIndex 0) return; const [dragged] this.dataList.splice(fromIndex, 1); this.dataList.splice(toIndex, 0, dragged); }先移除再插入的语义是“把 A 放到 B 原来所在的位置”这恰好符合拖拽排序的用户认知。如果用交换两元素的写法跨多个位置拖动时会经历多次交换路径最终顺序极容易偏离用户预期。要注意移除后数组长度变了这里因为先把 fromIndex 移除又把目标定成 B 的原位置所以插入位置直接用 toIndex 不用补偿。如果业务上把 fromIndex 参与进目标位次才需要考虑移除带来的索引前移。5.3 本地存储保存排序结果并在加载时还原排序结果要写进本地存储才能跨会话生效。Cocos Creator 3.x 里直接使用 localStorage存储结构用 JSON 数组保存 dataId 顺序。private saveOrder() { const orderedIds this.visualOrder.map((node) node.getComponent(DragSortItem)!.dataId); localStorage.setItem(drag_sort_order, JSON.stringify(orderedIds)); } private loadOrder() { const raw localStorage.getItem(drag_sort_order); if (!raw) return; try { const ids JSON.parse(raw) as string[]; // 按 ids 顺序重新构建列表数据 this.rebuildListData(ids); } catch (e) { console.error(排序数据解析失败, e); } }保存时依赖 visualOrder 而不是读取节点 position 排序视觉顺序数组是在每帧排序判定中同步维护的它的状态永远跟最终动画目标一致。真实项目里保存的时机也要卡准如果在动画未结束时保存visualOrder 虽然已经更新但节点实际位置还在飞下次构建列表时如果读的是节点位置就会错。建议在 TOUCH_END 之后等 0.2 秒再保存给最后一段动画留出落定时间。这个延迟在很多场景下是土办法但它稳定比在多个 Tween 回调里计数等动画结束要简单得多。this.scheduleOnce(() { this.saveOrder(); }, 0.2);配合本地存储还有一个常见需求重新进入界面后按保存的顺序重建列表。rebuildListData里做的事很简单遍历保存的 ids在数据源里找到对应数据项按顺序 push 到新数组再刷新全部 Item 节点。注意要把界面上的 Item 也按照这个顺序重新排布不然数据层对而界面错用户一样会认为是 Bug。5.4 一段完整的排序项目管理器骨架把前面这些逻辑收敛到一个管理器组件里结构会清楚很多。我给这套脚本设计的是一个DragSortManager组件挂在列表容器上持有数据源、Item 工厂函数、视觉顺序数组三个核心状态。ccclass(DragSortManager) export class DragSortManager extends Component { dataList: SortableListData[] []; visualOrder: Node[] []; itemHeight 88; public refresh() { this.visualOrder this.node.children.filter((n) n.active); this.syncPositionsFromVisualOrder(); } public onItemDragTo(item: Node, targetIndex: number) { const currentIndex this.visualOrder.indexOf(item); if (currentIndex targetIndex) return; this.visualOrder.splice(currentIndex, 1); this.visualOrder.splice(targetIndex, 0, item); this.syncPositionsFromVisualOrder(); } public commitOrder() { this.reorderData(); this.saveOrder(); } }这样 Item 组件只负责触摸和坐标排序算法、动画、数据同步都集中在管理器中代码边界清楚后期接服务端排序或做撤销功能都容易。我在做某跨平台系统的装备排序需求时最终版本就是这个结构。6. 一个加分技巧50 条数据时虚拟列表也能拖拽排序虚拟列表在条目超过几十条时会启用它只实例化可视区域内的节点滚动时循环复用 Item。这个机制和拖拽排序天然冲突一个正在被拖的节点如果被回收去显示另一条数据手指底下突然空掉排序逻辑跟着崩。我的处理是给虚拟列表引擎加一个“拖拽锁定开关”。public recycleLocked false; private onDragStart() { this.recycleLocked true; } private onDragFinish() { this.scheduleOnce(() { this.recycleLocked false; }, 0.05); }每次刷新可视窗口前虚拟列表先检查recycleLocked锁定时只更新滚动范围不回收节点、不重置子项数据。解锁延迟 0.05 秒不是随便写的它保证最后一段动画时间帧里不被回收打断。锁定期间因为少了一部分回收复用内存占用会略高但对于 50 到 100 条数据的列表完全在可控范围内。还有一个设计习惯虚拟列表要求每个 Item 尺寸一致拖拽排序最好也做等宽等高设计不要做不同高度的卡片混合。等尺寸之后排序判定公式可以简化成“按高度直接算目标索引”几乎不用循环比较中心点。我做某跨平台系统工具栏时把所有 Item 设计成 88px 等高的网格换来的是排序逻辑里index Math.floor(-local.y / 88)一行搞定这种简化非常有价值。如果你硬要做不规则卡片那排序判定就得退回到逐项累计高度代码复杂度会上一个台阶。从那以后我每次接到排列表单里的拖拽排序需求都会先确认三件事列表是不是固定容器、Item 是不是等尺寸、排序结果要不要持久化。这三件事定了方案基本就固定了剩下都是坐标和 Tween 的流水活。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

吉布斯采样实现LDA主题模型:MATLAB代码实战与避坑指南

吉布斯采样实现LDA主题模型:MATLAB代码实战与避坑指南

简介:面向机器学习和自然语言处理方向开发者的开源实现,基于吉布斯采样方法完成LDA主题模型推断,帮助解决高维概率分布采样的核心难题,适用于文本挖掘、主题建模等场景,也适合作为MCMC算法入门的代码范本。资源共15个文…

2026/10/17 4:39:12 阅读更多 →
MES系统如何打通车间现场:从黑盒到透明,制造执行的核心价值解析

MES系统如何打通车间现场:从黑盒到透明,制造执行的核心价值解析

1. 从车间现场的“黑匣子”说起:MES到底在解决什么问题先说一个我在制造业圈子里反复听到的抱怨:很多企业的老板和管理者,花大价钱上了ERP,觉得“系统都有了,管理应该没问题了”,结果到了车间一看&#xff…

2026/10/17 4:39:12 阅读更多 →
Linux最小化系统搭建Firefox与VNC远程桌面完整指南

Linux最小化系统搭建Firefox与VNC远程桌面完整指南

一台用最小化模式装好的 Linux,装完就是纯命令行环境,连图形界面都没有。但很多时候,你又确实需要在这台机器上跑出一个有界面的浏览器——用 Firefox 登录网页后台、远程给同事演示页面效果,或者把一台旧电脑改成专用网页终端。于…

2026/10/17 4:39:12 阅读更多 →

最新新闻

Claude Code模板化实战:把项目约定固化,让AI编程助手真正懂你

Claude Code模板化实战:把项目约定固化,让AI编程助手真正懂你

项目标题往那摆,说白了就是一句话的事儿:Claude Code 的真正效率,不在于你问得多细,而在于你给它的模板有多靠谱。今年 Claude Code 这类命令行 AI 编程工具火了之后,最容易被忽略的就是“模板化”这件事。很多人拿到 …

2026/10/17 5:23:24 阅读更多 →
金智维入选WISE2025商业之王:企业级RPA数字员工如何实现精度与效率双提升

金智维入选WISE2025商业之王:企业级RPA数字员工如何实现精度与效率双提升

金智维入选“WISE2025商业之王”年度企业,这件事在自动化圈子里这几天的讨论度确实不低。很多人问我怎么看,我的标准一直很简单:不只看它拿了什么奖,而是看这个奖背后的评判维度,是不是真的踩中了企业自动化的命门。按…

2026/10/17 5:23:24 阅读更多 →
让Claude Code懂你的项目:CLAUDE.md、斜杠命令与工作流全解析

让Claude Code懂你的项目:CLAUDE.md、斜杠命令与工作流全解析

用过Claude Code的朋友应该都有体会:刚上手那阵子特别爽,随手问一句它就能翻代码、改文件、提提交,感觉像开了挂。但用上一周、两周之后,问题就来了——它总是重复问你已经回答过的问题,总是不按你仓库里的目录习惯找文…

2026/10/17 5:23:24 阅读更多 →
Claude Code模板库实战:打造可复用的AI编程工作流

Claude Code模板库实战:打造可复用的AI编程工作流

一个多月前,我把分散在多个仓库里的 Claude Code 配置、斜杠命令和项目记忆文件整理成了一个 claude-code-templates 模板库。原本只是想解决自己来回复制粘贴的问题,没想到它对团队协作的帮助更大。这篇文章就把这套模板的设计思路、具体内容和落地过程…

2026/10/17 5:23:24 阅读更多 →
分类模型与评估指标实战:从混淆矩阵到阈值选择

分类模型与评估指标实战:从混淆矩阵到阈值选择

做算法这几年,我招过不少人,也带过不少新人。大家第一次接触项目时,问得最多的往往不是某个公式怎么推,而是“这批数据到底能上什么模型”。每次听到这个问题,我都会先把话题引到另一边:你想用它判断什么&a…

2026/10/17 5:23:24 阅读更多 →
Claude Code模板实战:CLAUDE.md、自定义命令与hooks全解析

Claude Code模板实战:CLAUDE.md、自定义命令与hooks全解析

1. 先把这个标题拆明白看到“claude-code-templates”这个项目名,估计大部分人都能猜个大概:这是给Claude Code用的模板集合。但真正用过Claude Code的人会知道,模板这两个字背后藏的东西远比想象中多——它不是简单的几段提示词,…

2026/10/17 5:22:24 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式: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/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/16 14:23:36 阅读更多 →