自动登录问题修复
This commit is contained in:
+1
-1
@@ -63,5 +63,5 @@ typings/
|
|||||||
# next.js build output
|
# next.js build output
|
||||||
.next
|
.next
|
||||||
|
|
||||||
old/
|
# 下载文件夹
|
||||||
downloads/
|
downloads/
|
||||||
|
|||||||
+16
-6
@@ -67,9 +67,12 @@ class PixivServer {
|
|||||||
this.app.use(express.json({ limit: '10mb' }));
|
this.app.use(express.json({ limit: '10mb' }));
|
||||||
this.app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
this.app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||||
|
|
||||||
// 静态文件服务 - 临时注释掉
|
// 静态文件服务
|
||||||
this.app.use('/downloads', express.static(path.join(__dirname, '../downloads')));
|
this.app.use('/downloads', express.static(path.join(__dirname, '../downloads')));
|
||||||
|
|
||||||
|
// 前端静态文件服务
|
||||||
|
this.app.use(express.static(path.join(__dirname, '../ui/dist')));
|
||||||
|
|
||||||
// 将后端实例注入到请求对象中
|
// 将后端实例注入到请求对象中
|
||||||
this.app.use((req, res, next) => {
|
this.app.use((req, res, next) => {
|
||||||
req.backend = this.backend;
|
req.backend = this.backend;
|
||||||
@@ -102,10 +105,16 @@ class PixivServer {
|
|||||||
|
|
||||||
// 404 处理
|
// 404 处理
|
||||||
this.app.use((req, res) => {
|
this.app.use((req, res) => {
|
||||||
res.status(404).json({
|
// 如果是API请求,返回JSON格式的404
|
||||||
error: 'Not Found',
|
if (req.path.startsWith('/api/')) {
|
||||||
message: `Route ${req.originalUrl} not found`
|
return res.status(404).json({
|
||||||
});
|
error: 'Not Found',
|
||||||
|
message: `Route ${req.originalUrl} not found`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则返回前端页面(SPA路由支持)
|
||||||
|
res.sendFile(path.join(__dirname, '../ui/dist/index.html'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +131,8 @@ class PixivServer {
|
|||||||
start() {
|
start() {
|
||||||
this.app.listen(this.port, () => {
|
this.app.listen(this.port, () => {
|
||||||
console.log(`🚀 Pixiv 后端服务器已启动`);
|
console.log(`🚀 Pixiv 后端服务器已启动`);
|
||||||
console.log(`📍 地址: http://localhost:${this.port}`);
|
console.log(`📍 后端API: http://localhost:${this.port}`);
|
||||||
|
console.log(`🌐 前端页面: http://localhost:${this.port}`);
|
||||||
console.log(`🔗 健康检查: http://localhost:${this.port}/health`);
|
console.log(`🔗 健康检查: http://localhost:${this.port}/health`);
|
||||||
console.log(`📊 登录状态: ${this.backend.isLoggedIn ? '已登录' : '未登录'}`);
|
console.log(`📊 登录状态: ${this.backend.isLoggedIn ? '已登录' : '未登录'}`);
|
||||||
if (this.backend.isLoggedIn) {
|
if (this.backend.isLoggedIn) {
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo.
|
||||||
|
echo ========================================
|
||||||
|
echo 🔍 Pixiv Manager 环境检测
|
||||||
|
echo ========================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo 📂 当前目录: %CD%
|
||||||
|
echo.
|
||||||
|
|
||||||
|
:: 检查 Node.js
|
||||||
|
echo 🔍 检查 Node.js...
|
||||||
|
node --version >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo ❌ 未找到 Node.js
|
||||||
|
echo 📥 请先安装 Node.js: https://nodejs.org/
|
||||||
|
goto :end
|
||||||
|
) else (
|
||||||
|
for /f "tokens=*" %%i in ('node --version') do echo ✅ Node.js: %%i
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 检查 package.json
|
||||||
|
echo.
|
||||||
|
echo 🔍 检查项目文件...
|
||||||
|
if not exist "package.json" (
|
||||||
|
echo ❌ 未找到 package.json
|
||||||
|
goto :end
|
||||||
|
) else (
|
||||||
|
echo ✅ package.json 存在
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 检查 node_modules
|
||||||
|
if not exist "node_modules" (
|
||||||
|
echo ⚠️ node_modules 不存在,需要安装依赖
|
||||||
|
set /p choice="是否现在安装依赖? (y/n): "
|
||||||
|
if /i "%choice%"=="y" (
|
||||||
|
echo 📦 安装依赖包...
|
||||||
|
npm install
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo ❌ 依赖安装失败
|
||||||
|
goto :end
|
||||||
|
) else (
|
||||||
|
echo ✅ 依赖安装成功
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo ✅ node_modules 存在
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 检查前端构建文件
|
||||||
|
echo.
|
||||||
|
echo 🔍 检查前端构建文件...
|
||||||
|
if not exist "ui/dist" (
|
||||||
|
echo ⚠️ ui/dist 不存在,需要构建前端
|
||||||
|
set /p choice="是否现在构建前端? (y/n): "
|
||||||
|
if /i "%choice%"=="y" (
|
||||||
|
echo 📦 构建前端文件...
|
||||||
|
cd ui
|
||||||
|
npm run build
|
||||||
|
cd ..
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo ❌ 前端构建失败
|
||||||
|
goto :end
|
||||||
|
) else (
|
||||||
|
echo ✅ 前端构建成功
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo ✅ ui/dist 存在
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ========================================
|
||||||
|
echo ✅ 环境检测完成,可以启动应用
|
||||||
|
echo ========================================
|
||||||
|
|
||||||
|
:end
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1,19 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo.
|
||||||
|
echo 🚀 Pixiv Manager 启动中...
|
||||||
|
echo.
|
||||||
|
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo 📊 启动后端服务器...
|
||||||
|
echo 🌐 访问地址: http://localhost:3000
|
||||||
|
echo.
|
||||||
|
echo 💡 提示: 按 Ctrl+C 停止服务器
|
||||||
|
echo.
|
||||||
|
|
||||||
|
node backend/start.js
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ⏹️ 服务器已停止
|
||||||
|
pause
|
||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Vite App</title>
|
<title>Pixiv Manager</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 448 KiB |
+140
-16
@@ -41,24 +41,53 @@
|
|||||||
|
|
||||||
<div v-else class="login-form">
|
<div v-else class="login-form">
|
||||||
<div class="login-info">
|
<div class="login-info">
|
||||||
<p>点击下方按钮将跳转到 Pixiv 官方登录页面</p>
|
<p>通过 Pixiv 官方登录页面获取授权码</p>
|
||||||
<ul class="login-features">
|
<div class="code-instructions">
|
||||||
<li>安全可靠的官方登录</li>
|
<h4>获取授权码步骤:</h4>
|
||||||
<li>支持所有 Pixiv 功能</li>
|
<ol>
|
||||||
<li>自动保存登录状态</li>
|
<li>点击"获取登录链接"按钮</li>
|
||||||
</ul>
|
<li>在新窗口中完成 Pixiv 登录</li>
|
||||||
|
<li>登录成功后,在地址栏找到 <code>code=</code> 后面的内容</li>
|
||||||
|
<li>复制该授权码并粘贴到下方输入框</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="code-input-section">
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="authCode" class="input-label">授权码</label>
|
||||||
|
<input
|
||||||
|
id="authCode"
|
||||||
|
v-model="authCode"
|
||||||
|
type="text"
|
||||||
|
placeholder="粘贴授权码..."
|
||||||
|
class="code-input"
|
||||||
|
:disabled="loading"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="login-actions">
|
||||||
|
<button
|
||||||
|
@click="handleLogin"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
<LoadingSpinner v-if="loading" text="获取登录链接..." />
|
||||||
|
<span v-else>获取登录链接</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click="handleManualLogin"
|
||||||
|
class="btn btn-primary btn-large"
|
||||||
|
:disabled="!authCode.trim() || loading"
|
||||||
|
>
|
||||||
|
<LoadingSpinner v-if="loading" text="登录中..." />
|
||||||
|
<span v-else>完成登录</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="login-actions">
|
<div class="login-actions">
|
||||||
<button
|
|
||||||
@click="handleLogin"
|
|
||||||
class="btn btn-primary btn-large"
|
|
||||||
:disabled="loading"
|
|
||||||
>
|
|
||||||
<LoadingSpinner v-if="loading" text="获取登录链接..." />
|
|
||||||
<span v-else>开始登录</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<router-link to="/" class="btn btn-text">
|
<router-link to="/" class="btn btn-text">
|
||||||
返回首页
|
返回首页
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -79,7 +108,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useAuthStore } from '@/stores/auth';
|
import { useAuthStore } from '@/stores/auth';
|
||||||
import LoadingSpinner from '@/components/common/LoadingSpinner.vue';
|
import LoadingSpinner from '@/components/common/LoadingSpinner.vue';
|
||||||
@@ -88,6 +117,9 @@ import ErrorMessage from '@/components/common/ErrorMessage.vue';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
// 响应式变量
|
||||||
|
const authCode = ref('');
|
||||||
|
|
||||||
const isLoggedIn = computed(() => authStore.isLoggedIn);
|
const isLoggedIn = computed(() => authStore.isLoggedIn);
|
||||||
const username = computed(() => authStore.username);
|
const username = computed(() => authStore.username);
|
||||||
const loading = computed(() => authStore.loading);
|
const loading = computed(() => authStore.loading);
|
||||||
@@ -106,6 +138,22 @@ const handleLogin = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleManualLogin = async () => {
|
||||||
|
if (!authCode.value.trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await authStore.handleLoginCallback(authCode.value.trim());
|
||||||
|
authCode.value = ''; // 清空输入框
|
||||||
|
router.push('/');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('手动登录失败:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
try {
|
try {
|
||||||
await authStore.logout();
|
await authStore.logout();
|
||||||
@@ -201,6 +249,82 @@ const clearError = () => {
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.code-instructions {
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-instructions h4 {
|
||||||
|
margin: 0 0 0.75rem 0;
|
||||||
|
color: #374151;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-instructions ol {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-instructions li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-instructions code {
|
||||||
|
background: #f3f4f6;
|
||||||
|
padding: 0.125rem 0.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.code-input-section {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #374151;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-input:disabled {
|
||||||
|
background: #f9fafb;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.login-info {
|
.login-info {
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user