You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

508 lines
20 KiB
C#

using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using DevComponents.DotNetBar.SuperGrid;
using NLog;
using POSV.Card;
using POSV.Entity;
using POSV.Helper;
using POSV.PayApi;
using POSV.ShoppingCart;
using POSV.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace POSV.Member
{
public partial class GiftSaomaCheckoutForm : BusinessForm
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
public decimal PayMoney = 0.00M;
/// <summary>
/// 支付渠道
/// </summary>
private PayChannelEnum _payChannel = PayChannelEnum.;
private string outTradeNo = null;
private string CardNo = null;
public GiftSaomaCheckoutForm(string cardNo ,decimal amount)
{
InitializeComponent();
this.controlBox.Text = "扫码支付核销";
this.controlBox.ShowApplicationVersion = false;
this.PayMoney = amount;
this.CardNo = cardNo;
}
private PayMode CurrentPayMode = null;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.DesignMode) return;
this.Focus();
this.txtReChargeNo.Focus();
this.txtReChargeNo.SelectAll();
this.ActiveControl = this.txtReChargeNo;
QueryTicket();
}
private void OnCloseTouchClick(object sender, EventArgs e)
{
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
//再关闭当前窗体
this.Close();
}
private void BtnQuery(object sender, EventArgs e)
{
QueryTicket();
}
private void QueryTicket()
{
string orderNo = this.txtReChargeNo.Text;
List<SaomaPayTicket> listPay = getSaomaPayTicket(orderNo);
foreach (SaomaPayTicket saomaPayTicket in listPay)
{
if (saomaPayTicket.PayStatus == 0)
{
saomaPayTicket.OrderStatus = "未核销";
}
else if (saomaPayTicket.PayStatus == 1)
{
saomaPayTicket.OrderStatus = "核销成功";
}
}
payListTable.PrimaryGrid.DataSource = listPay;
}
public List<SaomaPayTicket> getSaomaPayTicket(string orderNo)
{
List<SaomaPayTicket> list = null;
try
{
using (var db = Global.Instance.OpenDataBase)
{
StringBuilder sqlBuld = new StringBuilder();
sqlBuld.Append(" select * ");
sqlBuld.Append(" from pos_saoma_pay_ticket ");
sqlBuld.Append(" where busType =2 ");
if (orderNo != null && !"".Equals(orderNo))
{
sqlBuld.Append(" and orderNo like '%" + orderNo + "%' ");
}
sqlBuld.Append(" and storeId ='{0}' and shiftNo = '{1}' ");
sqlBuld.Append(" order by createDate desc ");
string sql = string.Format(sqlBuld.ToString(), Global.Instance.BusinessPlanLog.StoreId, Global.Instance.BusinessPlanLog.No);
list = db.Query<SaomaPayTicket>(sql).ToList();
}
}
catch (Exception ex)
{
LOGGER.Error(ex);
}
if (list == null)
{
list = new List<SaomaPayTicket>();
}
return list;
}
private void BtnCheck(object sender, EventArgs e)
{
var row = this.payListTable.ActiveRow as GridRow;
if (row == null)
{
this.ShowToastNotify(this, "请选择要核销的数据");
return;
}
var money = StringUtils.GetDecimal(row.Cells["money"].Value.ToString());
if (this.PayMoney != money)
{
this.ShowToastNotify(this, "要核销的金额和充值金额不一致");
return;
}
var orderNo = row.Cells["orderNo"].Value.ToString();
var authCode = row.Cells["authCode"].Value.ToString();
this.CurrentPayMode = RechargeSaomaUtils.GetPayMode(authCode).Item3;
if (this.CurrentPayMode == null)
{
this.ShowToastNotify(this, "支付码不合法或尚未适配...");
return;
}
bool paymentVerify = RechargeSaomaUtils.VerifyInputValue(authCode, this.CurrentPayMode).Item1;
if (!paymentVerify)
{
this.ShowToastNotify(this, "支付渠道获取失败,请检查后台配置");
return;
}
this._payChannel = RechargeSaomaUtils.VerifyInputValue(authCode, this.CurrentPayMode).Item3;
switch (this._payChannel)
{
case PayChannelEnum.:
{
switch (this.CurrentPayMode.No)
{
case "04":
{
QueryAliPayResult(orderNo);
}
break;
case "05":
{
QueryWxPayResult(orderNo);
}
break;
}
}
break;
}
}
private void BtnClose(object sender, EventArgs e)
{
OnCloseTouchClick(sender, e);
}
#region 原生微信支付渠道查询
/// <summary>
/// 微信支付结果查询
/// </summary>
private void QueryWxPayResult(string orderNo)
{
try
{
var parameter = this.CurrentPayMode.Body;
string appId = parameter.ContainsKey("appid") ? parameter["appid"].ToString() : "";
string mchId = parameter.ContainsKey("mchid") ? parameter["mchid"].ToString() : "";
string subMchId = parameter.ContainsKey("submchid") ? parameter["submchid"].ToString() : "";
string key = parameter.ContainsKey("appsecret") ? parameter["appsecret"].ToString() : "";
string nonceStr = "x86" + ObjectId.GenerateNewStringId();
var dataInfo = new WxPayV3OrderQueryRequestData(appId, "", mchId, subMchId, "", nonceStr, orderNo, key);
var result = WxPayV3.OrderQuery(dataInfo);
if ("SUCCESS".Equals(result.return_code))
{
if ("SUCCESS".Equals(result.result_code))
{
var tradeState = WxPayTradeState.NONE;
Enum.TryParse(result.trade_state, out tradeState);
switch (tradeState)
{
case WxPayTradeState.SUCCESS:
{
this.ShowToastNotify(this, "微信支付成功,正在进行销售处理");
//先查询状态再发起充值
DoQuery(orderNo);
}
break;
case WxPayTradeState.USERPAYING:
{
this.ShowToastNotify(this, "未查询到订单是否支付成功,请再次确认");
}
break;
case WxPayTradeState.NOTPAY:
case WxPayTradeState.PAYERROR:
{
this.ShowToastNotify(this, "密码错误或未输入,微信支付失败");
}
break;
default:
break;
}
}
else
{
this.ShowToastNotify(this, "未查询到订单是否支付成功,请再次确认");
}
}
else
{
LOGGER.Warn("查询支付结果网络通信错误:{0}", result.return_msg);
this.ShowToastNotify(this, result.return_msg);
}
}
catch (Exception ex)
{
this.ShowToastNotify(this, "微信支付结果查询发生异常,请再次确认");
LOGGER.Error(ex, "微信支付结果查询发生异常");
}
}
#endregion
#region 原生支付宝渠道查询
/// <summary>
/// 支付宝支付结果查询
/// </summary>
/// <param name="OutTradeNo"></param>
private void QueryAliPayResult(string orderNo)
{
try
{
var parameter = this.CurrentPayMode.Body;
string appId = parameter.ContainsKey("appid") ? parameter["appid"].ToString() : "";
string privateKey = parameter.ContainsKey("privatekey") ? parameter["privatekey"].ToString() : "";
string appAuthToken = parameter.ContainsKey("appAuthToken") ? parameter["appAuthToken"].ToString() : "";
string storeNo = parameter.ContainsKey("storeNo") ? parameter["storeNo"].ToString() : "";
string signType = parameter.ContainsKey("signType") ? parameter["signType"].ToString() : "RSA";
DefaultAopClient client = null;
if ("RSA2".Equals(signType))
{
client = new DefaultAopClient(Global.Instance.AliPayServerUrl, appId, privateKey, "json", "utf-8", "RSA2");
}
else
{
client = new DefaultAopClient(Global.Instance.AliPayServerUrl, appId, privateKey, false);
}
var request = new AlipayTradeQueryRequest();
var content = new Dictionary<string, object>();
content.Add("out_trade_no", orderNo);
request.BizContent = JsonUtils.Serialize(content);
AlipayTradeQueryResponse response = client.Execute(request, string.Empty, appAuthToken);
switch (response.TradeStatus)
{
case "TRADE_SUCCESS":
{
//发送消息通知显示文本
this.ShowToastNotify(this, "支付宝付款成功,正在进行销售处理");
//先查询状态再发起充值
DoQuery(orderNo);
}
break;
case "WAIT_BUYER_PAY":
{
this.ShowToastNotify(this, "等待买家付款,未查询到支付成功过状态");
}
break;
default:
{
this.ShowToastNotify(this, "等待买家付款,未查询到支付成功过状态");
}
break;
}
}
catch (Exception ex)
{
this.ShowToastNotify(this, "支付宝结果查询发生异常");
LOGGER.Error(ex, "支付宝结果查询发生异常");
}
}
#endregion
/// <summary>
/// 查询核销
/// </summary>
/// <param name="cardRecharge"></param>
public void DoQuery(string orderNo)
{
try
{
lock (Global.Instance.SyncLock)
{
using (var db = Global.Instance.OpenDataBase)
{
using (var transaction = db.GetTransaction())
{
//先查询本地支付记录是否已经核销
string querySql = "select * from pos_card_sale where busNo = '{0}'";
querySql = string.Format(querySql, orderNo.Split('_')[1]);
CardSale cardSale = db.FirstOrDefault<CardSale>(querySql);
//如果插入扫码支付记录
if (cardSale != null)
{
logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......开始", orderNo);
string sql = "update pos_saoma_pay_ticket set payStatus =1 where orderNo = '{0}'";
sql = string.Format(sql, orderNo);
db.Execute(sql, null);
transaction.Complete();
logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......更新成功", orderNo);
this.ShowToastNotify(this, string.Format("支付核销成功,本地订单号[{0}]已结算成功", orderNo));
return;
}
else {
transaction.Complete();
logger.Info("单号:[{0}]不存在,进行核销业务", orderNo);
}
}
}
}
}
catch (Exception ex)
{
LOGGER.Error(ex);
}
DoSale(orderNo, this.PayMoney);
}
public void DoSale(string payVoucherNo, decimal SaleAmount)
{
try
{
this.outTradeNo = payVoucherNo;
var request = new SaleGiftCardRecordRequest();
request.CardNo = this.CardNo;
request.SaleAmount = SaleAmount;
request.PayTypeNo = this.CurrentPayMode.No;
request.PayType = this.CurrentPayMode.Name;
request.PayVoucherNo = payVoucherNo;
request.ShopNo = Global.Instance.Authc.StoreNo;
request.PosNo = Global.Instance.Authc.PosNo;
request.WorkerNo = Global.Instance.Worker.No;
var response = CardUtils.SaleGiftCardRecord(request);
//成功
if (response.Item1)
{
SaleGiftCardRecordResponse saleGiftCardRecordResponse = response.Item3.Data;
this.ShowToastNotify(this, response.Item2);
SaveSaleTickt(request, saleGiftCardRecordResponse);
}
else
{
this.ShowToastNotify(this, response.Item2);
}
}
catch (Exception ex)
{
this.ShowToastNotify(this, "礼品卡销售异常");
LOGGER.Error(ex, "礼品卡销售异常");
}
}
public void SaveSaleTickt(SaleGiftCardRecordRequest request, SaleGiftCardRecordResponse response)
{
string busNo = this.outTradeNo.Split('_')[1];
CardSale entity = new CardSale();
entity.Id = IdWorkerUtils.Instance.NextId();
entity.TenantId = Global.Instance.BusinessPlanLog.TenantId;
entity.StoreId = Global.Instance.BusinessPlanLog.StoreId;
entity.StoreNo = Global.Instance.BusinessPlanLog.StoreNo;
entity.StoreName = Global.Instance.Authc.StoreName;
entity.WorkerId = Global.Instance.BusinessPlanLog.WorkerId;
entity.WorkerName = Global.Instance.BusinessPlanLog.WorkerName;
entity.WorkerNo = Global.Instance.BusinessPlanLog.WorkerNo;
entity.PosNo = Global.Instance.Authc.PosNo;
entity.ShiftName = Global.Instance.BusinessPlanLog.Name;
entity.ShiftNo = Global.Instance.BusinessPlanLog.No;
entity.PlanNo = response.SchemeNo;
entity.PlanName = response.SchemeName;
entity.CardNo = response.CardNo;
entity.BusNo = busNo;
entity.TicketNo = response.TicketNo;
entity.PayStatus = 1;//付款成功
entity.AuthCode = "";
entity.RetailPrice = response.RetailPrice;
entity.RealAmount = response.RealAmount;
entity.Money = request.SaleAmount;
string data = JsonUtils.Serialize(request);
entity.RequestMessage = data;
List<CardSalePay> pay = new List<CardSalePay>();
CardSalePay cardSalePay = new CardSalePay();
cardSalePay.Amount = request.SaleAmount;
cardSalePay.TicketId = entity.Id;
cardSalePay.PayName = this.CurrentPayMode.Name;
cardSalePay.PayNo = this.CurrentPayMode.No;
cardSalePay.TenantId = Global.Instance.BusinessPlanLog.TenantId;
cardSalePay.VoucherNo = this.outTradeNo;
cardSalePay.Id = IdWorkerUtils.Instance.NextId();
cardSalePay.PayChannel = this._payChannel;
pay.Add(cardSalePay);
entity.Pay = pay;
try
{
lock (Global.Instance.SyncLock)
{
using (var db = Global.Instance.OpenDataBase)
{
using (var transaction = db.GetTransaction())
{
logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......开始", this.outTradeNo);
string sql = "update pos_saoma_pay_ticket set payStatus =1 where orderNo = '{0}'";
sql = string.Format(sql, this.outTradeNo);
db.Execute(sql, null);
logger.Info("单号:[{0}]保存礼品卡销售订单......开始", entity.BusNo);
// 保存主单数据
db.Save<CardSale>(entity);
// 保存支付明细
List<CardSalePay> detail = entity.Pay;
if (detail != null && detail.Count > 0)
{
foreach (CardSalePay detailEntity in detail)
{
db.Save<CardSalePay>(detailEntity);
}
}
transaction.Complete();
logger.Info("单号:[{0}]保存礼品卡销售订单......成功", entity.BusNo);
}
}
}
}
catch (Exception ex)
{
LOGGER.Error(ex);
}
//成功以后打印
this.ShowToastNotify(this, "开始打印");
//构建收银小票模版参数打印
var vars = CardHelper.BuilderGiftCardVariable(request, response, false,false);
//现金充值开钱箱
bool openCashbox = false;
if ("01".Equals(request.PayTypeNo))
{
openCashbox = true;
}
//充值打印份数
int ticketCount = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_RECHARGE_COUNT, 1);
//打印延迟
int delaySecond = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_CARD_PRINT_DELAY, 1);
//执行收银小票打印
Tuple<bool, string> result = CardHelper.PrinterTicket("礼品卡销售", vars, true, openCashbox, ticketCount, delaySecond);
this.ShowToastNotify(this, string.Format("{0}", result.Item2));
//打开提示界面
var form = new GiftCardResultForm(request, response);
form.ShowDialog();
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
//再关闭当前窗体
this.Close();
}
}
}