delphi_postjson

unit YSL_ConsumeIntf;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdHTTP, IdHashMessageDigest, superobject;

type
  TConsume = record
    cardSnr: string;          //卡序列号
    clientTradeCode: string;  //随机码
    consumeMoney: Double;     //消费金额
    consumeBusinessSourceType: Integer;  //传9
    placeId: Integer;          //场所编号(配置一下,测试环境随便)
    placeName: string;        //场所名称(配置一下,测试环境随便)
    sourceUser: string;       //操作员(配置一下,测试环境使用gzy)
    sign: string;             //签名
  end;

type
  TRetConsume = record
    corpCode: string;
    cardInfoId: string;       //卡ID
    clientTradeCode: string;  //客户端交易号
    consumeMoney: Double;     //消费金额
    leftMoney: Double;        //剩余金额
    cardSnr: string;          //卡序列号
  end;

function Post_YSLConsume(cardSnr: string; consumeMoney: Double; var leftMoney: Double): Boolean;

implementation

function MyReadIniItem(const Section, Item, IniFileName, DefaultValue: string): string;
var
  Value: string;
begin
  SetLength(Value, 3001 * sizeof(Char));
  GetPrivateProfileString(PChar(Section), PChar(Item), '', PChar(Value), 3000, PChar(ExtractFilePath(Paramstr(0)) + IniFileName));
  SetLength(Value, StrLen(PChar(Value)));
  if Trim(Value) <> '' then
    Result := Value
  else
    Result := DefaultValue;
end;

procedure MyWriteLog(const mStr: string);
var
  f: textfile;
  myDir, myFileName: string;
  FileHandle: Integer;
  LogType, LogDate, ModuleID: string;
begin
  LogType := 'INFO';
  LogDate := FormatDateTime('YYYY-MM-DD hh:nn:ss zzz', Now);
  ModuleID := '';
