移除自己的系统管理员角色后恢复访问权限

如果你从自己的用户账号中移除了系统管理员角色,或者移除了所有角色,你就会失去对用户、角色以及所有需要系统管理员权限的页面的访问权。大多数情况下,你可以自己恢复访问权限,不需要提交工单。

为什么会发生这种情况

Frappe 会在每个页面上检查你的角色。像用户列表、角色和角色权限管理器这样的页面,只有拥有系统管理员角色的用户才能看到。如果你编辑自己的用户记录并取消勾选系统管理员,或者取消勾选所有角色,那么你接下来打开的页面就是你已经无法看到的页面了。Frappe 不会在你保存一个会把自己锁在外面的更改之前提醒你。

例如,Bluepeak Technologies 的 Ayesha Khan 打开了自己的用户记录,想清理掉一些不再需要的角色,结果把系统管理员也一起取消勾选了。

roles-tab-uncheck-system-manager.png

在 dev16.localhost 上实时截取:Ayesha Khan 的用户表单的角色与权限选项卡,角色列表底部的系统管理员复选框已被清除,表单显示“未保存”。已端到端验证:取消勾选此框并保存会重现锁定问题,该账号的用户列表从 16 行降到 0 行。

她保存后,设置工作区从她的侧边栏消失了。如果她直接打开用户列表,列表加载出来没有任何行。如果她打开一个需要系统管理员权限的页面,比如角色权限管理器,她会看到:

错误

Not permitted to view Role Permission Manager

Administrator 用户是唯一的例外:无论“拥有角色”表中显示什么角色,Frappe 始终授予它所有权限。下面的每个选项都直接或间接地利用这一点来恢复你的访问权限。

自己修复

使用下面第一个适用于你的选项。

另一个用户仍然拥有系统管理员角色

请该用户执行以下操作:

  1. 前往用户列表并打开你的用户记录。
  2. 打开角色与权限选项卡。
  3. 勾选系统管理员。
  4. 点击保存。

注销后重新登录以应用更改。

从 bench 控制台重新添加角色

终端

bench --site yoursite.com console

在 In [1]: 提示符下,运行:

Python

user = frappe.get_doc("User", "your-email@example.com")
user.add_roles("System Manager")

从站点注销并重新登录。

如果你不想动自己的用户记录,也可以改为从命令行创建一个临时的第二个系统管理员用户,然后用它通过界面修复你的主账号:

终端

bench --site yoursite.com add-system-manager temp-admin@example.com \
  --first-name Temp --password "a-strong-password"

通过 SSH 进入 bench 组

SSH 访问需要先创建一个私有的 bench 组并添加你的 SSH 密钥。参见 SSH 访问。一旦你能通过 SSH 登录,运行与选项 2 中相同的 bench --site yoursite.com console 命令和 user.add_roles("System Manager"),然后从你的站点注销并重新登录。

使用数据库访问

前往站点仪表盘 → 操作 → 访问站点数据库,如果你之前没用过,点击启用访问。使用显示的凭据通过 MariaDB 命令行客户端连接,然后运行:

SQL

INSERT INTO `tabHas Role`
  (name, creation, modified, modified_by, owner, docstatus,
   idx, parent, parentfield, parenttype, role)
VALUES
  (UUID(), NOW(), NOW(), 'Administrator', 'Administrator', 0,
   1, 'your-email@example.com', 'roles', 'User', 'System Manager');

通过这种方式所做的更改会跳过 Frappe 的正常保存步骤,因此对已经打开的会话不会生效。从你的站点注销并重新登录,角色才会生效。(已验证:直接在数据库中添加的角色只有在重新登录后才会出现——在那之前,正在运行的会话会一直保留旧的角色列表。)

重置 Administrator 密码

这在自托管环境中有效,或者在 Frappe Cloud 上,只要你像选项 2 或 3 那样拥有控制台或 SSH 访问权限也有效:

