feat(withdraw): DMEPA提现手续费与最小提现额度配置收敛至商城配置页面并实现内扣闭环

1. 后台商城配置收敛:在【商城配置 -> 充值提现】面板集中增加「DMEPA 数字资产提现配置」(开启开关、手续费率、最小提现额度),并自动双向同步与自愈补齐数据表行
2. 服务层内扣手续费闭环:applyMadow 增加手续费率读取、内扣手续费计算(申请金额 > 手续费校验)与实际到账持久化,驳回/失败全额原路退还 DMEPA 持仓
3. API 与前台联动:rules() 与 madow() 接口返回手续费率,withdraw.vue 实时动态计算扣除 DMEPA 枚数、手续费内扣金额与预计到账金额
4. 后台列表与导出优化:提现管理列表与导出功能支持展示换算市值、手续费与到账金额
5. 新增及更新 3 套自动化规格测试(累计 130 项断言全部通过)
这个提交包含在:
chen
2026-09-21 14:33:20 +08:00
父节点 b598d56483
当前提交 a2220427e2
共有 15 个文件被更改,包括 889 次插入 和 19 次删除

查看文件

@@ -197,7 +197,7 @@ class Config extends Common
'partner_show_madow_rate',
'partner_madow_base_rate', 'partner_madow_step_orders',
'partner_madow_rule_title', 'partner_madow_rules',
'partner_madow_withdraw_enable', 'partner_madow_withdraw_min',
'partner_madow_withdraw_enable', 'partner_madow_withdraw_min', 'partner_madow_withdraw_charge_rate',
'partner_voucher_times', 'partner_voucher_days',
'partner_voucher_rule_title', 'partner_voucher_rules',
'partner_maker_bonus', 'partner_maker_peer_rate',
@@ -238,6 +238,7 @@ class Config extends Common
'partner_show_madow_rate' => 1,
'partner_madow_withdraw_enable' => 1,
'partner_madow_withdraw_min' => 1,
'partner_madow_withdraw_charge_rate' => 0,
'partner_madow_base_rate' => '0.00000075',
'partner_madow_step_orders' => 1,
'partner_voucher_times' => 1.5,
@@ -266,6 +267,7 @@ class Config extends Common
$configs['partner_show_madow_rate'] = isset($configs['partner_show_madow_rate']) ? intval($configs['partner_show_madow_rate']) : 1;
$configs['partner_madow_withdraw_enable'] = isset($configs['partner_madow_withdraw_enable']) ? intval($configs['partner_madow_withdraw_enable']) : 1;
$configs['partner_madow_withdraw_min'] = isset($configs['partner_madow_withdraw_min']) ? floatval($configs['partner_madow_withdraw_min']) : 1.0;
$configs['partner_madow_withdraw_charge_rate'] = isset($configs['partner_madow_withdraw_charge_rate']) ? floatval($configs['partner_madow_withdraw_charge_rate']) : 0.0;
foreach (['partner_madow_rules', 'partner_voucher_rules'] as $ruleKey) {
if (isset($configs[$ruleKey]) && is_string($configs[$ruleKey])) {
$decoded = json_decode($configs[$ruleKey], true);
@@ -292,6 +294,9 @@ class Config extends Common
if (isset($save['partner_madow_withdraw_min'])) {
$save['partner_madow_withdraw_min'] = max(0.0, floatval($save['partner_madow_withdraw_min']));
}
if (isset($save['partner_madow_withdraw_charge_rate'])) {
$save['partner_madow_withdraw_charge_rate'] = max(0.0, floatval($save['partner_madow_withdraw_charge_rate']));
}
// 确保数据库存在 partner_show_madow_rate 配置行
$existConfig = ShoproConfig::where('code', 'shop.commission.partner_show_madow_rate')->find();
if (!$existConfig) {
@@ -309,6 +314,7 @@ class Config extends Common
$ensureConfigs = [
'shop.commission.partner_madow_withdraw_enable' => ['name' => '开启dmepa提现', 'desc' => '1=开启 0=关闭', 'type' => 'int', 'value' => '1', 'weigh' => 86],
'shop.commission.partner_madow_withdraw_min' => ['name' => 'dmepa最低提现金额', 'desc' => 'dmepa最低提现金额(元)', 'type' => 'number', 'value' => '1', 'weigh' => 86],
'shop.commission.partner_madow_withdraw_charge_rate' => ['name' => 'dmepa提现手续费率', 'desc' => 'dmepa提现手续费率(%)', 'type' => 'number', 'value' => '0', 'weigh' => 86],
'shop.commission.partner_madow_rule_title' => ['name' => 'dmepa规则弹窗标题', 'desc' => '我的dmepa市值规则弹窗标题', 'type' => 'string', 'value' => '市值与增值规则', 'weigh' => 86],
'shop.commission.partner_madow_rules' => ['name' => 'dmepa规则说明条目', 'desc' => '我的dmepa市值规则条目', 'type' => 'array', 'value' => json_encode($ruleDefaults['partner_madow_rules'], JSON_UNESCAPED_UNICODE), 'weigh' => 86],
'shop.commission.partner_voucher_rule_title' => ['name' => '兑换券规则弹窗标题', 'desc' => '兑换券规则弹窗标题', 'type' => 'string', 'value' => '兑换券释放与使用规则', 'weigh' => 89],
@@ -411,6 +417,29 @@ class Config extends Common
} else {
$configs['withdraw']['status'] = intval($configs['withdraw']['status']);
}
// 读取 DMEPA 专属提现配置(优先提现配置,降级兼容合伙股东历史配置)
$partnerEnable = ShoproConfig::getConfigField('shop.commission.partner_madow_withdraw_enable', false);
$partnerMin = ShoproConfig::getConfigField('shop.commission.partner_madow_withdraw_min', false);
$partnerChargeRate = ShoproConfig::getConfigField('shop.commission.partner_madow_withdraw_charge_rate', false);
if (!isset($configs['withdraw']['madow_withdraw_enable']) || $configs['withdraw']['madow_withdraw_enable'] === '') {
$configs['withdraw']['madow_withdraw_enable'] = ($partnerEnable !== null && $partnerEnable !== '') ? intval($partnerEnable) : 1;
} else {
$configs['withdraw']['madow_withdraw_enable'] = intval($configs['withdraw']['madow_withdraw_enable']);
}
if (!isset($configs['withdraw']['madow_min_amount']) || $configs['withdraw']['madow_min_amount'] === '') {
$configs['withdraw']['madow_min_amount'] = ($partnerMin !== null && $partnerMin !== '') ? floatval($partnerMin) : 1.0;
} else {
$configs['withdraw']['madow_min_amount'] = floatval($configs['withdraw']['madow_min_amount']);
}
if (!isset($configs['withdraw']['madow_charge_rate']) || $configs['withdraw']['madow_charge_rate'] === '') {
$configs['withdraw']['madow_charge_rate'] = ($partnerChargeRate !== null && $partnerChargeRate !== '') ? floatval($partnerChargeRate) : 0.0;
} else {
$configs['withdraw']['madow_charge_rate'] = floatval($configs['withdraw']['madow_charge_rate']);
}
}
} elseif ('POST' === $this->request->method()) {
$params = $this->request->param();
@@ -428,7 +457,38 @@ class Config extends Common
} else {
$params['withdraw']['status'] = intval($params['withdraw']['status']);
}
if (isset($params['withdraw'])) {
if (isset($params['withdraw']['madow_withdraw_enable'])) {
$params['withdraw']['madow_withdraw_enable'] = intval($params['withdraw']['madow_withdraw_enable']);
}
if (isset($params['withdraw']['madow_charge_rate'])) {
$params['withdraw']['madow_charge_rate'] = max(0.0, floatval($params['withdraw']['madow_charge_rate']));
}
if (isset($params['withdraw']['madow_min_amount'])) {
$params['withdraw']['madow_min_amount'] = max(0.0, floatval($params['withdraw']['madow_min_amount']));
}
}
$configs = ShoproConfig::setConfigs('shop.recharge_withdraw', $params);
// 双向同步合伙股东配置项,确保老服务读取与全链路向后兼容
if (isset($params['withdraw']['madow_withdraw_enable'])) {
ShoproConfig::setConfigs('shop.commission', [
'partner_madow_withdraw_enable' => $params['withdraw']['madow_withdraw_enable']
]);
}
if (isset($params['withdraw']['madow_charge_rate'])) {
ShoproConfig::setConfigs('shop.commission', [
'partner_madow_withdraw_charge_rate' => $params['withdraw']['madow_charge_rate']
]);
}
if (isset($params['withdraw']['madow_min_amount'])) {
ShoproConfig::setConfigs('shop.commission', [
'partner_madow_withdraw_min' => $params['withdraw']['madow_min_amount']
]);
}
if ($configs && isset($configs['withdraw'])) {
$configs['withdraw']['status'] = isset($configs['withdraw']['status']) ? intval($configs['withdraw']['status']) : (!empty($configs['withdraw']['methods']) ? 1 : 0);
}