news 2026/10/1 1:41:44

JumpServer 忘记密码与用户锁定:admin 密码重置和解锁指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JumpServer 忘记密码与用户锁定:admin 密码重置和解锁指南

上周三凌晨两点,值班群里跳出一条消息:JumpServer 登不进去了,admin 账号连续输错五次,页面直接提示账号被锁定,而手上正在处理的故障还等着通过堡垒机连生产库。这种场景我遇到过不止一次,也帮同事救过不止一次场。JumpServer 登录密码忘记和用户锁定这两件事,看着都是"进不去",但底层成因、处理路径、收尾动作完全不同,搞混了就容易越救越乱——比如有人上来就把users_user表里的密码字段改成明文,结果账号彻底废掉,只能重建。

这篇内容面向的是正在用或刚接手 JumpServer 的运维人员,也包括那些把 JumpServer 当部门共享跳板机用的开发者。核心要解决的问题就三个:admin 或普通用户忘记密码怎么救回来、账号被锁定怎么判断是哪种锁、怎么解、解完之后怎么保证不再复发。文中涉及的版本以 JumpServer v2.28 及 v3.x 为主,不同小版本命令位置略有差异,但只要理解了"改密码到底改的是哪一层",任何版本都能自己摸索出来。下面我就按实际操作顺序,把整套流程拆开讲透。

1. 先把"忘记密码"这件事拆开看:帐号体系与锁定机制

很多人一上手就去翻配置文件,这是方向性错误。JumpServer 的账号问题必须先分类,分类错了,后面所有操作都是白费力气。

1.1 三类账号,三条完全不同的救援路径

JumpServer 里的"用户"不是同一种东西,登录入口虽然长得差不多,但背后的认证源完全不一样。

第一类是本地账号,也就是source字段为local的用户,密码哈希直接存在 JumpServer 自己的数据库里。admin 默认就是这类。忘记密码只能靠改库或者进容器改哈希,没有别的路。

第二类是外部认证账号,source可能是ldap、openid、radius等。这类账号在 JumpServer 里根本不存密码,登录时是把凭据转发给外部认证源校验的。你就算把 JumpServer 数据库里的密码字段改成花,也一点用都没有——因为登录时压根不看这个字段。这类账号忘记密码,得去 LDAP/AD 域控那边重置,JumpServer 这边最多只能"清除并重新同步"用户记录。

第三类是系统内置的服务账号,比如 koko、lion、magnus 这些组件连接 core 时用的账号,普通用户看不到。这类账号密码在config.txt里,一般不会有人去记,也不需要记。

我再强调一遍这个判断的重要性:曾经有同事遇到 LDAP 用户登不上,在 JumpServer 数据库里折腾了两个小时,最后发现是域账号被域控锁了。先看source字段,能省掉 90% 的无用功。

1.2 用户被"锁定"到底锁的是什么

"锁定"这个词在 JumpServer 里至少对应四种状态,页面上给用户的提示还都挺含糊,所以必须能区分。

现象提示实际含义触发方式
账号已被锁定 / 尝试次数过多登录失败次数超限,临时锁连续输错密码,达到阈值
用户已被禁用is_active = False管理员手工禁用或同步覆盖
账号已过期date_expired早于当前时间管理员设的到期时间到了
密码已过期密码有效期到了强制改密策略触发

前两种最好区分:一个是"试错太多被系统挡在门外",一个是"人主动把你踢出去了"。后两种属于"伪锁定",用户看到的也是登不上,但处理方式完全不同——账号过期要延长date_expired,密码过期要走一次强制改密流程,这时候你会发现密码本身是对的,但系统就是不让你进。

1.3 救援前的三条自检清单

动手之前,先在脑子里过一遍这三条,能避免绝大部分误操作。

  • 确认自己还有没有别的可用管理员账号。如果有,优先用那个账号从 Web 后台解决,命令行都不用碰,风险最低。
  • 确认 JumpServer 跑在什么形态上。是官方一键脚本装的,还是自己编排的容器,还是极少数情况下的源码部署。路径不同,进容器的方式不同。
  • 确认这次救援窗口期有多长。如果生产故障正等着处理,那就走最快路径:先把 admin 拉回来,收尾工作回头再做。