终端

bench --site yoursite.com set-admin-password "a-strong-new-password"

使用用户名 Administrator 和你刚设置的密码登录。Administrator 始终拥有完全访问权限,所以你现在可以打开自己的用户记录,并通过正常的角色与权限选项卡重新勾选系统管理员。

user-list-access-restored.png

在 dev16.localhost 上实时截取:Ayesha Khan 账号的系统管理员角色恢复后、她重新登录时的用户列表——列表再次显示全部 16 个用户(锁定期间为 0),右上角的+ 添加按钮也回来了。

如果这些都不适用于你

如果你的站点在共享的 Frappe Cloud bench 上,你没有数据库访问权限、没有其他系统管理员用户,也没有保存的 Administrator 密码,请在 support.frappe.io 上提交工单。支持人员会要求你从 Frappe Cloud 仪表盘(侧边菜单中的访问请求)批准一个站点访问请求,然后他们才能恢复你的角色。

如何预防

  • 在每个站点上保留第二个拥有系统管理员角色的用户,作为常备的备用管理员。如果你把一个账号锁在外面,你可以在不到一分钟内从另一个账号修复它。
  • 在从您自己的用户中移除角色之前,请检查它是否是最后一个系统管理员账户。
  • 创建站点时,请将管理员密码保存在安全的地方。即使其他所有系统管理员账户都不在了,它也是您的备用方案。
  • 用户和权限
  • 权限类型
  • SSH 访问
  • 数据库访问

S3文件存储

我可以把文件存到 S3、GCS 或 Google Drive,而不是服务器上吗?

不能直接这样做。Frappe 没有内置的设置可以把新上传的附件发送到
Amazon S3、Google Cloud Storage (GCS) 或 Google Drive。用户通过附件对话框上传的每个文件
都会保存到站点的本地文件存储中,而不是外部对象存储。

提出这个问题最多的,通常是附件增长很快的团队,比如扫描的收据、客户上传的视频或产品图片,
他们希望在站点磁盘空间用完之前把这些文件转移出去。

为什么没有这个功能

Frappe 的文件存储出于速度和简洁性的考虑,设计上就是直接写入本地磁盘。要把新上传的文件
发送到外部对象存储,需要改变 Frappe 读写文件的方式,而不仅仅是一个设置,所以目前没有
受支持的方法来实现这一点。

Frappe Framework 中的 Google Drive 集成经常被误认为是这个功能。其实不是一回事:
它只能让你浏览自己的 Google Drive,并为那里已经存在的文件附加一个链接。
它不会改变用户新上传文件的存储位置,也不会把站点已有的文件移到 Drive 中。

最接近的办法

如果文件已经存在于 Frappe 之外

如果文件已经托管在 S3、GCS、Google Drive 或任何其他服务上,可以附加一个链接,
而不是上传一份副本:

  1. 打开文档,在侧边栏中进入 附件。
  2. 点击 +,然后选择 链接。
  3. 把文件的 URL 粘贴到 附加网页链接 中,然后点击 上传。

Frappe 存储的是链接而不是文件,所以这个附件不占用站点的任何存储空间。

如果你希望新上传的文件自动存到 S3

有一个社区维护的应用市场应用 Frappe S3 Attachment,可以把新上传的文件重定向到 S3
存储桶。它不是由 Frappe 开发或维护的:

  • Frappe 支持团队无法排查该应用中的问题,也无法保证它能与你的站点版本兼容。
    安装前请查看该应用自己的页面,了解它目前支持哪些 Frappe 版本。
  • 它是针对 AWS S3 开发和测试的。像 Oracle Object Storage 或 MinIO 这样的 S3 兼容服务商
    可能可以用相同的存储桶名称、访问密钥、密钥、区域和自定义端点 URL 来运行,
    但这并未得到确认,出现的任何问题都需要你自己解决。

