调整api路径

This commit is contained in:
mtvpls
2026-04-08 18:03:18 +08:00
parent 31a4f4baac
commit 204eec782f
6 changed files with 7 additions and 348 deletions
+2 -343
View File
@@ -7771,349 +7771,8 @@ const ThemeConfigComponent = ({
); );
}; };
// 音乐配置组件 // 音乐配置组件(已停用)
export const MusicConfigComponent = ({ // const MusicConfigComponent = (...) => { ... }
config,
refreshConfig,
}: {
config: AdminConfig | null;
refreshConfig: () => Promise<void>;
}) => {
const { alertModal, showAlert, hideAlert } = useAlertModal();
const { isLoading, withLoading } = useLoadingState();
const [musicSettings, setMusicSettings] = useState({
TuneHubEnabled: false,
TuneHubBaseUrl: 'https://tunehub.sayqz.com/api',
TuneHubApiKey: '',
OpenListCacheEnabled: false,
OpenListCacheURL: '',
OpenListCacheUsername: '',
OpenListCachePassword: '',
OpenListCachePath: '/music-cache',
OpenListCacheProxyEnabled: true,
});
// 从配置加载音乐设置
useEffect(() => {
if (config?.MusicConfig) {
setMusicSettings({
TuneHubEnabled: config.MusicConfig.TuneHubEnabled ?? false,
TuneHubBaseUrl: config.MusicConfig.TuneHubBaseUrl ?? 'https://tunehub.sayqz.com/api',
TuneHubApiKey: config.MusicConfig.TuneHubApiKey ?? '',
OpenListCacheEnabled: config.MusicConfig.OpenListCacheEnabled ?? false,
OpenListCacheURL: config.MusicConfig.OpenListCacheURL ?? '',
OpenListCacheUsername: config.MusicConfig.OpenListCacheUsername ?? '',
OpenListCachePassword: config.MusicConfig.OpenListCachePassword ?? '',
OpenListCachePath: config.MusicConfig.OpenListCachePath ?? '/music-cache',
OpenListCacheProxyEnabled: config.MusicConfig.OpenListCacheProxyEnabled ?? true,
});
}
}, [config]);
const handleSave = async () => {
await withLoading('saveMusicConfig', async () => {
try {
const resp = await fetch('/api/admin/music', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...musicSettings }),
});
if (!resp.ok) {
const data = await resp.json().catch(() => ({}));
throw new Error(data.error || '保存失败');
}
showAlert({ type: 'success', title: '保存成功', message: '音乐配置已更新', timer: 2000 });
await refreshConfig();
} catch (error: any) {
showAlert({ type: 'error', title: '保存失败', message: error.message || '未知错误', showConfirm: true });
}
});
};
return (
<div className='space-y-6'>
{/* TuneHub 音乐配置 */}
<div className='space-y-4'>
<h3 className='text-sm font-semibold text-gray-900 dark:text-gray-100'>
TuneHub
</h3>
{/* 开启音乐功能 */}
<div>
<div className='flex items-center justify-between'>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
</label>
<button
type='button'
onClick={() =>
setMusicSettings((prev) => ({
...prev,
TuneHubEnabled: !prev.TuneHubEnabled,
}))
}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${
musicSettings.TuneHubEnabled
? buttonStyles.toggleOn
: buttonStyles.toggleOff
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full ${
buttonStyles.toggleThumb
} transition-transform ${
musicSettings.TuneHubEnabled
? buttonStyles.toggleThumbOn
: buttonStyles.toggleThumbOff
}`}
/>
</button>
</div>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
QQ音乐
</p>
</div>
{/* TuneHub Base URL */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
TuneHub API
</label>
<input
type='text'
placeholder='https://tunehub.sayqz.com/api'
value={musicSettings.TuneHubBaseUrl}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
TuneHubBaseUrl: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
TuneHub API https://tunehub.sayqz.com/api。也可以通过环境变量 TUNEHUB_BASE_URL 配置
</p>
</div>
{/* TuneHub API Key */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
TuneHub API Key
</label>
<input
type='password'
placeholder='th_your_api_key_here'
value={musicSettings.TuneHubApiKey}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
TuneHubApiKey: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
API Key Key TUNEHUB_API_KEY
</p>
</div>
</div>
{/* OpenList 缓存配置 */}
<div className='space-y-4 pt-4 border-t border-gray-200 dark:border-gray-700'>
<h3 className='text-sm font-semibold text-gray-900 dark:text-gray-100'>
OpenList
</h3>
{/* 开启 OpenList 缓存 */}
<div>
<div className='flex items-center justify-between'>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
OpenList
</label>
<button
type='button'
onClick={() =>
setMusicSettings((prev) => ({
...prev,
OpenListCacheEnabled: !prev.OpenListCacheEnabled,
}))
}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${
musicSettings.OpenListCacheEnabled
? buttonStyles.toggleOn
: buttonStyles.toggleOff
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full ${
buttonStyles.toggleThumb
} transition-transform ${
musicSettings.OpenListCacheEnabled
? buttonStyles.toggleThumbOn
: buttonStyles.toggleThumbOff
}`}
/>
</button>
</div>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
OpenList API 线
</p>
</div>
{/* OpenList URL */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
OpenList
</label>
<input
type='text'
placeholder='https://your-openlist-server.com'
value={musicSettings.OpenListCacheURL}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
OpenListCacheURL: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
OpenList https://your-openlist-server.com
</p>
</div>
{/* OpenList 用户名 */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
OpenList
</label>
<input
type='text'
placeholder='admin'
value={musicSettings.OpenListCacheUsername}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
OpenListCacheUsername: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
</div>
{/* OpenList 密码 */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
OpenList
</label>
<input
type='password'
placeholder='••••••••'
value={musicSettings.OpenListCachePassword}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
OpenListCachePassword: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
OpenList 访
</p>
</div>
{/* OpenList 缓存目录 */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
</label>
<input
type='text'
placeholder='/music-cache'
value={musicSettings.OpenListCachePath}
onChange={(e) =>
setMusicSettings((prev) => ({
...prev,
OpenListCachePath: e.target.value,
}))
}
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
OpenList /music-cache
</p>
</div>
{/* 缓存代理返回开关 */}
<div>
<div className='flex items-center justify-between'>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
</label>
<button
type='button'
onClick={() =>
setMusicSettings((prev) => ({
...prev,
OpenListCacheProxyEnabled: !prev.OpenListCacheProxyEnabled,
}))
}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${
musicSettings.OpenListCacheProxyEnabled
? buttonStyles.toggleOn
: buttonStyles.toggleOff
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full ${
buttonStyles.toggleThumb
} transition-transform ${
musicSettings.OpenListCacheProxyEnabled
? buttonStyles.toggleThumbOn
: buttonStyles.toggleThumbOff
}`}
/>
</button>
</div>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
OpenList
</p>
</div>
</div>
{/* 操作按钮 */}
<div className='flex justify-end'>
<button
onClick={handleSave}
disabled={isLoading('saveMusicConfig')}
className={`px-4 py-2 ${
isLoading('saveMusicConfig')
? buttonStyles.disabled
: buttonStyles.success
} rounded-lg transition-colors`}
>
{isLoading('saveMusicConfig') ? '保存中…' : '保存'}
</button>
</div>
{/* 弹窗 */}
<AlertModal
isOpen={alertModal.isOpen}
onClose={hideAlert}
type={alertModal.type}
title={alertModal.title}
message={alertModal.message}
timer={alertModal.timer}
showConfirm={alertModal.showConfirm}
/>
</div>
);
};
// 新增站点配置组件 // 新增站点配置组件
const SiteConfigComponent = ({ const SiteConfigComponent = ({
+1 -1
View File
@@ -9,7 +9,7 @@ import {
assertQuarkCookieHeaderSafe, assertQuarkCookieHeaderSafe,
normalizeQuarkCookie, normalizeQuarkCookie,
validateQuarkCookieReadable, validateQuarkCookieReadable,
} from '@/lib/quark.client'; } from '@/lib/netdisk/quark.client';
export const runtime = 'nodejs'; export const runtime = 'nodejs';
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { getAuthInfoFromCookie } from '@/lib/auth'; import { getAuthInfoFromCookie } from '@/lib/auth';
import { getConfig } from '@/lib/config'; import { getConfig } from '@/lib/config';
import { createQuarkInstantPlayFolder } from '@/lib/quark.client'; import { createQuarkInstantPlayFolder } from '@/lib/netdisk/quark.client';
import { base58Encode } from '@/lib/utils'; import { base58Encode } from '@/lib/utils';
export const runtime = 'nodejs'; export const runtime = 'nodejs';
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { getAuthInfoFromCookie } from '@/lib/auth'; import { getAuthInfoFromCookie } from '@/lib/auth';
import { getConfig } from '@/lib/config'; import { getConfig } from '@/lib/config';
import { transferQuarkShare } from '@/lib/quark.client'; import { transferQuarkShare } from '@/lib/netdisk/quark.client';
export const runtime = 'nodejs'; export const runtime = 'nodejs';
+2 -2
View File
@@ -125,7 +125,7 @@ export default function PansouSearch({
const handleQuarkTransfer = async (link: PansouLink) => { const handleQuarkTransfer = async (link: PansouLink) => {
try { try {
setTransferingUrl(link.url); setTransferingUrl(link.url);
const response = await fetch('/api/quark/transfer', { const response = await fetch('/api/netdisk/quark/transfer', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -152,7 +152,7 @@ export default function PansouSearch({
const handleQuarkInstantPlay = async (link: PansouLink) => { const handleQuarkInstantPlay = async (link: PansouLink) => {
try { try {
setPlayingUrl(link.url); setPlayingUrl(link.url);
const response = await fetch('/api/quark/instant-play', { const response = await fetch('/api/netdisk/quark/instant-play', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',