🎨 优化登录页面逻辑,增强唤醒登录体验;移除旧的登出方法,简化代码结构
All checks were successful
BuildImage / build-image (push) Successful in 4m28s
All checks were successful
BuildImage / build-image (push) Successful in 4m28s
This commit is contained in:
parent
932d754b8a
commit
b4bb6654c5
@ -259,35 +259,6 @@ func LogOut(ctx context.Context, wxid string, containerHost string) (*AutoHeartb
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// LogoutWechatBot 登出微信机器人(旧方法,使用HTTP请求替代)
|
||||
func LogoutWechatBot(ctx context.Context, containerID string) error {
|
||||
// 获取容器IP(简化处理,默认使用localhost)
|
||||
hostIP := "localhost"
|
||||
|
||||
client := newHTTPClient()
|
||||
url := fmt.Sprintf("http://%s:3000/api/logout", hostIP)
|
||||
|
||||
var response BaseResponse[any]
|
||||
resp, err := client.R().
|
||||
SetContext(ctx).
|
||||
SetResult(&response).
|
||||
Post(url)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute logout command: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode() != 200 {
|
||||
return fmt.Errorf("logout API returned non-200 status code: %d", resp.StatusCode())
|
||||
}
|
||||
|
||||
if !response.Success {
|
||||
return fmt.Errorf("logout failed: %s", response.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetWechatBotStatus 获取微信机器人状态(使用HTTP请求替代)
|
||||
func GetWechatBotStatus(ctx context.Context, containerID string) (model.RobotStatus, string, error) {
|
||||
// 检查容器状态
|
||||
|
@ -169,7 +169,7 @@ func DeleteRobot(c *fiber.Ctx) error {
|
||||
defer cancel()
|
||||
|
||||
if robot.Status == model.RobotStatusOnline {
|
||||
if err = docker.LogoutWechatBot(ctx, robot.ContainerID); err != nil {
|
||||
if _, err = docker.LogOut(ctx, robot.WechatID, robot.ContainerHost); err != nil {
|
||||
log.Printf("登出机器人失败: %v", err)
|
||||
// 继续删除流程,不因登出失败而中断
|
||||
}
|
||||
@ -209,7 +209,7 @@ func DeleteRobot(c *fiber.Ctx) error {
|
||||
return c.Redirect("/admin/robots")
|
||||
}
|
||||
|
||||
// RobotLogin 显示微信登录二维码
|
||||
// RobotLogin 显示微信登录二维码或唤醒登录
|
||||
func RobotLogin(c *fiber.Ctx) error {
|
||||
id, err := strconv.Atoi(c.Params("id"))
|
||||
if err != nil {
|
||||
@ -229,6 +229,45 @@ func RobotLogin(c *fiber.Ctx) error {
|
||||
db.Save(&robot)
|
||||
}
|
||||
|
||||
// 检查机器人是否已在线,如果在线则无需登录
|
||||
if robot.Status == model.RobotStatusOnline {
|
||||
// 渲染"已在线"页面
|
||||
return c.Render("robot/login", fiber.Map{
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"IsOnline": true,
|
||||
})
|
||||
}
|
||||
|
||||
// 检查是否指定使用二维码登录
|
||||
forceQrcode := c.Query("qrcode") == "1"
|
||||
|
||||
// 如果存在WechatID且没有强制要求使用二维码,则使用唤醒登录
|
||||
if robot.WechatID != "" && !forceQrcode {
|
||||
// 尝试唤醒登录
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
awakenResp, err := docker.AwakenLogin(ctx, robot.WechatID, robot.ContainerHost)
|
||||
if err != nil {
|
||||
return c.Render("robot/login", fiber.Map{
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"Message": "唤醒登录失败: " + err.Error(),
|
||||
"IsError": true,
|
||||
})
|
||||
}
|
||||
|
||||
// 渲染唤醒登录页面
|
||||
return c.Render("robot/login", fiber.Map{
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"UUID": awakenResp.Data.QrCodeResponse.Uuid,
|
||||
"Expired": awakenResp.Data.QrCodeResponse.ExpiredTime,
|
||||
"IsAwaken": true,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取登录二维码
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
@ -236,16 +275,22 @@ func RobotLogin(c *fiber.Ctx) error {
|
||||
// 使用新的GetQRCode接口获取二维码,并传递容器访问地址
|
||||
qrcodeResp, err := docker.GetQRCode(ctx, robot.ContainerHost)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "获取登录二维码失败: "+err.Error())
|
||||
return c.Render("robot/login", fiber.Map{
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"Message": "获取登录二维码失败: " + err.Error(),
|
||||
"IsError": true,
|
||||
})
|
||||
}
|
||||
|
||||
// 渲染登录页面,包含二维码和UUID(用于后续状态检查)
|
||||
return c.Render("robot/login", fiber.Map{
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"QRCode": qrcodeResp.Data.QRCodeURL, // 完整的data URL格式
|
||||
"UUID": qrcodeResp.Data.UUID,
|
||||
"Expired": qrcodeResp.Data.ExpiredTime,
|
||||
"Title": "微信登录",
|
||||
"Robot": robot,
|
||||
"QRCode": qrcodeResp.Data.QRCodeURL,
|
||||
"UUID": qrcodeResp.Data.UUID,
|
||||
"Expired": qrcodeResp.Data.ExpiredTime,
|
||||
"IsAwaken": false,
|
||||
})
|
||||
}
|
||||
|
||||
@ -275,11 +320,6 @@ func RobotLogout(c *fiber.Ctx) error {
|
||||
if _, err = docker.LogOut(ctx, robot.WechatID, robot.ContainerHost); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "登出微信失败: "+err.Error())
|
||||
}
|
||||
} else {
|
||||
// 如果没有WechatID,使用原来的方法
|
||||
if err = docker.LogoutWechatBot(ctx, robot.ContainerID); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "登出微信失败: "+err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 更新机器人状态
|
||||
|
@ -116,18 +116,6 @@
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
|
||||
{{if eq .Status "offline"}}
|
||||
<a href="/admin/robots/{{.ID}}/login" class="p-1.5 rounded-md text-blue-600 hover:bg-blue-50 hover:text-blue-700" title="登录微信">
|
||||
<i class="fas fa-sign-in-alt"></i>
|
||||
</a>
|
||||
{{else}}
|
||||
<form method="POST" action="/admin/robots/{{.ID}}/logout" class="inline">
|
||||
<button type="submit" class="p-1.5 rounded-md text-yellow-600 hover:bg-yellow-50 hover:text-yellow-700" title="登出微信">
|
||||
<i class="fas fa-sign-out-alt"></i>
|
||||
</button>
|
||||
</form>
|
||||
{{end}}
|
||||
|
||||
<a href="#" class="p-1.5 rounded-md text-red-600 hover:bg-red-50 hover:text-red-700 delete-robot" data-id="{{.ID}}" data-robot-name="{{.Nickname}}" title="删除">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
|
@ -8,43 +8,122 @@
|
||||
</div>
|
||||
|
||||
<div class="max-w-md mx-auto">
|
||||
<div class="clean-card overflow-hidden">
|
||||
<div class="text-center px-6 py-5 bg-gray-50 border-b border-gray-100">
|
||||
<h2 class="text-lg font-medium text-gray-800">{{.Robot.Nickname}}</h2>
|
||||
<p class="text-sm text-gray-600 mt-1">请使用微信扫描二维码登录</p>
|
||||
{{if .IsError}}
|
||||
<div class="mb-4 bg-red-50 border border-red-200 rounded-lg p-4 text-red-700">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<i class="fas fa-exclamation-circle text-red-500 mt-0.5"></i>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<p>{{.Message}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="clean-card overflow-hidden shadow-md rounded-lg">
|
||||
<div class="p-6 flex flex-col items-center">
|
||||
<div class="border border-gray-200 rounded-lg p-3 mb-6 bg-white">
|
||||
<img src="{{.QRCode}}" alt="Login QR Code" class="w-64 h-64">
|
||||
</div>
|
||||
{{if .IsOnline}}
|
||||
<!-- 已在线状态 -->
|
||||
<div class="flex flex-col items-center mb-6">
|
||||
<div class="relative mb-4">
|
||||
<div class="w-24 h-24 rounded-full overflow-hidden border-4 shadow-lg flex items-center justify-center">
|
||||
<img src="{{.Robot.Avatar}}" alt="WeChat Avatar" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="absolute bottom-0 right-0 bg-green-500 w-6 h-6 rounded-full border-2 border-white flex items-center justify-center">
|
||||
<i class="fas fa-check text-white text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="text-xl font-medium text-gray-800">{{.Robot.Nickname}}</h3>
|
||||
<div class="mt-2 px-4 py-1.5 bg-green-50 rounded-full">
|
||||
<span class="inline-flex items-center text-sm font-medium text-green-700">
|
||||
<i class="fas fa-check-circle mr-1.5"></i>
|
||||
微信已在线,无需登录
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="qrcode-status" class="text-center mb-4">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
||||
<span class="relative flex h-3 w-3 mr-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
<div class="w-full flex justify-center mt-4">
|
||||
<a href="/admin/robots/{{.Robot.ID}}" class="py-2 px-6 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 transition-colors">
|
||||
返回机器人详情
|
||||
</a>
|
||||
</div>
|
||||
{{else if .IsAwaken}}
|
||||
<!-- 唤醒登录模式 -->
|
||||
<div class="flex flex-col items-center mb-6">
|
||||
<div class="relative mb-4">
|
||||
<div class="w-24 h-24 rounded-full overflow-hidden border-4 border-white shadow-lg flex items-center justify-center bg-blue-50">
|
||||
<img src="{{.Robot.Avatar}}" alt="WeChat Avatar" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="absolute bottom-0 right-0 bg-blue-500 w-6 h-6 rounded-full border-2 border-white flex items-center justify-center animate-pulse">
|
||||
<i class="fas fa-bell text-white text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="text-xl font-medium text-gray-800">{{.Robot.Nickname}}</h3>
|
||||
<p class="text-sm text-gray-500 mt-1">请在手机上确认登录</p>
|
||||
</div>
|
||||
|
||||
<div id="login-status" class="text-center mb-6">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
||||
<span class="relative flex h-3 w-3 mr-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
</span>
|
||||
正在唤醒
|
||||
</span>
|
||||
等待扫描
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-gray-500 mb-4 text-center">
|
||||
请打开微信,使用"扫一扫"功能扫描上方二维码登录
|
||||
</p>
|
||||
<div class="text-center mb-6">
|
||||
<div class="inline-block">
|
||||
<div class="flex space-x-2">
|
||||
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce" style="animation-delay: 0s"></div>
|
||||
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
|
||||
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="timer" class="text-sm text-gray-500 mb-5">
|
||||
二维码有效期: <span id="countdown">120</span>秒
|
||||
</div>
|
||||
<div class="w-full flex justify-between">
|
||||
<a href="/admin/robots/{{.Robot.ID}}" class="py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 transition-colors">
|
||||
取消
|
||||
</a>
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login?qrcode=1" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 transition-colors">
|
||||
使用二维码
|
||||
</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<!-- 二维码登录模式 -->
|
||||
<div class="border border-gray-200 rounded-lg p-3 mb-6 bg-white">
|
||||
<img src="{{.QRCode}}" alt="Login QR Code" class="w-64 h-64">
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-between">
|
||||
<a href="/admin/robots/{{.Robot.ID}}" class="py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 transition-colors">
|
||||
取消
|
||||
</a>
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login" id="refresh-qrcode" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 transition-colors hidden">
|
||||
刷新二维码
|
||||
</a>
|
||||
</div>
|
||||
<div id="login-status" class="text-center mb-4">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
||||
<span class="relative flex h-3 w-3 mr-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
</span>
|
||||
等待扫描
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-gray-500 mb-4 text-center">
|
||||
请打开微信,使用"扫一扫"功能扫描上方二维码登录
|
||||
</p>
|
||||
|
||||
<div id="timer" class="text-sm text-gray-500 mb-5">
|
||||
二维码有效期: <span id="countdown">120</span>秒
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-between">
|
||||
<a href="/admin/robots/{{.Robot.ID}}" class="py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 transition-colors">
|
||||
取消
|
||||
</a>
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login" id="refresh-qrcode" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 transition-colors hidden">
|
||||
刷新二维码
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -55,53 +134,31 @@
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const qrcodeStatus = document.getElementById('qrcode-status');
|
||||
const timer = document.getElementById('timer');
|
||||
const countdown = document.getElementById('countdown');
|
||||
{{if not .IsOnline}}
|
||||
const loginStatus = document.getElementById('login-status');
|
||||
const refreshQrcode = document.getElementById('refresh-qrcode');
|
||||
|
||||
let secondsLeft = 120;
|
||||
let statusCheckInterval;
|
||||
let countdown = document.getElementById('countdown');
|
||||
|
||||
// 开始倒计时
|
||||
const countdownTimer = setInterval(() => {
|
||||
secondsLeft--;
|
||||
countdown.textContent = secondsLeft;
|
||||
|
||||
if (secondsLeft <= 0) {
|
||||
clearInterval(countdownTimer);
|
||||
clearInterval(statusCheckInterval);
|
||||
|
||||
qrcodeStatus.innerHTML = `
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
|
||||
<i class="fas fa-times-circle mr-1"></i>
|
||||
二维码已过期
|
||||
</span>
|
||||
`;
|
||||
|
||||
refreshQrcode.classList.remove('hidden');
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// 检查扫码状态
|
||||
function checkQRCodeStatus() {
|
||||
// 检查登录状态
|
||||
function checkLoginStatus() {
|
||||
fetch(`/admin/robots/{{.Robot.ID}}/check-qrcode?uuid={{.UUID}}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// 扫码阶段:0-未扫描, 1-已扫描未确认, 2-已登录
|
||||
if (data.status === 0) {
|
||||
qrcodeStatus.innerHTML = `
|
||||
loginStatus.innerHTML = `
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
||||
<span class="relative flex h-3 w-3 mr-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||
</span>
|
||||
等待扫描
|
||||
{{if .IsAwaken}}正在唤醒{{else}}等待扫描{{end}}
|
||||
</span>
|
||||
`;
|
||||
} else if (data.status === 1) {
|
||||
qrcodeStatus.innerHTML = `
|
||||
loginStatus.innerHTML = `
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-yellow-100 text-yellow-800">
|
||||
<span class="relative flex h-3 w-3 mr-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-yellow-400 opacity-75"></span>
|
||||
@ -111,23 +168,36 @@
|
||||
</span>
|
||||
`;
|
||||
} else if (data.status === 99 && data.userInfo && Object.keys(data.userInfo).length > 0) {
|
||||
qrcodeStatus.innerHTML = `
|
||||
loginStatus.innerHTML = `
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800">
|
||||
<i class="fas fa-check-circle mr-1"></i>
|
||||
登录成功
|
||||
</span>
|
||||
`;
|
||||
|
||||
clearInterval(countdownTimer);
|
||||
clearInterval(timerInterval);
|
||||
clearInterval(statusCheckInterval);
|
||||
|
||||
// 重定向到机器人详情页
|
||||
// 延迟一下再跳转,让用户有时间看到成功状态
|
||||
setTimeout(() => {
|
||||
window.location.href = `/admin/robots/{{.Robot.ID}}`;
|
||||
}, 1500);
|
||||
}
|
||||
} else {
|
||||
console.error('Error checking QR code status:', data.message);
|
||||
} else if (data.expired) {
|
||||
loginStatus.innerHTML = `
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
|
||||
<i class="fas fa-times-circle mr-1"></i>
|
||||
{{if .IsAwaken}}唤醒失败{{else}}二维码已过期{{end}}
|
||||
</span>
|
||||
`;
|
||||
|
||||
clearInterval(timerInterval);
|
||||
clearInterval(statusCheckInterval);
|
||||
|
||||
// 显示刷新按钮
|
||||
if (refreshQrcode) {
|
||||
refreshQrcode.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
@ -135,10 +205,30 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 每3秒检查一次扫码状态
|
||||
statusCheckInterval = setInterval(checkQRCodeStatus, 3000);
|
||||
// 每3秒检查一次状态
|
||||
const statusCheckInterval = setInterval(checkLoginStatus, 3000);
|
||||
|
||||
// 立即执行一次检查
|
||||
checkQRCodeStatus();
|
||||
checkLoginStatus();
|
||||
|
||||
{{if not .IsAwaken}}
|
||||
// 开始倒计时
|
||||
const timerInterval = setInterval(() => {
|
||||
secondsLeft--;
|
||||
if (countdown) {
|
||||
countdown.textContent = secondsLeft;
|
||||
}
|
||||
|
||||
if (secondsLeft <= 0) {
|
||||
clearInterval(timerInterval);
|
||||
|
||||
// 显示刷新按钮
|
||||
if (refreshQrcode) {
|
||||
refreshQrcode.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
{{end}}
|
||||
{{end}}
|
||||
});
|
||||
</script>
|
||||
|
@ -16,9 +16,6 @@
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login" class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors mr-2">
|
||||
<i class="fas fa-qrcode mr-2"></i> 登录
|
||||
</a>
|
||||
<!-- 修改删除按钮,使用confirmDialog而非直接调用deleteRobot函数 -->
|
||||
<button onclick="confirmDelete({{.Robot.ID}}, '{{.Robot.Nickname}}')" class="inline-flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 transition-colors">
|
||||
<i class="fas fa-trash mr-2"></i> 删除
|
||||
@ -82,8 +79,8 @@
|
||||
</button>
|
||||
</form>
|
||||
{{else}}
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login" class="w-full flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none transition-colors">
|
||||
<i class="fas fa-qrcode mr-2"></i> 扫码登录
|
||||
<a href="/admin/robots/{{.Robot.ID}}/login" class="w-full flex items-center justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none transition-colors">
|
||||
<i class="fas fa-qrcode mr-2"></i> 登录
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
@ -263,7 +260,7 @@
|
||||
`确定要删除机器人"${name}"吗?此操作将永久删除容器及相关数据,无法恢复!`,
|
||||
{ type: 'danger', title: '删除机器人' }
|
||||
);
|
||||
|
||||
|
||||
if (confirmed) {
|
||||
deleteRobot(id);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user