+
📊 模型价格表格
+
+ 在飞书多维表格中查看完整价格表
+
+
+ 查看所有 AI 模型的详细价格信息,包括输入输出价格、通道类型等
-
-
-
+
+
+
+
🔄 JSON API 接口
+
+ 获取价格数据的 JSON 格式
+
+
+ 用于程序接入的 JSON 格式数据,支持实时获取最新价格信息
-
-
-
+
+
+
+
📝 提交/更新价格
+
+ 提交新的模型价格信息
+
+
+ 通过飞书表单提交新的模型价格或更新现有模型的价格信息
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
`;
@@ -135,60 +153,104 @@ function validateData(data: any): string | null {
return null;
}
-// 处理请求
+// 修改处理函数
async function handler(req: Request): Promise
{
const url = new URL(req.url);
- // 添加 CORS 支持
const headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
};
- // 处理 OPTIONS 请求
if (req.method === "OPTIONS") {
return new Response(null, { headers });
}
- // API 端点
if (url.pathname === "/api/prices") {
if (req.method === "POST") {
try {
- let data;
+ let rawData;
const contentType = req.headers.get("content-type") || "";
+ // 获取原始数据
if (contentType.includes("application/json")) {
- data = await req.json();
+ rawData = await req.json();
} else if (contentType.includes("application/x-www-form-urlencoded")) {
const formData = await req.formData();
- data = {};
+ rawData = {};
for (const [key, value] of formData.entries()) {
- // 如果值包含逗号,只取第一个值
- const actualValue = String(value).split(',')[0];
- data[key] = actualValue;
+ rawData[key] = value;
}
} else {
throw new Error("不支持的内容类型");
}
- console.log("Received raw data:", data); // 调试日志
+ console.log("Received raw data:", rawData);
+
+ // 修改数组声明
+ let dataArray: Price[] = [];
- // 清理和转换数据
- const cleanData = {
- model: String(data.model).trim(),
- type: String(data.type).trim(),
- channel_type: Number(String(data.channel_type).split(',')[0]),
- input: Number(String(data.input).split(',')[0]),
- output: Number(String(data.output).split(',')[0])
- };
+ // 如果数据中的字段包含逗号,说明是批量数据
+ if (typeof rawData.model === 'string' && rawData.model.includes(',')) {
+ const models = rawData.model.split(',');
+ const types = rawData.type.split(',');
+ const channelTypes = rawData.channel_type.split(',');
+ const inputs = rawData.input.split(',');
+ const outputs = rawData.output.split(',');
+
+ // 确保所有数组长度一致
+ const length = Math.min(
+ models.length,
+ types.length,
+ channelTypes.length,
+ inputs.length,
+ outputs.length
+ );
+
+ // 构建数据数组
+ for (let i = 0; i < length; i++) {
+ if (models[i] && types[i] && channelTypes[i] && inputs[i] && outputs[i]) {
+ dataArray.push({
+ model: models[i].trim(),
+ type: types[i].trim(),
+ channel_type: Number(channelTypes[i]),
+ input: Number(inputs[i]),
+ output: Number(outputs[i])
+ });
+ }
+ }
+ } else {
+ // 单条数据
+ dataArray.push({
+ model: String(rawData.model).trim(),
+ type: String(rawData.type).trim(),
+ channel_type: Number(rawData.channel_type),
+ input: Number(rawData.input),
+ output: Number(rawData.output)
+ });
+ }
- console.log("Cleaned data:", cleanData); // 调试日志
+ console.log("Processed data array:", dataArray);
- // 验证数据
- const error = validateData(cleanData);
- if (error) {
- return new Response(JSON.stringify({ error }), {
+ // 验证所有数据
+ const errors = [];
+ const validData = [];
+
+ for (const data of dataArray) {
+ const error = validateData(data);
+ if (error) {
+ errors.push({ data, error });
+ } else {
+ validData.push(data);
+ }
+ }
+
+ if (errors.length > 0) {
+ return new Response(JSON.stringify({
+ error: "部分数据验证失败",
+ details: errors
+ }), {
status: 400,
headers: {
"Content-Type": "application/json",
@@ -201,14 +263,15 @@ async function handler(req: Request): Promise {
const prices = await readPrices();
// 添加新数据
- prices.push(cleanData);
+ prices.push(...validData);
// 保存数据
await writePrices(prices);
return new Response(JSON.stringify({
success: true,
- data: cleanData
+ processed: validData.length,
+ data: validData
}), {
headers: {
"Content-Type": "application/json",
@@ -216,7 +279,7 @@ async function handler(req: Request): Promise {
}
});
} catch (error) {
- console.error("Processing error:", error); // 调试日志
+ console.error("Processing error:", error);
return new Response(JSON.stringify({
error: error.message,
details: "数据处理失败,请检查输入格式"