pay_dlg.cpp 9.12 KB
// D:\GitProject\etradeclient\central_clearing_system\ETradeClient\mfc_ui\pay_dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "ETradeClient.h"
#include "D:\GitProject\etradeclient\central_clearing_system\ETradeClient\mfc_ui\pay_dlg.h"
#include "afxdialogex.h"
#include "etradeclient/hardware/hardware_cmd.h"
#include "etradeclient/boost_patch/property_tree/json_parser.hpp"
#include "ETradeClient/utility/win_msg_define.h"
#include "ETradeClient/utility/logging.h"
#include "etradeclient/utility/url_config.h"
#include "etradeclient/utility/application_config.h"
#include "etradeclient/browser/session.h"
#include "ETradeClient/utility/string_converter.h"
#include "ETradeClient/utility/win_msg_define.h"
#include <vector>
#include "pay_dlg.h"
#include "etradeclient/hardware/hardware_cmd.h"
#include "ETradeClient/utility/logging.h"
#include <sstream>


// PayDlg 对话框

IMPLEMENT_DYNAMIC(PayDlg, CDialogEx)

PayDlg::PayDlg(long statement_id, CString total_money, int card_type, CWnd* pParent /*=NULL*/)
	: CDialogEx(PayDlg::IDD, pParent)
{
	statement_id_ = statement_id;
	total_money_ = total_money;
	card_type_ = card_type;
}

PayDlg::~PayDlg()
{
}

void PayDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PAY_STATIC_TOTAL_MONEY, total_money_static_);
	DDX_Control(pDX, IDC_PAY_STATIC_REAL_MONEY, real_money_static_);
	DDX_Control(pDX, IDC_PAY_STATIC_PASSWORD, password_static_);
	DDX_Control(pDX, IDC_PAY_EDIT_PASSWORD, password_edit_);
	DDX_Control(pDX, IDC_PAY_BUTTON_PAY, pay_button_);
	DDX_Control(pDX, IDC_PAY_BUTTON_CLOSE, close_button_);
	DDX_Control(pDX, IDC_PAY_BUTTON_PASSWORD, password_button_);
	DDX_Control(pDX, IDC_STATIC_ERROR_MSG, error_msg_static_);
}


BEGIN_MESSAGE_MAP(PayDlg, CDialogEx)
	ON_BN_CLICKED(IDC_PAY_BUTTON_CLOSE, &PayDlg::OnBnClickedPayButtonClose)
	ON_BN_CLICKED(IDC_PAY_BUTTON_PAY, &PayDlg::OnBnClickedPayButtonPay)
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(IDC_PAY_BUTTON_PASSWORD, &PayDlg::OnBnClickedPayButtonPassword)
	ON_COMMAND(ID_ACCELERATOR_A, &PayDlg::OnBnClickedPayButtonPassword)
	ON_COMMAND(ID_ACCELERATOR_F, &PayDlg::OnBnClickedPayButtonPay)
	ON_COMMAND(ID_ACCELERATOR_X, &PayDlg::OnBnClickedPayButtonClose)
END_MESSAGE_MAP()


// PayDlg 消息处理程序


BOOL PayDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	SetCtrlPos();

	real_money_static_.SetWindowText(total_money_);
	if (card_type_ == 30)
	{
		password_static_.ShowWindow(SW_HIDE);
		password_edit_.ShowWindow(SW_HIDE);
		password_button_.ShowWindow(SW_HIDE);
	}
	else
	{
		password_static_.ShowWindow(SW_SHOW);
		password_edit_.ShowWindow(SW_SHOW);
		password_button_.ShowWindow(SW_SHOW);
	}

	acce_ = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR_ORDER));

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常:  OCX 属性页应返回 FALSE
}

