feat: new ui

This commit is contained in:
archer
2023-05-04 23:30:59 +08:00
parent 4d043e0e46
commit 014fb504a4
133 changed files with 2426 additions and 1696 deletions

View File

@@ -6,11 +6,7 @@ import { authToken } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { chatId, contentId } = req.query as { chatId: string; contentId: string };
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!chatId || !contentId) {
throw new Error('缺少参数');
}
@@ -18,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await connectToDatabase();
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
const chatRecord = await Chat.findById(chatId);

View File

@@ -6,7 +6,7 @@ import { authToken } from '@/service/utils/auth';
/* 获取历史记录 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const userId = await authToken(req.headers.authorization);
const userId = await authToken(req);
await connectToDatabase();
@@ -14,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
{
userId
},
'_id title modelId'
'_id title modelId updateTime latestChat'
)
.sort({ updateTime: -1 })
.limit(20);

View File

@@ -1,33 +1,57 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { connectToDatabase, Chat } from '@/service/mongo';
import { connectToDatabase, Chat, Model } from '@/service/mongo';
import type { InitChatResponse } from '@/api/response/chat';
import { authToken } from '@/service/utils/auth';
import { ChatItemType } from '@/types/chat';
import { authModel } from '@/service/utils/auth';
import mongoose from 'mongoose';
import { ModelStatusEnum } from '@/constants/model';
import type { ModelSchema } from '@/types/mongoSchema';
/* 初始化我的聊天框,需要身份验证 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
const userId = await authToken(authorization);
const userId = await authToken(req);
const { modelId, chatId } = req.query as { modelId: string; chatId: '' | string };
if (!modelId) {
throw new Error('缺少参数');
}
let { modelId, chatId } = req.query as { modelId: '' | string; chatId: '' | string };
await connectToDatabase();
// 获取 model 数据
const { model } = await authModel({ modelId, userId, authUser: false, authOwner: false });
let model: ModelSchema;
// 没有 modelId 时直接获取用户的第一个id
if (!modelId) {
const myModel = await Model.findOne({ userId });
if (!myModel) {
const { _id } = await Model.create({
name: 'AI助手1',
userId,
status: ModelStatusEnum.running
});
model = (await Model.findById(_id)) as ModelSchema;
} else {
model = myModel;
}
modelId = model._id;
} else {
// 校验使用权限
const authRes = await authModel({ modelId, userId, authUser: false, authOwner: false });
model = authRes.model;
}
// 历史记录
let history: ChatItemType[] = [];
if (chatId) {
// auth chatId
const chat = await Chat.countDocuments({
_id: chatId,
userId
});
if (chat === 0) {
throw new Error('聊天框不存在');
}
// 获取 chat.content 数据
history = await Chat.aggregate([
{
@@ -59,9 +83,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
data: {
chatId: chatId || '',
modelId: modelId,
name: model.name,
avatar: model.avatar,
intro: model.share.intro,
model: {
name: model.name,
avatar: model.avatar,
intro: model.share.intro,
canUse: model.share.isShare || String(model.userId) === userId
},
chatModel: model.chat.chatModel,
history
}

View File

@@ -1,6 +1,5 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { ChatItemType } from '@/types/chat';
import { connectToDatabase, Chat } from '@/service/mongo';
import { authToken } from '@/service/utils/auth';
@@ -8,7 +7,7 @@ import { authToken } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { id } = req.query;
const userId = await authToken(req.headers.authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -20,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
throw new Error('缺少参数');
}
const userId = await authToken(req.headers.authorization);
const userId = await authToken(req);
await connectToDatabase();
@@ -40,7 +40,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
userId,
modelId,
content,
title: content[0].value.slice(0, 20)
title: content[0].value.slice(0, 20),
latestChat: content[content.length - 1].value
});
return jsonRes(res, {
data: _id
@@ -53,7 +54,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
$each: content
}
},
updateTime: new Date()
updateTime: new Date(),
latestChat: content[content.length - 1].value
});
}
jsonRes(res);

View File

@@ -11,18 +11,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const { name } = req.body as {
name: string;
};
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!name) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -8,18 +8,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
let { dataId } = req.query as {
dataId: string;
};
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!dataId) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await PgClient.delete('modelData', {
where: [['user_id', userId], 'AND', ['id', dataId]]

View File

@@ -10,18 +10,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modelId: string;
};
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!modelId) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -16,9 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
await connectToDatabase();
const { authorization } = req.headers;
await authToken(authorization);
await authToken(req);
const data = await axios
.get(url, {

View File

@@ -19,21 +19,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
pageSize: string;
searchText: string;
};
const { authorization } = req.headers;
pageNum = +pageNum;
pageSize = +pageSize;
if (!authorization) {
throw new Error('无权操作');
}
if (!modelId) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -12,9 +12,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
await connectToDatabase();
const { authorization } = req.headers;
const userId = await authToken(authorization);
const userId = await authToken(req);
// 找到长度大于0的数据
const data = await SplitData.find({

View File

@@ -13,18 +13,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modelId: string;
data: string[][];
};
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!modelId || !Array.isArray(data)) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();
@@ -36,9 +31,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
// 去重
const searchRes = await Promise.allSettled(
data.map(async ([q, a]) => {
if (!q || !a) {
return Promise.reject('q/a为空');
data.map(async ([q, a = '']) => {
if (!q) {
return Promise.reject('q为空');
}
try {
q = q.replace(/\\n/g, '\n');

View File

@@ -13,18 +13,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modelId: string;
data: { a: ModelDataSchema['a']; q: ModelDataSchema['q'] }[];
};
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!modelId || !Array.isArray(data)) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -8,18 +8,13 @@ import { PgClient } from '@/service/pg';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { dataId, a, q } = req.body as { dataId: string; a: string; q?: string };
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!dataId) {
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
// 更新 pg 内容
await PgClient.update('modelData', {

View File

@@ -20,9 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
await connectToDatabase();
const { authorization } = req.headers;
const userId = await authToken(authorization);
const userId = await authToken(req);
// 验证是否是该用户的 model
const model = await Model.findOne({

View File

@@ -1,6 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { Chat, Model, connectToDatabase } from '@/service/mongo';
import { Chat, Model, connectToDatabase, Collection } from '@/service/mongo';
import { authToken } from '@/service/utils/auth';
import { PgClient } from '@/service/pg';
import { authModel } from '@/service/utils/auth';
@@ -9,18 +9,13 @@ import { authModel } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { modelId } = req.query as { modelId: string };
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!modelId) {
throw new Error('参数错误');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();
@@ -40,6 +35,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modelId
});
// 删除收藏列表
await Collection.deleteMany({
modelId
});
// 删除模型
await Model.deleteOne({
_id: modelId,

View File

@@ -7,12 +7,6 @@ import { authModel } from '@/service/utils/auth';
/* 获取我的模型 */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
const { modelId } = req.query as { modelId: string };
if (!modelId) {
@@ -20,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -1,32 +1,49 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { connectToDatabase } from '@/service/mongo';
import { connectToDatabase, Collection, Model } from '@/service/mongo';
import { authToken } from '@/service/utils/auth';
import { Model } from '@/service/models/model';
import type { ModelListResponse } from '@/api/response/model';
/* 获取模型列表 */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();
// 根据 userId 获取模型信息
const models = await Model.find({
userId
}).sort({
_id: -1
});
const [myModels, myCollections] = await Promise.all([
Model.find(
{
userId
},
'_id avatar name chat.systemPrompt'
).sort({
_id: -1
}),
Collection.find({
userId
}).populate('modelId', '_id avatar name chat.systemPrompt')
]);
jsonRes(res, {
data: models
jsonRes<ModelListResponse>(res, {
data: {
myModels: myModels.map((item) => ({
_id: item._id,
name: item.name,
avatar: item.avatar,
systemPrompt: item.chat.systemPrompt
})),
myCollectionModels: myCollections
.map((item: any) => ({
_id: item.modelId?._id,
name: item.modelId?.name,
avatar: item.modelId?.avatar,
systemPrompt: item.modelId?.chat.systemPrompt
}))
.filter((item) => !myModels.find((model) => String(model._id) === String(item._id))) // 去重
}
});
} catch (err) {
jsonRes(res, {

View File

@@ -12,7 +12,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
throw new Error('缺少参数');
}
// 凭证校验
const userId = await authToken(req.headers.authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -8,7 +8,7 @@ import type { ShareModelItem } from '@/types/model';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
// 凭证校验
const userId = await authToken(req.headers.authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -1,7 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { connectToDatabase, Collection, Model } from '@/service/mongo';
import { authToken } from '@/service/utils/auth';
import type { PagingData } from '@/types';
import type { ShareModelItem } from '@/types/model';

View File

@@ -11,18 +11,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
try {
const { name, avatar, chat, share, security } = req.body as ModelUpdateParams;
const { modelId } = req.query as { modelId: string };
const { authorization } = req.headers;
if (!authorization) {
throw new Error('无权操作');
}
if (!name || !chat || !security || !modelId) {
throw new Error('参数错误');
}
// 凭证校验
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -46,7 +46,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
throw new Error('prompts is not array');
}
if (prompts.length > 30 || prompts.length === 0) {
throw new Error('prompts length range 1-30');
throw new Error('Prompts arr length range 1-30');
}
await connectToDatabase();

View File

@@ -7,17 +7,12 @@ import { authToken } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { id } = req.query as { id: string };
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
if (!id) {
throw new Error('缺少参数');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -7,13 +7,7 @@ import { UserOpenApiKey } from '@/types/openapi';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -8,13 +8,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890');
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -11,10 +11,9 @@ import { PRICE_SCALE } from '@/constants/common';
/* 校验支付结果 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
let { payId } = req.query as { payId: string };
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -7,17 +7,12 @@ import type { BillSchema } from '@/types/mongoSchema';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
let { pageNum = 1, pageSize = 10 } = req.query as { pageNum: string; pageSize: string };
pageNum = +pageNum;
pageSize = +pageSize;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -11,14 +11,10 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 20);
/* 获取支付二维码 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
let { amount = 0 } = req.query as { amount: string };
amount = +amount;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
const id = nanoid();
await connectToDatabase();

View File

@@ -5,12 +5,7 @@ import { connectToDatabase, Pay } from '@/service/mongo';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -32,9 +32,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
throw new Error('密码错误');
}
res.setHeader('Set-Cookie', `token=${generateToken(user._id)}; Path=/; HttpOnly`);
jsonRes(res, {
data: {
token: generateToken(user._id),
user
}
});

View File

@@ -7,13 +7,7 @@ import mongoose from 'mongoose';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -6,15 +6,11 @@ import { authToken } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
let { pageNum = 1, pageSize = 10 } = req.query as { pageNum: string; pageSize: string };
pageNum = +pageNum;
pageSize = +pageSize;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -56,9 +56,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
username
});
res.setHeader('Set-Cookie', `token=${generateToken(user._id)}; Path=/; HttpOnly`);
jsonRes(res, {
data: {
token: generateToken(user._id),
user
}
});

View File

@@ -7,13 +7,7 @@ import { authToken } from '@/service/utils/auth';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { authorization } = req.headers;
if (!authorization) {
throw new Error('缺少登录凭证');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();

View File

@@ -9,14 +9,9 @@ import { UserUpdateParams } from '@/types/user';
/* 更新一些基本信息 */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { openaiKey } = req.body as UserUpdateParams;
const { authorization } = req.headers;
const { openaiKey, avatar } = req.body as UserUpdateParams;
if (!authorization) {
throw new Error('无权操作');
}
const userId = await authToken(authorization);
const userId = await authToken(req);
await connectToDatabase();
@@ -26,7 +21,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
_id: userId
},
{
openaiKey
...(avatar && { avatar }),
...(openaiKey && { openaiKey })
}
);

View File

@@ -48,9 +48,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
throw new Error('获取用户信息异常');
}
res.setHeader('Set-Cookie', `token=${generateToken(user._id)}; Path=/; HttpOnly`);
jsonRes(res, {
data: {
token: generateToken(user._id),
user
}
});