|
|
|
|
@ -126,7 +126,7 @@ async function copyEntryUrl(row: PublicSourceChannelRow) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function renderQr(row: PublicSourceChannelRow, canvas: HTMLCanvasElement, size = 220) {
|
|
|
|
|
async function renderQr(row: PublicSourceChannelRow, canvas: HTMLCanvasElement, size = 440) {
|
|
|
|
|
await toCanvas(canvas, row.entry_url, {
|
|
|
|
|
width: size,
|
|
|
|
|
margin: 2,
|
|
|
|
|
@ -143,7 +143,7 @@ async function openQrDialog(row: PublicSourceChannelRow) {
|
|
|
|
|
qrDialogVisible.value = true
|
|
|
|
|
await nextTick()
|
|
|
|
|
if (qrCanvasRef.value) {
|
|
|
|
|
await renderQr(row, qrCanvasRef.value, 240)
|
|
|
|
|
await renderQr(row, qrCanvasRef.value, 480)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -162,8 +162,8 @@ function drawCenteredText(ctx: CanvasRenderingContext2D, text: string, y: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function downloadQr(row: PublicSourceChannelRow) {
|
|
|
|
|
const qrSize = 360
|
|
|
|
|
const labelHeight = 72
|
|
|
|
|
const qrSize = 720
|
|
|
|
|
const labelHeight = 144
|
|
|
|
|
const qrCanvas = document.createElement('canvas')
|
|
|
|
|
await renderQr(row, qrCanvas, qrSize)
|
|
|
|
|
|
|
|
|
|
@ -178,7 +178,7 @@ async function downloadQr(row: PublicSourceChannelRow) {
|
|
|
|
|
ctx.fillStyle = '#ffffff'
|
|
|
|
|
ctx.fillRect(0, 0, output.width, output.height)
|
|
|
|
|
ctx.drawImage(qrCanvas, 0, 0)
|
|
|
|
|
drawCenteredText(ctx, row.source_name, qrSize + labelHeight / 2 - 2, output.width)
|
|
|
|
|
drawCenteredText(ctx, `${row.source_name}专属报名二维码`, qrSize + labelHeight / 2 - 2, output.width)
|
|
|
|
|
|
|
|
|
|
const link = document.createElement('a')
|
|
|
|
|
link.download = `${row.source_code}-qrcode.png`
|
|
|
|
|
@ -186,6 +186,17 @@ async function downloadQr(row: PublicSourceChannelRow) {
|
|
|
|
|
link.click()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function downloadQrOnly(row: PublicSourceChannelRow) {
|
|
|
|
|
const qrSize = 720
|
|
|
|
|
const qrCanvas = document.createElement('canvas')
|
|
|
|
|
await renderQr(row, qrCanvas, qrSize)
|
|
|
|
|
|
|
|
|
|
const link = document.createElement('a')
|
|
|
|
|
link.download = `${row.source_code}-qrcode-only.png`
|
|
|
|
|
link.href = qrCanvas.toDataURL('image/png')
|
|
|
|
|
link.click()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatTime(value?: string): string {
|
|
|
|
|
if (!value) return '-'
|
|
|
|
|
const date = new Date(value)
|
|
|
|
|
@ -253,6 +264,9 @@ onMounted(() => {
|
|
|
|
|
{{ row.status === 'enabled' ? '停用' : '启用' }}
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button size="small" :icon="Download" @click="downloadQr(row)">下载</el-button>
|
|
|
|
|
<el-button size="small" :icon="Download" @click="downloadQrOnly(row)">
|
|
|
|
|
不含文字
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
@ -282,10 +296,10 @@ onMounted(() => {
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="qrDialogVisible" title="渠道二维码" width="380px" destroy-on-close>
|
|
|
|
|
<el-dialog v-model="qrDialogVisible" title="渠道二维码" width="640px" destroy-on-close>
|
|
|
|
|
<div v-if="qrRow" class="qr-preview">
|
|
|
|
|
<canvas ref="qrCanvasRef" width="240" height="240" />
|
|
|
|
|
<div class="qr-label">{{ qrRow.source_name }}</div>
|
|
|
|
|
<canvas ref="qrCanvasRef" width="480" height="480" />
|
|
|
|
|
<div class="qr-label">{{ qrRow.source_name }}专属报名二维码</div>
|
|
|
|
|
<div class="qr-url">{{ qrRow.entry_url }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<template #footer>
|
|
|
|
|
@ -293,6 +307,9 @@ onMounted(() => {
|
|
|
|
|
<el-button v-if="qrRow" type="primary" :icon="Download" @click="downloadQr(qrRow)">
|
|
|
|
|
下载二维码
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button v-if="qrRow" :icon="Download" @click="downloadQrOnly(qrRow)">
|
|
|
|
|
不含文字
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</section>
|
|
|
|
|
@ -359,13 +376,13 @@ onMounted(() => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.qr-preview canvas {
|
|
|
|
|
width: 240px;
|
|
|
|
|
height: 240px;
|
|
|
|
|
width: 480px;
|
|
|
|
|
height: 480px;
|
|
|
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.qr-label {
|
|
|
|
|
max-width: 300px;
|
|
|
|
|
max-width: 560px;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
font-weight: 650;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
@ -374,10 +391,17 @@ onMounted(() => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.qr-url {
|
|
|
|
|
max-width: 300px;
|
|
|
|
|
max-width: 560px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 700px) {
|
|
|
|
|
.qr-preview canvas {
|
|
|
|
|
width: min(480px, calc(100vw - 80px));
|
|
|
|
|
height: min(480px, calc(100vw - 80px));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 760px) {
|
|
|
|
|
.source-toolbar {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|