移除流程中的支付相关和会员卡相关

This commit was merged in pull request #48.
This commit is contained in:
2026-07-14 18:49:15 +08:00
parent 593f6f13e7
commit cacc8997ec
22 changed files with 594 additions and 754 deletions
@@ -91,11 +91,14 @@
{{ row.currentMembers || 0 }}/{{ row.maxMembers || 0 }}
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<el-table-column label="操作" width="260" fixed="right">
<template #default="{ row }">
<el-button type="primary" link size="small" @click="handleEdit(row)">
编辑
</el-button>
<el-button type="success" link size="small" @click="showQrCode(row)">
二维码
</el-button>
<el-button
v-if="row.status === '0'"
type="warning"
@@ -210,6 +213,33 @@
<el-button type="primary" @click="handleModalOk">确定</el-button>
</template>
</el-dialog>
<!-- 签到二维码弹窗 -->
<el-dialog
v-model="qrDialogVisible"
:title="'签到二维码 - ' + currentCourseName"
width="420px"
center
>
<div class="qr-dialog-body">
<div v-loading="qrLoading" class="qr-image-wrapper">
<img
v-if="qrImageUrl"
:src="qrImageUrl"
class="qr-image"
alt="签到二维码"
/>
<el-empty v-else-if="!qrLoading" description="暂无二维码" />
</div>
<p class="qr-tip">扫码签到参加团课</p>
</div>
<template #footer>
<el-button @click="qrDialogVisible = false">关闭</el-button>
<el-button type="primary" :disabled="!qrImageUrl" @click="downloadQrCode">
下载二维码
</el-button>
</template>
</el-dialog>
</div>
</template>
@@ -395,6 +425,75 @@ const uploadCover = async (options: any) => {
const coverPreviewSrc = ref('')
// ===== 二维码弹窗相关 =====
const qrDialogVisible = ref(false)
const qrLoading = ref(false)
const qrImageUrl = ref('')
const currentCourseName = ref('')
/**
* 从 qrCodePath 中提取文件 ID
* 支持格式:/api/files/preview/{id} 或旧版 OSS URL
*/
const extractFileId = (path: string | undefined): string | null => {
if (!path) return null
// 新格式: /api/files/{id}/preview
const match = path.match(/\/files\/(\d+)\/preview/)
if (match) return match[1]
// 旧格式 OSS URL: 直接作为图片 URL 使用
if (path.startsWith('http')) return path
// 纯数字 ID
if (/^\d+$/.test(path)) return path
return null
}
/**
* 显示团课签到二维码
*/
const showQrCode = async (row: GroupCourse) => {
currentCourseName.value = row.courseName
qrDialogVisible.value = true
qrLoading.value = true
qrImageUrl.value = ''
const fileId = extractFileId(row.qrCodePath)
if (!fileId) {
qrLoading.value = false
return
}
try {
if (fileId.startsWith('http')) {
// 旧版 OSS URL,直接使用
qrImageUrl.value = fileId
} else {
// 新版文件 ID,通过预览接口获取
const blob: any = await request.get(`/files/${fileId}/preview`, { responseType: 'blob' })
// 释放旧 URL
if (qrImageUrl.value) URL.revokeObjectURL(qrImageUrl.value)
qrImageUrl.value = URL.createObjectURL(blob)
}
} catch {
ElMessage.error('获取二维码失败')
} finally {
qrLoading.value = false
}
}
/**
* 下载二维码图片
*/
const downloadQrCode = () => {
if (!qrImageUrl.value) return
const a = document.createElement('a')
a.href = qrImageUrl.value
a.download = `签到二维码_${currentCourseName.value}.png`
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
ElMessage.success('二维码下载成功')
}
const loadCoverPreview = async (val: string) => {
if (!val) {
coverPreviewSrc.value = ''
@@ -576,4 +675,36 @@ onMounted(() => {
color: #c0c4cc;
font-size: 12px;
}
/* 二维码弹窗样式 */
.qr-dialog-body {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px 0;
}
.qr-image-wrapper {
width: 260px;
height: 260px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #ebeef5;
border-radius: 8px;
background: #fafafa;
overflow: hidden;
}
.qr-image {
width: 100%;
height: 100%;
object-fit: contain;
}
.qr-tip {
margin-top: 16px;
color: #909399;
font-size: 14px;
}
</style>