You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
369 lines
8.0 KiB
369 lines
8.0 KiB
<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>
|