新版本官网优化完成

This commit is contained in:
2025-02-12 16:37:07 +08:00
parent 43a2e17a80
commit 3efdbfc662
547 changed files with 23001 additions and 28169 deletions

View File

@@ -1,104 +0,0 @@
<template>
<div class="text-center flex flex-col items-center py-10">
<h2 class="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl lg:text-5xl">
{{ title }}
</h2>
<div class="sub-title">
<p class="text-gray-500 dark:text-gray-400 py-3">
{{ comments }}
</p>
</div>
</div>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative" v-infinite-scroll="load">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer"
@click="openSpmUrl(`/detail`,item,item.articleId,true)">
<el-image :src="item.image" fit="cover" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex items-center gap-1.5">
<span class="flex-1 text-xl cursor-pointer max-h-[57px] overflow-hidden">{{ item.title }}</span>
</div>
<div class="flex items-center gap-1.5 py-2 text-gray-500">
<el-avatar :src="item.avatar" :size="20"/>
<span>{{ item.author }} · {{ dayjs(item.createTime).format('MM-DD hh:mm') }}</span>
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div v-if="disabled" class="p-4 text-center text-gray-500">
没有更多了
</div>
</template>
<script setup lang="ts">
import {openSpmUrl} from "~/utils/common";
import dayjs from "dayjs";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult, PageResult} from "~/api";
import type {Article} from "~/api/cms/article/model";
import type {CompanyParam} from "~/api/system/company/model";
const props = withDefaults(
defineProps<{
list?: any[];
disabled?: boolean;
title?: string;
comments?: string;
}>(),
{
title: '卡片标题',
comments: '卡片描述'
}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const runtimeConfig = useRuntimeConfig();
const list = ref<Article[]>([]);
const page = ref<number>(1);
const resultText = ref('');
const disabled = ref(false);
// 搜索表单
const where = reactive<CompanyParam>({
keywords: ''
});
const load = () => {
if (!props.disabled) {
page.value++;
reload();
}
}
// 请求数据
const reload = async () => {
const {data: response} = await useServerRequest<ApiResult<PageResult<Article>>>('/cms/cms-article/page', {
baseURL: runtimeConfig.public.apiServer, params: {
page: page.value, limit: 8, keywords: where.keywords
}
})
if (response.value?.data) {
if (list.value.length < response.value?.data.count) {
disabled.value = false;
if (response.value?.data.list) {
list.value = list.value.concat(response.value?.data.list);
}
} else {
disabled.value = true;
}
if (response.value.data.count == 0) {
resultText.value = '暂无相关结果'
}
}
}
reload();
</script>

View File

@@ -1,96 +0,0 @@
<template>
<div class="banner m-auto relative sm:flex">
<svg viewBox="0 0 1440 181" fill="none" xmlns="http://www.w3.org/2000/svg"
class="pointer-events-none absolute w-full top-[-2px] transition-all text-green-5 flex-shrink-0 opacity-100 duration-[400ms] opacity-80 -z-10">
<mask id="path-1-inside-1_414_5526" fill="white">
<path d="M0 0H1440V181H0V0Z"></path>
</mask>
<path d="M0 0H1440V181H0V0Z" fill="url(#paint0_linear_414_5526)" fill-opacity="0.22"></path>
<path d="M0 2H1440V-2H0V2Z" fill="url(#paint1_linear_414_5526)" mask="url(#path-1-inside-1_414_5526)"></path>
<defs>
<linearGradient id="paint0_linear_414_5526" x1="720" y1="0" x2="720" y2="181" gradientUnits="userSpaceOnUse">
<stop stop-color="currentColor"></stop>
<stop offset="1" stop-color="currentColor" stop-opacity="0"></stop>
</linearGradient>
<linearGradient id="paint1_linear_414_5526" x1="0" y1="90.5" x2="1440" y2="90.5" gradientUnits="userSpaceOnUse">
<stop stop-color="currentColor" stop-opacity="0"></stop>
<stop offset="0.395" stop-color="currentColor"></stop>
<stop offset="1" stop-color="currentColor" stop-opacity="0"></stop>
</linearGradient>
</defs>
</svg>
<div class="md:w-screen-xl m-auto">
<div class="py-8 sm:py-16" _path="/templates" _dir="" _draft="false" _partial="false" _locale=""
_id="content:4.templates.yml" _type="yaml" _source="content" _file="4.templates.yml" _stem="4.templates"
_extension="yml">
<div class="gap-8 sm:gap-y-16 grid lg:grid-cols-2 lg:items-center" v-if="layout">
<div class="">
<h1
class="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl lg:text-5xl">
<span>WEBSOFT</span>
<span v-if="layout.name">{{ layout.name }}</span>
</h1>
<div class="mt-4 text-lg text-gray-500 dark:text-gray-400">
{{ layout.description }}
</div>
<el-space class="mt-4">
<el-button
:icon="ElIconView"
size="large"
v-if="layout.demoUrl"
@click="openSpmUrl(layout.demoUrl)"
>
演示地址
</el-button>
<el-button
v-if="layout.buyUrl"
:icon="ElIconBottom"
size="large"
@click="openSpmUrl(layout.buyUrl)"
>
下载模版
</el-button>
<el-button
:icon="ElIconMemo"
size="large"
v-if="layout.docUrl"
@click="openSpmUrl(layout.docUrl)"
>
帮助文档
</el-button>
</el-space>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {useConfigInfo} from "~/composables/configState";
import {openSpmUrl} from "~/utils/common";
const token = useToken();
const sysDomain = useSysDomain();
withDefaults(
defineProps<{
layout?: any;
title?: string;
desc?: string;
buyUrl?: string;
}>(),
{
title: 'Templates',
desc: 'Explore community templates to get up and running in a few seconds.',
demoUrl: '/product/website',
buyUrl: 'https://github.com/websoft9/ansible-templates'
}
);
const config = useConfigInfo();
</script>

View File

@@ -1,87 +0,0 @@
<template>
<div class="text-center flex flex-col items-center pb-10">
<h2 class="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl lg:text-5xl">
{{ title }}
</h2>
<div class="sub-title">
<p class="text-gray-500 dark:text-gray-400 py-3">
{{ comments }}
</p>
</div>
</div>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer">
<el-image
:src="`https://oss.wsdns.cn/20240925/e5e47100f4b6471395b3b81f834d2902.jpg?x-oss-process=image/resize,m_fixed,w_750/quality,Q_90`"
fit="contain" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col gap-1.5">
<div class="flex-1 text-xl cursor-pointer">{{ item.title }}</div>
<div class="text-red-500">{{ item.price }}</div>
</div>
<div v-if="item.price && item.price > 0" class="flex items-center gap-1.5 py-2 text-gray-500 justify-between">
<div class="text-gray-500">{{ item.comments }}</div>
</div>
<div class="button-group flex justify-center mt-3">
<el-button class="w-full" size="large" :icon="ElIconView" @click="openSpmUrl('/item', item,item.goodsId,true)">
查看详情
</el-button>
<el-button type="primary" size="large" v-if="item.price && item.price > 0" class="w-full" :icon="ElIconShoppingCart">购买
</el-button>
<el-button v-else class="w-full" size="large" :icon="ElIconShoppingCart">下载</el-button>
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div v-if="disabled" class="px-1 text-center text-gray-500 min-h-xs">
没有更多了
</div>
</template>
<script setup lang="ts">
import {openSpmUrl} from "~/utils/common";
import dayjs from "dayjs";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult, PageResult} from "~/api";
import type {Product} from "~/api/oa/product/model";
const props = withDefaults(
defineProps<{
disabled?: boolean;
title?: string;
comments?: string;
}>(),
{
title: '卡片标题',
comments: '卡片描述'
}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const runtimeConfig = useRuntimeConfig();
const list = ref<Product[]>([]);
// 请求数据
const reload = async () => {
const {data: response} = await useServerRequest<ApiResult<PageResult<Product>>>('/cms/cms-product/page', {
baseURL: runtimeConfig.public.apiServer, params: {
limit: 8
}
})
if (response.value?.data) {
if (response.value?.data.list) {
list.value = response.value?.data.list;
}
}
}
reload();
</script>

View File

@@ -0,0 +1,79 @@
<template>
<div>
<div class="w-full bg-white mb-3 hidden-sm-and-down" v-if="ad">
<el-carousel :height="'750px'">
<el-carousel-item v-for="(item,index) in ad?.imageList" :key="index">
<div class="item relative flex justify-center items-center">
<el-image :src="item.url" />
</div>
</el-carousel-item>
</el-carousel>
</div>
<!-- 移动端 -->
<div class="sm:hidden w-full bg-white mt-[48px] mb-3 hidden-sm-and-up" v-if="ad">
<el-carousel indicator-position="none" height="150">
<el-carousel-item v-for="(item,index) in ad?.imageList" :key="index">
<el-image :src="item.url" />
</el-carousel-item>
</el-carousel>
</div>
</div>
</template>
<script setup lang="ts">
import type {CompanyParam} from "~/api/system/company/model";
import type {CmsAd} from "~/api/cms/cmsAd/model";
import {pageCmsAd} from "~/api/cms/cmsAd";
const props = withDefaults(
defineProps<{
config?: any;
list?: any[];
disabled?: boolean;
title?: string;
comments?: string;
}>(),
{
title: '卡片标题',
comments: '卡片描述'
}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const ad = ref<CmsAd>();
// 搜索表单
const where = reactive<CompanyParam>({
keywords: ''
});
// 请求数据
const reload = async () => {
pageCmsAd({
type: 1,
lang: getLang()
}).then(res => {
console.log(res)
if(res){
ad.value = res.list[0];
}
})
}
watch(
() => props.config,
() => {
reload();
},
{immediate: true}
);
</script>
<style>
.hidden-sm-and-up .el-carousel{
height: 160px;
}
</style>

View File

@@ -19,8 +19,8 @@
</defs>
</svg>
<div class="py-24 sm:py-32 md:py-20 relative dark:bg-gradient-to-b from-gray-950 to-gray-900 md:pb-36">
<svg data-v-835f5c7a="" width="100%" height="869" viewBox="0 0 1440 869" fill="none"
<div class="mt-10 py-24 sm:py-32 md:py-20 relative dark:bg-gradient-to-b from-gray-950 to-gray-900 md:pb-36">
<svg data-v-835f5c7a="" width="100%" height="700" viewBox="0 0 1440 869" fill="none"
xmlns="http://www.w3.org/2000/svg" class="absolute top-0 inset-x-0 w-full hidden lg:block">
<g clip-path="url(#clip0_184_92145)" data-v-835f5c7a="">
<path
@@ -85,23 +85,45 @@
<div class="mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl gap-16 sm:gap-y-24 flex flex-col ">
<div class="text-center relative z-[1]">
<div class="mb-8 cursor-pointer">
<el-tag type="warning" round @click="openSpmUrl(`/detail`, {},730,true)">v3.0 版本发布
<el-tag type="warning" round @click="navTo(`/detail`)">v3.0 版本发布
</el-tag>
</div>
<h1 class="text-5xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-7xl">
<span>构建现代Web应用</span><br/>
<span class="text-primary block lg:inline-block text-green-500">Vue 框架</span>
<!-- <span class="text-primary block lg:inline-block text-green-500">Vue 框架</span>-->
</h1>
<div class="mt-6 text-lg tracking-tight text-gray-600 dark:text-gray-300"> WEBSOFT是一个基于Vue和Nuxt构建的web框架使web开发更直观而强大<br>
<div class="mt-6 text-lg tracking-tight text-gray-400 dark:text-gray-300"> 基于Java SpringBoot构建的SaaS软件平台支持VueReact前端框架<br>
自信地创建高性能和生产级的全栈web应用程序和网站
</div>
<div class="mt-10 flex flex-wrap gap-x-6 gap-y-3 justify-center">
<div class="flex flex-col gap-4">
<div class="flex items-center">
<el-button size="large" type="primary" :icon="ElIconArrowRight" @click="openSpmUrl(`/passport/login`)">立即开始</el-button>
<!-- <el-button size="large" type="primary" v-else :icon="ElIconArrowRight" @click="loginAdminByToken">进入控制台</el-button>-->
<el-button size="large" type="success" :icon="ElIconDownload" @click="openSpmUrl(`http://git.gxwebsoft.com/free`, {},0,true)">源码下载</el-button>
<el-button size="large" type="danger" @click="openSpmUrl(`https://website.websoft.top`, {},123)">商业版演示</el-button>
<div class="flex items-center gap-4">
<!-- <el-button size="large" type="danger" :icon="ElIconUser" @click="openUrl(`https://site.websoft.top`)">立即登录</el-button>-->
<!-- <el-button size="large" type="primary" :icon="ElIconArrowRight" @click="openUrl(`https://site.websoft.top/register`)">免费注册</el-button>-->
<div class="flex flex-col justify-center cursor-pointer text-white items-center bg-gray-400 hover:bg-gray-500 w-[100px] h-[100px] rounded-full">
<img alt="Windows" src="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E %3Cg fill='%23FFF' fill-rule='evenodd'%3E %3Cpath d='M6.316 21.826v9.025l10.99 1.539V21.826zm12.045 0v10.712l14.463 2.026V21.826zM6.316 11.767v9.004h10.99V10.205zM32.824 8l-14.463 2.055v10.716h14.463z' opacity='1'/%3E %3Cpath fill='none' d='M0 0h40v40H0z'/%3E %3C/g%3E%3C/svg%3E" />
<span class="text-sm">Windows</span>
</div>
<div class="flex flex-col justify-center cursor-pointer text-white items-center bg-gray-400 hover:bg-green-600 w-[100px] h-[100px] rounded-full" @click="openUrl(`https://oss.wsdns.cn/download/%E7%BD%91%E5%AE%BF%E8%BD%AF%E4%BB%B6%28OA%29-3.0.0-arm64.dmg`)">
<img alt="macOs" src="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='40' height='40' viewBox='0 0 40 40'%3E %3Cdefs%3E %3Cpath id='47f1323c-993c-4d45-aab1-bebb1206c2bb-a' d='M.001.592h26.926v24.039H.001z'/%3E %3C/defs%3E %3Cg fill='none' fill-rule='evenodd'%3E %3Cpath d='M0 0h40v40H0z'/%3E %3Cg opacity='1' transform='translate(6.316 2.737)'%3E %3Cg transform='translate(0 7.045)'%3E %3Cmask id='47f1323c-993c-4d45-aab1-bebb1206c2bb-b' fill='%23fff'%3E %3Cuse xlink:href='%2347f1323c-993c-4d45-aab1-bebb1206c2bb-a'/%3E %3C/mask%3E %3Cpath fill='%23FFF' d='M20.005.608c-2.722-.193-5.031 1.456-6.32 1.456-1.308 0-3.324-1.415-5.461-1.376-2.806.04-5.393 1.564-6.84 3.972C-1.531 9.506.64 16.687 3.479 20.62c1.389 1.922 3.045 4.088 5.221 4.009 2.094-.08 2.887-1.298 5.418-1.298 2.53 0 3.243 1.298 5.458 1.259 2.254-.04 3.683-1.962 5.061-3.894 1.596-2.23 2.251-4.39 2.29-4.505-.05-.018-4.394-1.614-4.437-6.408-.04-4.008 3.415-5.935 3.573-6.028C24.102.989 21.073.684 20.005.608' mask='url(%2347f1323c-993c-4d45-aab1-bebb1206c2bb-b)'/%3E %3C/g%3E %3Cpath fill='%23FFF' d='M18.325 5.057C19.482 3.718 20.26 1.854 20.045 0c-1.663.063-3.676 1.062-4.87 2.4-1.07 1.185-2.008 3.083-1.753 4.899 1.855.137 3.748-.902 4.903-2.242'/%3E %3C/g%3E %3C/g%3E%3C/svg%3E" />
<span class="text-sm">macOs</span>
</div>
<div class="flex flex-col justify-center cursor-pointer text-white items-center bg-gray-400 hover:bg-gray-500 w-[100px] h-[100px] rounded-full">
<img alt="iOS" src="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='40' height='40' viewBox='0 0 40 40'%3E %3Cdefs%3E %3Cpath id='f46e5a6d-7d66-4f5f-8628-7f4ceb95844a-a' d='M0 0h27v24.104H0z'/%3E %3C/defs%3E %3Cg fill='none' fill-rule='evenodd' transform='translate(7 4)'%3E %3Cg transform='translate(0 7.658)'%3E %3Cmask id='f46e5a6d-7d66-4f5f-8628-7f4ceb95844a-b' fill='%23fff'%3E %3Cuse xlink:href='%23f46e5a6d-7d66-4f5f-8628-7f4ceb95844a-a'/%3E %3C/mask%3E %3Cpath fill='%23FFF' d='M20.06.016c-2.73-.194-5.046 1.46-6.339 1.46-1.311 0-3.332-1.418-5.475-1.38-2.814.04-5.408 1.57-6.86 3.983-2.922 4.86-.745 12.06 2.102 16.004 1.392 1.927 3.053 4.098 5.235 4.02 2.1-.08 2.895-1.302 5.433-1.302 2.536 0 3.252 1.301 5.473 1.262 2.26-.04 3.692-1.967 5.075-3.904 1.6-2.237 2.257-4.403 2.296-4.517-.05-.018-4.406-1.619-4.45-6.426-.039-4.019 3.425-5.951 3.583-6.044C24.167.398 21.129.092 20.059.016z' mask='url(%23f46e5a6d-7d66-4f5f-8628-7f4ceb95844a-b)'/%3E %3C/g%3E %3Cpath fill='%23FFF' d='M18.375 5.07c1.16-1.342 1.94-3.21 1.725-5.07-1.669.063-3.687 1.065-4.884 2.406-1.072 1.188-2.013 3.091-1.757 4.912 1.86.138 3.758-.904 4.916-2.247z'/%3E %3C/g%3E%3C/svg%3E">
<span class="text-sm">iOS</span>
</div>
<div class="flex flex-col justify-center cursor-pointer text-white items-center bg-gray-400 hover:bg-gray-500 w-[100px] h-[100px] rounded-full">
<img alt="Android" src="data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='40' height='40' viewBox='0 0 40 40'%3E %3Cdefs%3E %3Cpath id='a688108f-309f-4e18-a0dc-ed026741fa12-a' d='M0 0h33.684v18.947H0z'/%3E %3C/defs%3E %3Cg fill='none' fill-rule='evenodd'%3E %3Cpath d='M0 0h40v40H0z'/%3E %3Cg opacity='1' transform='translate(3.158 11.158)'%3E %3Cmask id='a688108f-309f-4e18-a0dc-ed026741fa12-b' fill='%23fff'%3E %3Cuse xlink:href='%23a688108f-309f-4e18-a0dc-ed026741fa12-a'/%3E %3C/mask%3E %3Cpath fill='%23FFF' d='M24.594 14.156a1.402 1.402 0 1 1-.003-2.803 1.402 1.402 0 0 1 .003 2.803m-15.504 0a1.402 1.402 0 1 1-.002-2.803 1.402 1.402 0 0 1 .002 2.803M25.097 5.72L27.9.874a.584.584 0 0 0-1.01-.583L24.05 5.2c-2.17-.989-4.608-1.54-7.21-1.54-2.6 0-5.038.552-7.209 1.54L6.794.291a.584.584 0 0 0-1.01.582l2.803 4.848C3.774 8.335.482 13.2 0 18.947h33.684C33.202 13.2 29.91 8.335 25.097 5.721' mask='url(%23a688108f-309f-4e18-a0dc-ed026741fa12-b)'/%3E %3C/g%3E %3C/g%3E%3C/svg%3E">
<span class="text-sm">Android</span>
</div>
<!-- <el-button size="large" :icon="ElIconDownload" @click="openUrl(`https://file.gxwebsoft.com/download/website-3.0.1-arm64.dmg`)">macOs</el-button>-->
</div>
</div>
</div>
@@ -112,7 +134,8 @@
</template>
<script setup lang="ts">
import {useToken} from "~/composables/configState";
import {loginAdminByToken, openSpmUrl} from "~/utils/common";
import {loginAdminByToken, navTo, openUrl} from "~/utils/common";
import {navigateTo} from "#imports";
const token = useToken();
</script>

View File

@@ -1,83 +0,0 @@
<template>
<div class="text-center flex flex-col items-center py-10">
<h2 class="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl lg:text-5xl">
插件市场
</h2>
<div class="sub-title">
<p class="text-gray-500 dark:text-gray-400 py-3">
安装插件几秒钟内即可启动并运行
</p>
</div>
</div>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer">
<el-image
:src="item.image"
fit="contain" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer bg-gray-50"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col gap-1.5">
<div class="flex-1 text-xl cursor-pointer">{{ item.title }}</div>
<div class="text-red-500">{{ item.price }}</div>
</div>
<div v-if="item.price && item.price > 0" class="flex items-center gap-1.5 py-2 text-gray-500 justify-between">
<div class="text-gray-500">{{ item.comments }}</div>
</div>
<div class="button-group flex justify-center mt-3">
<el-button class="w-full" size="large" :icon="ElIconView" @click="openSpmUrl(`/item`, item,item.productId,true)">查看详情</el-button>
<el-button type="primary" size="large" v-if="item.price && item.price > 0" class="w-full" :icon="ElIconShoppingCart">购买
</el-button>
<el-button v-else class="w-full" size="large" :icon="ElIconShoppingCart">下载</el-button>
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div v-if="disabled" class="px-1 text-center text-gray-500 min-h-xs">
没有更多了
</div>
</template>
<script setup lang="ts">
import {openSpmUrl} from "~/utils/common";
import dayjs from "dayjs";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult, PageResult} from "~/api";
import type {Plug} from "~/api/system/plug/model";
import type {Product} from "~/api/oa/product/model";
const props = withDefaults(
defineProps<{
disabled?: boolean;
type?: number;
}>(),
{}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const runtimeConfig = useRuntimeConfig();
const list = ref<Product[]>([]);
// 请求数据
const reload = async () => {
const {data: response} = await useServerRequest<ApiResult<PageResult<Product>>>('/cms/cms-product/page', {
baseURL: runtimeConfig.public.apiServer, params: {
limit: 8,
type: props.type,
}
})
if (response.value?.data) {
if (response.value?.data.list) {
list.value = response.value?.data.list;
}
}
}
reload();
</script>

View File

@@ -1,92 +0,0 @@
<template>
<div class="text-center flex flex-col items-center py-12">
<h2 class="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl lg:text-5xl">
{{ title }}
</h2>
<div class="sub-title">
<p class="text-gray-500 dark:text-gray-400 py-3">
{{ comments }}
</p>
</div>
</div>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer" @click="openSpmUrl(`/item`, item,item.productId,true)">
<el-image
:src="item.image"
fit="cover" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer bg-gray-50"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col gap-1.5">
<div class="flex-1 text-xl cursor-pointer flex items-center">
{{ item.title }}
<el-tag v-if="item.tag == '1'" size="small" type="success" class="text-white ml-2" effect="dark">免费</el-tag>
<el-tag v-if="item.tag == '2'" size="small" type="success" class="text-white ml-2" effect="dark">开源</el-tag>
<el-tag v-if="item.tag == '3'" size="small" type="danger" class="text-white ml-2" effect="dark">付费</el-tag>
</div>
</div>
<div class="flex items-center gap-1.5 py-2 text-gray-500 justify-between">
<div class="text-gray-500 line-clamp-3">{{ item.comments }}</div>
</div>
<div class="button-group flex justify-between items-center mt-3">
<div v-if="item.price && item.price > 0" class="text-red-500 text-xl">{{ item.price }} </div>
<el-button v-if="item.price && item.price > 0" @click.stop="openSpmUrl(`/product/create`,item,item.productId,true)">立即开通
</el-button>
<el-button v-else>下载</el-button>
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div v-if="disabled" class="px-1 text-center text-gray-500 min-h-xs">
没有更多了
</div>
</template>
<script setup lang="ts">
import {openSpmUrl} from "~/utils/common";
import dayjs from "dayjs";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult, PageResult} from "~/api";
import type {Product} from "~/api/oa/product/model";
const props = withDefaults(
defineProps<{
disabled?: boolean;
title?: string;
type?: number;
comments?: string;
}>(),
{
title: '卡片标题',
comments: '卡片描述'
}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const runtimeConfig = useRuntimeConfig();
const list = ref<Product[]>([]);
// 请求数据
const reload = async () => {
const {data: response} = await useServerRequest<ApiResult<PageResult<Product>>>('/cms/cms-product/page', {
baseURL: runtimeConfig.public.apiServer, params: {
type: props.type,
limit: 8,
status: 0
}
})
if (response.value?.data) {
if (response.value?.data.list) {
list.value = response.value?.data.list;
}
}
}
reload();
</script>