CaiWuXiTong/app/Models/Business/StoreReceivingAccount.php
92451 c424ffffce fix: calculate withdrawal compliance from dated amounts
按余额减提现金额与预留标准计算达标状态,并接入提现金额日期化导入。
Co-authored-by: 92451 <924518135@qq.com>
Co-committed-by: 92451 <924518135@qq.com>
2026-09-24 19:34:09 +08:00

311 lines
9.2 KiB
PHP

<?php
namespace App\Models\Business;
use App\Abstracts\Model;
class StoreReceivingAccount extends Model
{
private const META_PREFIX = '__srmj:';
private const META_COMPRESSED_PREFIX = '__srmz:';
private const META_KEYS = [
'shop_name' => 'n',
'store_status' => 's',
'original_store_entity' => 'o',
'account_status' => 'a',
'payment_password' => 'p',
'payment_verification_method' => 'v',
'financial_account' => 'f',
'financial_password' => 'w',
'payment_verification_method_secondary' => 'x',
'bank_card_last_four' => 'b',
'store_id' => 'i',
'source_platform' => 'r',
'withdrawal_amount' => 'm',
'withdrawal_balance_date' => 'd',
];
protected $table = 'business_store_receiving_accounts';
protected $fillable = [
'company_id', 'store_platform', 'store_name', 'wallet_number', 'store_entity_name',
'login_account', 'login_password', 'receiving_method', 'receiving_account_name',
'alipay_or_bank_account', 'opening_bank',
'erp_store_name', 'shop_name', 'store_status', 'original_store_entity', 'account_status',
'payment_password', 'payment_verification_method', 'financial_account', 'financial_password',
'payment_verification_method_secondary', 'withdrawal_path', 'withdrawal_account_name',
'bank_card_last_four', 'store_id', 'source_platform',
'withdrawal_amount', 'withdrawal_balance_date',
];
protected $casts = [
'company_id' => 'integer',
];
public static function columnLabels(): array
{
return [
'store_platform' => '店铺平台',
'store_name' => '店铺名称',
'wallet_number' => '钱包号',
'store_entity_name' => '店铺主体名称',
'login_account' => '登录账号',
'login_password' => '登录密码',
'receiving_method' => '收款方式',
'receiving_account_name' => '收款账户名称',
'alipay_or_bank_account' => '支付宝或银行卡账号',
'opening_bank' => '开户行',
];
}
/**
* Extra account fields are kept in the existing nullable opening_bank
* column as a compact JSON payload so this feature does not require a
* shared-database schema migration. Core account fields remain in their
* original columns and are never exposed through the payload.
*/
public function getErpStoreNameAttribute(): ?string
{
return $this->attributes['store_name'] ?? null;
}
public function setErpStoreNameAttribute($value): void
{
$this->attributes['store_name'] = $this->clean($value);
}
public function getShopNameAttribute(): ?string
{
return $this->meta('shop_name') ?: ($this->attributes['store_name'] ?? null);
}
public function setShopNameAttribute($value): void
{
$this->setMeta('shop_name', $this->clean($value));
}
public function getStoreStatusAttribute(): ?string
{
return $this->meta('store_status');
}
public function setStoreStatusAttribute($value): void
{
$this->setMeta('store_status', $this->clean($value));
}
public function getOriginalStoreEntityAttribute(): ?string
{
return $this->meta('original_store_entity');
}
public function setOriginalStoreEntityAttribute($value): void
{
$this->setMeta('original_store_entity', $this->clean($value));
}
public function getAccountStatusAttribute(): ?string
{
return $this->meta('account_status');
}
public function setAccountStatusAttribute($value): void
{
$this->setMeta('account_status', $this->clean($value));
}
public function getPaymentPasswordAttribute(): ?string
{
return $this->meta('payment_password');
}
public function setPaymentPasswordAttribute($value): void
{
$this->setMeta('payment_password', $this->clean($value));
}
public function getPaymentVerificationMethodAttribute(): ?string
{
return $this->meta('payment_verification_method');
}
public function setPaymentVerificationMethodAttribute($value): void
{
$this->setMeta('payment_verification_method', $this->clean($value));
}
public function getFinancialAccountAttribute(): ?string
{
return $this->meta('financial_account');
}
public function setFinancialAccountAttribute($value): void
{
$this->setMeta('financial_account', $this->clean($value));
}
public function getFinancialPasswordAttribute(): ?string
{
return $this->meta('financial_password');
}
public function setFinancialPasswordAttribute($value): void
{
$this->setMeta('financial_password', $this->clean($value));
}
public function getPaymentVerificationMethodSecondaryAttribute(): ?string
{
return $this->meta('payment_verification_method_secondary');
}
public function setPaymentVerificationMethodSecondaryAttribute($value): void
{
$this->setMeta('payment_verification_method_secondary', $this->clean($value));
}
public function getWithdrawalPathAttribute(): ?string
{
return $this->attributes['receiving_method'] ?? null;
}
public function setWithdrawalPathAttribute($value): void
{
$this->attributes['receiving_method'] = $this->clean($value) ?: '银行卡';
}
public function getWithdrawalAccountNameAttribute(): ?string
{
return $this->attributes['receiving_account_name'] ?? null;
}
public function setWithdrawalAccountNameAttribute($value): void
{
$this->attributes['receiving_account_name'] = $this->clean($value);
}
public function getBankCardLastFourAttribute(): ?string
{
return $this->meta('bank_card_last_four');
}
public function setBankCardLastFourAttribute($value): void
{
$this->setMeta('bank_card_last_four', $this->clean($value));
}
public function getStoreIdAttribute(): ?string
{
return $this->meta('store_id');
}
public function setStoreIdAttribute($value): void
{
$this->setMeta('store_id', $this->clean($value));
}
public function getSourcePlatformAttribute(): ?string
{
return $this->meta('source_platform');
}
public function setSourcePlatformAttribute($value): void
{
$this->setMeta('source_platform', $this->clean($value));
}
public function getWithdrawalAmountAttribute(): ?string
{
return $this->meta('withdrawal_amount');
}
public function setWithdrawalAmountAttribute($value): void
{
$this->setMeta('withdrawal_amount', $this->clean($value));
}
public function getWithdrawalBalanceDateAttribute(): ?string
{
return $this->meta('withdrawal_balance_date');
}
public function setWithdrawalBalanceDateAttribute($value): void
{
$this->setMeta('withdrawal_balance_date', $this->clean($value));
}
private function clean($value): ?string
{
$value = trim((string) $value);
return $value === '' ? null : $value;
}
private function meta(string $key): ?string
{
$payload = $this->metaPayload();
$value = $payload[$key] ?? null;
return $value === null || $value === '' ? null : (string) $value;
}
private function setMeta(string $key, ?string $value): void
{
$payload = $this->metaPayload();
if ($value === null || $value === '') {
unset($payload[$key]);
} else {
$payload[$key] = $value;
}
$compact = [];
foreach ($payload as $name => $metaValue) {
$compact[self::META_KEYS[$name] ?? $name] = $metaValue;
}
$json = $compact === [] ? null : json_encode($compact, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$encoded = $json === null ? null : self::META_PREFIX . $json;
if ($json !== null && strlen($encoded) > 191) {
$encoded = self::META_COMPRESSED_PREFIX . base64_encode(gzdeflate($json, 9));
}
if ($encoded !== null && strlen($encoded) > 191) {
throw new \InvalidArgumentException('店铺收款账户扩展字段内容过长,请精简单项内容后重试。');
}
$this->attributes['opening_bank'] = $encoded;
}
private function metaPayload(): array
{
$raw = (string) ($this->attributes['opening_bank'] ?? '');
if (str_starts_with($raw, self::META_COMPRESSED_PREFIX)) {
$decoded = base64_decode(substr($raw, strlen(self::META_COMPRESSED_PREFIX)), true);
$json = $decoded === false ? false : gzinflate($decoded);
} elseif (str_starts_with($raw, self::META_PREFIX)) {
$json = substr($raw, strlen(self::META_PREFIX));
} else {
return [];
}
$compact = is_string($json) ? json_decode($json, true) : null;
if (! is_array($compact)) {
return [];
}
$reverse = array_flip(self::META_KEYS);
$payload = [];
foreach ($compact as $name => $metaValue) {
$payload[$reverse[$name] ?? $name] = $metaValue;
}
return $payload;
}
}