feat:版本迭代

This commit is contained in:
jiangrui
2025-02-20 12:00:19 +08:00
parent fd110590af
commit 510fdc48f6
86 changed files with 5045 additions and 1161 deletions

View File

@@ -1,46 +1,61 @@
import { Request, Response, NextFunction } from "express";
import { Cloud115Service } from "../services/Cloud115Service";
import { config } from "../config";
import handleError from "../utils/handleError";
import { handleResponse } from "../utils/responseHandler";
import { sendSuccess, sendError } from "../utils/response";
import UserSetting from "../models/UserSetting";
const { cookie } = config.cloud115;
const cloud115 = new Cloud115Service(cookie);
const cloud115 = new Cloud115Service();
const setCookie = async (req: Request) => {
const userId = req.user?.userId;
const userSetting = await UserSetting.findOne({
where: { userId },
});
console.log(userSetting?.dataValues.cloud115Cookie);
if (userSetting && userSetting.dataValues.cloud115Cookie) {
cloud115.setCookie(userSetting.dataValues.cloud115Cookie);
} else {
throw new Error("请先设置115网盘cookie");
}
};
export const cloud115Controller = {
async getShareInfo(req: Request, res: Response, next: NextFunction) {
try {
const { shareCode, receiveCode } = req.query;
await setCookie(req);
const result = await cloud115.getShareInfo(shareCode as string, receiveCode as string);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取分享信息失败", next);
console.log(error);
sendError(res, { message: (error as Error).message || "获取分享信息失败" });
}
},
async getFolderList(req: Request, res: Response, next: NextFunction) {
try {
const { parentCid } = req.query;
await setCookie(req);
const result = await cloud115.getFolderList(parentCid as string);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取目录列表失败", next);
sendError(res, { message: (error as Error).message || "获取目录列表失败" });
}
},
async saveFile(req: Request, res: Response, next: NextFunction) {
try {
const { shareCode, receiveCode, fileId, folderId } = req.body;
await setCookie(req);
const result = await cloud115.saveSharedFile({
shareCode,
receiveCode,
fileId,
cid: folderId,
});
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "保存文件失败", next);
sendError(res, { message: (error as Error).message || "保存文件失败" });
}
},
};
export const Cloud115ServiceInstance = cloud115;

View File

@@ -0,0 +1,22 @@
import { Request, Response, NextFunction } from "express";
import DoubanService from "../services/DoubanService";
import { sendSuccess, sendError } from "../utils/response";
const doubanService = new DoubanService();
export const doubanController = {
async getDoubanHotList(req: Request, res: Response, next: NextFunction) {
try {
const { type = "movie", tag = "热门", page_limit = "50", page_start = "0" } = req.query;
const result = await doubanService.getHotList({
type: type as string,
tag: tag as string,
page_limit: page_limit as string,
page_start: page_start as string,
});
sendSuccess(res, result);
} catch (error) {
sendError(res, { message: "获取热门列表失败" });
}
},
};

View File

@@ -1,40 +1,52 @@
import { Request, Response, NextFunction } from "express";
import { QuarkService } from "../services/QuarkService";
import { config } from "../config";
import { handleResponse } from "../utils/responseHandler";
import handleError from "../utils/handleError";
import { sendSuccess, sendError } from "../utils/response";
import UserSetting from "../models/UserSetting";
const { cookie } = config.quark;
const quark = new QuarkService();
const quark = new QuarkService(cookie);
const setCookie = async (req: Request) => {
const userId = req.user?.userId;
const userSetting = await UserSetting.findOne({
where: { userId },
});
if (userSetting && userSetting.dataValues.quarkCookie) {
quark.setCookie(userSetting.dataValues.quarkCookie);
} else {
throw new Error("请先设置夸克网盘cookie");
}
};
export const quarkController = {
async getShareInfo(req: Request, res: Response, next: NextFunction) {
try {
const { pwdId, passcode } = req.query;
await setCookie(req);
const result = await quark.getShareInfo(pwdId as string, passcode as string);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取分享信息失败", next);
sendError(res, { message: "获取分享信息失败" });
}
},
async getFolderList(req: Request, res: Response, next: NextFunction) {
try {
const { parentCid } = req.query;
await setCookie(req);
const result = await quark.getFolderList(parentCid as string);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取目录列表失败", next);
sendError(res, { message: (error as Error).message || "获取目录列表失败" });
}
},
async saveFile(req: Request, res: Response, next: NextFunction) {
try {
await setCookie(req);
const result = await quark.saveSharedFile(req.body);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "保存文件失败", next);
sendError(res, { message: (error as Error).message || "保存文件失败" });
}
},
};

View File