注意:任何时候都不要直接在数据库里把密码字段更新成明文。Django 的密码字段存的是 PBKDF2 哈希串,格式类似pbkdf2_sha256$390000$随机盐$哈希值。直接写明文进去,登录时会因为格式解析失败而永远认证不通过,比忘记密码还难修。

2. 救援前置准备:搞清楚部署形态和组件布局

这一步很多教程都跳过了,但它直接决定你后面敲的每条命令能不能跑通。

2.1 一键脚本安装与手动编排安装的目录差异

用官方一键安装脚本部署的 JumpServer,默认会在/opt下生成一个带版本号的目录,比如/opt/jumpserver-installer-v3.10.0。这个目录里有jmsctl.sh这个管理脚本,还有config目录存放配置。真正的应用代码和运行环境在 Docker 数据卷里,不直接暴露在宿主机上。

自己用 Compose 编排的,目录结构就因人为异了,可能叫jumpserver、jms、bastion什么都行。判断方法很简单:找config.txt和docker-compose.yml这两个文件在哪,那里就是你的工作目录。

# 快速定位安装目录 find / -name "config.txt" -path "*jumpserver*" 2>/dev/null find / -name "jmsctl.sh" 2>/dev/null

找到之后,先用管理脚本看一眼整体状态,这一步能帮你确认所有组件是不是都活着——有时候"登不上"根本不是密码问题,而是 core 容器挂了。

cd /opt/jumpserver-installer-v3.x.x ./jmsctl.sh status docker ps --format "table {{.Names}}\t{{.Status}}" | grep jms

正常你会看到jms_core、jms_koko、jms_lion、jms_magnus、jms_web、jms_celery、jms_mysql、jms_redis一圈容器都是 Up 状态。少一个,先解决容器问题,别急着改密码。

2.2 找到真正存放用户数据的那套数据库

JumpServer 容器化部署后,MySQL 通常也是容器化的,名字叫jms_mysql。连接信息在config.txt里,关键几项是MYSQL_HOST、MYSQL_PORT、MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD。

grep -i "MYSQL" /opt/jumpserver-installer-v3.x.x/config/config.txt

默认数据库名是jumpserver,用户表是users_user。这里有个坑:如果你早期做过数据迁移,或者用了外部独立 MySQL,那jms_mysql容器可能只是个摆设,真正在用的是外边那台。判断方法是在 JumpServer 里新建一个测试用户,然后去两边数据库分别查一下,看哪个有数据。

2.3 动手前必须做的两件事:备份与快照

改密码本身风险不大,但改错了要能回退。我习惯在动数据库之前先做两件事。

第一件是数据库备份。新版jmsctl.sh一般带backup子命令,可以直接用;老版本或者没有这个命令的,手动 mysqldump 一样靠谱。

# 方式一:使用自带脚本 ./jmsctl.sh backup # 方式二:手动备份(推荐,可控性更强) docker exec jms_mysql sh -c 'exec mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" jumpserver' \ > /root/jumpserver_users_$(date +%F_%H%M).sql # 确认备份文件不是空的 ls -lh /root/jumpserver_users_*.sql

第二件是给虚拟机打快照。如果 JumpServer 跑在虚拟化平台上,一个快照几秒钟的事,出任何意外五分钟回滚。这个习惯我在一次误删用户记录之后彻底养成了——那次没有快照,只能从三天前的全量备份里恢复,丢了两天的操作审计日志,被安全部门追着问了一周。

3. 忘记 admin 密码:从容器内改密到数据库兜底

准备工作做完,进入正题。我把方法按推荐程度排序,优先用第一种。

3.1 方法一:jms_core 容器内用 manage.py 改密

JumpServer 的 core 组件本身就是一个 Django 项目,Django 自带的changepassword管理命令在这里可以直接用。这是最规范的方式,因为它会自动调用set_password(),生成的哈希格式一定正确,也不会碰到其他字段。

# 进入 core 容器 docker exec -it jms_core bash # 切到 Django 项目目录 cd /opt/jumpserver/apps # 执行改密命令,按提示输入两遍新密码 python manage.py changepassword admin

