mirror of
https://github.com/acepanel/panel.git
synced 2026-02-05 08:07:17 +08:00
feat: update
This commit is contained in:
@@ -73,7 +73,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
color.Greenln("初始化成功")
|
||||
|
||||
case "update":
|
||||
err := tools.UpdatePanel()
|
||||
input := arg1
|
||||
proxy := false
|
||||
if input == "y" || input == "Y" || input == "yes" || input == "Yes" {
|
||||
proxy = true
|
||||
}
|
||||
err := tools.UpdatePanel(cast.ToBool(proxy))
|
||||
if err != nil {
|
||||
color.Redln("更新失败: " + err.Error())
|
||||
return nil
|
||||
@@ -279,7 +284,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
default:
|
||||
color.Yellowln(facades.Config().GetString("panel.name") + "命令行工具 - " + facades.Config().GetString("panel.version"))
|
||||
color.Greenln("请使用以下命令:")
|
||||
color.Greenln("panel update 更新/修复面板到最新版本")
|
||||
color.Greenln("panel update {proxy} 更新/修复面板到最新版本")
|
||||
color.Greenln("panel getInfo 重新初始化面板账号信息")
|
||||
color.Greenln("panel getPort 获取面板访问端口")
|
||||
color.Greenln("panel getEntrance 获取面板访问入口")
|
||||
@@ -287,7 +292,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} 备份网站/MySQL数据库/PostgreSQL数据库到指定目录")
|
||||
color.Redln("以下命令请在开发者指导下使用:")
|
||||
color.Yellowln("panel init 初始化面板")
|
||||
color.Yellowln("panel writePlugin {slug} 写入插件安装状态")
|
||||
color.Yellowln("panel writePlugin {slug} {version} 写入插件安装状态")
|
||||
color.Yellowln("panel deletePlugin {slug} 移除插件安装状态")
|
||||
color.Yellowln("panel writeMysqlPassword {password} 写入MySQL root密码")
|
||||
color.Yellowln("panel writeSite {name} {status} {path} {php} {ssl} 写入网站数据到面板")
|
||||
|
||||
@@ -122,3 +122,42 @@ func (r *InfoController) InstalledDbAndPhp(ctx http.Context) {
|
||||
"postgresql": postgresqlInstalled,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *InfoController) CheckUpdate(ctx http.Context) {
|
||||
version := facades.Config().GetString("panel.version")
|
||||
remote, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusInternalServerError, "获取最新版本失败")
|
||||
return
|
||||
}
|
||||
|
||||
if version == remote.Version {
|
||||
Success(ctx, http.Json{
|
||||
"update": false,
|
||||
"version": remote.Version,
|
||||
"name": remote.Name,
|
||||
"body": remote.Body,
|
||||
"date": remote.Date,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"update": true,
|
||||
"version": remote.Version,
|
||||
"name": remote.Name,
|
||||
"body": remote.Body,
|
||||
"date": remote.Date,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *InfoController) Update(ctx http.Context) {
|
||||
proxy := ctx.Request().InputBool("proxy")
|
||||
err := tools.UpdatePanel(proxy)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusInternalServerError, "更新失败")
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -170,6 +170,11 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !tools.Exists("/www/wwwlogs/nginx_error.log") {
|
||||
controllers.Success(ctx, "")
|
||||
return
|
||||
}
|
||||
|
||||
out := tools.ExecShell("tail -n 100 /www/wwwlogs/nginx_error.log")
|
||||
controllers.Success(ctx, out)
|
||||
}
|
||||
@@ -180,7 +185,7 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
_ = tools.ExecShell("echo '' > /www/wwwlogs/nginx_error.log")
|
||||
tools.ExecShell("echo '' > /www/wwwlogs/nginx_error.log")
|
||||
controllers.Success(ctx, "清空OpenResty错误日志成功")
|
||||
}
|
||||
|
||||
@@ -199,42 +204,64 @@ func (r *OpenRestyController) Load(ctx http.Context) {
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
var data map[int]map[string]any
|
||||
type nginxStatus struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
var data []nginxStatus
|
||||
|
||||
out := tools.ExecShell("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
workers := strings.TrimSpace(out)
|
||||
data[0]["name"] = "工作进程"
|
||||
data[0]["value"] = workers
|
||||
data = append(data, nginxStatus{
|
||||
Name: "工作进程",
|
||||
Value: workers,
|
||||
})
|
||||
|
||||
out = tools.ExecShell("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
mem := tools.FormatBytes(cast.ToFloat64(strings.TrimSpace(out)))
|
||||
data[1]["name"] = "内存占用"
|
||||
data[1]["value"] = mem
|
||||
data = append(data, nginxStatus{
|
||||
Name: "内存占用",
|
||||
Value: mem,
|
||||
})
|
||||
|
||||
match := regexp.MustCompile(`Active connections:\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 2 {
|
||||
data[2]["name"] = "活跃连接数"
|
||||
data[2]["value"] = match[1]
|
||||
data = append(data, nginxStatus{
|
||||
Name: "活跃连接数",
|
||||
Value: match[1],
|
||||
})
|
||||
}
|
||||
|
||||
match = regexp.MustCompile(`server accepts handled requests\s+(\d+)\s+(\d+)\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 4 {
|
||||
data[3]["name"] = "总连接次数"
|
||||
data[3]["value"] = match[1]
|
||||
data[4]["name"] = "总握手次数"
|
||||
data[4]["value"] = match[2]
|
||||
data[5]["name"] = "总请求次数"
|
||||
data[5]["value"] = match[3]
|
||||
data = append(data, nginxStatus{
|
||||
Name: "总连接次数",
|
||||
Value: match[1],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
Name: "总握手次数",
|
||||
Value: match[2],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
Name: "总请求次数",
|
||||
Value: match[3],
|
||||
})
|
||||
}
|
||||
|
||||
match = regexp.MustCompile(`Reading:\s+(\d+)\s+Writing:\s+(\d+)\s+Waiting:\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 4 {
|
||||
data[6]["name"] = "请求数"
|
||||
data[6]["value"] = match[1]
|
||||
data[7]["name"] = "响应数"
|
||||
data[7]["value"] = match[2]
|
||||
data[8]["name"] = "驻留进程"
|
||||
data[8]["value"] = match[3]
|
||||
data = append(data, nginxStatus{
|
||||
Name: "请求数",
|
||||
Value: match[1],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
Name: "响应数",
|
||||
Value: match[2],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
Name: "驻留进程",
|
||||
Value: match[3],
|
||||
})
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (r *TaskController) Log(ctx http.Context) {
|
||||
|
||||
func (r *TaskController) Delete(ctx http.Context) {
|
||||
var task models.Task
|
||||
_, err := facades.Orm().Query().Where("id", ctx.Request().QueryInt("id")).Delete(&task)
|
||||
_, err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).Delete(&task)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][TaskController] 删除任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
@@ -8,6 +8,6 @@ func init() {
|
||||
config := facades.Config()
|
||||
config.Add("panel", map[string]any{
|
||||
"name": "耗子面板",
|
||||
"version": "2.0.0",
|
||||
"version": "v2.0.0",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func ExecShell(shell string) string {
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -64,13 +64,13 @@ func ExecShellAsync(shell string) {
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := cmd.Wait()
|
||||
if err != nil {
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
|
||||
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gookit/color"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
"github.com/shirou/gopsutil/host"
|
||||
@@ -114,17 +116,52 @@ func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
}
|
||||
|
||||
// UpdatePanel 更新面板
|
||||
func UpdatePanel() error {
|
||||
func UpdatePanel(proxy bool) error {
|
||||
panelInfo, err := GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("/bin/bash", "-c", "wget -O panel.tar.gz "+panelInfo.DownloadUrl+" && tar -zxvf panel.tar.gz && rm -rf panel.tar.gz && chmod +x panel && ./panel artisan migrate")
|
||||
_, err = cmd.Output()
|
||||
if err != nil {
|
||||
return errors.New("更新面板失败")
|
||||
color.Greenln("最新版本: " + panelInfo.Version)
|
||||
color.Greenln("下载链接: " + panelInfo.DownloadUrl)
|
||||
color.Greenln("使用代理: " + strconv.FormatBool(proxy))
|
||||
|
||||
color.Greenln("备份面板配置...")
|
||||
ExecShell("cp -f /www/panel/database/panel.db /tmp/panel.db.bak")
|
||||
ExecShell("cp -f /www/panel/panel.conf /tmp/panel.conf.bak")
|
||||
if !Exists("/tmp/panel.db.bak") || !Exists("/tmp/panel.conf.bak") {
|
||||
return errors.New("备份面板配置失败")
|
||||
}
|
||||
color.Greenln("备份完成")
|
||||
|
||||
color.Greenln("清理旧版本...")
|
||||
ExecShell("rm -rf /www/panel/*")
|
||||
color.Greenln("清理完成")
|
||||
|
||||
color.Greenln("正在下载...")
|
||||
if proxy {
|
||||
ExecShell("wget -O /www/panel/panel.zip https://ghproxy.com/" + panelInfo.DownloadUrl)
|
||||
} else {
|
||||
ExecShell("wget -O /www/panel/panel.zip " + panelInfo.DownloadUrl)
|
||||
}
|
||||
color.Greenln("下载完成")
|
||||
|
||||
color.Greenln("更新新版本...")
|
||||
ExecShell("cd /www/panel && unzip -o panel.zip && rm -rf panel.zip && chmod 700 panel")
|
||||
color.Greenln("更新完成")
|
||||
|
||||
color.Greenln("恢复面板配置...")
|
||||
ExecShell("cp -f /tmp/panel.db.bak /www/panel/database/panel.db")
|
||||
ExecShell("cp -f /tmp/panel.conf.bak /www/panel/panel.conf")
|
||||
if !Exists("/www/panel/database/panel.db") || !Exists("/www/panel/panel.conf") {
|
||||
return errors.New("恢复面板配置失败")
|
||||
}
|
||||
ExecShell("/www/panel/panel --env=panel.conf artisan migrate")
|
||||
color.Greenln("恢复完成")
|
||||
|
||||
color.Greenln("重启面板...")
|
||||
ExecShell("systemctl restart panel")
|
||||
color.Greenln("重启完成")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ layui.define(['laytpl', 'layer'], function (exports) {
|
||||
delete options.success
|
||||
delete options.error
|
||||
|
||||
if (options.type === 'post' || options.type === 'put' || options.type === 'delete' || options.type === 'patch' || options.type === 'POST' || options.type === 'PUT' || options.type === 'DELETE' || options.type === 'PATCH') {
|
||||
if (options.method === 'post' || options.method === 'put' || options.method === 'delete' || options.method === 'patch' || options.method === 'POST' || options.method === 'PUT' || options.method === 'DELETE' || options.method === 'PATCH') {
|
||||
options.contentType = 'application/json'
|
||||
options.data = JSON.stringify(options.data)
|
||||
}
|
||||
|
||||
@@ -320,22 +320,50 @@ Date: 2023-06-22
|
||||
layer.msg('获取版本信息失败,请刷新重试!')
|
||||
return false
|
||||
}
|
||||
if (result.data.version) {
|
||||
admin.popup({
|
||||
title: '提示'
|
||||
,
|
||||
shade: 0
|
||||
,
|
||||
anim: -1
|
||||
,
|
||||
area: ['400px', '200px']
|
||||
,
|
||||
id: 'layadmin-layer-skin-update-panel'
|
||||
,
|
||||
skin: 'layui-anim layui-anim-upbit'
|
||||
,
|
||||
content: '最新版本:' + result.data.version + '<br><br>更新日志:' + result.data.describe + '<br><br>请在SSH执行<span class="layui-badge-rim">panel update</span>以更新面板!'
|
||||
})
|
||||
if (result.data.update) {
|
||||
layer.confirm('更新日期: <br>'+new Date(result.data.date).toLocaleString()+'<br>更新日志: <pre>'+result.data.body+'</pre>', {
|
||||
title: '最新版本: '+result.data.version+' ,是否更新?',
|
||||
btn: ['更新', '取消']
|
||||
}, function () {
|
||||
let proxy = false
|
||||
layer.confirm('对于大陆服务器,建议使用代理进行更新', {
|
||||
title: '是否使用代理更新?',
|
||||
btn: ['是', '否']
|
||||
}, function () {
|
||||
proxy = true
|
||||
index = layer.msg('正在更新...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/panel/info/update'
|
||||
, method: 'post'
|
||||
, data: { proxy: proxy }
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
return false
|
||||
}
|
||||
layer.alert('更新成功!')
|
||||
location.href = '/';
|
||||
}
|
||||
})
|
||||
}, function(){
|
||||
proxy = false
|
||||
index = layer.msg('正在更新...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/panel/info/update'
|
||||
, method: 'post'
|
||||
, data: { proxy: proxy }
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
return false
|
||||
}
|
||||
layer.alert('更新成功!')
|
||||
location.href = '/';
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
} else {
|
||||
layer.msg('当前已是最新版本!')
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ Date: 2023-06-24
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="layui-btn-container">
|
||||
<button id="openresty-clean-error-log" class="layui-btn">清空日志</button>
|
||||
<button id="openresty-clear-error-log" class="layui-btn">清空日志</button>
|
||||
</div>
|
||||
<pre id="openresty-error-log" class="layui-code">
|
||||
获取中...
|
||||
@@ -141,54 +141,50 @@ Date: 2023-06-24
|
||||
|
||||
// 事件监听
|
||||
$('#openresty-start').click(function () {
|
||||
admin.popup({
|
||||
title: '<span style="color: red;">警告</span>'
|
||||
,
|
||||
shade: 0
|
||||
,
|
||||
anim: -1
|
||||
,
|
||||
area: ['300px', '200px']
|
||||
,
|
||||
id: 'layadmin-layer-skin-openresty-start'
|
||||
,
|
||||
skin: 'layui-anim layui-anim-upbit'
|
||||
,
|
||||
content: '面板的正常访问依赖OpenResty,因此不支持在面板启动OpenResty,如您确需操作,请在SSH执行<span class="layui-badge-rim">systemctl start nginx</span>以启动OpenResty!'
|
||||
})
|
||||
index = layer.msg('正在启动OpenResty...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/start'
|
||||
, method: 'post'
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
return false
|
||||
}
|
||||
admin.events.refresh()
|
||||
layer.alert('OpenResty启动成功!')
|
||||
}
|
||||
})
|
||||
})
|
||||
$('#openresty-stop').click(function () {
|
||||
admin.popup({
|
||||
title: '<span style="color: red;">警告</span>'
|
||||
,
|
||||
shade: 0
|
||||
,
|
||||
anim: -1
|
||||
,
|
||||
area: ['300px', '200px']
|
||||
,
|
||||
id: 'layadmin-layer-skin-openresty-stop'
|
||||
,
|
||||
skin: 'layui-anim layui-anim-upbit'
|
||||
,
|
||||
content: '面板的正常访问依赖OpenResty,因此不支持在面板停止OpenResty,如您确需操作,请在SSH执行<span class="layui-badge-rim">systemctl stop nginx</span>以停止OpenResty!'
|
||||
})
|
||||
layer.confirm('停止OpenResty将导致网站无法访问,是否继续停止?', {
|
||||
btn: ['停止', '取消']
|
||||
}, function () {
|
||||
index = layer.msg('正在停止OpenResty...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/stop'
|
||||
, method: 'post'
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
return false
|
||||
}
|
||||
admin.events.refresh()
|
||||
layer.alert('OpenResty停止成功!')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
$('#openresty-restart').click(function () {
|
||||
layer.confirm('重启OpenResty有可能导致面板短时间无法访问,是否继续重启?', {
|
||||
layer.confirm('重启OpenResty将导致网站短时间无法访问,是否继续重启?', {
|
||||
btn: ['重启', '取消']
|
||||
}, function () {
|
||||
index = layer.msg('正在重启OpenResty...', { icon: 16, time: 0 })
|
||||
index = layer.msg('正在重启OpenResty...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/restart'
|
||||
, method: 'post'
|
||||
, beforeSend: function () {
|
||||
layer.msg('已发送重启请求,请稍后刷新确认重启状态。')
|
||||
}
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
console.log('耗子Linux面板:OpenResty重启失败,接口返回' + result)
|
||||
return false
|
||||
}
|
||||
admin.events.refresh()
|
||||
@@ -198,22 +194,22 @@ Date: 2023-06-24
|
||||
})
|
||||
})
|
||||
$('#openresty-reload').click(function () {
|
||||
index = layer.msg('正在重载OpenResty...', { icon: 16, time: 0 })
|
||||
index = layer.msg('正在重载OpenResty...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/reload'
|
||||
, method: 'post'
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
console.log('耗子Linux面板:OpenResty重载失败,接口返回' + result)
|
||||
return false
|
||||
}
|
||||
admin.events.refresh()
|
||||
layer.alert('OpenResty重载成功!')
|
||||
}
|
||||
})
|
||||
})
|
||||
$('#openresty-config-save').click(function () {
|
||||
index = layer.msg('正在保存OpenResty主配置...', { icon: 16, time: 0 })
|
||||
index = layer.msg('正在保存OpenResty主配置...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/config'
|
||||
, method: 'post'
|
||||
@@ -223,17 +219,16 @@ Date: 2023-06-24
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
console.log('耗子Linux面板:OpenResty配置保存失败,接口返回' + result)
|
||||
return false
|
||||
}
|
||||
layer.alert('OpenResty配置保存成功!')
|
||||
}
|
||||
})
|
||||
})
|
||||
$('#openresty-clean-error-log').click(function () {
|
||||
index = layer.msg('正在清空OpenResty错误日志...', { icon: 16, time: 0 })
|
||||
$('#openresty-clear-error-log').click(function () {
|
||||
index = layer.msg('正在清空OpenResty错误日志...', { icon: 16, time: 0, shade: 0.3 })
|
||||
admin.req({
|
||||
url: '/api/plugins/openresty/cleanErrorLog'
|
||||
url: '/api/plugins/openresty/clearErrorLog'
|
||||
, method: 'post'
|
||||
, success: function (result) {
|
||||
layer.close(index)
|
||||
|
||||
158
public/panel/views/task.html
Normal file
158
public/panel/views/task.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<!--
|
||||
Name: 任务中心
|
||||
Author: 耗子
|
||||
Date: 2023-07-21
|
||||
-->
|
||||
|
||||
<title>任务中心</title>
|
||||
<div class="layui-fluid" id="component-tabs">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">任务列表</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">进行中</li>
|
||||
<li>等待中</li>
|
||||
<li>已完成</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<script type="text/html" template
|
||||
lay-url="/api/panel/task/list?status=running&page=1&limit=10"
|
||||
lay-done="layui.data.done(d);">
|
||||
{{# if(d.data.total != 0){ }}
|
||||
<blockquote class="layui-elem-quote">{{ d.data.items[0].name }}</blockquote>
|
||||
<pre id="plugin-install-log" class="layui-code">
|
||||
日志获取中...
|
||||
</pre>
|
||||
{{# } else { }}
|
||||
<blockquote class="layui-elem-quote">暂无任务</blockquote>
|
||||
{{# } }}
|
||||
</script>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<table id="panel-task-waiting" lay-filter="panel-task-waiting"></table>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<table id="panel-task-finished" lay-filter="panel-task-finished"></table>
|
||||
<script type="text/html" id="panel-task-finished-control-tpl">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="remove">移除</a>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function render_plugin_install_log(d) {
|
||||
layui.use(['admin', 'jquery'], function () {
|
||||
let admin = layui.admin
|
||||
, $ = layui.jquery;
|
||||
admin.req({
|
||||
url: "/api/panel/task/log?id=" + d.data.items[0].id
|
||||
, method: 'get'
|
||||
, success: function (result) {
|
||||
if (result.code !== 0) {
|
||||
$('#plugin-install-log').html('实时安装日志获取失败,请刷新重试!');
|
||||
return false;
|
||||
}
|
||||
$('#plugin-install-log').html(result.data);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
layui.data.done = function (d) {
|
||||
if (d.data.items[0] !== undefined) {
|
||||
render_plugin_install_log(d);
|
||||
setInterval(function () {
|
||||
render_plugin_install_log(d);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
layui.use(['admin', 'table', 'jquery'], function () {
|
||||
var table = layui.table
|
||||
, admin = layui.admin;
|
||||
|
||||
table.render({
|
||||
elem: '#panel-task-waiting'
|
||||
, url: '/api/panel/task/list?status=waiting'
|
||||
, cols: [[
|
||||
{field: 'id', hide: true, title: 'ID', sort: true}
|
||||
, {field: 'name', width: '100%', title: '任务名'}
|
||||
]]
|
||||
, page: true
|
||||
, text: '耗子Linux面板:数据加载出现异常!'
|
||||
, parseData: function (res) {
|
||||
return {
|
||||
"code": res.code,
|
||||
"msg": res.message,
|
||||
"count": res.data.total,
|
||||
"data": res.data.items
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
table.render({
|
||||
elem: '#panel-task-finished'
|
||||
, id: 'panel-task-finished-table'
|
||||
, url: '/api/panel/task/list?status=finished'
|
||||
, cols: [[
|
||||
{field: 'id', hide: true, title: 'ID', sort: true}
|
||||
, {field: 'name', width: '80%', title: '任务名'}
|
||||
, {
|
||||
field: 'control',
|
||||
title: '操作',
|
||||
templet: '#panel-task-finished-control-tpl',
|
||||
fixed: 'right',
|
||||
align: 'center'
|
||||
}
|
||||
]]
|
||||
, page: true
|
||||
, text: '耗子Linux面板:数据加载出现异常!'
|
||||
, parseData: function (res) {
|
||||
return {
|
||||
"code": res.code,
|
||||
"msg": res.message,
|
||||
"count": res.data.total,
|
||||
"data": res.data.items
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// 工具条
|
||||
table.on('tool(panel-task-finished)', function (obj) {
|
||||
let data = obj.data;
|
||||
if (obj.event === 'remove') {
|
||||
layer.confirm('确定移除该记录吗?', function (index) {
|
||||
layer.close(index);
|
||||
admin.req({
|
||||
url: '/api/panel/task/delete',
|
||||
type: 'post',
|
||||
data: {
|
||||
id: data.id
|
||||
}
|
||||
, success: function (res) {
|
||||
if (res.code == 0) {
|
||||
layer.msg('移除任务:' + data.name + ' 成功!', {icon: 1, time: 1000}, function () {
|
||||
// 重载表格
|
||||
table.reload('panel-task-finished-table');
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2, time: 1000});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -23,7 +23,7 @@ func Plugin() {
|
||||
route.Get("config", openRestyController.GetConfig)
|
||||
route.Post("config", openRestyController.SaveConfig)
|
||||
route.Get("errorLog", openRestyController.ErrorLog)
|
||||
route.Get("clearErrorLog", openRestyController.ClearErrorLog)
|
||||
route.Post("clearErrorLog", openRestyController.ClearErrorLog)
|
||||
})
|
||||
facades.Route().Prefix("api/plugins/mysql80").Middleware(middleware.Jwt()).Group(func(route route.Route) {
|
||||
mysql80Controller := mysql80.NewMysql80Controller()
|
||||
|
||||
@@ -19,6 +19,8 @@ func Web() {
|
||||
r.Middleware(middleware.Jwt()).Get("nowMonitor", infoController.NowMonitor)
|
||||
r.Middleware(middleware.Jwt()).Get("systemInfo", infoController.SystemInfo)
|
||||
r.Middleware(middleware.Jwt()).Get("installedDbAndPhp", infoController.InstalledDbAndPhp)
|
||||
r.Middleware(middleware.Jwt()).Get("checkUpdate", infoController.CheckUpdate)
|
||||
r.Middleware(middleware.Jwt()).Post("update", infoController.Update)
|
||||
})
|
||||
r.Prefix("user").Group(func(r route.Route) {
|
||||
userController := controllers.NewUserController()
|
||||
|
||||
@@ -58,8 +58,7 @@ Prepare_system() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wwwUserCheck=$(cat /etc/passwd | grep www)
|
||||
if [ "${wwwUserCheck}" == "" ]; then
|
||||
if ! id -u "www" >/dev/null 2>&1; then
|
||||
groupadd www
|
||||
useradd -s /sbin/nologin -g www www
|
||||
fi
|
||||
|
||||
@@ -362,6 +362,6 @@ systemctl daemon-reload
|
||||
systemctl enable openresty.service
|
||||
systemctl start openresty.service
|
||||
|
||||
panel writePlugin openresty
|
||||
panel writePlugin openresty ${openrestyVersion}
|
||||
|
||||
echo -e "${HR}\nOpenResty install completed.\n${HR}"
|
||||
|
||||
Reference in New Issue
Block a user