From fd2058574140e2c467cd78436902900546384df4 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Thu, 5 Feb 2026 15:15:42 +0800 Subject: [PATCH] feat: opt printer --- .claude/settings.local.json | 5 +- .../module_base/util/PrinterUtils.kt | 77 ++++++++++--------- .../gjc/holder/GjcBoxWeighingViewHolder.kt | 16 ++++ .../gjc/viewModel/GjcBoxWeighingViewModel.kt | 27 ++++++- 4 files changed, 88 insertions(+), 37 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 8b29e6e..6d60244 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -52,7 +52,10 @@ "Bash(identify:*)", "WebFetch(domain:github.com)", "Bash(file:*)", - "Bash(xargs:*)" + "Bash(xargs:*)", + "Bash(unzip:*)", + "WebFetch(domain:gainscha.github.io)", + "WebFetch(domain:m.gainscha.com)" ], "deny": [], "ask": [] diff --git a/module_base/src/main/java/com/lukouguoji/module_base/util/PrinterUtils.kt b/module_base/src/main/java/com/lukouguoji/module_base/util/PrinterUtils.kt index cb0c681..38d9c61 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/util/PrinterUtils.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/util/PrinterUtils.kt @@ -1,7 +1,6 @@ package com.lukouguoji.module_base.util import android.Manifest -import android.graphics.Typeface import com.gainscha.sdk2.ConnectType import com.gainscha.sdk2.ConnectionListener import com.gainscha.sdk2.Printer @@ -334,9 +333,9 @@ object PrinterUtils { merged = CellData("集装器编号:", "ULD NO.:", bean.uld) )) - // 第4行:件数 | 重量 + // 第4行:件数 | 重量(件数value暂不打印) rows.add(GridRow( - left = CellData("件数:", "PIECES:", bean.pieces.ifEmpty { "0" }), + left = CellData("件数:", "PIECES:", ""), right = CellData("重量:", "GROSS WEIGHT:", bean.totalWeight.toInt().toString()) )) @@ -360,7 +359,8 @@ object PrinterUtils { addSize(100, 100) addGap(3) addCls() - addTextByBitmap(150, 80, 0, 110, "合肥新桥国际机场", Typeface.DEFAULT) + // 使用 addText 替代 addTextByBitmap,避免 fimage 依赖问题 + addText(150, 80, Tspl.FONT_TSS24, 0, 3, 3, "合肥新桥国际机场") // 表格横线 for (i in 0 until 5) { addBar(gridStartX, gridStartY + (i * gridItemHeight), gridWidth, 2) @@ -403,7 +403,8 @@ object PrinterUtils { addSize(100, 100) addGap(3) addCls() - addTextByBitmap(80, 80, 0, 130, "合肥新桥国际机场", Typeface.DEFAULT) + // 使用 addText 替代 addTextByBitmap,避免 fimage 依赖问题 + addText(80, 80, Tspl.FONT_TSS24, 0, 3, 3, "合肥新桥国际机场") // 表格横线 for (i in 0 until 9) { addBar(gridStartX, gridStartY + (i * gridItemHeight), gridWidth, 2) @@ -449,17 +450,18 @@ object PrinterUtils { */ private fun printMergedGrid(rows: ArrayList) { val gridStartX = 30 - val gridStartY = 250 + val gridStartY = 200 val columnWidth = 570 - val rowHeight = 240 + val rowHeight = 180 // 减小行高,适应较小字体 val gridWidth = columnWidth * 2 - val gridHeight = rowHeight * rows.size val bytes = Tspl().apply { addSize(100, 100) addGap(3) addCls() - addTextByBitmap(80, 80, 0, 130, "合肥新桥国际机场", Typeface.DEFAULT) + // 标题居中(8个字 * 72像素/字 = 576像素宽,居中X = 30 + (1140-576)/2 = 312) + val titleX = gridStartX + (gridWidth - 576) / 2 + addText(titleX, 60, Tspl.FONT_TSS24, 0, 3, 3, "合肥新桥国际机场") // 绘制表格横线 for (i in 0..rows.size) { @@ -479,9 +481,7 @@ object PrinterUtils { } // 右边线(总是绘制) - if (rowIndex == rows.size - 1) { - addBar(gridStartX + gridWidth, yTop, 2, rowHeight) - } + addBar(gridStartX + gridWidth, yTop, 2, rowHeight) } // 填充单元格内容 @@ -492,17 +492,18 @@ object PrinterUtils { // 合并单元格 renderCell( cell = row.merged, - x = gridStartX + 30, + x = gridStartX + 20, y = yBase, cellWidth = gridWidth, - cellHeight = rowHeight + cellHeight = rowHeight, + isMerged = true ) } else { // 左列单元格 row.left?.let { cell -> renderCell( cell = cell, - x = gridStartX + 30, + x = gridStartX + 20, y = yBase, cellWidth = columnWidth, cellHeight = rowHeight @@ -512,7 +513,7 @@ object PrinterUtils { row.right?.let { cell -> renderCell( cell = cell, - x = gridStartX + columnWidth + 30, + x = gridStartX + columnWidth + 20, y = yBase, cellWidth = columnWidth, cellHeight = rowHeight @@ -532,37 +533,43 @@ object PrinterUtils { * @param cell 单元格数据 * @param x 起始X坐标 * @param y 起始Y坐标 - * @param cellWidth 单元格宽度(用于计算右侧对齐) - * @param cellHeight 单元格高度(用于计算垂直居中) + * @param cellWidth 单元格宽度 + * @param cellHeight 单元格高度 + * @param isMerged 是否为合并单元格 */ private fun Tspl.renderCell( cell: CellData, x: Int, y: Int, cellWidth: Int, - cellHeight: Int + cellHeight: Int, + isMerged: Boolean = false ) { - // 左上角:中文标签和英文标签 - val titleY = y + 30 // 中文标签Y位置 - val subtitleY = y + 80 // 英文标签Y位置(中文下方) + // 字体大小配置 + val titleSize = 2 // 中文标签字体倍数 + val subtitleSize = 1 // 英文标签字体倍数 + val valueSize = 2 // 值字体倍数 - // 中文标签(大字,左上) - addText(x, titleY, Tspl.FONT_TSS24, 0, 3, 3, cell.title) + // Y坐标配置(基于24点阵字体,size=2约48像素高,size=1约24像素高) + val titleY = y + 15 // 中文标签Y位置 + val subtitleY = titleY + 70 // 英文标签Y位置(中文下方,间距加大) + val valueY = y + (cellHeight / 2) - 24 // 值垂直居中 - // 英文标签(小字,左上) - addText(x, subtitleY, Tspl.FONT_TSS24, 0, 2, 2, cell.subtitle) + // 中文标签 + addText(x, titleY, Tspl.FONT_TSS24, 0, titleSize, titleSize, cell.title) - // 右侧:值(大字,垂直居中) - // 计算垂直居中的Y坐标:y + (cellHeight / 2) - (文字高度 / 2) - // 假设size=3的文字高度约为80像素 - val valueY = y + (cellHeight / 2) - 40 // 垂直居中 + // 英文标签 + addText(x, subtitleY, Tspl.FONT_TSS24, 0, subtitleSize, subtitleSize, cell.subtitle) - // 计算右侧X坐标:中文标签宽度 + 间距 - // 假设"目的站:"宽度约为180像素,"DESTINATION:"宽度约为240像素 - val valueX = x + 280 // 右侧偏移量 + // 计算value的X坐标(根据英文标签长度动态调整) + // 合并单元格(如集装器编号)使用更大的间距 + val extraGap = if (isMerged) 80 else 50 + val minOffset = if (isMerged) 280 else 220 + val labelWidth = cell.subtitle.length * 12 + extraGap + val valueX = x + maxOf(labelWidth, minOffset) - // 值(大字,垂直居中,右侧) - addText(valueX, valueY, Tspl.FONT_TSS24, 0, 3, 3, cell.value) + // 值(垂直居中) + addText(valueX, valueY, Tspl.FONT_TSS24, 0, valueSize, valueSize, cell.value) } fun printTest() { diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcBoxWeighingViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcBoxWeighingViewHolder.kt index fe95e8c..159524c 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcBoxWeighingViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcBoxWeighingViewHolder.kt @@ -1,6 +1,7 @@ package com.lukouguoji.gjc.holder import android.view.View +import com.lukouguoji.gjc.R import com.lukouguoji.gjc.activity.GjcBoxWeighingDetailsActivity import com.lukouguoji.gjc.databinding.ItemGjcBoxWeighingBinding import com.lukouguoji.module_base.base.BaseViewHolder @@ -16,9 +17,24 @@ class GjcBoxWeighingViewHolder(view: View) : val bean = getItemBean(item)!! binding.bean = bean + // 更新图标状态 + updateIcon(bean) + + // 图标点击切换选中状态 + binding.ivIcon.setOnClickListener { + bean.checked.set(!bean.checked.get()) + updateIcon(bean) + } + // 整行点击跳转到详情页 binding.ll.setOnClickListener { GjcBoxWeighingDetailsActivity.start(it.context, bean.useId) } } + + private fun updateIcon(bean: GjcUldUseBean) { + binding.ivIcon.setImageResource( + if (bean.checked.get()) R.drawable.img_plane_s else R.drawable.img_plane + ) + } } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcBoxWeighingViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcBoxWeighingViewModel.kt index 04635ab..af1cb08 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcBoxWeighingViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcBoxWeighingViewModel.kt @@ -6,12 +6,17 @@ import androidx.lifecycle.MutableLiveData import com.lukouguoji.gjc.R import com.lukouguoji.gjc.holder.GjcBoxWeighingViewHolder import com.lukouguoji.module_base.base.BasePageViewModel +import com.lukouguoji.module_base.bean.GjcUldUseBean import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.http.net.NetApply +import com.lukouguoji.module_base.ktx.commonAdapter import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchLoadingCollect +import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.toRequestBody +import com.lukouguoji.module_base.model.BluetoothDialogModel import com.lukouguoji.module_base.model.ScanModel +import com.lukouguoji.module_base.util.PrinterUtils import dev.utils.common.DateUtils import com.lukouguoji.module_base.ktx.formatDate @@ -73,7 +78,27 @@ class GjcBoxWeighingViewModel : BasePageViewModel() { * 挂签打印按钮点击 */ fun printClick() { - // TODO: 实现挂签打印功能 + // 获取列表中选中的记录 + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selectedItems = list.filter { it.isSelected } + + // 校验未选择 + if (selectedItems.isEmpty()) { + showToast("请选择要打印的数据") + return + } + + // 校验多选 + if (selectedItems.size > 1) { + showToast("只能选择一条记录进行打印") + return + } + + // 执行打印 + val bean = selectedItems.first() + BluetoothDialogModel().showCallBack { + PrinterUtils.printGjcBoxWeighing(bean) + } } /**