123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- <?php
- // +----------------------------------------------------------------------
- // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
- // +----------------------------------------------------------------------
- // | Author: 萤火科技 <admin@yiovo.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\common\model;
- use cores\BaseModel;
- use cores\exception\BaseException;
- use think\facade\Cache;
- use think\model\relation\BelongsTo;
- use app\common\library\helper;
- use app\common\model\PaymentTemplate as PaymentTemplateModel;
- use app\common\enum\Client as ClientEnum;
- use app\common\enum\payment\Method as PaymentMethodEnum;
- /**
- * 模型类:支付方式记录
- * Class Payment
- * @package app\common\model
- */
- class Payment extends BaseModel
- {
- // 定义表名
- protected $name = 'payment';
- // 定义主键
- protected $pk = 'payment_id';
- /**
- * 关联支付模板记录表
- * @return BelongsTo
- */
- public function template(): BelongsTo
- {
- return $this->belongsTo('PaymentTemplate');
- }
- /**
- * 获取器:其他选项
- * @param $value
- * @return array
- */
- public function getOthersAttr($value): array
- {
- return helper::jsonDecode($value);
- }
- /**
- * 修改器:其他选项
- * @param $value
- * @return string
- */
- public function setOthersAttr($value): string
- {
- return helper::jsonEncode($value);
- }
- /**
- * 支付方式详情
- * @param int $paymentId
- * @return static|array|null
- */
- public static function detail(int $paymentId)
- {
- return self::get($paymentId);
- }
- /**
- * 获取支付方式配置
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\DataNotFoundException
- */
- public static function getAll(int $storeId): array
- {
- // 实例化当前模型
- $model = new static;
- // 默认的支付方式数据
- $defaultData = $model->defaultData();
- if (!$data = Cache::get("payment_{$storeId}")) {
- // 获取所有支付方式
- $data = $model->dataByStorage($storeId, $defaultData);
- // 写入缓存中
- Cache::tag('cache')->set("payment_{$storeId}", $data);
- }
- return static::resetOptions($defaultData, $data);
- }
- /**
- * 获取指定客户端的支付方式
- * @param string $client
- * @param int $storeId
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public static function getItem(string $client, int $storeId): array
- {
- return static::getAll($storeId)[$client];
- }
- /**
- * 重组缓存数据 (多维)
- * @param array $defaultData
- * @param array $data
- * @return array
- */
- private static function resetOptions(array $defaultData, array $data): array
- {
- $data = \resetOptions($defaultData, $data);
- foreach ($data as &$item) {
- $item['methods'] = array_values($item['methods']);
- }
- return $data;
- }
- /**
- * 获取所有支付方式 (从数据库中)
- * @param int $storeId
- * @param array $defaultData
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- private function dataByStorage(int $storeId, array $defaultData): array
- {
- // 获取数据库中所有的支付方式
- $list = $this->where('store_id', '=', $storeId)->select();
- if ($list->isEmpty()) {
- return [];
- }
- // 客户端标识合集
- $clientKeys = helper::getArrayColumn($defaultData, 'client');
- // 整理数据格式
- $data = [];
- $listArr = $list->toArray();
- foreach ($clientKeys as $client) {
- $listAsClient = $this->listAsClient($listArr, $client);
- $methods = empty($listAsClient) ? [] : $this->buildMethods($client, $listAsClient);
- if (!empty($methods)) {
- $data[$client] = ['client' => $client, 'methods' => $this->buildMethods($client, $listAsClient)];
- }
- }
- return $data;
- }
- /**
- * 格式化支付方式数据 (赋值key用于合并默认数据)
- * @param string $client
- * @param array $listAsClient
- * @return array
- */
- private function buildMethods(string $client, array $listAsClient): array
- {
- $methods = helper::getArrayColumns($listAsClient, [
- 'method', 'client', 'is_must_template', 'template_id',
- 'is_enable', 'is_default', 'others'
- ]);
- $data = [];
- foreach ($methods as $item) {
- if ($item['client'] === $client) {
- $data["$client-{$item['method']}"] = $item;
- }
- }
- return $data;
- }
- /**
- * 默认的支付方式数据
- * @return array[]
- */
- protected function defaultData(): array
- {
- $data = [
- ClientEnum::MP_WEIXIN => $this->defaultGroup(ClientEnum::MP_WEIXIN, [
- PaymentMethodEnum::WECHAT,
- PaymentMethodEnum::BALANCE,
- ]),
- ClientEnum::H5 => $this->defaultGroup(ClientEnum::H5, [
- PaymentMethodEnum::WECHAT,
- PaymentMethodEnum::ALIPAY,
- PaymentMethodEnum::BALANCE,
- ]),
- ClientEnum::WXOFFICIAL => $this->defaultGroup(ClientEnum::WXOFFICIAL, [
- // PaymentMethodEnum::WECHAT,
- PaymentMethodEnum::BALANCE,
- ]),
- ClientEnum::APP => $this->defaultGroup(ClientEnum::APP, [
- PaymentMethodEnum::WECHAT,
- PaymentMethodEnum::ALIPAY,
- PaymentMethodEnum::BALANCE,
- ]),
- ];
- return $data;
- }
- /**
- * 默认的支付客户端分组
- * @param string $client
- * @param array $designated
- * @return array
- */
- private function defaultGroup(string $client, array $designated): array
- {
- return [
- 'client' => $client,
- 'name' => ClientEnum::getName($client),
- 'desc' => '在' . ClientEnum::getName($client) . '付款时使用',
- 'methods' => $this->defaultMethods($client, $designated)
- ];
- }
- /**
- * 默认的methods数据
- * @param string $client
- * @param array $designated
- * @return array
- */
- private function defaultMethods(string $client, array $designated): array
- {
- $record = [
- 'key' => 1,
- 'method' => PaymentMethodEnum::WECHAT, // 支付方式
- 'is_must_template' => true, // 是否必须使用模板
- 'template_id' => 0, // 模板ID
- 'is_enable' => false, // 是否启用该支付方式
- 'is_default' => false, // 是否为默认支付方式
- 'others' => [] // 其他配置
- ];
- $defaultMethods = [];
- foreach ($designated as $key => $method) {
- $defaultMethods["{$client}-{$method}"] = array_merge($record, [
- 'key' => $key + 1,
- 'method' => $method,
- 'is_must_template' => $method != PaymentMethodEnum::BALANCE,
- 'is_enable' => $method == PaymentMethodEnum::BALANCE,
- ]);
- }
- return $defaultMethods;
- }
- /**
- * 根据client过滤list
- * @param array $listArr
- * @param string $client
- * @return array|iterable
- */
- private function listAsClient(array $listArr, string $client)
- {
- $listAsClient = helper::arrayFilterAsVal($listArr, 'client', $client);
- foreach ($listAsClient as &$item) {
- $item['is_must_template'] = (bool)$item['is_must_template'];
- $item['is_enable'] = (bool)$item['is_enable'];
- $item['is_default'] = (bool)$item['is_default'];
- }
- return $listAsClient;
- }
- /**
- * 根据指定客户端获取可用的支付方式
- * @param string $client 客户端来源
- * @param bool $balance 是否支持余额支付
- * @param int|null $storeId 商城ID
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws BaseException
- */
- public function getMethodsByClient(string $client, bool $balance = true, int $storeId = null): array
- {
- $storeId = $storeId ?: self::$storeId;
- $group = static::getItem($client, $storeId);
- $methods = [];
- foreach ($group['methods'] as $method) {
- if ($method['is_enable'] && ($balance || $method['method'] !== PaymentMethodEnum::BALANCE)) {
- $methods[] = $method;
- }
- }
- if (empty($methods)) {
- throwError('很抱歉,当前没有可用的支付方式,请检查后台支付设置');
- }
- return $methods;
- }
- /**
- * 获取指定的支付方式及模板
- * @param string $method 支付方式
- * @param string $client 客户端来源
- * @param int|null $storeId 商城ID
- * @return bool|mixed
- * @throws BaseException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function getPaymentInfo(string $method, string $client, int $storeId = null)
- {
- // 获取当前指定的支付方式
- $methodInfo = $this->getCurrentMethod($method, $client, $storeId);
- // 获取支付模板信息
- $methodInfo['template'] = !$methodInfo['is_must_template'] ? [] : $this->getTemplateInfo($methodInfo['template_id']);
- return $methodInfo;
- }
- /**
- * 获取支付模板
- * @param int $templateId 支付模板ID
- * @return array
- * @throws BaseException
- */
- private function getTemplateInfo(int $templateId): array
- {
- return (new PaymentTemplateModel)->getTemplateInfo($templateId);
- }
- /**
- * 获取当前指定的支付方式
- * @param string $method 指定的支付方式
- * @param string $client 客户端来源
- * @param int|null $storeId 商城ID
- * @return bool|mixed
- * @throws BaseException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- private function getCurrentMethod(string $method, string $client, int $storeId = null)
- {
- $methods = $this->getMethodsByClient($client, true, $storeId);
- $method = helper::arraySearch($methods, 'method', $method);
- if (empty($method)) {
- throwError('很抱歉,当前未找到指定的支付方式');
- }
- return $method;
- }
- }
|