فهرست منبع

feat(gameEvent): 调整参赛证生成器尺寸配置以支持高分辨率输出

- 将对话框宽度从900px调整为1100px,以适应更大的预览区域
- 更新背景图片建议尺寸从600×400px改为2948×2079px,支持高分辨率输出
- 新增实际输出尺寸常量(2948×2079px)和预览缩放比例(3倍)
- 修改预览容器尺寸从600×400px改为983×693px,保持3倍缩放比例
- 调整Logo、二维码和文字元素的尺寸计算逻辑,乘以预览缩放比例
  确保预览效果与实际输出保持一致
- 移除对动态背景图片尺寸的依赖,统一使用固定的输出尺寸配置
zhou 3 ماه پیش
والد
کامیت
dcf25f52df
1فایلهای تغییر یافته به همراه31 افزوده شده و 25 حذف شده
  1. 31 25
      src/views/system/gameEvent/components/bibViewerDialog.vue

+ 31 - 25
src/views/system/gameEvent/components/bibViewerDialog.vue

@@ -1,6 +1,6 @@
 <template>
   <!-- 生成参赛证对话框 -->
-  <el-dialog v-model="bibDialog.visible" title="生成参赛证" width="900px" append-to-body @close="handleCloseBibDialog">
+  <el-dialog v-model="bibDialog.visible" title="生成参赛证" width="1100px" append-to-body @close="handleCloseBibDialog">
     <div class="bib-generator">
       <!-- 预览面板 - 占满宽度 -->
       <div class="preview-container" ref="previewContainer">
@@ -124,7 +124,7 @@
                     {{'上传背景图片' }}
                   </el-button>
                 </el-upload>
-                <span class="upload-tip">建议尺寸:600×400px</span>
+                <span class="upload-tip">建议尺寸:2948×2079px</span>
               </div>
               <div v-if="bgImageFile" class="file-info">
                 <span class="file-name">{{ bgImageFile.name }}</span>
@@ -266,8 +266,14 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const router = useRouter();
 
 // 预览框尺寸常量(与后端保持一致)
