feat(ppt-templates): 添加PPT模板库页面
This commit is contained in:
@@ -18,10 +18,15 @@ export default defineAppConfig({
|
||||
container: 'gap-2',
|
||||
base: 'px-3 py-4',
|
||||
after: 'after:hidden',
|
||||
active: 'before:bg-neutral-600 hover:before:bg-neutral-600 dark:before:bg-neutral-800 dark:hover:before:bg-neutral-800 text-neutral-50 dark:text-neutral-300',
|
||||
active:
|
||||
'before:bg-neutral-600 hover:before:bg-neutral-600 dark:before:bg-neutral-800 dark:hover:before:bg-neutral-800 text-neutral-50 dark:text-neutral-300',
|
||||
icon: {
|
||||
active: 'text-neutral-50 dark:text-neutral-300',
|
||||
},
|
||||
},
|
||||
formGroup: {
|
||||
hint: 'text-xs',
|
||||
help: 'text-xs',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ const colorMode = useColorMode()
|
||||
const dayjs = useDayjs()
|
||||
const modal = useModal()
|
||||
const toast = useToast()
|
||||
const router = useRouter()
|
||||
const loginState = useLoginState()
|
||||
|
||||
const isDark = computed({
|
||||
@@ -42,6 +43,7 @@ const items = [
|
||||
}], [{
|
||||
label: '账号资料',
|
||||
icon: 'i-tabler-user-circle',
|
||||
to: '/profile'
|
||||
}], [{
|
||||
label: '注销登录',
|
||||
icon: 'i-tabler-logout',
|
||||
@@ -63,8 +65,8 @@ const open_login_modal = () => {
|
||||
<div class="relative grid w-full min-h-screen">
|
||||
<header>
|
||||
<h1 class="inline-flex flex-col">
|
||||
<span class="text-lg text-neutral-600 dark:text-neutral-300 font-bold">眩生花 AI 助手</span>
|
||||
<span class="text-xs text-neutral-600 dark:text-neutral-300">XSH AI Assistant</span>
|
||||
<span class="text-lg text-neutral-600 dark:text-neutral-300 font-bold">AIGC 微课视频研创平台</span>
|
||||
<!-- <span class="text-xs text-neutral-600 dark:text-neutral-300">眩生花科技</span> -->
|
||||
</h1>
|
||||
<div class="hidden md:block">
|
||||
<UHorizontalNavigation :links="links" class="select-none"/>
|
||||
|
||||
@@ -33,6 +33,11 @@ const navList = ref<
|
||||
icon: 'tabler:keyframes',
|
||||
to: '/generation/materials',
|
||||
},
|
||||
{
|
||||
label: 'PPT 模板库',
|
||||
icon: 'tabler:file-type-ppt',
|
||||
to: '/generation/ppt-templates',
|
||||
},
|
||||
{
|
||||
label: '用户管理',
|
||||
icon: 'tabler:users',
|
||||
|
||||
125
pages/generation/ppt-templates.vue
Normal file
125
pages/generation/ppt-templates.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<script lang="ts" setup>
|
||||
const loginState = useLoginState()
|
||||
|
||||
const { data: pptCategories } = useAsyncData('pptCategories', () =>
|
||||
useFetchWrapped<
|
||||
PagedDataRequest & AuthedRequest,
|
||||
BaseResponse<PagedData<PPTCategory>>
|
||||
>('App.Digital_PowerPointCat.GetList', {
|
||||
token: loginState.token!,
|
||||
user_id: loginState.user.id,
|
||||
page: 1,
|
||||
perpage: 20,
|
||||
})
|
||||
)
|
||||
|
||||
const selectedCat = ref<number>(0)
|
||||
const pagination = reactive({
|
||||
page: 1,
|
||||
perpage: 18,
|
||||
})
|
||||
|
||||
const { data: pptTemplates } = useAsyncData(
|
||||
'pptTemplates',
|
||||
() =>
|
||||
useFetchWrapped<
|
||||
PagedDataRequest & { type: string | number } & AuthedRequest,
|
||||
BaseResponse<PagedData<PPTTemplate>>
|
||||
>('App.Digital_PowerPoint.GetList', {
|
||||
token: loginState.token!,
|
||||
user_id: loginState.user.id,
|
||||
page: pagination.page,
|
||||
perpage: pagination.perpage,
|
||||
type: selectedCat.value === 0 ? '' : selectedCat.value,
|
||||
}),
|
||||
{
|
||||
watch: [selectedCat, pagination],
|
||||
}
|
||||
)
|
||||
|
||||
const onDownloadClick = (ppt: PPTTemplate) => {
|
||||
const { download } = useDownload(ppt.file_url, `${ppt.title}.pptx`)
|
||||
download()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="p-4 pb-0">
|
||||
<BubbleTitle
|
||||
title="PPT 模板库"
|
||||
subtitle="Slide Templates"
|
||||
/>
|
||||
<GradientDivider />
|
||||
</div>
|
||||
<div class="p-4 pt-0">
|
||||
<!-- cat selector -->
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div
|
||||
v-for="cat in [
|
||||
{ id: 0, type: '全部' },
|
||||
...(pptCategories?.data.items || []),
|
||||
]"
|
||||
@click="selectedCat = cat.id"
|
||||
:key="cat.id"
|
||||
:class="{
|
||||
'bg-primary text-white': selectedCat === cat.id,
|
||||
'bg-gray-100 text-gray-500': selectedCat !== cat.id,
|
||||
}"
|
||||
class="rounded-lg px-4 py-2 text-sm cursor-pointer"
|
||||
>
|
||||
{{ cat.type }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4 mt-4"
|
||||
>
|
||||
<div
|
||||
v-for="ppt in pptTemplates?.data.items"
|
||||
:key="ppt.id"
|
||||
class="relative bg-white rounded-lg shadow-md overflow-hidden"
|
||||
>
|
||||
<NuxtImg
|
||||
:src="ppt.preview_url"
|
||||
:alt="ppt.title"
|
||||
class="w-full aspect-video object-cover"
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-x-0 bottom-0 p-3 pt-6 flex justify-between items-end bg-gradient-to-t from-black/50 to-transparent"
|
||||
>
|
||||
<div class="space-y-0.5">
|
||||
<h3 class="text-base font-bold text-white">{{ ppt.title }}</h3>
|
||||
<p class="text-xs font-medium text-neutral-400">
|
||||
{{ ppt.description }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<UButton
|
||||
label="下载"
|
||||
size="sm"
|
||||
color="primary"
|
||||
icon="tabler:download"
|
||||
@click="onDownloadClick(ppt)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-end">
|
||||
<UPagination
|
||||
v-if="pptTemplates?.data.total > pagination.perpage"
|
||||
:total="pptTemplates?.data.total"
|
||||
:page-count="pagination.perpage"
|
||||
:max="9"
|
||||
v-model="pagination.page"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
33
typings/types.d.ts
vendored
33
typings/types.d.ts
vendored
@@ -32,6 +32,7 @@ interface UserSchema {
|
||||
email: string
|
||||
mobile: string
|
||||
auth_code: 0 | 1 | 2 // 0: Banned, 1: User, 2: Operator
|
||||
company?: string
|
||||
}
|
||||
|
||||
interface DigitalHumanItem {
|
||||
@@ -76,6 +77,22 @@ interface TitlesTemplate {
|
||||
description: string
|
||||
}
|
||||
|
||||
interface PPTCategory {
|
||||
id: number
|
||||
type: string
|
||||
create_time: number
|
||||
}
|
||||
|
||||
interface PPTTemplate {
|
||||
id: number
|
||||
create_time: number
|
||||
file_url: string
|
||||
preview_url: string
|
||||
title: string
|
||||
description: string
|
||||
type: string
|
||||
}
|
||||
|
||||
// Common request and response schemas
|
||||
namespace req {
|
||||
namespace user {
|
||||
@@ -103,6 +120,22 @@ namespace req {
|
||||
perpage?: number
|
||||
is_verify: boolean
|
||||
}
|
||||
|
||||
interface ChangePassword {
|
||||
username: string
|
||||
old_password: string
|
||||
new_password: string
|
||||
}
|
||||
|
||||
interface SmsChangePasswordVerify {
|
||||
mobile: string
|
||||
}
|
||||
|
||||
interface SmsChangePassword {
|
||||
mobile: string
|
||||
sms_code: string
|
||||
new_password: string
|
||||
}
|
||||
}
|
||||
|
||||
namespace file {
|
||||
|
||||
Reference in New Issue
Block a user