package com.dayu.general.bean.card
|
|
import com.dayu.baselibrary.bean.BaseUserCardCard
|
import com.dayu.baselibrary.tools.BcdUtil
|
import com.dayu.baselibrary.tools.HexUtil
|
import com.dayu.general.tool.CardCommon.Companion.USER_CARD_TYPE_1
|
import java.io.Serializable
|
import java.util.*
|
|
/**
|
* 通用项目用户卡结构
|
*/
|
class UserCard : BaseCard(), Serializable {
|
var cardType: String = USER_CARD_TYPE_1 // 卡类型:A1终端写卡 A8刷卡开泵后值 A2叠加充值
|
var areaNumber: Int = 0 // 国家行政区域号(12位BCD,精确到村)
|
var userCode: String = "" // 用户编号BCD
|
var userCodeNumber: Int = 0 // 用户卡编号(HEX)
|
var phoneNumber: String = "" // 手机号(BCD)
|
var projectCode: Int = 0 // 项目编码(HEX 1-255)
|
var balance: Int = 0 // 剩余金额(2位小数点,单位元)
|
var surplusWater: Int = 0 // 剩余水量(2位小数点,单位立方米)
|
var waterPrice: Float = 0f // 水量单价(最大655.35,2位小数点。单位:m3/元)
|
var electricPrice: Float = 0f // 电量单价(最大655.35,2位小数点。单位: 元/度)
|
var rechargeDate: Calendar? = null // 充值时间
|
|
/**
|
* 写卡完成后校验是否写卡成功
|
*/
|
fun equalsUserCard(data: List<ByteArray>?): Boolean {
|
if (data == null || data.size < 3) {
|
return false
|
}
|
|
val expectedBytes = arrayOf(getZeroBytes(), getOneBytes(), getTwoBytes())
|
return data.zip(expectedBytes.toList()).all { (actual, expected) ->
|
actual.contentEquals(expected)
|
}
|
}
|
|
/**
|
* 返回完整的用户编号
|
*/
|
fun getMyUserCode(): String {
|
return userCode + String.format("%04d", userCodeNumber)
|
}
|
|
/**
|
* 通过byte转bean
|
*/
|
fun getBean(data: List<ByteArray>): UserCard? {
|
try {
|
val userCard = UserCard()
|
// 解析第0块
|
val zero = data[0]
|
userCard.apply {
|
// 解析国家行政区域号(0-5位)
|
val areaCodeBytes = zero.copyOfRange(0, 6)
|
areaNumber = BcdUtil.bcdToStr(areaCodeBytes).toInt()
|
|
// 解析用户卡编号(6-7位)
|
val userCodeNumberBytes = zero.copyOfRange(6, 8)
|
userCodeNumber = HexUtil.get16To10LowHightByBytes(userCodeNumberBytes)
|
|
// 解析卡类型(8位)
|
cardType = HexUtil.byteToHex(zero[8])
|
|
// 解析手机号(9-14位)
|
phoneNumber = BcdUtil.bcdToStr(zero.copyOfRange(9, 15))
|
}
|
|
// 解析第1块
|
val one = data[1]
|
userCard.apply {
|
projectCode = HexUtil.get16To10LowHightByBytes(byteArrayOf(one[0]))
|
balance = HexUtil.get16To10LowHightByBytes(one.copyOfRange(1, 5))
|
surplusWater = HexUtil.get16To10LowHightByBytes(one.copyOfRange(5, 9))
|
electricPrice = HexUtil.hexToFloatLowHigh(one.copyOfRange(9, 11))
|
|
// 解析充值时间
|
val year = HexUtil.getBcdToInt(one[11])
|
val month = HexUtil.getBcdToInt(one[12])
|
val day = HexUtil.getBcdToInt(one[13])
|
val hour = HexUtil.getBcdToInt(one[14])
|
Calendar.getInstance().apply {
|
set(2000 + year, month - 1, day, hour, 0, 0)
|
rechargeDate = this
|
}
|
}
|
|
// 解析第2块
|
val two = data[2]
|
userCard.apply {
|
waterPrice = HexUtil.hexToFloatLowHigh(two.copyOfRange(9, 11))
|
}
|
|
return userCard
|
} catch (e: Exception) {
|
e.printStackTrace()
|
return null
|
}
|
}
|
|
// 内部类用于生成各个数据块
|
inner class Zero : BaseCard() {
|
fun toBytes(): ByteArray {
|
val data = ByteArray(16)
|
try {
|
// 设置国家行政区域号(BCD格式,6字节,0-5位)
|
val areaCodeBytes = BcdUtil.strToBcd(String.format("%012d", areaNumber))
|
System.arraycopy(areaCodeBytes, 0, data, 0, 6)
|
|
// 设置用户卡编号(HEX格式,2字节,6-7位)
|
val userCodeBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(userCodeNumber))
|
System.arraycopy(userCodeBytes, 0, data, 6, 2)
|
|
// 设置卡类型(8位)
|
data[8] = HexUtil.hexToByte(cardType)
|
|
// 设置手机号(BCD格式,6字节,9-14位)
|
val phoneBytes = BcdUtil.strToBcd(phoneNumber.padStart(12, '0'))
|
System.arraycopy(phoneBytes, 0, data, 9, 6)
|
|
// 设置校验和(15位)
|
data[15] = getByteSum(data)
|
} catch (e: Exception) {
|
e.printStackTrace()
|
}
|
return data
|
}
|
}
|
|
inner class One : BaseCard() {
|
fun toBytes(): ByteArray {
|
val data = ByteArray(16)
|
try {
|
data[0] = projectCode.toByte()
|
|
// 设置余额
|
val balanceBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(balance))
|
System.arraycopy(balanceBytes, 0, data, 1, 4)
|
|
// 设置剩余水量
|
val waterBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(surplusWater))
|
System.arraycopy(waterBytes, 0, data, 5, 4)
|
|
// 设置电价
|
val priceBytes = HexUtil.hexToByteArray(HexUtil.floatToHexLowHigh(electricPrice))
|
System.arraycopy(priceBytes, 0, data, 9, 2)
|
|
// 设置充值时间
|
rechargeDate?.let {
|
data[11] = HexUtil.getIntToBCD(it.get(Calendar.YEAR) % 100)[0]
|
data[12] = HexUtil.getIntToBCD(it.get(Calendar.MONTH) + 1)[0]
|
data[13] = HexUtil.getIntToBCD(it.get(Calendar.DAY_OF_MONTH))[0]
|
data[14] = HexUtil.getIntToBCD(it.get(Calendar.HOUR_OF_DAY))[0]
|
}
|
|
data[15] = getByteSum(data)
|
} catch (e: Exception) {
|
e.printStackTrace()
|
}
|
return data
|
}
|
}
|
|
inner class Two : BaseCard() {
|
fun toBytes(): ByteArray {
|
val data = ByteArray(16)
|
try {
|
// 备份余额和水量数据
|
val balanceBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(balance))
|
System.arraycopy(balanceBytes, 0, data, 1, 4)
|
|
val waterBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(surplusWater))
|
System.arraycopy(waterBytes, 0, data, 5, 4)
|
|
// 设置水价
|
val priceBytes = HexUtil.hexToByteArray(HexUtil.floatToHexLowHigh(waterPrice))
|
System.arraycopy(priceBytes, 0, data, 9, 2)
|
|
// 设置充值时间
|
rechargeDate?.let {
|
data[11] = HexUtil.getIntToBCD(it.get(Calendar.YEAR) % 100)[0]
|
data[12] = HexUtil.getIntToBCD(it.get(Calendar.MONTH) + 1)[0]
|
data[13] = HexUtil.getIntToBCD(it.get(Calendar.DAY_OF_MONTH))[0]
|
data[14] = HexUtil.getIntToBCD(it.get(Calendar.HOUR_OF_DAY))[0]
|
}
|
|
data[15] = getByteSum(data)
|
} catch (e: Exception) {
|
e.printStackTrace()
|
}
|
return data
|
}
|
}
|
|
fun getZeroBytes(): ByteArray = Zero().toBytes()
|
fun getOneBytes(): ByteArray = One().toBytes()
|
fun getTwoBytes(): ByteArray = Two().toBytes()
|
}
|