|
|
<template> <div class="paper-selector" :class="{ 'horizontal-mode': horizontalMode }"> <!-- 垂直模式的标题 --> <div v-if="!horizontalMode" class="selector-header"> <h4>纸张设置</h4> <el-tooltip content="选择合适的纸张尺寸以获得最佳设计效果" placement="top"> <i class="el-icon-info"></i> </el-tooltip> </div>
<!-- 纸张类型选择 --> <div class="paper-type-select"> <el-select :value="normalizedSelectedPaper" @change="handlePaperChange" placeholder="选择纸张类型" size="small" :loading="loading" :style="horizontalMode ? 'width: 120px;' : 'width: 100%;'" filterable > <el-option v-for="option in paperOptions" :key="option.value" :label="option.label" :value="option.value" > <span style="float: left">{{ option.label }}</span> <span v-if="!horizontalMode" style="float: right; color: #8492a6; font-size: 12px"> {{ option.description }} </span> </el-option> </el-select> </div> </div></template>
<script>import { getPaperOptions, getCanvasSize, PAPER_SIZES } from '@/utils/paperConfig.js'import dynamicPaperConfig from '@/utils/paperConfigDynamic.js'
export default { name: 'PaperSelector', props: { selectedPaper: { type: [String, Number], // 支持字符串(旧格式)和数字(新的纸张ID)
default: null }, orientation: { type: String, default: 'portrait' }, customSize: { type: Object, default: () => ({ width: 600, height: 400 }) }, horizontalMode: { type: Boolean, default: false } }, emits: ['paper-change', 'custom-size-change'], data() { return { dynamicPapers: [], // 动态纸张列表
loading: false, defaultPaperId: null // 默认纸张ID
} }, async created() { await this.loadPapers() }, watch: { orientation: { handler(newVal, oldVal) { if (newVal !== oldVal) { // 方向改变时,给用户一个视觉反馈
this.$nextTick(() => { const orientationText = newVal === 'portrait' ? '纵向' : '横向' console.log(`打印方向已切换为: ${orientationText}`, { orientation: newVal, currentSize: this.currentSize }) }) } }, immediate: false } }, computed: { paperOptions() { return this.dynamicPapers.map(paper => ({ value: paper.id, label: paper.name, description: `${paper.widthMm}×${paper.heightMm}mm`, paper: paper })) }, // 确保选中的纸张ID是正确的类型
normalizedSelectedPaper() { if (this.selectedPaper === null || this.selectedPaper === undefined) { return null } // 如果是字符串类型的数字,转换为数字
if (typeof this.selectedPaper === 'string' && /^\d+$/.test(this.selectedPaper)) { return parseInt(this.selectedPaper, 10) } return this.selectedPaper },
orientationText() { return this.orientation === 'portrait' ? '纵向' : '横向' }, quickSizes() { // 从动态纸张中选择常用尺寸
return this.dynamicPapers.slice(0, 8).map(paper => ({ value: paper.id, label: paper.name.replace('英寸', '').replace('×', '×') })) }, // 方向图标
orientationIcon() { return this.orientation === 'portrait' ? 'el-icon-mobile-phone' : 'el-icon-monitor' }, }, methods: { // 加载纸张数据
async loadPapers() { try { this.loading = true await dynamicPaperConfig.loadPapers() this.dynamicPapers = dynamicPaperConfig.getActivePapers()
// 设置默认纸张ID
if (this.dynamicPapers.length > 0 && !this.defaultPaperId) { // 优先选择4×2英寸作为默认纸张
const defaultPaper = this.dynamicPapers.find(p => p.name.includes('4×2')) || this.dynamicPapers[0] this.defaultPaperId = defaultPaper.id }
console.log('纸张选择器加载完成:', this.dynamicPapers.length, '个纸张') } catch (error) { console.error('加载纸张数据失败:', error) this.$message.error('加载纸张数据失败') } finally { this.loading = false } },
handlePaperChange(paperId) { localStorage.setItem('paperId',paperId); this.$emit('paper-change', paperId) },
handleOrientationChange(orientation) { // 通过父组件处理方向变化
this.$emit('orientation-change', orientation) },
// 刷新纸张数据
async refreshPapers() { await this.loadPapers() },
// 获取当前选择的纸张对象
getCurrentPaper() { const paperId = this.normalizedSelectedPaper if (typeof paperId === 'number') { return this.dynamicPapers.find(p => p.id === paperId) } return null } }}</script>
<style scoped>.paper-selector { padding: 12px; background: white; border-radius: 4px; border: 1px solid #e8e8e8; margin-bottom: 12px;}
.selector-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;}
.selector-header h4 { margin: 0; font-size: 13px; font-weight: 600; color: #333;}
.selector-header i { color: #909399; cursor: help; font-size: 12px;}
.paper-type-select { margin-bottom: 10px;}
.custom-size { margin-bottom: 10px; padding: 8px; background: #f8f9fa; border-radius: 3px;}
.size-inputs { display: flex; gap: 8px;}
.input-group { flex: 1; display: flex; flex-direction: column; gap: 3px;}
.input-group label { font-size: 11px; color: #666; font-weight: 500;}
.canvas-info { margin-bottom: 10px; padding: 8px; background: #f0f9ff; border-radius: 3px; border-left: 2px solid #409eff;}
.info-item { display: flex; justify-content: space-between; margin-bottom: 3px; font-size: 11px;}
.info-item:last-child { margin-bottom: 0;}
.info-item .label { color: #666; font-weight: 500;}
.info-item .value { color: #333; font-weight: 600;}
.info-item.description .value { color: #909399; font-weight: normal; font-style: italic;}
.quick-sizes { border-top: 1px solid #e8e8e8; padding-top: 8px;}
.quick-title { font-size: 11px; color: #666; margin-bottom: 6px; font-weight: 500;}
.quick-buttons { display: flex; flex-wrap: wrap;}
.quick-buttons .el-button { flex: 1; min-width: 0; font-size: 8px; padding: 4px 1px; height: 24px; line-height: 1; border-radius: 3px; transition: all 0.2s ease;}
.quick-buttons .el-button--mini { height: 24px; padding: 4px 1px;}
.paper-preview { margin-bottom: 10px; padding: 8px; background: #f8f9fa; border-radius: 3px; text-align: center;}
.preview-container { display: flex; justify-content: center; align-items: center; min-height: 60px;}
.preview-paper { border: 2px solid #409eff; border-radius: 2px; display: flex; align-items: center; justify-content: center; position: relative; transition: all 0.3s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);}
.preview-paper.landscape { border-color: #67c23a;}
.preview-label { font-size: 9px; color: #333; font-weight: 600; text-align: center; line-height: 1.2; padding: 2px; background: rgba(255, 255, 255, 0.8); border-radius: 2px;}
/* 水平模式样式 */.paper-selector.horizontal-mode { display: flex; align-items: center; gap: 15px; padding: 0; background: transparent; border: none; margin-bottom: 0;}
.horizontal-mode .paper-type-select { margin-bottom: 0;}
.horizontal-mode .orientation-select.horizontal-inline { margin-bottom: 0;}
.horizontal-mode .custom-size,.horizontal-mode .canvas-info,.horizontal-mode .quick-sizes,.horizontal-mode .paper-preview { display: none; /* 水平模式下隐藏这些详细信息 */}</style>
|