From f5106e782a3e3e3eb139cc43b0d5e0dbe52aacab Mon Sep 17 00:00:00 2001 From: jiangrui Date: Mon, 24 Feb 2025 15:22:43 +0800 Subject: [PATCH] format:format and fix code --- .eslintignore | 4 + .eslintrc.js | 57 ++ .prettierignore | 5 +- .prettierrc.js | 14 + .prettierrc.json | 11 - backend/src/app.ts | 2 +- backend/src/controllers/cloud115.ts | 11 +- backend/src/controllers/douban.ts | 4 +- backend/src/controllers/quark.ts | 10 +- backend/src/controllers/resource.ts | 17 +- backend/src/controllers/setting.ts | 6 +- backend/src/controllers/teleImages.ts | 6 +- backend/src/controllers/user.ts | 8 +- backend/src/middleware/auth.ts | 2 +- backend/src/middleware/errorHandler.ts | 8 +- backend/src/middleware/validateRequest.ts | 4 +- backend/src/routes/api.ts | 1 - backend/src/routes/user.ts | 2 +- backend/src/services/Cloud115Service.ts | 31 +- backend/src/services/DoubanService.ts | 16 +- backend/src/services/QuarkService.ts | 41 +- backend/src/services/RSSSearcher.ts | 116 --- backend/src/services/Searcher.ts | 7 +- backend/src/types/express.ts | 1 + backend/src/utils/axiosInstance.ts | 2 - backend/src/utils/handleError.ts | 9 +- frontend/auto-imports.d.ts | 2 +- frontend/components.d.ts | 5 - frontend/src/App.vue | 56 +- frontend/src/components/AsideMenu.vue | 212 +++-- frontend/src/components/Home/FolderSelect.vue | 176 ++-- frontend/src/components/Home/ResourceCard.vue | 228 ++--- .../src/components/Home/ResourceTable.vue | 161 ++-- frontend/src/env.d.ts | 2 +- frontend/src/main.ts | 6 +- frontend/src/stores/resource.ts | 122 ++- frontend/src/styles/global.scss | 14 +- frontend/src/types/index.ts | 2 +- frontend/src/utils/request.ts | 16 +- frontend/src/views/Douban.vue | 204 +++-- frontend/src/views/Home.vue | 110 +-- frontend/src/views/Login.vue | 307 +++---- frontend/src/views/ResourceList.vue | 226 ++--- frontend/src/views/Setting.vue | 128 +-- package.json | 18 +- pnpm-lock.yaml | 837 +++++++++++++++++- 46 files changed, 2055 insertions(+), 1172 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .prettierrc.js delete mode 100644 .prettierrc.json delete mode 100644 backend/src/services/RSSSearcher.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..77440d3 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +node_modules +dist +build +coverage \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..295720a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,57 @@ +module.exports = { + root: true, + ignorePatterns: ["node_modules", "dist", "build", "coverage"], + env: { + node: true, + es6: true, + }, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint"], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + ], + rules: { + "prettier/prettier": "error", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/explicit-function-return-type": 0, + }, + overrides: [ + { + files: ["frontend/**/*.{js,ts,vue}"], + env: { + browser: true, + }, + parser: "vue-eslint-parser", + parserOptions: { + parser: "@typescript-eslint/parser", + ecmaVersion: 2020, + sourceType: "module", + }, + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:vue/vue3-recommended", + "plugin:prettier/recommended", + ], + plugins: ["@typescript-eslint", "vue"], + rules: { + "vue/multi-word-component-names": "off", + "vue/require-default-prop": "off", + "vue/no-v-html": "off", + }, + }, + { + files: ["backend/**/*.{js,ts}"], + env: { + node: true, + }, + rules: { + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/no-non-null-assertion": "warn", + }, + }, + ], +}; diff --git a/.prettierignore b/.prettierignore index 30fcb30..6009c54 100644 --- a/.prettierignore +++ b/.prettierignore @@ -24,4 +24,7 @@ node_modules # 系统文件 .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +# 版本控制 +.git \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..7878679 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,14 @@ +module.exports = { + semi: true, + trailingComma: "es5", + singleQuote: false, + printWidth: 100, + tabWidth: 2, + useTabs: false, + endOfLine: "auto", + arrowParens: "always", + bracketSpacing: true, + embeddedLanguageFormatting: "auto", + htmlWhitespaceSensitivity: "css", + vueIndentScriptAndStyle: false, +}; diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 4e28c26..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "semi": true, - "singleQuote": false, - "tabWidth": 2, - "printWidth": 100, - "trailingComma": "es5", - "bracketSpacing": true, - "endOfLine": "lf", - "arrowParens": "always", - "vueIndentScriptAndStyle": true -} diff --git a/backend/src/app.ts b/backend/src/app.ts index 51951fa..f3c6d5a 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -38,7 +38,7 @@ app.use((req, res, next) => { app.use("/", routes); -const initializeGlobalSettings = async () => { +const initializeGlobalSettings = async (): Promise => { const settings = await GlobalSetting.findOne(); if (!settings) { await GlobalSetting.create({ diff --git a/backend/src/controllers/cloud115.ts b/backend/src/controllers/cloud115.ts index f289098..a70185f 100644 --- a/backend/src/controllers/cloud115.ts +++ b/backend/src/controllers/cloud115.ts @@ -1,15 +1,14 @@ -import { Request, Response, NextFunction } from "express"; +import { Request, Response } from "express"; import { Cloud115Service } from "../services/Cloud115Service"; import { sendSuccess, sendError } from "../utils/response"; import UserSetting from "../models/UserSetting"; const cloud115 = new Cloud115Service(); -const setCookie = async (req: Request) => { +const setCookie = async (req: Request): Promise => { 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 { @@ -18,7 +17,7 @@ const setCookie = async (req: Request) => { }; export const cloud115Controller = { - async getShareInfo(req: Request, res: Response, next: NextFunction) { + async getShareInfo(req: Request, res: Response): Promise { try { const { shareCode, receiveCode } = req.query; await setCookie(req); @@ -30,7 +29,7 @@ export const cloud115Controller = { } }, - async getFolderList(req: Request, res: Response, next: NextFunction) { + async getFolderList(req: Request, res: Response): Promise { try { const { parentCid } = req.query; await setCookie(req); @@ -41,7 +40,7 @@ export const cloud115Controller = { } }, - async saveFile(req: Request, res: Response, next: NextFunction) { + async saveFile(req: Request, res: Response): Promise { try { const { shareCode, receiveCode, fileId, folderId } = req.body; await setCookie(req); diff --git a/backend/src/controllers/douban.ts b/backend/src/controllers/douban.ts index 2af3246..461061a 100644 --- a/backend/src/controllers/douban.ts +++ b/backend/src/controllers/douban.ts @@ -1,11 +1,11 @@ -import { Request, Response, NextFunction } from "express"; +import { Request, Response } 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) { + async getDoubanHotList(req: Request, res: Response): Promise { try { const { type = "movie", tag = "热门", page_limit = "50", page_start = "0" } = req.query; const result = await doubanService.getHotList({ diff --git a/backend/src/controllers/quark.ts b/backend/src/controllers/quark.ts index 631e88f..5673aa0 100644 --- a/backend/src/controllers/quark.ts +++ b/backend/src/controllers/quark.ts @@ -1,11 +1,11 @@ -import { Request, Response, NextFunction } from "express"; +import { Request, Response } from "express"; import { QuarkService } from "../services/QuarkService"; import { sendSuccess, sendError } from "../utils/response"; import UserSetting from "../models/UserSetting"; const quark = new QuarkService(); -const setCookie = async (req: Request) => { +const setCookie = async (req: Request): Promise => { const userId = req.user?.userId; const userSetting = await UserSetting.findOne({ where: { userId }, @@ -18,7 +18,7 @@ const setCookie = async (req: Request) => { }; export const quarkController = { - async getShareInfo(req: Request, res: Response, next: NextFunction) { + async getShareInfo(req: Request, res: Response): Promise { try { const { pwdId, passcode } = req.query; await setCookie(req); @@ -29,7 +29,7 @@ export const quarkController = { } }, - async getFolderList(req: Request, res: Response, next: NextFunction) { + async getFolderList(req: Request, res: Response): Promise { try { const { parentCid } = req.query; await setCookie(req); @@ -40,7 +40,7 @@ export const quarkController = { } }, - async saveFile(req: Request, res: Response, next: NextFunction) { + async saveFile(req: Request, res: Response): Promise { try { await setCookie(req); const result = await quark.saveSharedFile(req.body); diff --git a/backend/src/controllers/resource.ts b/backend/src/controllers/resource.ts index f07dbbd..2be16e7 100644 --- a/backend/src/controllers/resource.ts +++ b/backend/src/controllers/resource.ts @@ -1,22 +1,9 @@ -import { Request, Response, NextFunction } from "express"; -import { RSSSearcher } from "../services/RSSSearcher"; +import { Request, Response } from "express"; import Searcher from "../services/Searcher"; import { sendSuccess, sendError } from "../utils/response"; export const resourceController = { - async rssSearch(req: Request, res: Response, next: NextFunction) { - try { - const { keyword } = req.query; - const searcher = new RSSSearcher(); - const result = await searcher.searchAll(keyword as string); - sendSuccess(res, result); - } catch (error) { - sendError(res, { - message: (error as Error).message || "RSS 搜索失败", - }); - } - }, - async search(req: Request, res: Response, next: NextFunction) { + async search(req: Request, res: Response): Promise { try { const { keyword, channelId = "", lastMessageId = "" } = req.query; // Remove `: string` from here const result = await Searcher.searchAll( diff --git a/backend/src/controllers/setting.ts b/backend/src/controllers/setting.ts index 3931810..659792b 100644 --- a/backend/src/controllers/setting.ts +++ b/backend/src/controllers/setting.ts @@ -1,11 +1,11 @@ -import { Request, Response, NextFunction } from "express"; +import { Request, Response } 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) { + async get(req: Request, res: Response): Promise { try { const userId = req.user?.userId; const role = req.user?.role; @@ -36,7 +36,7 @@ export const settingController = { sendError(res, { message: (error as Error).message || "获取设置失败" }); } }, - async save(req: Request, res: Response) { + async save(req: Request, res: Response): Promise { try { const userId = req.user?.userId; const role = req.user?.role; diff --git a/backend/src/controllers/teleImages.ts b/backend/src/controllers/teleImages.ts index c1eccf2..7038eb5 100644 --- a/backend/src/controllers/teleImages.ts +++ b/backend/src/controllers/teleImages.ts @@ -12,7 +12,7 @@ export class ImageControll { this.initializeAxiosInstance(); } - private async initializeAxiosInstance(isUpdate = false) { + private async initializeAxiosInstance(isUpdate = false): Promise { let settings = null; if (isUpdate) { settings = await GlobalSetting.findOne(); @@ -35,7 +35,7 @@ export class ImageControll { withCredentials: true, }); } - async getImages(req: Request, res: Response, url: string) { + async getImages(req: Request, res: Response, url: string): Promise { try { if (!this.isUpdate) await this.initializeAxiosInstance(true); const response = await this.axiosInstance?.get(url, { responseType: "stream" }); @@ -50,7 +50,7 @@ export class ImageControll { const iamgesInstance = new ImageControll(); export const imageControll = { - getImages: async (req: Request, res: Response) => { + getImages: async (req: Request, res: Response): Promise => { const url = req.query.url as string; iamgesInstance.getImages(req, res, url); }, diff --git a/backend/src/controllers/user.ts b/backend/src/controllers/user.ts index 9340910..84d67d5 100644 --- a/backend/src/controllers/user.ts +++ b/backend/src/controllers/user.ts @@ -12,7 +12,7 @@ const isValidInput = (input: string): boolean => { return regex.test(input); }; export const userController = { - async register(req: Request, res: Response) { + async register(req: Request, res: Response): Promise { const { username, password, registerCode } = req.body; const globalSetting = await GlobalSetting.findOne(); const registerCodeList = [ @@ -39,12 +39,12 @@ export const userController = { data: user, message: "用户注册成功", }); - } catch (error: any) { - sendError(res, { message: error.message || "用户注册失败" }); + } catch (error) { + sendError(res, { message: (error as Error).message || "用户注册失败" }); } }, - async login(req: Request, res: Response) { + async login(req: Request, res: Response): Promise { const { username, password } = req.body; const user = await User.findOne({ where: { username } }); if (!user || !(await bcrypt.compare(password, user.password))) { diff --git a/backend/src/middleware/auth.ts b/backend/src/middleware/auth.ts index ffbd8f3..6a41518 100644 --- a/backend/src/middleware/auth.ts +++ b/backend/src/middleware/auth.ts @@ -15,7 +15,7 @@ export const authMiddleware = async ( req: AuthenticatedRequest, res: Response, next: NextFunction -) => { +): Promise => { if (req.path === "/user/login" || req.path === "/user/register") { return next(); } diff --git a/backend/src/middleware/errorHandler.ts b/backend/src/middleware/errorHandler.ts index 76f12da..c7ec51e 100644 --- a/backend/src/middleware/errorHandler.ts +++ b/backend/src/middleware/errorHandler.ts @@ -1,6 +1,10 @@ -import { Request, Response, NextFunction } from "express"; +import { Request, Response } from "express"; -export const errorHandler = (err: any, req: Request, res: Response, next: NextFunction) => { +interface CustomError extends Error { + status?: number; +} + +export const errorHandler = (err: CustomError, req: Request, res: Response): void => { console.error(err); res.status(err.status || 500).json({ success: false, diff --git a/backend/src/middleware/validateRequest.ts b/backend/src/middleware/validateRequest.ts index 907105a..7f6d02f 100644 --- a/backend/src/middleware/validateRequest.ts +++ b/backend/src/middleware/validateRequest.ts @@ -1,6 +1,8 @@ import { Request, Response, NextFunction } from "express"; -export const validateRequest = (requiredParams: string[]) => { +export const validateRequest = ( + requiredParams: string[] +): ((req: Request, res: Response, next: NextFunction) => Response | void) => { return (req: Request, res: Response, next: NextFunction) => { const missingParams = requiredParams.filter((param) => !req.query[param] && !req.body[param]); if (missingParams.length > 0) { diff --git a/backend/src/routes/api.ts b/backend/src/routes/api.ts index a8c5aa1..73367d4 100644 --- a/backend/src/routes/api.ts +++ b/backend/src/routes/api.ts @@ -19,7 +19,6 @@ router.use("/setting", settingRoutes); // 资源搜索 router.get("/search", resourceController.search); -router.get("/rssSearch", resourceController.rssSearch); // 115网盘相关 router.get("/cloud115/share-info", cloud115Controller.getShareInfo); diff --git a/backend/src/routes/user.ts b/backend/src/routes/user.ts index 8d49002..f0dbc76 100644 --- a/backend/src/routes/user.ts +++ b/backend/src/routes/user.ts @@ -7,4 +7,4 @@ const router = express.Router(); router.post("/register", userController.register); router.post("/login", userController.login); -export default router; \ No newline at end of file +export default router; diff --git a/backend/src/services/Cloud115Service.ts b/backend/src/services/Cloud115Service.ts index 7b19968..50e4f00 100644 --- a/backend/src/services/Cloud115Service.ts +++ b/backend/src/services/Cloud115Service.ts @@ -4,6 +4,23 @@ import { Logger } from "../utils/logger"; import { config } from "../config/index"; import { ShareInfoResponse } from "../types/cloud115"; +interface Cloud115ListItem { + cid: string; + n: string; + s: number; +} + +interface Cloud115FolderItem { + cid: string; + n: string; + ns: number; +} + +interface Cloud115PathItem { + cid: string; + name: string; +} + export class Cloud115Service { private api: AxiosInstance; private cookie: string = ""; @@ -39,7 +56,7 @@ export class Cloud115Service { }); } - public setCookie(cookie: string) { + public setCookie(cookie: string): void { this.cookie = cookie; } @@ -56,7 +73,7 @@ export class Cloud115Service { if (response.data?.state && response.data.data?.list?.length > 0) { return { - data: response.data.data.list.map((item: any) => ({ + data: response.data.data.list.map((item: Cloud115ListItem) => ({ fileId: item.cid, fileName: item.n, fileSize: item.s, @@ -66,7 +83,9 @@ export class Cloud115Service { throw new Error("未找到文件信息"); } - async getFolderList(parentCid = "0") { + async getFolderList( + parentCid = "0" + ): Promise<{ data: { cid: string; name: string; path: Cloud115PathItem[] }[] }> { const response = await this.api.get("/files", { params: { aid: 1, @@ -87,8 +106,8 @@ export class Cloud115Service { if (response.data?.state) { return { data: response.data.data - .filter((item: any) => item.cid && !!item.ns) - .map((folder: any) => ({ + .filter((item: Cloud115FolderItem) => item.cid && !!item.ns) + .map((folder: Cloud115FolderItem) => ({ cid: folder.cid, name: folder.n, path: response.data.path, @@ -105,7 +124,7 @@ export class Cloud115Service { shareCode: string; receiveCode: string; fileId: string; - }) { + }): Promise<{ message: string; data: unknown }> { const param = new URLSearchParams({ cid: params.cid, user_id: config.cloud115.userId, diff --git a/backend/src/services/DoubanService.ts b/backend/src/services/DoubanService.ts index a6f54ce..8f27a7a 100644 --- a/backend/src/services/DoubanService.ts +++ b/backend/src/services/DoubanService.ts @@ -1,6 +1,15 @@ import { AxiosHeaders, AxiosInstance } from "axios"; import { createAxiosInstance } from "../utils/axiosInstance"; +interface DoubanSubject { + id: string; + title: string; + rate: string; + cover: string; + url: string; + is_new: boolean; +} + class DoubanService { private baseUrl: string; private api: AxiosInstance; @@ -28,7 +37,12 @@ class DoubanService { ); } - async getHotList(params: { type: string; tag: string; page_limit: string; page_start: string }) { + async getHotList(params: { + type: string; + tag: string; + page_limit: string; + page_start: string; + }): Promise<{ data: DoubanSubject[] }> { try { const response = await this.api.get("/search_subjects", { params: params, diff --git a/backend/src/services/QuarkService.ts b/backend/src/services/QuarkService.ts index bbda65d..67b2cb1 100644 --- a/backend/src/services/QuarkService.ts +++ b/backend/src/services/QuarkService.ts @@ -2,6 +2,23 @@ import { AxiosInstance, AxiosHeaders } from "axios"; import { Logger } from "../utils/logger"; import { createAxiosInstance } from "../utils/axiosInstance"; +interface QuarkShareInfo { + stoken?: string; + pwdId?: string; + list: { + fid: string; + file_name: string; + file_type: number; + share_fid_token: string; + }[]; +} + +interface QuarkFolderItem { + fid: string; + file_name: string; + file_type: number; +} + export class QuarkService { private api: AxiosInstance; private cookie: string = ""; @@ -34,11 +51,11 @@ export class QuarkService { }); } - public setCookie(cookie: string) { + public setCookie(cookie: string): void { this.cookie = cookie; } - async getShareInfo(pwdId: string, passcode = "") { + async getShareInfo(pwdId: string, passcode = ""): Promise<{ data: QuarkShareInfo }> { const response = await this.api.post( `/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc&uc_param_str=&__dt=994&__t=${Date.now()}`, { @@ -49,7 +66,7 @@ export class QuarkService { if (response.data?.status === 200 && response.data.data) { const fileInfo = response.data.data; if (fileInfo.stoken) { - let res = await this.getShareList(pwdId, fileInfo.stoken); + const res = await this.getShareList(pwdId, fileInfo.stoken); return { data: res, }; @@ -58,7 +75,7 @@ export class QuarkService { throw new Error("获取夸克分享信息失败"); } - async getShareList(pwdId: string, stoken: string) { + async getShareList(pwdId: string, stoken: string): Promise { const response = await this.api.get("/1/clouddrive/share/sharepage/detail", { params: { pr: "ucpro", @@ -80,8 +97,8 @@ export class QuarkService { }); if (response.data?.data) { const list = response.data.data.list - .filter((item: any) => item.fid) - .map((folder: any) => ({ + .filter((item: QuarkShareInfo["list"][0]) => item.fid) + .map((folder: QuarkShareInfo["list"][0]) => ({ fileId: folder.fid, fileName: folder.file_name, fileIdToken: folder.share_fid_token, @@ -89,7 +106,7 @@ export class QuarkService { return { list, pwdId, - stoken: stoken, + stoken, }; } else { return { @@ -98,7 +115,9 @@ export class QuarkService { } } - async getFolderList(parentCid = "0") { + async getFolderList( + parentCid = "0" + ): Promise<{ data: { cid: string; name: string; path: [] }[] }> { const response = await this.api.get("/1/clouddrive/file/sort", { params: { pr: "ucpro", @@ -116,8 +135,8 @@ export class QuarkService { }); if (response.data?.data && response.data.data.list) { const data = response.data.data.list - .filter((item: any) => item.fid && item.file_type === 0) - .map((folder: any) => ({ + .filter((item: QuarkFolderItem) => item.fid && item.file_type === 0) + .map((folder: QuarkFolderItem) => ({ cid: folder.fid, name: folder.file_name, path: [], @@ -140,7 +159,7 @@ export class QuarkService { stoken: string; pdir_fid: string; scene: string; - }) { + }): Promise<{ message: string; data: unknown }> { try { const response = await this.api.post( `/1/clouddrive/share/sharepage/save?pr=ucpro&fr=pc&uc_param_str=&__dt=208097&__t=${Date.now()}`, diff --git a/backend/src/services/RSSSearcher.ts b/backend/src/services/RSSSearcher.ts deleted file mode 100644 index e9da9d3..0000000 --- a/backend/src/services/RSSSearcher.ts +++ /dev/null @@ -1,116 +0,0 @@ -import RSSParser from "rss-parser"; -import { AxiosInstance, AxiosHeaders } from "axios"; -import { config } from "../config"; -import { Logger } from "../utils/logger"; -import { createAxiosInstance } from "../utils/axiosInstance"; -import { data } from "cheerio/dist/commonjs/api/attributes"; - -interface RSSItem { - title?: string; - link?: string; - pubDate?: string; - content?: string; - description?: string; - image?: string; - cloudLinks?: string[]; -} - -export class RSSSearcher { - private parser: RSSParser; - private axiosInstance: AxiosInstance; - - constructor() { - this.parser = new RSSParser({ - customFields: { - item: [ - ["content:encoded", "content"], - ["description", "description"], - ], - }, - }); - - this.axiosInstance = createAxiosInstance( - config.rss.baseUrl, - AxiosHeaders.from({ - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", - Accept: "application/xml,application/xhtml+xml,text/html,application/rss+xml", - }), - true - ); - } - - private extractCloudLinks(text: string): { links: string[]; cloudType: string } { - const links: string[] = []; - let cloudType = ""; - Object.values(config.cloudPatterns).forEach((pattern, index) => { - const matches = text.match(pattern); - if (matches) { - links.push(...matches); - cloudType = Object.keys(config.cloudPatterns)[index]; - } - }); - return { - links: [...new Set(links)], - cloudType, - }; - } - - async searchAll(keyword: string) { - const allResults = []; - - for (let i = 0; i < config.rss.channels.length; i++) { - const channel = config.rss.channels[i]; - try { - const rssUrl = `${config.rss.baseUrl}/${ - channel.id - }${keyword ? `/searchQuery=${encodeURIComponent(keyword)}` : ""}`; - - const results = await this.searchInRSSFeed(rssUrl); - if (results.items.length > 0) { - const channelResults = results.items - .filter((item: RSSItem) => item.cloudLinks && item.cloudLinks.length > 0) - .map((item: RSSItem) => ({ - ...item, - channel: channel.name + "(" + channel.id + ")", - })); - - allResults.push(...channelResults); - } - } catch (error) { - Logger.error(`搜索频道 ${channel.name} 失败:`, error); - } - } - - return { - data: allResults, - message: "搜索成功", - }; - } - - async searchInRSSFeed(rssUrl: string) { - try { - const response = await this.axiosInstance.get(rssUrl); - const feed = await this.parser.parseString(response.data); - - return { - items: feed.items.map((item: RSSItem) => { - const linkInfo = this.extractCloudLinks(item.content || item.description || ""); - return { - title: item.title || "", - link: item.link || "", - pubDate: item.pubDate || "", - image: item.image || "", - cloudLinks: linkInfo.links, - cloudType: linkInfo.cloudType, - }; - }), - }; - } catch (error) { - Logger.error(`RSS源解析错误: ${rssUrl}`, error); - return { - items: [], - }; - } - } -} diff --git a/backend/src/services/Searcher.ts b/backend/src/services/Searcher.ts index 0fd7f9b..3286cd4 100644 --- a/backend/src/services/Searcher.ts +++ b/backend/src/services/Searcher.ts @@ -27,7 +27,7 @@ export class Searcher { this.initializeAxiosInstance(); } - private async initializeAxiosInstance(isUpdate = false) { + private async initializeAxiosInstance(isUpdate = false): Promise { let settings = null; if (isUpdate) { settings = await GlobalSetting.findOne(); @@ -78,7 +78,6 @@ export class Searcher { async searchAll(keyword: string, channelId?: string, messageId?: string) { const allResults = []; - const totalChannels = config.rss.channels.length; const channelList = channelId ? config.rss.channels.filter((channel) => channel.id === channelId) @@ -90,7 +89,7 @@ export class Searcher { const messageIdparams = messageId ? `before=${messageId}` : ""; const url = `/${channel.id}${keyword ? `?q=${encodeURIComponent(keyword)}&${messageIdparams}` : `?${messageIdparams}`}`; console.log(`Searching in channel ${channel.name} with URL: ${url}`); - const results = await this.searchInWeb(url, channel.id); + const results = await this.searchInWeb(url); console.log(`Found ${results.items.length} items in channel ${channel.name}`); if (results.items.length > 0) { const channelResults = results.items @@ -120,7 +119,7 @@ export class Searcher { }; } - async searchInWeb(url: string, channelId: string) { + async searchInWeb(url: string) { try { if (!this.axiosInstance) { throw new Error("Axios instance is not initialized"); diff --git a/backend/src/types/express.ts b/backend/src/types/express.ts index 7f7e104..6c55528 100644 --- a/backend/src/types/express.ts +++ b/backend/src/types/express.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars import { Request } from "express"; declare module "express" { diff --git a/backend/src/utils/axiosInstance.ts b/backend/src/utils/axiosInstance.ts index 04b2af4..3626a26 100644 --- a/backend/src/utils/axiosInstance.ts +++ b/backend/src/utils/axiosInstance.ts @@ -1,7 +1,5 @@ import axios, { AxiosInstance, AxiosRequestHeaders } from "axios"; import tunnel from "tunnel"; -import { config } from "../config"; -import GlobalSetting from "../models/GlobalSetting"; interface ProxyConfig { host: string; diff --git a/backend/src/utils/handleError.ts b/backend/src/utils/handleError.ts index d187ee2..2923ca5 100644 --- a/backend/src/utils/handleError.ts +++ b/backend/src/utils/handleError.ts @@ -1,8 +1,15 @@ import { Response, NextFunction } from "express"; import { Logger } from "../utils/logger"; + +interface CustomError { + name?: string; + message: string; + success?: boolean; +} + export default function handleError( res: Response, - error: any, + error: CustomError | unknown, message: string, next: NextFunction ) { diff --git a/frontend/auto-imports.d.ts b/frontend/auto-imports.d.ts index 78813d8..c1cd8b3 100644 --- a/frontend/auto-imports.d.ts +++ b/frontend/auto-imports.d.ts @@ -5,5 +5,5 @@ // Generated by unplugin-auto-import export {} declare global { - const ElMessage: typeof import('element-plus/es')['ElMessage'] + const ElMessage: (typeof import("element-plus/es"))["ElMessage"] } diff --git a/frontend/components.d.ts b/frontend/components.d.ts index c6f269f..e9b1961 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -13,8 +13,6 @@ declare module 'vue' { ElBacktop: typeof import('element-plus/es')['ElBacktop'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] - ElCheckbox: (typeof import("element-plus/es"))["ElCheckbox"] - ElCol: typeof import('element-plus/es')['ElCol'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElContainer: typeof import('element-plus/es')['ElContainer'] ElDialog: typeof import('element-plus/es')['ElDialog'] @@ -30,8 +28,6 @@ declare module 'vue' { ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] - ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] - ElRow: typeof import('element-plus/es')['ElRow'] ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] @@ -43,7 +39,6 @@ declare module 'vue' { ElTree: typeof import('element-plus/es')['ElTree'] FolderSelect: typeof import('./src/components/Home/FolderSelect.vue')['default'] ResourceCard: typeof import('./src/components/Home/ResourceCard.vue')['default'] - ResourceList: typeof import('./src/components/Home/ResourceList.vue')['default'] ResourceTable: typeof import('./src/components/Home/ResourceTable.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 8de459e..c343623 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -5,32 +5,32 @@ diff --git a/frontend/src/components/AsideMenu.vue b/frontend/src/components/AsideMenu.vue index 92534d7..cefe2dc 100644 --- a/frontend/src/components/AsideMenu.vue +++ b/frontend/src/components/AsideMenu.vue @@ -12,15 +12,15 @@ @close="handleClose" > diff --git a/frontend/src/components/Home/FolderSelect.vue b/frontend/src/components/Home/FolderSelect.vue index 339e4aa..6e205f9 100644 --- a/frontend/src/components/Home/FolderSelect.vue +++ b/frontend/src/components/Home/FolderSelect.vue @@ -11,8 +11,8 @@ node-key="cid" :load="loadNode" lazy - @node-click="handleNodeClick" highlight-current + @node-click="handleNodeClick" > diff --git a/frontend/src/components/Home/ResourceCard.vue b/frontend/src/components/Home/ResourceCard.vue index 9b4b4b8..d2d7c22 100644 --- a/frontend/src/components/Home/ResourceCard.vue +++ b/frontend/src/components/Home/ResourceCard.vue @@ -10,7 +10,7 @@ > -
+
{{ resource.title }}
-
+
标签: {{ item }} @@ -54,7 +54,7 @@
-
+
加载更多
@@ -62,128 +62,128 @@ diff --git a/frontend/src/components/Home/ResourceTable.vue b/frontend/src/components/Home/ResourceTable.vue index dee9c03..e8c218e 100644 --- a/frontend/src/components/Home/ResourceTable.vue +++ b/frontend/src/components/Home/ResourceTable.vue @@ -13,8 +13,8 @@ diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 2eef3ca..fb89ef4 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -1,5 +1,5 @@ diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index 5682529..7f21b7e 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -11,9 +11,9 @@ @@ -46,9 +46,9 @@ @@ -80,180 +80,181 @@ diff --git a/frontend/src/views/ResourceList.vue b/frontend/src/views/ResourceList.vue index b4ad348..f380370 100644 --- a/frontend/src/views/ResourceList.vue +++ b/frontend/src/views/ResourceList.vue @@ -11,8 +11,8 @@
@@ -20,19 +20,19 @@
- +