void PayDlg::SetCtrlPos()
{
	const int StaticWidth = 80, StaticHeigth = 35;
	const int EditWidth = 140, EditHeigth = 35;
	const int EditWidthShort = 70, StaticWidthShort = 70;
	const int ButtonWidth = 120, ButtonHeight = 40;

	CRect ctrl_rect;
	ctrl_rect.top = 30 + 10;
	ctrl_rect.bottom = ctrl_rect.top + StaticHeigth;
	ctrl_rect.left = 30;
	ctrl_rect.right = ctrl_rect.left + StaticWidth;
	total_money_static_.MoveWindow(&ctrl_rect);

	ctrl_rect.left = ctrl_rect.right;
	ctrl_rect.right += StaticWidth;
	real_money_static_.MoveWindow(&ctrl_rect);

	ctrl_rect.top = ctrl_rect.bottom + 30;
	ctrl_rect.bottom = ctrl_rect.top + StaticHeigth;
	ctrl_rect.left = 30;
	ctrl_rect.right = ctrl_rect.left + StaticWidth;
	password_static_.MoveWindow(ctrl_rect);

	ctrl_rect.left = ctrl_rect.right;
	ctrl_rect.right += EditWidth;
	password_edit_.MoveWindow(&ctrl_rect);

	ctrl_rect.left = ctrl_rect.right + 10;
	ctrl_rect.right += ButtonWidth;
	password_button_.MoveWindow(&ctrl_rect);

	CRect dlg_rect;
	GetClientRect(&dlg_rect);

	ctrl_rect.top = ctrl_rect.bottom + 10;
	ctrl_rect.bottom = ctrl_rect.top + StaticHeigth;
	ctrl_rect.left = 30;
	ctrl_rect.right = dlg_rect.right - 30;
	error_msg_static_.MoveWindow(&ctrl_rect);

	
	ctrl_rect.bottom = dlg_rect.bottom - 20;
	ctrl_rect.top = ctrl_rect.bottom - ButtonHeight;
	ctrl_rect.right = dlg_rect.right - 100;
	ctrl_rect.left = ctrl_rect.right - ButtonWidth;
	close_button_.MoveWindow(&ctrl_rect);

	ctrl_rect.right = ctrl_rect.left - 100;
	ctrl_rect.left = ctrl_rect.right - ButtonWidth;
	pay_button_.MoveWindow(ctrl_rect);

	CRect rect;
	password_edit_.GetClientRect(&rect);
	OffsetRect(&rect, 0, 10);
	password_edit_.SendMessage(EM_SETRECT, 0, (LPARAM)&rect);

	password_edit_.EnableWindow(FALSE);
}

void PayDlg::OnBnClickedPayButtonClose()
{
	CDialogEx::OnCancel();
}

#include "etradeclient/hardware/hardware_cmd.h"
#include "etradeclient/boost_patch/property_tree/json_parser.hpp"
#include "ETradeClient/utility/logging.h"

