diff --git a/components/comment-section/index.vue b/components/comment-section/index.vue new file mode 100644 index 0000000..a2b8ba5 --- /dev/null +++ b/components/comment-section/index.vue @@ -0,0 +1,92 @@ + + + diff --git a/components/kl-card-detail/index.vue b/components/kl-card-detail/index.vue new file mode 100644 index 0000000..40ec798 --- /dev/null +++ b/components/kl-card-detail/index.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/components/kl-card-picture/index.vue b/components/kl-card-picture/index.vue new file mode 100644 index 0000000..0a0c8ab --- /dev/null +++ b/components/kl-card-picture/index.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/components/kl-email/index.ts b/components/kl-email/index.ts new file mode 100644 index 0000000..0699c6b --- /dev/null +++ b/components/kl-email/index.ts @@ -0,0 +1,29 @@ +import { createApp, ref } from 'vue' +import GlobalPopup from './index.vue' + +const popupInstance = ref() + +const openLoginEmail = () => { + if (!popupInstance.value) { + const app = createApp(GlobalPopup, { + visible: true, + onClose: () => { + closeLoginEmail() + }, + }) + + const container = document.createElement('div') + document.body.appendChild(container) + popupInstance.value = app.mount(container) + } + // popupInstance.value.$el.innerHTML = content +} + +const closeLoginEmail = () => { + if (popupInstance.value) { + popupInstance.value.$el.parentNode.removeChild(popupInstance.value.$el) + popupInstance.value = null + } +} + +export { openLoginEmail, closeLoginEmail } diff --git a/components/kl-email/index.vue b/components/kl-email/index.vue new file mode 100644 index 0000000..b40540f --- /dev/null +++ b/components/kl-email/index.vue @@ -0,0 +1,456 @@ + + + + + + + diff --git a/components/kl-form-title/index.vue b/components/kl-form-title/index.vue new file mode 100644 index 0000000..3df7567 --- /dev/null +++ b/components/kl-form-title/index.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/components/kl-login/index.ts b/components/kl-login/index.ts new file mode 100644 index 0000000..e298cc7 --- /dev/null +++ b/components/kl-login/index.ts @@ -0,0 +1,33 @@ +import { createApp, ref } from 'vue' +import GlobalPopup from './index.vue' + +const popupInstance = ref() + +const openLogin = (active = 'account', code = '', type = '', state = '') => { + if (!popupInstance.value) { + const app = createApp(GlobalPopup, { + visible: true, + active: active, + code: code, + type: type, + state: state, + onClose: () => { + closeLogin() + }, + }) + + const container = document.createElement('div') + document.body.appendChild(container) + popupInstance.value = app.mount(container) + } + // popupInstance.value.$el.innerHTML = content +} + +const closeLogin = () => { + if (popupInstance.value) { + popupInstance.value.$el.parentNode.removeChild(popupInstance.value.$el) + popupInstance.value = null + } +} + +export { openLogin, closeLogin } diff --git a/components/kl-login/index.vue b/components/kl-login/index.vue new file mode 100644 index 0000000..ef2e2ed --- /dev/null +++ b/components/kl-login/index.vue @@ -0,0 +1,471 @@ + + + + + + + diff --git a/components/kl-nav-tab/index.vue b/components/kl-nav-tab/index.vue new file mode 100644 index 0000000..c983843 --- /dev/null +++ b/components/kl-nav-tab/index.vue @@ -0,0 +1,264 @@ + + + + diff --git a/components/kl-query-filter/index.vue b/components/kl-query-filter/index.vue new file mode 100644 index 0000000..14c7c50 --- /dev/null +++ b/components/kl-query-filter/index.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/components/kl-quick-menu/components/kl-service.vue b/components/kl-quick-menu/components/kl-service.vue new file mode 100644 index 0000000..588973f --- /dev/null +++ b/components/kl-quick-menu/components/kl-service.vue @@ -0,0 +1,731 @@ + + + + + + diff --git a/components/kl-quick-menu/components/kl-vip.vue b/components/kl-quick-menu/components/kl-vip.vue new file mode 100644 index 0000000..4f7b3bc --- /dev/null +++ b/components/kl-quick-menu/components/kl-vip.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/components/kl-quick-menu/index.vue b/components/kl-quick-menu/index.vue new file mode 100644 index 0000000..e31a8b0 --- /dev/null +++ b/components/kl-quick-menu/index.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/components/kl-register/index.ts b/components/kl-register/index.ts new file mode 100644 index 0000000..ff23dc6 --- /dev/null +++ b/components/kl-register/index.ts @@ -0,0 +1,29 @@ +import { createApp, ref } from 'vue' +import GlobalPopup from './index.vue' + +const popupInstance = ref() + +const openRegister = () => { + if (!popupInstance.value) { + const app = createApp(GlobalPopup, { + visible: true, + onClose: () => { + closeRegister() + }, + }) + + const container = document.createElement('div') + document.body.appendChild(container) + popupInstance.value = app.mount(container) + } + // popupInstance.value.$el.innerHTML = content +} + +const closeRegister = () => { + if (popupInstance.value) { + popupInstance.value.$el.parentNode.removeChild(popupInstance.value.$el) + popupInstance.value = null + } +} + +export { openRegister, closeRegister } diff --git a/components/kl-register/index.vue b/components/kl-register/index.vue new file mode 100644 index 0000000..9ea553c --- /dev/null +++ b/components/kl-register/index.vue @@ -0,0 +1,333 @@ + + + + + + + diff --git a/components/kl-svg-icon/index.vue b/components/kl-svg-icon/index.vue new file mode 100644 index 0000000..0c4b680 --- /dev/null +++ b/components/kl-svg-icon/index.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/components/kl-tab-bar/index.vue b/components/kl-tab-bar/index.vue new file mode 100644 index 0000000..0929a83 --- /dev/null +++ b/components/kl-tab-bar/index.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/components/kl-tab-bar/v2/index.vue b/components/kl-tab-bar/v2/index.vue new file mode 100644 index 0000000..656882b --- /dev/null +++ b/components/kl-tab-bar/v2/index.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/kl-tag/index.vue b/components/kl-tag/index.vue new file mode 100644 index 0000000..9798f25 --- /dev/null +++ b/components/kl-tag/index.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/components/kl-uploader/index.vue b/components/kl-uploader/index.vue new file mode 100644 index 0000000..0a5946d --- /dev/null +++ b/components/kl-uploader/index.vue @@ -0,0 +1,418 @@ + + + + + diff --git a/components/kl-wallpaper-category/index.vue b/components/kl-wallpaper-category/index.vue new file mode 100644 index 0000000..fd20b59 --- /dev/null +++ b/components/kl-wallpaper-category/index.vue @@ -0,0 +1,145 @@ + + diff --git a/composables/useDollarFetchRequest.ts b/composables/useDollarFetchRequest.ts new file mode 100644 index 0000000..1d8855e --- /dev/null +++ b/composables/useDollarFetchRequest.ts @@ -0,0 +1,37 @@ +import { isArray } from "~/utils/utils"; + +type FetchType = typeof $fetch; +export type FetchOptions = Parameters[1]; + +export const useClientRequest = ( + url: string, + opts?: FetchOptions +) => { + const token = useCookie("token"); + const runtimeConfig = useRuntimeConfig(); + + const defaultOptions: FetchOptions = { + baseURL: runtimeConfig.public.apiBase, + onRequest({ options }) { + options.headers = options.headers || 'application/json'; + if (token.value) { + // @ts-ignore + options.headers["authorization"] = "Bearer " + token.value; + } + }, + onResponse({ response }) { + if (+response.status === 200 && +response._data.code !== 200) { + ElMessage.error(response._data.msg); + } + }, + onResponseError({ response }) { + ElMessage.error( + isArray(response._data.data.msg) + ? response._data.data.msg[0] + : response._data.data.msg + ); + }, + }; + + return $fetch(url, { ...defaultOptions, ...opts }); +}; diff --git a/composables/useFetchRequest.ts b/composables/useFetchRequest.ts new file mode 100644 index 0000000..04bdff4 --- /dev/null +++ b/composables/useFetchRequest.ts @@ -0,0 +1,37 @@ +import { useFetch } from "#app"; +import type { UseFetchOptions } from "#app"; +import { isArray } from "~/utils/utils"; + +export const useServerRequest = ( + url: string, + opts?: UseFetchOptions +) => { + const token = useCookie("token"); + const runtimeConfig = useRuntimeConfig(); + + const defaultOptions: UseFetchOptions = { + baseURL: runtimeConfig.public.apiBase, + onRequest({ options }) { + options.headers = options.headers || "application/json"; + if (token.value) { + // @ts-ignore + options.headers["authorization"] = "Bearer " + token.value; + } + }, + onResponse({ response }) { + if (+response.status === 200 && +response._data.code !== 200) { + process.client && ElMessage.error(response._data.msg); + } + }, + onResponseError({ response }) { + process.client && + ElMessage.error( + isArray(response._data.data.msg) + ? response._data.data.msg[0] + : response._data.data.msg + ); + }, + }; + + return useFetch(url, { ...defaultOptions, ...opts } as any); +}; diff --git a/layout/default.vue b/layout/default.vue new file mode 100644 index 0000000..ba22ba4 --- /dev/null +++ b/layout/default.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/layout/kl-footer/index.vue b/layout/kl-footer/index.vue new file mode 100644 index 0000000..d04eb15 --- /dev/null +++ b/layout/kl-footer/index.vue @@ -0,0 +1,139 @@ + + + + diff --git a/layout/kl-menus-v2/index.vue b/layout/kl-menus-v2/index.vue new file mode 100644 index 0000000..10fc9c5 --- /dev/null +++ b/layout/kl-menus-v2/index.vue @@ -0,0 +1,105 @@ + + + diff --git a/layout/kl-menus/index.vue b/layout/kl-menus/index.vue new file mode 100644 index 0000000..6fa5ac6 --- /dev/null +++ b/layout/kl-menus/index.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/layout/kl-menus/kl-menu-item.vue b/layout/kl-menus/kl-menu-item.vue new file mode 100644 index 0000000..df9f2d9 --- /dev/null +++ b/layout/kl-menus/kl-menu-item.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/layout/kl-search/index.vue b/layout/kl-search/index.vue new file mode 100644 index 0000000..5fbc394 --- /dev/null +++ b/layout/kl-search/index.vue @@ -0,0 +1,153 @@ + + + diff --git a/nuxt.config.ts b/nuxt.config.ts index b8bc492..1744899 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,18 +1,17 @@ +// import { base_api } from '~/constants/index' // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ devServer: { - port: 8888, - host: '0.0.0.0' + port: 6188, }, - devtools: { - enabled: process.env.NODE_ENV === 'development' + devtools: { + enabled: process.env.NODE_ENV === "development", }, - ssr: true, - modules: ['@unocss/nuxt', '@pinia/nuxt','@element-plus/nuxt'], - css: ['@unocss/reset/tailwind.css', 'element-plus/dist/index.css'], + modules: ["@unocss/nuxt", "@pinia/nuxt", "@element-plus/nuxt"], + css: ["@unocss/reset/tailwind.css", "element-plus/dist/index.css"], vite: { css: { preprocessorOptions: { @@ -32,111 +31,89 @@ export default defineNuxtConfig({ }, }, optimizeDeps: { - include: ['naive-ui'] + include: ["naive-ui"], }, // 生产环境构建优化 build: { // 生产环境移除 console 和 debugger - minify: 'esbuild', - target: 'es2020' + minify: "esbuild", + target: "es2020", }, esbuild: { // 生产环境下移除所有 console 语句和 debugger - drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [] - } + drop: + process.env.NODE_ENV === "production" ? ["console", "debugger"] : [], + }, }, // 页面过渡配置 app: { - pageTransition: { - name: 'page', - mode: 'out-in', - duration: 400 + pageTransition: { + name: "page", + mode: "out-in", + duration: 400, }, - layoutTransition: { - name: 'layout', - mode: 'out-in', - duration: 400 + layoutTransition: { + name: "layout", + mode: "out-in", + duration: 400, }, head: { - title: 'xlCig - 专业PC硬件产品和装机服务', + title: "xlCig - 专业PC硬件产品和装机服务", htmlAttrs: { - lang: 'en', + lang: "en", }, meta: [ - { charset: 'utf-8' }, - { name: 'viewport', content: 'width=device-width, initial-scale=1' }, - { name: 'description', content: '专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑' }, - { name: 'keywords', content: 'xlCig,PC硬件,电脑配置,显卡,CPU,装机' }, - { name: 'author', content: 'xlCig' }, + { charset: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + { + name: "description", + content: "专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑", + }, + { name: "keywords", content: "xlCig,PC硬件,电脑配置,显卡,CPU,装机" }, + { name: "author", content: "xlCig" }, // 百度站点验证 - { name: 'baidu-site-verification', content: 'codeva-2z90c1PlRw' }, + { name: "baidu-site-verification", content: "codeva-2z90c1PlRw" }, // SEO meta tags - { property: 'og:title', content: 'xlCig - 专业PC硬件产品和装机服务' }, - { property: 'og:description', content: '专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑' }, - { property: 'og:type', content: 'website' }, - { property: 'og:url', content: 'https://www.xlcig.cn' }, - { property: 'og:site_name', content: 'xlCig' }, - { name: 'theme-color', content: '#00f5ff' }, + { property: "og:title", content: "xlCig - 专业PC硬件产品和装机服务" }, + { + property: "og:description", + content: "专业的PC硬件产品和装机建议,助您打造梦想中的高性能电脑", + }, + { property: "og:type", content: "website" }, + { property: "og:url", content: "https://www.xlcig.cn" }, + { property: "og:site_name", content: "xlCig" }, + { name: "theme-color", content: "#00f5ff" }, // robots meta - { name: 'robots', content: 'index, follow' } + { name: "robots", content: "index, follow" }, ], link: [ - { rel: 'icon', type: 'image/png', href: '/logo.png' }, - { rel: 'apple-touch-icon', sizes: '180x180', href: '/logo.png' }, - { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/logo.png' }, - { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/logo.png' } - ] - } + { rel: "icon", type: "image/png", href: "/logo.png" }, + { rel: "apple-touch-icon", sizes: "180x180", href: "/logo.png" }, + { rel: "icon", type: "image/png", sizes: "32x32", href: "/logo.png" }, + { rel: "icon", type: "image/png", sizes: "16x16", href: "/logo.png" }, + ], + }, }, - + runtimeConfig: { public: { // API 基础地址 - apiBase: process.env.NUXT_PUBLIC_API_BASE || ( - process.env.NODE_ENV === 'production' - ? 'https://api.xlcig.cn' // 生产环境 - : 'http://192.168.11.194:9999' // 开发环境 - ), - - // WebSocket 地址 - wsUrl: process.env.NUXT_PUBLIC_WS_URL || ( - process.env.NODE_ENV === 'production' - ? 'wss://api.xlcig.cn/websocket' // 生产环境使用wss - : 'ws://192.168.11.194:9999/websocket' // 开发环境使用ws - ), - + apiBase: 'https://tuxixi.net', + // 应用信息 - appName: process.env.NUXT_PUBLIC_APP_NAME || 'xlCig', - appVersion: process.env.NUXT_PUBLIC_APP_VERSION || '1.0.0', - + appName: "xlCig", + appVersion: "1.0.0", + // 调试模式 - debug: process.env.NUXT_PUBLIC_DEBUG === 'true' || process.env.NODE_ENV === 'development', - + debug: process.env.NODE_ENV === "development", + // 环境标识 - environment: process.env.NODE_ENV || 'development' - } + environment: process.env.NODE_ENV || "development", + }, }, - + build: { - transpile: ['naive-ui', 'vueuc', '@css-render/vue3-ssr'] + transpile: ["vueuc", "@css-render/vue3-ssr"], }, - - // 优化SSR性能和开发代理 - nitro: { - compressPublicAssets: true, - // 开发环境代理配置 - devProxy: { - '/api': { - target: 'http://192.168.11.194:9999/api', - changeOrigin: true, - prependPath: true, - }, - '/websocket': { - target: 'ws://192.168.11.194:9999', - ws: true, - changeOrigin: true, - } - } - } -}) \ No newline at end of file +}); diff --git a/pages/home/index.vue b/pages/home/index.vue index 3b6a25d..a22711d 100644 --- a/pages/home/index.vue +++ b/pages/home/index.vue @@ -21,8 +21,8 @@