这个变通方法的局限

  • 两种方案都不能自动生成文件夹结构,比如按文档类型、客户或日期分类。
    这需要通过 Frappe 合作伙伴或你自己的团队进行定制开发。
  • 网页链接方案只适用于你已经托管在别处的文件。它不会减少已经上传到 Frappe 的文件
    所占用的空间。
  • 如果团队很在意把文件存储从服务器上移走,可以在 GitHub 上提交功能请求,
    或者在社区论坛中询问是否已有其他开发者构建了可以复用的东西。
  • 附件
  • Google Drive
  • 将备份上传到 Amazon S3

从工作区或侧边栏移除不用的链接

你可以移除用户不需要的 DocType 链接,比如 Buying 中的 Material Request。你可以在设置里完成这个操作,不需要修改任何代码。

开始之前

  • 你需要 Workspace Manager 角色才能为所有用户修改工作区或侧边栏。System Manager 角色不包含这个权限。请在 User → Roles 下添加它。
  • 以下步骤适用于 Frappe v16。

一个 DocType 链接可以在模块中的两个地方显示:

  • 左侧边栏。 它是一个独立的记录,名为 Workspace Sidebar。每个模块都有一个,比如 Buying。
  • 工作区上的卡片。 这是模块的主页面,比如 Reports & Masters 下的 Buying 卡片。

每个地方都有自己的链接列表。如果你从一个地方移除了链接,它还会保留在另一个地方。要彻底移除它,需要按照两组步骤都操作一遍。

移除链接只是把它隐藏起来,并不会删除 DocType、它的记录或用户权限。用户仍然可以通过搜索栏或 URL 打开列表。如果要阻止用户打开它,请参阅“仅对部分用户隐藏”。

观看操作步骤:

  1. 打开模块,比如 Buying。
  2. 在右上角点击 ···,然后点击 Edit。工作区会进入编辑模式。
  3. 指向包含该链接的卡片,比如 Buying。点击卡片上的铅笔图标。Edit Links 对话框会打开。
  4. 在 Card Links 下,点击该链接所在行的铅笔图标,比如 Material Request。Editing Row 对话框会打开。
  5. 点击 Delete。该行会从 Card Links 中移除。
  6. 用保存按钮关闭 Edit Links 对话框。
  7. 在右上角点击 Save。

卡片上不再显示该链接。

  • Workspace
  • Users and permissions

原始打印和网络打印

大多数打印都会经过浏览器的打印对话框。还有两种方式可以跳过它:

  • 网络打印通过打印服务器(CUPS)将 PDF 直接发送到网络上的打印机。
  • 原始打印通过用户电脑上的 QZ Tray 向热敏打印机和标签打印机发送 ESC/POS 命令。

适用于 Frappe v16 及更高版本。

网络打印

开始之前

  • 一个 Frappe 服务器可以访问的 CUPS 打印服务器。
  • Frappe 服务器上的 pycups Python 包和 CUPS 系统库。使用系统的包管理器安装该库,然后在 bench 目录下运行 bench pip install pycups。

设置步骤

  1. 在打印设置中,开启启用打印服务器。
  2. 打开网络打印机设置列表,添加一台打印机,填写服务器的服务器 IP、端口和打印机名称。
  3. 在打印页面上,打开⋯ > 选择网络打印机并选择它。

现在点击打印会按照你选择的格式和样式将文档发送到该打印机。

原始打印

开始之前

  • 在每台需要打印的电脑上安装 QZ Tray。
  • 一个勾选了自定义格式和原始打印的打印格式,并在原始命令中填写打印机命令。你可以在命令中使用 Jinja。

设置步骤

  1. 在打印设置中,开启启用原始打印。
  2. 在打印页面上,选择原始格式。
  3. 打开⋯ > 原始打印设置,将该格式映射到 QZ Tray 找到的打印机。
  4. 点击打印。

原始格式的打印页面不会显示预览。

  • 打印设置
  • 打印文档

