Compare commits
2 Commits
7e6356cf17
...
bf3bdc63f5
| Author | SHA1 | Date | |
|---|---|---|---|
| bf3bdc63f5 | |||
| 45ffaccb7a |
49
app/page.tsx
49
app/page.tsx
@@ -1,50 +1,5 @@
|
|||||||
import Link from 'next/link';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
redirect('/links');
|
||||||
<main className="flex min-h-screen flex-col items-center justify-center p-24 relative overflow-hidden">
|
|
||||||
{/* Colorful background elements */}
|
|
||||||
<div className="absolute top-0 left-0 w-full h-full overflow-hidden z-0">
|
|
||||||
<div className="absolute top-10 left-1/4 w-64 h-64 rounded-full bg-accent-blue opacity-10 blur-3xl"></div>
|
|
||||||
<div className="absolute bottom-10 right-1/4 w-96 h-96 rounded-full bg-accent-purple opacity-10 blur-3xl"></div>
|
|
||||||
<div className="absolute top-1/3 right-1/3 w-48 h-48 rounded-full bg-accent-green opacity-10 blur-3xl"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="text-center max-w-xl z-10 relative">
|
|
||||||
<div className="flex items-center justify-center mb-6">
|
|
||||||
<div className="h-10 w-10 rounded-lg bg-gradient-blue flex items-center justify-center shadow-lg">
|
|
||||||
<svg className="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h1 className="text-4xl font-bold ml-3 text-foreground">ShortURL <span className="text-accent-blue">Analytics</span></h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p className="text-text-secondary text-xl mb-10">Your complete analytics suite for tracking and optimizing short URL performance</p>
|
|
||||||
|
|
||||||
<div className="flex flex-col md:flex-row items-center justify-center space-y-4 md:space-y-0 md:space-x-4">
|
|
||||||
<Link
|
|
||||||
href="/dashboard"
|
|
||||||
className="bg-gradient-blue hover:opacity-90 text-white font-medium py-2.5 px-6 rounded-md text-lg transition-colors inline-flex items-center shadow-lg"
|
|
||||||
>
|
|
||||||
Go to Dashboard
|
|
||||||
<svg className="ml-2 h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
|
||||||
</svg>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link
|
|
||||||
href="/links"
|
|
||||||
className="bg-card-bg border border-card-border hover:border-accent-purple text-foreground font-medium py-2.5 px-6 rounded-md text-lg transition-all inline-flex items-center"
|
|
||||||
>
|
|
||||||
View Links
|
|
||||||
<svg className="ml-2 h-5 w-5 text-accent-purple" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101" />
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.828 14.828a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
|
||||||
</svg>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export async function main(
|
|||||||
// 获取上次同步的状态
|
// 获取上次同步的状态
|
||||||
let syncState: SyncState;
|
let syncState: SyncState;
|
||||||
try {
|
try {
|
||||||
const rawSyncState = await getVariable<string>("f/shorturl_analytics/clickhouse/shorturl_sync_state");
|
const rawSyncState = await getVariable<string>("f/shorturl_analytics/clickhouse/shorturl_event_sync_state");
|
||||||
try {
|
try {
|
||||||
syncState = JSON.parse(rawSyncState);
|
syncState = JSON.parse(rawSyncState);
|
||||||
console.log(`获取同步状态成功: 上次同步时间 ${new Date(syncState.last_sync_time).toISOString()}`);
|
console.log(`获取同步状态成功: 上次同步时间 ${new Date(syncState.last_sync_time).toISOString()}`);
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ interface ClickHouseConfig {
|
|||||||
interface ShortRecord {
|
interface ShortRecord {
|
||||||
_id: ObjectId;
|
_id: ObjectId;
|
||||||
slug: string; // 短链接的slug部分
|
slug: string; // 短链接的slug部分
|
||||||
url: string; // 原始URL
|
origin: string; // 原始URL
|
||||||
|
domain?: string; // 域名
|
||||||
createTime: number; // 创建时间戳
|
createTime: number; // 创建时间戳
|
||||||
user: string; // 创建用户
|
user?: string; // 创建用户
|
||||||
title?: string; // 标题
|
title?: string; // 标题
|
||||||
description?: string; // 描述
|
description?: string; // 描述
|
||||||
tags?: string[]; // 标签
|
tags?: string[]; // 标签
|
||||||
@@ -41,9 +42,9 @@ interface SyncState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function main(
|
export async function main(
|
||||||
batch_size = 50,
|
batch_size = 100,
|
||||||
initial_sync = false,
|
initial_sync = false,
|
||||||
max_records = 1000,
|
max_records = 999999,
|
||||||
timeout_minutes = 30,
|
timeout_minutes = 30,
|
||||||
skip_clickhouse_check = false,
|
skip_clickhouse_check = false,
|
||||||
force_insert = false
|
force_insert = false
|
||||||
@@ -248,7 +249,7 @@ export async function main(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 提取所有记录的ID
|
// 提取所有记录的ID
|
||||||
const recordIds = records.map(record => record.slug);
|
const recordIds = records.map(record => record._id.toString());
|
||||||
logWithTimestamp(`待检查的短链接ID: ${recordIds.join(', ')}`);
|
logWithTimestamp(`待检查的短链接ID: ${recordIds.join(', ')}`);
|
||||||
|
|
||||||
// 构建查询SQL,检查记录是否已存在
|
// 构建查询SQL,检查记录是否已存在
|
||||||
@@ -311,7 +312,7 @@ export async function main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 过滤出不存在的记录
|
// 过滤出不存在的记录
|
||||||
const newRecords = records.filter(record => !existingIds.has(record.slug));
|
const newRecords = records.filter(record => !existingIds.has(record._id.toString()));
|
||||||
logWithTimestamp(`过滤后剩余 ${newRecords.length} 条新记录需要插入`);
|
logWithTimestamp(`过滤后剩余 ${newRecords.length} 条新记录需要插入`);
|
||||||
|
|
||||||
return newRecords;
|
return newRecords;
|
||||||
@@ -374,11 +375,11 @@ export async function main(
|
|||||||
const expiresAtStr = record.expiresAt ? new Date(record.expiresAt).toISOString().replace('Z', '') : null;
|
const expiresAtStr = record.expiresAt ? new Date(record.expiresAt).toISOString().replace('Z', '') : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
link_id: record.slug,
|
link_id: record._id.toString(), // 使用MongoDB的_id作为link_id
|
||||||
original_url: record.url || "",
|
original_url: record.origin || "",
|
||||||
created_at: createdAtStr,
|
created_at: createdAtStr,
|
||||||
created_by: record.user || "unknown",
|
created_by: record.user || "unknown",
|
||||||
title: record.title || (record.url ? record.url.substring(0, 50) : "无标题"),
|
title: record.slug, // 使用slug作为title
|
||||||
description: record.description || "",
|
description: record.description || "",
|
||||||
tags: record.tags || [],
|
tags: record.tags || [],
|
||||||
is_active: record.active !== undefined ? record.active : true,
|
is_active: record.active !== undefined ? record.active : true,
|
||||||
@@ -528,4 +529,4 @@ export async function main(
|
|||||||
await client.close();
|
await client.close();
|
||||||
console.log("MongoDB连接已关闭");
|
console.log("MongoDB连接已关闭");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user