webman_duanju/app/common/model/BaseModel.php

150 lines
5.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\model;
use app\common\library\DatabaseRoute;
use think\db\BaseQuery;
use think\facade\Db;
use think\facade\Log;
use support\think\Model;
use think\db\Query;
class BaseModel extends Model
{
/**
* 查询前处理数据库连接
*/
public static function findbefore($model, $where):string
{
return DatabaseRoute::getConnection($model->getTable(), $where, false);
}
/**
* 写入数据前处理数据库连接
* @param array $data 写入的数据
* @return void
*/
protected static function onBeforeInsert($data)
{
$connection = DatabaseRoute::getConnection($data->getTable(), $data, true);
print_r($connection);
$data->setConnection($connection);
}
/**
* 更新数据前处理数据库连接
* @param array $data 更新的数据
* @return void
*/
protected static function onBeforeUpdate($data)
{
$connection = DatabaseRoute::getConnection($data->getTable(), $data->getWhere(), true);
$data->setConnection($connection);
}
/**
* 从查询选项中提取分库键的值(深度解析版)
*/
private static function extractKeyFromOptions(array $options, string $keyField)
{
$dbKey = null;
// 1. 处理顶级 where 条件
if (isset($options['where'])) {
$dbKey = static::parseWhereCondition($options['where'], $keyField);
if ($dbKey !== null) return $dbKey;
}
// 2. 处理 whereOr 条件
if (isset($options['whereOr'])) {
$dbKey = static::parseWhereCondition($options['whereOr'], $keyField);
if ($dbKey !== null) return $dbKey;
}
// 3. 处理软删除条件
if (isset($options['soft_delete']) && is_array($options['soft_delete'])) {
if ($options['soft_delete'][0] === $keyField) {
$dbKey = $options['soft_delete'][2] ?? null;
Log::info("条件类型3: 软删除条件中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
}
// 4. 处理字段绑定bind
if (isset($options['bind'][$keyField])) {
$dbKey = $options['bind'][$keyField];
Log::info("条件类型4: 绑定参数中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
// 5. 处理查询参数param
if (isset($options['param'][$keyField])) {
$dbKey = $options['param'][$keyField];
Log::info("条件类型5: 查询参数中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
// 6. 处理数据data- 适用于更新操作
if (isset($options['data'][$keyField])) {
$dbKey = $options['data'][$keyField];
Log::info("条件类型6: 数据中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
// 未找到分库键
Log::warning("条件解析失败: 未找到 {$keyField} 的值");
return null;
}
/**
* 解析 where 条件(处理 AND/OR 逻辑)
*/
private static function parseWhereCondition($where, string $keyField)
{
$dbKey = null;
// 处理数组形式的 where 条件
if (is_array($where)) {
foreach ($where as $index => $whereItem) {
// 1. 处理 AND/OR 逻辑分组
if (is_string($index) && in_array(strtoupper($index), ['AND', 'OR', 'NOT'])) {
Log::info("条件类型1: 发现 {$index} 逻辑分组,开始递归解析");
// 递归解析逻辑分组中的条件
$dbKey = static::parseWhereCondition($whereItem, $keyField);
if ($dbKey !== null) {
Log::info("条件类型1: {$index} 分组中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
} // 2. 处理 ['user_id', '=', 123] 形式
elseif (is_array($whereItem) && count($whereItem) >= 3) {
if ($whereItem[0] === $keyField) {
$dbKey = $whereItem[2];
Log::info("条件类型2: 直接匹配 {$keyField}={$dbKey}");
return $dbKey;
}
} // 3. 处理闭包条件: ['user_id', function($query){...}]
elseif (is_array($whereItem) && isset($whereItem[1]) && $whereItem[1] instanceof \Closure) {
Log::info("条件类型3: 发现闭包条件,开始递归解析");
// 创建临时查询对象执行闭包
$subQuery = new Query();
$whereItem[1]($subQuery);
// 递归解析闭包中的条件
$dbKey = static::extractKeyFromOptions($subQuery->getOptions(), $keyField);
if ($dbKey !== null) {
Log::info("条件类型3: 闭包中匹配到 {$keyField}={$dbKey}");
return $dbKey;
}
}
}
return null;
}
}
}