PDF生成

Frappe 使用三种引擎之一将打印格式转换为 PDF。

适用于 Frappe v16 及更高版本。

引擎 用途 说明
Chromium 在编辑器中创建的格式(默认)、标准格式,以及当打印设置中指定为 chrome 时的 HTML 格式 能正确渲染现代 HTML 和 CSS。首次需要时会自动下载到 bench 的 chromium 文件夹中,也可以提前通过 bench setup-chrome 下载。
Typst 在编辑器中创建的格式,且 PDF 渲染器 设置为 Typst(快速) 实验性功能。速度更快,适合批量打印。仅支持部分功能。
wkhtmltopdf 当打印设置中指定为 wkhtmltopdf 时的 HTML 格式 已不再维护。无法渲染多列或 flexbox 布局。仅为兼容旧版 HTML 格式而保留。

注意:wkhtmltopdf 在版本 17 中已被移除。所有 PDF 均由 Chromium 生成,设置为 wkhtmltopdf 的格式在迁移时会自动切换为 Chromium。

哪种引擎负责打印格式

  1. 在编辑器中创建的格式使用其自身的 PDF 渲染器 设置:Chromium 或 Typst。
  2. 其他格式如果设置了自身的 PDF 生成器,则使用该设置。
  3. 否则,使用打印设置中的 PDF 生成器。

Typst 无法打印的内容

在你选择 Typst 之前,编辑器会检查格式,并列出所有阻碍项:

  • 自定义 HTML 块和字段模板;
  • 格式或字段上的自定义 CSS,且使用了 Typst 无法转换的属性;
  • 除二维码以外的条形码;
  • 从网址加载的图片;
  • 非十六进制颜色值;
  • 带有自定义 CSS、HTML 或网络图片的信头。

如果使用 Typst 的格式之后出现了上述任一情况,打印会失败并给出明确的错误提示,而不会静默切换引擎。

故障排查

问题 需要检查的内容
PDF 中列堆叠在一起 该格式是用 wkhtmltopdf 打印的。请在打印设置中将 PDF 生成器 设为 chrome。
第一个 PDF 耗时很长 正在下载 Chromium。之后的 PDF 会很快。
在没有网络的服务器上 PDF 生成失败 无法下载 Chromium。请在有网络的地方运行 bench setup-chrome,或在 common_site_config.json 中将 chromium_path 设置为已安装的 Chromium。
PDF 中字体看起来不一样 在格式的 字体 中使用 Google Font 名称,以便 PDF 引擎能够加载它。
  • 打印格式编辑器
  • 打印设置

HTML打印格式

HTML 打印格式是通过 HTML 和 Jinja 手工编写的。当打印格式编辑器无法生成你需要的布局时,就可以使用它。对于大多数格式来说,用编辑器更快,也更容易维护。

适用于 Frappe v16 及更高版本。

开始之前

你需要:

  • 创建打印格式的权限;
  • 熟练使用 HTML、CSS 和 Jinja 模板。

创建 HTML 格式

  1. 打开打印格式列表,点击添加打印格式。
  2. 选择文档类型并输入名称。
  3. 将起始方式设为HTML,然后点击创建。
  4. 在 HTML 中编写模板并保存。

如果你想随应用一起发布某个格式,请开启开发者模式并勾选标准。这样该格式就会作为文件保存在应用中,并由 git 跟踪。

编写模板

文档可通过 doc 获取:

<h2>{{ doc.select_print_heading or _("Sales Invoice") }}</h2>
<p>{{ doc.customer_name }}</p>

<table class="table table-bordered">

<tr><th>{{ _("Item") }}</th>
<th class="text-right">{{ _("Amount") }}</th></tr>
    {% for row in doc.items %}

<tr>

<td>{{ row.item_name }}</td>
        <td class="text-right">{{ row.get_formatted("amount", doc) }}</td>
    </tr>
    {% endfor %}