void PayDlg::OnBnClickedPayButtonPay()
{
	LOG_TRACE(L"支付订单");
	CString error_msg;

	std::string statement_data;
	do
	{
		CString pass_word;
		password_edit_.GetWindowText(pass_word);
		if (card_type_ != 30)
		{
			if (pass_word.IsEmpty() || pass_word.GetLength() < 6)
			{
				SetErrorMsg(L"错误提示:密码为空或密码长度不足!");
				break;
			}
			
		}

		const uint32_t kHTTPOK = 200;
		WinHttp win_http;
		auto& url_cfg = URLConfig::Instance();
		win_http.ConnectHost(url_cfg.Host(), url_cfg.Port(), url_cfg.IsHttps());
		std::string url = url_cfg.GetFinishStatementPath();
		auto& request = win_http.OpenRequest(WinHttp::Method::JSONPOST, url);

		std::ostringstream os;
		os << statement_id_;
		std::string statement_id_str;
		std::istringstream is(os.str());
		is >> statement_id_str;

		std::string post_data = "{\"statementId\":" + statement_id_str + ",\"password\":\"" + wstr_2_str(pass_word) + "\"}";

		request.SetPostData(post_data);
		if (url_cfg.IsHttps())
		{
			auto& app_cfg = ApplicationConfig::Instance();
			request.SetClientCertificate(app_cfg.ClientCertStore(), app_cfg.ClientCertSubject());
		}
		request.SetCookies(Session::Instance().Cookies());
		request.Send();
		uint32_t status_code = request.GetResponseStatus();
		if (kHTTPOK != status_code)
		{
			std::string err_msg = "网络请求错误! 错误码: " + std::to_string(status_code);
			LOG_ERROR(CString(err_msg.c_str()).GetBuffer());
			error_msg = err_msg.c_str();
			break;
		}
		std::string response_body = request.ReadResponseBody();
		if (response_body.empty())
		{
			LOG_ERROR(L"获取服务器响应数据失败,请确保网络连接正常!");
			error_msg = CString(L"获取服务器响应数据失败,请确保网络连接正常!");
			break;
		}

		namespace PT = boost::property_tree;
		bool card_res = false;
		try //Parse the configuration file
		{
			PT::ptree ptree;
			std::stringstream ss;
			ss << response_body;
			PT::read_json(ss, ptree);
			if (ptree.get<long>("code") == 0)
			{
				PT::ptree data_child = ptree.get_child("data");
				std::ostringstream os;
				PT::write_json(os, data_child);
				CString data = str_2_wstr(std::string(os.str())).c_str();
				statement_data = CT2A(data);
			}
			else
			{
				error_msg = str_2_wstr(ptree.get<std::string>("message")).c_str();
				break;
			}

		}
		catch (...)
		{
			LOG_ERROR(L"解析服务器返回的登录结果信息时出错!请确认返回数据不为空,返回的数据格式为正确的Json格式!");
			error_msg = CString(L"解析服务器返回的登录结果信息时出错!请确认返回数据不为空,返回的数据格式为正确的Json格式!");
			break;
		}
	} while (0);

	if (!error_msg.IsEmpty())
	{
		SetErrorMsg(error_msg);
	}
	else if (!statement_data.empty())
	{
		auto printer_device = StylusPrinterCmd();
		HardwareCmd::Reply reply = printer_device.Execute(statement_data);
		CDialogEx::OnCancel();
	}
}

void PayDlg::SetErrorMsg(CString error)
{
	error_msg_static_.SetWindowTextW(error);
}


HBRUSH PayDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	if (nCtlColor == CTLCOLOR_STATIC)
	{
		if (IDC_STATIC_ERROR_MSG == pWnd->GetDlgCtrlID())
		{
			pDC->SetTextColor(RGB(200, 0, 0));
		}
	}

	return hbr;
}


void PayDlg::OnBnClickedPayButtonPassword()
{
	password_edit_.SetWindowTextW(L"");
	auto pin_pad = ReadPINPadCmd();
	HardwareCmd::Reply reply = pin_pad.Execute("");
	CString error_msg;
	do 
	{
		if (reply.error_code.compare("") != 0)
		{
			if (reply.error_code.compare("100") == 0)
			{
				error_msg = L"连接密码键盘失败";
			}
			else if (reply.error_code.compare("101") == 0)
			{
				error_msg = L"用户密码输入超时";
			}
			else if (reply.error_code.compare("102") == 0)
			{
				error_msg = L"用户取消密码输入";
			}
			else if (reply.error_code.compare("103") == 0)
			{
				error_msg = L"读取密码失败";
			}
			else
			{
				error_msg = L"读卡失败";
			}
			std::wstring log = L"支付时输入密码错误,错误码:" + str_2_wstr(reply.error_code);
			LOG_ERROR(log);
			break;
		}

		boost::property_tree::ptree password_child = reply.data.get_child("password");
		std::string password = password_child.data();
		password_edit_.SetWindowText(CString(password.c_str()));
	} while (0);
	if (!error_msg.IsEmpty())
	{
		SetErrorMsg(error_msg);
		password_edit_.SetWindowTextW(L"");
	}
	else
	{
		SetErrorMsg(CString(L""));
	}
}


BOOL PayDlg::PreTranslateMessage(MSG* pMsg)
{
	if (WM_KEYFIRST <= pMsg->message&&pMsg->message <= WM_KEYLAST)
	{
		if (acce_ && ::TranslateAccelerator(m_hWnd, acce_, pMsg))
			return TRUE;
	}

	return CDialogEx::PreTranslateMessage(pMsg);
}