'json' ]; // 追加属性 protected $append = [ 'status_text', 'charge_rate_format', 'withdraw_info_hidden', 'withdraw_info_display', 'is_madow_withdraw', 'is_money_withdraw', 'real_amount', 'withdraw_type_text', 'wechat_transfer_state_text', ]; // 微信商家转账状态 const WECHAT_TRANSFER_STATE = [ 'ACCEPTED' => '单据已受理,请稍等', 'PROCESSING' => '单据处理中,请稍等', 'SUCCESS' => '转账成功', 'FAIL' => '转账失败', 'CANCELING' => '单据撤销中', 'CANCELLED' => '单据已撤销', 'WAIT_USER_CONFIRM' => '待收款用户确认', 'TRANSFERING' => '转账中', 'NOT_FOUND' => '未申请微信提现', ]; // 可以安全退还佣金的状态 const CAN_CANCEL_STATE = [ 'FAIL', 'WAIT_USER_CONFIRM', 'CANCELLED' ]; public function statusList() { return [ -3 => '撤销提现', -2 => '提现失败', -1 => '已拒绝', 0 => '待审核', 1 => '处理中', 2 => '已处理' ]; } public function withdrawTypeList() { return [ 'wechat' => '微信零钱', 'alipay' => '支付宝账户', 'bank' => '银行卡', ]; } /** * 类型获取器 */ public function getWithdrawTypeTextAttr($value, $data) { $value = $value ?: ($data['withdraw_type'] ?? null); $list = $this->withdrawTypeList(); return isset($list[$value]) ? $list[$value] : ''; } public function getWechatTransferStateTextAttr($value, $data) { $value = $value ?: ($data['wechat_transfer_state'] ?? null); $list = self::WECHAT_TRANSFER_STATE; return isset($list[$value]) ? $list[$value] : $value; } public function getChargeRateFormatAttr($value, $data) { $rate = $value !== null && $value !== '' ? $value : ($data['charge_rate'] ?? 0); $rate = is_numeric($rate) ? (string)$rate : '0'; return function_exists('bcmul') ? (bcmul($rate, '100', 1) . '%') : (round(floatval($rate) * 100, 1) . '%'); } public function getIsMadowWithdrawAttr($value, $data) { $info = $this->withdraw_info ?? ($data['withdraw_info'] ?? null); if (is_string($info)) { $info = json_decode($info, true) ?: []; } if (!is_array($info)) { return false; } return (isset($info['wallet_type']) && $info['wallet_type'] === 'madow') || (isset($info['提现资产']) && strcasecmp($info['提现资产'], 'dmepa') === 0); } public function getIsMoneyWithdrawAttr($value, $data) { $info = $this->withdraw_info ?? ($data['withdraw_info'] ?? null); if (is_string($info)) { $info = json_decode($info, true) ?: []; } if (!is_array($info)) { return false; } return (isset($info['wallet_type']) && $info['wallet_type'] === 'money') || (isset($info['提现资产']) && in_array($info['提现资产'], ['钱包余额', '商城余额'], true)); } public function getRealAmountAttr($value, $data) { $amount = isset($data['amount']) && is_numeric($data['amount']) ? (string)$data['amount'] : (string)($this->amount ?? '0'); $chargeFee = isset($data['charge_fee']) && is_numeric($data['charge_fee']) ? (string)$data['charge_fee'] : (string)($this->charge_fee ?? '0'); $amount = is_numeric($amount) ? $amount : '0'; $chargeFee = is_numeric($chargeFee) ? $chargeFee : '0'; $real = function_exists('bcsub') ? bcsub($amount, $chargeFee, 2) : number_format(floatval($amount) - floatval($chargeFee), 2, '.', ''); return max(0, floatval($real)); } public function getWithdrawInfoDisplayAttr($value, $data) { $info = $this->withdraw_info ?? ($data['withdraw_info'] ?? null); if (is_string($info)) { $info = json_decode($info, true) ?: []; } if (!is_array($info)) { return []; } $display = []; $isMadow = (isset($info['wallet_type']) && $info['wallet_type'] === 'madow') || (isset($info['提现资产']) && strcasecmp($info['提现资产'], 'dmepa') === 0); $isMoney = (isset($info['wallet_type']) && $info['wallet_type'] === 'money') || (isset($info['提现资产']) && in_array($info['提现资产'], ['钱包余额', '商城余额'], true)); if ($isMadow) { $display['提现资产'] = 'DMEPA'; // 扣除 DMEPA $madowAmount = $info['madow_amount'] ?? ($info['扣除DMEPA'] ?? ($info['扣除dmepa'] ?? null)); if ($madowAmount !== null) { $madowClean = trim(str_ireplace(['dmepa', ' '], '', (string)$madowAmount)); $display['扣除DMEPA'] = $madowClean . ' DMEPA'; } // 市值汇率 $rate = $info['rate'] ?? ($info['市值汇率'] ?? ($info['折算汇率'] ?? null)); if ($rate !== null) { if (is_numeric($rate)) { $rateClean = rtrim(rtrim(number_format((float)$rate, 12, '.', ''), '0'), '.'); $display['市值汇率'] = '1 DMEPA ≈ ' . $rateClean . ' 元'; } else { $rateStr = (string)$rate; $rateClean = trim(str_replace(['1 DMEPA ≈', '元/dmepa', '元/DMEPA', '元', ' '], '', $rateStr)); $display['市值汇率'] = '1 DMEPA ≈ ' . $rateClean . ' 元'; } } // 换算市值 $marketValue = $info['换算市值'] ?? ($data['amount'] ?? ($this->amount ?? null)); if ($marketValue !== null) { $valClean = trim(str_replace(['元', ' '], '', (string)$marketValue)); $display['换算市值'] = number_format((float)$valClean, 2, '.', '') . ' 元'; } // 手续费与预计到账 $chargeFee = $data['charge_fee'] ?? ($this->charge_fee ?? ($info['charge_fee'] ?? 0)); $chargeRate = $data['charge_rate'] ?? ($this->charge_rate ?? ($info['charge_rate'] ?? 0)); $chargeFee = is_numeric($chargeFee) ? (string)$chargeFee : '0'; $chargeRate = is_numeric($chargeRate) ? (string)$chargeRate : '0'; if (floatval($chargeFee) > 0 || floatval($chargeRate) > 0) { $ratePercent = function_exists('bcmul') ? bcmul($chargeRate, '100', 1) : round(floatval($chargeRate) * 100, 1); $display['提现手续费'] = number_format(floatval($chargeFee), 2, '.', '') . ' 元 (' . $ratePercent . '%)'; } $amount = $data['amount'] ?? ($this->amount ?? 0); $amount = is_numeric($amount) ? (string)$amount : '0'; $real = function_exists('bcsub') ? bcsub($amount, $chargeFee, 2) : number_format(floatval($amount) - floatval($chargeFee), 2, '.', ''); $display['预计到账'] = number_format(max(0, floatval($real)), 2, '.', '') . ' 元'; } elseif ($isMoney) { $display['提现资产'] = '钱包余额'; $amount = $data['amount'] ?? ($this->amount ?? 0); $chargeFee = $data['charge_fee'] ?? ($this->charge_fee ?? 0); $amount = is_numeric($amount) ? (string)$amount : '0'; $chargeFee = is_numeric($chargeFee) ? (string)$chargeFee : '0'; $real = function_exists('bcsub') ? bcsub($amount, $chargeFee, 2) : number_format(floatval($amount) - floatval($chargeFee), 2, '.', ''); $display['预计到账'] = number_format(max(0, floatval($real)), 2, '.', '') . ' 元'; } // 填充银行卡或其它常规账户信息,并过滤英文底层键 $excludeKeys = ['wallet_type', 'madow_amount', 'rate', 'charge_fee', 'charge_rate', '提现资产', '扣除DMEPA', '扣除dmepa', '市值汇率', '折算汇率', '换算市值', '提现手续费', '预计到账']; foreach ($info as $k => $v) { if (!in_array($k, $excludeKeys)) { $display[$k] = $v; } } return $display; } public function getWithdrawInfoHiddenAttr($value, $data) { $withdraw_info = $value ?: ($this->withdraw_info ?? null); if (is_string($withdraw_info)) { $withdraw_info = json_decode($withdraw_info, true) ?: []; } if (!is_array($withdraw_info)) { return []; } foreach ($withdraw_info as $key => &$info) { if (in_array($key, ['微信用户', '真实姓名'])) { $info = string_hide($info, 2); } elseif (in_array($key, ['银行卡号', '支付宝账户', '微信ID'])) { $info = account_hide($info); } } return $withdraw_info; } public function user() { return $this->belongsTo(User::class, 'user_id', 'id')->field('id, nickname, mobile, avatar, total_consume'); } }