diff --git a/napcat.webui/package.json b/napcat.webui/package.json index f6b8c6e7..11ccaca9 100644 --- a/napcat.webui/package.json +++ b/napcat.webui/package.json @@ -5,12 +5,13 @@ "type": "module", "scripts": { "webui:lint": "eslint --fix src/**/*.{js,ts,vue}", - "webui:dev": "vite", + "webui:dev": "vite --host", "webui:build": "vite build", "webui:preview": "vite preview" }, "dependencies": { "eslint-plugin-prettier": "^5.2.1", + "event-source-polyfill": "^1.0.31", "qrcode": "^1.5.4", "tdesign-icons-vue-next": "^0.3.3", "tdesign-vue-next": "^1.10.3", @@ -20,6 +21,7 @@ "devDependencies": { "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.14.0", + "@types/event-source-polyfill": "^1.0.5", "@types/qrcode": "^1.5.5", "@vitejs/plugin-legacy": "^5.4.3", "@vitejs/plugin-vue": "^5.1.4", diff --git a/napcat.webui/src/App.vue b/napcat.webui/src/App.vue index d26b9165..431f07c5 100644 --- a/napcat.webui/src/App.vue +++ b/napcat.webui/src/App.vue @@ -109,4 +109,4 @@ onUnmounted(() => { window.removeEventListener('resize', haddingFbars); }); - + diff --git a/napcat.webui/src/assets/0xProtoNerdFont-Italic.ttf b/napcat.webui/src/assets/0xProtoNerdFont-Italic.ttf new file mode 100644 index 00000000..6c0529fb Binary files /dev/null and b/napcat.webui/src/assets/0xProtoNerdFont-Italic.ttf differ diff --git a/napcat.webui/src/backend/githubApi.ts b/napcat.webui/src/backend/githubApi.ts new file mode 100644 index 00000000..3ce4d4e1 --- /dev/null +++ b/napcat.webui/src/backend/githubApi.ts @@ -0,0 +1,66 @@ +export class githubApiManager { + public async GetBaseData(): Promise { + try { + const ConfigResponse= await fetch('https://api.github.com/repos/NapNeko/NapCatQQ', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + return await ConfigResponse.json(); + } + } catch (error) { + console.error('Error getting github data :', error); + } + return null; + } + public async GetReleasesData(): Promise { + try { + const ConfigResponse = await fetch('https://api.github.com/repos/NapNeko/NapCatQQ/releases', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + return await ConfigResponse.json(); + } + } catch (error) { + console.error('Error getting releases data:', error); + } + return null; + } + public async GetPullsData(): Promise { + try { + const ConfigResponse = await fetch('https://api.github.com/repos/NapNeko/NapCatQQ/pulls', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + return await ConfigResponse.json(); + } + } catch (error) { + console.error('Error getting Pulls data:', error); + } + return null; + } + public async GetContributors(): Promise { + try { + const ConfigResponse = await fetch('https://api.github.com/repos/NapNeko/NapCatQQ/contributors', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + return await ConfigResponse.json(); + } + } catch (error) { + console.error('Error getting Pulls data:', error); + } + return null; + } +} diff --git a/napcat.webui/src/backend/log.ts b/napcat.webui/src/backend/log.ts new file mode 100644 index 00000000..32fdaac2 --- /dev/null +++ b/napcat.webui/src/backend/log.ts @@ -0,0 +1,72 @@ +import { EventSourcePolyfill } from 'event-source-polyfill'; +type LogListItem = string; +type LogListData = LogListItem[]; +let eventSourcePoly: EventSourcePolyfill | null = null; +export class LogManager { + private readonly retCredential: string; + private readonly apiPrefix: string; + + //调试时http://127.0.0.1:6099/api 打包时 ../api + constructor(retCredential: string, apiPrefix: string = '../api') { + this.retCredential = retCredential; + this.apiPrefix = apiPrefix; + } + public async GetLogList(): Promise { + try { + const ConfigResponse = await fetch(`${this.apiPrefix}/Log/GetLogList`, { + method: 'GET', + headers: { + Authorization: 'Bearer ' + this.retCredential, + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + const ConfigResponseJson = await ConfigResponse.json(); + if (ConfigResponseJson.code == 0) { + return ConfigResponseJson?.data as LogListData; + } + } + } catch (error) { + console.error('Error getting LogList:', error); + } + return [] as LogListData; + } + public async GetLog(FileName: string): Promise { + try { + const ConfigResponse = await fetch(`${this.apiPrefix}/Log/GetLog?id=${FileName}`, { + method: 'GET', + headers: { + Authorization: 'Bearer ' + this.retCredential, + 'Content-Type': 'application/json', + }, + }); + if (ConfigResponse.status == 200) { + const ConfigResponseJson = await ConfigResponse.json(); + if (ConfigResponseJson.code == 0) { + return ConfigResponseJson?.data; + } + } + } catch (error) { + console.error('Error getting LogData:', error); + } + return 'null'; + } + public async getRealTimeLogs(): Promise { + this.creatEventSource(); + return eventSourcePoly; + } + private creatEventSource() { + try { + eventSourcePoly = new EventSourcePolyfill(`${this.apiPrefix}/Log/GetLogRealTime`, { + heartbeatTimeout: 3 * 60 * 1000, + headers: { + Authorization: 'Bearer ' + this.retCredential, + Accept: 'text/event-stream', + }, + withCredentials: true, + }); + } catch (error) { + console.error('创建SSE连接出错:', error); + } + } +} diff --git a/napcat.webui/src/components/Dashboard.vue b/napcat.webui/src/components/Dashboard.vue index 8bd8a031..b46315e5 100644 --- a/napcat.webui/src/components/Dashboard.vue +++ b/napcat.webui/src/components/Dashboard.vue @@ -1,18 +1,28 @@ @@ -49,6 +64,12 @@ onMounted(() => { position: relative; z-index: 2; } +.bottom-menu { + position: fixed; + bottom: 0; + width: 100%; + z-index: 2; +} @media (max-width: 768px) { .content { @@ -56,3 +77,19 @@ onMounted(() => { } } + diff --git a/napcat.webui/src/components/QQLogin.vue b/napcat.webui/src/components/QQLogin.vue index a5e27c72..ee20d9a5 100644 --- a/napcat.webui/src/components/QQLogin.vue +++ b/napcat.webui/src/components/QQLogin.vue @@ -1,5 +1,5 @@