2025-03-28 09:49:56 +08:00

207 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EShangApi.Models;
using HZQR.Common;
namespace EShangApi.Helper
{
public class ECodeHelper
{
/// <summary>
/// 生成电子码
/// </summary>
/// <param name="membershipType"></param>
/// <param name="memberShipId">会员Id</param>
/// <param name="companyId">企业Id</param>
/// <param name="isSupportPoint">是否支持积分</param>
/// <param name="couponCode">优惠券编码</param>
/// <returns>返回字符串,最终生成的电子码</returns>
public static string EncodedECode(int membershipType, int? memberShipId, int? companyId, int isSupportPoint = 0, string couponCode = "")
{
//电子码新规则,共计23位
//2位固定数+2位分钟+9位会员ID+2位小时+5位企业ID+1位固定数(标识是否支持积分)+1位随机数+1位校验码
/* 2位固定数字具体含义
* 20 企业会员电子码
* 21 驿网会员电子码
* 30 企业会员优惠券码
* 31 驿网会员优惠券码
*/
int ecodeType = 21;//默认驿网会员
Random random = new Random();//创建随机数的函数
int randNum = (int)((1 - 9) * random.NextDouble() + 9);//从1-9中产生随机数
string memberOrCouponECode = "";//会员内码或者是优惠券编码
//判断是否是优惠券码,优惠券码为空则是会员电子码
if (string.IsNullOrEmpty(couponCode))
{
//membershipType=3000,企业会员电子码,首位显示20否则驿网会员电子码,首位显示21
ecodeType = membershipType == 3000 ? 20 : 21;
memberOrCouponECode = CalculateCode(memberShipId.ToString().PadLeft(9, '0'), randNum, true);//根据随机数计算出虚拟的会员Id
}
else
{
//membershipType=3000,企业会员电子码,首位显示30否则驿网会员电子码,首位显示31
ecodeType = membershipType == 3000 ? 30 : 31; //30:企业会员优惠券码31:驿网会员优惠券码
memberOrCouponECode = CalculateCode(couponCode.PadLeft(9, '0'), randNum, true);//根据随机数计算出虚拟的优惠券编码
}
string calCompanyId = CalculateCode(companyId.ToString().PadLeft(5, '0'), randNum, true);//根据随机数计算出虚拟的企业Id
string ECode = ecodeType + DateTime.Now.Minute.ToString().PadLeft(2, '0') + //当前时间的分钟
memberOrCouponECode + DateTime.Now.Hour.ToString().PadLeft(2, '0') + calCompanyId + isSupportPoint + randNum;
int checkNum = GetCheckCode(ECode);//1校验码
ECode = ECode + checkNum;
return ECode;//返回最终的电子码
}
/// <summary>
/// 判断电子码是否有效
/// </summary>
/// <param name="ECode">会员电子码</param>
/// <returns>返回结果100电子码有效101电子码无效102电子码失效</returns>
public static Result CheckECode(string ECode)
{
Result result = new Result();
if (ECode.Length != 23)//电子码长度一定是23位
{
result.Result_Code = 101;//电子码无效
result.Result_Desc = "电子码无效";
return result;
}
string strMin = ECode.Substring(2, 2);//电子码中的第3、4位显示的分钟
string strHour = ECode.Substring(13, 2);//电子码中的第14、15位显示的分钟
DateTime eCodeTime = Convert.ToDateTime(DateTime.Now.ToShortDateString() +
" " + strHour + ":" + strMin + ":00");//生成电子码的时间
//如果生成码的时间比当前时间则表示电子码是昨天生成的
if (eCodeTime > DateTime.Now)
{
eCodeTime = eCodeTime.AddDays(-1);
}
if (DateTime.Now >= eCodeTime.AddMinutes(10))//电子码生成5分钟后则不能使用
{
result.Result_Code = 102;//超过五分钟,电子码失效
result.Result_Desc = "电子码失效";
return result;
}
return result;
}
/// <summary>
/// 电子码解码
/// 创建人zhengxp
/// 创建日期2020-08-11
/// 修改人:
/// 修改日期yyyy-mm-dd
/// 修改备注:无
/// </summary>
/// <param name="ECode">会员电子码</param>
/// <returns>返回实体对象包含MemberShipId会员IdCompanyId企业IdCouponCode优惠券编码SupportPoint是否支持积分</returns>
public static Models.ECode DecodeECode(string ECode)
{
//电子码新规则,共计23位
//2位固定数+2位分钟+9位会员ID+2位小时+5位企业ID+1位固定数(标识是否支持积分)+1位随机数+1位校验码
/* 2位固定数字具体含义
* 20 企业会员电子码
* 21 驿网会员电子码
* 30 企业会员优惠券码
* 31 驿网会员优惠券码
*/
Models.ECode ecodeModel = new Models.ECode();
string memberOrCouponECode = ECode.Substring(4, 9);//会员内码或者是优惠券编码
string subStringCompanyId = ECode.Substring(15, 5);//企业Id
int supportPoint = ECode.Substring(20, 1).TryParseToInt();//是否支持积分
int randNum = ECode.Substring(21, 1).TryParseToInt();//随机数
int EcodeType = ECode.Substring(0, 2).TryParseToInt();//电子码类型
ecodeModel.IsCompanyUser = (EcodeType == 20 || EcodeType == 30) ? true : false;//判断是否是企业会员
ecodeModel.CompanyId = CalculateCode(subStringCompanyId, randNum, false).TryParseToInt();//根据随机数计算出实际的企业ID
string _memberOrCouponECode = CalculateCode(memberOrCouponECode, randNum, false);//根据随机数计算出实际的会员ID 或者 优惠券编码
if (EcodeType == 20 || EcodeType == 21)
{
//会员Id
ecodeModel.MemberShipId = _memberOrCouponECode.TryParseToInt();
}
else
{
//优惠券编码
ecodeModel.CouponCode = _memberOrCouponECode;
}
ecodeModel.SupportPoint = supportPoint == 1 ? true : false;//是否支持积分积累
return ecodeModel;
}
/// <summary>
/// 根据随机数计算出实际的Code
/// 创建人zhengxp
/// 创建日期2020-08-11
/// 修改人:
/// 修改日期yyyy-mm-dd
/// 修改备注:无
/// </summary>
/// <param name="orgiCode">原Code</param>
/// <param name="randNum">随机数</param>
/// <param name="isAdd">是否是增加随机数,否则减去随机数</param>
/// <returns></returns>
protected static string CalculateCode(string orgiCode, int randNum, bool isAdd)
{
bool isOdd = Common.IsOdd(randNum);//判断随机数是否是偶数
string newCode = "";
char[] array = orgiCode.ToCharArray();
for (int i = 0; i < array.Length; i++)
{
//随机数是奇数,则奇数位加上随机数;随机数是偶数,则偶数位加上随机数
if (Common.IsOdd(i + 1) == isOdd)
{
if (isAdd)
{
//增加随机数,生成电子码规则用到
int Number = array[i].TryParseToInt() + randNum;
//加上随机数后>9则取个位
newCode += (Number > 9 ? (Number / 1 % 10) : Number).ToString();
}
else
{
//减去随机数,解析电子码规则用到
int Number = array[i].TryParseToInt() < randNum ? array[i].TryParseToInt() + 10 : array[i].TryParseToInt();
newCode += (Number - randNum).ToString();
}
}
else
{
//不需要加/减随机数则不变
newCode += array[i].ToString();
}
}
return newCode;
}
/// <summary>
/// 获取校验位
/// </summary>
/// <param name="code">会员电子码</param>
/// <returns></returns>
public static int GetCheckCode(string code)
{
int check = 0;
for (int i = code.Length - 1; i >= 0; i--)
{
decimal val = code.Substring(i, 1).TryParseToInt() * 2;
if ((i + 1) % 2 == 0)
{
while (val > 0)
{
check += (int)(val % 10);
val /= 10;
val = (int)(val);
}
}
else
{
check += code.Substring(i, 1).TryParseToInt();
}
}
check = 10 - check % 10;
check = check == 10 ? 0 : check;
return check;
}
}
}