</table>
  • _("text") 将文本翻译为打印语言。
  • doc.get_formatted("fieldname") 按照表单显示的方式格式化值,包括货币和日期格式。
  • frappe.get_doc、frappe.db.get_value 以及其他辅助函数均可使用。请参阅 Jinja API。
  • 在该格式的自定义 CSS字段中添加样式。

脚本报表和查询报表可以有自己的打印格式,使用 JavaScript 模板编写。请参阅报表的打印格式。

PDF 引擎

HTML 格式使用打印设置中设置的PDF 生成器。wkhtmltopdf 无法排版 flexbox 等现代 CSS,而且已不再维护,因此除非某个格式依赖 wkhtmltopdf,否则请使用 chrome。

  • Jinja API
  • 从其他文档获取信息
  • PDF 生成

打印标题

打印标题用于更改文档上打印的标题。例如,报价单可以打印为“提案”,或者销售发票可以打印为“形式发票”。

适用于 Frappe v16 及更高版本。

创建打印标题

  1. 打开打印标题列表,然后点击添加打印标题。
  2. 在打印标题中输入标题,例如“形式发票”。
  3. 保存。

使用它

支持该功能的文档都有一个打印标题字段,通常位于表单的打印设置部分。在那里选择标题并保存。打印输出将显示该标题,而不是文档类型的名称。

该字段会列出站点上的所有打印标题,涵盖所有文档类型。请为标题取清晰的名称,并删除没人使用的标题,以保持列表简短。

如果只想为某一次打印使用某个标题,而不更改文档,请改用 HTML 打印格式,或在编辑器中用文本块创建的格式。

信头

信头是贵公司的页眉和页脚,打印时会出现在打印稿的顶部和底部。当打印设置中开启重复页眉和页脚时,它会在每一页上重复出现。

适用于 Frappe v16 及更高版本。

创建信头

  1. 打开信头列表,点击添加信头。
  2. 输入信头名称。
  3. 设置信头基于:
    • 图片:上传页眉图片,并设置其高度、宽度和对齐方式。这是最简单的方式,适合放置徽标或设计好的横幅。
    • HTML:用 HTML 编写页眉。你可以使用 Jinja,例如 {{ doc.company }}。
  4. 在页脚基于下用同样的方式设置页脚。
  5. 勾选默认信头,以便在未选择其他信头时使用它。
  6. 保存。

信头会原样打印你放入的内容,因此在将其设为默认之前,请检查地址、电子邮件和电话号码。

对于文档,请将信头用于保持为文档类型。如果信头用于报表打印,请选择报表。

使用信头

  • 在打印页面上,在信头中选择它。留空则不使用信头打印。
  • 在打印格式编辑器中,在页面设置中设置信头,以便将其与格式一起保存。点击页面上的信头可更改其图片、对齐方式或大小。
  • 带有自己的信头字段的文档会使用该信头。

只有当打印设置中开启重复页眉和页脚时,页眉和页脚才会在每一页上重复出现。关闭时,页脚只会在末尾打印一次,并且打印页面会在信头旁边显示警告。

提示

  • 使用至少为实际打印尺寸两倍的图片,以保持清晰。
  • 在格式的上边距中为页眉留出空间。
  • 带有自定义 CSS 的 HTML 信头无法使用 Typst 渲染器打印。

打印设置

打印设置保存了全站范围的打印默认值。只有系统管理员才能修改它。

可以从打印工作区打开它,或者在打印页面上通过⋯ > 打印设置打开。

适用于 Frappe v16 及更高版本。

PDF 设置

