正在显示
20 个修改的文件
包含
281 行增加
和
122 行删除
api/app.ts
0 → 100644
| 1 | +import { useGet } from "~/utils/request"; | ||
| 2 | +import type { queryParams } from "./types/app"; | ||
| 3 | +// 获取应用列表 | ||
| 4 | +export const getAppList = (params: queryParams) => { | ||
| 5 | + return useGet('/dh/app/listFrontApp', params) | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +// 获取已分类的所有应用 | ||
| 9 | +export const getAllApp = () => { | ||
| 10 | + return useGet('/dh/app/allFrontApp') | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +// 获取应用详情 | ||
| 14 | +export const getAppDetail = (appId: number) => { | ||
| 15 | + return useGet(`/dh/app/${appId}`) | ||
| 16 | +} |
api/classify.ts
0 → 100644
api/types/app.ts
0 → 100644
| 1 | +// 单个应用类型 | ||
| 2 | +export interface appType { | ||
| 3 | + id: number, | ||
| 4 | + title: string, | ||
| 5 | + popupContent: string, | ||
| 6 | + image: string, | ||
| 7 | + description: string, | ||
| 8 | + type: number, | ||
| 9 | + isPopup: string, | ||
| 10 | + isRecommend: string, | ||
| 11 | + typeIds: number | number[] | ||
| 12 | + types: Types[] | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +// 单个应用详情 | ||
| 16 | +export interface appDetail { | ||
| 17 | + id: number | ||
| 18 | + title: string | ||
| 19 | + content: string | ||
| 20 | + popupContent?: string | ||
| 21 | + image: string | ||
| 22 | + description: string | ||
| 23 | + type?: number | ||
| 24 | + isPopup?: string | ||
| 25 | + link: string | ||
| 26 | + isRecommend?: string | ||
| 27 | + types: Types[] | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +export interface Types{ | ||
| 31 | + id: number, | ||
| 32 | + label: string, | ||
| 33 | + icon?: string, | ||
| 34 | + alias?: string, | ||
| 35 | + disabled?: boolean, | ||
| 36 | + children: Array<Types> | ||
| 37 | +} | ||
| 38 | +// 查询应用参数类型 | ||
| 39 | +export interface queryParams { | ||
| 40 | + pageNum: number | ||
| 41 | + pageSize: number | ||
| 42 | + typeIds?: number | number[] | ||
| 43 | + typeAlias?: string | ||
| 44 | + title?: string | ||
| 45 | + isPopup?: string | ||
| 46 | + isRecommend?: string | ||
| 47 | +} | ||
| 48 | +// 返回所有应用 | ||
| 49 | +export interface appListType { | ||
| 50 | + alias: string | ||
| 51 | + appVos: appType[] | ||
| 52 | + disabled: boolean | ||
| 53 | + icon: string | ||
| 54 | + id: number | ||
| 55 | + label: string | ||
| 56 | + sort: number | ||
| 57 | + children: Array<appListType> | ||
| 58 | +} |
api/types/classify.ts
0 → 100644
api/types/webSite.ts
0 → 100644
api/webSite.ts
0 → 100644
| @@ -4,18 +4,16 @@ | @@ -4,18 +4,16 @@ | ||
| 4 | </NuxtLayout> | 4 | </NuxtLayout> |
| 5 | </template> | 5 | </template> |
| 6 | 6 | ||
| 7 | -<script setup> | ||
| 8 | -const webSite = useState("webSite", () => {}); | ||
| 9 | -const sortList = useState("sortTree", () => []); | ||
| 10 | -const { data: webData } = await useFetch( | ||
| 11 | - "http://aitoolht.crgx.net/dh/config/get" | ||
| 12 | -); | ||
| 13 | -const { data: treeData } = await useFetch( | ||
| 14 | - "http://aitoolht.crgx.net/dh/type/typeTree" | ||
| 15 | -); | ||
| 16 | -webSite.value = webData.value.data; | ||
| 17 | -sortList.value = treeData.value.data; | 7 | +<script lang="ts" setup> |
| 8 | +import { getWebSite } from "~/api/webSite"; | ||
| 9 | +import { getClassifyList } from "~/api/classify"; | ||
| 10 | +import type { webSiteType } from "~/api/types/webSite"; | ||
| 11 | +import type { classifyType } from "~/api/types/classify"; | ||
| 12 | +const webSite = useState<webSiteType>("webSite"); | ||
| 13 | +const sortList = useState<classifyType>("sortTree"); | ||
| 18 | 14 | ||
| 15 | +webSite.value = await getWebSite(); | ||
| 16 | +sortList.value = await getClassifyList(); | ||
| 19 | useHead({ | 17 | useHead({ |
| 20 | title: webSite.value.webname, | 18 | title: webSite.value.webname, |
| 21 | meta: [ | 19 | meta: [ |
| @@ -92,7 +92,7 @@ | @@ -92,7 +92,7 @@ | ||
| 92 | <div class="group p-3"> | 92 | <div class="group p-3"> |
| 93 | <div class="flex items-start space-x-4"> | 93 | <div class="flex items-start space-x-4"> |
| 94 | <img | 94 | <img |
| 95 | - :src="'http://aitoolht.crgx.net' + appItem.image" | 95 | + :src="config.public.baseUrl + appItem.image" |
| 96 | :alt="appItem.title" | 96 | :alt="appItem.title" |
| 97 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 97 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 98 | /> | 98 | /> |
| @@ -117,7 +117,7 @@ | @@ -117,7 +117,7 @@ | ||
| 117 | <div class="group p-3"> | 117 | <div class="group p-3"> |
| 118 | <div class="flex items-start space-x-4"> | 118 | <div class="flex items-start space-x-4"> |
| 119 | <img | 119 | <img |
| 120 | - :src="'http://aitoolht.crgx.net' + appItem.image" | 120 | + :src="config.public.baseUrl + appItem.image" |
| 121 | :alt="appItem.title" | 121 | :alt="appItem.title" |
| 122 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 122 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 123 | /> | 123 | /> |
| @@ -148,6 +148,7 @@ const props = defineProps<{ | @@ -148,6 +148,7 @@ const props = defineProps<{ | ||
| 148 | }>(); | 148 | }>(); |
| 149 | 149 | ||
| 150 | const childAlias = ref(props.childData.children[0].alias); | 150 | const childAlias = ref(props.childData.children[0].alias); |
| 151 | +const config = useRuntimeConfig(); | ||
| 151 | // 阻止默认行为 | 152 | // 阻止默认行为 |
| 152 | function onNuxtLink(event: any) { | 153 | function onNuxtLink(event: any) { |
| 153 | event.preventDefault(); | 154 | event.preventDefault(); |
| @@ -53,7 +53,7 @@ | @@ -53,7 +53,7 @@ | ||
| 53 | <div class="group p-3"> | 53 | <div class="group p-3"> |
| 54 | <div class="flex items-start space-x-4"> | 54 | <div class="flex items-start space-x-4"> |
| 55 | <img | 55 | <img |
| 56 | - :src="'http://aitoolht.crgx.net' + item.image" | 56 | + :src="config.public.baseUrl + item.image" |
| 57 | :alt="item.title" | 57 | :alt="item.title" |
| 58 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 58 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 59 | /> | 59 | /> |
| @@ -78,7 +78,7 @@ | @@ -78,7 +78,7 @@ | ||
| 78 | <div class="group p-3"> | 78 | <div class="group p-3"> |
| 79 | <div class="flex items-start space-x-4"> | 79 | <div class="flex items-start space-x-4"> |
| 80 | <img | 80 | <img |
| 81 | - :src="'http://aitoolht.crgx.net' + item.image" | 81 | + :src="config.public.baseUrl + item.image" |
| 82 | :alt="item.title" | 82 | :alt="item.title" |
| 83 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 83 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 84 | /> | 84 | /> |
| @@ -106,7 +106,7 @@ import { Promotion } from "@element-plus/icons-vue"; | @@ -106,7 +106,7 @@ import { Promotion } from "@element-plus/icons-vue"; | ||
| 106 | defineProps<{ | 106 | defineProps<{ |
| 107 | childData: any; | 107 | childData: any; |
| 108 | }>(); | 108 | }>(); |
| 109 | - | 109 | +const config = useRuntimeConfig(); |
| 110 | // 阻止默认行为 | 110 | // 阻止默认行为 |
| 111 | function onNuxtLink(event: any) { | 111 | function onNuxtLink(event: any) { |
| 112 | event.preventDefault(); | 112 | event.preventDefault(); |
| @@ -59,7 +59,7 @@ | @@ -59,7 +59,7 @@ | ||
| 59 | <div class="group p-3"> | 59 | <div class="group p-3"> |
| 60 | <div class="flex items-start space-x-4"> | 60 | <div class="flex items-start space-x-4"> |
| 61 | <img | 61 | <img |
| 62 | - :src="'http://aitoolht.crgx.net' + item.image" | 62 | + :src="config.public.baseUrl + item.image" |
| 63 | :alt="item.title" | 63 | :alt="item.title" |
| 64 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 64 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 65 | /> | 65 | /> |
| @@ -84,7 +84,7 @@ | @@ -84,7 +84,7 @@ | ||
| 84 | <div class="group p-3"> | 84 | <div class="group p-3"> |
| 85 | <div class="flex items-start space-x-4"> | 85 | <div class="flex items-start space-x-4"> |
| 86 | <img | 86 | <img |
| 87 | - :src="'http://aitoolht.crgx.net' + item.image" | 87 | + :src="config.public.baseUrl + item.image" |
| 88 | :alt="item.title" | 88 | :alt="item.title" |
| 89 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" | 89 | class="w-10 h-10 md:w-14 md:h-14 object-cover rounded-lg" |
| 90 | /> | 90 | /> |
| @@ -115,7 +115,7 @@ defineProps<{ | @@ -115,7 +115,7 @@ defineProps<{ | ||
| 115 | navTitle: string; | 115 | navTitle: string; |
| 116 | navIcon: string; | 116 | navIcon: string; |
| 117 | }>(); | 117 | }>(); |
| 118 | - | 118 | +const config = useRuntimeConfig(); |
| 119 | // 阻止默认行为 | 119 | // 阻止默认行为 |
| 120 | function onNuxtLink(event: any) { | 120 | function onNuxtLink(event: any) { |
| 121 | event.preventDefault(); | 121 | event.preventDefault(); |
ecosystem.config.cjs
0 → 100644
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | export default defineNuxtConfig({ | 2 | export default defineNuxtConfig({ |
| 3 | runtimeConfig: { | 3 | runtimeConfig: { |
| 4 | public: { | 4 | public: { |
| 5 | - baseUrl: 'http://aitoolht.crgx.net', | 5 | + baseUrl: process.env.NUXT_API_URL, |
| 6 | } | 6 | } |
| 7 | }, | 7 | }, |
| 8 | devtools: { enabled: true }, | 8 | devtools: { enabled: true }, |
| @@ -14,6 +14,21 @@ export default defineNuxtConfig({ | @@ -14,6 +14,21 @@ export default defineNuxtConfig({ | ||
| 14 | host: 'localhost', | 14 | host: 'localhost', |
| 15 | port: 3666 | 15 | port: 3666 |
| 16 | }, | 16 | }, |
| 17 | + nitro: { | ||
| 18 | + devProxy: { | ||
| 19 | + '/dev-api': { | ||
| 20 | + target: 'http://192.168.2.188:35273/', | ||
| 21 | + changeOrigin: true, | ||
| 22 | + | ||
| 23 | + } | ||
| 24 | + }, | ||
| 25 | + // 该配置用于服务端请求转发 | ||
| 26 | + routeRules: { | ||
| 27 | + '/dev-api/**': { | ||
| 28 | + proxy: 'http://192.168.2.188:35273/**' | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + }, | ||
| 17 | css: [ | 32 | css: [ |
| 18 | '~/assets/iconfonts/iconfont.css', | 33 | '~/assets/iconfonts/iconfont.css', |
| 19 | ], | 34 | ], |
| @@ -2,8 +2,8 @@ | @@ -2,8 +2,8 @@ | ||
| 2 | "name": "nuxt-app", | 2 | "name": "nuxt-app", |
| 3 | "private": true, | 3 | "private": true, |
| 4 | "scripts": { | 4 | "scripts": { |
| 5 | - "build": "nuxt build", | ||
| 6 | - "dev": "nuxt dev", | 5 | + "build": "nuxt build --dotenv .env.production", |
| 6 | + "dev": "nuxt dev --dotenv .env.development", | ||
| 7 | "generate": "nuxt generate", | 7 | "generate": "nuxt generate", |
| 8 | "preview": "nuxt preview", | 8 | "preview": "nuxt preview", |
| 9 | "postinstall": "nuxt prepare" | 9 | "postinstall": "nuxt prepare" |
| @@ -18,11 +18,14 @@ | @@ -18,11 +18,14 @@ | ||
| 18 | </template> | 18 | </template> |
| 19 | 19 | ||
| 20 | <script lang="ts" setup> | 20 | <script lang="ts" setup> |
| 21 | -const sortList = useState("sortTree"); | 21 | +import type { appType } from "~/api/types/app"; |
| 22 | +import { getAppList } from "~/api/app"; | ||
| 23 | +import type { classifyType } from "~/api/types/classify"; | ||
| 24 | +const sortList = useState<classifyType>("sortTree"); | ||
| 22 | const route = useRoute(); | 25 | const route = useRoute(); |
| 23 | const router = useRouter(); | 26 | const router = useRouter(); |
| 24 | const { name } = route.params; | 27 | const { name } = route.params; |
| 25 | -const list = ref<any[]>([]); | 28 | +const list = ref<appType[]>([]); |
| 26 | const total = ref<number>(0); | 29 | const total = ref<number>(0); |
| 27 | const params = ref<any>({ | 30 | const params = ref<any>({ |
| 28 | pageNum: 1, | 31 | pageNum: 1, |
| @@ -64,13 +67,8 @@ function onPageChange(pageNum: number) { | @@ -64,13 +67,8 @@ function onPageChange(pageNum: number) { | ||
| 64 | path: route.path + "/page/" + pageNum, | 67 | path: route.path + "/page/" + pageNum, |
| 65 | }); | 68 | }); |
| 66 | } | 69 | } |
| 67 | -const { data } = await useFetch( | ||
| 68 | - "http://aitoolht.crgx.net/dh/app/listFrontApp", | ||
| 69 | - { | ||
| 70 | - method: "get", | ||
| 71 | - params: params.value, | ||
| 72 | - } | ||
| 73 | -); | ||
| 74 | -list.value = data.value.rows; | ||
| 75 | -total.value = data.value.total; | 70 | + |
| 71 | +const res = await getAppList(params.value); | ||
| 72 | +list.value = res.rows; | ||
| 73 | +total.value = res.total; | ||
| 76 | </script> | 74 | </script> |
| @@ -20,12 +20,14 @@ | @@ -20,12 +20,14 @@ | ||
| 20 | </template> | 20 | </template> |
| 21 | 21 | ||
| 22 | <script lang="ts" setup> | 22 | <script lang="ts" setup> |
| 23 | -import { ref } from "vue"; | ||
| 24 | -const sortList = useState("sortTree"); | 23 | +import type { appType } from "~/api/types/app"; |
| 24 | +import { getAppList } from "~/api/app"; | ||
| 25 | +import type { classifyType } from "~/api/types/classify"; | ||
| 26 | +const sortList = useState<classifyType>("sortTree"); | ||
| 25 | const route = useRoute(); | 27 | const route = useRoute(); |
| 26 | const router = useRouter(); | 28 | const router = useRouter(); |
| 27 | const { pageNum, name } = route.params; | 29 | const { pageNum, name } = route.params; |
| 28 | -const list = ref<any[]>([]); | 30 | +const list = ref<appType[]>([]); |
| 29 | const total = ref<number>(0); | 31 | const total = ref<number>(0); |
| 30 | const params = ref<any>({ | 32 | const params = ref<any>({ |
| 31 | pageNum: Number(pageNum), | 33 | pageNum: Number(pageNum), |
| @@ -74,13 +76,7 @@ function onPageChange(pageNum: number) { | @@ -74,13 +76,7 @@ function onPageChange(pageNum: number) { | ||
| 74 | } | 76 | } |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | -const { data } = await useFetch( | ||
| 78 | - "http://aitoolht.crgx.net/dh/app/listFrontApp", | ||
| 79 | - { | ||
| 80 | - method: "get", | ||
| 81 | - params: params.value, | ||
| 82 | - } | ||
| 83 | -); | ||
| 84 | -list.value = data.value.rows; | ||
| 85 | -total.value = data.value.total; | 79 | +const res = await getAppList(params.value); |
| 80 | +list.value = res.rows; | ||
| 81 | +total.value = res.total; | ||
| 86 | </script> | 82 | </script> |
| 1 | -<script setup> | 1 | +<script lang="ts" setup> |
| 2 | +import { getAppDetail } from "~/api/app"; | ||
| 3 | +import type { appDetail, Types } from "~/api/types/app"; | ||
| 4 | +import type { webSiteType } from "~/api/types/webSite"; | ||
| 2 | const route = useRoute(); | 5 | const route = useRoute(); |
| 3 | const config = useRuntimeConfig(); | 6 | const config = useRuntimeConfig(); |
| 4 | -const showAd = ref(true); | ||
| 5 | -const appDetail = ref({ | 7 | +const DetailData = ref<appDetail>({ |
| 8 | + id: 0, | ||
| 9 | + title: "", | ||
| 10 | + content: "", | ||
| 11 | + image: "", | ||
| 12 | + description: "", | ||
| 13 | + link: "", | ||
| 6 | types: [], | 14 | types: [], |
| 7 | }); | 15 | }); |
| 8 | -const webSite = useState("webSite"); | ||
| 9 | -const detailAd = ref({ | ||
| 10 | - width: 300, | ||
| 11 | - height: 177, | ||
| 12 | - frontAdVos: [], | ||
| 13 | -}); | ||
| 14 | -function mergeDuplicates(data) { | 16 | +const webSite = useState<webSiteType>("webSite"); |
| 17 | +function mergeDuplicates(data: Types[]) { | ||
| 15 | const map = new Map(); | 18 | const map = new Map(); |
| 16 | 19 | ||
| 17 | data.forEach((item) => { | 20 | data.forEach((item) => { |
| @@ -27,7 +30,7 @@ function mergeDuplicates(data) { | @@ -27,7 +30,7 @@ function mergeDuplicates(data) { | ||
| 27 | const existing = map.get(item.id); | 30 | const existing = map.get(item.id); |
| 28 | // 避免重复的子项(基于子项id) | 31 | // 避免重复的子项(基于子项id) |
| 29 | const existingChildIds = new Set( | 32 | const existingChildIds = new Set( |
| 30 | - existing.children.map((child) => child.id) | 33 | + existing.children.map((child: any) => child.id) |
| 31 | ); | 34 | ); |
| 32 | item.children.forEach((child) => { | 35 | item.children.forEach((child) => { |
| 33 | if (!existingChildIds.has(child.id)) { | 36 | if (!existingChildIds.has(child.id)) { |
| @@ -39,34 +42,26 @@ function mergeDuplicates(data) { | @@ -39,34 +42,26 @@ function mergeDuplicates(data) { | ||
| 39 | 42 | ||
| 40 | return Array.from(map.values()); | 43 | return Array.from(map.values()); |
| 41 | } | 44 | } |
| 42 | -const { data: detailData } = await useFetch( | ||
| 43 | - `http://aitoolht.crgx.net/dh/app/${route.params.id}` | ||
| 44 | -); | ||
| 45 | -const { data: adData } = await useFetch( | ||
| 46 | - "http://aitoolht.crgx.net/dh/ad/listFrontAd", | ||
| 47 | - { | ||
| 48 | - method: "get", | ||
| 49 | - params: { pageSize: 10, pageNum: 1, code: "top" }, | ||
| 50 | - } | ||
| 51 | -); | ||
| 52 | -detailAd.value = adData.value.rows[0]; | ||
| 53 | -appDetail.value = detailData.value.data; | ||
| 54 | -appDetail.value.types = mergeDuplicates(detailData.value.data.types); | 45 | + |
| 46 | +// 获取详情数据 | ||
| 47 | +const detailRes = await getAppDetail(Number(route.params.id)); | ||
| 48 | +DetailData.value = detailRes.data; | ||
| 49 | +DetailData.value.types = mergeDuplicates(detailRes.data.types); | ||
| 55 | 50 | ||
| 56 | useHead({ | 51 | useHead({ |
| 57 | - title: appDetail.value.popupContent | ||
| 58 | - ? `${appDetail.value.title} - ${appDetail.value.popupContent}` | ||
| 59 | - : appDetail.value.title, | 52 | + title: DetailData.value.popupContent |
| 53 | + ? `${DetailData.value.title} - ${DetailData.value.popupContent}` | ||
| 54 | + : DetailData.value.title, | ||
| 60 | meta: [ | 55 | meta: [ |
| 61 | - { name: "description", content: appDetail.value.description }, | 56 | + { name: "description", content: DetailData.value.description }, |
| 62 | { | 57 | { |
| 63 | name: "og:title", | 58 | name: "og:title", |
| 64 | - content: `${appDetail.value.title}-${appDetail.value.popupContent}`, | 59 | + content: `${DetailData.value.title}-${DetailData.value.popupContent}`, |
| 65 | }, | 60 | }, |
| 66 | - { name: "og:description", content: appDetail.value.description }, | 61 | + { name: "og:description", content: DetailData.value.description }, |
| 67 | { | 62 | { |
| 68 | name: "og:image", | 63 | name: "og:image", |
| 69 | - content: config.public.baseUrl + appDetail.value.image, | 64 | + content: config.public.baseUrl + DetailData.value.image, |
| 70 | }, | 65 | }, |
| 71 | { name: "og:url", content: route.fullPath }, | 66 | { name: "og:url", content: route.fullPath }, |
| 72 | { name: "og:site_name", content: webSite.value.webname }, | 67 | { name: "og:site_name", content: webSite.value.webname }, |
| @@ -79,25 +74,25 @@ useHead({ | @@ -79,25 +74,25 @@ useHead({ | ||
| 79 | <main class="flex-grow md:p-6 bg-white p-1"> | 74 | <main class="flex-grow md:p-6 bg-white p-1"> |
| 80 | <!-- Top Application Info Bar --> | 75 | <!-- Top Application Info Bar --> |
| 81 | <header | 76 | <header |
| 82 | - v-show="appDetail.types.length > 0" | 77 | + v-show="DetailData.types.length > 0" |
| 83 | class="bg-white shadow-sm md:py-4 md:px-8 py-2 px-4 flex md:items-center md:justify-between flex-col md:flex-row" | 78 | class="bg-white shadow-sm md:py-4 md:px-8 py-2 px-4 flex md:items-center md:justify-between flex-col md:flex-row" |
| 84 | > | 79 | > |
| 85 | <div class="flex items-center space-x-4"> | 80 | <div class="flex items-center space-x-4"> |
| 86 | <img | 81 | <img |
| 87 | - :src="config.public.baseUrl + appDetail.image" | 82 | + :src="config.public.baseUrl + DetailData.image" |
| 88 | alt="App Icon" | 83 | alt="App Icon" |
| 89 | class="w-16 h-16 object-contain" | 84 | class="w-16 h-16 object-contain" |
| 90 | /> | 85 | /> |
| 91 | <div> | 86 | <div> |
| 92 | <h1 class="text-2xl font-bold text-[#5961f9]"> | 87 | <h1 class="text-2xl font-bold text-[#5961f9]"> |
| 93 | - {{ appDetail.title }} | 88 | + {{ DetailData.title }} |
| 94 | </h1> | 89 | </h1> |
| 95 | <p class="text-sm text-gray-600 mt-1"> | 90 | <p class="text-sm text-gray-600 mt-1"> |
| 96 | - {{ appDetail.description }} | 91 | + {{ DetailData.description }} |
| 97 | </p> | 92 | </p> |
| 98 | <div class="mt-2 flex items-center space-x-2"> | 93 | <div class="mt-2 flex items-center space-x-2"> |
| 99 | <div | 94 | <div |
| 100 | - v-for="tag in appDetail.types" | 95 | + v-for="tag in DetailData.types" |
| 101 | class="flex items-center space-x-2" | 96 | class="flex items-center space-x-2" |
| 102 | > | 97 | > |
| 103 | <template v-if="tag.children.length > 0"> | 98 | <template v-if="tag.children.length > 0"> |
| @@ -123,7 +118,7 @@ useHead({ | @@ -123,7 +118,7 @@ useHead({ | ||
| 123 | </div> | 118 | </div> |
| 124 | <div class="flex md:space-x-3 md:mt-0 mt-4"> | 119 | <div class="flex md:space-x-3 md:mt-0 mt-4"> |
| 125 | <a | 120 | <a |
| 126 | - :href="appDetail.link" | 121 | + :href="DetailData.link" |
| 127 | target="_blank" | 122 | target="_blank" |
| 128 | class="!rounded-button whitespace-nowrap px-4 py-2 bg-[#5961f9] max-[768px]:text-xs text-white hover:bg-blue-600 transition-colors" | 123 | class="!rounded-button whitespace-nowrap px-4 py-2 bg-[#5961f9] max-[768px]:text-xs text-white hover:bg-blue-600 transition-colors" |
| 129 | > | 124 | > |
| @@ -134,7 +129,7 @@ useHead({ | @@ -134,7 +129,7 @@ useHead({ | ||
| 134 | 129 | ||
| 135 | <main class="relative w-full"> | 130 | <main class="relative w-full"> |
| 136 | <!-- 悬浮广告弹窗 --> | 131 | <!-- 悬浮广告弹窗 --> |
| 137 | - <div | 132 | + <!-- <div |
| 138 | class="md:absolute top-0 right-0 md:m-4 z-50 relative max-[768px]:m-auto" | 133 | class="md:absolute top-0 right-0 md:m-4 z-50 relative max-[768px]:m-auto" |
| 139 | v-show="showAd" | 134 | v-show="showAd" |
| 140 | :style="{ | 135 | :style="{ |
| @@ -158,9 +153,9 @@ useHead({ | @@ -158,9 +153,9 @@ useHead({ | ||
| 158 | X | 153 | X |
| 159 | </div> | 154 | </div> |
| 160 | </div> | 155 | </div> |
| 161 | - </div> | 156 | + </div> --> |
| 162 | <div class="md:max-w-5xl mx-auto md:p-8 p-2 w-full"> | 157 | <div class="md:max-w-5xl mx-auto md:p-8 p-2 w-full"> |
| 163 | - <div v-html="appDetail.content"></div> | 158 | + <div v-html="DetailData.content"></div> |
| 164 | </div> | 159 | </div> |
| 165 | </main> | 160 | </main> |
| 166 | </main> | 161 | </main> |
| 1 | -<script setup> | ||
| 2 | -const recommendList = ref([]); | ||
| 3 | -const appList = ref([]); | ||
| 4 | -const { data: RecommendData } = await useFetch( | ||
| 5 | - "http://aitoolht.crgx.net/dh/app/listFrontApp", | ||
| 6 | - { | ||
| 7 | - method: "get", | ||
| 8 | - params: { pageSize: 10, pageNum: 1, isRecommend: "1" }, | ||
| 9 | - } | ||
| 10 | -); | ||
| 11 | -const { data: allData } = await useFetch( | ||
| 12 | - "http://aitoolht.crgx.net/dh/app/allFrontApp" | ||
| 13 | -); | ||
| 14 | -recommendList.value = RecommendData.value.rows; | ||
| 15 | -appList.value = allData.value.data; | 1 | +<script lang="ts" setup> |
| 2 | +import type { appListType, appType } from "~/api/types/app"; | ||
| 3 | +import { getAppList, getAllApp } from "~/api/app"; | ||
| 4 | +const recommendList = ref<appType[]>([]); | ||
| 5 | +const appList = ref<appListType[]>([]); | ||
| 6 | +// 获取推荐应用 | ||
| 7 | +const recommendRes = await getAppList({ | ||
| 8 | + pageSize: 10, | ||
| 9 | + pageNum: 1, | ||
| 10 | + isRecommend: "1", | ||
| 11 | +}); | ||
| 12 | +recommendList.value = recommendRes.rows; | ||
| 13 | +// 获取全部应用 | ||
| 14 | +const allRes = await getAllApp(); | ||
| 15 | +appList.value = allRes.data; | ||
| 16 | </script> | 16 | </script> |
| 17 | 17 | ||
| 18 | <template> | 18 | <template> |
| @@ -14,11 +14,14 @@ | @@ -14,11 +14,14 @@ | ||
| 14 | </template> | 14 | </template> |
| 15 | 15 | ||
| 16 | <script lang="ts" setup> | 16 | <script lang="ts" setup> |
| 17 | +import type { appType } from "~/api/types/app"; | ||
| 18 | +import { getAppList } from "~/api/app"; | ||
| 19 | + | ||
| 17 | const route = useRoute(); | 20 | const route = useRoute(); |
| 18 | const router = useRouter(); | 21 | const router = useRouter(); |
| 19 | 22 | ||
| 20 | const { keyword } = route.query as { keyword: string }; | 23 | const { keyword } = route.query as { keyword: string }; |
| 21 | -const list = ref<any[]>([]); | 24 | +const list = ref<appType[]>([]); |
| 22 | const total = ref<number>(0); | 25 | const total = ref<number>(0); |
| 23 | const params = ref<any>({ | 26 | const params = ref<any>({ |
| 24 | pageNum: 1, | 27 | pageNum: 1, |
| @@ -35,13 +38,7 @@ function onPageChange(pageNum: number) { | @@ -35,13 +38,7 @@ function onPageChange(pageNum: number) { | ||
| 35 | }); | 38 | }); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 38 | -const { data } = await useFetch( | ||
| 39 | - "http://aitoolht.crgx.net/dh/app/listFrontApp", | ||
| 40 | - { | ||
| 41 | - method: "get", | ||
| 42 | - params: params.value, | ||
| 43 | - } | ||
| 44 | -); | ||
| 45 | -list.value = data.value.rows; | ||
| 46 | -total.value = data.value.total; | 41 | +const res = await getAppList(params.value); |
| 42 | +list.value = res.rows; | ||
| 43 | +total.value = res.total; | ||
| 47 | </script> | 44 | </script> |
| @@ -20,12 +20,13 @@ | @@ -20,12 +20,13 @@ | ||
| 20 | </template> | 20 | </template> |
| 21 | 21 | ||
| 22 | <script lang="ts" setup> | 22 | <script lang="ts" setup> |
| 23 | -import { ref } from "vue"; | 23 | +import type { appType } from "~/api/types/app"; |
| 24 | +import { getAppList } from "~/api/app"; | ||
| 24 | const route = useRoute(); | 25 | const route = useRoute(); |
| 25 | const router = useRouter(); | 26 | const router = useRouter(); |
| 26 | const { pageNum } = route.params; | 27 | const { pageNum } = route.params; |
| 27 | const { keyword } = route.query as { keyword: string }; | 28 | const { keyword } = route.query as { keyword: string }; |
| 28 | -const list = ref<any[]>([]); | 29 | +const list = ref<appType[]>([]); |
| 29 | const total = ref<number>(0); | 30 | const total = ref<number>(0); |
| 30 | const params = ref<any>({ | 31 | const params = ref<any>({ |
| 31 | pageNum: Number(pageNum), | 32 | pageNum: Number(pageNum), |
| @@ -50,14 +51,7 @@ function onPageChange(pageNum: number) { | @@ -50,14 +51,7 @@ function onPageChange(pageNum: number) { | ||
| 50 | }); | 51 | }); |
| 51 | } | 52 | } |
| 52 | } | 53 | } |
| 53 | - | ||
| 54 | -const { data } = await useFetch( | ||
| 55 | - "http://aitoolht.crgx.net/dh/app/listFrontApp", | ||
| 56 | - { | ||
| 57 | - method: "get", | ||
| 58 | - params: params.value, | ||
| 59 | - } | ||
| 60 | -); | ||
| 61 | -list.value = data.value.rows; | ||
| 62 | -total.value = data.value.total; | 54 | +const res = await getAppList(params.value); |
| 55 | +list.value = res.rows; | ||
| 56 | +total.value = res.total; | ||
| 63 | </script> | 57 | </script> |
utils/request.ts
0 → 100644
| 1 | +import { ElLoading } from 'element-plus' | ||
| 2 | + | ||
| 3 | +const useMyfetch = async (url: any, options?: any, headers?: any) => { | ||
| 4 | + let loadingInstance | ||
| 5 | + | ||
| 6 | + try { | ||
| 7 | + loadingInstance = ElLoading.service() | ||
| 8 | + const config = useRuntimeConfig() // 3.0正式版环境变量要从useRuntimeConfig里的public拿 | ||
| 9 | + const reqUrl = config.public.baseUrl + url // 你的接口地址 | ||
| 10 | + // 不设置key,始终拿到的都是第一个请求的值,参数一样则不会进行第二次请求 | ||
| 11 | + | ||
| 12 | + // 可以设置默认headers例如 | ||
| 13 | + const customHeaders = { | ||
| 14 | + Authorization: useCookie('accessToken').value, | ||
| 15 | + ...headers | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + const { data, pending } = await useFetch(reqUrl, { | ||
| 19 | + ...options, | ||
| 20 | + watch: false, | ||
| 21 | + headers: customHeaders | ||
| 22 | + }) | ||
| 23 | + | ||
| 24 | + const result = data.value as any | ||
| 25 | + | ||
| 26 | + if (pending && loadingInstance) { | ||
| 27 | + loadingInstance.close() | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + return result | ||
| 31 | + } catch (err) { | ||
| 32 | + return Promise.reject(err) | ||
| 33 | + } finally { | ||
| 34 | + if (loadingInstance) { | ||
| 35 | + loadingInstance.close() | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +export const useGet = (url: string, params?: any, headers?: any) => { | ||
| 41 | + return useMyfetch(url, { method: 'get', params }, headers) | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +export const usePost = (url: string, params?: any, headers?: any) => { | ||
| 45 | + return useMyfetch(url, { method: 'post', body: params }, headers) | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +export const usePut = (url: string, params?: any, headers?: any) => { | ||
| 49 | + return useMyfetch(url, { method: 'put', body: params }, headers) | ||
| 50 | +} |
-
请 注册 或 登录 后发表评论