🎨 优化登录页面逻辑,增强唤醒登录体验;移除旧的登出方法,简化代码结构
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
|
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请求替代)
|
// GetWechatBotStatus 获取微信机器人状态(使用HTTP请求替代)
|
||||||
func GetWechatBotStatus(ctx context.Context, containerID string) (model.RobotStatus, string, error) {
|
func GetWechatBotStatus(ctx context.Context, containerID string) (model.RobotStatus, string, error) {
|
||||||
// 检查容器状态
|
// 检查容器状态
|
||||||
|
@ -169,7 +169,7 @@ func DeleteRobot(c *fiber.Ctx) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if robot.Status == model.RobotStatusOnline {
|
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)
|
log.Printf("登出机器人失败: %v", err)
|
||||||
// 继续删除流程,不因登出失败而中断
|
// 继续删除流程,不因登出失败而中断
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ func DeleteRobot(c *fiber.Ctx) error {
|
|||||||
return c.Redirect("/admin/robots")
|
return c.Redirect("/admin/robots")
|
||||||
}
|
}
|
||||||
|
|
||||||
// RobotLogin 显示微信登录二维码
|
// RobotLogin 显示微信登录二维码或唤醒登录
|
||||||
func RobotLogin(c *fiber.Ctx) error {
|
func RobotLogin(c *fiber.Ctx) error {
|
||||||
id, err := strconv.Atoi(c.Params("id"))
|
id, err := strconv.Atoi(c.Params("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -229,6 +229,45 @@ func RobotLogin(c *fiber.Ctx) error {
|
|||||||
db.Save(&robot)
|
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)
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -236,16 +275,22 @@ func RobotLogin(c *fiber.Ctx) error {
|
|||||||
// 使用新的GetQRCode接口获取二维码,并传递容器访问地址
|
// 使用新的GetQRCode接口获取二维码,并传递容器访问地址
|
||||||
qrcodeResp, err := docker.GetQRCode(ctx, robot.ContainerHost)
|
qrcodeResp, err := docker.GetQRCode(ctx, robot.ContainerHost)
|
||||||
if err != nil {
|
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(用于后续状态检查)
|
// 渲染登录页面,包含二维码和UUID(用于后续状态检查)
|
||||||
return c.Render("robot/login", fiber.Map{
|
return c.Render("robot/login", fiber.Map{
|
||||||
"Title": "微信登录",
|
"Title": "微信登录",
|
||||||
"Robot": robot,
|
"Robot": robot,
|
||||||
"QRCode": qrcodeResp.Data.QRCodeURL, // 完整的data URL格式
|
"QRCode": qrcodeResp.Data.QRCodeURL,
|
||||||
"UUID": qrcodeResp.Data.UUID,
|
"UUID": qrcodeResp.Data.UUID,
|
||||||
"Expired": qrcodeResp.Data.ExpiredTime,
|
"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 {
|
if _, err = docker.LogOut(ctx, robot.WechatID, robot.ContainerHost); err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "登出微信失败: "+err.Error())
|
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>
|
<i class="fas fa-eye"></i>
|
||||||
</a>
|
</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="删除">
|
<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>
|
<i class="fas fa-trash"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -8,43 +8,122 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="max-w-md mx-auto">
|
<div class="max-w-md mx-auto">
|
||||||
<div class="clean-card overflow-hidden">
|
{{if .IsError}}
|
||||||
<div class="text-center px-6 py-5 bg-gray-50 border-b border-gray-100">
|
<div class="mb-4 bg-red-50 border border-red-200 rounded-lg p-4 text-red-700">
|
||||||
<h2 class="text-lg font-medium text-gray-800">{{.Robot.Nickname}}</h2>
|
<div class="flex">
|
||||||
<p class="text-sm text-gray-600 mt-1">请使用微信扫描二维码登录</p>
|
<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>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<div class="clean-card overflow-hidden shadow-md rounded-lg">
|
||||||
<div class="p-6 flex flex-col items-center">
|
<div class="p-6 flex flex-col items-center">
|
||||||
<div class="border border-gray-200 rounded-lg p-3 mb-6 bg-white">
|
{{if .IsOnline}}
|
||||||
<img src="{{.QRCode}}" alt="Login QR Code" class="w-64 h-64">
|
<!-- 已在线状态 -->
|
||||||
</div>
|
<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">
|
<div class="w-full flex justify-center mt-4">
|
||||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
<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">
|
||||||
<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>
|
</a>
|
||||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
</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>
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-sm text-gray-500 mb-4 text-center">
|
<div class="text-center mb-6">
|
||||||
请打开微信,使用"扫一扫"功能扫描上方二维码登录
|
<div class="inline-block">
|
||||||
</p>
|
<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">
|
<div class="w-full flex justify-between">
|
||||||
二维码有效期: <span id="countdown">120</span>秒
|
<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">
|
||||||
</div>
|
取消
|
||||||
|
</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">
|
<div id="login-status" class="text-center mb-4">
|
||||||
<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">
|
<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">
|
||||||
</a>
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
|
||||||
<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">
|
<span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||||
刷新二维码
|
</span>
|
||||||
</a>
|
等待扫描
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -55,53 +134,31 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const qrcodeStatus = document.getElementById('qrcode-status');
|
{{if not .IsOnline}}
|
||||||
const timer = document.getElementById('timer');
|
const loginStatus = document.getElementById('login-status');
|
||||||
const countdown = document.getElementById('countdown');
|
|
||||||
const refreshQrcode = document.getElementById('refresh-qrcode');
|
const refreshQrcode = document.getElementById('refresh-qrcode');
|
||||||
|
|
||||||
let secondsLeft = 120;
|
let secondsLeft = 120;
|
||||||
let statusCheckInterval;
|
let countdown = document.getElementById('countdown');
|
||||||
|
|
||||||
// 开始倒计时
|
// 检查登录状态
|
||||||
const countdownTimer = setInterval(() => {
|
function checkLoginStatus() {
|
||||||
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() {
|
|
||||||
fetch(`/admin/robots/{{.Robot.ID}}/check-qrcode?uuid={{.UUID}}`)
|
fetch(`/admin/robots/{{.Robot.ID}}/check-qrcode?uuid={{.UUID}}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
// 扫码阶段:0-未扫描, 1-已扫描未确认, 2-已登录
|
// 扫码阶段:0-未扫描, 1-已扫描未确认, 2-已登录
|
||||||
if (data.status === 0) {
|
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="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="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="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 class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
|
||||||
</span>
|
</span>
|
||||||
等待扫描
|
{{if .IsAwaken}}正在唤醒{{else}}等待扫描{{end}}
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
} else if (data.status === 1) {
|
} 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="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="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>
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-yellow-400 opacity-75"></span>
|
||||||
@ -111,23 +168,36 @@
|
|||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
} else if (data.status === 99 && data.userInfo && Object.keys(data.userInfo).length > 0) {
|
} 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">
|
<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>
|
<i class="fas fa-check-circle mr-1"></i>
|
||||||
登录成功
|
登录成功
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
clearInterval(countdownTimer);
|
clearInterval(timerInterval);
|
||||||
clearInterval(statusCheckInterval);
|
clearInterval(statusCheckInterval);
|
||||||
|
|
||||||
// 重定向到机器人详情页
|
// 延迟一下再跳转,让用户有时间看到成功状态
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = `/admin/robots/{{.Robot.ID}}`;
|
window.location.href = `/admin/robots/{{.Robot.ID}}`;
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (data.expired) {
|
||||||
console.error('Error checking QR code status:', data.message);
|
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 => {
|
.catch(error => {
|
||||||
@ -135,10 +205,30 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每3秒检查一次扫码状态
|
// 每3秒检查一次状态
|
||||||
statusCheckInterval = setInterval(checkQRCodeStatus, 3000);
|
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>
|
</script>
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<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函数 -->
|
<!-- 修改删除按钮,使用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">
|
<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> 删除
|
<i class="fas fa-trash mr-2"></i> 删除
|
||||||
@ -82,8 +79,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{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">
|
<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> 扫码登录
|
<i class="fas fa-qrcode mr-2"></i> 登录
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@ -263,7 +260,7 @@
|
|||||||
`确定要删除机器人"${name}"吗?此操作将永久删除容器及相关数据,无法恢复!`,
|
`确定要删除机器人"${name}"吗?此操作将永久删除容器及相关数据,无法恢复!`,
|
||||||
{ type: 'danger', title: '删除机器人' }
|
{ type: 'danger', title: '删除机器人' }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
deleteRobot(id);
|
deleteRobot(id);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user