设置项 作用
以 PDF 发送打印件 邮件会将打印件作为 PDF 附件发送。关闭时,则以 HTML 附件发送。默认开启。
每页重复页眉和页脚 在每一页上打印页眉和页脚(包括信头)。关闭时,页眉只在顶部打印一次,页脚只在末尾打印一次。默认开启。
PDF 生成器 用于非编辑器创建的格式的引擎:chrome 或 wkhtmltopdf。编辑器创建的格式始终使用 Chromium 或 Typst。参见 PDF 生成。
PDF 页面尺寸 默认纸张尺寸,除非更改否则为 A4。选择自定义可以输入以毫米为单位的高度和宽度。
批量打印文档上限 单个批量 PDF 中最多包含的文档数。默认 100。
每用户最大并发批量导出数 一个人同时可以运行的批量导出数量。默认 5。

注意:版本 17 中移除了 PDF 生成器设置,所有 PDF 都使用 Chromium 生成。

页面设置

设置项 作用
使用信头打印 选择打印页面上的默认信头
允许打印草稿 允许用户打印已保存但未提交的文档。默认开启。
始终添加”草稿”标题 在打印的草稿上添加”草稿”横幅
允许表格内分页 允许长表格行跨页拆分
允许打印已取消的文档 允许用户打印已取消的文档

应用可以在此处添加自己的设置。ERPNext 添加了紧凑物料打印、数量后打印计量单位和打印零金额税费,这些也会显示在其文档的打印页面侧边栏中。

设置项 作用
启用打印服务器 通过 CUPS 将打印任务发送到网络打印机
启用原始打印 通过 QZ Tray 向热敏打印机和标签打印机发送 ESC/POS 命令

参见原始打印和网络打印。

设置项 作用
打印样式 标准格式的默认打印样式。默认为 Redesign。
字体和字号 HTML 格式的字体。编辑器创建的格式会设置自己的字体。

打印样式

打印样式会改变标准打印格式的外观:表格、章节标题和边框。你可以在打印页面上选择一种样式,这样无需创建格式就能获得不同的外观。

适用于 Frappe v16 及更高版本。打印页面上的样式选择器是 frappe/frappe#44232 中新增的功能。

内置样式

样式 外观
默认 标准外观:标签在值上方,浅色表头,带线的章节标题
现代 开放轻盈:圆角表头,无表格边框,低调的章节标题
经典 框线风格:每个章节都是带边框的网格,标题带底纹,表格有完整边框
粗体 章节标题和表头使用深色色带
条纹 紧凑:较小的文字,交替行底纹,表头下方只有一条线。适合较长的项目列表。
单色 仅使用黑色文字和线条,无填充

默认是名为Redesign的记录。

为单次打印选择样式

  1. 打开打印页面并选择标准格式。

  2. 在样式下,点击一张卡片。预览会更新。

  3. 可选:选择字体或开启省墨模式。

  4. 打印、下载 PDF 或通过电子邮件发送。这三种方式都会使用你选择的样式。

设置默认样式

打开打印设置并设置打印样式。当未选择样式时,将使用此样式,包括定时邮件和通知。

创建你自己的样式

  1. 打开打印样式列表,然后点击添加打印样式。
  2. 输入打印样式名称。
  3. 编写 CSS。将规则限定在标准布局范围内,以免影响在编辑器中创建的格式:
.print-format-doc.print-format-doc--standard .section-label {
    color: #1f4e79;
    border-bottom: 2px solid #1f4e79;
}
  1. 保存。该样式会作为卡片显示在打印页面上。

标准布局中有用的类:

类 元素
.print-format-doc 整个文档
.print-format-doc--standard 仅出现在标准格式上
.print-heading 顶部的文档标题和编号
.section, .section-label 一个章节及其标题
.field .label, .field .value 字段的标签和值
.child-table .table th, td 子表格表头单元格和单元格

要隐藏某个样式而不删除它,请勾选已禁用。

样式和其他格式

  • 在编辑器中创建的格式有自己的设计,因此不会为它们显示样式卡片。
  • HTML 格式会获得样式的 CSS,但只有针对其类编写的规则(例如 .print-format)才会生效。
  • 打印文档
  • 打印格式编辑器