add
This commit is contained in:
parent
c95616561f
commit
34da927bc9
|
|
@ -4,5 +4,6 @@
|
|||
/vendor
|
||||
*.log
|
||||
.env
|
||||
.idea
|
||||
/tests/tmp
|
||||
/tests/.phpunit.result.cache
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.0" />
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
namespace app;
|
||||
|
||||
class DbCoroutineContext
|
||||
{
|
||||
// 协程隔离数据
|
||||
protected static array $data = [];
|
||||
protected static array $list = [];
|
||||
|
||||
// 普通环境全局数据
|
||||
protected static array $globalData = [];
|
||||
protected static array $globalList = [];
|
||||
|
||||
protected static function getCid(): ?int
|
||||
{
|
||||
if (class_exists('\Swoole\Coroutine')) {
|
||||
$cid = \Swoole\Coroutine::getCid();
|
||||
if ($cid >= 0) {
|
||||
return $cid;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// put 存数据到 list
|
||||
public static function put(mixed $value): void
|
||||
{
|
||||
$val = self::get('startTrans');
|
||||
if (!empty($val) && $val === true) {
|
||||
$value->startTrans();
|
||||
}
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
self::$list[$cid][] = $value;
|
||||
} else {
|
||||
self::$globalList[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// set 设置 key-value
|
||||
public static function set(string $key, mixed $value): void
|
||||
{
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
self::$data[$cid][$key] = $value;
|
||||
} else {
|
||||
self::$globalData[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// get 获取 key-value
|
||||
public static function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
return self::$data[$cid][$key] ?? $default;
|
||||
} else {
|
||||
return self::$globalData[$key] ?? $default;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 list
|
||||
public static function getList(): array
|
||||
{
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
return self::$list[$cid] ?? [];
|
||||
} else {
|
||||
return self::$globalList;
|
||||
}
|
||||
}
|
||||
|
||||
// 删除指定 key
|
||||
public static function delete(string $key): void
|
||||
{
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
unset(self::$data[$cid][$key]);
|
||||
} else {
|
||||
unset(self::$globalData[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function clearList()
|
||||
{
|
||||
foreach (self::getList() as $conn) {
|
||||
try {
|
||||
$conn->query('SELECT 1');
|
||||
$conn->close();
|
||||
// 连接正常
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
unset(self::$list[$cid]);
|
||||
} else {
|
||||
self::$globalList = [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function rollback()
|
||||
{
|
||||
foreach (self::getList() as $conn) {
|
||||
$conn->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
// 清理当前上下文
|
||||
public static function clear(): void
|
||||
{
|
||||
foreach (self::getList() as $conn) {
|
||||
try {
|
||||
$conn->query('SELECT 1');
|
||||
$conn->close();
|
||||
// 连接正常
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
$cid = self::getCid();
|
||||
if ($cid !== null) {
|
||||
unset(self::$data[$cid], self::$list[$cid]);
|
||||
} else {
|
||||
self::$globalData = [];
|
||||
self::$globalList = [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function commit()
|
||||
{
|
||||
foreach (self::getList() as $conn) {
|
||||
$conn->commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,31 +2,192 @@
|
|||
|
||||
namespace app\controller;
|
||||
|
||||
use app\api\model\CourseCollect;
|
||||
use app\api\model\CourseDetails;
|
||||
use app\api\model\TbUser;
|
||||
use app\model\DatabaseRoute;
|
||||
use app\model\Test;
|
||||
use support\Request;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
class IndexController
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return <<<EOF
|
||||
<style>
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
|
||||
$get['courseId'] = $course_id = '1877654905222135809';
|
||||
$user['user_id'] = $user_id = '14240';
|
||||
$user = DatabaseRoute::getDb('tb_user', $user_id)->find();
|
||||
try {
|
||||
if(empty($get['courseId'])) {
|
||||
return json('参数不完整');
|
||||
}
|
||||
iframe {
|
||||
border: none;
|
||||
overflow: scroll;
|
||||
$courseId = $get['courseId'];
|
||||
// 获取短剧详情
|
||||
$dd_b = Db::connect('duanju_slave');
|
||||
$db_name = $dd_b->name('course');
|
||||
$bean = $db_name->where(['course_id' => $courseId])->find();
|
||||
if(!$bean) {
|
||||
return json('短剧不存在');
|
||||
}
|
||||
|
||||
|
||||
$courseCollect = DatabaseRoute::getDb('course_collect', $user_id)
|
||||
->where(['course_id' => $course_id])
|
||||
->where(['user_id' => $user_id])
|
||||
->where(['classify' => 3])
|
||||
->limit(1)
|
||||
->find();
|
||||
|
||||
|
||||
|
||||
// 是否追剧
|
||||
$collect = DatabaseRoute::getDb('course_collect', $user_id)
|
||||
->where(['course_id' => $course_id])
|
||||
->where(['classify' => 1])
|
||||
->limit(1)
|
||||
->find();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$db = Db::connect(config('think-orm.search_library'));
|
||||
$userVip = $db->name('user_vip')->where(['user_id' => $user['user_id']])->find();
|
||||
|
||||
if ($userVip) {
|
||||
$user['member'] = $userVip['is_vip'];
|
||||
$user['end_time'] = $userVip['end_time'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$userInfo = $user;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!empty($userInfo['member']) && $userInfo['member'] == 2) {
|
||||
$isVip = true;
|
||||
}else{
|
||||
$isVip = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 查询用户是否购买了整集
|
||||
$courseUser = DatabaseRoute::getDb('course_user', $user_id)
|
||||
->where(['course_id' => $course_id])
|
||||
->where(['classify' => 1])
|
||||
->find();
|
||||
|
||||
|
||||
|
||||
// 每天购买超过上限,获得免费时间段资格
|
||||
$freeWatch = Test::checkFreeWatchPayCount($user['user_id']);
|
||||
|
||||
$startSort = 0;
|
||||
$endSort = 5;
|
||||
$dn_course_details = DatabaseRoute::getDb('course_details', ['course_id' => $courseId]);
|
||||
$sort = null;
|
||||
if (is_null($sort)) {
|
||||
|
||||
if (!empty($courseCollect)) {
|
||||
$courseDetails = $dn_course_details->field('sort')
|
||||
->where('course_details_id', $courseCollect['course_details_id'])
|
||||
->limit(1)
|
||||
->find();
|
||||
$sort = $courseDetails['sort'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($freeWatch || !empty($courseUser)) {
|
||||
$courseDetailsSetVos = Test::courseSets($courseId, 2, null);
|
||||
} else {
|
||||
$courseDetailsSetVos = Test::courseSets($courseId, 1, $bean['wholesale_price']);
|
||||
}
|
||||
|
||||
// 调整集数范围
|
||||
if (!is_null($sort) && $sort > 2) {
|
||||
$startSort = $sort - 3;
|
||||
$endSort = $sort + 3;
|
||||
if (count($courseDetailsSetVos) < $endSort) {
|
||||
$startSort = count($courseDetailsSetVos) - 5;
|
||||
$endSort = count($courseDetailsSetVos) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 已购买剧集ID集合
|
||||
$detailsId = [];
|
||||
if (!$freeWatch) {
|
||||
$det_db = Db::connect(DatabaseRoute::getConnection('course_user', ['user_id' => $user['user_id']]));
|
||||
$detailsId = $det_db->name('course_user')->where(['course_id' => $courseId, 'classify' => 2])->column('course_details_id');
|
||||
$det_db->close();
|
||||
$detailsId = array_flip(array_flip($detailsId)); // 去重
|
||||
}
|
||||
// 处理剧集列表
|
||||
$current = null;
|
||||
foreach ($courseDetailsSetVos as &$s) {
|
||||
$s['wholesalePrice'] = (int) $s['wholesalePrice'];
|
||||
// 当前播放集
|
||||
if (!empty($courseCollect) && $s['courseDetailsId'] == $courseCollect['course_details_id']) {
|
||||
$s['current'] = 1;
|
||||
$current = &$s;
|
||||
}
|
||||
|
||||
// 非免费用户的权限控制
|
||||
if (
|
||||
!$freeWatch &&
|
||||
$s['sort'] > 3 &&
|
||||
(empty($detailsId) || !in_array($s['courseDetailsId'], $detailsId)) &&
|
||||
empty($courseUser) &&
|
||||
!$isVip
|
||||
) {
|
||||
$s['videoUrl'] = null;
|
||||
}
|
||||
|
||||
// 检查是否已点赞
|
||||
if ($s['sort'] > $startSort && $s['sort'] < $endSort) {
|
||||
$isGood_db = Db::connect(DatabaseRoute::getConnection('course_collect', ['user_id' => $user['user_id']]));
|
||||
$isGood = $isGood_db->name('course_collect')
|
||||
->where('course_details_id', $s['courseDetailsId'])
|
||||
->where('classify', 2)
|
||||
->limit(1)
|
||||
->count();
|
||||
$isGood_db->close();
|
||||
$s['isGood'] = empty($isGood) || $isGood == 0 ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有当前播放集,默认第一集
|
||||
if (empty($current) && !empty($courseDetailsSetVos)) {
|
||||
$courseDetailsSetVos[0]['current'] = 1;
|
||||
$current = &$courseDetailsSetVos[0];
|
||||
}
|
||||
Test::setCourseView($bean);
|
||||
|
||||
$price = ($freeWatch ? 0 : ($bean['price'] ?? 0));
|
||||
$price = bccomp($price, '0', 2) <= 0 ? 0 : $price;
|
||||
// 返回结果
|
||||
$map = [
|
||||
'current' => $current,
|
||||
'price' => $price,
|
||||
'title' => $bean['title'],
|
||||
'collect' => empty($collect) || $collect == 0 ? 0 : 1,
|
||||
'list' => $courseDetailsSetVos
|
||||
];
|
||||
return json($map);
|
||||
} catch (\Exception $e) {
|
||||
return json($e->getMessage());
|
||||
}
|
||||
</style>
|
||||
<iframe
|
||||
src="https://www.workerman.net/wellcome"
|
||||
width="100%"
|
||||
height="100%"
|
||||
allow="*"
|
||||
sandbox="allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
EOF;
|
||||
}
|
||||
|
||||
public function view(Request $request)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,516 @@
|
|||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\DbCoroutineContext;
|
||||
use think\Collection;
|
||||
use think\db\Connection;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
class DatabaseRoute
|
||||
{
|
||||
|
||||
/**
|
||||
* 跨所有分库分页(自动 count,自动追加 LIMIT 和 ORDER BY)
|
||||
*
|
||||
* @param \Closure $sqlBuilder 生成基础 SQL 的闭包函数(不包含 LIMIT)
|
||||
* @param int $page 当前页码
|
||||
* @param int $pageSize 每页条数
|
||||
* @param string|null $orderCol 排序字段(全局排序使用)
|
||||
* @return array
|
||||
*/
|
||||
public static function paginateAllDbBySqlAutoCount(
|
||||
\Closure $sqlBuilder,
|
||||
int $page = 1,
|
||||
int $pageSize = 20,
|
||||
string $orderCol = null,
|
||||
int $count = null,
|
||||
): array
|
||||
{
|
||||
$dbMap = config('database.db_map');
|
||||
$counts = [];
|
||||
$total = 0;
|
||||
|
||||
|
||||
if ($count === null) {
|
||||
// 1. 自动 count 分库总数
|
||||
$dbList = DatabaseRoute::getAllSelectDb();
|
||||
foreach ($dbMap as $connName) {
|
||||
if (in_array($connName, $dbList) ) {
|
||||
$baseSql = call_user_func($sqlBuilder, $connName);
|
||||
$countSql = self::buildCountSql($baseSql);
|
||||
$count = Db::connect($connName)->query($countSql)[0]['count'] ?? 0;
|
||||
$counts[$connName] = $count;
|
||||
$total += $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($total === 0) {
|
||||
return [
|
||||
'list' => [],
|
||||
'totalCount' => 0,
|
||||
'totalPage' => 0,
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
if ($offset >= $total) {
|
||||
return [
|
||||
'list' => [],
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $pageSize),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
$limit = $pageSize;
|
||||
$allRows = [];
|
||||
$skip = $offset;
|
||||
|
||||
// 2. 分库分页查询
|
||||
foreach ($counts as $connName => $count) {
|
||||
if ($count <= 0) continue;
|
||||
if ($skip >= $count) {
|
||||
$skip -= $count;
|
||||
continue;
|
||||
}
|
||||
|
||||
$localOffset = $skip;
|
||||
$localLimit = min($count - $localOffset, $limit);
|
||||
|
||||
$baseSql = call_user_func($sqlBuilder, $connName);
|
||||
$sql = rtrim($baseSql, ';');
|
||||
|
||||
if ($orderCol) {
|
||||
$sql .= " ORDER BY {$orderCol} DESC";
|
||||
}
|
||||
$sql .= " LIMIT {$localOffset}, {$localLimit}";
|
||||
|
||||
$rows = Db::connect($connName)->query($sql);
|
||||
$allRows = array_merge($allRows, $rows);
|
||||
|
||||
$limit -= $localLimit;
|
||||
$skip = 0;
|
||||
if ($limit <= 0) break;
|
||||
}
|
||||
|
||||
// 3. 全局排序(若指定排序字段)
|
||||
if ($orderCol) {
|
||||
usort($allRows, function ($a, $b) use ($orderCol) {
|
||||
return strtotime($b[$orderCol]) <=> strtotime($a[$orderCol]);
|
||||
});
|
||||
}
|
||||
|
||||
// 4. 返回结构
|
||||
return [
|
||||
'list' => $allRows,
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $pageSize),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 SELECT SQL 自动构建对应的 COUNT SQL
|
||||
*
|
||||
* @param string $sql
|
||||
* @return string
|
||||
*/
|
||||
private static function buildCountSql(string $sql): string
|
||||
{
|
||||
$sql = preg_replace('/\s+ORDER\s+BY\s+.+?$/i', '', $sql);
|
||||
$sql = preg_replace('/\s+LIMIT\s+\d+(\s*,\s*\d+)?$/i', '', $sql);
|
||||
if (preg_match('/FROM\s+(.*)/i', $sql, $matches)) {
|
||||
return 'SELECT COUNT(*) AS count FROM ' . $matches[1];
|
||||
}
|
||||
throw new \RuntimeException("无法从 SQL 自动构建 COUNT 查询,请检查 SQL 是否规范");
|
||||
}
|
||||
|
||||
public static function paginateDb(
|
||||
string $table,
|
||||
\Closure $builder,
|
||||
int $page = 1,
|
||||
int $pageSize = 20,
|
||||
string|array $keyInfo = null,
|
||||
$isRecords = false
|
||||
) {
|
||||
// 构建基础查询
|
||||
if ($keyInfo) {
|
||||
$query = self::getDb($table, $keyInfo);
|
||||
}else{
|
||||
$query = Db::table($table);
|
||||
}
|
||||
$builder($query); // 应用外部闭包设置查询条件,如 where/order 等
|
||||
|
||||
// 获取总数
|
||||
$totalCount = (clone $query)->count();
|
||||
|
||||
// 计算总页数
|
||||
$totalPage = (int) ceil($totalCount / $pageSize);
|
||||
$currPage = max(1, min($page, $totalPage));
|
||||
|
||||
// 获取分页数据
|
||||
$list = $query
|
||||
->page($currPage, $pageSize)
|
||||
->select()
|
||||
->toArray();
|
||||
$query->getConnection()->close();
|
||||
|
||||
return [
|
||||
'totalCount' => $totalCount,
|
||||
'pageSize' => $pageSize,
|
||||
'totalPage' => $totalPage,
|
||||
'currPage' => $currPage,
|
||||
$isRecords ? 'records' : 'list' => convertToCamelCase($list),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨所有从库分页(支持游标分页和传统页码分页)
|
||||
* @param string $table 表名
|
||||
* @param \Closure $builder 查询构造器
|
||||
* @param int|null $page 当前页(null 表示使用游标分页)
|
||||
* @param int $pageSize 每页条数
|
||||
* @param string|null $lastCreateTime 游标分页的游标值(create_time)
|
||||
* @return array [list, total|nextCursor, hasMore]
|
||||
*/
|
||||
public static function paginateAllDb(
|
||||
string $table,
|
||||
\Closure $builder,
|
||||
int $page = 1,
|
||||
int $pageSize = 20,
|
||||
string $orderCol = 'create_time',
|
||||
string $modelOrderCol = null,
|
||||
bool $isRecords = false
|
||||
): array
|
||||
{
|
||||
$dbMap = config('database.db_map');
|
||||
$counts = [];
|
||||
$total = 0;
|
||||
|
||||
// 1. 统计每个分库总数
|
||||
$dbList = DatabaseRoute::getAllSelectDb();
|
||||
foreach ($dbMap as $connName) {
|
||||
if (in_array($connName, $dbList) ) {
|
||||
$query = Db::connect($connName)->name($table);
|
||||
$query = call_user_func($builder, $query);
|
||||
// 不要order,避免报错
|
||||
$query->removeOption('order');
|
||||
$count = $query->count();
|
||||
$query->getConnection()->close();
|
||||
$counts[$connName] = $count;
|
||||
$total += $count;
|
||||
}
|
||||
}
|
||||
|
||||
if ($total === 0) {
|
||||
return [
|
||||
$isRecords ? 'records' : 'list' => [],
|
||||
'totalCount' => 0,
|
||||
'totalPage' => 0,
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
if ($offset >= $total) {
|
||||
// 超出总数,返回空数据
|
||||
return [
|
||||
$isRecords ? 'records' : 'list' => [],
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $pageSize),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
$limit = $pageSize;
|
||||
$allRows = [];
|
||||
|
||||
// 2. 计算每个库需要查询的偏移和条数
|
||||
$skip = $offset; // 还需要跳过多少条
|
||||
foreach ($counts as $connName => $count) {
|
||||
if ($count <= 0) continue;
|
||||
|
||||
if ($skip >= $count) {
|
||||
// 跳过整个分库
|
||||
$skip -= $count;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 本库要查询的起始 offset
|
||||
$localOffset = $skip;
|
||||
// 本库剩余条数
|
||||
$localLimit = min($count - $localOffset, $limit);
|
||||
|
||||
// 查询数据
|
||||
$query = Db::connect($connName)->name($table);
|
||||
$query = call_user_func($builder, $query);
|
||||
$rows = $query->order($orderCol, 'desc')
|
||||
->limit($localOffset, $localLimit)
|
||||
->select()
|
||||
->toArray();
|
||||
$query->getConnection()->close();
|
||||
|
||||
$allRows = array_merge($allRows, $rows);
|
||||
|
||||
$limit -= $localLimit; // 剩余要查询的条数
|
||||
$skip = 0; // 之后库不再跳过
|
||||
|
||||
if ($limit <= 0) break; // 已查够
|
||||
}
|
||||
|
||||
// 3. 全局排序(降序)
|
||||
if ($modelOrderCol) {
|
||||
usort($allRows, function ($a, $b) use ($modelOrderCol) {
|
||||
return strtotime($b[$modelOrderCol]) <=> strtotime($a[$modelOrderCol]);
|
||||
});
|
||||
}
|
||||
|
||||
// 4. 返回分页数据
|
||||
return [
|
||||
$isRecords ? 'records' : 'list' => $allRows,
|
||||
'totalCount' => $total,
|
||||
'totalPage' => (int)ceil($total / $pageSize),
|
||||
'currPage' => $page,
|
||||
'pageSize' => $pageSize,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对所有从库执行事务(XA 分布式模拟,非真实两阶段提交)
|
||||
* @param \Closure $callback
|
||||
* @return mixed
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public static function transactionXa(\Closure $callback)
|
||||
{
|
||||
DbCoroutineContext::set('startTrans', true);
|
||||
|
||||
try {
|
||||
|
||||
// 执行用户操作(传入事务闭包)
|
||||
$result = call_user_func($callback);
|
||||
// 提交所有连接
|
||||
DbCoroutineContext::commit();
|
||||
return $result;
|
||||
} catch (\Throwable $e) {
|
||||
// 回滚所有连接
|
||||
DbCoroutineContext::rollback();
|
||||
|
||||
Log::error("transactionXa 全部回滚:" . $e->getMessage());
|
||||
Log::info('错误信息'.$e->getMessage().'具体信息'.$e->getTraceAsString());
|
||||
throw $e;
|
||||
}finally {
|
||||
DbCoroutineContext::clearList();
|
||||
DbCoroutineContext::set('startTrans', false);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMasterDb($table, $isWrite = false)
|
||||
{
|
||||
$conn = Db::connect();
|
||||
if ($isWrite) {
|
||||
DbCoroutineContext::put($conn);
|
||||
}
|
||||
return $conn->name($table);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据表和分库值获取db
|
||||
* @param $table string 表名
|
||||
* @param $keyInfo string | array
|
||||
*/
|
||||
public static function getDb($table, $keyInfo, $isWrite = false, $isUpdate = false, $addWhere = true)
|
||||
{
|
||||
if (is_array($keyInfo)) {
|
||||
$con = Db::connect(DatabaseRoute::getConnection($table, $keyInfo, $isWrite));
|
||||
if ($isWrite) {
|
||||
DbCoroutineContext::put($con);
|
||||
}
|
||||
$model = $con->name($table);
|
||||
if ($addWhere && (!$isWrite || $isUpdate)) {
|
||||
$model->where($keyInfo);
|
||||
}
|
||||
} else {
|
||||
$con = Db::connect(DatabaseRoute::getConnection($table, ['user_id' => $keyInfo], $isWrite));
|
||||
if ($isWrite) {
|
||||
DbCoroutineContext::put($con);
|
||||
}
|
||||
$model = $con->name($table);
|
||||
if ($addWhere && (!$isWrite || $isUpdate)) {
|
||||
$model->where([
|
||||
'user_id' => $keyInfo
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨所有分库直接删除(危险操作,务必确认条件准确)
|
||||
* @param string $table 表名
|
||||
* @param \Closure $builder 条件构造器,如 function($query) { return $query->where('xxx', xxx); }
|
||||
* @return int 删除的总记录数
|
||||
*/
|
||||
public static function deleteAllDbDirect(string $table, \Closure $builder): int
|
||||
{
|
||||
$dbMap = config('database.db_master_map');
|
||||
$totalDeleted = 0;
|
||||
|
||||
foreach ($dbMap as $connName) {
|
||||
if ($connName === 'duanju_master') continue;
|
||||
|
||||
$query = Db::connect($connName)->name($table);
|
||||
$query = call_user_func($builder, $query);
|
||||
$deleted = $query->delete();
|
||||
$query->getConnection()->close();
|
||||
$totalDeleted += $deleted;
|
||||
}
|
||||
|
||||
return $totalDeleted;
|
||||
}
|
||||
|
||||
public static function getAllDbData($table, \Closure $builder)
|
||||
{
|
||||
|
||||
return new class($table, $builder) {
|
||||
protected $table;
|
||||
protected $builder;
|
||||
protected $dbMap;
|
||||
protected $masterDbMap;
|
||||
|
||||
public function __construct($table, $builder)
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->builder = $builder;
|
||||
$this->dbMap = config('database.db_map');
|
||||
$this->masterDbMap = config('database.db_master_map');
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$finalResult = null;
|
||||
try {
|
||||
if ($method == 'insert') {
|
||||
throw new \RuntimeException("不支持insert");
|
||||
}
|
||||
// insert 和 update 使用主库
|
||||
if ($method == 'update' || $method == 'delete') {
|
||||
foreach ($this->masterDbMap as $dbname) {
|
||||
if ($dbname !== 'duanju_master') {
|
||||
$query = Db::connect($dbname)->name($this->table);
|
||||
$query = call_user_func($this->builder, $query);
|
||||
if (method_exists($query, $method)) {
|
||||
$result = call_user_func_array([$query, $method], $args);
|
||||
$finalResult = $result;
|
||||
$query->getConnection()->close();
|
||||
// find 返回 null,select 返回空数组,count 返回数字
|
||||
if ($result || $result === 0) {
|
||||
return $result;
|
||||
}
|
||||
}else {
|
||||
$query->getConnection()->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $finalResult;
|
||||
}else{
|
||||
$dbList = DatabaseRoute::getAllSelectDb();
|
||||
foreach ($this->dbMap as $dbname) {
|
||||
if (in_array($dbname, $dbList) ) {
|
||||
$query = Db::connect($dbname)->name($this->table);
|
||||
$query = call_user_func($this->builder, $query);
|
||||
if (method_exists($query, $method)) {
|
||||
$result = call_user_func_array([$query, $method], $args);
|
||||
// find 返回 null,select 返回空数组,count 返回数字
|
||||
$finalResult = $result;
|
||||
$query->getConnection()->close();
|
||||
if ($result instanceof Collection) {
|
||||
if (!$result->isEmpty()) {
|
||||
return $result;
|
||||
}
|
||||
}elseif (is_int($result) && $result != 0) {
|
||||
return $result;
|
||||
} else if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}else {
|
||||
$query->getConnection()->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (\Throwable $e) {
|
||||
Log::error("错误信息".$e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
|
||||
return $finalResult;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static function getAllSelectDb()
|
||||
{
|
||||
$index = self::getIndex();
|
||||
return ["duanju$index-0_slave", "duanju$index-1_slave", "duanju$index-2_slave", "duanju$index-3_slave", "duanju$index-4_slave"];
|
||||
}
|
||||
|
||||
|
||||
private static function getIndex()
|
||||
{
|
||||
$INDEX = \cache('db_index');
|
||||
if ($INDEX == null) {
|
||||
$INDEX = 0;
|
||||
}
|
||||
$INDEX = ++$INDEX % 4;
|
||||
\cache('db_index', $INDEX);
|
||||
return $INDEX;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据库连接
|
||||
* @param string $tableName 表名
|
||||
* @param array $data 数据
|
||||
* @param bool $isWrite 是否为写操作
|
||||
* @return Connection
|
||||
*/
|
||||
public static function getConnection($table, $data = [], $isWrite = false)
|
||||
{
|
||||
$routeConfig = config('think-orm.route');
|
||||
$keyField = strpos($table, 'user') !== false || in_array($table, [
|
||||
'orders', 'course_collect', 'pay_details', 'disc_spinning_record',
|
||||
'cash_out', 'course_user', 'tb_user', 'task_center_record',
|
||||
'user_money', 'user_sign_record', 'invite_achievement',
|
||||
'invite_money', 'user_info', 'sys_user', 'user_money_details', 'sys_user_money_details'
|
||||
]) ? 'user_id' : 'course_id';
|
||||
|
||||
if (!isset($data[$keyField])) {
|
||||
Log::warning("分库警告: 表={$table}, 数据中缺少 {$keyField} 字段");
|
||||
return $isWrite ? 'duanju_master' : 'duanju_slave';
|
||||
}
|
||||
|
||||
$index = abs($data[$keyField] % 5);
|
||||
$connectionTemplate = $isWrite
|
||||
? $routeConfig[$table]['master']
|
||||
: $routeConfig[$table]['slave'];
|
||||
|
||||
$connectionName = str_replace("{\${$keyField}%5}", $index, $connectionTemplate);
|
||||
return $connectionName;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace app\model;
|
||||
|
||||
use support\Model;
|
||||
use think\model;
|
||||
use think\facade\Db;
|
||||
|
||||
class Test extends Model
|
||||
{
|
||||
|
|
@ -26,4 +27,84 @@ class Test extends Model
|
|||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
|
||||
|
||||
public static function checkFreeWatchPayCount($userId)
|
||||
{
|
||||
$count = DatabaseRoute::getDb('orders', $userId)->where([
|
||||
'status' => 1,
|
||||
'pay_way' => 9,
|
||||
['create_time', '>', date('Y-m-d 00:00:00')],
|
||||
])->count();
|
||||
$needCount = Db::name('common_info')->where([
|
||||
'type' => 916
|
||||
])->find();
|
||||
$freeTime = Db::name('common_info')->where([
|
||||
'type' => 917
|
||||
])->find();
|
||||
if (!$needCount || !$freeTime) {
|
||||
return false;
|
||||
}
|
||||
if ($count >= intval($needCount['value'])) {
|
||||
$isExpire = false;
|
||||
}else{
|
||||
$isExpire = true;
|
||||
}
|
||||
|
||||
return !$isExpire;
|
||||
}
|
||||
|
||||
|
||||
public static function courseSets($courseId, $isPrice, $wholesalePrice)
|
||||
{
|
||||
|
||||
$db = Db::connect(DatabaseRoute::getConnection('course_details', ['course_id' => $courseId]));
|
||||
$courseDetailsSetVos = $db->name('course_details')
|
||||
->alias('c')
|
||||
->field([
|
||||
'c.course_id' => 'courseId',
|
||||
'c.course_details_id' => 'courseDetailsId',
|
||||
'c.course_details_name' => 'courseDetailsName',
|
||||
'c.video_url' => 'videoUrl',
|
||||
'c.price' => 'price',
|
||||
'c.sort' => 'sort',
|
||||
'c.is_price' => 'isPrice',
|
||||
'c.title_img' => 'titleImg',
|
||||
'c.good_num' => 'goodNum',
|
||||
])
|
||||
->where('c.course_id', $courseId)
|
||||
->order('c.sort', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($courseDetailsSetVos as $k => &$v) {
|
||||
$v['courseId'] = (string) $v['courseId'];
|
||||
$v['courseDetailsId'] = (string) $v['courseDetailsId'];
|
||||
if(empty($wholesalePrice)) {
|
||||
$v['wholesalePrice'] = 0;
|
||||
}else {
|
||||
$v['wholesalePrice'] = $wholesalePrice;
|
||||
}
|
||||
if($isPrice != 1) {
|
||||
$v['isPrice'] = 2;
|
||||
}
|
||||
}
|
||||
return $courseDetailsSetVos;
|
||||
}
|
||||
public static function setCourseView($course)
|
||||
{
|
||||
// 1. 更新总播放量
|
||||
if (empty($course['view_counts'])) {
|
||||
$viewCounts = 1;
|
||||
} else {
|
||||
$viewCounts = $course['view_counts'] + 1;
|
||||
}
|
||||
|
||||
$db_name = Db::connect(config('think-orm.z_library'))->name('course');
|
||||
// 4. 执行数据库更新
|
||||
$db_name->where(['course_id' => $course['course_id']])->update([
|
||||
'view_counts' => $viewCounts,
|
||||
'week_view' => 999
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,9 @@
|
|||
"require": {
|
||||
"php": ">=8.1",
|
||||
"workerman/webman-framework": "^2.1",
|
||||
"monolog/monolog": "^2.0"
|
||||
"monolog/monolog": "^2.0",
|
||||
"webman/think-orm": "^2.1",
|
||||
"vlucas/phpdotenv": "^5.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
|
|
|
|||
|
|
@ -4,8 +4,77 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "691f538563ac6695008ddc51b7722c80",
|
||||
"content-hash": "31b009f9f2392b9eda909c76dbca259f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "graham-campbell/result-type",
|
||||
"version": "1.1.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/GrahamCampbell/Result-Type.git",
|
||||
"reference": "9d6c1d7ce69a3329936e603617e59ba205ab0a66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/9d6c1d7ce69a3329936e603617e59ba205ab0a66",
|
||||
"reference": "9d6c1d7ce69a3329936e603617e59ba205ab0a66",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"phpoption/phpoption": "^1.9.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GrahamCampbell\\ResultType\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
}
|
||||
],
|
||||
"description": "An Implementation Of The Result Type",
|
||||
"keywords": [
|
||||
"Graham Campbell",
|
||||
"GrahamCampbell",
|
||||
"Result Type",
|
||||
"Result-Type",
|
||||
"result"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
|
||||
"source": "https://github.com/GrahamCampbell/Result-Type/tree/1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-09T22:43:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.10.0",
|
||||
|
|
@ -170,6 +239,87 @@
|
|||
},
|
||||
"time": "2018-02-13T20:26:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/php-option.git",
|
||||
"reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54",
|
||||
"reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOption\\": "src/PhpOption/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh"
|
||||
},
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
}
|
||||
],
|
||||
"description": "Option Type for PHP",
|
||||
"keywords": [
|
||||
"language",
|
||||
"option",
|
||||
"php",
|
||||
"type"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/schmittjoh/php-option/issues",
|
||||
"source": "https://github.com/schmittjoh/php-option/tree/1.9.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-20T21:41:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
|
|
@ -285,6 +435,673 @@
|
|||
},
|
||||
"time": "2024-08-21T13:31:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
|
||||
},
|
||||
"time": "2021-10-29T13:26:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-container",
|
||||
"version": "v3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-container.git",
|
||||
"reference": "a24d442a02fb2a4716de232ff1a4f006c178a370"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-container/zipball/a24d442a02fb2a4716de232ff1a4f006c178a370",
|
||||
"reference": "a24d442a02fb2a4716de232ff1a4f006c178a370",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"psr/container": "^2.0",
|
||||
"topthink/think-helper": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [],
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "liu21st",
|
||||
"email": "liu21st@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Container & Facade Manager",
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-container/issues",
|
||||
"source": "https://github.com/top-think/think-container/tree/v3.0.1"
|
||||
},
|
||||
"time": "2025-01-07T08:19:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-helper",
|
||||
"version": "v3.1.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-helper.git",
|
||||
"reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-helper/zipball/1d6ada9b9f3130046bf6922fe1bd159c8d88a33c",
|
||||
"reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"description": "The ThinkPHP6 Helper Package",
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-helper/issues",
|
||||
"source": "https://github.com/top-think/think-helper/tree/v3.1.11"
|
||||
},
|
||||
"time": "2025-04-07T06:55:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v4.0.40",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "1637860ff736859058f0a5003c7cc719c2068dbc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/1637860ff736859058f0a5003c7cc719c2068dbc",
|
||||
"reference": "1637860ff736859058f0a5003c7cc719c2068dbc",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0.0",
|
||||
"psr/log": ">=1.0",
|
||||
"psr/simple-cache": ">=1.0",
|
||||
"topthink/think-helper": "^3.1",
|
||||
"topthink/think-validate": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6|^10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mongodb": "provide mongodb support"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helper.php",
|
||||
"stubs/load_stubs.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "liu21st",
|
||||
"email": "liu21st@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "the PHP Database&ORM Framework",
|
||||
"keywords": [
|
||||
"database",
|
||||
"orm"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-orm/issues",
|
||||
"source": "https://github.com/top-think/think-orm/tree/v4.0.40"
|
||||
},
|
||||
"time": "2025-05-27T03:32:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-validate",
|
||||
"version": "v3.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-validate.git",
|
||||
"reference": "85063f6d4ef8ed122f17a36179dc3e0949b30988"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-validate/zipball/85063f6d4ef8ed122f17a36179dc3e0949b30988",
|
||||
"reference": "85063f6d4ef8ed122f17a36179dc3e0949b30988",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"topthink/think-container": ">=3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "liu21st",
|
||||
"email": "liu21st@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "think validate",
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-validate/issues",
|
||||
"source": "https://github.com/top-think/think-validate/tree/v3.0.7"
|
||||
},
|
||||
"time": "2025-06-11T05:51:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v5.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2",
|
||||
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"ext-pcre": "*",
|
||||
"graham-campbell/result-type": "^1.1.3",
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"phpoption/phpoption": "^1.9.3",
|
||||
"symfony/polyfill-ctype": "^1.24",
|
||||
"symfony/polyfill-mbstring": "^1.24",
|
||||
"symfony/polyfill-php80": "^1.24"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"ext-filter": "*",
|
||||
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-filter": "Required to use the boolean validator."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "5.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dotenv\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Vance Lucas",
|
||||
"email": "vance@vancelucas.com",
|
||||
"homepage": "https://github.com/vlucas"
|
||||
}
|
||||
],
|
||||
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
|
||||
"keywords": [
|
||||
"dotenv",
|
||||
"env",
|
||||
"environment"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/vlucas/phpdotenv/issues",
|
||||
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-20T21:52:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webman/think-orm",
|
||||
"version": "v2.1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webman-php/think-orm.git",
|
||||
"reference": "af4a2586177a333983e0da1bf6512ec12f894b29"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webman-php/think-orm/zipball/af4a2586177a333983e0da1bf6512ec12f894b29",
|
||||
"reference": "af4a2586177a333983e0da1bf6512ec12f894b29",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"topthink/think-container": "^2.0|^3.0",
|
||||
"topthink/think-orm": "^2.0.53 || ^3.0.0 || ^4.0.30 || dev-master",
|
||||
"workerman/webman-framework": "^2.1 || dev-master"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"support\\": "src/support",
|
||||
"Webman\\ThinkOrm\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webman-php/think-orm/issues",
|
||||
"source": "https://github.com/webman-php/think-orm/tree/v2.1.6"
|
||||
},
|
||||
"time": "2025-05-27T13:15:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "workerman/coroutine",
|
||||
"version": "v1.1.3",
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@
|
|||
|
||||
return [
|
||||
support\bootstrap\Session::class,
|
||||
Webman\ThinkOrm\ThinkOrm::class,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'default' => 'duanju_master',
|
||||
'connections' => [
|
||||
'duanju_master' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju',
|
||||
// 数据库用户名
|
||||
'username' => env('USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
'duanju_slave' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
'duanju_slave_0' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju-0',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
|
||||
'duanju_slave_1' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju-1',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
|
||||
'duanju_slave_2' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju-2',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
'duanju_slave_3' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju-3',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
'duanju_slave_4' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => env('SLAVE_HOSTNAME', '127.0.0.1'),
|
||||
// 数据库名
|
||||
'database' => 'duanju-4',
|
||||
// 数据库用户名
|
||||
'username' => env('SLAVE_USERNAME', 'video_user'),
|
||||
// 数据库密码
|
||||
'password' => env('SLAVE_PASSWORD', 'VideoUser@1'),
|
||||
// 数据库连接端口
|
||||
'hostport' => env('SLAVE_HOSTPORT', '3306'),
|
||||
// 数据库连接参数
|
||||
'params' => [
|
||||
// 连接超时3秒
|
||||
\PDO::ATTR_TIMEOUT => 3,
|
||||
],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8mb4',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 断线重连
|
||||
'break_reconnect' => true,
|
||||
// 自定义分页类
|
||||
'bootstrap' => '',
|
||||
// 连接池配置
|
||||
'pool' => [
|
||||
'max_connections' => 500, // 最大连接数
|
||||
'min_connections' => 20, // 最小连接数
|
||||
'wait_timeout' => 3, // 从连接池获取连接等待超时时间
|
||||
'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
|
||||
'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
|
||||
],
|
||||
],
|
||||
],
|
||||
'db_map' => [
|
||||
'duanju_slave', 'duanju_slave_0', 'duanju_slave_1', 'duanju_slave_2', 'duanju_slave_3', 'duanju_slave_4',
|
||||
],
|
||||
// 从主库
|
||||
'search_library' => 'duanju_slave',
|
||||
'z_library' => 'duanju_master',
|
||||
// 主主库
|
||||
// 数据库路由配置
|
||||
'route' => [
|
||||
// user_id分库的表
|
||||
'user_money_details' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'sys_user_money_details' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'orders' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'course_collect' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'pay_details' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'disc_spinning_record' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'cash_out' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'course_user' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'tb_user' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'task_center_record' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'user_money' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'user_sign_record' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'invite_achievement' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'invite_money' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'user_info' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
'sys_user' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$user_id%5}'],
|
||||
|
||||
// course_id分库的表
|
||||
'course_details' => ['master' => 'duanju_master', 'slave' => 'duanju_slave_{$course_id%5}'],
|
||||
],
|
||||
];
|
||||
Loading…
Reference in New Issue