命令执行成功会输出Password changed successfully for user 'admin'。如果提示找不到命令或者报 Django 配置错误,说明你的版本裁剪了这条命令,直接跳到 3.2。

用这种方式改完密码,有一个细节要注意:它不会自动把账号的is_active改回 True。如果 admin 之前被禁用了,改完密码还是登不上,得再补一步。

python manage.py shell
from users.models import User u = User.objects.get(username='admin') u.is_active = True u.save() print('username =', u.username, '| is_active =', u.is_active, '| source =', u.source)

最后那行打印非常关键,它能一次告诉你三件事:账号是否存在、是否启用、认证源是不是本地。如果是ldap,那你得停下来了,改密码这条路走不通。

3.2 方法二:直接操作数据库重置密码

容器进不去、manage.py 也跑不起来的情况下,就得直接从数据库层面动手。核心难点在于生成一个格式正确的密码哈希。

最稳的办法是借 Django 自己的工具生成,而不是自己拼字符串。

docker exec -it jms_core bash cd /opt/jumpserver/apps python manage.py shell
from django.contrib.auth.hashers import make_password print(make_password('YourNewPass@2024'))

把这行输出复制出来,然后进数据库更新。

docker exec -it jms_mysql bash mysql -uroot -p jumpserver
-- 先看现状,别急着改 SELECT id, username, name, is_active, source, date_expired FROM users_user WHERE username = 'admin'; -- 更新密码哈希 UPDATE users_user SET password = 'pbkdf2_sha256$390000$xxxxx$yyyyy' WHERE username = 'admin';

改完记得刷新一下权限缓存,不然 JumpServer 可能有短时间的认证不一致。

cd /opt/jumpserver-installer-v3.x.x ./jmsctl.sh restart

注意:make_password每次生成的盐都不一样,所以同一个人执行两次得到的字符串不同,这是正常的。不要去网上找"固定哈希"直接粘贴,那样等于把密码公开了。

3.3 改完密码必须做的收尾动作

密码改回来能登录,很多人就以为完事了。实际上还有几步不收尾,安全上会留隐患。

第一,清理已有的登录会话。如果这次改密是因为怀疑账号被盗用,那旧的会话可能还活着。JumpServer 的在线会话和登录令牌存在 Redis 里,最直接的处理方式是重启 core 和 koko,把所有会话断掉。

docker restart jms_core jms_koko jms_lion

第二,检查近期登录日志。JumpServer 有登录日志和操作日志,Web 后台"审计台"里能看。重点看改密之前的 24 小时内,有没有来自陌生 IP 的成功登录记录。

第三,检查是否有异常用户被创建。入侵者习惯性动作是给自己留后门账号。一条 SQL 就能扫出来。

SELECT id, username, name, is_active, source, date_joined FROM users_user WHERE date_joined > DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY date_joined DESC;

3.4 验证清单与常见报错对照

改完密码之后,别急着重启所有服务,先按下面这个顺序验证,哪一步失败就说明对应环节有问题。

验证动作预期结果失败含义
Web 登录页输入新密码成功进入哈希格式或缓存问题
User.objects.get查询返回对象,is_active=True账号被禁用或不存在
登录后查看个人信息能正常显示会话和权限缓存正常
SSH 通过 koko 连接资产能拉取到资产列表koko 与 core 通信正常

常见的报错里,Invalid password format or unknown hashing algorithm基本可以确定是密码字段被写成了明文或者哈希串残缺。Unable to log in at server. Probably wrong configuration这类通常是 Redis 或数据库连接问题,跟密码本身无关。还有一种很迷惑的情况:新密码能登录 Web,但通过 koko SSH 连接资产时仍然认证失败——这通常是 koko 缓存了旧的认证结果,重启 koko 容器即可。

4. 用户被锁定:判定、解锁与策略调整

密码对不对是一回事,账号能不能用是另一回事。锁定问题比密码问题更绕,因为提示信息往往不够精确。

4.1 先分清是哪种"锁定"

我的排查习惯是从三个地方交叉判断。

