mirror of
https://github.com/netcccyun/dnsmgr.git
synced 2026-05-13 00:26:27 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
933f98a909 | ||
|
|
3beb0ec637 | ||
|
|
7a92ad7094 | ||
|
|
5dc4dbfabd | ||
|
|
291f715e91 | ||
|
|
4f15d4d7a2 | ||
|
|
11e83860b7 | ||
|
|
479af4fe5f |
@@ -458,7 +458,7 @@ class Cert extends BaseController
|
||||
$ids = input('post.ids');
|
||||
$success = 0;
|
||||
foreach ($ids as $id) {
|
||||
if (input('post.action') == 'delete') {
|
||||
if (input('post.act') == 'delete') {
|
||||
$dcount = DB::name('cert_deploy')->where('oid', $id)->count();
|
||||
if ($dcount > 0) continue;
|
||||
try {
|
||||
@@ -468,7 +468,7 @@ class Cert extends BaseController
|
||||
Db::name('cert_order')->where('id', $id)->delete();
|
||||
Db::name('cert_domain')->where('oid', $id)->delete();
|
||||
$success++;
|
||||
} elseif (input('post.action') == 'reset') {
|
||||
} elseif (input('post.act') == 'reset') {
|
||||
try {
|
||||
$service = new CertOrderService($id);
|
||||
$service->cancel();
|
||||
@@ -476,8 +476,8 @@ class Cert extends BaseController
|
||||
$success++;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
} elseif (input('post.action') == 'open' || input('post.action') == 'close') {
|
||||
$isauto = input('post.action') == 'open' ? 1 : 0;
|
||||
} elseif (input('post.act') == 'open' || input('post.act') == 'close') {
|
||||
$isauto = input('post.act') == 'open' ? 1 : 0;
|
||||
Db::name('cert_order')->where('id', $id)->update(['isauto' => $isauto]);
|
||||
$success++;
|
||||
}
|
||||
@@ -754,21 +754,21 @@ class Cert extends BaseController
|
||||
if (!$cert) return json(['code' => -1, 'msg' => '证书订单不存在']);
|
||||
}
|
||||
foreach ($ids as $id) {
|
||||
if (input('post.action') == 'delete') {
|
||||
if (input('post.act') == 'delete') {
|
||||
Db::name('cert_deploy')->where('id', $id)->delete();
|
||||
$success++;
|
||||
} elseif (input('post.action') == 'reset') {
|
||||
} elseif (input('post.act') == 'reset') {
|
||||
try {
|
||||
$service = new CertDeployService($id);
|
||||
$service->reset();
|
||||
$success++;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
} elseif (input('post.action') == 'open' || input('post.action') == 'close') {
|
||||
$active = input('post.action') == 'open' ? 1 : 0;
|
||||
} elseif (input('post.act') == 'open' || input('post.act') == 'close') {
|
||||
$active = input('post.act') == 'open' ? 1 : 0;
|
||||
Db::name('cert_deploy')->where('id', $id)->update(['active' => $active]);
|
||||
$success++;
|
||||
} elseif (input('post.action') == 'cert') {
|
||||
} elseif (input('post.act') == 'cert') {
|
||||
Db::name('cert_deploy')->where('id', $id)->update(['oid' => $certid]);
|
||||
$success++;
|
||||
}
|
||||
|
||||
@@ -998,6 +998,24 @@ class DeployHelper
|
||||
'show' => 'product==\'lighthouse\'||product==\'ddos\'',
|
||||
'required' => true,
|
||||
],
|
||||
'site_type' => [
|
||||
'name' => '站点类型',
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
['value'=>'cn', 'label'=>'国内站'],
|
||||
['value'=>'intl', 'label'=>'国际站'],
|
||||
],
|
||||
'value' => 'cn',
|
||||
'show' => 'product==\'teo\'',
|
||||
'required' => true,
|
||||
],
|
||||
'site_id' => [
|
||||
'name' => '站点ID',
|
||||
'type' => 'input',
|
||||
'placeholder' => '类似于zone-xxxx,在站点列表或概览页面查看',
|
||||
'show' => 'product==\'teo\'',
|
||||
'required' => true,
|
||||
],
|
||||
'domain' => [
|
||||
'name' => '绑定的域名',
|
||||
'type' => 'input',
|
||||
@@ -1866,6 +1884,12 @@ class DeployHelper
|
||||
'show' => 'format==\'pfx\'',
|
||||
'required' => true,
|
||||
],
|
||||
'cmd_pre' => [
|
||||
'name' => '上传前执行命令',
|
||||
'type' => 'textarea',
|
||||
'show' => 'format==\'pem\'||uptype==0',
|
||||
'placeholder' => '可留空,上传前执行脚本命令',
|
||||
],
|
||||
'cmd' => [
|
||||
'name' => '上传完执行命令',
|
||||
'type' => 'textarea',
|
||||
|
||||
@@ -264,6 +264,12 @@ class aliyun implements DeployInterface
|
||||
$domain = $config['domain'];
|
||||
if (empty($domain)) throw new Exception('WAF绑定域名不能为空');
|
||||
|
||||
if ($config['region'] == 'ap-southeast-1') {
|
||||
$cert_id .= '-ap-southeast-1';
|
||||
} else {
|
||||
$cert_id .= '-cn-hangzhou';
|
||||
}
|
||||
|
||||
$endpoint = 'wafopenapi.' . $config['region'] . '.aliyuncs.com';
|
||||
|
||||
$client = new AliyunClient($this->AccessKeyId, $this->AccessKeySecret, $endpoint, '2021-10-01', $this->proxy);
|
||||
@@ -292,17 +298,19 @@ class aliyun implements DeployInterface
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('查询CNAME接入详情失败:' . $e->getMessage());
|
||||
}
|
||||
if (!isset($data['Listen'])) {
|
||||
throw new Exception('没有找到' . $domain . '监听器');
|
||||
}
|
||||
|
||||
if (isset($data['Listen']['CertId'])) {
|
||||
$old_cert_id = $data['Listen']['CertId'];
|
||||
if (strpos($old_cert_id, '-')) $old_cert_id = substr($old_cert_id, 0, strpos($old_cert_id, '-'));
|
||||
if (!empty($old_cert_id) && $old_cert_id == $cert_id) {
|
||||
$this->log('WAF域名 ' . $domain . ' 证书已配置,无需重复操作');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$data['Listen']['CertId'] = $cert_id . '-cn-hangzhou';
|
||||
$data['Listen']['CertId'] = $cert_id;
|
||||
if (empty($data['Listen']['HttpsPorts'])) $data['Listen']['HttpsPorts'] = [443];
|
||||
$data['Redirect']['Backends'] = $data['Redirect']['AllBackends'];
|
||||
$param = [
|
||||
|
||||
@@ -23,6 +23,14 @@ class ssh implements DeployInterface
|
||||
public function deploy($fullchain, $privatekey, $config, &$info)
|
||||
{
|
||||
$connection = $this->connect();
|
||||
if (isset($config['cmd_pre']) && !empty($config['cmd_pre'])) {
|
||||
$cmds = explode("\n", $config['cmd_pre']);
|
||||
foreach ($cmds as $cmd) {
|
||||
$cmd = trim($cmd);
|
||||
if (empty($cmd)) continue;
|
||||
$this->exec($connection, $cmd);
|
||||
}
|
||||
}
|
||||
$sftp = ssh2_sftp($connection);
|
||||
if ($config['format'] == 'pem') {
|
||||
$stream = fopen("ssh2.sftp://$sftp{$config['pem_cert_file']}", 'w');
|
||||
|
||||
@@ -60,6 +60,8 @@ class tencent implements DeployInterface
|
||||
return $this->deploy_clb($cert_id, $config);
|
||||
} elseif ($config['product'] == 'scf') {
|
||||
return $this->deploy_scf($cert_id, $config);
|
||||
} elseif ($config['product'] == 'teo' && isset($config['site_id'])) {
|
||||
return $this->deploy_teo($cert_id, $config);
|
||||
} else {
|
||||
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||
if ($config['product'] == 'waf') {
|
||||
@@ -122,11 +124,17 @@ class tencent implements DeployInterface
|
||||
} else {
|
||||
$instance_ids = [$instance_id];
|
||||
}
|
||||
if ($product == 'cdn') {
|
||||
$instance_ids = array_map(function ($id) {
|
||||
return $id . '|on';
|
||||
}, $instance_ids);
|
||||
}
|
||||
$param = [
|
||||
'CertificateId' => $cert_id,
|
||||
'InstanceIdList' => $instance_ids,
|
||||
'ResourceType' => $product,
|
||||
];
|
||||
if ($product == 'live') $param['Status'] = 1;
|
||||
$data = $this->client->request('DeployCertificateInstance', $param);
|
||||
$this->log(json_encode($data));
|
||||
$this->log(strtoupper($product) . '实例 ' . $instance_id . ' 部署证书成功!');
|
||||
@@ -253,6 +261,26 @@ class tencent implements DeployInterface
|
||||
$this->log('云函数自定义域名 ' . $config['domain'] . ' 部署证书成功!');
|
||||
}
|
||||
|
||||
private function deploy_teo($cert_id, $config)
|
||||
{
|
||||
if (empty($config['site_id'])) throw new Exception('站点ID不能为空');
|
||||
if (empty($config['domain'])) throw new Exception('绑定的域名不能为空');
|
||||
|
||||
$endpoint = isset($config['site_type']) && $config['site_type'] == 'intl' ? 'teo.intl.tencentcloudapi.com' : 'teo.tencentcloudapi.com';
|
||||
$client = new TencentCloud($this->SecretId, $this->SecretKey, $endpoint, 'teo', '2022-09-01', null, $this->proxy);
|
||||
$hosts = explode(',', $config['domain']);
|
||||
$param = [
|
||||
'ZoneId' => $config['site_id'],
|
||||
'Hosts' => $hosts,
|
||||
'Mode' => 'sslcert',
|
||||
'ServerCertInfo' => [[
|
||||
'CertId' => $cert_id
|
||||
]]
|
||||
];
|
||||
$data = $client->request('ModifyHostsCertificate', $param);
|
||||
$this->log('边缘安全加速域名 ' . $config['domain'] . ' 部署证书成功!');
|
||||
}
|
||||
|
||||
public function setLogger($func)
|
||||
{
|
||||
$this->logger = $func;
|
||||
|
||||
@@ -39,9 +39,7 @@ class OptimizeService
|
||||
public function get_ip_address($cdn_type = 1, $ip_type = 'v4')
|
||||
{
|
||||
$api = config_get('optimize_ip_api', 0);
|
||||
if ($api == 2) {
|
||||
$url = 'https://api.345673.xyz/get_data';
|
||||
} elseif ($api == 1) {
|
||||
if ($api == 1) {
|
||||
$url = 'https://api.hostmonit.com/get_optimization_ip';
|
||||
} else {
|
||||
$url = 'https://www.wetest.vip/api/cf2dns/';
|
||||
@@ -51,6 +49,8 @@ class OptimizeService
|
||||
$url .= 'get_cloudfront_ip';
|
||||
} elseif ($cdn_type == 3) {
|
||||
$url .= 'get_gcore_ip';
|
||||
} elseif ($cdn_type == 4) {
|
||||
$url .= 'get_edgeone_ip';
|
||||
}
|
||||
}
|
||||
$params = [
|
||||
|
||||
@@ -454,7 +454,7 @@ function operation(action){
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/cert/order/operation',
|
||||
data : {action: action, ids: ids},
|
||||
data : {act: action, ids: ids},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
|
||||
@@ -317,7 +317,7 @@ function operation(action){
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/cert/deploy/operation',
|
||||
data : {action: action, ids: ids},
|
||||
data : {act: action, ids: ids},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
@@ -337,7 +337,7 @@ function batch_set_cert(ids){
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/cert/deploy/operation',
|
||||
data : {action: 'cert', ids: ids, certid: text},
|
||||
data : {act: 'cert', ids: ids, certid: text},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
<link href="/static/css/app.min.css" rel="stylesheet">
|
||||
<link href="/static/css/skins/{$skin}.css" rel="stylesheet">
|
||||
<link href="/static/css/bootstrap-table.css?v=2" rel="stylesheet"/>
|
||||
{if file_exists(public_path() . 'static/css/custom.css')}
|
||||
<link href="/static/css/custom.css" rel="stylesheet">
|
||||
{/if}
|
||||
<script src="{$cdnpublic}jquery/3.6.4/jquery.min.js"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{$cdnpublic}html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
|
||||
@@ -175,7 +175,7 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
<div id="searchbox1">
|
||||
<div class="form-group">
|
||||
<label>搜索</label>
|
||||
<input type="text" class="form-control" name="keyword" placeholder="输入关键字">
|
||||
<input type="text" class="form-control" name="keyword" placeholder="输入关键字">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="status" class="form-control"><option value="">所有状态</option><option value="1">启用</option><option value="0">暂停</option></select>
|
||||
@@ -213,13 +213,13 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="subdomain" placeholder="输入主机记录">
|
||||
<input type="text" class="form-control" name="subdomain" placeholder="输入主机记录">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select name="line" class="form-control"><option value="">全部线路</option></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" name="value" placeholder="输入记录值">
|
||||
<input type="text" class="form-control" name="value" placeholder="输入记录值">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
||||
<a href="javascript:searchClear()" class="btn btn-default" title="刷新解析记录列表"><i class="fa fa-refresh"></i> 刷新</a>
|
||||
@@ -227,9 +227,9 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:360px;
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table id="listTable">
|
||||
<table id="listTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -269,10 +269,10 @@ $(document).ready(function(){
|
||||
visible: false,
|
||||
title: '记录ID'
|
||||
},
|
||||
{
|
||||
field: 'Name',
|
||||
title: '主机记录'
|
||||
},
|
||||
{
|
||||
field: 'Name',
|
||||
title: '主机记录'
|
||||
},
|
||||
{
|
||||
field: 'Type',
|
||||
title: '记录类型',
|
||||
@@ -282,18 +282,26 @@ $(document).ready(function(){
|
||||
return value;
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
field: 'LineName',
|
||||
title: '线路类型'
|
||||
},
|
||||
{
|
||||
field: 'Value',
|
||||
title: '记录值',
|
||||
formatter: function(value, row, index) {
|
||||
if(row.Type == 'MX') return value + ' | '+row.MX;
|
||||
return value;
|
||||
}
|
||||
},
|
||||
field: 'Value',
|
||||
title: '记录值',
|
||||
formatter: function(value, row, index) {
|
||||
var copyId = 'copy-value-' + row.RecordId;
|
||||
if(row.Type == 'MX') {
|
||||
// 只复制 mx.yandex.net,按钮在其右侧,优先级单独显示
|
||||
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+value+'</span>'
|
||||
+ '<a href="javascript:void(0);" title="复制记录值" onclick="copyToClipboard(null, \'#'+copyId+'\')" style="padding-left:6px;"><i class=\"fa fa-copy\"></i></a>'
|
||||
+ '<span class="mx-priority"> | '+row.MX+'</span>';
|
||||
} else {
|
||||
return '<span id="'+copyId+'" data-value="'+htmlEscape(value)+'">'+value+'</span>'
|
||||
+ '<a href="javascript:void(0);" title="复制记录值" onclick="copyToClipboard(null, \'#'+copyId+'\')" style="padding-left:6px;"><i class=\"fa fa-copy\"></i></a>';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'TTL',
|
||||
title: 'TTL'
|
||||
@@ -339,8 +347,12 @@ $(document).ready(function(){
|
||||
}
|
||||
html += '<a href="javascript:delItem(\''+row.RecordId+'\')" class="btn btn-danger btn-xs">删除</a> ';
|
||||
if(dnsconfig.remark == 1){
|
||||
html += '<a href="javascript:setRemark(\''+row.RecordId+'\')" class="btn btn-info btn-xs">备注</a>';
|
||||
html += '<a href="javascript:setRemark(\''+row.RecordId+'\')" class="btn btn-info btn-xs">备注</a> ';
|
||||
}
|
||||
if(row.Name === "@") var domain = "{$domainName}";
|
||||
else var domain = row.Name + ".{$domainName}";
|
||||
domain = domain.replace(/\*/g, 'www');
|
||||
html += '<a href="http://' + domain + '" target="_blank" title="访问域名" class="btn btn-default btn-xs"><i class="fa fa-external-link"></i></a>';
|
||||
return html;
|
||||
}
|
||||
},
|
||||
@@ -719,5 +731,39 @@ function advanceSearch(){
|
||||
$("#searchbox1").slideDown();
|
||||
}
|
||||
}
|
||||
function copyToClipboard(text, selector) {
|
||||
if (!text && selector) {
|
||||
var el = document.querySelector(selector);
|
||||
if (el) {
|
||||
text = el.getAttribute('data-value');
|
||||
}
|
||||
}
|
||||
var tempInput = document.createElement('input');
|
||||
tempInput.style.position = 'absolute';
|
||||
tempInput.style.left = '-9999px';
|
||||
tempInput.value = text;
|
||||
document.body.appendChild(tempInput);
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(tempInput);
|
||||
if(selector){
|
||||
var icon = document.querySelector(selector + ' + a i');
|
||||
if(icon){
|
||||
var oldClass = icon.className;
|
||||
icon.className = 'fa fa-check';
|
||||
setTimeout(function(){ icon.className = oldClass; }, 1000);
|
||||
}
|
||||
}
|
||||
layer.msg('已复制到剪贴板', {icon: 1, time: 600});
|
||||
}
|
||||
// 工具函数:HTML转义,防止XSS
|
||||
function htmlEscape(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -129,7 +129,7 @@ new Vue({
|
||||
cdntypeList: {
|
||||
1:'CloudFlare',
|
||||
2:"CloudFront",
|
||||
3:'Gcore'
|
||||
4:'EdgeOne'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -75,6 +75,8 @@ $(document).ready(function(){
|
||||
return 'CloudFront';
|
||||
}else if(value == 3){
|
||||
return 'Gcore';
|
||||
}else if(value == 4){
|
||||
return 'EdgeOne';
|
||||
}else{
|
||||
return '未知';
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="panel-heading"><h3 class="panel-title">使用说明</h3></div>
|
||||
<div class="panel-body">
|
||||
<p><li>不支持对CloudFlare里的域名添加优选,必须使用其他DNS服务商。需开通Cloudflare for SaaS,且域名使用CNAME的方式解析到CloudFlare。</li></p>
|
||||
<p><li>数据接口:<a href="https://www.wetest.vip/" target="_blank" rel="noreferrer">wetest.vip</a> 数据接口支持CloudFlare、CloudFront、Gcore;<a href="https://stock.hostmonit.com/" target="_blank" rel="noreferrer">HostMonit</a> 只支持CloudFlare。</li></p>
|
||||
<p><li>数据接口:<a href="https://www.wetest.vip/" target="_blank" rel="noreferrer">wetest.vip</a> 数据接口支持CloudFlare、CloudFront、EdgeOne;<a href="https://stock.hostmonit.com/" target="_blank" rel="noreferrer">HostMonit</a> 只支持CloudFlare。</li></p>
|
||||
<p><li>接口密钥:默认o1zrmHAF为免费KEY可永久免费使用。</li></p>
|
||||
<p><li>计划任务:将以下命令添加到计划任务,周期设置为15分钟以上</li></p>
|
||||
<p><code>cd {:app()->getRootPath()} && php think opiptask</code></p>
|
||||
|
||||
24
composer.lock
generated
24
composer.lock
generated
@@ -1507,16 +1507,16 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v4.0.45",
|
||||
"version": "v4.0.46",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "ea2e627af7306f7714e4baafc70943cad954cc77"
|
||||
"reference": "4bb0a5679a97db8de1c0eb02bbbe179cb3afd901"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/ea2e627af7306f7714e4baafc70943cad954cc77",
|
||||
"reference": "ea2e627af7306f7714e4baafc70943cad954cc77",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/4bb0a5679a97db8de1c0eb02bbbe179cb3afd901",
|
||||
"reference": "4bb0a5679a97db8de1c0eb02bbbe179cb3afd901",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1561,9 +1561,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/top-think/think-orm/issues",
|
||||
"source": "https://github.com/top-think/think-orm/tree/v4.0.45"
|
||||
"source": "https://github.com/top-think/think-orm/tree/v4.0.46"
|
||||
},
|
||||
"time": "2025-06-24T00:00:32+00:00"
|
||||
"time": "2025-06-26T06:05:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-template",
|
||||
@@ -1727,16 +1727,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e"
|
||||
"reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/548f6760c54197b1084e1e5c71f6d9d523f2f78e",
|
||||
"reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/6e209fbe5f5a7b6043baba46fe5735a4b85d0d42",
|
||||
"reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1791,7 +1791,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1807,7 +1807,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-27T18:39:23+00:00"
|
||||
"time": "2025-06-27T19:55:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-trace",
|
||||
|
||||
@@ -31,7 +31,7 @@ return [
|
||||
'show_error_msg' => true,
|
||||
'exception_tmpl' => \think\facade\App::getAppPath() . 'view/exception.tpl',
|
||||
|
||||
'version' => '1037',
|
||||
'version' => '1038',
|
||||
|
||||
'dbversion' => '1033'
|
||||
];
|
||||
|
||||
0
public/static/css/custom.css
Normal file
0
public/static/css/custom.css
Normal file
Reference in New Issue
Block a user