//  if not (CanLogFile in FLogFlags) then exit;
  //------写入文件部分的实现--开始
  myDir := ExtractFilePath(Paramstr(0));
  //确定文件名称
  myFileName := FormatDateTime('"YSLConsumeIntf"yyyymmdd".log"', Date);
  //如果可执行目录下不存在log目录创建之
  if not DirectoryExists(myDir + '\log') then
    CreateDir(myDir + '\log');
  //如果当日日志文件不存在,则创建文件并释放句柄
  if not FileExists(myDir + '\log\' + myFileName) then
  begin
    FileHandle := FileCreate(myDir + '\log\' + myFileName); //创建文件
    FileClose(FileHandle); //释放句柄
  end;
  try//try...except...statements
    AssignFile(f, myDir + '\log\' + myFileName);
    Append(f);
    Writeln(f, '$$' + Format('%6s', [LogType]) + '$$ ' + Format('%12s', [ModuleID]) + '$$' + LogDate + chr(9) + mStr);
    Flush(f);
    CloseFile(f);
    //-----写入文件部分的实现--结束
  except//try...except...statements
  end; //try...except...statements
end;

function ret_mymd5(const sVaule: string): string;
var
  mymd5: TIdHashMessageDigest5;
begin
  try
    mymd5 := TIdHashMessageDigest5.Create;
    Result := LowerCase(mymd5.AsHex(mymd5.HashValue(sVaule)));
  finally
    mymd5.Free;
  end;
end;

function getContent(AConsume: TConsume; privateKey: string): string;
var
  i: Integer;
  lv_sTmp: string;
  lv_List: TStringList;
begin
  Result := '';
  try
    lv_List := TStringList.Create;
    try
      if Trim(AConsume.cardSnr) <> '' then
        lv_List.Add('cardSnr=' + AConsume.cardSnr);
      if Trim(AConsume.clientTradeCode) <> '' then
        lv_List.Add('clientTradeCode=' + AConsume.clientTradeCode);
      if Length(FloatToStr(AConsume.consumeMoney)) > 0 then
        lv_List.Add('consumeMoney=' + FloatToStr(AConsume.consumeMoney));
      if Length(IntToStr(AConsume.consumeBusinessSourceType)) > 0 then
        lv_List.Add('consumeBusinessSourceType=' + IntToStr(AConsume.consumeBusinessSourceType));
      if Length(IntToStr(AConsume.placeId)) > 0 then
        lv_List.Add('placeId=' + IntToStr(AConsume.placeId));
      if Trim(AConsume.placeName) <> '' then
        lv_List.Add('placeName=' + AConsume.placeName);
      if Trim(AConsume.sourceUser) <> '' then
        lv_List.Add('sourceUser=' + AConsume.sourceUser);

      lv_List.Sorted := False;
      lv_List.CaseSensitive := True;    //此句设置排序大小写敏感
      lv_List.Sort;                     //最后进行sort排序

      //累加字符串
      for i := 0 to lv_List.Count - 1 do
        lv_sTmp := lv_sTmp + lv_List.Strings[i] + '&';

      lv_sTmp := Copy(lv_sTmp, 1, Length(lv_sTmp) - 1) + privateKey;
      MyWriteLog('[组合签名字符串]' + lv_sTmp);
      Result := lv_sTmp;
    finally
      FreeAndNil(lv_List);
    end;
  except
    on e: Exception do
    begin
      MyWriteLog('[组合签名字符串]异常:' + e.Message);
      Exit;
    end;
  end;
end;

function getSing(AConsume: TConsume; privateKey: string): string;
var
  lv_sTmp: string;
begin
  try
    lv_sTmp := ret_mymd5(getContent(AConsume, privateKey));
    MyWriteLog('[生成签名结果]' + lv_sTmp);
    Result := lv_sTmp;
  except
    on e: Exception do
    begin
      MyWriteLog('[获取签名]异常:' + e.Message);
      Exit;
    end;
  end;
end;

function doHttpPost(const aUrl, aJson: string): string;
var
  IDHttp: TIdHTTP;
  requestBody: TStringStream;
begin
  Result := EmptyStr;
  try
    try
      IDHttp := TIdHTTP.Create(nil);
      IDHttp.Request.ContentType := 'application/json';
      IDHttp.HTTPOptions := IDHttp.HTTPOptions + [hoKeepOrigProtocol]; //必须有这行才使设置协议版本生效
      IDHttp.ProtocolVersion := pv1_1;
      requestBody := TStringStream.Create(aJson);
      Result := AnsiLowerCase(Utf8ToAnsi(IDHttp.Post(aUrl, requestBody)));
    except
      on e: Exception do
      begin
        MyWriteLog('[POST]接口请求异常!' + e.Message);
        Exit;
      end;
    end;
  finally
    freeandnil(IDHttp);
    freeandnil(requestBody);
  end;
end;

function Record2Json_TConsume(AConsume: TConsume): string;
var
  lv_sTmp: string;
begin
  try
    lv_sTmp := '{';
    lv_sTmp := lv_sTmp + '"cardSnr":"' + AConsume.cardSnr + '",';
    lv_sTmp := lv_sTmp + '"clientTradeCode":"' + AConsume.clientTradeCode + '",';
    lv_sTmp := lv_sTmp + '"consumeMoney":"' + FloatToStr(AConsume.consumeMoney) + '",';
    lv_sTmp := lv_sTmp + '"consumeBusinessSourceType":"' + IntToStr(AConsume.consumeBusinessSourceType) + '",';
    lv_sTmp := lv_sTmp + '"placeId":"' + IntToStr(AConsume.placeId) + '",';
    lv_sTmp := lv_sTmp + '"placeName":"' + AConsume.placeName + '",';
    lv_sTmp := lv_sTmp + '"sourceUser":"' + AConsume.sourceUser + '",';
    lv_sTmp := lv_sTmp + '"sign":"' + AConsume.sign + '"}';
    Result := lv_sTmp;
  except
    on e: Exception do
    begin
      MyWriteLog('[组合消费Json字符串]异常:' + e.Message);
      Exit;
    end;
  end;
end;

function getGUID(): string;
var
  lv_sTmp: string;
  AGUID: TGUID;
begin
  try
    CreateGUID(AGUID);
    lv_sTmp := StringReplace(GUIDToString(AGUID),'-','',[rfReplaceAll]);
    lv_sTmp := StringReplace(lv_sTmp,'{','',[rfReplaceAll]);
    lv_sTmp := StringReplace(lv_sTmp,'}','',[rfReplaceAll]);
    Result := lv_sTmp;
  except
    on e: Exception do
    begin
      MyWriteLog('[生成GUID随机码]异常:' + e.Message);
      Exit;
    end;
  end;
end;

function AnalysisRetString(sRetJsonString: string; var ARetConsume: TRetConsume; var leftMoney: Double): Boolean;
var
  JSO: ISuperObject;
begin
  Result := False;
  try
    if sRetJsonString = '' then
    begin
      MyWriteLog('[解析返回信息]字符串为空,退出!');
      Exit;
    end;

    JSO := SO(sRetJsonString);
    if JSO.O['status'] = nil then
    begin
      MyWriteLog('[解析返回信息]status为空,退出!');
      Result := False;
      Exit;
    end
    else
    begin
      if JSO.O['status'].AsInteger <> 200 then
      begin
        MyWriteLog('[解析返回信息]status非成功200标识,退出!');
        Result := False;
        Exit;
      end;

      if JSO.O['data'].O['corpcode'] <> nil then
        ARetConsume.corpCode := JSO.O['data'].O['corpcode'].AsString;
      if JSO.O['data'].O['cardinfoid'] <> nil then
        ARetConsume.cardInfoId := JSO.O['data'].O['cardinfoid'].AsString;
      if JSO.O['data'].O['clienttradecode'] <> nil then
        ARetConsume.clientTradeCode := JSO.O['data'].O['clienttradecode'].AsString;
      if JSO.O['data'].O['consumemoney'] <> nil then
        ARetConsume.consumeMoney := JSO.O['data'].O['consumemoney'].AsDouble;
      if JSO.O['data'].O['leftmoney'] <> nil then
        ARetConsume.leftMoney := JSO.O['data'].O['leftmoney'].AsDouble;
      if JSO.O['data'].O['cardsnr'] <> nil then
        ARetConsume.cardSnr := JSO.O['data'].O['cardsnr'].AsString;

      leftMoney := ARetConsume.leftMoney;
      Result := True;
    end;
  except
    on e: Exception do
    begin
      MyWriteLog('[解析返回信息]异常:' + e.Message);
      Exit;
    end;
  end;
end;

function Post_YSLConsume(cardSnr: string; consumeMoney: Double; var leftMoney: Double): Boolean;
var
  AConsume: TConsume;
  ARetConsume: TRetConsume;
  lv_sUrl,lv_sRetString,lv_sTmp: string;
begin
  Result := False;
  leftMoney := 0;
  try
    MyWriteLog('-------------------[消费]--------------------');
    MyWriteLog('传入参数:cardSnr=' + cardSnr + ',consumeMoney=' + FloatToStr(consumeMoney));
    FillMemory(@AConsume, SizeOf(TConsume), Byte(#0));
    FillMemory(@ARetConsume, SizeOf(TRetConsume), Byte(#0));
    AConsume.cardSnr := cardSnr;
    AConsume.clientTradeCode := getGUID();
    AConsume.consumeMoney := consumeMoney;
    AConsume.consumeBusinessSourceType := 9;
    AConsume.placeId := StrToIntDef(MyReadIniItem('Location','LocationCode','YSLConsume.Ini',''),0);
    AConsume.placeName := MyReadIniItem('Location','LocationName','YSLConsume.Ini','');
    AConsume.sourceUser := MyReadIniItem('User','OperatorCode','YSLConsume.Ini','');
    AConsume.sign := getSing(AConsume, MyReadIniItem('Key','PrivateKey','YSLConsume.Ini',''));
    lv_sUrl := MyReadIniItem('Url','Url_Consume','YSLConsume.Ini','');
    lv_sTmp := Record2Json_TConsume(AConsume);
    MyWriteLog('提交Url:' + lv_sUrl+ ', 参数:' + lv_sTmp);
    lv_sRetString := doHttpPost(lv_sUrl,lv_sTmp);
    MyWriteLog('返回信息:' + lv_sRetString);
    Result := AnalysisRetString(lv_sRetString,ARetConsume,leftMoney);
    MyWriteLog('-------------------[消费]--是否成功:' + BoolToStr(Result,True) + ',剩余金额:' + FloatToStr(leftMoney) + '元------------------');
  except
    on e: Exception do
    begin
      MyWriteLog('[消费接口]异常:' + e.Message);
      Exit;
    end
  end;
end;

end.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值