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 : BaseUserCardCard(), 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 
 | 
     */ 
 | 
    override 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 
 | 
        } 
 | 
    } 
 | 
  
 | 
    override fun getZeroBytes(): ByteArray = Zero().toBytes() 
 | 
    override fun getOneBytes(): ByteArray = One().toBytes() 
 | 
    override fun getTwoBytes(): ByteArray = Two().toBytes() 
 | 
} 
 |