2023-09-07 21:52:53 +08:00

158 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="export-pptx-dialog">
<div class="configs">
<div class="row">
<div class="title">导出范围</div>
<RadioGroup
class="config-item"
v-model:value="rangeType"
>
<RadioButton style="width: 33.33%;" value="all">全部</RadioButton>
<RadioButton style="width: 33.33%;" value="current">当前页</RadioButton>
<RadioButton style="width: 33.33%;" value="custom">自定义</RadioButton>
</RadioGroup>
</div>
<div class="row" v-if="rangeType === 'custom'">
<div class="title" :data-range="`${range[0]} ~ ${range[1]}`">自定义范围</div>
<Slider
class="config-item"
range
:min="1"
:max="slides.length"
:step="1"
v-model:value="range"
/>
</div>
<div class="row">
<div class="title">忽略音频/视频</div>
<div class="config-item">
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.1" title="导出时默认忽略音视频若您的幻灯片中存在音视频元素且希望将其导出到PPTX文件中可选择关闭【忽略音视频】选项但要注意这将会大幅增加导出用时。">
<Switch v-model:checked="ignoreMedia" />
</Tooltip>
</div>
</div>
<div class="row">
<div class="title">覆盖默认母版</div>
<div class="config-item">
<Switch v-model:checked="masterOverwrite" />
</div>
</div>
<div class="tip" v-if="!ignoreMedia">
提示
1. 支持导出的视频格式avimp4m4vmovwmv
2. 支持导出的音频格式mp3m4amp4wavwma
3. 跨域资源无法导出
</div>
</div>
<div class="btns">
<Button class="btn export" type="primary" @click="exportPPTX(selectedSlides, masterOverwrite, ignoreMedia)">导出 PPTX</Button>
<Button class="btn close" @click="emit('close')">关闭</Button>
</div>
<FullscreenSpin :loading="exporting" tip="正在导出..." />
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import useExport from '@/hooks/useExport'
import FullscreenSpin from '@/components/FullscreenSpin.vue'
import {
Tooltip,
Button,
Slider,
Switch,
Radio,
} from 'ant-design-vue'
const { Group: RadioGroup, Button: RadioButton } = Radio
const emit = defineEmits<{
(event: 'close'): void
}>()
const { slides, currentSlide } = storeToRefs(useSlidesStore())
const { exportPPTX, exporting } = useExport()
const rangeType = ref<'all' | 'current' | 'custom'>('all')
const range = ref<[number, number]>([1, slides.value.length])
const masterOverwrite = ref(true)
const ignoreMedia = ref(true)
const selectedSlides = computed(() => {
if (rangeType.value === 'all') return slides.value
if (rangeType.value === 'current') return [currentSlide.value]
return slides.value.filter((item, index) => {
const [min, max] = range.value
return index >= min - 1 && index <= max - 1
})
})
</script>
<style lang="scss" scoped>
.export-pptx-dialog {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
overflow: hidden;
}
.configs {
width: 350px;
height: calc(100% - 100px);
display: flex;
flex-direction: column;
justify-content: center;
.row {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 25px;
}
.title {
width: 100px;
position: relative;
line-height: 1;
&::after {
content: attr(data-range);
position: absolute;
top: 20px;
left: 0;
}
}
.config-item {
flex: 1;
}
.tip {
font-size: 12px;
color: #aaa;
line-height: 1.8;
margin-top: 20px;
}
}
.btns {
width: 300px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
.export {
flex: 1;
}
.close {
width: 100px;
margin-left: 10px;
}
}
</style>