gm-printer 10.41.10-beta.162 → 10.41.10-beta.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-printer",
3
- "version": "10.41.10-beta.162",
3
+ "version": "10.41.10-beta.180",
4
4
  "description": "diy printer",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -22,6 +22,11 @@
22
22
  },
23
23
  "author": "",
24
24
  "license": "ISC",
25
+ "files": [
26
+ "src",
27
+ "locales",
28
+ "postcss.config.js"
29
+ ],
25
30
  "bugs": {
26
31
  "url": "https://github.com/gmfe/gm-printer/issues"
27
32
  },
@@ -216,9 +216,12 @@ class Table extends React.Component {
216
216
 
217
217
  if (!width) return tdStyle
218
218
  if (fontSize) minWidth = _.parseInt(fontSize) * 2
219
+ // 宽列也要锁 width:只设 minWidth 时打印阶段列宽会被该页内容重新分配,
220
+ // 与测量阶段(全量行 auto 布局)不一致,边界文本换行数漂移导致分页后页尾空白/溢出
219
221
  if (width >= 150) {
220
222
  tdStyle = {
221
- minWidth: width
223
+ minWidth: width,
224
+ width
222
225
  }
223
226
  } else {
224
227
  tdStyle = {
@@ -246,11 +249,16 @@ class Table extends React.Component {
246
249
  const needDiyTag = config.diyTagSubtotal?.show && dataKey.includes('tagDiy')
247
250
  const diyTagGroups = needDiyTag ? collectGroups(tableData, range) : []
248
251
 
252
+ // 列宽齐全(走过分页测量)时用 fixed:列宽锁定为测量值,不再随每页内容重新分配,
253
+ // 保证打印阶段换行/行高与测量阶段一致,分页边界才准确。
254
+ // 测量阶段自身(renderBefore)与合并打印首渲染(tablesInfo 为空)仍走 auto。
255
+ const isFixedLayout = thWidths.length === columns.length
256
+
249
257
  return (
250
258
  <table
251
259
  style={{
252
260
  // td会撑开table的宽度
253
- tableLayout: 'inherit',
261
+ tableLayout: isFixedLayout ? 'fixed' : 'inherit',
254
262
  wordBreak: 'break-all'
255
263
  }}
256
264
  >
package/.eslintrc.js DELETED
@@ -1,5 +0,0 @@
1
- const path = require('path')
2
-
3
- module.exports = {
4
- extends: ['plugin:gmfe/recommended']
5
- }
@@ -1,99 +0,0 @@
1
- name: Release
2
-
3
- permissions:
4
- contents: write
5
-
6
- on:
7
- push:
8
- tags:
9
- - 'v*'
10
- # 分支推送自动发 beta 预发布包(供宿主灰度/验证):
11
- # - hotfix/**、hotfix-*:hotfix 分支(从全量版本对应 tag 拉出),patch+1 版本
12
- # - feature/latest*、release/**、release-*:周期分支,minor+1 版本
13
- branches:
14
- - 'hotfix/**'
15
- - 'hotfix-*'
16
- - 'feature/latest*'
17
- - 'release/**'
18
- - 'release-*'
19
-
20
- jobs:
21
- release:
22
- runs-on: ubuntu-latest
23
- steps:
24
- - uses: actions/checkout@v3
25
- with:
26
- fetch-depth: 0
27
-
28
- - name: Set node
29
- uses: actions/setup-node@v3
30
- with:
31
- node-version: 16.x
32
- registry-url: 'https://registry.npmjs.org'
33
-
34
- - name: Setup
35
- run: npm i -g @antfu/ni@29.0.0
36
-
37
- - name: Install
38
- run: nci
39
-
40
- # 分支推送时自动生成预发布版本号(只用于本次发布,不改分支上的文件;run_number 保证每次推送唯一):
41
- # - hotfix 分支: patch+1,如 10.41.9 -> 10.41.10-beta.N,一个 hotfix 分支只对应一个修复版本
42
- # - 周期分支: minor+1,如 10.41.9 -> 10.42.0-beta.N,与 hotfix 的 patch 序列隔离
43
- - name: Bump pre-release version
44
- if: startsWith(github.ref, 'refs/heads/')
45
- run: |
46
- if [[ ${{ github.ref }} == refs/heads/hotfix* ]]; then
47
- VERSION=$(node -p "const p = require('./package.json').version.split('-')[0].split('.'); p[2] = Number(p[2]) + 1; p.join('.')")
48
- else
49
- VERSION=$(node -p "const p = require('./package.json').version.split('-')[0].split('.'); p[1] = Number(p[1]) + 1; p[2] = 0; p.join('.')")
50
- fi
51
- VERSION="$VERSION-beta.${{ github.run_number }}"
52
- npm version "$VERSION" --no-git-tag-version
53
- echo "本次分支推送发布版本: $VERSION (dist-tag: beta)" | tee -a "$GITHUB_STEP_SUMMARY"
54
-
55
- # hotfix 发布前差异审查:列出包内相对 npm 全量(latest)版本的全部提交,写入 Actions Summary 与运行日志。
56
- # hotfix 包应只包含目标修复提交;若清单中出现周期需求提交,说明分支基线不对,应停止发布。
57
- - name: Audit commits vs npm latest
58
- if: startsWith(github.ref, 'refs/heads/hotfix')
59
- run: |
60
- LATEST=$(npm dist-tag ls gm-printer | awk '/^latest:/ {print $2}')
61
- if [ -n "$LATEST" ]; then
62
- git fetch -q origin "refs/tags/v$LATEST:refs/tags/v$LATEST"
63
- fi
64
- if [ -n "$LATEST" ] && git rev-parse -q --verify "v$LATEST" >/dev/null; then
65
- {
66
- echo "## Hotfix 差异审查(npm latest: v$LATEST)"
67
- echo "hotfix 包应只包含目标修复提交,以下为 v$LATEST..HEAD 的全部提交:"
68
- echo '```'
69
- git log --oneline "v$LATEST..HEAD"
70
- echo '```'
71
- } >> "$GITHUB_STEP_SUMMARY"
72
- echo "Hotfix 差异审查(npm latest: v$LATEST),v$LATEST..HEAD 的全部提交:"
73
- git log --oneline "v$LATEST..HEAD"
74
- else
75
- echo "未找到全量版本 v$LATEST 对应的 tag,跳过差异审查" | tee -a "$GITHUB_STEP_SUMMARY"
76
- fi
77
-
78
- - name: Build
79
- run: npm run build
80
-
81
- - name: Release
82
- run: |
83
- if [[ ${{ github.ref }} == refs/tags/* ]]; then
84
- if [[ ${{ github.ref }} == *-beta* ]]; then
85
- npm publish --tag beta
86
- elif [[ ${{ github.ref }} == *-alpha* ]]; then
87
- npm publish --tag alpha
88
- else
89
- npm publish
90
- fi
91
- else
92
- npm publish --tag beta
93
- fi
94
- env:
95
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
96
- # - name: ChangeLog
97
- # run: npx changelogithub
98
- # env:
99
- # GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
package/.prettierrc.js DELETED
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- semi: false,
3
- singleQuote: true,
4
- jsxSingleQuote: true
5
- }
package/.stylelintrc DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "stylelint-config-standard"
3
- }
@@ -1,8 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "Accomodate",
4
- "Heihgt",
5
- "qrcode",
6
- "tableoverallordertr"
7
- ]
8
- }
package/CLAUDE.md DELETED
@@ -1,64 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## 这是什么
6
-
7
- `gm-printer` 是一个独立于宿主应用的网页打印库(以 npm 包 `gm-printer` 发布)。使用方传入 JSON **模板配置(template config)** 和 **数据(data)**,它负责渲染出经过像素级测量、自动分页的可打印页面(A4/A5/标签/长条等),并驱动浏览器打印对话框。同时附带可视化的 **编辑器(Editor)**,让最终用户通过拖拽/选中/右键来设计模板。由「果麦(gmfe)」前端团队开发,UI 文案与 i18n key 均为中文。
8
-
9
- 技术栈:React 16 + MobX 4 + webpack 4 + Less。宿主应用需以 **peerDependencies** 形式提供 react/mobx/lodash/moment/big.js 等;唯一的硬依赖是 `qrcode.react`。
10
-
11
- ## 常用命令
12
-
13
- ```bash
14
- yarn # 安装依赖(以 yarn.lock 为准)
15
- yarn start # 启动 webpack-dev-server,自动打开 demo: http://localhost:5678
16
- yarn build # 生产构建,产物输出到 build/(主要用于 CI 发版)
17
- yarn release # 交互式 bumpp 选版本 → 生成 tag → 触发 .github/workflows/release.yml → npm publish
18
- yarn locale # i18n-m 同步(从 src/ 抽取/同步多语言文案)
19
- ```
20
-
21
- - **本项目没有测试套件** —— 没有测试运行器,也没有 `test` 脚本。改动请通过 `yarn start` 在 demo / 实际打印预览中验证。
22
- - **代码检查(lint)只通过 precommit 钩子触发**(husky + lint-staged → 对暂存的 `src/**/*.js` 执行 `eslint --fix`)。没有独立的 `lint` 脚本;需要时手动执行 `npx eslint src/path/to/file.js`。ESLint 继承 `plugin:gmfe/recommended`(standard + prettier + 团队的 import-resolver 别名)。
23
- - 发版流程:在 feature/fix 分支执行 `yarn release` 选择 **beta/alpha** tag;在 `master` 上执行则选择 **正式** tag。推送 `v*` tag 会触发 `.github/workflows/release.yml`(Node 16,执行 build,用 `NPM_TOKEN` 执行 `npm publish`)。遵循 semver:不兼容变更 → 主版本,新增功能 → 次版本,缺陷修复 → 补丁版本。
24
-
25
- ## 架构
26
-
27
- 两个协作的 halves 共享同一个唯一事实来源 —— **模板配置(template config)**(结构详见 `README.md`:`page` / `header` / `contents` / `sign` / `footer`)。`contents` 是一个数组,混合了 `panel` 块和 `table` 块。
28
-
29
- ### 打印引擎 —— `src/printer/`
30
- - `do_print.js` 是对外入口:`doPrint` / `doBatchPrint` / `doBatchFinancePrint` / `getPrintContainerHTML` / `setPrintStyle`。它创建一个隐藏的 `<iframe>`,注入 `getCSS()`,把 `<Printer>` 渲染进去,等待图片/SVG 加载完成(`afterImgAndSvgLoaded`),再调用 `iframe.contentWindow.print()`。
31
- - `printer.js`(`Printer`)组合 `Page` → header/footer/sign + 分页后的 contents。
32
- - `store.js`(`PrinterStore`)是核心复杂度所在:**基于测量的分页**。它先渲染内容,测量真实 DOM 高度(`src/util.js` 中的 `getHeight`/`getWidth`),再按高度把表格行拆分到多页(`pages`、`remainPageHeight`、`tablesInfo`)。当你改动布局/纸张尺寸逻辑时,这里和 `page.js` 的分页计算是最容易出问题的地方。
33
- - 行渲染分散在多个 `table_*_tr.js` 变体中(`table_category_tr`、`table_subtotal_tr`、`table_special_tr`、`table_overallOrder_tr`、`table_diy_summary_tr` …),每种表格 `dataKey`/模式对应一个文件。长条打印有独立的 `long_print_table/` 以及 `longPrint` 页面类型。
34
- - `get_css.js` 拼接 `normalize.csss` + `style.lesss`。**`.lesss`/`.csss` 后缀是有意为之** —— 它们被当作纯文本读取并字符串拼接到注入的 `<style>` 中,刻意绕过 webpack 的 Less/CSS loader。
35
-
36
- ### 编辑器 —— `src/editor/`(基础) + 各业务域 `src/editor_*/`
37
- 编辑器让用户可视化地修改 Printer 所渲染的同一份 config。关键模式:
38
- - **`common/hoc_with_shadow_dom.js`** 把整个编辑器 + 打印预览渲染进 **Shadow DOM**(`attachShadow({mode:'open'})`),并注入合并后的 printer + editor CSS,使 gm-printer 的样式永远不会与宿主应用冲突。`window.shadowRoot` 被设为全局变量 —— 代码依赖它。
39
- - **`common/hoc_with_store.js`** 用 `{config, mockData}` 初始化 MobX store,并**仅通过 `window.document` 自定义事件**把打印预览的交互桥接回 Editor store —— 而不是通过 React props/context(因为 Printer 生活在 shadow DOM / iframe 中)。事件包括:`gm-printer-select`、`gm-printer-select-region`、`gm-printer-panel-style-set`、`gm-printer-block-style-set`、`gm-printer-block-text-set`、`gm-printer-table-drag`。它还实现了键盘微调(方向键移动块 / 重排表格列、Backspace 删除、Esc 取消选中)。新增编辑器↔预览交互时,请沿用这套事件桥接模式。
40
- - **`common/editor_store.js`**(`EditorStore`)是基础 MobX store:持有 `config`、`selected`、`selectedRegion`。选中状态采用**点号分隔的路径字符串约定**来定位 config 树:
41
- - 区域(region):`header` · `footer` · `sign` · `contents.panel.N` · `contents.table.N`
42
- - 元素(element):`header.block.N` · `contents.panel.N.block.M` · `contents.table.N.column.M`
43
- - 每个业务域编辑器(`editor_purchase`、`editor_stockin`、`editor_stockout`、`editor_settle`、`editor_statement`、`editor_account_statement`、`editor_box_label`、`editor_salemenus`、`editor_account`、`examining_report_editor`)都遵循**相同的 4 文件结构**:`editor.js`(组合 `src/common/` 中的共享子编辑器)、`store.js`(`class Store extends EditorStore`,追加业务列/dataKey)、`context_menu.js`、`index.js`(默认导出 `withShadowDom(Editor)`)。新增业务域编辑器时,照此结构复制即可。
44
- - 基础 `src/editor/` 导出 `Editor`(通用/配送单)和 `Editor2`(基于 `editor_menu_config.js` 的菜单配置变体)。
45
-
46
- ### 数据层
47
- 打印调用形式为 `{ config, data }`。`data` 包含 `common`、`_origin`、`_counter` 以及 `_table`(按表格 `dataKey` 索引:`orders`、`orders_multi`、`orders_category`、`orders_category_multi` …,与 `config.js` 及 README 中的模式对应)。config 文本中的 `{{field}}` 占位符会基于此数据进行插值。`src/util.js` 存放共享辅助函数(`getHeight`、`getWidth`、`dispatchMsg`、`getStyleWithDiff`、`getBlockName`、金额格式化等)。
48
-
49
- `src/finance_voucher/` 是一个平行的、财务专用的打印机,拥有自己的组件和批量打印机(`doBatchFinancePrint`)。
50
-
51
- ### 辅助模块
52
- - `src/config.js` —— 纸张类型映射(A4/A5/A4/2/A4/3/241x280/241x140/`longPrint`/`DIY`)、打印方向、块类型(text/line/image/counter/barcode/qrcode)、`MULTI_SUFFIX`/`MULTI_SUFFIX3` 多栏标记。
53
- - `src/components/` —— 内部 UI 组件库(dropdown、tooltip、radio、dialog、tip),统一使用 `gm-` CSS 命名空间。
54
- - `src/common/` —— 共享的编辑器构建块(`editor_title`、`editor_select`、`editor_edit_field`、`editor_add_field`、`editor_special_field`、`editor_page_summary`、`context_menu`、css 辅助)。
55
- - `demo/` —— 开发用应用(webpack 入口)。每个子目录是一个业务域示例;开发时在这里增改 demo 数据。
56
- - `build/` —— webpack 产物 + 内置字体资源(已提交)。`locales/` —— zh / zh-HK / en / th 多语言文件。
57
-
58
- ## 约定与坑
59
-
60
- - **i18n** 是 `locales/index.js` 中的轻量 shim,并非真正的 `i18next`。默认语言为 `zh`。调用 `i18next.t('中文文本')` —— **中文串本身即 key**;缺失的 key 会回退到 `__` 之后的子串。`setLocale` 切换语言,且**必须在渲染前执行**(`import '../locales'` 被刻意放在 `src/index.js` 的第一行)。
61
- - **金额/数量计算使用 `big.js`** —— 涉及价格或数量时绝不要用原生浮点运算。沿用 `price()` 辅助函数的写法。
62
- - **选中路径字符串的取值不能包含下划线**(特指表格 dataKey)—— `computedTableDataKeyOfSelectedRegion` 会按 `_` 切分。该注意点已在 `src/editor/editor.js` 中标注。
63
- - **对外 API 出口是 `src/index.js`** —— 此处导出的内容即为库的契约,其余皆为内部实现。
64
- - README 中的目录说明(`add_fields`、`data_to_key`、`mock_data`、`template_config`)**已过时** —— 这些文件夹已不存在;以当前 `src/` 实际布局为准。但 README 中关于模板配置结构和区域路径的文档仍然准确,是了解 config 结构的最佳参考。
Binary file
Binary file
Binary file
Binary file
Binary file
package/babel.config.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = api => {
2
- api.cache(true)
3
- return {
4
- ignore: [/@babel[/\\]runtime/], // 忽略 @babel/runtime
5
- presets: ['gmfe']
6
- }
7
- }