feat(front): implement text sharing functionality with new TextShareHandle and TextShareResult components

This commit is contained in:
keven1024
2025-05-20 10:39:02 +08:00
parent 838d425369
commit c1fd4e7bbd
6 changed files with 227 additions and 41 deletions

View File

@@ -1,33 +1,41 @@
<script lang="ts" setup>
import FileShareResult from '@/components/Result/FileShareResult.vue'
import TextShareResult from '@/components/Result/TextShareResult.vue'
type basehandleData = { config: any, handle_type: string }
type filehandleData = { file: File, file_id: string } & basehandleData
type texthandleData = { text: string } & basehandleData
const props = defineProps<{
data: filehandleData
data: filehandleData | texthandleData
}>()
const emit = defineEmits<{
(e: 'change', key: string): void
}>()
// console.log(props.data)
const handleList = [
{ component: FileShareResult, key: 'file-share' },
// { component: FileShareResult, key: 'file-share' },
{ component: TextShareResult, key: 'text-share' },
]
const handleComponent = computed(() => {
return handleList.find((item) => item.key === props?.data?.handle_type)?.component
})
// vue这个ts蠢的没边了本来想写component: FileShareResult | TextShareResult结果不行
</script>
<template>
<div class="">
<component :is="handleComponent" :data="data" @change="(key: string) => {
emit('change', key)
}" />
<div>
<FileShareResult
v-if="handleComponent === FileShareResult && 'file' in data"
:data="data"
@change="(key: string) => emit('change', key)"
/>
<TextShareResult
v-else-if="handleComponent === TextShareResult && 'text' in data"
:data="data"
@change="(key: string) => emit('change', key)"
/>
</div>
</template>

View File

@@ -0,0 +1,70 @@
<script setup lang="ts">
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'
import { useClipboard } from '@vueuse/core'
import { toast } from 'vue-sonner'
import { useQuery } from '@tanstack/vue-query';
const props = defineProps<{
data: { text: string, config: any, handle_type: string }
}>()
const emit = defineEmits<{
(e: 'change', key: string): void
}>()
const { data } = useQuery({
queryKey: ['create-share', props?.data?.text],
queryFn: async () => {
const { config, text } = props?.data || {}
const data = await $fetch<{
code: number
data: {
id?: string
}
}>(`/api/share`, {
method: 'POST',
body: {
type: 'text',
config,
data: text,
}
})
return data?.data
}
})
const appConfig = useAppConfig()
const url = computed(() => {
const { id } = data?.value || {}
return `${appConfig?.value?.site_url}/s/${id}`
})
const { copy } = useClipboard()
</script>
<template>
<div class="flex flex-col gap-3">
<div class="flex flex-row justify-between">
<h2 class="text-lg">分享成功</h2>
<div class="flex flex-row gap-2 basis-1/2">
<Button variant="outline" class="bg-white/70" size="icon" @click="() => {
emit('change', 'input')
}">
<LucideHome />
</Button>
<Input v-model="url" class="bg-white/70" />
<Button variant="outline" class="bg-white/70" size="icon" @click="() => {
copy(url)
toast.success('复制成功')
}">
<LucideCopy />
</Button>
<Button variant="outline" class="bg-white/70" size="icon">
<LucideQrCode />
</Button>
</div>
</div>
<div class="prose rounded-md bg-white/70 p-3 w-full max-w-full" v-html="props?.data?.text" />
</div>
</template>