359 lines
11 KiB
C#
359 lines
11 KiB
C#
using AllBase;
|
||
using AllBase.Extension;
|
||
using AllBase.Model.Result;
|
||
using AllBase.Model.Result.WXResult;
|
||
using NaiBa.Util.Extension;
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Drawing.Printing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using TemuKJD.BaseForms;
|
||
using TemuKJD.Extension;
|
||
using Work;
|
||
using Work.Api;
|
||
using Work.BLL.Tools;
|
||
|
||
namespace TemuKJD.WXForms.ShopForms
|
||
{
|
||
/// <summary>
|
||
/// 商户(OEM)提现管理:
|
||
/// 上半部分:账户统计(可提现总额 / 历史累计返利 / 历史累计提现) + 申请提现(上传收款二维码图片);
|
||
/// 下半部分:已申请的提现记录列表(DataGridView 绑定方式,参考 WXAdminOemWithdrawal)。
|
||
/// 接口约定(与后台 user/* 系列一致):
|
||
/// user/oem_withdrawal_summary → data: { withdrawable_amount(分), total_rebate(分), total_withdrawn(分) }
|
||
/// user/oem_withdrawal_apply → 参数 amount(分) / withdrawal_type / qrcode_base64
|
||
/// user/oem_withdrawals → 分页返回提现记录列表
|
||
/// </summary>
|
||
public partial class WXShopOemWithdrawalForm : BaseForms.BaseGeneralForm
|
||
{
|
||
private BindingList<WXOemWithdrawalInfo> dataList = new BindingList<WXOemWithdrawalInfo>();
|
||
|
||
/// <summary>收款二维码图片(base64)</summary>
|
||
private string qrCodeBase64 = "";
|
||
|
||
public WXShopOemWithdrawalForm()
|
||
{
|
||
InitializeComponent();
|
||
InitBindingDataGridView();
|
||
this.cmbType.SelectedIndex = 0;
|
||
}
|
||
|
||
#region 提现记录列表(DataGridView 绑定方式)
|
||
/// <summary>
|
||
/// 初始化 DataGridView 绑定:列与模型字段绑定(参考 WXAdminOemWithdrawal.InitBindingDataGridView)
|
||
/// </summary>
|
||
private void InitBindingDataGridView()
|
||
{
|
||
this.dgvWithdrawal.AutoGenerateColumns = false;
|
||
|
||
this.colNo.DataPropertyName = nameof(WXOemWithdrawalInfo.withdrawal_no);
|
||
this.colAmount.DataPropertyName = nameof(WXOemWithdrawalInfo.amount);
|
||
this.colType.DataPropertyName = nameof(WXOemWithdrawalInfo.withdrawal_type_string);
|
||
this.colAccount.DataPropertyName = nameof(WXOemWithdrawalInfo.account_no);
|
||
this.colStatus.DataPropertyName = nameof(WXOemWithdrawalInfo.status_string);
|
||
this.colApplyTime.DataPropertyName = nameof(WXOemWithdrawalInfo.created_at);
|
||
this.colAuditRemark.DataPropertyName = nameof(WXOemWithdrawalInfo.audit_remark);
|
||
this.colAuditTime.DataPropertyName = nameof(WXOemWithdrawalInfo.audit_time);
|
||
this.colPayTradeNo.DataPropertyName = nameof(WXOemWithdrawalInfo.pay_trade_no);
|
||
|
||
// 时间列格式化
|
||
this.colApplyTime.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
|
||
this.colAuditTime.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
|
||
|
||
// 金额列右对齐
|
||
this.colAmount.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
|
||
|
||
// 注册金额格式化事件(分→元)
|
||
this.dgvWithdrawal.CellFormatting += DgvWithdrawal_CellFormatting;
|
||
|
||
this.dgvWithdrawal.DataSource = dataList;
|
||
}
|
||
|
||
private void DgvWithdrawal_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
|
||
{
|
||
// 金额列:将分转换为元
|
||
if (e.ColumnIndex == this.colAmount.Index && e.Value != null && e.Value != DBNull.Value)
|
||
{
|
||
if (long.TryParse(e.Value.ToString(), out long amountInFen))
|
||
{
|
||
e.Value = (amountInFen / 100m).ToString("F2");
|
||
e.FormattingApplied = true;
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 数据加载
|
||
private void WXShopOemWithdrawalForm_VisibleChanged(object sender, EventArgs e)
|
||
{
|
||
if (this.Visible && first)
|
||
{
|
||
first = false;
|
||
RefreshAll();
|
||
}
|
||
}
|
||
|
||
bool first = true;
|
||
|
||
/// <summary>
|
||
/// 刷新账户统计 + 提现记录
|
||
/// </summary>
|
||
private void RefreshAll()
|
||
{
|
||
LoadSummary();
|
||
GetWithdrawals(ucSplitPage1.CurrentPage);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载账户统计:可提现总额 / 历史累计返利 / 历史累计提现
|
||
/// </summary>
|
||
public void LoadSummary()
|
||
{
|
||
this.btnRefreshBalance.Enabled = false;
|
||
Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
var url = BaseClass.BuildObjString("user/oem_settle_flows");
|
||
var obj = UserLogin.GetSignPostData(new { });
|
||
string data = JsonHelper.SerializeObject(obj);
|
||
var html = GetHtml.PostUtf8(url, data);
|
||
var ret = JsonConvert.DeserializeObject<Result<oemflowsStatistics>>(html);
|
||
Invoke(new Action(() =>
|
||
{
|
||
if (ret.Code != 200)
|
||
{
|
||
BaseMsgForm.ShowError("刷新失败:" + ret.Msg);
|
||
return;
|
||
}
|
||
|
||
this.lblWithdrawable.Text = (ret.Data.available_balance / 100m).ToString("F2");
|
||
this.lblTotalRebate.Text = (ret.Data.total_rebate_amount / 100m).ToString("F2");
|
||
this.lblTotalWithdrawn.Text = (ret.Data.total_withdraw_amount / 100m).ToString("F2");
|
||
}));
|
||
}
|
||
finally
|
||
{
|
||
Invoke(new Action(() => this.btnRefreshBalance.Enabled = true));
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 加载提现记录(分页)
|
||
/// </summary>
|
||
public void GetWithdrawals(int page)
|
||
{
|
||
this.pbLoading.Visible = true;
|
||
this.dgvWithdrawal.Rows.Clear();
|
||
dataList.Clear();
|
||
int pageSize = this.ucSplitPage1.PageSize;
|
||
Task.Run(() =>
|
||
{
|
||
int pageCount;
|
||
decimal seconds;
|
||
List<WXOemWithdrawalInfo> list = GetOemWithdrawals(out pageCount, out seconds, page, pageSize);
|
||
|
||
Invoke(new Action(() =>
|
||
{
|
||
this.ucSplitPage1.TotalPage = pageCount;
|
||
list.ForEach(a => dataList.Add(a));
|
||
this.pbLoading.Visible = false;
|
||
this.statusBar.lblTaskStatus.Text = "提现记录查询完毕";
|
||
#if DEBUG
|
||
this.statusBar.lblTaskStatus.Text += ",耗时:" + seconds;
|
||
#endif
|
||
}));
|
||
});
|
||
}
|
||
|
||
public List<WXOemWithdrawalInfo> GetOemWithdrawals(out int pageCount, out decimal seconds, int page = 1, int pageSize = 200)
|
||
{
|
||
List<WXOemWithdrawalInfo> list = new List<WXOemWithdrawalInfo>();
|
||
pageCount = 1;
|
||
seconds = 0;
|
||
|
||
var url = BaseClass.BuildObjString("user/oem_withdrawals");
|
||
var obj = UserLogin.GetSignPostData(new
|
||
{
|
||
page = page,
|
||
page_size = pageSize
|
||
});
|
||
|
||
string data = JsonHelper.SerializeObject(obj);
|
||
var html = GetHtml.PostUtf8(url, data);
|
||
var ret = JsonConvert.DeserializeObject<PageResult<WXOemWithdrawalInfo>>(html);
|
||
if (ret.Code != 200)
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
BaseMsgForm.ShowError("提现记录获取失败,请重试!" + ret.Msg);
|
||
}));
|
||
return list;
|
||
}
|
||
|
||
|
||
seconds = BaseRegex.GetDecimalJson(ref html, "seconds");
|
||
pageCount = Math.Ceiling(1.0 * ret.Total / pageSize).ParseToInt();
|
||
pageCount = Math.Max(pageCount, 1);
|
||
|
||
return ret.Data;
|
||
}
|
||
#endregion
|
||
|
||
#region 事件
|
||
/// <summary>刷新可提现总额等账户统计</summary>
|
||
private void btnRefreshBalance_Click(object sender, EventArgs e)
|
||
{
|
||
LoadSummary();
|
||
}
|
||
|
||
/// <summary>选择收款二维码图片</summary>
|
||
private void btnSelectImage_Click(object sender, EventArgs e)
|
||
{
|
||
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||
openFileDialog.Multiselect = false;
|
||
openFileDialog.Filter = "图片文件 (*.jpeg;*.jpg;*.png;*.bmp)|*.jpeg;*.jpg;*.png;*.bmp|All files (*.*)|*.*";
|
||
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
||
return;
|
||
|
||
try
|
||
{
|
||
using (Image imageSource = Image.FromFile(openFileDialog.FileName))
|
||
{
|
||
using (MemoryStream memoryStream = new MemoryStream())
|
||
{
|
||
// 统一转成 jpg 压缩后提交,避免原图过大
|
||
Image image = new Bitmap(imageSource);
|
||
image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||
image.Dispose();
|
||
byte[] imageBytes = memoryStream.ToArray();
|
||
qrCodeBase64 = Convert.ToBase64String(imageBytes);
|
||
}
|
||
this.pictureBoxQr.Image = new Bitmap(imageSource);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
qrCodeBase64 = "";
|
||
this.pictureBoxQr.Image = Properties.Resources.nopic;
|
||
BaseMsgForm.ShowError("打开二维码图片失败 " + ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>提交提现申请</summary>
|
||
private void btnSubmit_Click(object sender, EventArgs e)
|
||
{
|
||
decimal amountYuan = this.numAmount.Value;
|
||
if (amountYuan <= 0)
|
||
{
|
||
BaseMsgForm.ShowError("请输入提现金额!");
|
||
return;
|
||
}
|
||
if (string.IsNullOrEmpty(qrCodeBase64))
|
||
{
|
||
BaseMsgForm.ShowError("请先上传收款二维码图片!");
|
||
return;
|
||
}
|
||
|
||
if (BaseMsgForm.ShowConfirm("确定提交提现申请?提现金额:" + amountYuan.ToString("F2") + " 元", "提示").DialogResult != DialogResult.OK)
|
||
return;
|
||
|
||
this.btnSubmit.Enabled = false;
|
||
try
|
||
{
|
||
// 金额(元) → 分
|
||
long amountFen = (long)(amountYuan * 100m);
|
||
// 提现方式:1银行卡 2支付宝 3微信 4其他
|
||
int withdrawalType = GetWithdrawalType(this.cmbType.Text);
|
||
|
||
string data = "";
|
||
var obj = UserLogin.GetSignPostData(new
|
||
{
|
||
amount = amountFen,
|
||
withdrawal_type = withdrawalType,
|
||
account_no = qrCodeBase64,
|
||
});
|
||
data = JsonHelper.SerializeObject(obj);
|
||
//data.Append(UserLogin.GetSignaturex());
|
||
//data.Append("&amount=" + amountFen);
|
||
//data.Append("&withdrawal_type=" + withdrawalType);
|
||
//data.Append("&qrcode_base64=" + GetHtml.UrlEncodeUtf8(qrCodeBase64));
|
||
|
||
var url = BaseClass.BuildObjString("user/apply_oem_withdrawal");
|
||
string html = GetHtml.PostUtf8(url, data.ToString());
|
||
var ret = JsonConvert.DeserializeObject<Result>(html);
|
||
|
||
if (ret.Code != 200)
|
||
{
|
||
BaseMsgForm.ShowError("提现申请提交失败:" + ret.Msg);
|
||
return;
|
||
}
|
||
|
||
BaseMsgForm.ShowInfo("提现申请提交成功!");
|
||
|
||
// 提交成功后:清空输入、刷新统计与记录
|
||
this.numAmount.Value = 0;
|
||
this.qrCodeBase64 = "";
|
||
this.pictureBoxQr.Image = Properties.Resources.nopic;
|
||
RefreshAll();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
BaseMsgForm.ShowError("提现申请提交异常:" + ex.Message);
|
||
}
|
||
finally
|
||
{
|
||
this.btnSubmit.Enabled = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 提现方式名称 → 类型值:1银行卡 2支付宝 3微信 4其他
|
||
/// </summary>
|
||
private static int GetWithdrawalType(string typeName)
|
||
{
|
||
switch (typeName)
|
||
{
|
||
case "支付宝": return 2;
|
||
case "银行卡": return 1;
|
||
case "其他": return 4;
|
||
default: return 3; // 微信收款
|
||
}
|
||
}
|
||
|
||
private void ucSplitPage1_PageChange(object obj)
|
||
{
|
||
GetWithdrawals(ucSplitPage1.CurrentPage);
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
class oemflowsStatistics
|
||
{
|
||
/// <summary>
|
||
/// 当前可提现
|
||
/// </summary>
|
||
public long available_balance { get; set; }
|
||
/// <summary>
|
||
/// 历史累计返利
|
||
/// </summary>
|
||
public long total_rebate_amount { get; set; }
|
||
/// <summary>
|
||
/// 历史累计提现
|
||
/// </summary>
|
||
public long total_withdraw_amount { get; set; }
|
||
}
|
||
}
|