From 8c0b79066f8886674d33baeafef29dd504506c8c Mon Sep 17 00:00:00 2001 From: Sense T Date: Mon, 8 Apr 2024 09:37:32 +0800 Subject: [PATCH] base UI --- package-lock.json | 18 ++++ package.json | 5 + web/src/App.vue | 105 +++++------------- web/src/apis/api.ts | 118 ++++++++------------ web/src/assets/logo.svg | 1 - web/src/assets/main.css | 6 +- web/src/components/domains/DomainInfo.vue | 35 ++++++ web/src/components/domains/DomainOps.vue | 51 +++++++++ web/src/router/index.ts | 15 +-- web/src/stores/domains.ts | 2 +- web/src/views/AboutView.vue | 15 --- web/src/views/DomainsView.vue | 51 +++++++++ web/src/views/HomeView.vue | 9 +- web/src/views/RecordsView.vue | 126 ++++++++++++++++++++++ 14 files changed, 371 insertions(+), 186 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 web/src/assets/logo.svg create mode 100644 web/src/components/domains/DomainInfo.vue create mode 100644 web/src/components/domains/DomainOps.vue delete mode 100644 web/src/views/AboutView.vue create mode 100644 web/src/views/DomainsView.vue create mode 100644 web/src/views/RecordsView.vue diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5388e92 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "recored-ui", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@vicons/fa": "^0.12.0" + } + }, + "node_modules/@vicons/fa": { + "version": "0.12.0", + "resolved": "https://registry.npmmirror.com/@vicons/fa/-/fa-0.12.0.tgz", + "integrity": "sha512-g2PIeJLsTHUjt6bK63LxqC0uYQB7iu+xViJOxvp1s8b9/akpXVPVWjDTTsP980/0KYyMMe4U7F/aUo7wY+MsXA==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..930591e --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "@vicons/fa": "^0.12.0" + } +} diff --git a/web/src/App.vue b/web/src/App.vue index 7905b05..8eb6192 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -1,85 +1,30 @@ - - diff --git a/web/src/apis/api.ts b/web/src/apis/api.ts index c6fe2d7..069713f 100644 --- a/web/src/apis/api.ts +++ b/web/src/apis/api.ts @@ -1,5 +1,4 @@ import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from "axios"; -import { useLoadingBar, useNotification } from 'naive-ui' import { type Record } from '@/stores/records'; import { type Domain } from "@/stores/domains"; @@ -9,84 +8,57 @@ type Result = { data: T } +// 5 second. +const notificationDuration = 5000 +const messages = new Map( + // TODO: i18n + [ + [400, { + title: "请求错误 (400)", + content: "参数提交错误", + duration: notificationDuration + }], + [401, { + title: "未授权 (401)", + content: "请刷新页面重新登录", + duration: notificationDuration + }], + [403, { + title: "拒绝访问 (403)", + content: "你没有权限!", + duration: notificationDuration + }], + [404, { + title: "查无此项 (404)", + content: "没有该项内容", + duration: notificationDuration + }], + [500, { + title: "服务器错误 (500)", + content: "请检查系统日志", + duration: notificationDuration + }] + ] +) + +export function getErrorInfo(err: any) { + const msg = messages.get(err.response.status) + return msg? msg: { + title: "未知错误", + content: "请打开控制台了解详情", + duration: notificationDuration + } +} + export class Request { private instance: AxiosInstance; private baseConfig: AxiosRequestConfig = { baseURL: "api/v1" } - private loadingBar = useLoadingBar() - private notification = useNotification() - private messages = new Map( - // TODO: i18n - [ - [400, { - title: "请求错误 (400)", - content: "参数提交错误" - }], - [401, { - title: "未授权 (401)", - content: "请刷新页面重新登录" - }], - [403, { - title: "拒绝访问 (403)", - content: "你没有权限!" - }], - [404, { - title: "查无此项 (404)", - content: "没有该项内容" - }], - [500, { - title: "服务器错误 (500)", - content: "请检查系统日志" - }] - ] - ) + constructor(config: AxiosRequestConfig) { this.instance = axios.create(Object.assign(this.baseConfig, config)) - this.setupInceptors() - } - private setupInceptors() { - this.setupRequestInterceptors() - this.setupResponseInterceptors() - } - - private setupRequestInterceptors() { - const fulFilled = (res: InternalAxiosRequestConfig) => { - this.loadingBar.start() - return res - } - const onError = (err: any) => { - this.loadingBar.error() - return Promise.reject(err) - } - - this.instance.interceptors.request.use(fulFilled, onError) - } - - private setupResponseInterceptors() { - const fulFilled = (res: AxiosResponse) => { - this.loadingBar.finish() - return res - } - const onError = (err: any) => { - this.loadingBar.error() - - const msg = this.messages.get(err.response.status) - if (msg) { - this.notification.error(msg) - } else { - console.log(err.response) - this.notification.error({ - title: "未知错误", - content: "请打开控制台了解详情" - }) - } - - return Promise.reject(err.response) - } - - this.instance.interceptors.response.use(fulFilled, onError) } public request(config: AxiosRequestConfig): Promise { diff --git a/web/src/assets/logo.svg b/web/src/assets/logo.svg deleted file mode 100644 index 7565660..0000000 --- a/web/src/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/web/src/assets/main.css b/web/src/assets/main.css index 36fb845..c956d0b 100644 --- a/web/src/assets/main.css +++ b/web/src/assets/main.css @@ -28,8 +28,8 @@ a, } #app { - display: grid; - grid-template-columns: 1fr 1fr; - padding: 0 2rem; + display: flex; + grid-template-columns: 1fr; + padding: 2rem 2rem; } } diff --git a/web/src/components/domains/DomainInfo.vue b/web/src/components/domains/DomainInfo.vue new file mode 100644 index 0000000..5b68671 --- /dev/null +++ b/web/src/components/domains/DomainInfo.vue @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/web/src/components/domains/DomainOps.vue b/web/src/components/domains/DomainOps.vue new file mode 100644 index 0000000..9c33d40 --- /dev/null +++ b/web/src/components/domains/DomainOps.vue @@ -0,0 +1,51 @@ + + + \ No newline at end of file diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 9221fd9..bbab616 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -10,12 +10,15 @@ const router = createRouter({ component: HomeView }, { - path: '/about', - name: 'about', - // route level code-splitting - // this generates a separate chunk (About.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import('../views/AboutView.vue') + path: '/domains', + name: 'domains', + component: () => import('../views/DomainsView.vue') + }, + { + path: '/records/:domain', + name: 'records', + component: () => import('../views/RecordsView.vue'), + props: true } ] }) diff --git a/web/src/stores/domains.ts b/web/src/stores/domains.ts index cf0a4aa..37e92e7 100644 --- a/web/src/stores/domains.ts +++ b/web/src/stores/domains.ts @@ -36,7 +36,7 @@ const domainDevData: Domain[] = [ retry_interval: 7200, expiry_period: 3600000, negative_ttl: 86400 - } + }, ] export const useDomainStore = defineStore('domains', () => { diff --git a/web/src/views/AboutView.vue b/web/src/views/AboutView.vue deleted file mode 100644 index 756ad2a..0000000 --- a/web/src/views/AboutView.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/web/src/views/DomainsView.vue b/web/src/views/DomainsView.vue new file mode 100644 index 0000000..527806e --- /dev/null +++ b/web/src/views/DomainsView.vue @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/HomeView.vue b/web/src/views/HomeView.vue index d5c0217..0b4b0f9 100644 --- a/web/src/views/HomeView.vue +++ b/web/src/views/HomeView.vue @@ -1,9 +1,4 @@ - - diff --git a/web/src/views/RecordsView.vue b/web/src/views/RecordsView.vue new file mode 100644 index 0000000..ec6fbb9 --- /dev/null +++ b/web/src/views/RecordsView.vue @@ -0,0 +1,126 @@ + + + + + \ No newline at end of file