feat: opt 板箱过磅 print
This commit is contained in:
@@ -2,7 +2,6 @@ package com.lukouguoji.module_base.util
|
||||
|
||||
import android.Manifest
|
||||
import android.graphics.Typeface
|
||||
import android.util.Log
|
||||
import com.gainscha.sdk2.ConnectType
|
||||
import com.gainscha.sdk2.ConnectionListener
|
||||
import com.gainscha.sdk2.Printer
|
||||
@@ -18,23 +17,39 @@ import com.gprinter.io.PortManager
|
||||
import com.gprinter.utils.CallbackListener
|
||||
import com.gprinter.utils.Command
|
||||
import com.gprinter.utils.ConnMethod
|
||||
import com.lukouguoji.module_base.bean.FlatcarBean
|
||||
import com.lukouguoji.module_base.bean.GjcUldUseBean
|
||||
import com.lukouguoji.module_base.bean.GncFuBangBean
|
||||
import com.lukouguoji.module_base.bean.GncShouYunBean
|
||||
import com.lukouguoji.module_base.http.net.NetApply
|
||||
import com.lukouguoji.module_base.ktx.launchCollect
|
||||
import com.lukouguoji.module_base.ktx.launchLoadingCollect
|
||||
import com.lukouguoji.module_base.ktx.loge
|
||||
import com.lukouguoji.module_base.ktx.permission
|
||||
import com.lukouguoji.module_base.ktx.showToast
|
||||
import com.lukouguoji.module_base.model.LoadingModel
|
||||
import dev.DevUtils
|
||||
import dev.utils.app.SizeUtils
|
||||
import okio.internal.commonToUtf8String
|
||||
|
||||
|
||||
object PrinterUtils {
|
||||
|
||||
/**
|
||||
* 打印单元格数据
|
||||
*/
|
||||
private data class CellData(
|
||||
val title: String, // 中文标签(大字)
|
||||
val subtitle: String, // 英文标签(小字)
|
||||
val value: String // 值(大字,垂直居中)
|
||||
)
|
||||
|
||||
/**
|
||||
* 打印表格行数据
|
||||
*/
|
||||
private data class GridRow(
|
||||
val left: CellData? = null,
|
||||
val right: CellData? = null,
|
||||
val merged: CellData? = null // 合并单元格数据
|
||||
)
|
||||
|
||||
private val loading by lazy {
|
||||
LoadingModel()
|
||||
}
|
||||
@@ -133,7 +148,8 @@ object PrinterUtils {
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
) {
|
||||
finder.searchPrinters(ConnectType.BLUETOOTH,
|
||||
finder.searchPrinters(
|
||||
ConnectType.BLUETOOTH,
|
||||
object : PrinterFinder.SimpleSearchPrinterResultListener() {
|
||||
override fun onSearchBluetoothPrinter(device: BluetoothPrinterDevice?) {
|
||||
if (device == null) return
|
||||
@@ -218,28 +234,28 @@ object PrinterUtils {
|
||||
var fDestinationCn = ""
|
||||
launchCollect({
|
||||
NetApply.api.getAirportByCode(bean.dest1)
|
||||
}){
|
||||
}) {
|
||||
onSuccess = {
|
||||
destinationCn = it.data?.nameCn ?: ""
|
||||
rowItem.add(listOf("日期", "航班号", "目的站"))
|
||||
rowItem.add(listOf( bean.fdate, bean.fno, bean.dest1 + destinationCn ))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf( bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf( "", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息","备注"))
|
||||
rowItem.add(listOf(bean.fdate, bean.fno, bean.dest1 + destinationCn))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf(bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf("", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息", "备注"))
|
||||
if (bean.dest2 != "") {
|
||||
launchCollect({
|
||||
NetApply.api.getAirportByCode(bean.dest2)
|
||||
}){
|
||||
}) {
|
||||
onSuccess = { it2 ->
|
||||
fDestinationCn = it2.data?.nameCn ?: ""
|
||||
rowItem.add(listOf( "", bean.dest2 + fDestinationCn, ""))
|
||||
rowItem.add(listOf("", bean.dest2 + fDestinationCn, ""))
|
||||
printCommonGridNew(rowItem)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rowItem.add(listOf( "", "", ""))
|
||||
rowItem.add(listOf("", "", ""))
|
||||
printCommonGridNew(rowItem)
|
||||
}
|
||||
}
|
||||
@@ -259,35 +275,35 @@ object PrinterUtils {
|
||||
var fDestinationCn = ""
|
||||
launchCollect({
|
||||
NetApply.api.getAirportByCode(bean.fdest)
|
||||
}){
|
||||
}) {
|
||||
onSuccess = {
|
||||
fDestinationCn = it.data?.nameCn ?: ""
|
||||
if (bean.dest != "") {
|
||||
launchCollect({
|
||||
NetApply.api.getAirportByCode(bean.dest)
|
||||
}){
|
||||
}) {
|
||||
onSuccess = { it2 ->
|
||||
destinationCn = it2.data?.nameCn ?: ""
|
||||
rowItem.add(listOf("日期", "航班号", "目的站"))
|
||||
rowItem.add(listOf( bean.fdate, bean.fno, bean.fdest + fDestinationCn ))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf( bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf( "", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息","备注"))
|
||||
rowItem.add(listOf( "", bean.dest + destinationCn, ""))
|
||||
rowItem.add(listOf(bean.fdate, bean.fno, bean.fdest + fDestinationCn))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf(bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf("", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息", "备注"))
|
||||
rowItem.add(listOf("", bean.dest + destinationCn, ""))
|
||||
printCommonGridNew(rowItem)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rowItem.add(listOf("日期", "航班号", "目的站"))
|
||||
rowItem.add(listOf( bean.fdate, bean.fno, bean.fdest + fDestinationCn ))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf( bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf( "", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息","备注"))
|
||||
rowItem.add(listOf( "", "", ""))
|
||||
rowItem.add(listOf(bean.fdate, bean.fno, bean.fdest + fDestinationCn))
|
||||
rowItem.add(listOf("斗号", "计重", "仓管"))
|
||||
rowItem.add(listOf(bean.location, bean.username, ""))
|
||||
rowItem.add(listOf("装机仓位", "机位", "特车司机"))
|
||||
rowItem.add(listOf("", "", ""))
|
||||
rowItem.add(listOf("监装监卸", "中转信息", "备注"))
|
||||
rowItem.add(listOf("", "", ""))
|
||||
printCommonGridNew(rowItem)
|
||||
}
|
||||
|
||||
@@ -295,6 +311,43 @@ object PrinterUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印国际出港板箱过磅挂签(2列布局,支持合并单元格)
|
||||
*/
|
||||
fun printGjcBoxWeighing(bean: GjcUldUseBean) {
|
||||
val rows = arrayListOf<GridRow>()
|
||||
|
||||
// 第1行:日期 | 航班号
|
||||
rows.add(GridRow(
|
||||
left = CellData("日期:", "DATA:", bean.fdate),
|
||||
right = CellData("航班号:", "FLIGHT NO.:", bean.fno)
|
||||
))
|
||||
|
||||
// 第2行:目的站 | 板型
|
||||
rows.add(GridRow(
|
||||
left = CellData("目的站:", "DESTINATION:", bean.fdest),
|
||||
right = CellData("板型:", "PALLET TYPE:", bean.boardType)
|
||||
))
|
||||
|
||||
// 第3行:集装器编号(合并两列)
|
||||
rows.add(GridRow(
|
||||
merged = CellData("集装器编号:", "ULD NO.:", bean.uld)
|
||||
))
|
||||
|
||||
// 第4行:件数 | 重量
|
||||
rows.add(GridRow(
|
||||
left = CellData("件数:", "PIECES:", bean.pieces.ifEmpty { "0" }),
|
||||
right = CellData("重量:", "GROSS WEIGHT:", bean.totalWeight.toInt().toString())
|
||||
))
|
||||
|
||||
// 第5行:备注(合并两列)
|
||||
rows.add(GridRow(
|
||||
merged = CellData("备注:", "NOTES:", bean.remark)
|
||||
))
|
||||
|
||||
printMergedGrid(rows)
|
||||
}
|
||||
|
||||
private fun printCommonGrid(rowItem: ArrayList<List<String>>) {
|
||||
val gridStartX = 80
|
||||
val gridStartY = 300
|
||||
@@ -370,10 +423,10 @@ object PrinterUtils {
|
||||
if (index % 2 == 0) {
|
||||
padding = 15
|
||||
}
|
||||
if (str.length == 2){
|
||||
if (str.length == 2) {
|
||||
padding += 60
|
||||
}
|
||||
if (str.length == 3){
|
||||
if (str.length == 3) {
|
||||
padding += 30
|
||||
}
|
||||
if (str.length == 7) {
|
||||
@@ -391,6 +444,127 @@ object PrinterUtils {
|
||||
portManager?.writeDataImmediately(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印支持合并单元格的表格
|
||||
*/
|
||||
private fun printMergedGrid(rows: ArrayList<GridRow>) {
|
||||
val gridStartX = 30
|
||||
val gridStartY = 250
|
||||
val columnWidth = 570
|
||||
val rowHeight = 240
|
||||
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)
|
||||
|
||||
// 绘制表格横线
|
||||
for (i in 0..rows.size) {
|
||||
addBar(gridStartX, gridStartY + (i * rowHeight), gridWidth, 2)
|
||||
}
|
||||
|
||||
// 绘制表格竖线(需要根据是否合并单元格决定)
|
||||
rows.forEachIndexed { rowIndex, row ->
|
||||
val yTop = gridStartY + (rowIndex * rowHeight)
|
||||
|
||||
// 左边线(总是绘制)
|
||||
addBar(gridStartX, yTop, 2, rowHeight)
|
||||
|
||||
// 中间分隔线(非合并单元格才绘制)
|
||||
if (row.merged == null) {
|
||||
addBar(gridStartX + columnWidth, yTop, 2, rowHeight)
|
||||
}
|
||||
|
||||
// 右边线(总是绘制)
|
||||
if (rowIndex == rows.size - 1) {
|
||||
addBar(gridStartX + gridWidth, yTop, 2, rowHeight)
|
||||
}
|
||||
}
|
||||
|
||||
// 填充单元格内容
|
||||
rows.forEachIndexed { rowIndex, row ->
|
||||
val yBase = gridStartY + (rowIndex * rowHeight)
|
||||
|
||||
if (row.merged != null) {
|
||||
// 合并单元格
|
||||
renderCell(
|
||||
cell = row.merged,
|
||||
x = gridStartX + 30,
|
||||
y = yBase,
|
||||
cellWidth = gridWidth,
|
||||
cellHeight = rowHeight
|
||||
)
|
||||
} else {
|
||||
// 左列单元格
|
||||
row.left?.let { cell ->
|
||||
renderCell(
|
||||
cell = cell,
|
||||
x = gridStartX + 30,
|
||||
y = yBase,
|
||||
cellWidth = columnWidth,
|
||||
cellHeight = rowHeight
|
||||
)
|
||||
}
|
||||
// 右列单元格
|
||||
row.right?.let { cell ->
|
||||
renderCell(
|
||||
cell = cell,
|
||||
x = gridStartX + columnWidth + 30,
|
||||
y = yBase,
|
||||
cellWidth = columnWidth,
|
||||
cellHeight = rowHeight
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addPrint(1)
|
||||
}.bytes
|
||||
|
||||
portManager?.writeDataImmediately(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染单元格内容
|
||||
* @param cell 单元格数据
|
||||
* @param x 起始X坐标
|
||||
* @param y 起始Y坐标
|
||||
* @param cellWidth 单元格宽度(用于计算右侧对齐)
|
||||
* @param cellHeight 单元格高度(用于计算垂直居中)
|
||||
*/
|
||||
private fun Tspl.renderCell(
|
||||
cell: CellData,
|
||||
x: Int,
|
||||
y: Int,
|
||||
cellWidth: Int,
|
||||
cellHeight: Int
|
||||
) {
|
||||
// 左上角:中文标签和英文标签
|
||||
val titleY = y + 30 // 中文标签Y位置
|
||||
val subtitleY = y + 80 // 英文标签Y位置(中文下方)
|
||||
|
||||
// 中文标签(大字,左上)
|
||||
addText(x, titleY, Tspl.FONT_TSS24, 0, 3, 3, cell.title)
|
||||
|
||||
// 英文标签(小字,左上)
|
||||
addText(x, subtitleY, Tspl.FONT_TSS24, 0, 2, 2, cell.subtitle)
|
||||
|
||||
// 右侧:值(大字,垂直居中)
|
||||
// 计算垂直居中的Y坐标:y + (cellHeight / 2) - (文字高度 / 2)
|
||||
// 假设size=3的文字高度约为80像素
|
||||
val valueY = y + (cellHeight / 2) - 40 // 垂直居中
|
||||
|
||||
// 计算右侧X坐标:中文标签宽度 + 间距
|
||||
// 假设"目的站:"宽度约为180像素,"DESTINATION:"宽度约为240像素
|
||||
val valueX = x + 280 // 右侧偏移量
|
||||
|
||||
// 值(大字,垂直居中,右侧)
|
||||
addText(valueX, valueY, Tspl.FONT_TSS24, 0, 3, 3, cell.value)
|
||||
}
|
||||
|
||||
fun printTest() {
|
||||
getConnectedPrinters().forEach {
|
||||
val bytes = v(Instruction.TSC.toString(), null).bytes
|
||||
|
||||
Reference in New Issue
Block a user