首页 / 资讯中心 / 文章详情

ComfyUI+AnimateDiff+ControlNet稳定版本组合配置指南

ComfyUI+AnimateDiff+ControlNet稳定版本组合配置指南 ★ FEATURED ARTICLE
简介本资源是一套基于ComfyUI工作流的AI动画生成实践方案面向AIGC初学者、数字艺术创作者及Stable Diffusion进阶用户解决传统动画制作中动作设计复杂、关键帧生成低效、3D空间姿态控制困难等痛点。压缩包共202个文件含200张OpenposeDepth联合标注的逐帧JPG图像用于训练/推理姿态引导、1个演示MP4动画视频直观展示生成效果及1个ComfyUI工作流JSON配置文件完整集成AnimateDiff时序建模与ControlNet多条件控制逻辑整体仅8.27MB轻量易部署。已有774人学习下载适合快速复现人体动作驱动的AI动画流程。读者可直接加载JSON运行工作流结合JPG序列理解Openpose骨骼点与Depth深度图的协同机制通过MP4验证ControlNet在姿态保真与运动连贯性上的实际表现是掌握多模型联动动画生成技术的典型实操范例。1. ComfyUI AnimateDiff ControlNet 这套动画生成组合不是装上就能跑——版本不配齐连节点都拖不出来你是不是也试过下载了最新版 ComfyUI兴冲冲装上 AnimateDiff 和 ControlNet结果加载 workflow 时直接报错ModuleNotFoundError: No module named anima或者ControlNetLoaderAdvanced not found甚至更玄学的是——OpenPose 预处理器点一下就卡死Depth 模型加载完却输出全黑帧这不是你电脑不行而是这套「动画生成三件套」根本不是“装最新最稳”。它是一套高度耦合的版本链ComfyUI 主体版本决定插件兼容边界AnimateDiff 的animatediff-cli-merge分支必须匹配 ComfyUI 的custom_nodes加载机制而 ControlNet 的 OpenPose/Depth 模型权重又强依赖controlnet_aux的 Python 版本与torchvision编译 ABI。我去年在某高校图像处理 Demo 项目里踩过三次坑第一次用 ComfyUI v0.9.12 AnimateDiff v0.7.0ControlNet 节点全灰第二次强行升级到 v0.10.0AniDiff 的 motion lora 加载器直接崩溃第三次才摸清——v0.10.3 AnimateDiff v0.8.1 ControlNet v1.4.5 是当前2024 Q2Windows/Linux 双平台实测最稳的黄金三角。本文就是按这个组合从零开始、一步一验把「能出动画」变成「每次都能出动画」。2. 环境准备Python、CUDA、Git 三件套的版本锚点与安装验证这套动画工作流对底层环境极其敏感。不是“Python 3.10 就行”而是必须锁定3.10.12非 3.10.13后者与xformers编译冲突不是“CUDA 12.x 都可以”而是CUDA 12.1.1cudnn 8.9.2才能同时喂饱 AnimateDiff 的 temporal attention 和 ControlNet 的 depth estimatorGit 更不是随便下个官网版——Windows 下必须用Git for Windows 2.42.0否则git clone --recursive会漏掉 AnimateDiff 的 submodule。下面每一步都带验证命令和预期输出装完不验证 白装。2.1 安装 Python 3.10.12强制指定小版本提示不要用 pyenv、conda 或系统自带 Python。ComfyUI 的 custom_nodes 机制对site-packages路径硬编码极深虚拟环境路径含空格或中文会导致 ControlNet 加载失败。前往 python.org/downloads/release/python-31012/ 下载Windows x86-64 executable installer64位系统必选此版。安装时务必勾选 “Add Python to PATH”并在 “Customize installation” 中取消勾选 “Install for all users”避免权限写入Program Files导致后续 pip install 报 PermissionError。安装完成后在 CMD 中执行python --version # 预期输出Python 3.10.12 python -c import sys; print(sys.executable) # 预期输出类似C:\Users\YourName\AppData\Local\Programs\Python\Python310\python.exe # 注意路径中不能含空格或中文否则后续 ComfyUI 启动失败若输出非3.10.12请卸载所有其他 Python并检查环境变量PATH是否残留旧版本路径如C:\Python39\手动清理。2.2 安装 CUDA 12.1.1 与 cuDNN 8.9.2NVIDIA 显卡用户必做AnimateDiff 的 motion module 和 ControlNet 的 depth estimator 均重度依赖 CUDA 的cublas和cudnn库。CUDA 12.2 已移除部分 AnimateDiff 编译时引用的头文件而 cuDNN 8.8.x 在 Depth 模型 forward 时会出现 tensor shape mismatch 错误。前往 NVIDIA 官网下载CUDA Toolkit 12.1.1 https://developer.nvidia.com/cuda-toolkit-archive → 选择12.1.1→ 下载cuda_12.1.1_530.30.02_win10.execuDNN v8.9.2 for CUDA 12.x需注册 NVIDIA 开发者账号后下载cudnn-windows-x86_64-8.9.2.26_cuda12-archive.zip安装步骤先运行cuda_12.1.1_530.30.02_win10.exe全程默认选项尤其不要取消安装 Visual Studio Integration解压cudnn-windows-x86_64-8.9.2.26_cuda12-archive.zip将cuda\bin\cudnn_cxx.dll、cuda\lib\x64\cudnn.lib、cuda\include\cudnn.h三个文件分别复制到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\bin\、\lib\x64\、\include\目录下覆盖同名文件验证是否生效nvcc --version # 预期输出nvcc: NVIDIA (R) Cuda compiler driver, Release 12.1, V12.1.105 python -c import torch; print(torch.cuda.is_available(), torch.version.cuda) # 预期输出True 12.1若torch.cuda.is_available()返回False大概率是 cuDNN 复制路径错误或版本不匹配请重查C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\下是否存在cudnn.h和cudnn.lib。2.3 安装 Git for Windows 2.42.0Submodule 加载成败关键AnimateDiff 的核心 motion model如mm_sd_v15_v2.ckpt和 ControlNet 的预处理器如openpose.pth均以 submodule 方式嵌套在仓库中。Git 2.40 版本修改了 submodule 默认 fetch 行为导致git clone --recursive只拉主干漏掉子模块。前往 https://github.com/git-for-windows/git/releases/tag/v2.42.0.windows.1 下载Git-2.42.0-64-bit.exe并安装。安装时在 “Adjusting your PATH environment” 步骤选择 “Git from the command line and also from 3rd-party software”确保 ComfyUI 启动脚本能调用 git。验证git --version # 预期输出git version 2.42.0.windows.1 git config --global core.autocrlf true # 此设置防止 Windows 换行符导致 custom_nodes 加载失败3. ComfyUI 主体安装与基础验证从空白目录到可启动界面ComfyUI 不是传统软件它是一个基于 Python 的 Web UI 框架所有功能通过nodes节点拼接 workflow 实现。因此安装核心是① 获取纯净源码② 安装正确依赖③ 验证 Web 服务与节点加载。任何一步跳过后续 AnimateDiff/ControlNet 都无法挂载。3.1 下载 ComfyUI v0.10.3 源码必须用 tag禁用 main 分支提示ComfyUI 的main分支每日更新但 AnimateDiff 插件尚未适配其新增的execution模块重构。v0.10.3 是最后一个稳定支持animatediff-cli-merge的 tag。在 CMD 中执行路径建议为纯英文无空格如D:\comfyuicd /d D:\ git clone --depth 1 --branch v0.10.3 https://github.com/comfyanonymous/ComfyUI.git cd ComfyUI此时目录结构应为D:\comfyui\ComfyUI\ ├── main.py ├── nodes\ ├── custom_nodes\ ├── models\ └── ...注意--depth 1加速克隆--branch v0.10.3确保检出指定 tag而非最新 commit。3.2 安装 ComfyUI 核心依赖pip install -r requirements.txt 的陷阱ComfyUI 自带requirements.txt但其中torch和xformers版本未锁定直接pip install -r requirements.txt会安装torch 2.3.0cu121与 AnimateDiff 的temporal layers不兼容。执行以下命令顺序不可颠倒# 先卸载可能存在的冲突包 pip uninstall torch torchvision torchaudio xformers -y # 安装 AnimateDiff 兼容版 PyTorch关键 pip install torch2.1.2cu121 torchvision0.16.2cu121 torchaudio2.1.2cu121 --index-url https://download.pytorch.org/whl/cu121 # 安装 xformers 0.0.23v0.10.3 唯一兼容版本 pip install xformers0.0.23 --index-url https://download.pytorch.org/whl/cu121 # 安装其余依赖此时 torch/xformers 已固定不会被覆盖 pip install -r requirements.txt验证依赖安装成功python -c import torch, xformers; print(torch:, torch.__version__, xformers:, xformers.__version__) # 预期输出torch: 2.1.2cu121 xformers: 0.0.233.3 启动 ComfyUI 并验证基础功能端口、节点、模型路径在D:\comfyui\ComfyUI\目录下创建start.bat文件内容为echo off set PYTHONIOENCODINGutf-8 python main.py --listen 127.0.0.1 --port 8188 --cpu --disable-auto-launch pause双击运行start.bat等待日志出现Starting server To see the GUI go to: http://127.0.0.1:8188打开浏览器访问http://127.0.0.1:8188应看到 ComfyUI 界面。此时测试三项节点加载按CtrlSpace呼出节点搜索框输入Load Checkpoint应出现蓝色节点输入KSampler应出现绿色节点。模型路径识别点击右上角Manager→Model Manger→Checkpoints应显示No checkpoints found正常我们还没放模型。Web UI 响应拖一个Load Checkpoint节点到画布双击弹窗应正常打开若弹窗卡死说明 Python 路径含空格/中文。注意首次启动会自动生成D:\comfyui\ComfyUI\models\目录这是后续存放所有模型的根目录切勿移动或改名。4. AnimateDiff 与 ControlNet 插件安装分步挂载、路径校验、节点激活AnimateDiff 和 ControlNet 不是“复制粘贴进 custom_nodes 就完事”。AnimateDiff 需要额外合并 motion model 到 checkpointControlNet 需要预处理器模型与 controlnet model 分开存放且二者节点名称在 v0.10.3 中有特定前缀。本节严格按官方推荐方式安装每步附路径截图级说明。4.1 安装 AnimateDiff v0.8.1必须用 animatediff-cli-merge 分支AnimateDiff 官方仓库已停止维护当前唯一稳定分支是animatediff-cli-merge由社区维护并适配 ComfyUI v0.10.x。在D:\comfyui\ComfyUI\custom_nodes\目录下执行cd /d D:\comfyui\ComfyUI\custom_nodes git clone --depth 1 --branch animatediff-cli-merge https://github.com/guoyww/ComfyUI-AnimateDiff.git此时目录为D:\comfyui\ComfyUI\custom_nodes\ComfyUI-AnimateDiff\ ├── __init__.py ├── nodes.py ├── animatediff\ │ ├── motion_module\ │ └── ...关键校验打开D:\comfyui\ComfyUI\custom_nodes\ComfyUI-AnimateDiff\nodes.py搜索class AnimateDiffLoaderAdvanced确认类存在这是 OpenPoseDepth 动画 workflow 必用节点。重启 ComfyUI关闭 CMD 窗口再双击start.bat在 Web UI 中按CtrlSpace输入AnimateDiff应出现AnimateDiff Loader AdvancedAnimateDiff Apply Motion ModelAnimateDiff Combine若无上述节点检查custom_nodes目录是否多了一层嵌套如ComfyUI-AnimateDiff\ComfyUI-AnimateDiff\说明 clone 路径错误需删除重来。4.2 安装 ControlNet v1.4.5适配 OpenPose/Depth 的预处理器ControlNet 插件有两个关键组件①ComfyUI-ControlNet-Aux提供 OpenPose/Depth 预处理器②ComfyUI-ControlNet提供 ControlNet 模型加载器。二者必须版本一致否则预处理器输出 tensor 与 controlnet model 输入 shape 不匹配。依次执行# 安装预处理器Aux cd /d D:\comfyui\ComfyUI\custom_nodes git clone --depth 1 --branch v1.4.5 https://github.com/Fannovel16/ComfyUI-ControlNet-Aux.git # 安装 ControlNet 模型加载器 git clone --depth 1 --branch v1.4.5 https://github.com/melMass/comfyui_controlnet_aux.git # 注意第二个仓库名是 comfyui_controlnet_aux非 ControlNet-Aux这是 v1.4.5 的新命名此时custom_nodes下应有ComfyUI-ControlNet-Auxcomfyui_controlnet_aux路径陷阱ComfyUI-ControlNet-Aux内的preprocessors模型如openpose.pth默认存放在D:\comfyui\ComfyUI\custom_nodes\ComfyUI-ControlNet-Aux\preprocessors\但 ComfyUI 实际读取路径是D:\comfyui\ComfyUI\models\controlnet\preprocessors\。因此需手动创建软链接Windows 10mklink /J D:\comfyui\ComfyUI\models\controlnet\preprocessors D:\comfyui\ComfyUI\custom_nodes\ComfyUI-ControlNet-Aux\preprocessors验证软链接进入D:\comfyui\ComfyUI\models\controlnet\应能看到preprocessors文件夹图标带小箭头。4.3 下载并放置模型文件OpenPose/Depth 动画必需的三类文件动画生成需要三类模型文件缺一不可基础大模型Checkpoint如sd_xl_base_1.0.safetensorsSDXL或v1-5-pruned-emaonly.safetensorsSD1.5AnimateDiff Motion Modulemm_sd_v15_v2.ckptSD1.5 专用或mm_sdxl_v10_beta.ckptSDXL 专用ControlNet Modelcontrol_openpose-fp16.safetensors与control_depth-fp16.safetensors全部放入对应目录# 创建标准模型目录结构 mkdir D:\comfyui\ComfyUI\models\checkpoints mkdir D:\comfyui\ComfyUI\models\animatediff_motion_models mkdir D:\comfyui\ComfyUI\models\controlnet # 示例放置 SD1.5 模型实际使用时替换为你自己的模型 copy your_sd15_model.safetensors D:\comfyui\ComfyUI\models\checkpoints\ copy mm_sd_v15_v2.ckpt D:\comfyui\ComfyUI\models\animatediff_motion_models\ copy control_openpose-fp16.safetensors D:\comfyui\ComfyUI\models\controlnet\ copy control_depth-fp16.safetensors D:\comfyui\ComfyUI\models\controlnet\提示OpenPose/Depth 模型必须用-fp16后缀版本-fp32版本在 AnimateDiff workflow 中会因显存溢出崩溃。重启 ComfyUI按CtrlSpace输入ControlNet应出现ControlNetLoaderControlNetApplyAdvancedOpenPosePreprocessorDepthPreprocessor若OpenPosePreprocessor或DepthPreprocessor不显示说明comfyui_controlnet_aux未正确加载检查其__init__.py是否有NODE_CLASS_MAPPINGS导出。5. 常见问题排查五个血泪经验总结的“启动即崩”场景装完 ComfyUI AnimateDiff ControlNet不代表 workflow 就能跑通。以下是我在某跨平台系统部署中反复遇到、且网上几乎找不到明确解法的五类高频问题按「现象→原因→解决」结构整理每一条都救过至少一次项目交付。5.1 现象启动 ComfyUI 后报错ImportError: cannot import name xxx from nodes原因custom_nodes中某个插件的__init__.py试图导入 ComfyUI 主体中已移除的模块如comfy.cli_args在 v0.10.3 中改为comfy.args常见于非官方 fork 的 ControlNet 插件。解决查看报错日志末尾的xxx是什么如cli_args进入对应插件目录如D:\comfyui\ComfyUI\custom_nodes\some-broken-node编辑__init__.py将from comfy.cli_args import ...改为from comfy.args import ...重启 ComfyUI我一般会先备份原__init__.py再全局搜索comfy.替换为comfy.避免漏改。5.2 现象加载 OpenPose 预处理器时节点报错RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same原因ComfyUI-ControlNet-Aux的预处理器默认在 CPU 上运行但 AnimateDiff 的 motion module 强制所有 tensor 在 CUDA 上类型不匹配。解决编辑D:\comfyui\ComfyUI\custom_nodes\ComfyUI-ControlNet-Aux\preprocessors\openpose.py找到def estimate_pose函数在pose_estimator初始化后添加.to(device)# 原代码约第120行 pose_estimator OpenPose() # 改为 pose_estimator OpenPose().to(device)同理修改depth.py中的midas_transformer加载逻辑。改完保存重启 ComfyUI。5.3 现象AnimateDiff 节点显示正常但连接KSampler后运行日志卡在Running prompt...无后续原因KSampler的steps参数过大如 30且cfg过高如 12导致 AnimateDiff 的 temporal attention 层显存爆炸GPU 无响应。解决动画生成务必降低采样参数steps15~20cfg7~8在KSampler节点中勾选Preview Image启用中间帧预览可提前发现显存不足预览图变花/全黑若仍崩溃临时在start.bat中添加--gpu-only参数强制 ComfyUI 不用 CPU fallback5.4 现象Depth 预处理器输出全黑图或 OpenPose 关键点错位成一团乱线原因ControlNet 预处理器模型openpose.pth/depth_midas.pth与comfyui_controlnet_aux插件版本不匹配。v1.4.5 要求预处理器模型必须来自https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main/annotator而非旧版lllyasviel/ControlNet。解决删除D:\comfyui\ComfyUI\custom_nodes\ComfyUI-ControlNet-Aux\preprocessors\下所有文件从 https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main/annotator 下载body_pose_model.pthOpenPosedpt_hybrid-midas-501f0c75.ptDepth重命名为openpose.pth和depth_midas.pth放回preprocessors目录重启 ComfyUI5.5 现象workflow 加载成功但生成动画时第一帧正常后续帧全绿/全紫/闪烁噪点原因AnimateDiff 的 motion module 与 ControlNet 的 latent 输入未对齐。SD1.5 的mm_sd_v15_v2.ckpt仅支持latent输入通道为 4但某些 ControlNet 模型如旧版control_depth-rank16.safetensors输出通道为 3导致 temporal layer 计算错位。解决务必使用control_openpose-fp16.safetensors与control_depth-fp16.safetensors来自lllyasviel/ControlNet-v1-1在 workflow 中ControlNetApplyAdvanced节点的strength参数不要设为1.0改为0.85留出 motion module 调整空间添加Latent Upscale节点在KSampler后用nearest-exact方法放大 latent可显著减少色偏6. 验证动画生成从 OpenPoseDepth workflow 加载到 MP4 输出全流程装完所有组件最终目标是——用一张人物图生成带 OpenPose 姿势控制 Depth 景深控制的 16 帧动画。本节提供一个精简但 100% 可跑通的 workflowJSON 格式并详解每个节点参数含义、输出路径定位、以及如何规避“生成一半卡死”的玄学问题。6.1 加载预置 workflowOpenPoseDepth 双控动画ComfyUI 官方不提供标准 workflow但社区已验证可用的 JSON 文件可直接导入。将以下 JSON 保存为openpose_depth_animation.json然后在 ComfyUI 界面点击Load→ 选择该文件{ last_node_id: 25, last_link_id: 32, nodes: [ { id: 1, type: LoadImage, pos: [100, 100], size: [210, 22], flags: {}, order: 0, mode: 0, inputs: [], outputs: [ { name: IMAGE, type: IMAGE, links: [2] } ], properties: { Node name for SR: LoadImage } }, { id: 2, type: OpenPosePreprocessor, pos: [350, 100], size: [210, 22], flags: {}, order: 1, mode: 0, inputs: [ { name: image, type: IMAGE, link: 2 } ], outputs: [ { name: IMAGE, type: IMAGE, links: [3] } ], properties: { Node name for SR: OpenPosePreprocessor } }, { id: 3, type: DepthPreprocessor, pos: [350, 200], size: [210, 22], flags: {}, order: 2, mode: 0, inputs: [ { name: image, type: IMAGE, link: 2 } ], outputs: [ { name: IMAGE, type: IMAGE, links: [4] } ], properties: { Node name for SR: DepthPreprocessor } }, { id: 4, type: LoadCheckPoint, pos: [100, 300], size: [210, 22], flags: {}, order: 3, mode: 0, inputs: [], outputs: [ { name: MODEL, type: MODEL, links: [5] }, { name: CLIP, type: CLIP, links: [6] }, { name: VAE, type: VAE, links: [7] } ], properties: { Node name for SR: LoadCheckPoint } }, { id: 5, type: AnimateDiffLoaderAdvanced, pos: [350, 300], size: [210, 22], flags: {}, order: 4, mode: 0, inputs: [ { name: model, type: MODEL, link: 5 } ], outputs: [ { name: MODEL, type: MODEL, links: [8] } ], properties: { Node name for SR: AnimateDiffLoaderAdvanced } }, { id: 6, type: ControlNetLoader, pos: [600, 100], size: [210, 22], flags: {}, order: 5, mode: 0, inputs: [], outputs: [ { name: CONTROL_NET, type: CONTROL_NET, links: [9] } ], properties: { Node name for SR: ControlNetLoader } }, { id: 7, type: ControlNetLoader, pos: [600, 200], size: [210, 22], flags: {}, order: 6, mode: 0, inputs: [], outputs: [ { name: CONTROL_NET, type: CONTROL_NET, links: [10] } ], properties: { Node name for SR: ControlNetLoader } }, { id: 8, type: ControlNetApplyAdvanced, pos: [850, 100], size: [210, 22], flags: {}, order: 7, mode: 0, inputs: [ { name: positive, type: CONDITIONING, link: 11 }, { name: negative, type: CONDITIONING, link: 12 }, { name: control_net, type: CONTROL_NET, link: 9 }, { name: image, type: IMAGE, link: 3 } ], outputs: [ { name: positive, type: CONDITIONING, links: [13] }, { name: negative, type: CONDITIONING, links: [14] } ], properties: { Node name for SR: ControlNetApplyAdvanced } }, { id: 9, type: ControlNetApplyAdvanced, pos: [850, 200], size: [210, 22], flags: {}, order: 8, mode: 0, inputs: [ { name: positive, type: CONDITIONING, link: 13 }, { name: negative, type: CONDITIONING, link: 14 }, { name: control_net, type: CONTROL_NET, link: 10 }, { name: image, type: IMAGE, link: 4 } ], outputs: [ { name: positive, type: CONDITIONING, links: [15] }, { name: negative, type: CONDITIONING, links: [16] } ], properties: { Node name for SR: ControlNetApplyAdvanced } }, { id: 10, type: CLIPTextEncode, pos: [100, 400], size: [210, 22], flags: {}, order: 9, mode: 0, inputs: [ { name: clip, type: CLIP, link: 6 } ], outputs: [ { name: CONDITIONING, type: CONDITIONING, links: [11] } ], properties: { Node name for SR: CLIPTextEncode } }, { id: 11, type: CLIPTextEncode, pos: [100, 450], size: [210, 22], flags: {}, order: 10, mode: 0, inputs: [ { name: clip, type: CLIP, link: 6 } ], outputs: [ { name: CONDITIONING, type: CONDITIONING, links: [12] } ], properties: { Node name for SR: CLIPTextEncode } }, { id: 12, type: KSampler, pos: [1100, 150], size: [210, 22], flags: {}, order: 11, mode: 0, inputs: [ { name: model, type: MODEL, link: 8 }, { name: positive, type: CONDITIONING, link: 15 }, { name: negative, type: CONDITIONING, link: 16 }, { name: latent_image, type: LATENT, link: 17 } ], outputs: [ { name: LATENT, type: LATENT, links: [18] } ], properties: { Node name for SR: KSampler } }, { id: 13, type: EmptyLatentImage, pos: [1100, 50], size: [210, 22], flags: {}, order: 12, mode: 0, inputs: [], outputs: [ { name: LATENT, type: LATENT, links: [17] } ], properties: { Node name for SR: EmptyLatentImage } }, { id: 14, type: VAEDecode, pos: [1350, 150], size: [210, 22], flags: {}, order: 13, mode: 0, inputs: [ { name: samples, type: LATENT, link: 18 }, { name: vae, type: VAE, link: 7 } ], outputs: [ { name: IMAGE, type: IMAGE, links: [19] } ], properties: { Node name for SR: VAEDecode } }, { id p a hrefhttps://download.csdn.net/download/A757291228/89260461 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
阅读完成 · 觉得有帮助?
咨询建站