Web 登录页的红色提示是最直接的线索。"尝试次数过多"和"用户已被禁用"是两个完全不同的分支,前者等一会儿或者解锁就行,后者得去改is_active。

数据库查询是最权威的。一条 SQL 把所有关键状态一次性拉出来。

SELECT id, username, is_active, source, date_expired, last_login, date_joined FROM users_user WHERE username = 'zhangsan';

重点看is_active和date_expired。is_active = 0表示被禁用;date_expired比当前时间早表示账号已过期,这两个都是"看起来像密码错,其实是状态问题"的典型。

如果用户走的是外部认证源,那还得去认证源那边看一眼。LDAP 域账号有自己的锁定策略,通常是连续输错 N 次锁 30 分钟。这种情况下 JumpServer 什么都做不了,等时间过去或者在域控上解锁。

4.2 管理后台解锁的标准操作

还有一个可用的管理员账号的话,走后台是最省事的。

登录后进入"用户管理 - 用户列表",找到目标用户,点进详情页。页面上能看到账号状态、认证源、MFA 状态、到期时间。要解锁的话,具体动作取决于锁的类型:被禁用的把"启用"开关打开;过期的把到期时间往后调;MFA 丢失的点"重置 MFA",用户下次登录会重新走绑定流程。

这里有个细节值得说一下:重置 MFA 之后,用户原本绑定的动态令牌会立即失效。如果这个用户同时开着多台设备的令牌,需要提前通知他重新绑定,不然会以为又出问题了。

4.3 通过数据库层面的强制解锁

后台进不去、又急着恢复某个用户的情况下,可以从数据库直接改状态。但要注意一点:只改状态类字段,不要碰密码字段。

-- 启用账号 UPDATE users_user SET is_active = 1 WHERE username = 'zhangsan'; -- 解除账号过期 UPDATE users_user SET date_expired = DATE_ADD(NOW(), INTERVAL 90 DAY) WHERE username = 'zhangsan';

至于登录失败次数导致的临时锁定,JumpServer 不同版本的实现方式不一样。有的版本把失败计数放在 Redis 里,有的版本通过数据库表记录。最稳妥的做法是先找出它到底用的哪套机制。

# 在配置里找登录限制相关配置 grep -in "lock\|limit\|attempt" /opt/jumpserver-installer-v3.x.x/config/config.txt

如果确实找不到明确的表名,重置 Redis 里的相关键是最快的通用办法。Redis 里存的登录状态本身就是易失数据,清掉不影响业务数据。

docker exec -it jms_redis redis-cli -a <redis密码> --scan --pattern "*login*"

注意:清 Redis 只解决临时锁定,如果账号本身是被禁用的,清多少次都没用。状态类问题必须落到users_user表上解决。

4.4 MFA 丢失、密码过期、账号到期这三类"伪锁定"

这三种情况用户描述起来都是"密码没错但进不去",值得单独拎出来讲。

MFA 丢失最麻烦。用户手机换了、验证器卸载了,动态码就没了。管理员在后台用户详情里重置 MFA 之后,用户需要重新扫码绑定。如果后台也进不去,命令行同样能清。

from users.models import User u = User.objects.get(username='zhangsan') u.otp_secret_key = '' u.mfa_level = 0 u.save()

字段名在不同版本略有差异,拿不准的时候先dir(u)看一眼,把和mfa、otp相关的属性列出来,比猜省事。

密码过期和账号到期则是策略问题。JumpServer 支持设置密码有效期和账号有效期,很多单位为了合规要求,会强制 90 天改一次密码。这类"锁定"的正规解法是走强制改密流程,而不是去数据库里延长有效期——后者会让合规检查出问题。

4.5 调整登录失败策略:要不要关,关到什么程度

有些团队为了少点麻烦,想把登录失败锁定直接关掉。我的建议是别一刀切,而是分层处理。

原因是这样:登录失败锁定本身是很重要的防护。堡垒机是所有资产的总入口,如果允许无限次尝试密码,暴力破解的风险会显著上升。真正合理的做法是调阈值而不是关功能——比如把连续失败次数从 5 次放宽到 10 次,锁定时长从永久改成 15 分钟。

