This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user