diff --git a/src/components/QrcodeActionCard/index.vue b/src/components/QrcodeActionCard/index.vue
index 016d0a33..ca74d771 100644
--- a/src/components/QrcodeActionCard/index.vue
+++ b/src/components/QrcodeActionCard/index.vue
@@ -9,18 +9,24 @@
class="qrcode-action-card__img"
>
- {{ emptyText }}
+ {{ errorText || emptyText }}
{{ emptyText }}
-
-
+
+
-
+
-
+
@@ -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 {
diff --git a/src/views/erp/component/product/ProductForm.vue b/src/views/erp/component/product/ProductForm.vue
index ae9e14d3..8125056b 100644
--- a/src/views/erp/component/product/ProductForm.vue
+++ b/src/views/erp/component/product/ProductForm.vue
@@ -101,42 +101,20 @@
-
+
@@ -155,7 +133,7 @@
-
+
diff --git a/src/views/erp/mold/components/MoldForm.vue b/src/views/erp/mold/components/MoldForm.vue
index c48bd250..72c6d109 100644
--- a/src/views/erp/mold/components/MoldForm.vue
+++ b/src/views/erp/mold/components/MoldForm.vue
@@ -85,38 +85,20 @@
-
+
@@ -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([]) // 产品单位列表
const { t } = useI18n() // 国际化
@@ -165,7 +147,6 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
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()
}
-
+
diff --git a/src/views/mes/criticalComponent/CriticalComponentForm.vue b/src/views/mes/criticalComponent/CriticalComponentForm.vue
index 4b0efa05..2d1e3202 100644
--- a/src/views/mes/criticalComponent/CriticalComponentForm.vue
+++ b/src/views/mes/criticalComponent/CriticalComponentForm.vue
@@ -46,38 +46,20 @@
/>
-
-
-
- {{ t('EquipmentManagement.EquipmentKeyItems.qrcodeLoadError') }}
-
-
-
{{ t('EquipmentManagement.EquipmentKeyItems.qrcodeEmpty') }}
-
-
-
-
-
-
-
-
-
+
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>({
@@ -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 () => {
}
}
-
+
diff --git a/src/views/mes/deviceledger/index.vue b/src/views/mes/deviceledger/index.vue
index 0cd54439..4ff0c86a 100644
--- a/src/views/mes/deviceledger/index.vue
+++ b/src/views/mes/deviceledger/index.vue
@@ -156,21 +156,19 @@ link type="danger" @click="handleDelete(scope.row.id)"
-
-
-
-
- {{ t('EquipmentManagement.EquipmentLedger.qrcodeLoadError') }}
-
-
+
+
-
@@ -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;
}