diff --git a/package-lock.json b/package-lock.json index f1d5db2..c09d149 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,29 @@ { "name": "IndWebIndex", - "version": "2.0.1", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "IndWebIndex", - "version": "2.0.1", + "version": "2.1.0", "dependencies": { "@notionhq/client": "^0.4.11", "@vercel/analytics": "^1.3.1", + "mongodb": "^6.8.0", "next": "^14.2.4", "react": "^18.3.1", "react-dom": "^18.3.1" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", + "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@next/env": { "version": "14.2.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.4.tgz", @@ -198,6 +207,19 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/@vercel/analytics": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.3.1.tgz", @@ -223,6 +245,14 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/bson": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -311,6 +341,11 @@ "loose-envify": "cli.js" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -330,6 +365,91 @@ "node": ">= 0.6" } }, + "node_modules/mongodb": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", + "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -447,6 +567,14 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -491,6 +619,14 @@ "node": ">=0.10.0" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", diff --git a/package.json b/package.json index 1509cd2..359c068 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "IndWebIndex", - "version": "2.0.1", + "version": "2.1.0", "scripts": { "dev": "next dev", "build": "next build", @@ -9,6 +9,7 @@ "dependencies": { "@notionhq/client": "^0.4.11", "@vercel/analytics": "^1.3.1", + "mongodb": "^6.8.0", "next": "^14.2.4", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/pages/_app.js b/pages/_app.js index cb2cf8b..62e279d 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -2,8 +2,6 @@ import { Analytics } from '@vercel/analytics/react'; import '../public/css/style.css'; import '../public/css/context-menu.css'; -import '../public/css/daytime.css'; -import '../public/css/dark.css'; function MyApp({ Component, pageProps }) { return ( diff --git a/pages/_document.js b/pages/_document.js index 0471c14..029e479 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -5,6 +5,7 @@ class MyDocument extends Document { return ( + diff --git a/pages/api/visit-count.js b/pages/api/visit-count.js new file mode 100644 index 0000000..39b5400 --- /dev/null +++ b/pages/api/visit-count.js @@ -0,0 +1,44 @@ +import { MongoClient } from 'mongodb'; + +const uri = process.env.MONGODB_URI; +const client = new MongoClient(uri); + +export default async function handler(req, res) { + if (req.method === 'GET') { + try { + await client.connect(); + const database = client.db('indwebindex-count'); + const collection = database.collection('visits'); + + console.log("Connected to database"); + + // 查找文档 + let visit = await collection.findOne({ _id: 'visit_count' }); + + if (!visit) { + console.log("No document found, inserting initial document"); + await collection.insertOne({ _id: 'visit_count', count: 1 }); + visit = { count: 1 }; + } else { + // 更新计数 + visit = await collection.findOneAndUpdate( + { _id: 'visit_count' }, + { $inc: { count: 1 } }, + { returnDocument: 'after' } + ); + } + + console.log('API response data:', visit); + res.status(200).json({ count: visit.value ? visit.value.count : visit.count }); + } catch (error) { + console.error('读取或写入计数数据失败:', error.message); + res.status(200).json({ message: '未能读取或写入计数数据,但这不是致命错误。', error: error.message }); + } finally { + await client.close(); + console.log("Database connection closed"); + } + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`方法 ${req.method} 不被允许`); + } +} \ No newline at end of file diff --git a/pages/index.js b/pages/index.js index acef10b..635c302 100644 --- a/pages/index.js +++ b/pages/index.js @@ -20,12 +20,29 @@ export default function Home({ initialPosts, lastFetched }) { const [tags, setTags] = useState([]); const [onList, setOnList] = useState([]); const [filteredPosts, setFilteredPosts] = useState(initialPosts); + const [visitCount, setVisitCount] = useState(null); // 新增的状态用于存储访问次数 useEffect(() => { initializeTheme(); initializeContextMenu(); console.log(`数据更新时间: ${new Date(lastFetched).toLocaleString()}`); setPosts(initialPosts); + + // 调用访问计数 API + fetch('/api/visit-count') + .then(response => response.json()) + .then(data => { + if (data.count) { + console.log(`本页面已被访问 ${data.count} 次`); + setVisitCount(data.count); + } else { + console.log('访问计数数据不可用:', data.message); + } + }) + .catch(error => { + console.error('Error fetching visit count:', error); + }); + }, [initialPosts, lastFetched]); useEffect(() => {