This commit is contained in:
2025-12-04 12:44:54 +08:00
parent d687bf67b1
commit 3f33e5c2f1
8 changed files with 447 additions and 99 deletions

View File

@@ -10,6 +10,15 @@
</div>
<div class="list-page-actions">
<el-button @click="$router.back()">返回</el-button>
<el-button
v-if="product?.documentation"
type="info"
@click="downloadDocumentation"
:loading="downloading"
>
<el-icon><Download /></el-icon>
{{ product?.documentation?.pdf_file_path ? '下载PDF文档' : '下载接口文档' }}
</el-button>
<el-button
v-if="!isSubscribed"
type="primary"
@@ -20,10 +29,11 @@
</el-button>
<el-button
v-else
type="success"
disabled
type="danger"
@click="handleCancelSubscription"
:loading="cancelling"
>
订阅
取消订阅
</el-button>
<el-button
v-if="isSubscribed"
@@ -260,7 +270,7 @@
<script setup>
import { productApi, subscriptionApi } from '@/api'
import { DocumentCopy } from '@element-plus/icons-vue'
import { DocumentCopy, Download } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { marked } from 'marked'
@@ -272,6 +282,8 @@ const loading = ref(false)
const product = ref(null)
const userSubscriptions = ref([])
const subscribing = ref(false)
const cancelling = ref(false)
const downloading = ref(false)
const activeTab = ref('content')
const currentTimestamp = ref('')
@@ -288,6 +300,12 @@ const isSubscribed = computed(() => {
return userSubscriptions.value.some(sub => sub.product_id === product.value.id)
})
// 获取当前产品的订阅信息
const currentSubscription = computed(() => {
if (!product.value || !userSubscriptions.value.length) return null
return userSubscriptions.value.find(sub => sub.product_id === product.value.id)
})
// 初始化
onMounted(() => {
loadUserSubscriptions()
@@ -321,7 +339,7 @@ const startTimestampUpdate = () => {
// 加载用户订阅
const loadUserSubscriptions = async () => {
try {
const response = await subscriptionApi.getMySubscriptions({ page: 1, page_size: 100 })
const response = await subscriptionApi.getMySubscriptions({ page: 1, page_size: 1000 })
userSubscriptions.value = response.data?.items || []
} catch (error) {
console.error('加载用户订阅失败:', error)
@@ -528,19 +546,53 @@ const handleSubscribe = async () => {
} catch (error) {
if (error !== 'cancel') {
console.error('订阅失败:', error)
ElMessage.error('订阅失败')
const errorMessage = error.response?.data?.message || error.message || '订阅失败'
ElMessage.error(errorMessage)
}
} finally {
subscribing.value = false
}
}
// 取消订阅
const handleCancelSubscription = async () => {
if (!product.value || !currentSubscription.value) return
try {
await ElMessageBox.confirm(
`确定要取消订阅产品"${product.value.name}"吗取消后将无法继续使用该产品的API服务。`,
'取消订阅确认',
{
confirmButtonText: '确定取消',
cancelButtonText: '我再想想',
type: 'warning'
}
)
cancelling.value = true
await subscriptionApi.cancelMySubscription(currentSubscription.value.id)
ElMessage.success('取消订阅成功')
// 重新加载用户订阅
await loadUserSubscriptions()
} catch (error) {
if (error !== 'cancel') {
console.error('取消订阅失败:', error)
const errorMessage = error.response?.data?.message || error.message || '取消订阅失败'
ElMessage.error(errorMessage)
}
} finally {
cancelling.value = false
}
}
// 前往在线调试
const goToApiDebugger = () => {
if (!product.value) return
router.push({
name: 'ApiDebugger',
params: { productId: product.value.id }
query: { productId: product.value.id }
})
}
@@ -659,6 +711,65 @@ const getDefaultErrorCodes = () => {
| 2001 | 业务失败 |`
}
// 下载接口文档
const downloadDocumentation = async () => {
if (!product.value) {
ElMessage.warning('产品信息不存在')
return
}
downloading.value = true
try {
// 根据是否有PDF文件路径判断文件类型
const hasPDF = product.value.documentation?.pdf_file_path
// 使用原生fetch以获取完整的响应信息包括headers
const token = localStorage.getItem('access_token')
const tokenType = localStorage.getItem('token_type') || 'Bearer'
const headers = {
'Authorization': token ? `${tokenType} ${token}` : ''
}
const response = await fetch(`/api/v1/products/${product.value.id}/documentation/download`, {
headers
})
if (!response.ok) {
throw new Error('下载失败')
}
// 获取Content-Type
const contentType = response.headers.get('content-type') || ''
const isPDF = contentType.includes('application/pdf') || hasPDF
// 获取文件内容
const blob = await response.blob()
// 创建下载链接
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
const extension = isPDF ? 'pdf' : 'md'
const filename = `${product.value.name || '产品'}_接口文档.${extension}`
link.download = filename
// 触发下载
document.body.appendChild(link)
link.click()
// 清理
document.body.removeChild(link)
URL.revokeObjectURL(url)
ElMessage.success('文档下载成功')
} catch (error) {
console.error('下载接口文档失败:', error)
ElMessage.error('下载接口文档失败')
} finally {
downloading.value = false
}
}
// 下载 Markdown 文档
const downloadMarkdown = (type) => {
if (!product.value?.documentation) {