vluk@2fi-solutions.com.hk пре 4 часа
родитељ
комит
510e3e90bc
3 измењених фајлова са 118 додато и 0 уклоњено
  1. +86
    -0
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/PlasticBagPrinterService.kt
  2. +10
    -0
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/PlasticBagPrinterController.kt
  3. +22
    -0
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/LaserBag2MarkInfoResponse.kt

+ 86
- 0
src/main/java/com/ffii/fpsms/modules/jobOrder/service/PlasticBagPrinterService.kt Прегледај датотеку

@@ -6,6 +6,7 @@ import com.ffii.fpsms.modules.jobOrder.entity.JobOrder
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SendRequest
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SendResponse
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2MarkInfoResponse
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SettingsResponse
import com.ffii.fpsms.modules.jobOrder.web.model.LaserLastReceiveSuccessDto
import com.ffii.fpsms.modules.jobOrder.web.model.PrintRequest
@@ -351,6 +352,91 @@ class PlasticBagPrinterService(
}
}

/**
* TCP text queries on the same [LASER_PRINT] host/port as Bag2 send (UTF-8, line-terminated commands).
* Uses one connection per command so the plugin can answer independently.
*/
fun getLaserBag2MarkInfo(): LaserBag2MarkInfoResponse {
val host = resolveLaserBag2Host()
val port = resolveLaserBag2Port()
val (dataVal, dataErr) = sendLaserBag2QueryCommand(host, port, "GetMarkData")
val (statusVal, statusErr) = sendLaserBag2QueryCommand(host, port, "GetMarkStatus")
val (countVal, countErr) = sendLaserBag2QueryCommand(host, port, "GetMarkedCount")
val statusInt = statusVal?.let { parseFirstIntToken(it) }
val countInt = countVal?.let { parseFirstIntToken(it) }
val errs = listOfNotNull(
dataErr?.let { "GetMarkData:$it" },
statusErr?.let { "GetMarkStatus:$it" },
countErr?.let { "GetMarkedCount:$it" },
)
return LaserBag2MarkInfoResponse(
host = host,
port = port,
markData = dataVal,
markStatus = statusInt,
markStatusLabel = markStatusToLabel(statusInt),
markedCount = countInt,
rawMarkStatus = statusVal,
rawMarkedCount = countVal,
error = errs.joinToString(";").ifBlank { null },
)
}

/**
* Sends [command] as UTF-8 with LF, half-closes output, reads one response chunk (same pattern as job send ack read).
* @return Pair(trimmed response or null, error message or null)
*/
private fun sendLaserBag2QueryCommand(ip: String, port: Int, command: String): Pair<String?, String?> {
var socket: Socket? = null
try {
socket = Socket()
socket.soTimeout = 3000
socket.connect(InetSocketAddress(ip, port), 3000)
val line = command.trim() + "\n"
val out = socket.getOutputStream()
out.write(line.toByteArray(StandardCharsets.UTF_8))
out.flush()
try {
socket.shutdownOutput()
} catch (_: Exception) {
}
socket.soTimeout = 2500
val buf = ByteArray(8192)
val n = socket.getInputStream().read(buf)
val raw = if (n > 0) {
String(buf, 0, n, StandardCharsets.UTF_8).trim()
} else {
""
}
return raw to null
} catch (e: ConnectException) {
return null to "無法連線"
} catch (e: SocketTimeoutException) {
return null to "讀取逾時"
} catch (e: Exception) {
return null to (e.message ?: e.javaClass.simpleName)
} finally {
try {
socket?.close()
} catch (_: Exception) {
}
}
}

private fun parseFirstIntToken(text: String): Int? {
val t = text.trim()
if (t.isEmpty()) return null
t.toIntOrNull()?.let { return it }
return Regex("""-?\d+""").find(t)?.value?.toIntOrNull()
}

private fun markStatusToLabel(v: Int?): String? = when (v) {
0 -> "待機"
1 -> "打標中"
2 -> "其他狀態"
else -> null
}

fun generatePrintJobBundle(
itemCode: String,
lotNo: String,


+ 10
- 0
src/main/java/com/ffii/fpsms/modules/jobOrder/web/PlasticBagPrinterController.kt Прегледај датотеку

@@ -8,6 +8,7 @@ import com.ffii.fpsms.modules.jobOrder.web.model.Laser2Request
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2AutoSendReport
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SendRequest
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SendResponse
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2MarkInfoResponse
import com.ffii.fpsms.modules.jobOrder.web.model.LaserBag2SettingsResponse
import com.ffii.fpsms.modules.jobOrder.web.model.NgpclPushResponse
import com.ffii.fpsms.modules.jobOrder.web.model.OnPackQrDownloadRequest
@@ -37,6 +38,15 @@ class PlasticBagPrinterController(
return plasticBagPrinterService.getLaserBag2Settings()
}

/**
* Live laser TCP queries: `GetMarkData`, `GetMarkStatus` (0 idle / 1 marking / 2 other), `GetMarkedCount`.
* Uses [LASER_PRINT.host] / [LASER_PRINT.port] (same as print-laser-bag2).
*/
@GetMapping("/laser-bag2-mark-info")
fun getLaserBag2MarkInfo(): LaserBag2MarkInfoResponse {
return plasticBagPrinterService.getLaserBag2MarkInfo()
}

/**
* Job orders for /laserPrint: same as GET /py/job-orders but filtered by [LASER_PRINT.itemCodes] (comma-separated).
* Blank itemCodes setting = no filter (all 包裝 job orders for the day).


+ 22
- 0
src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/LaserBag2MarkInfoResponse.kt Прегледај датотеку

@@ -0,0 +1,22 @@
package com.ffii.fpsms.modules.jobOrder.web.model

/**
* Live laser TCP query results (EZCAD-style commands on same host/port as Bag2 laser send).
*
* [markStatus]: 0 = idle, 1 = marking, 2 = other (when the device returns a parseable digit).
*/
data class LaserBag2MarkInfoResponse(
val host: String,
val port: Int,
/** Response body from `GetMarkData` (current mark string / job data). */
val markData: String? = null,
/** Parsed from `GetMarkStatus` when possible. */
val markStatus: Int? = null,
/** Short label for [markStatus] (Traditional Chinese). */
val markStatusLabel: String? = null,
val markedCount: Int? = null,
val rawMarkStatus: String? = null,
val rawMarkedCount: String? = null,
/** Non-fatal per-command issues (e.g. read timeout); fields may still be partially filled. */
val error: String? = null,
)

Loading…
Откажи
Сачувај