配置的修改入口有两个:Web 后台的系统设置里可能有安全相关选项,这个最直观;配置文件里则通常在config.txt中有对应开关。改完之后必须重启 core 才生效。

vim /opt/jumpserver-installer-v3.x.x/config/config.txt ./jmsctl.sh restart

重启前先记下改了哪几项,重启后去后台验证一遍配置是否真的加载进去了。经常有人改了文件忘记重启,然后困惑"为什么改了没用"。

5. 宿主机与关联系统:别忘了外层也有一把锁

JumpServer 是跑在 Linux 上的,很多时候"JumpServer 登不上"只是表象,真正的问题在下面一层。

5.1 Linux 宿主机 root 密码忘记怎么救

要进容器改 JumpServer 的密码,前提是你能登录宿主机。如果宿主机的 root 密码也忘了,那就得走单用户模式。这个过程跟发行版有关,但思路一致:在 GRUB 启动菜单里中断启动流程,把内核参数改成单用户模式进入,然后重置密码。

大致流程是在 GRUB 界面按e编辑启动项,在内核行末尾加上单用户相关参数,按Ctrl+X启动,进入后重新挂载根文件系统为可写,用passwd改密,再恢复 SELinux 上下文并重启。

这里我要提醒一句:不同发行版的参数名不一样,操作前一定要查清楚自己那套系统的做法。改错了内核参数会导致系统起不来,比忘记密码严重得多。而且生产环境做这个操作之前,务必确认有备份或者快照,我见过因为单用户模式操作失误导致 SELinux 标签错乱、系统无法启动的案例,恢复过程花了大半天。

5.2 国产化环境下的用户锁定处理思路

现在不少单位的堡垒机部署在国产化操作系统上,统信 UOS 或者麒麟。这两类系统对用户锁定的处理跟通用 Linux 类似,都是通过 PAM 模块记录失败次数。

排查的第一步是看日志,/var/log/secure或者/var/log/auth.log里会记录失败尝试和被锁定的信息。确认是 PAM 层面的锁定之后,用对应的工具解锁。

# 较新的系统使用 faillock faillock --user someuser --reset # 老一些的系统可能还在用 pam_tally2 pam_tally2 --user someuser --reset

哪个命令能用,试一下就知道了。如果两个都提示命令不存在,去看/etc/pam.d/system-auth或者/etc/pam.d/password-auth里引用了哪个模块,那里会写清楚。解锁之后建议顺手把锁定策略调宽松一点,国产化环境里经常出现管理员在运维终端上反复输错密码被锁的情况,阈值太严会严重影响日常操作。

5.3 Windows 端修改密码提示需要介质是怎么回事

这个提示在接入域环境或者有安全策略的 Windows 上很常见,用户改密码时系统弹出"此功能需要智能卡或其他移动介质"。这不是故障,而是策略要求——单位的安全基线里配置了"智能卡登录"或者"交互式登录需要特定凭据",所以改密码也得插入对应的介质。

处理方式取决于你的权限。如果是终端用户,只能联系域管理员,让对方在域控上直接重置密码,重置之后首次登录会走强制改密流程。如果是管理员,可以在组策略里检查交互式登录相关设置,确认是不是策略本身配得太严。但这类策略通常来自上级安全要求,不建议自己偷偷放宽,改之前得走变更流程。

这个场景和 JumpServer 的关系在于:很多团队的 Windows 资产是挂在 JumpServer 上管理的,用户登录 JumpServer 之后通过 RDP 连过去。如果 Windows 端的改密策略导致用户没法自助改密,就会有人转向找 JumpServer 管理员帮忙,无形中增加了堡垒机管理员的工作量。把这条链路提前梳理清楚,能省掉不少沟通成本。

6. 常见问题速查表与踩坑记录

前面讲的是方法论,这一节把零散的经验集中起来,方便出问题时快速翻阅。

6.1 现象-原因-处理速查表

