| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- <?php
- // +----------------------------------------------------------------------
- // | saiadmin [ saiadmin快速开发框架 ]
- // +----------------------------------------------------------------------
- namespace plugin\saiadmin\app\logic\miniProgram;
- use plugin\saiadmin\app\model\miniProgram\MiniProgramSettings;
- use plugin\saiadmin\basic\think\BaseLogic;
- use plugin\saiadmin\exception\ApiException;
- /**
- * 小程序系统设置逻辑层
- */
- class MiniProgramSettingsLogic extends BaseLogic
- {
- private const CONFIG_ID = 1;
- private const DEFAULTS = [
- 'deposit_refund' => [
- 'original_refund' => 1,
- 'refund_speed' => 'immediate',
- 'delay_hours' => 0,
- 'wallet_as_deposit' => 0,
- ],
- 'withdraw_methods' => ['wechat_qrcode'],
- 'agent_withdraw' => [
- 'review_amount' => 200,
- 'other_fee_mode' => 'fee',
- 'alipay_fee_mode' => 'tax',
- 'tax_rate' => 0.6,
- 'fee' => 0,
- 'min_amount' => 0.3,
- 'max_amount' => 500,
- 'schedule_type' => 'day',
- 'time_ranges' => [['start' => '00:00', 'end' => '24:00']],
- ],
- 'merchant_withdraw' => [
- 'review_amount' => 200,
- 'other_fee_mode' => 'tax',
- 'alipay_fee_mode' => 'tax',
- 'tax_rate' => 0.6,
- 'fee' => 0,
- 'min_amount' => 0.3,
- 'max_amount' => 500,
- 'schedule_type' => 'day',
- 'time_ranges' => [['start' => '00:00', 'end' => '24:00']],
- ],
- 'user_withdraw' => [
- 'review_amount' => 100,
- 'fee_rate' => 0,
- 'min_amount' => 0.01,
- 'max_amount' => 100,
- 'deposit_refund_mode' => 0,
- ],
- 'user_settings' => [
- 'wechat_phone_authorization' => 0,
- 'alipay_phone_authorization' => 0,
- ],
- 'membership' => [
- 'enabled' => 0,
- 'month_price' => 0,
- 'quarter_price' => 0,
- 'year_price' => 0,
- ],
- 'order_profit_detail' => 1,
- 'official_account_login' => 0,
- 'new_merchant_dd_prefix' => 0,
- ];
- public function __construct()
- {
- $this->model = new MiniProgramSettings();
- }
- public function getSettings(): array
- {
- $model = $this->model->findOrEmpty(self::CONFIG_ID);
- if ($model->isEmpty()) {
- return self::DEFAULTS;
- }
- $stored = json_decode((string) $model->getAttr('settings'), true);
- if (!is_array($stored)) {
- return self::DEFAULTS;
- }
- return $this->normalizeSettings(array_replace_recursive(self::DEFAULTS, $stored));
- }
- public function saveSettings(array $data): bool
- {
- $settings = $this->normalizeSettings($data);
- $json = json_encode($settings, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
- if ($json === false) {
- throw new ApiException('系统设置序列化失败');
- }
- $model = $this->model->findOrEmpty(self::CONFIG_ID);
- if ($model->isEmpty()) {
- return (bool) $this->model->create(['id' => self::CONFIG_ID, 'settings' => $json])->getKey();
- }
- return $model->save(['settings' => $json]) !== false;
- }
- private function normalizeSettings(array $input): array
- {
- $deposit = $this->arrayValue($input, 'deposit_refund');
- $userWithdraw = $this->arrayValue($input, 'user_withdraw');
- $userSettings = $this->arrayValue($input, 'user_settings');
- $membership = $this->arrayValue($input, 'membership');
- return [
- 'deposit_refund' => [
- 'original_refund' => $this->flag($deposit['original_refund'] ?? 1),
- 'refund_speed' => $this->enum($deposit['refund_speed'] ?? 'immediate', ['immediate', 'delayed'], '押金退回速度'),
- 'delay_hours' => (int) $this->number($deposit['delay_hours'] ?? 0, 0, 8760, '押金退款延长时间'),
- 'wallet_as_deposit' => $this->flag($deposit['wallet_as_deposit'] ?? 0),
- ],
- 'withdraw_methods' => $this->withdrawMethods($input['withdraw_methods'] ?? []),
- 'agent_withdraw' => $this->withdrawProfile($this->arrayValue($input, 'agent_withdraw'), '代理'),
- 'merchant_withdraw' => $this->withdrawProfile($this->arrayValue($input, 'merchant_withdraw'), '商家'),
- 'user_withdraw' => [
- 'review_amount' => $this->number($userWithdraw['review_amount'] ?? 100, 0, 99999999, '用户提现审核金额'),
- 'fee_rate' => $this->number($userWithdraw['fee_rate'] ?? 0, 0, 100, '用户提现手续费'),
- 'min_amount' => $this->number($userWithdraw['min_amount'] ?? 0.01, 0, 99999999, '用户提现最小金额'),
- 'max_amount' => $this->number($userWithdraw['max_amount'] ?? 100, 0, 99999999, '用户提现最大金额'),
- 'deposit_refund_mode' => $this->flag($userWithdraw['deposit_refund_mode'] ?? 0),
- ],
- 'user_settings' => [
- 'wechat_phone_authorization' => $this->flag($userSettings['wechat_phone_authorization'] ?? 0),
- 'alipay_phone_authorization' => $this->flag($userSettings['alipay_phone_authorization'] ?? 0),
- ],
- 'membership' => [
- 'enabled' => $this->flag($membership['enabled'] ?? 0),
- 'month_price' => $this->number($membership['month_price'] ?? 0, 0, 99999999, '月卡金额'),
- 'quarter_price' => $this->number($membership['quarter_price'] ?? 0, 0, 99999999, '季卡金额'),
- 'year_price' => $this->number($membership['year_price'] ?? 0, 0, 99999999, '年卡金额'),
- ],
- 'order_profit_detail' => $this->flag($input['order_profit_detail'] ?? 1),
- 'official_account_login' => $this->flag($input['official_account_login'] ?? 0),
- 'new_merchant_dd_prefix' => (int) $this->number($input['new_merchant_dd_prefix'] ?? 0, 0, 999999, '新商户 DD 规则'),
- ];
- }
- private function withdrawProfile(array $profile, string $label): array
- {
- $min = $this->number($profile['min_amount'] ?? 0.3, 0, 99999999, $label . '提现最小金额');
- $max = $this->number($profile['max_amount'] ?? 500, 0, 99999999, $label . '提现最大金额');
- if ($max < $min) {
- throw new ApiException($label . '提现最大金额不能小于最小金额');
- }
- return [
- 'review_amount' => $this->number($profile['review_amount'] ?? 200, 0, 99999999, $label . '提现审核金额'),
- 'other_fee_mode' => $this->enum($profile['other_fee_mode'] ?? 'tax', ['tax', 'fee', 'both'], $label . '其他手续费模式'),
- 'alipay_fee_mode' => $this->enum($profile['alipay_fee_mode'] ?? 'tax', ['tax', 'fee', 'both'], $label . '支付宝手续费模式'),
- 'tax_rate' => $this->number($profile['tax_rate'] ?? 0.6, 0, 100, $label . '提现税点'),
- 'fee' => $this->number($profile['fee'] ?? 0, 0, 99999999, $label . '提现手续费'),
- 'min_amount' => $min,
- 'max_amount' => $max,
- 'schedule_type' => $this->enum($profile['schedule_type'] ?? 'day', ['day', 'week', 'month'], $label . '提现时间'),
- 'time_ranges' => $this->timeRanges($profile['time_ranges'] ?? []),
- ];
- }
- private function timeRanges(mixed $ranges): array
- {
- if (!is_array($ranges) || $ranges === []) {
- return [['start' => '00:00', 'end' => '24:00']];
- }
- if (count($ranges) > 10) {
- throw new ApiException('提现时间段不能超过 10 个');
- }
- $result = [];
- foreach ($ranges as $range) {
- if (!is_array($range)) {
- throw new ApiException('提现时间段格式不正确');
- }
- $start = (string) ($range['start'] ?? '');
- $end = (string) ($range['end'] ?? '');
- if (!$this->validTime($start, false) || !$this->validTime($end, true)) {
- throw new ApiException('提现时间段必须使用 HH:mm 格式');
- }
- $result[] = ['start' => $start, 'end' => $end];
- }
- return $result;
- }
- private function validTime(string $value, bool $allowEndOfDay): bool
- {
- if ($allowEndOfDay && $value === '24:00') {
- return true;
- }
- return preg_match('/^(?:[01]\\d|2[0-3]):[0-5]\\d$/', $value) === 1;
- }
- private function withdrawMethods(mixed $methods): array
- {
- $allowed = ['bank_card', 'wechat', 'alipay', 'wechat_qrcode', 'alipay_qrcode'];
- if (!is_array($methods)) {
- return [];
- }
- return array_values(array_unique(array_intersect($allowed, array_map('strval', $methods))));
- }
- private function arrayValue(array $input, string $key): array
- {
- return isset($input[$key]) && is_array($input[$key]) ? $input[$key] : [];
- }
- private function flag(mixed $value): int
- {
- return in_array($value, [1, '1', true], true) ? 1 : 0;
- }
- private function enum(mixed $value, array $allowed, string $label): string
- {
- $value = (string) $value;
- if (!in_array($value, $allowed, true)) {
- throw new ApiException($label . '设置不正确');
- }
- return $value;
- }
- private function number(mixed $value, float $min, float $max, string $label): float
- {
- if (!is_numeric($value)) {
- throw new ApiException($label . '必须是数字');
- }
- $number = (float) $value;
- if ($number < $min || $number > $max) {
- throw new ApiException($label . '超出允许范围');
- }
- return $number;
- }
- }
|