feat:设备台账、模具台账、备件、设备关键件模块二维码统一调用组件

pull/1/head
黄伟杰 2 months ago
parent 7baec6c279
commit a5ba206e72

@ -9,18 +9,24 @@
class="qrcode-action-card__img"
>
<template #error>
<div class="qrcode-action-card__error">{{ emptyText }}</div>
<div class="qrcode-action-card__error">{{ errorText || emptyText }}</div>
</template>
</el-image>
<div v-else class="qrcode-action-card__error">{{ emptyText }}</div>
<div class="qrcode-action-card__mask">
<el-button circle :disabled="!imageUrl" @click="handlePreview">
<div v-if="showActionMask" class="qrcode-action-card__mask">
<el-button v-if="showPreview" circle :disabled="!imageUrl" @click="handlePreview">
<Icon icon="ep:zoom-in" />
</el-button>
<el-button circle :disabled="!imageUrl || printDisabled" @click="handlePrint">
<el-button v-if="showPrint" circle :disabled="!imageUrl || printDisabled" @click="handlePrint">
<Icon icon="ep:printer" />
</el-button>
<el-button circle :loading="refreshLoading" :disabled="refreshDisabled || refreshLoading" @click="handleRefresh">
<el-button
v-if="showRefresh"
circle
:loading="refreshLoading"
:disabled="refreshDisabled || refreshLoading"
@click="handleRefresh"
>
<Icon icon="ep:refresh" />
</el-button>
</div>
@ -48,6 +54,15 @@ const props = withDefaults(
refreshDisabled?: boolean
printDisabled?: boolean
refreshConfirmText?: string
errorText?: string
showPreview?: boolean
showPrint?: boolean
showRefresh?: boolean
printAdaptive?: boolean
printPaperWidth?: number
printPaperHeight?: number
printMaxWidth?: number
printMaxHeight?: number
}>(),
{
imageUrl: '',
@ -58,7 +73,16 @@ const props = withDefaults(
refreshMethod: 'post',
refreshDisabled: false,
printDisabled: false,
refreshConfirmText: ''
refreshConfirmText: '',
errorText: '',
showPreview: true,
showPrint: true,
showRefresh: true,
printAdaptive: true,
printPaperWidth: 80,
printPaperHeight: 80,
printMaxWidth: 180,
printMaxHeight: 120
}
)
@ -69,13 +93,21 @@ const emit = defineEmits<{
const hiprintPreviewDialogRef = ref()
const refreshLoading = ref(false)
const buildQrcodeTemplateJson = (qrcodeUrl: string, printId: string | number) => ({
const showActionMask = computed(() => props.showPreview || props.showPrint || props.showRefresh)
const buildQrcodeTemplateJson = (
qrcodeUrl: string,
printId: string,
imageWidth: number,
imageHeight: number,
paperHeight: number
) => ({
panels: [
{
index: 0,
name: 1,
width: 80,
height: 80,
width: imageWidth,
height: paperHeight,
paperHeader: 0,
paperFooter: 0,
printElements: [
@ -83,8 +115,8 @@ const buildQrcodeTemplateJson = (qrcodeUrl: string, printId: string | number) =>
options: {
left: 0,
top: 0,
width: 100,
height: 100,
width: imageWidth,
height: imageHeight,
src: qrcodeUrl,
field: 'qrcodeUrl',
title: '二维码图片',
@ -95,12 +127,12 @@ const buildQrcodeTemplateJson = (qrcodeUrl: string, printId: string | number) =>
type: 'image'
}
},
{
{
options: {
left: 20,
top: 100,
height: 8,
width: 60,
left: 0,
top: imageHeight + 2,
height: 10,
width: imageWidth,
testData: printId,
title: 'ID',
field: 'printId',
@ -121,6 +153,47 @@ const buildQrcodeTemplateJson = (qrcodeUrl: string, printId: string | number) =>
]
})
const getImageSize = (src: string) =>
new Promise<{ width: number; height: number }>((resolve, reject) => {
const img = new Image()
img.onload = () => {
const width = img.naturalWidth || img.width
const height = img.naturalHeight || img.height
if (!width || !height) {
reject(new Error('invalid image size'))
return
}
resolve({ width, height })
}
img.onerror = () => reject(new Error('image load failed'))
img.src = src
})
const resolvePrintSize = async (src: string) => {
const fallbackWidth = Math.max(20, Number(props.printPaperWidth) || 80)
const fallbackHeight = Math.max(20, Number(props.printPaperHeight) || 80)
if (!props.printAdaptive) {
return { width: fallbackWidth, height: fallbackHeight }
}
try {
const size = await getImageSize(src)
const ratio = size.width / size.height
if (!Number.isFinite(ratio) || ratio <= 0) {
return { width: fallbackWidth, height: fallbackHeight }
}
if (ratio >= 1) {
const height = fallbackHeight
const width = Math.min(Math.max(fallbackWidth, Math.round(height * ratio)), Number(props.printMaxWidth) || 180)
return { width, height }
}
const width = fallbackWidth
const height = Math.min(Math.max(fallbackHeight, Math.round(width / ratio)), Number(props.printMaxHeight) || 120)
return { width, height }
} catch {
return { width: fallbackWidth, height: fallbackHeight }
}
}
const handlePreview = () => {
if (!props.imageUrl) return
createImageViewer({
@ -129,25 +202,31 @@ const handlePreview = () => {
})
}
const handlePrint = () => {
if (!props.imageUrl) return
const handlePrint = async () => {
if (!props.imageUrl || !props.showPrint) return
const printSize = await resolvePrintSize(props.imageUrl)
const imageWidth = printSize.width
const imageHeight = printSize.height
const printId = props.printId === undefined || props.printId === null ? '' : String(props.printId)
const idAreaHeight = printId ? 14 : 0
const paperHeight = imageHeight + idAreaHeight
hiprintPreviewDialogRef.value?.open({
title: props.printTitle,
printData: {
qrcodeUrl: props.imageUrl,
printId: props.printId ? String(props.printId) : ''
printId
},
templateJson: buildQrcodeTemplateJson(props.imageUrl,props.printId),
templateJson: buildQrcodeTemplateJson(props.imageUrl, printId, imageWidth, imageHeight, paperHeight),
withDefaultQrcodeLayout: false,
paperSize: {
width: 80,
height: 80
width: imageWidth,
height: paperHeight
}
})
}
const handleRefresh = async () => {
if (!props.refreshUrl || props.refreshDisabled) return
if (!props.refreshUrl || props.refreshDisabled || !props.showRefresh) return
try {
await message.confirm(props.refreshConfirmText || '确认刷新二维码吗?')
} catch {

@ -101,42 +101,20 @@
</el-col>
<el-col v-if="formType === 'update'" :span="24">
<el-form-item :label="t('SparePartsManagement.SpareInfo.qrcode')" prop="qrcodeUrl">
<div class="product-form-qrcode-wrap">
<el-image
v-if="formData.qrcodeUrl"
:src="formData.qrcodeUrl"
:preview-src-list="[formData.qrcodeUrl]"
preview-teleported
fit="cover"
class="product-form-qrcode-img"
>
<template #error>
<div class="product-form-qrcode-error">
{{ t('SparePartsManagement.SpareInfo.qrcodeLoadError') }}
</div>
</template>
</el-image>
<div v-else class="product-form-qrcode-error">
{{ t('SparePartsManagement.SpareInfo.qrcodeEmpty') }}
</div>
<div class="product-form-qrcode-mask">
<el-button
circle
:disabled="!formData.qrcodeUrl"
@click="handlePreviewQrcode"
>
<Icon icon="ep:zoom-in" />
</el-button>
<el-button
circle
:loading="regenerateCodeLoading"
:disabled="regenerateCodeLoading"
@click="handleRegenerateCode"
>
<Icon icon="ep:refresh" />
</el-button>
</div>
</div>
<QrcodeActionCard
:image-url="formData.qrcodeUrl"
:print-id="formData.id"
:print-title="`${formData.name || '备件'}码打印预览`"
:print-paper-width="80"
:print-paper-height="80"
:print-max-width="220"
:empty-text="t('SparePartsManagement.SpareInfo.qrcodeEmpty')"
:error-text="t('SparePartsManagement.SpareInfo.qrcodeLoadError')"
:refresh-url="getQrcodeRefreshUrl()"
:refresh-disabled="!formData.id || !formData.barCode"
refresh-confirm-text="确认刷新该备件二维码吗?"
@refresh-success="handleQrcodeRefreshSuccess"
/>
</el-form-item>
</el-col>
<el-col :span="24">
@ -155,7 +133,7 @@
<script setup lang="ts">
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import { ProductUnitApi, ProductUnitVO } from '@/api/erp/product/unit'
import { createImageViewer } from '@/components/ImageViewer'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
import { CommonStatusEnum } from '@/utils/constants'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
@ -169,7 +147,6 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const regenerateCodeLoading = ref(false)
const formData = ref({
id: undefined,
name: undefined,
@ -236,30 +213,20 @@ const handleCodeAutoChange = (value: boolean) => {
formRef.value?.clearValidate('barCode')
}
const handleRegenerateCode = async () => {
if (!formData.value.id || !formData.value.barCode) return
regenerateCodeLoading.value = true
try {
const data = await ProductApi.regenerateCode(formData.value.id, formData.value.barCode)
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
} else {
const productData = await ProductApi.getProduct(formData.value.id)
formData.value.qrcodeUrl = productData?.qrcodeUrl
formData.value.barCode = productData?.barCode ?? formData.value.barCode
}
message.success(t('common.updateSuccess'))
} finally {
regenerateCodeLoading.value = false
}
const getQrcodeRefreshUrl = () => {
if (!formData.value.id || !formData.value.barCode) return ''
return `/erp/product/regenerate-code?id=${formData.value.id}&code=${encodeURIComponent(String(formData.value.barCode))}`
}
const handlePreviewQrcode = () => {
if (!formData.value.qrcodeUrl) return
createImageViewer({
zIndex: 9999999,
urlList: [formData.value.qrcodeUrl]
})
const handleQrcodeRefreshSuccess = async (data: any) => {
if (!formData.value.id) return
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
return
}
const productData = await ProductApi.getProduct(formData.value.id)
formData.value.qrcodeUrl = productData?.qrcodeUrl
formData.value.barCode = productData?.barCode ?? formData.value.barCode
}
/** 提交表单 */
@ -309,48 +276,4 @@ const resetForm = () => {
formRef.value?.resetFields()
}
</script>
<style scoped lang="scss">
.product-form-qrcode-wrap {
position: relative;
height: 150px;
width: fit-content;
min-width: 150px;
border-radius: 10px;
overflow: hidden;
border: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-blank);
}
.product-form-qrcode-img {
height: 150px;
width: auto;
display: block;
}
.product-form-qrcode-error {
height: 150px;
min-width: 150px;
display: flex;
align-items: center;
justify-content: center;
color: var(--el-text-color-secondary);
font-size: 12px;
padding: 0 12px;
}
.product-form-qrcode-mask {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
background: rgba(0, 0, 0, 0.35);
opacity: 0;
transition: opacity 0.2s ease;
}
.product-form-qrcode-wrap:hover .product-form-qrcode-mask {
opacity: 1;
}
</style>
<style scoped lang="scss"></style>

@ -85,38 +85,20 @@
</el-radio-group>
</el-form-item>
<el-form-item v-if="formType === 'update'" :label="t('MoldManagement.Mold.qrcode')" prop="qrcodeUrl">
<div class="mold-form-qrcode-wrap">
<el-image
v-if="formData.qrcodeUrl"
:src="formData.qrcodeUrl"
:preview-src-list="[formData.qrcodeUrl]"
preview-teleported
fit="cover"
class="mold-form-qrcode-img"
>
<template #error>
<div class="mold-form-qrcode-error">{{ t('MoldManagement.Mold.qrcodeLoadError') }}</div>
</template>
</el-image>
<div v-else class="mold-form-qrcode-error">{{ t('MoldManagement.Mold.qrcodeEmpty') }}</div>
<div class="mold-form-qrcode-mask">
<el-button
circle
:disabled="!formData.qrcodeUrl"
@click="handlePreviewQrcode"
>
<Icon icon="ep:zoom-in" />
</el-button>
<el-button
circle
:loading="regenerateCodeLoading"
:disabled="regenerateCodeLoading"
@click="handleRegenerateCode"
>
<Icon icon="ep:refresh" />
</el-button>
</div>
</div>
<QrcodeActionCard
:image-url="formData.qrcodeUrl"
:print-id="formData.id"
:print-title="`${formData.name || '模具'}码打印预览`"
:print-paper-width="80"
:print-paper-height="80"
:print-max-width="220"
:empty-text="t('MoldManagement.Mold.qrcodeEmpty')"
:error-text="t('MoldManagement.Mold.qrcodeLoadError')"
:refresh-url="getQrcodeRefreshUrl()"
:refresh-disabled="!formData.id || !formData.code"
refresh-confirm-text="确认刷新该模具二维码吗?"
@refresh-success="handleQrcodeRefreshSuccess"
/>
</el-form-item>
<el-form-item :label="t('MoldManagement.Mold.images')" prop="images">
<UploadImg v-model="formData.images" />
@ -155,7 +137,7 @@
import { getIntDictOptions, DICT_TYPE, getBoolDictOptions } from '@/utils/dict'
import { MoldBrandApi } from '@/api/erp/mold'
import { ProductUnitApi, ProductUnitVO } from '@/api/erp/product/unit'
import { createImageViewer } from '@/components/ImageViewer'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
const unitList = ref<ProductUnitVO[]>([]) //
const { t } = useI18n() //
@ -165,7 +147,6 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const regenerateCodeLoading = ref(false)
const formData = ref({
id: undefined,
code: undefined,
@ -245,30 +226,20 @@ const handleCodeAutoChange = (value: boolean) => {
formRef.value?.clearValidate('code')
}
const handleRegenerateCode = async () => {
if (!formData.value.id || !formData.value.code) return
regenerateCodeLoading.value = true
try {
const data = await MoldBrandApi.regenerateCode(formData.value.id, formData.value.code)
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
} else {
const moldData = await MoldBrandApi.getMold(formData.value.id)
formData.value.qrcodeUrl = moldData?.qrcodeUrl
formData.value.code = moldData?.code ?? formData.value.code
}
message.success(t('common.updateSuccess'))
} finally {
regenerateCodeLoading.value = false
}
const getQrcodeRefreshUrl = () => {
if (!formData.value.id || !formData.value.code) return ''
return `/erp/mold-brand/regenerate-code?id=${formData.value.id}&code=${encodeURIComponent(String(formData.value.code))}`
}
const handlePreviewQrcode = () => {
if (!formData.value.qrcodeUrl) return
createImageViewer({
zIndex: 9999999,
urlList: [formData.value.qrcodeUrl]
})
const handleQrcodeRefreshSuccess = async (data: any) => {
if (!formData.value.id) return
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
return
}
const moldData = await MoldBrandApi.getMold(formData.value.id)
formData.value.qrcodeUrl = moldData?.qrcodeUrl
formData.value.code = moldData?.code ?? formData.value.code
}
/** 提交表单 */
@ -317,48 +288,4 @@ const resetForm = () => {
formRef.value?.resetFields()
}
</script>
<style scoped lang="scss">
.mold-form-qrcode-wrap {
position: relative;
height: 150px;
width: fit-content;
min-width: 150px;
border-radius: 10px;
overflow: hidden;
border: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-blank);
}
.mold-form-qrcode-img {
height: 150px;
width: auto;
display: block;
}
.mold-form-qrcode-error {
height: 150px;
min-width: 150px;
display: flex;
align-items: center;
justify-content: center;
color: var(--el-text-color-secondary);
font-size: 12px;
padding: 0 12px;
}
.mold-form-qrcode-mask {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
background: rgba(0, 0, 0, 0.35);
opacity: 0;
transition: opacity 0.2s ease;
}
.mold-form-qrcode-wrap:hover .mold-form-qrcode-mask {
opacity: 1;
}
</style>
<style scoped lang="scss"></style>

@ -46,38 +46,20 @@
/>
</el-form-item>
<el-form-item v-if="formType === 'update'" :label="t('EquipmentManagement.EquipmentKeyItems.qrcode')" prop="qrcodeUrl">
<div class="critical-component-qrcode-wrap">
<el-image
v-if="formData.qrcodeUrl"
:src="formData.qrcodeUrl"
:preview-src-list="[formData.qrcodeUrl]"
preview-teleported
fit="cover"
class="critical-component-qrcode-img"
>
<template #error>
<div class="critical-component-qrcode-error">{{ t('EquipmentManagement.EquipmentKeyItems.qrcodeLoadError') }}</div>
</template>
</el-image>
<div v-else class="critical-component-qrcode-error">{{ t('EquipmentManagement.EquipmentKeyItems.qrcodeEmpty') }}</div>
<div class="critical-component-qrcode-mask">
<el-button
circle
:disabled="!formData.qrcodeUrl"
@click="handlePreviewQrcode"
>
<Icon icon="ep:zoom-in" />
</el-button>
<el-button
circle
:loading="regenerateCodeLoading"
:disabled="regenerateCodeLoading"
@click="handleRegenerateCode"
>
<Icon icon="ep:refresh" />
</el-button>
</div>
</div>
<QrcodeActionCard
:image-url="formData.qrcodeUrl"
:print-id="formData.id"
:print-title="`${formData.name || '关键件'}码打印预览`"
:print-paper-width="80"
:print-paper-height="80"
:print-max-width="220"
:empty-text="t('EquipmentManagement.EquipmentKeyItems.qrcodeEmpty')"
:error-text="t('EquipmentManagement.EquipmentKeyItems.qrcodeLoadError')"
:refresh-url="getQrcodeRefreshUrl()"
:refresh-disabled="!formData.id || !formData.code"
refresh-confirm-text="确认刷新该关键件二维码吗?"
@refresh-success="handleQrcodeRefreshSuccess"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.remark')" prop="remark">
<el-input
@ -97,7 +79,7 @@
<script setup lang="ts">
import { CriticalComponentApi, CriticalComponentVO } from '@/api/mes/criticalComponent'
import { createImageViewer } from '@/components/ImageViewer'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
defineOptions({ name: 'CriticalComponentForm' })
@ -108,7 +90,6 @@ const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref<'create' | 'update'>('create')
const regenerateCodeLoading = ref(false)
const formRef = ref()
const formData = ref<Partial<CriticalComponentVO>>({
@ -160,30 +141,20 @@ const handleCodeAutoChange = (value: boolean) => {
formRef.value?.clearValidate('code')
}
const handleRegenerateCode = async () => {
if (!formData.value.id || !formData.value.code) return
regenerateCodeLoading.value = true
try {
const data = await CriticalComponentApi.regenerateCode(formData.value.id, formData.value.code)
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
} else {
const detail = await CriticalComponentApi.getCriticalComponent(formData.value.id)
formData.value.qrcodeUrl = detail?.qrcodeUrl
formData.value.code = detail?.code ?? formData.value.code
}
message.success(t('common.updateSuccess'))
} finally {
regenerateCodeLoading.value = false
}
const getQrcodeRefreshUrl = () => {
if (!formData.value.id || !formData.value.code) return ''
return `/mes/critical-component/regenerate-code?id=${formData.value.id}&code=${encodeURIComponent(String(formData.value.code))}`
}
const handlePreviewQrcode = () => {
if (!formData.value.qrcodeUrl) return
createImageViewer({
zIndex: 9999999,
urlList: [formData.value.qrcodeUrl]
})
const handleQrcodeRefreshSuccess = async (data: any) => {
if (!formData.value.id) return
if (data?.qrcodeUrl) {
formData.value.qrcodeUrl = data.qrcodeUrl
return
}
const detail = await CriticalComponentApi.getCriticalComponent(formData.value.id)
formData.value.qrcodeUrl = detail?.qrcodeUrl
formData.value.code = detail?.code ?? formData.value.code
}
const open = async (type: 'create' | 'update', id?: number) => {
@ -233,48 +204,4 @@ const submitForm = async () => {
}
}
</script>
<style scoped lang="scss">
.critical-component-qrcode-wrap {
position: relative;
height: 150px;
width: fit-content;
min-width: 150px;
border-radius: 10px;
overflow: hidden;
border: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-blank);
}
.critical-component-qrcode-img {
height: 150px;
width: auto;
display: block;
}
.critical-component-qrcode-error {
height: 150px;
min-width: 150px;
display: flex;
align-items: center;
justify-content: center;
color: var(--el-text-color-secondary);
font-size: 12px;
padding: 0 12px;
}
.critical-component-qrcode-mask {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
background: rgba(0, 0, 0, 0.35);
opacity: 0;
transition: opacity 0.2s ease;
}
.critical-component-qrcode-wrap:hover .critical-component-qrcode-mask {
opacity: 1;
}
</style>
<style scoped lang="scss"></style>

@ -156,21 +156,19 @@ link type="danger" @click="handleDelete(scope.row.id)"
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.updateTime')" align="center" prop="updateTime" :formatter="dateFormatter" width="180px" sortable /> -->
</el-descriptions>
<div v-if="detailData?.qrcodeUrl" label="" :span="3">
<div class="device-ledger-detail-qrcode">
<el-image
:src="detailData.qrcodeUrl"
:preview-src-list="[detailData.qrcodeUrl]"
preview-teleported
fit="cover"
class="device-ledger-detail-qrcode-img"
>
<template #error>
<div class="device-ledger-detail-qrcode-error">{{ t('EquipmentManagement.EquipmentLedger.qrcodeLoadError') }}</div>
</template>
</el-image>
<div v-if="detailData?.qrcodeUrl" class="device-ledger-detail-qrcode">
<QrcodeActionCard
:image-url="detailData.qrcodeUrl"
:print-id="detailData.id || detailData.deviceCode"
:print-title="`${detailData.deviceName || '设备'}码打印预览`"
:print-paper-width="80"
:print-paper-height="80"
:print-max-width="220"
:empty-text="t('EquipmentManagement.EquipmentLedger.qrcodeLoadError')"
:error-text="t('EquipmentManagement.EquipmentLedger.qrcodeLoadError')"
:show-refresh="false"
/>
</div>
</div>
<el-tabs v-model="detailActiveTab" class="mt-12px">
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.checkHistory')" name="check">
<div style="margin-bottom: 16px;">
@ -452,6 +450,7 @@ import DeviceLedgerForm from './DeviceLedgerForm.vue'
import { getIntDictOptions } from '@/utils/dict'
import { isHexColor } from '@/utils/color'
import { useDictStoreWithOut } from '@/store/modules/dict'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
/** 设备类型 列表 */
defineOptions({ name: 'DeviceLedger' })
@ -1209,26 +1208,6 @@ onMounted(async () => {
}
.device-ledger-detail-qrcode {
width: fit-content;
padding: 8px;
border-radius: 10px;
border: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-blank);
}
.device-ledger-detail-qrcode-img {
width: auto;
height: 150px;
display: block;
}
.device-ledger-detail-qrcode-error {
width: 150px;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
color: var(--el-text-color-secondary);
font-size: 12px;
margin-top: 10px;
}
</style>

Loading…
Cancel
Save