diff --git a/src/components/assistant/util.ts b/src/components/assistant/util.ts
index 2c1ab63a..fa9afd0f 100644
--- a/src/components/assistant/util.ts
+++ b/src/components/assistant/util.ts
@@ -397,7 +397,9 @@ export async function generateImage(options: {
const response = await fetch('/bizyair/model/images', {
method: 'POST',
headers: {
- 'Content-Type': 'application/json'
+ 'Content-Type': 'application/json',
+ Authorization: Cookies.get('bizy_token') || '',
+ ...(options as any)?.headers
},
body: JSON.stringify({
prompt: prompt,
diff --git a/src/components/community/detail/Index.vue b/src/components/community/detail/Index.vue
index 50a6cbb3..2ff5fc84 100644
--- a/src/components/community/detail/Index.vue
+++ b/src/components/community/detail/Index.vue
@@ -58,6 +58,14 @@
const showAllTags = ref(false)
+ // 添加视频检测函数
+ const isVideoUrl = (url: string) => {
+ if (!url) return false
+ const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']
+ const lowercaseUrl = url.toLowerCase()
+ return videoExtensions.some(ext => lowercaseUrl.includes(ext))
+ }
+
const fetchModelDetail = async () => {
try {
const res = await model_detail({
@@ -821,15 +829,30 @@
class="flex flex-col gap-4 items-start justify-start relative min-w-[620px] w-[65%] overflow-hidden"
>
-
-
-
+
- import { Model } from '@/types/model'
+ // import { Model } from '@/types/model'
import vDefaultPic from '@/components/modules/vDefaultPic.vue'
import vTooltips from '@/components/modules/v-tooltip.vue'
import { sliceString, formatNumber } from '@/utils/tool'
@@ -18,24 +18,16 @@
const showDialog = ref(false)
const imgSrc = ref('')
const tagsStore = useDictStore()
- const props = defineProps({
- model: {
- type: Object as () => Model | null,
- default: null
- },
- loading: {
- type: Boolean,
- default: false
- },
- imageLoaded: {
- type: Boolean,
- default: false
- }
- })
+ const props = defineProps<{
+ model?: any
+ imageLoaded?: boolean
+ loading?: boolean
+ }>()
const emit = defineEmits(['action', 'image-load', 'image-error'])
- // 计算工作流或节点的提示文本
+ const isHovering = ref(false)
+
const actionTooltipText = computed(() => {
return props.model?.type === 'Workflow'
? t('community.modelCard.tooltips.loadWorkflow')
@@ -94,6 +86,41 @@
imgSrc.value = url.includes('?') ? `${url}&t=${timestamp}` : `${url}?t=${timestamp}`
}
})
+
+ const isVideo = computed(() => {
+ if (!imgSrc.value) return false
+ const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']
+ const url = imgSrc.value.toLowerCase()
+ return videoExtensions.some(ext => url.includes(ext))
+ })
+
+ const getVideoThumbnail = (videoUrl: string) => {
+ if (videoUrl.includes('x-oss-process=video/snapshot')) {
+ return videoUrl
+ }
+ const separator = videoUrl.includes('?') ? '&' : '?'
+ return `${videoUrl}${separator}x-oss-process=video/snapshot,t_0000,f_jpg,w_300,h_600`
+ }
+
+ const currentMediaSrc = computed(() => {
+ if (!imgSrc.value) return ''
+ if (isVideo.value) {
+ return isHovering.value ? imgSrc.value : getVideoThumbnail(imgSrc.value)
+ }
+ return imgSrc.value
+ })
+
+ const handleMouseEnter = () => {
+ if (isVideo.value) {
+ isHovering.value = true
+ }
+ }
+
+ const handleMouseLeave = () => {
+ if (isVideo.value) {
+ isHovering.value = false
+ }
+ }
@@ -139,17 +166,39 @@
+
+
+
+
![]()
+
diff --git a/src/components/model-select/detail/Index.vue b/src/components/model-select/detail/Index.vue
index 4ae70140..a24db2aa 100644
--- a/src/components/model-select/detail/Index.vue
+++ b/src/components/model-select/detail/Index.vue
@@ -46,6 +46,15 @@
const isLoading = ref(false)
const activeTab = ref
()
const showAllTags = ref(false)
+
+ // 添加视频检测函数
+ const isVideoUrl = (url: string) => {
+ if (!url) return false
+ const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']
+ const lowercaseUrl = url.toLowerCase()
+ return videoExtensions.some(ext => lowercaseUrl.includes(ext))
+ }
+
const fetchModelDetail = async () => {
try {
const res = await model_detail({
@@ -688,15 +697,30 @@
class="flex flex-col gap-4 items-start justify-start relative min-w-[620px] w-[65%] overflow-hidden"
>
-
-
-
+
{{ t('community.detail.baseModel') }}
-
+
{{ currentVersion?.base_model }}
diff --git a/src/components/model-select/modules/ModelCard.vue b/src/components/model-select/modules/ModelCard.vue
index 7d5f9248..a0408942 100644
--- a/src/components/model-select/modules/ModelCard.vue
+++ b/src/components/model-select/modules/ModelCard.vue
@@ -6,7 +6,7 @@
import { sliceString, formatNumber } from '@/utils/tool'
import { useModelSelectStore } from '@/stores/modelSelectStore'
- import { ref, watch, onMounted } from 'vue'
+ import { ref, watch, onMounted, computed } from 'vue'
import { useDictStore } from '@/stores/dictStore'
const { t } = useI18n()
@@ -18,13 +18,13 @@
const modelSelectStore = useModelSelectStore()
const imgSrc = ref('')
const tagsStore = useDictStore()
+ const isHovering = ref(false)
const props = defineProps({
model: {
type: Object as () => Model | null,
default: null
},
-
loading: {
type: Boolean,
default: false
@@ -37,6 +37,48 @@
const emit = defineEmits(['action', 'image-load', 'image-error'])
+ // 添加计算属性判断是否为视频
+ const isVideo = computed(() => {
+ if (!imgSrc.value) return false
+ const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']
+ const url = imgSrc.value.toLowerCase()
+ return videoExtensions.some(ext => url.includes(ext))
+ })
+
+ // 生成视频缩略图URL
+ const getVideoThumbnail = (videoUrl: string) => {
+ // 如果URL已经包含OSS处理参数,直接返回
+ if (videoUrl.includes('x-oss-process=video/snapshot')) {
+ return videoUrl
+ }
+ // 添加OSS视频截图处理参数
+ const separator = videoUrl.includes('?') ? '&' : '?'
+ return `${videoUrl}${separator}x-oss-process=video/snapshot,t_000,f_jpg,w_300,h_600`
+ }
+
+ // 当前显示的媒体源
+ const currentMediaSrc = computed(() => {
+ if (!imgSrc.value) return ''
+ if (isVideo.value) {
+ // 如果是视频且鼠标悬停,返回视频URL,否则返回缩略图
+ return isHovering.value ? imgSrc.value : getVideoThumbnail(imgSrc.value)
+ }
+ return imgSrc.value
+ })
+
+ // 鼠标悬停处理
+ const handleMouseEnter = () => {
+ if (isVideo.value) {
+ isHovering.value = true
+ }
+ }
+
+ const handleMouseLeave = () => {
+ if (isVideo.value) {
+ isHovering.value = false
+ }
+ }
+
const handleImageLoad = (e: Event) => {
emit('image-load', e)
}
@@ -114,17 +156,40 @@
+
+
+
+
+
![]()
+
diff --git a/src/components/modules/vUpload/vUploadImage.vue b/src/components/modules/vUpload/vUploadImage.vue
index 2840671a..9661ab61 100644
--- a/src/components/modules/vUpload/vUploadImage.vue
+++ b/src/components/modules/vUpload/vUploadImage.vue
@@ -1,5 +1,5 @@
@@ -63,21 +106,38 @@
class="cursor-pointer opacity-0 w-full h-full absolute left-0 top-0 z-20"
type="file"
@change="handleFileChange"
- accept="image/*"
+ accept="image/*,video/*"
+ />
+
+
+
+
+
-
-
+
+
+
+
diff --git a/src/locales/en.json b/src/locales/en.json
index d6948495..827a74d2 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -350,7 +350,7 @@
"modalTitle": "Tips",
"uploadButton": "Upload",
"cancelButton": "Cancel",
- "uploadImage": "Upload Image",
+ "uploadImage": "Upload Image or Video",
"loading": "Loading",
"foundUnfinishedUpload": "Found unfinished upload, resuming...",
"noResumeData": "No resumable upload data found",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index 2b7a1863..64b0d407 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -350,7 +350,7 @@
"modalTitle": "提示",
"uploadButton": "上传",
"cancelButton": "取消",
- "uploadImage": "上传封面",
+ "uploadImage": "上传图片或视频",
"loading": "加载中",
"foundUnfinishedUpload": "发现未完成的上传任务,将从断点处继续",
"noResumeData": "无法找到断点续传数据",
diff --git a/version.txt b/version.txt
index fd9d1a5a..1fc5b820 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.2.14
+1.2.15