现象最可能的原因处理动作
admin 登录提示密码错误密码遗忘或已被篡改容器内changepassword重置
提示账号被锁定登录失败次数超限等待自动解锁或清 Redis 相关键
提示用户已被禁用is_active = 0后台启用或 SQL 更新
密码正确但登不上账号或密码已过期调整date_expired或走改密流程
改完密码依然登不上认证源非本地检查source字段
koko SSH 连接认证失败koko 缓存旧认证结果重启jms_koko
后台看不到用户用户被过滤或已删除去掉筛选条件,查数据库确认
数据库里改了密码无效写入了明文哈希用make_password重新生成
用户 MFA 丢失换了设备或卸载验证器后台重置 MFA 或清otp_secret_key
通过 DBeaver 连数据库资产失败堡垒机侧账号被锁按上述流程解锁后重连

6.2 我踩过的几个坑

说几个印象深刻的。

第一个坑是改完密码忘记重启。JumpServer 有缓存机制,改完数据库之后直接去登录,有时候能成有时候不能成,很不稳定。后来我固定动作:改完必重启 core。慢是慢几十秒,但能保证结果一致。

第二个坑是误以为所有用户都在本地。早期接手一套环境的时候,同事说某个账号密码忘了让我帮改,我改完数据库他还是登不上。查了半天发现source是openid,密码根本不归 JumpServer 管,白忙活一场。从那以后我形成了一个条件反射:动任何用户之前,先看source。

第三个坑是备份文件没验证。有一次备份命令执行成功,但后来真要恢复的时候发现文件只有几 KB,是个空文件。原因是 mysqldump 那一步容器内的环境变量没取到值,命令静默失败了。现在我的习惯是备份完立刻ls -lh看大小,并且拿head看一眼开头几行是不是正常的 SQL 语句。

第四个坑是清 Redis 清过头。有一次为了解锁一个用户,直接用FLUSHALL把整个 Redis 清空了。用户的密码问题是解决了,但所有在线会话全部断开,正在通过堡垒机操作生产环境的三个人当场掉线,其中一个正在改配置文件。这个教训让我之后所有清 Redis 的操作都严格限定 key 模式。

6.3 长效治理:让"忘记密码"这件事不再发生

救火只是应急,真正省心的是把火源掐掉。

我一般会推动团队做这几件事。给每个管理员配置独立的账号,不要多人共用一个 admin,这样出问题时能定位到人,也不用因为一个人离职就全员改密码。启用 MFA 但保留备用恢复方式,比如同时绑定验证器和备用邮箱,避免单点失效。把账号到期时间统一管理,提前一两周做提醒,而不是等到期当天才发现登不上。定期导出用户清单做核对,重点看有没有长期未登录却能保持启用状态的账号,这类账号是主要的风险敞口。

还有一条容易被忽略:把救援流程本身文档化。不是写给自己看,而是写到"半夜三点被叫醒、脑子不清楚的同事也能照着做"的程度。上面那些命令、路径、备份步骤,全部写进去,附上自己环境里的实际路径和容器名。我现在手上这套文档已经更新到第七版了,每次踩坑都往里补一条。事实证明,这份文档的价值比我写的任何一篇技术文章都高——因为它在最需要的时候真的能被人用上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 1:41:11

远程糖尿病随访系统:Java后端与大数据分析源码实战

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

作者头像 李华
网站建设 2026/10/1 1:40:39

Hermes v0.16.0 桌面版重构:一周百 PR 的架构迁移与 IPC 协议设计

1. 一周百 PR 背后的工程逻辑&#xff1a;Hermes v0.16.0 桌面版到底在做什么第一次看到 Hermes v0.16.0 这个版本号的时候&#xff0c;我下意识以为又是一次常规的小版本迭代——毕竟从 v0.15 到 v0.16&#xff0c;按语义化版本的习惯&#xff0c;顶多就是加几个 API、修几个 …

作者头像 李华
网站建设 2026/10/1 1:39:15

用开源AI接管Unity命令行:脚本生成与批处理自动化实战

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

作者头像 李华
网站建设 2026/10/1 1:39:07

Word论文页眉页码设置详解:分节符与域的使用技巧

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

作者头像 李华
网站建设 2026/10/1 1:39:07

约束规划入门:值域、变量、约束与传播器四要素解析

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

作者头像 李华
网站建设 2026/10/1 1:39:06

STM32+FPGA工业控制器存储选型:EEPROM/NOR/SD分级策略

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

作者头像 李华