mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-02 16:16:39 +08:00
commit
4383fbc1ef
@ -1,17 +1,7 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { insertUser } from "@/lib/auth";
|
import { insertUser } from "@/lib/auth";
|
||||||
|
import { getTokenLength } from "@/app/utils/token";
|
||||||
// function cleanObjectKeys(input: { [key: string]: string }): {
|
|
||||||
// [key: string]: string;
|
|
||||||
// } {
|
|
||||||
// const cleanedObj: { [key: string]: string } = {};
|
|
||||||
// Object.keys(input).forEach((key) => {
|
|
||||||
// cleanedObj[key] = input[key].trim();
|
|
||||||
// });
|
|
||||||
// console.log('========', input, cleanedObj)
|
|
||||||
// return cleanedObj;
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function handle(
|
async function handle(
|
||||||
req: NextRequest,
|
req: NextRequest,
|
||||||
@ -23,12 +13,22 @@ async function handle(
|
|||||||
await insertUser({ name: request_data?.userName });
|
await insertUser({ name: request_data?.userName });
|
||||||
}
|
}
|
||||||
// console.log("===========4", request_data);
|
// console.log("===========4", request_data);
|
||||||
|
if (request_data?.logEntry) {
|
||||||
|
const regex = /\[(.*)]/g;
|
||||||
|
const matchResponse = request_data.logEntry.match(regex);
|
||||||
|
if (matchResponse.length > 0) {
|
||||||
|
request_data.logToken = getTokenLength(matchResponse[0]);
|
||||||
|
}
|
||||||
|
// console.log('=======', request_data.logEntry, '=====', matchResponse);
|
||||||
|
}
|
||||||
|
|
||||||
await prisma.logEntry.create({
|
await prisma.logEntry.create({
|
||||||
data: request_data,
|
data: request_data,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log("[LOG]", e);
|
||||||
|
|
||||||
return NextResponse.json({ status: 0 });
|
return NextResponse.json({ status: 0 });
|
||||||
// console.log("[LOG]", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({ status: 1 });
|
return NextResponse.json({ status: 1 });
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
// "use client";
|
|
||||||
import { BarList, Bold, Card, Flex, Text, Title } from "@tremor/react";
|
|
||||||
import prisma from "@/lib/prisma";
|
|
||||||
import { estimateTokenLength } from "@/app/utils/token";
|
|
||||||
|
|
||||||
function HandleLogData(todayLog: [{ userName: string; logEntry: string }]) {
|
|
||||||
const data1 = todayLog.map((log) => {
|
|
||||||
return {
|
|
||||||
name: log.userName ?? "unknown",
|
|
||||||
value: estimateTokenLength(log.logEntry ?? ""),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
type Accumulator = {
|
|
||||||
[key: string]: number;
|
|
||||||
};
|
|
||||||
const data2 = data1.reduce<Accumulator>((acc, item) => {
|
|
||||||
if (acc[item.name]) {
|
|
||||||
acc[item.name] += item.value;
|
|
||||||
} else {
|
|
||||||
acc[item.name] = item.value;
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
const data3 = Object.entries(data2)
|
|
||||||
.map(([name, value]) => ({
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
}))
|
|
||||||
.sort((a, b) => {
|
|
||||||
return b.value - a.value;
|
|
||||||
});
|
|
||||||
return data3;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function UsageAnalysis() {
|
|
||||||
// 今天日期的开始和结束
|
|
||||||
const startDate = new Date();
|
|
||||||
startDate.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const endDate = new Date();
|
|
||||||
endDate.setHours(23, 59, 59, 999);
|
|
||||||
const todayLog = await prisma.logEntry.findMany({
|
|
||||||
where: {
|
|
||||||
createdAt: {
|
|
||||||
gte: startDate, // gte 表示 '大于等于'
|
|
||||||
lte: endDate, // lte 表示 '小于等于'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
user: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const log_data = HandleLogData(todayLog);
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
return (
|
|
||||||
<Card className="max-w-lg">
|
|
||||||
<Title>Website Analytics</Title>
|
|
||||||
<Flex className="mt-4">
|
|
||||||
<Text>
|
|
||||||
<Bold>Source</Bold>
|
|
||||||
</Text>
|
|
||||||
<Text>
|
|
||||||
<Bold>Visits</Bold>
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
<BarList data={log_data} className="mt-2" />
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
@ -2,17 +2,21 @@ import * as echarts from "echarts";
|
|||||||
import { EChartsOption } from "echarts";
|
import { EChartsOption } from "echarts";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { estimateTokenLength } from "@/app/utils/token";
|
import { addHours } from "date-fns";
|
||||||
|
|
||||||
|
// import { getTokenLength } from "@/app/utils/token";
|
||||||
|
|
||||||
const UsageByModelChart = dynamic(() => import("./usage-by-model-chart"), {
|
const UsageByModelChart = dynamic(() => import("./usage-by-model-chart"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
function HandleLogData(todayLog: [{ userName: string; logEntry: string }]) {
|
function HandleLogData(
|
||||||
|
todayLog: [{ userName: string; logEntry: string; logToken: number }],
|
||||||
|
) {
|
||||||
const data1 = todayLog.map((log) => {
|
const data1 = todayLog.map((log) => {
|
||||||
return {
|
return {
|
||||||
name: log.userName ?? "unknown",
|
name: log.userName ?? "unknown",
|
||||||
value: estimateTokenLength(log.logEntry ?? ""),
|
value: log.logToken,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,16 +55,32 @@ function HandleLogData(todayLog: [{ userName: string; logEntry: string }]) {
|
|||||||
|
|
||||||
export default async function UsageByModel() {
|
export default async function UsageByModel() {
|
||||||
// 今天日期的开始和结束
|
// 今天日期的开始和结束
|
||||||
const startDate = new Date();
|
var today = new Date();
|
||||||
startDate.setHours(0, 0, 0, 0);
|
today = addHours(today, +8);
|
||||||
|
const startOfTheDayInTimeZone = new Date(
|
||||||
const endDate = new Date();
|
today.getFullYear(),
|
||||||
endDate.setHours(23, 59, 59, 999);
|
today.getMonth(),
|
||||||
|
today.getDate(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
const endOfTheDayInTimeZone = new Date(
|
||||||
|
today.getFullYear(),
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDate(),
|
||||||
|
23,
|
||||||
|
59,
|
||||||
|
59,
|
||||||
|
); // 当天的结束时间
|
||||||
|
// const startDate = addHours(startOfTheDayInTimeZone, -8);
|
||||||
|
// const endDate = addHours(endOfTheDayInTimeZone, -8);
|
||||||
|
console.log("===", today, startOfTheDayInTimeZone, endOfTheDayInTimeZone);
|
||||||
const todayLog = await prisma.logEntry.findMany({
|
const todayLog = await prisma.logEntry.findMany({
|
||||||
where: {
|
where: {
|
||||||
createdAt: {
|
createdAt: {
|
||||||
gte: startDate, // gte 表示 '大于等于'
|
gte: startOfTheDayInTimeZone, // gte 表示 '大于等于'
|
||||||
lte: endDate, // lte 表示 '小于等于'
|
lte: endOfTheDayInTimeZone, // lte 表示 '小于等于'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
@ -68,6 +88,7 @@ export default async function UsageByModel() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("========", todayLog[todayLog.length - 1]);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const log_data = HandleLogData(todayLog);
|
const log_data = HandleLogData(todayLog);
|
||||||
|
|
||||||
|
@ -20,3 +20,22 @@ export function estimateTokenLength(input: string): number {
|
|||||||
|
|
||||||
return tokenLength;
|
return tokenLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// import { get_encoding } from "tiktoken";
|
||||||
|
|
||||||
|
export function getTokenLength(input: string): number {
|
||||||
|
// const { get_encoding } = require( "tiktoken" );
|
||||||
|
// const encoding = get_encoding("cl100k_base");
|
||||||
|
|
||||||
|
const { Tiktoken } = require("tiktoken/lite");
|
||||||
|
const cl100k_base = require("tiktoken/encoders/cl100k_base.json");
|
||||||
|
const encoding = new Tiktoken(
|
||||||
|
cl100k_base.bpe_ranks,
|
||||||
|
cl100k_base.special_tokens,
|
||||||
|
cl100k_base.pat_str,
|
||||||
|
);
|
||||||
|
const tokenLength = encoding.encode(input).length;
|
||||||
|
// console.log('[TOKEN],=========', input, tokenLength)
|
||||||
|
|
||||||
|
return tokenLength;
|
||||||
|
}
|
||||||
|
@ -28,11 +28,16 @@ const nextConfig = {
|
|||||||
}
|
}
|
||||||
// console.log('=======', config.optimization)
|
// console.log('=======', config.optimization)
|
||||||
|
|
||||||
|
|
||||||
config.resolve.fallback = {
|
config.resolve.fallback = {
|
||||||
child_process: false,
|
child_process: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// tiktoken
|
||||||
|
config.experiments = {
|
||||||
|
asyncWebAssembly: true,
|
||||||
|
layers: true,
|
||||||
|
};
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
output: mode,
|
output: mode,
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortaine/fetch-event-source": "^3.0.6",
|
"@fortaine/fetch-event-source": "^3.0.6",
|
||||||
|
"@hello-pangea/dnd": "^16.5.0",
|
||||||
"@next-auth/prisma-adapter": "^1.0.7",
|
"@next-auth/prisma-adapter": "^1.0.7",
|
||||||
"@prisma/client": "^5.7.0",
|
"@prisma/client": "^5.7.0",
|
||||||
"@hello-pangea/dnd": "^16.5.0",
|
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@tremor/react": "^3.12.1",
|
"@tremor/react": "^3.12.1",
|
||||||
"@vercel/analytics": "^1.1.1",
|
"@vercel/analytics": "^1.1.1",
|
||||||
@ -46,6 +46,7 @@
|
|||||||
"sonner": "^1.2.0",
|
"sonner": "^1.2.0",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
|
"tiktoken": "^1.0.11",
|
||||||
"use-debounce": "^10.0.0",
|
"use-debounce": "^10.0.0",
|
||||||
"zustand": "^4.3.8"
|
"zustand": "^4.3.8"
|
||||||
},
|
},
|
||||||
|
@ -71,6 +71,7 @@ model LogEntry {
|
|||||||
userName String? @db.VarChar(50)
|
userName String? @db.VarChar(50)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
logEntry String? @db.Text
|
logEntry String? @db.Text
|
||||||
|
logToken Int? @default(0)
|
||||||
user User? @relation(fields: [userName], references: [name], onDelete: NoAction)
|
user User? @relation(fields: [userName], references: [name], onDelete: NoAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user