第二次更新
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 企油通配置读取
|
||||
// +----------------------------------------------------------------------
|
||||
// | 三层来源,从低到高:
|
||||
// | 1. config/qyt.php —— 读 .env,含【密钥】与接口域名(接入方级)
|
||||
// | 2. 后台「企油通对接设置」—— yoshop_store_setting.key='qyt'(接入方级默认值)
|
||||
// | 3. 企业信息 —— yoshop_qyt_enterprise(企业级:执照号 / 通道 / 机构号 …)
|
||||
// |
|
||||
// | 分级依据见《企油通接口对接文档.md》:appId 与 RSA 密钥属于「接入方(慧明)」,
|
||||
// | 一个 appId 下可挂多个企业;business_license、passageway、institution_id 是企业级。
|
||||
// |
|
||||
// | 敏感项(private_key、platform_public_key)只从 .env 读,任何一层都不能覆盖,
|
||||
// | 数据库备份 / SQL 注入 / 后台账号失窃都拿不到签名私钥。
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\enum\Setting as SettingEnum;
|
||||
use app\common\model\qyt\Enterprise as EnterpriseModel;
|
||||
use think\facade\Db;
|
||||
|
||||
class QytConfig
|
||||
{
|
||||
/** 常驻进程内缓存有效期(秒):后台改完最迟这么久生效 */
|
||||
const TTL = 10;
|
||||
|
||||
/** 后台设置可覆盖的接入方级标量项 */
|
||||
const OVERRIDABLE = [
|
||||
'base_url', 'app_id', 'no_prefix', 'voucher_name',
|
||||
'h5_base_url', 'h5_app_id', 'consume_notify_url',
|
||||
];
|
||||
|
||||
/** @var array|null */
|
||||
protected static $cache = null;
|
||||
|
||||
/** @var int */
|
||||
protected static $cacheAt = 0;
|
||||
|
||||
/**
|
||||
* 接入方级配置(不含任何企业信息)
|
||||
*/
|
||||
public static function get(): array
|
||||
{
|
||||
if (self::$cache !== null && (time() - self::$cacheAt) < self::TTL) {
|
||||
return self::$cache;
|
||||
}
|
||||
|
||||
$conf = (array) config('qyt');
|
||||
$db = static::dbValues();
|
||||
|
||||
foreach (self::OVERRIDABLE as $k) {
|
||||
if (isset($db[$k]) && trim((string) $db[$k]) !== '') {
|
||||
$conf[$k] = trim((string) $db[$k]);
|
||||
}
|
||||
}
|
||||
// 日志开关是布尔,0 是合法值,不能用非空判断
|
||||
if (isset($db['log'])) {
|
||||
$conf['log'] = (bool) $db['log'];
|
||||
}
|
||||
|
||||
self::$cache = $conf;
|
||||
self::$cacheAt = time();
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* 叠加企业级参数,得到某个企业实际使用的完整配置
|
||||
*
|
||||
* @param EnterpriseModel|array $enterprise
|
||||
* @return array 额外带 enterprise_id / enterprise_name / passageway_code / require_id_card
|
||||
*/
|
||||
public static function forEnterprise($enterprise): array
|
||||
{
|
||||
$conf = self::get();
|
||||
$e = $enterprise instanceof EnterpriseModel ? $enterprise->toArray() : (array) $enterprise;
|
||||
|
||||
$passageway = (string) ($e['passageway'] ?? 'alipay');
|
||||
!isset(EnterpriseModel::PASSAGEWAY_CODE[$passageway]) && $passageway = 'alipay';
|
||||
|
||||
$conf['enterprise_id'] = (int) ($e['enterprise_id'] ?? 0);
|
||||
$conf['enterprise_name'] = (string) ($e['company_name'] ?? '');
|
||||
$conf['business_license'] = (string) ($e['business_license'] ?? '');
|
||||
$conf['passageway'] = $passageway;
|
||||
$conf['passageway_code'] = EnterpriseModel::PASSAGEWAY_CODE[$passageway];
|
||||
$conf['passageway_name'] = EnterpriseModel::PASSAGEWAY_NAME[$passageway];
|
||||
$conf['institution_id'] = (string) ($e['institution_id'] ?? '');
|
||||
// 平安银行通道要求实名
|
||||
$conf['require_id_card'] = $passageway === 'pingan';
|
||||
|
||||
// 以下留空则回落接入方级默认值
|
||||
foreach (['app_id', 'no_prefix', 'voucher_name'] as $k) {
|
||||
$v = trim((string) ($e[$k] ?? ''));
|
||||
$v !== '' && $conf[$k] = $v;
|
||||
}
|
||||
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取单项,支持点号:QytConfig::item('h5_base_url')
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function item(string $path, $default = null)
|
||||
{
|
||||
$node = self::get();
|
||||
foreach (explode('.', $path) as $seg) {
|
||||
if (!is_array($node) || !array_key_exists($seg, $node)) {
|
||||
return $default;
|
||||
}
|
||||
$node = $node[$seg];
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/** 清掉进程内缓存(单元测试 / 后台保存后使用) */
|
||||
public static function flush(): void
|
||||
{
|
||||
self::$cache = null;
|
||||
self::$cacheAt = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读后台设置。直接查表而不用 Setting 模型,是因为常驻命令行进程里
|
||||
* BaseModel::$storeId 不会被初始化(只有 store/api 模块才赋值),
|
||||
* 走模型会查不到数据。本项目为单商城部署,取 store_id 最小的一条即可。
|
||||
*/
|
||||
protected static function dbValues(): array
|
||||
{
|
||||
try {
|
||||
$json = Db::name('store_setting')
|
||||
->where('key', SettingEnum::QYT)
|
||||
->order('store_id', 'asc')
|
||||
->value('values');
|
||||
if (empty($json)) {
|
||||
return [];
|
||||
}
|
||||
$arr = json_decode((string) $json, true);
|
||||
return is_array($arr) ? $arr : [];
|
||||
} catch (\Throwable $e) {
|
||||
// 表不存在 / 库连不上时静默回落到 .env,不能因为读设置失败就中断发放
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user