@@ -1,8 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { RSSSearcher } from "../services/RSSSearcher";
import { Searcher } from "../services/Searcher";
import { handleResponse } from "../utils/responseHandler";
import handleError from "../utils/handleError";
import Searcher from "../services/Searcher";
import { sendSuccess, sendError } from "../utils/response";
export const resourceController = {
async rssSearch(req: Request, res: Response, next: NextFunction) {
@@ -10,23 +9,26 @@ export const resourceController = {
const { keyword } = req.query;
const searcher = new RSSSearcher();
const result = await searcher.searchAll(keyword as string);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取资源发生未知错误", next);
sendError(res, {
message: (error as Error).message || "RSS 搜索失败",
});
}
},
async search(req: Request, res: Response, next: NextFunction) {
try {
const { keyword, channelId = "", lastMessageId = "" } = req.query; // Remove `: string` from here
const searcher = new Searcher();
const result = await searcher.searchAll(
const result = await Searcher.searchAll(
keyword as string,
channelId as string,
lastMessageId as string
);
handleResponse(res, result, true);
sendSuccess(res, result);
} catch (error) {
handleError(res, error, "获取资源发生未知错误", next);
sendError(res, {
message: (error as Error).message || "搜索资源失败",
});
}
},
};

View File

@@ -0,0 +1,57 @@
import { Request, Response, NextFunction } from "express";
import { sendSuccess, sendError } from "../utils/response";
import Searcher from "../services/Searcher";
import UserSetting from "../models/UserSetting";
import GlobalSetting from "../models/GlobalSetting";
export const settingController = {
async get(req: Request, res: Response) {
try {
const userId = req.user?.userId;
const role = req.user?.role;
if (userId !== null) {
let userSettings = await UserSetting.findOne({ where: { userId } });
if (!userSettings) {
userSettings = {
userId: userId,
cloud115Cookie: "",
quarkCookie: "",
} as UserSetting;
if (userSettings) {
await UserSetting.create(userSettings);
}
}
const globalSetting = await GlobalSetting.findOne();
sendSuccess(res, {
data: {
userSettings,
globalSetting: role === 1 ? globalSetting : null,
},
});
} else {
sendError(res, { message: "用户ID无效" });
}
} catch (error) {
console.log("获取设置失败:" + error);
sendError(res, { message: (error as Error).message || "获取设置失败" });
}
},
async save(req: Request, res: Response) {
try {
const userId = req.user?.userId;
const role = req.user?.role;
if (userId !== null) {
const { userSettings, globalSetting } = req.body;
await UserSetting.update(userSettings, { where: { userId } });
if (role === 1 && globalSetting) await GlobalSetting.update(globalSetting, { where: {} });
Searcher.updateAxiosInstance();
sendSuccess(res, {
message: "保存成功",
});
}
} catch (error) {
console.log("保存设置失败:" + error);
sendError(res, { message: (error as Error).message || "保存设置失败" });
}
},
};

View File

@@ -0,0 +1,57 @@
import axios, { AxiosInstance } from "axios";
import { Request, Response } from "express";
import tunnel from "tunnel";
import GlobalSetting from "../models/GlobalSetting";
import { GlobalSettingAttributes } from "../models/GlobalSetting";
export class ImageControll {
private axiosInstance: AxiosInstance | null = null;
private isUpdate = false;
constructor() {
this.initializeAxiosInstance();
}
private async initializeAxiosInstance(isUpdate = false) {
let settings = null;
if (isUpdate) {
settings = await GlobalSetting.findOne();
this.isUpdate = isUpdate;
} else {
return;
}
const globalSetting = settings?.dataValues || ({} as GlobalSettingAttributes);
this.axiosInstance = axios.create({
timeout: 3000,
httpsAgent: tunnel.httpsOverHttp({
proxy: {
host: globalSetting.httpProxyHost,
port: globalSetting.httpProxyPort,
headers: {
"Proxy-Authorization": "",
},
},
}),
withCredentials: true,
});
}
async getImages(req: Request, res: Response, url: string) {
try {
if (!this.isUpdate) await this.initializeAxiosInstance(true);
const response = await this.axiosInstance?.get(url, { responseType: "stream" });
res.set("Content-Type", response?.headers["content-type"]);
response?.data.pipe(res);
} catch (error) {
res.status(500).send("Image fetch error");
}
}
}
const iamgesInstance = new ImageControll();
export const imageControll = {
getImages: async (req: Request, res: Response) => {
const url = req.query.url as string;
iamgesInstance.getImages(req, res, url);
},
};

View File

@@ -0,0 +1,62 @@
import { Request, Response } from "express";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import GlobalSetting from "../models/GlobalSetting";
import User from "../models/User";
import { config } from "../config";
import { sendSuccess, sendError } from "../utils/response";
const isValidInput = (input: string): boolean => {
// 检查是否包含空格或汉字
const regex = /^[^\s\u4e00-\u9fa5]+$/;
return regex.test(input);
};
export const userController = {
async register(req: Request, res: Response) {
const { username, password, registerCode } = req.body;
const globalSetting = await GlobalSetting.findOne();
const registerCodeList = [
globalSetting?.dataValues.CommonUserCode,
globalSetting?.dataValues.AdminUserCode,
];
if (!registerCode || !registerCodeList.includes(Number(registerCode))) {
return sendError(res, { message: "注册码错误" });
}
// 验证输入
if (!isValidInput(username) || !isValidInput(password)) {
return sendError(res, { message: "用户名、密码或注册码不能包含空格或汉字" });
}
// 检查用户名是否已存在
const existingUser = await User.findOne({ where: { username } });
if (existingUser) {
return sendError(res, { message: "用户名已存在" });
}
const hashedPassword = await bcrypt.hash(password, 10);
try {
const role = registerCodeList.findIndex((x) => x === Number(registerCode));
const user = await User.create({ username, password: hashedPassword, role });
sendSuccess(res, {
data: user,
message: "用户注册成功",
});
} catch (error: any) {
sendError(res, { message: error.message || "用户注册失败" });
}
},
async login(req: Request, res: Response) {
const { username, password } = req.body;
const user = await User.findOne({ where: { username } });
if (!user || !(await bcrypt.compare(password, user.password))) {
return sendError(res, { message: "用户名或密码错误" });
}
const token = jwt.sign({ userId: user.userId, role: user.role }, config.jwtSecret, {
expiresIn: "6h",
});
sendSuccess(res, {
data: {
token,
},
});
},
};