mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-06 03:58:04 +08:00
ComposerUpdate
This commit is contained in:
parent
587e823eff
commit
0ba3055b1f
19
vendor/composer/installed.json
vendored
19
vendor/composer/installed.json
vendored
@ -656,17 +656,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.36",
|
||||
"version_normalized": "2.0.36.0",
|
||||
"version": "v2.0.37",
|
||||
"version_normalized": "2.0.37.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "f48dc09050f25029d41a66bfc9c3c403e4f82024"
|
||||
"reference": "8a2225c3533f5ccae4a77d4988ed4c5523284871"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/f48dc09050f25029d41a66bfc9c3c403e4f82024",
|
||||
"reference": "f48dc09050f25029d41a66bfc9c3c403e4f82024",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/8a2225c3533f5ccae4a77d4988ed4c5523284871",
|
||||
"reference": "8a2225c3533f5ccae4a77d4988ed4c5523284871",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -682,7 +682,10 @@
|
||||
"psr/simple-cache": "^1.0",
|
||||
"topthink/think-helper": "^3.1"
|
||||
},
|
||||
"time": "2021-01-12T09:08:52+00:00",
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7|^8|^9.5"
|
||||
},
|
||||
"time": "2021-02-18T02:01:00+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -857,7 +860,7 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/zoujingli/ThinkLibrary",
|
||||
"reference": "145101aa5969d953d4d3bbadaea9e16b23569b25"
|
||||
"reference": "f835b371ad1d37cf7352d27aa7a24ea9667a5b51"
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
@ -867,7 +870,7 @@
|
||||
"ext-mbstring": "*",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"time": "2021-02-01T09:27:06+00:00",
|
||||
"time": "2021-02-22T02:50:49+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2021-02-01 17:32:06
|
||||
// This file is automatically generated at:2021-02-22 10:56:25
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'think\\admin\\Library',
|
||||
|
3
vendor/topthink/think-orm/.gitattributes
vendored
Normal file
3
vendor/topthink/think-orm/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/.github export-ignore
|
||||
/tests export-ignore
|
||||
/phpunit.xml export-ignore
|
11
vendor/topthink/think-orm/composer.json
vendored
11
vendor/topthink/think-orm/composer.json
vendored
@ -19,10 +19,21 @@
|
||||
"psr/log": "~1.0",
|
||||
"topthink/think-helper":"^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7|^8|^9.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
},
|
||||
"files": []
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
24
vendor/topthink/think-orm/src/DbManager.php
vendored
24
vendor/topthink/think-orm/src/DbManager.php
vendored
@ -92,8 +92,6 @@ class DbManager
|
||||
*/
|
||||
protected function modelMaker()
|
||||
{
|
||||
$this->triggerSql();
|
||||
|
||||
Model::setDb($this);
|
||||
|
||||
if (is_object($this->event)) {
|
||||
@ -122,26 +120,8 @@ class DbManager
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function triggerSql(): void
|
||||
{
|
||||
// 监听SQL
|
||||
$this->listen(function ($sql, $time, $master) {
|
||||
if (0 === strpos($sql, 'CONNECT:')) {
|
||||
$this->log($sql);
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录SQL
|
||||
if (is_bool($master)) {
|
||||
// 分布式记录当前操作的主从
|
||||
$master = $master ? 'master|' : 'slave|';
|
||||
} else {
|
||||
$master = '';
|
||||
}
|
||||
|
||||
$this->log($sql . ' [ ' . $master . 'RunTime:' . $time . 's ]');
|
||||
});
|
||||
}
|
||||
public function triggerSql(): void
|
||||
{}
|
||||
|
||||
/**
|
||||
* 初始化配置参数
|
||||
|
29
vendor/topthink/think-orm/src/Model.php
vendored
29
vendor/topthink/think-orm/src/Model.php
vendored
@ -266,9 +266,8 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
*/
|
||||
public function newInstance(array $data = [], $where = null): Model
|
||||
{
|
||||
$this->readDataType($data);
|
||||
|
||||
$model = new static($data);
|
||||
$model->readDataType();
|
||||
|
||||
if ($this->connection) {
|
||||
$model->setConnection($this->connection);
|
||||
@ -616,7 +615,7 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
if ($this->autoWriteTimestamp && $this->updateTime) {
|
||||
// 自动写入更新时间
|
||||
$data[$this->updateTime] = $this->autoWriteTimestamp();
|
||||
$this->data[$this->updateTime] = $data[$this->updateTime];
|
||||
$this->data[$this->updateTime] = $this->getTimestampValue($data[$this->updateTime]);
|
||||
}
|
||||
|
||||
// 检查允许字段
|
||||
@ -670,17 +669,6 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
*/
|
||||
protected function insertData(string $sequence = null): bool
|
||||
{
|
||||
// 时间戳自动写入
|
||||
if ($this->autoWriteTimestamp) {
|
||||
if ($this->createTime && !isset($this->data[$this->createTime])) {
|
||||
$this->data[$this->createTime] = $this->autoWriteTimestamp();
|
||||
}
|
||||
|
||||
if ($this->updateTime && !isset($this->data[$this->updateTime])) {
|
||||
$this->data[$this->updateTime] = $this->autoWriteTimestamp();
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $this->trigger('BeforeInsert')) {
|
||||
return false;
|
||||
}
|
||||
@ -688,6 +676,19 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
$this->checkData();
|
||||
$data = $this->writeDataType($this->data);
|
||||
|
||||
// 时间戳自动写入
|
||||
if ($this->autoWriteTimestamp) {
|
||||
if ($this->createTime && !isset($data[$this->createTime])) {
|
||||
$data[$this->createTime] = $this->autoWriteTimestamp();
|
||||
$this->data[$this->createTime] = $this->getTimestampValue($data[$this->createTime]);
|
||||
}
|
||||
|
||||
if ($this->updateTime && !isset($data[$this->updateTime])) {
|
||||
$data[$this->updateTime] = $this->autoWriteTimestamp();
|
||||
$this->data[$this->updateTime] = $this->getTimestampValue($data[$this->updateTime]);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查允许字段
|
||||
$allowFields = $this->checkAllowFields();
|
||||
|
||||
|
@ -266,11 +266,11 @@ abstract class BaseQuery
|
||||
/**
|
||||
* 得到某个列的数组
|
||||
* @access public
|
||||
* @param string $field 字段名 多个字段用逗号分隔
|
||||
* @param string|array $field 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @return array
|
||||
*/
|
||||
public function column(string $field, string $key = ''): array
|
||||
public function column($field, string $key = ''): array
|
||||
{
|
||||
return $this->connection->column($this, $field, $key);
|
||||
}
|
||||
|
11
vendor/topthink/think-orm/src/db/Builder.php
vendored
11
vendor/topthink/think-orm/src/db/Builder.php
vendored
@ -15,6 +15,7 @@ namespace think\db;
|
||||
use Closure;
|
||||
use PDO;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Db Builder
|
||||
@ -490,7 +491,7 @@ abstract class Builder
|
||||
// 字段分析
|
||||
$key = $field ? $this->parseKey($query, $field, true) : '';
|
||||
|
||||
list($exp, $value) = $val;
|
||||
[$exp, $value] = $val;
|
||||
|
||||
// 检测操作符
|
||||
if (!is_string($exp)) {
|
||||
@ -756,6 +757,9 @@ abstract class Builder
|
||||
$value = $this->parseRaw($query, $value);
|
||||
} else {
|
||||
$value = array_unique(is_array($value) ? $value : explode(',', $value));
|
||||
if (count($value) === 0) {
|
||||
return '0 = 1';
|
||||
}
|
||||
$array = [];
|
||||
|
||||
foreach ($value as $v) {
|
||||
@ -766,8 +770,7 @@ abstract class Builder
|
||||
if (count($array) == 1) {
|
||||
return $key . ('IN' == $exp ? ' = ' : ' <> ') . $array[0];
|
||||
} else {
|
||||
$zone = implode(',', $array);
|
||||
$value = empty($zone) ? "''" : $zone;
|
||||
$value = implode(',', $array);
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,7 +901,7 @@ abstract class Builder
|
||||
$array[] = $this->parseRand($query);
|
||||
} elseif (is_string($val)) {
|
||||
if (is_numeric($key)) {
|
||||
list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
|
||||
[$key, $sort] = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
|
||||
} else {
|
||||
$sort = $val;
|
||||
}
|
||||
|
41
vendor/topthink/think-orm/src/db/Connection.php
vendored
41
vendor/topthink/think-orm/src/db/Connection.php
vendored
@ -138,7 +138,6 @@ abstract class Connection implements ConnectionInterface
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建查询对象
|
||||
*/
|
||||
@ -234,19 +233,35 @@ abstract class Connection implements ConnectionInterface
|
||||
protected function trigger(string $sql = '', bool $master = false): void
|
||||
{
|
||||
$listen = $this->db->getListen();
|
||||
|
||||
if (!empty($listen)) {
|
||||
$runtime = number_format((microtime(true) - $this->queryStartTime), 6);
|
||||
$sql = $sql ?: $this->getLastsql();
|
||||
|
||||
if (empty($this->config['deploy'])) {
|
||||
$master = null;
|
||||
}
|
||||
|
||||
foreach ($listen as $callback) {
|
||||
if (is_callable($callback)) {
|
||||
$callback($sql, $runtime, $master);
|
||||
if (empty($listen)) {
|
||||
$listen[] = function ($sql, $time, $master) {
|
||||
if (0 === strpos($sql, 'CONNECT:')) {
|
||||
$this->db->log($sql);
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录SQL
|
||||
if (is_bool($master)) {
|
||||
// 分布式记录当前操作的主从
|
||||
$master = $master ? 'master|' : 'slave|';
|
||||
} else {
|
||||
$master = '';
|
||||
}
|
||||
|
||||
$this->db->log($sql . ' [ ' . $master . 'RunTime:' . $time . 's ]');
|
||||
};
|
||||
}
|
||||
|
||||
$runtime = number_format((microtime(true) - $this->queryStartTime), 6);
|
||||
$sql = $sql ?: $this->getLastsql();
|
||||
|
||||
if (empty($this->config['deploy'])) {
|
||||
$master = null;
|
||||
}
|
||||
|
||||
foreach ($listen as $callback) {
|
||||
if (is_callable($callback)) {
|
||||
$callback($sql, $runtime, $master);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,11 +145,11 @@ interface ConnectionInterface
|
||||
* 得到某个列的数组
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $column 字段名 多个字段用逗号分隔
|
||||
* @param string|array $column 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @return array
|
||||
*/
|
||||
public function column(BaseQuery $query, string $column, string $key = ''): array;
|
||||
public function column(BaseQuery $query, $column, string $key = ''): array;
|
||||
|
||||
/**
|
||||
* 执行数据库事务
|
||||
|
@ -1135,12 +1135,12 @@ abstract class PDOConnection extends Connection
|
||||
/**
|
||||
* 得到某个列的数组
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $column 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string|array $column 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @return array
|
||||
*/
|
||||
public function column(BaseQuery $query, string $column, string $key = ''): array
|
||||
public function column(BaseQuery $query, $column, string $key = ''): array
|
||||
{
|
||||
$options = $query->parseOptions();
|
||||
|
||||
@ -1148,13 +1148,27 @@ abstract class PDOConnection extends Connection
|
||||
$query->removeOption('field');
|
||||
}
|
||||
|
||||
if ($key && '*' != $column) {
|
||||
$field = $key . ',' . $column;
|
||||
} else {
|
||||
$field = $column;
|
||||
if (empty($key) || trim($key) === '') {
|
||||
$key = null;
|
||||
}
|
||||
|
||||
$field = array_map('trim', explode(',', $field));
|
||||
if (\is_string($column)) {
|
||||
$column = \trim($column);
|
||||
if ('*' !== $column) {
|
||||
$column = \array_map('\trim', \explode(',', $column));
|
||||
}
|
||||
} elseif (\is_array($column)) {
|
||||
if (\in_array('*', $column)) {
|
||||
$column = '*';
|
||||
}
|
||||
} else {
|
||||
throw new DbException('not support type');
|
||||
}
|
||||
|
||||
$field = $column;
|
||||
if ('*' !== $column && $key && !\in_array($key, $column)) {
|
||||
$field[] = $key;
|
||||
}
|
||||
|
||||
$query->setOption('field', $field);
|
||||
|
||||
@ -1178,32 +1192,30 @@ abstract class PDOConnection extends Connection
|
||||
}
|
||||
|
||||
// 执行查询操作
|
||||
$pdo = $this->getPDOStatement($sql, $query->getBind(), $options['master']);
|
||||
|
||||
$pdo = $this->getPDOStatement($sql, $query->getBind(), $options['master']);
|
||||
$resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (is_string($key) && strpos($key, '.')) {
|
||||
[$alias, $key] = explode('.', $key);
|
||||
}
|
||||
|
||||
if (empty($resultSet)) {
|
||||
$result = [];
|
||||
} elseif (('*' == $column || strpos($column, ',')) && $key) {
|
||||
$result = array_column($resultSet, null, $key);
|
||||
} elseif ('*' !== $column && \count($column) === 1) {
|
||||
$column = \array_shift($column);
|
||||
if (\strpos($column, ' ')) {
|
||||
$column = \substr(\strrchr(\trim($column), ' '), 1);
|
||||
}
|
||||
|
||||
if (\strpos($column, '.')) {
|
||||
[$alias, $column] = \explode('.', $column);
|
||||
}
|
||||
|
||||
$result = \array_column($resultSet, $column, $key);
|
||||
} elseif ($key) {
|
||||
$result = \array_column($resultSet, null, $key);
|
||||
} else {
|
||||
if (empty($key)) {
|
||||
$key = null;
|
||||
}
|
||||
|
||||
if ('*' == $column || strpos($column, ',')) {
|
||||
$column = null;
|
||||
} elseif (strpos($column, ' ')) {
|
||||
$column = substr(strrchr(trim($column), ' '), 1);
|
||||
} elseif (strpos($column, '.')) {
|
||||
[$alias, $column] = explode('.', $column);
|
||||
}
|
||||
|
||||
if (is_string($key) && strpos($key, '.')) {
|
||||
[$alias, $key] = explode('.', $key);
|
||||
}
|
||||
|
||||
$result = array_column($resultSet, $column, $key);
|
||||
$result = $resultSet;
|
||||
}
|
||||
|
||||
if (isset($cacheItem)) {
|
||||
@ -1225,19 +1237,19 @@ abstract class PDOConnection extends Connection
|
||||
public function getRealSql(string $sql, array $bind = []): string
|
||||
{
|
||||
foreach ($bind as $key => $val) {
|
||||
$value = is_array($val) ? $val[0] : $val;
|
||||
$value = strval(is_array($val) ? $val[0] : $val);
|
||||
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
||||
|
||||
if ((self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) && is_string($value)) {
|
||||
if (self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) {
|
||||
$value = '\'' . addslashes($value) . '\'';
|
||||
} elseif (PDO::PARAM_INT == $type && '' === $value) {
|
||||
$value = 0;
|
||||
$value = '0';
|
||||
}
|
||||
|
||||
// 判断占位符
|
||||
$sql = is_numeric($key) ?
|
||||
substr_replace($sql, (string) $value, strpos($sql, '?'), 1) :
|
||||
substr_replace($sql, (string) $value, strpos($sql, ':' . $key), strlen(':' . $key));
|
||||
substr_replace($sql, $value, strpos($sql, '?'), 1) :
|
||||
substr_replace($sql, $value, strpos($sql, ':' . $key), strlen(':' . $key));
|
||||
}
|
||||
|
||||
return rtrim($sql);
|
||||
|
@ -29,6 +29,8 @@ use think\db\builder\Mongo as Builder;
|
||||
use think\db\Connection;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\db\Mongo as Query;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* Mongo数据库驱动
|
||||
@ -969,11 +971,12 @@ class Mongo extends Connection
|
||||
/**
|
||||
* 得到某个列的数组
|
||||
* @access public
|
||||
* @param string $field 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @param BaseQuery $query
|
||||
* @param string|array $field 字段名 多个字段用逗号分隔
|
||||
* @param string $key 索引
|
||||
* @return array
|
||||
*/
|
||||
public function column(BaseQuery $query, string $field, string $key = ''): array
|
||||
public function column(BaseQuery $query, $field, string $key = ''): array
|
||||
{
|
||||
$options = $query->parseOptions();
|
||||
|
||||
@ -981,6 +984,9 @@ class Mongo extends Connection
|
||||
$query->removeOption('projection');
|
||||
}
|
||||
|
||||
if (is_array($field)) {
|
||||
$field = implode(',', $field);
|
||||
}
|
||||
if ($key && '*' != $field) {
|
||||
$projection = $key . ',' . $field;
|
||||
} else {
|
||||
|
@ -117,6 +117,21 @@ class Collection extends BaseCollection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模型输出场景
|
||||
* @access public
|
||||
* @param string $scene 场景名称
|
||||
* @return $this
|
||||
*/
|
||||
public function scene(string $scene)
|
||||
{
|
||||
$this->each(function (Model $model) use ($scene) {
|
||||
$model->scene($scene);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置父模型
|
||||
* @access public
|
||||
|
@ -510,17 +510,15 @@ trait Attribute
|
||||
/**
|
||||
* 读取数据类型处理
|
||||
* @access protected
|
||||
* @param array $data 数据
|
||||
* @return void
|
||||
*/
|
||||
protected function readDataType(array &$data): void
|
||||
protected function readDataType(): void
|
||||
{
|
||||
foreach ($data as $name => &$value) {
|
||||
if (isset($this->type[$name])) {
|
||||
// 类型转换
|
||||
$value = $this->readTransform($value, $this->type[$name]);
|
||||
} elseif ($this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||
$value = $this->getTimestampValue($value);
|
||||
foreach ($this->data as $key => $value) {
|
||||
if (isset($this->type[$key])) {
|
||||
$this->data[$key] = $this->readTransform($value, $this->type[$key]);
|
||||
} elseif ($this->autoWriteTimestamp && in_array($key, [$this->createTime, $this->updateTime])) {
|
||||
$this->data[$key] = $this->getTimestampValue($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -537,9 +535,6 @@ trait Attribute
|
||||
if (isset($this->type[$name])) {
|
||||
// 类型转换
|
||||
$value = $this->writeTransform($value, $this->type[$name]);
|
||||
} elseif (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||
// 自动写入的时间戳字段
|
||||
$value = $this->autoWriteTimestamp();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,12 @@ trait Conversion
|
||||
*/
|
||||
protected $append = [];
|
||||
|
||||
/**
|
||||
* 场景
|
||||
* @var array
|
||||
*/
|
||||
protected $scene = [];
|
||||
|
||||
/**
|
||||
* 数据输出字段映射
|
||||
* @var array
|
||||
@ -85,6 +91,26 @@ trait Conversion
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输出层场景
|
||||
* @access public
|
||||
* @param string $scene 场景名称
|
||||
* @return $this
|
||||
*/
|
||||
public function scene(string $scene)
|
||||
{
|
||||
if (isset($this->scene[$scene])) {
|
||||
$data = $this->scene[$scene];
|
||||
foreach (['append', 'hidden', 'visible'] as $name) {
|
||||
if (isset($data[$name])) {
|
||||
$this->$name($data[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置附加关联对象的属性
|
||||
* @access public
|
||||
@ -255,11 +281,11 @@ trait Conversion
|
||||
$value = $this->getAttr($name);
|
||||
$item[$name] = $value;
|
||||
|
||||
$this->getBindAttr($name, $value, $item);
|
||||
$this->getBindAttrValue($name, $value, $item);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getBindAttr(string $name, $value, array &$item = [])
|
||||
protected function getBindAttrValue(string $name, $value, array &$item = [])
|
||||
{
|
||||
$relation = $this->isRelationAttr($name);
|
||||
if (!$relation) {
|
||||
|
@ -17,7 +17,6 @@ declare (strict_types=1);
|
||||
|
||||
namespace think\admin\command;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\NullLogger;
|
||||
use think\admin\Command;
|
||||
use think\Collection;
|
||||
@ -33,6 +32,7 @@ use think\console\Output;
|
||||
*/
|
||||
class Queue extends Command
|
||||
{
|
||||
const QUEUE_LISTEN = 'xadmin:queue listen';
|
||||
|
||||
/**
|
||||
* 任务编号
|
||||
@ -54,7 +54,7 @@ class Queue extends Command
|
||||
$this->setName('xadmin:queue');
|
||||
$this->addOption('host', '-H', Option::VALUE_OPTIONAL, 'The host of WebServer.');
|
||||
$this->addOption('port', '-p', Option::VALUE_OPTIONAL, 'The port of WebServer.');
|
||||
$this->addOption('daemon', 'd', Option::VALUE_NONE, 'Run the queue listen in daemon mode');
|
||||
$this->addOption('daemon', 'd', Option::VALUE_NONE, 'The queue listen in daemon mode');
|
||||
$this->addArgument('action', Argument::OPTIONAL, 'stop|start|status|query|listen|clean|dorun|webstop|webstart|webstatus', 'listen');
|
||||
$this->addArgument('code', Argument::OPTIONAL, 'Taskcode');
|
||||
$this->addArgument('spts', Argument::OPTIONAL, 'Separator');
|
||||
@ -69,9 +69,9 @@ class Queue extends Command
|
||||
*/
|
||||
public function execute(Input $input, Output $output)
|
||||
{
|
||||
$action = $this->input->hasOption('daemon') ? 'start' : $input->getArgument('action');
|
||||
$action = $input->hasOption('daemon') ? 'start' : $input->getArgument('action');
|
||||
if (method_exists($this, $method = "{$action}Action")) return $this->$method();
|
||||
$this->output->error(">> Wrong operation, Allow stop|start|status|query|listen|clean|dorun|webstop|webstart|webstatus");
|
||||
$this->output->error("># Wrong operation, Allow stop|start|status|query|listen|clean|dorun|webstop|webstart|webstatus");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,10 +81,10 @@ class Queue extends Command
|
||||
{
|
||||
$root = $this->app->getRootPath() . 'public' . DIRECTORY_SEPARATOR;
|
||||
if (count($result = $this->process->query("-t {$root} {$root}router.php")) < 1) {
|
||||
$this->output->writeln(">> There are no WebServer processes to stop");
|
||||
$this->output->writeln("># There are no WebServer processes to stop");
|
||||
} else foreach ($result as $item) {
|
||||
$this->process->close(intval($item['pid']));
|
||||
$this->output->writeln(">> Successfully sent end signal to process {$item['pid']}");
|
||||
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,11 +100,11 @@ class Queue extends Command
|
||||
$this->output->comment("># {$command}");
|
||||
if (count($result = $this->process->query($command)) > 0) {
|
||||
if ($this->process->iswin()) $this->process->exec("start http://{$host}:{$port}");
|
||||
$this->output->writeln(">> WebServer process already exist for pid {$result[0]['pid']}");
|
||||
$this->output->writeln("># WebServer process already exist for pid {$result[0]['pid']}");
|
||||
} else {
|
||||
[$this->process->create($command), usleep(2000)];
|
||||
$this->process->create($command, 2000);
|
||||
if (count($result = $this->process->query($command)) > 0) {
|
||||
$this->output->writeln(">> WebServer process started successfully for pid {$result[0]['pid']}");
|
||||
$this->output->writeln("># WebServer process started successfully for pid {$result[0]['pid']}");
|
||||
if ($this->process->iswin()) $this->process->exec("start http://{$host}:{$port}");
|
||||
} else {
|
||||
$this->output->writeln('>> WebServer process failed to start');
|
||||
@ -119,55 +119,62 @@ class Queue extends Command
|
||||
{
|
||||
$root = $this->app->getRootPath() . 'public' . DIRECTORY_SEPARATOR;
|
||||
if (count($result = $this->process->query("-t {$root} {$root}router.php")) > 0) {
|
||||
$this->output->comment("># {$result[0]['cmd']}");
|
||||
$this->output->writeln(">> WebServer process {$result[0]['pid']} running");
|
||||
$this->output->comment(">$ {$result[0]['cmd']}");
|
||||
$this->output->writeln("># WebServer process {$result[0]['pid']} running");
|
||||
} else {
|
||||
$this->output->writeln(">> The WebServer process is not running");
|
||||
$this->output->writeln("># The WebServer process is not running");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有任务
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function stopAction()
|
||||
{
|
||||
$keyword = $this->process->think('xadmin:queue');
|
||||
if (count($result = $this->process->query($keyword)) < 1) {
|
||||
$this->output->writeln(">> There are no task processes to stop");
|
||||
if (count($result = $this->process->thinkQuery('xadmin:queue')) < 1) {
|
||||
$this->output->writeln("># There are no task processes to stop");
|
||||
} else foreach ($result as $item) {
|
||||
$this->process->close(intval($item['pid']));
|
||||
$this->output->writeln(">> Successfully sent end signal to process {$item['pid']}");
|
||||
$this->output->writeln("># Successfully sent end signal to process {$item['pid']}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动后台任务
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function startAction()
|
||||
{
|
||||
$this->app->db->name($this->table)->count();
|
||||
$command = $this->process->think('xadmin:queue listen');
|
||||
$this->output->comment("># {$command}");
|
||||
if (count($result = $this->process->query($command)) > 0) {
|
||||
$this->output->writeln(">> Asynchronous daemons already exist for pid {$result[0]['pid']}");
|
||||
$this->output->comment(">$ {$this->process->think(static::QUEUE_LISTEN)}");
|
||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||
$this->output->writeln("># Queue daemons already exist for pid {$result[0]['pid']}");
|
||||
} else {
|
||||
[$this->process->create($command), usleep(1000)];
|
||||
if (count($result = $this->process->query($command)) > 0) {
|
||||
$this->output->writeln(">> Asynchronous daemons started successfully for pid {$result[0]['pid']}");
|
||||
$this->process->thinkCreate(static::QUEUE_LISTEN, 1000);
|
||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||
$this->output->writeln("># Queue daemons started successfully for pid {$result[0]['pid']}");
|
||||
} else {
|
||||
$this->output->writeln(">> Asynchronous daemons failed to start");
|
||||
$this->output->writeln("># Queue daemons failed to start");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有任务
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function queryAction()
|
||||
{
|
||||
$list = $this->process->query($this->process->think("xadmin:queue"));
|
||||
$list = $this->process->thinkQuery('xadmin:queue');
|
||||
if (count($list) > 0) foreach ($list as $item) {
|
||||
$this->output->writeln(">> {$item['pid']}\t{$item['cmd']}");
|
||||
$this->output->writeln("># {$item['pid']}\t{$item['cmd']}");
|
||||
} else {
|
||||
$this->output->writeln('>> No related task process found');
|
||||
}
|
||||
@ -175,7 +182,7 @@ class Queue extends Command
|
||||
|
||||
/**
|
||||
* 清理所有任务
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function cleanAction()
|
||||
{
|
||||
@ -204,11 +211,13 @@ class Queue extends Command
|
||||
|
||||
/**
|
||||
* 查询兼听状态
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function statusAction()
|
||||
{
|
||||
$command = $this->process->think('xadmin:queue listen');
|
||||
if (count($result = $this->process->query($command)) > 0) {
|
||||
if (count($result = $this->process->thinkQuery(static::QUEUE_LISTEN)) > 0) {
|
||||
$this->output->writeln("Listening for main process {$result[0]['pid']} running");
|
||||
} else {
|
||||
$this->output->writeln("The Listening main process is not running");
|
||||
@ -217,7 +226,7 @@ class Queue extends Command
|
||||
|
||||
/**
|
||||
* 立即监听任务
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function listenAction()
|
||||
{
|
||||
@ -232,19 +241,19 @@ class Queue extends Command
|
||||
while (true) {
|
||||
[$start, $where] = [microtime(true), [['status', '=', 1], ['exec_time', '<=', time()]]];
|
||||
foreach ($this->app->db->name($this->table)->where($where)->order('exec_time asc')->cursor() as $vo) try {
|
||||
$command = $this->process->think("xadmin:queue dorun {$vo['code']} -");
|
||||
$this->output->comment("># {$command}");
|
||||
if (count($this->process->query($command)) > 0) {
|
||||
$this->output->writeln(">> Already in progress -> [{$vo['code']}] {$vo['title']}");
|
||||
$args = "xadmin:queue dorun {$vo['code']} -";
|
||||
$this->output->comment(">$ {$this->process->think($args)}");
|
||||
if (count($this->process->thinkQuery($args)) > 0) {
|
||||
$this->output->writeln("># Already in progress -> [{$vo['code']}] {$vo['title']}");
|
||||
} else {
|
||||
$this->process->create($command);
|
||||
$this->output->writeln(">> Created new process -> [{$vo['code']}] {$vo['title']}");
|
||||
$this->process->thinkCreate($args);
|
||||
$this->output->writeln("># Created new process -> [{$vo['code']}] {$vo['title']}");
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
} catch (\Exception $exception) {
|
||||
$this->app->db->name($this->table)->where(['code' => $vo['code']])->update([
|
||||
'status' => 4, 'outer_time' => time(), 'exec_desc' => $exception->getMessage(),
|
||||
]);
|
||||
$this->output->error(">> Execution failed -> [{$vo['code']}] {$vo['title']},{$exception->getMessage()}");
|
||||
$this->output->error("># Execution failed -> [{$vo['code']}] {$vo['title']},{$exception->getMessage()}");
|
||||
}
|
||||
if (microtime(true) < $start + 1) usleep(1000000);
|
||||
}
|
||||
@ -252,7 +261,7 @@ class Queue extends Command
|
||||
|
||||
/**
|
||||
* 执行任务内容
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function doRunAction()
|
||||
{
|
||||
@ -295,7 +304,7 @@ class Queue extends Command
|
||||
$this->updateQueue(3, $this->app->console->call(array_shift($attr), $attr)->fetch(), false);
|
||||
}
|
||||
}
|
||||
} catch (Exception | \Error | \Throwable $exception) {
|
||||
} catch (\Exception | \Throwable | \Error $exception) {
|
||||
$code = $exception->getCode();
|
||||
if (intval($code) !== 3) $code = 4;
|
||||
$this->updateQueue($code, $exception->getMessage());
|
||||
@ -307,7 +316,7 @@ class Queue extends Command
|
||||
* @param integer $status 任务状态
|
||||
* @param string $message 消息内容
|
||||
* @param boolean $isSplit 是否分隔
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function updateQueue(int $status, string $message, bool $isSplit = true)
|
||||
{
|
||||
@ -331,7 +340,7 @@ class Queue extends Command
|
||||
if (isset($this->queue->record['loops_time']) && $this->queue->record['loops_time'] > 0) {
|
||||
try {
|
||||
$this->queue->initialize($this->code)->reset($this->queue->record['loops_time']);
|
||||
} catch (Exception | \Error | \Throwable $exception) {
|
||||
} catch (\Exception | \Throwable | \Error $exception) {
|
||||
$this->app->log->error("Queue {$this->queue->record['code']} Loops Failed. {$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ class AdminService extends Service
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function apply(bool $force = false)
|
||||
public function apply(bool $force = false): AdminService
|
||||
{
|
||||
if ($force) $this->clearCache();
|
||||
if (($uid = $this->app->session->get('user.id'))) {
|
||||
@ -145,7 +145,7 @@ class AdminService extends Service
|
||||
* 清理节点缓存
|
||||
* @return $this
|
||||
*/
|
||||
public function clearCache()
|
||||
public function clearCache(): AdminService
|
||||
{
|
||||
TokenService::instance()->clearCache();
|
||||
$this->app->cache->delete('SystemAuthNode');
|
||||
|
@ -201,7 +201,7 @@ class MessageService extends Service
|
||||
* 查询国内短信余额
|
||||
* @return array
|
||||
*/
|
||||
public function queryChinaSmsBalance()
|
||||
public function queryChinaSmsBalance(): array
|
||||
{
|
||||
$tkey = date("YmdHis");
|
||||
$result = HttpExtend::get('http://www.ztsms.cn/balanceN.do', [
|
||||
|
@ -30,12 +30,47 @@ class ProcessService extends Service
|
||||
/**
|
||||
* 获取 Think 指令内容
|
||||
* @param string $args 指定参数
|
||||
* @param boolean $simple 指令内容
|
||||
* @return string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function think(string $args = ''): string
|
||||
public function think(string $args = '', $simple = false): string
|
||||
{
|
||||
$root = $this->app->getRootPath();
|
||||
return trim("php {$root}think {$args}");
|
||||
if ($simple) {
|
||||
return trim("{$this->app->getRootPath()}think {$args}");
|
||||
} else {
|
||||
$binary = sysconf('base.binary') ?: 'php';
|
||||
return trim("{$binary} {$this->app->getRootPath()}think {$args}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 Think 运行进程
|
||||
* @param string $args
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function thinkQuery(string $args): array
|
||||
{
|
||||
return $this->query($this->think($args, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 Think 指令内容
|
||||
* @param string $args 执行参数
|
||||
* @param integer $usleep 延时时间
|
||||
* @return ProcessService
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function thinkCreate(string $args, $usleep = 0): ProcessService
|
||||
{
|
||||
return $this->create($this->think($args), $usleep);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,15 +85,19 @@ class ProcessService extends Service
|
||||
/**
|
||||
* 创建异步进程
|
||||
* @param string $command 任务指令
|
||||
* @param integer $usleep 延时时间
|
||||
* @return $this
|
||||
*/
|
||||
public function create(string $command): ProcessService
|
||||
public function create(string $command, $usleep = 0): ProcessService
|
||||
{
|
||||
if ($this->iswin()) {
|
||||
$this->exec(__DIR__ . "/bin/console.exe {$command}");
|
||||
} else {
|
||||
$this->exec("{$command} > /dev/null 2>&1 &");
|
||||
}
|
||||
if ($usleep > 0) {
|
||||
usleep($usleep);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -124,7 +163,7 @@ class ProcessService extends Service
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息空白字符过滤
|
||||
* 清除空白字符过滤
|
||||
* @param string $content
|
||||
* @param string $tochar
|
||||
* @return string
|
||||
|
@ -203,17 +203,17 @@ class QueueService extends Service
|
||||
/**
|
||||
* 更新任务进度
|
||||
* @param integer $total 记录总和
|
||||
* @param integer $used 当前记录
|
||||
* @param integer $count 当前记录
|
||||
* @param string $message 文字描述
|
||||
* @param integer $backline 回退行数
|
||||
*/
|
||||
public function message(int $total, int $used, string $message = '', $backline = 0): void
|
||||
public function message(int $total, int $count, string $message = '', $backline = 0): void
|
||||
{
|
||||
$total = $total < 1 ? 1 : $total;
|
||||
$prefix = str_pad("{$used}", strlen("{$total}"), '0', STR_PAD_LEFT);
|
||||
$prefix = str_pad("{$count}", strlen("{$total}"), '0', STR_PAD_LEFT);
|
||||
$message = "[{$prefix}/{$total}] {$message}";
|
||||
if (defined('WorkQueueCode')) {
|
||||
$this->progress(2, $message, sprintf("%.2f", $used / $total * 100), $backline);
|
||||
$this->progress(2, $message, sprintf("%.2f", $count / $total * 100), $backline);
|
||||
} else {
|
||||
echo $message . PHP_EOL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user