C# 适配大华TM-F条码秤

背景

大华条码秤(TM-F),使用了自己的私有协议。在对接过程中,将PLU信息部分的转义和解析进行了封装。

基础信息

首先,为适配将来更多的条码秤,抽象PLU的基本信息作为基类。基类为充血模型,包含了信息转报文和报文解析信息的方法。

public class BasePLU
{
    /// <summary>
    /// 商品名
    /// </summary>
    public string GoodsName { get; set; } = string.Empty;

    /// <summary>
    /// 商品序号
    /// </summary>
    public int GoodsNum { get; set; }

    /// <summary>
    /// 商品代码
    /// </summary>
    public string GoodsCode { get; set; } = string.Empty;

    /// <summary>
    /// 商品单价,元
    /// </summary>
    public double UnitPrice { get; set; }

    /// <summary>
    /// 总价
    /// </summary>
    public double TotalPrice { get; set; }

    /// <summary>
    /// 称重方式
    /// </summary>
    public EnumWeighingWay WeighingWay { get; set; }

    /// <summary>
    /// 门店号
    /// </summary>
    public string StoreCode { get; set; } = string.Empty;

    /// <summary>
    /// 皮重,KG.最大1位数+3位小数
    /// </summary>
    public double Tare { get; set; }

    /// <summary>
    /// 有效期
    /// </summary>
    public int Validity { get; set; }

    public bool CheckSuccess { get; set; }

    /// <summary>
    /// 转义成PLU报文
    /// </summary>
    /// <returns></returns>
    public virtual string ToPLU() { return null; }


    /// <summary>
    /// 从PLU报文解析成实体
    /// </summary>
    /// <param name="message"></param>
    public virtual void ConvertFromImportMessage(string message) { }
}

从PLU报文解析成实体

报文解析时有一点需要注意,报文中的商品名称包含中文,中文是传入的区域码,不能直接转换成中文。需要先将区域码转换为中文。

/// <summary>
/// 区域码转文字
/// </summary>
/// <param name="coding"></param>
/// <returns></returns>
public static string ConvertCoding2Chinese(this string coding) {
    var result = string.Empty;
    if (coding.Length % 4 != 0) {
        throw new System.Exception("编码格式不正确");
    }
    var encoding = System.Text.Encoding.GetEncoding("GB2312");
    for (int i = 0; i < coding.Length; i += 4) {
        byte[] pArray = new byte[2];
        string front = coding.Substring(i, 2);
        string back = coding.Substring(i + 2, 2);
        if ("03".Equals(front))
        {
            byte[] pArray2 = new byte[1];
            pArray2[0] = (byte)(Convert.ToInt16(back) + 32);
            result += encoding.GetString(pArray2);
        }
        else
        {
            pArray[0] = (byte)(Convert.ToInt16(front) + 160);
            pArray[1] = (byte)(Convert.ToInt16(back) + 160);
            result += encoding.GetString(pArray);
        }
    }
    return result;
}

然后重写ConvertFromImportMessage函数

/// <summary>
/// 从PLU报文解析成实体
/// </summary>
/// <param name="message">报文</param>
public override void ConvertFromImportMessage(string message)
{
    var messageContentArray = message.ToArray();
    char[] goodsNumCharArray = new char[4];
    Array.Copy(messageContentArray,3, goodsNumCharArray, 0, 4);
    this.GoodsNum = messageContentArray.SubInt32(3, 4);
    this.GoodsCode = messageContentArray.SubString(8, 7);
    this.UnitPrice = messageContentArray.SubInt32(15, 6)/100f;
    this.WeighingWay = (EnumWeighingWay)messageContentArray.SubInt32(21,1);
    this.Validity = messageContentArray.SubInt32(28, 3);
    this.StoreCode = messageContentArray.SubString(31, 2);
    this.Tare = messageContentArray.SubInt32(48, 5);
    var tempGoodsName = messageContentArray.SubString(82, message.LastIndexOf("CDE") - 82);
    this.GoodsName = tempGoodsName.ConvertCoding2Chinese();
}

转义成PLU报文

大华报文的规则不在此赘述,可以参考以下代码的注释

/// <summary>
/// 转义成PLU报文
/// </summary>
/// <returns></returns>
public override string ToPLU()
{
    var sb = new StringBuilder("!0V");// 2
    sb.Append(this.GoodsNum.ToString("0000"));//商品序号 6
    sb.Append("A");// 7
    sb.Append(this.GoodsCode.PadLeft(7,'0'));//商品代码,7位
    sb.Append(this.UnitPrice.ConvertPrice4DHPLU());//单价,6位
    sb.Append((int)this.WeighingWay);//称重方式,1位
    sb.Append("00");//特殊信息1
    sb.Append("00");//特殊信息2
    sb.Append("00");//特殊信息3
    sb.Append(this.Validity.ToString("000"));//有效期,3位
    sb.Append(this.StoreCode.PadLeft(2,'0'));//门店号,2位
    sb.Append("00");//部门号
    sb.Append("0000000000000");//数字代号
    sb.Append((this.Tare * 1000).ToString("00000"));//皮重,克
    sb.Append("00");//标签号
    sb.Append("00");//是否打折
    sb.Append("00");//第一时间段起始时间
    sb.Append("00");//第一时间段结束时间
    sb.Append("00");//第一时间段内折扣
    sb.Append("00");//第二时间段起始时间
    sb.Append("00");//第二时间段结束时间
    sb.Append("00");//第二时间段内折扣
    sb.Append("00");//第三时间段起始时间
    sb.Append("00");//第三时间段结束时间
    sb.Append("00");//第三时间段内折扣
    sb.Append("00");//第四时间段起始时间
    sb.Append("00");//第四时间段结束时间
    sb.Append("00");//第四时间段内折扣
    sb.Append("B");
    sb.Append(this.GoodsName.ConvertChinese2Coding());
    sb.Append("CDE");
    sb.Append("\r\n");

    var result = sb.ToString();
    return result;
}
posted @ 2024-07-11 10:39  烟台西炮台  阅读(7)  评论(0编辑  收藏  举报