-const PREVIEW_WIDTH = 600;
-const PREVIEW_HEIGHT = 400;
+// 实际输出尺寸
+const ACTUAL_WIDTH = 2948;
+const ACTUAL_HEIGHT = 2079;
+// 预览缩放比例
+const PREVIEW_SCALE = 3;
+// 预览尺寸(实际尺寸除以3,四舍五入)
+const PREVIEW_WIDTH = Math.round(ACTUAL_WIDTH / PREVIEW_SCALE); // 983
+const PREVIEW_HEIGHT = Math.round(ACTUAL_HEIGHT / PREVIEW_SCALE); // 693
 
 // 响应式数据定义
 const bibDialog = reactive({
@@ -599,9 +605,9 @@ const convertCoordinatesWithScale = (x: number, y: number): { x: number; y: numb
   const previewWidth = container?.clientWidth || container?.offsetWidth || PREVIEW_WIDTH;
   const previewHeight = container?.clientHeight || container?.offsetHeight || PREVIEW_HEIGHT;
 
-  // 使用实际背景图片尺寸,如果没有则使用默认尺寸(600×400px)
-  const actualWidth = bgImageDimensions.value?.width || 600;
-  const actualHeight = bgImageDimensions.value?.height || 400;
+  // 使用固定的实际输出尺寸(2948×2079px)
+  const actualWidth = ACTUAL_WIDTH;
+  const actualHeight = ACTUAL_HEIGHT;
 
   // 计算实际比例
   const scaleX = actualWidth / previewWidth;
@@ -664,9 +670,9 @@ const handleCreateTask = async () => {
     // 等待一帧确保所有尺寸都已计算完成
     await nextTick();
 
-    // 计算画布的实际尺寸(不考虑预览缩放
-    const originalWidth = bgImageDimensions.value?.width || 600;
-    const originalHeight = bgImageDimensions.value?.height || 400;
+    // 计算画布的实际尺寸(使用固定的实际输出尺寸
+    const originalWidth = ACTUAL_WIDTH;
+    const originalHeight = ACTUAL_HEIGHT;
 
     // 将百分比坐标转换为像素坐标
     const convertPercentToPixel = (percent: number, dimension: number): number => {
@@ -677,13 +683,13 @@ const handleCreateTask = async () => {
     const logoPixelX = convertPercentToPixel(bibForm.logoX || 4.17, originalWidth);
     const logoPixelY = convertPercentToPixel(bibForm.logoY || 6.25, originalHeight);
 
-    // 计算Logo尺寸(前端统一处理,避免后端重复计算
+    // 计算Logo尺寸(需要乘以缩放比例,保证与预览效果一致
     const logoOriginalWidth = logoImageDimensions.value?.width || 80;
     const logoOriginalHeight = logoImageDimensions.value?.height || 80;
     const logoPreviewSize = 80; // 前端预览时的最大尺寸
     const logoScale = Math.min(1.0, logoPreviewSize / Math.max(logoOriginalWidth, logoOriginalHeight));
-    const logoFinalWidth = Math.round(logoOriginalWidth * logoScale * bibForm.logoScale);
-    const logoFinalHeight = Math.round(logoOriginalHeight * logoScale * bibForm.logoScale);
+    const logoFinalWidth = Math.round(logoOriginalWidth * logoScale * bibForm.logoScale * PREVIEW_SCALE);
+    const logoFinalHeight = Math.round(logoOriginalHeight * logoScale * bibForm.logoScale * PREVIEW_SCALE);
 
     // 二维码像素坐标
     const validQRCodeX = (qRCodeX !== null && qRCodeX !== undefined && !isNaN(qRCodeX)) ? qRCodeX : 11.67;
@@ -691,24 +697,24 @@ const handleCreateTask = async () => {
     const qrPixelX = convertPercentToPixel(validQRCodeX, originalWidth);
     const qrPixelY = convertPercentToPixel(validQRCodeY, originalHeight);
 
-    // 计算二维码尺寸(与前端预览一致:32px * 缩放比例
+    // 计算二维码尺寸(需要乘以缩放比例,保证与预览效果一致)
     const qrInitialSize = 32;
-    const qrFinalWidth = Math.round(qrInitialSize * bibForm.barcodeScale);
-    const qrFinalHeight = Math.round(qrInitialSize * bibForm.barcodeScale);
+    const qrFinalWidth = Math.round(qrInitialSize * bibForm.barcodeScale * PREVIEW_SCALE);
+    const qrFinalHeight = Math.round(qrInitialSize * bibForm.barcodeScale * PREVIEW_SCALE);
 
     // 号码像素坐标
     const numberPixelX = convertPercentToPixel(bibForm.numberX || 50, originalWidth);
     const numberPixelY = convertPercentToPixel(bibForm.numberY || 50, originalHeight);
 
-    // 计算号码字体大小(应用缩放
-    const numberPixelFontSize = Math.round((bibForm.fontSize || 36) * bibForm.numberScale);
+    // 计算号码字体大小(需要乘以缩放比例,保证与预览效果一致
+    const numberPixelFontSize = Math.round((bibForm.fontSize || 36) * bibForm.numberScale * PREVIEW_SCALE);
 
     // 赛事名称像素坐标
     const eventPixelX = convertPercentToPixel(bibForm.eventX || 50, originalWidth);
     const eventPixelY = convertPercentToPixel(bibForm.eventY || 5, originalHeight);
 
-    // 计算赛事名称字体大小(与前端预览一致:Math.min(28, Math.max(18, fontSize * 0.7))
-    const eventPixelFontSize = Math.round((bibForm.fontSize || 36) * bibForm.eventScale);
+    // 计算赛事名称字体大小(需要乘以缩放比例,保证与预览效果一致)
+    const eventPixelFontSize = Math.round((bibForm.fontSize || 36) * bibForm.eventScale * PREVIEW_SCALE);
 
     const bibParams = {
       // 画布实际尺寸
@@ -802,12 +808,12 @@ defineExpose({
   align-items: center;    // 让内容居中
 }
 
-/* 预览容器 - 占满宽度 */
+/* 预览容器 - 固定尺寸 983x693 */
 .preview-container {
   border: 2px dashed #ddd;
   border-radius: 8px;
-  width: 600px !important;
-  height: 400px !important;
+  width: 983px !important;
+  height: 693px !important;
   position: relative;
   overflow: auto;
   display: flex;
@@ -847,8 +853,8 @@ defineExpose({
 }
 
 .preview-canvas {
-  width: 600px;
-  height: 400px;
+  width: 983px;
+  height: 693px;
   position: relative;
   background-color: #f5f5f5;
   display: flex;