Add workflow sharing functionality (#371)

* Add workflow sharing feature with share, fork, and browse functionality

Co-authored-by: jxxghp <jxxghp@163.com>

* Refactor workflow page with dynamic tabs and internationalization support

Co-authored-by: jxxghp <jxxghp@163.com>

* Remove workflow share implementation documentation

Co-authored-by: jxxghp <jxxghp@163.com>

* Fix indentation and structure in Chinese locale files

Co-authored-by: jxxghp <jxxghp@163.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
jxxghp
2025-07-08 23:31:22 +08:00
committed by GitHub
co-authored by jxxghp Cursor Agent
parent f2bc832aca
commit 35332544e4
14 changed files with 876 additions and 27 deletions
+121
View File
@@ -0,0 +1,121 @@
<script lang="ts" setup>
import { formatDateDifference } from '@/@core/utils/formatters'
import type { WorkflowShare } from '@/api/types'
import WorkflowEditDialog from '../dialog/WorkflowAddEditDialog.vue'
import ForkWorkflowDialog from '../dialog/ForkWorkflowDialog.vue'
import { useGlobalSettingsStore } from '@/stores'
// 输入参数
const props = defineProps({
media: Object as PropType<WorkflowShare>,
})
// 定义删除事件
const emit = defineEmits(['delete'])
// 从 provide 中获取全局设置
// 全局设置
const globalSettingsStore = useGlobalSettingsStore()
const globalSettings = globalSettingsStore.globalSettings
// 工作流编辑弹窗
const workflowEditDialog = ref(false)
// 复用工作流弹窗
const forkWorkflowDialog = ref(false)
// 工作流ID
const workflowId = ref<string>()
// 分享时间
const dateText = ref(props.media && props.media?.date ? formatDateDifference(props.media.date) : '')
// 复用工作流
function showForkWorkflow() {
forkWorkflowDialog.value = true
}
// 完成复用工作流
function finishForkWorkflow(wid: string) {
workflowId.value = wid
forkWorkflowDialog.value = false
workflowEditDialog.value = true
}
// 删除工作流分享时处理
function doDelete() {
forkWorkflowDialog.value = false
// 通知父组件刷新
emit('delete')
}
</script>
<template>
<div class="h-full">
<VHover>
<template #default="hover">
<div
class="w-full h-full rounded-lg overflow-hidden"
:class="{
'transition transform-cpu duration-300 -translate-y-1': hover.isHovering,
}"
>
<VCard
v-bind="hover.props"
:key="props.media?.id"
class="flex flex-col h-full"
rounded="0"
min-height="150"
@click="showForkWorkflow"
>
<div class="h-full flex flex-col">
<VCardText class="flex items-center pa-3 pb-1 grow">
<div class="flex flex-col justify-center">
<div class="mr-2 min-w-0 text-lg font-bold line-clamp-2 overflow-hidden text-ellipsis ...">
{{ props.media?.share_title }}
</div>
<div class="text-sm font-medium text-gray-600 sm:pt-1 line-clamp-3 overflow-hidden text-ellipsis ...">
{{ props.media?.share_comment }}
</div>
</div>
</VCardText>
<VCardText class="flex justify-space-between align-center flex-wrap py-2">
<div class="flex align-center">
<IconBtn v-bind="props" icon="mdi-account" class="me-1" />
<div class="text-subtitle-2 me-4">
{{ props.media?.share_user }}
</div>
<IconBtn v-if="props.media?.count" icon="mdi-fire" class="me-1" />
<span v-if="props.media?.count" class="text-subtitle-2 me-4">
{{ props.media?.count.toLocaleString() }}
</span>
</div>
</VCardText>
<VCardText class="absolute right-0 bottom-0 d-flex align-center p-2 text-gray-500">
<VIcon icon="mdi-calendar" class="me-1" />
{{ dateText }}
</VCardText>
</div>
</VCard>
</div>
</template>
</VHover>
<!-- 工作流编辑弹窗 -->
<WorkflowEditDialog
v-if="workflowEditDialog"
v-model="workflowEditDialog"
:workflow="workflowId ? { id: workflowId } : undefined"
@close="workflowEditDialog = false"
@save="workflowEditDialog = false"
@remove="workflowEditDialog = false"
/>
<!-- 复用工作流弹窗 -->
<ForkWorkflowDialog
v-if="forkWorkflowDialog"
:media="props.media"
@close="forkWorkflowDialog = false"
@fork="finishForkWorkflow"
@delete="doDelete"
/>
</div>
</template>
+22
View File
@@ -4,6 +4,7 @@ import { useToast } from 'vue-toastification'
import { useConfirm } from '@/composables/useConfirm'
import WorkflowAddEditDialog from '@/components/dialog/WorkflowAddEditDialog.vue'
import WorkflowActionsDialog from '@/components/dialog/WorkflowActionsDialog.vue'
import WorkflowShareDialog from '@/components/dialog/WorkflowShareDialog.vue'
import api from '@/api'
import { useI18n } from 'vue-i18n'
@@ -32,6 +33,9 @@ const editDialog = ref(false)
// 流程对话框
const flowDialog = ref(false)
// 分享对话框
const shareDialog = ref(false)
// 加载中
const loading = ref(false)
@@ -45,10 +49,16 @@ function handleFlow(item: Workflow) {
flowDialog.value = true
}
// 分享工作流
function handleShare(item: Workflow) {
shareDialog.value = true
}
// 编辑完成
function editDone() {
editDialog.value = false
flowDialog.value = false
shareDialog.value = false
emit('refresh')
}
@@ -240,6 +250,12 @@ const resolveProgress = (item: Workflow) => {
</template>
<VListItemTitle>{{ t('workflow.task.reset') }}</VListItemTitle>
</VListItem>
<VListItem base-color="info" @click="handleShare(workflow)">
<template #prepend>
<VIcon icon="mdi-share" />
</template>
<VListItemTitle>{{ t('workflow.task.share') }}</VListItemTitle>
</VListItem>
<VListItem base-color="error" @click="handleDelete(workflow)">
<template #prepend>
<VIcon icon="mdi-delete" />
@@ -317,5 +333,11 @@ const resolveProgress = (item: Workflow) => {
@save="editDone"
:workflow="workflow"
/>
<!-- 分享对话框 -->
<WorkflowShareDialog
v-if="shareDialog"
:workflow="workflow"
@close="shareDialog = false"
/>
</div>
</template>