|
|
|
@ -39,6 +39,50 @@ |
|
|
|
</div> |
|
|
|
</el-form-item> |
|
|
|
|
|
|
|
<el-form-item > |
|
|
|
<div class="form-row"> |
|
|
|
<el-form-item label="字体" class="form-item-half"> |
|
|
|
<el-select |
|
|
|
v-model="element.fontFamily" |
|
|
|
size="mini" |
|
|
|
style="width: 100%;" |
|
|
|
placeholder="选择字体" |
|
|
|
filterable |
|
|
|
:loading="fontLoading" |
|
|
|
@focus="loadAvailableFonts" |
|
|
|
@change="onFontFamilyChange" |
|
|
|
> |
|
|
|
<el-option-group |
|
|
|
v-for="group in groupedFonts" |
|
|
|
:key="group.category" |
|
|
|
:label="group.label" |
|
|
|
> |
|
|
|
<el-option |
|
|
|
v-for="font in group.fonts" |
|
|
|
:key="font.value" |
|
|
|
:label="font.name" |
|
|
|
:value="font.value" |
|
|
|
:disabled="!font.supported" |
|
|
|
> |
|
|
|
<span style="float: left">{{ font.name }}</span> |
|
|
|
<span style="float: right; color: #8492a6; font-size: 11px"> |
|
|
|
{{ font.description }} |
|
|
|
<i v-if="!font.supported" class="el-icon-warning" style="color: #f56c6c;" title="不支持ZPL打印"></i> |
|
|
|
</span> |
|
|
|
</el-option> |
|
|
|
</el-option-group> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="文本对齐" class="form-item-half"> |
|
|
|
<el-select v-model="element.textAlign" size="mini" style="width: 100%;" placeholder="对齐方式"> |
|
|
|
<el-option label="左对齐" value="left" /> |
|
|
|
<el-option label="居中" value="center" /> |
|
|
|
<el-option label="右对齐" value="right" /> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
</div> |
|
|
|
</el-form-item> |
|
|
|
|
|
|
|
<el-form-item label="字体大小"> |
|
|
|
<div class="font-size-row"> |
|
|
|
<el-input |
|
|
|
@ -54,6 +98,25 @@ |
|
|
|
</div> |
|
|
|
</el-form-item> |
|
|
|
|
|
|
|
<!-- <el-form-item label="字体样式"> |
|
|
|
<div class="font-style-row"> |
|
|
|
<el-checkbox v-model="element.fontItalic" size="small" class="inline-checkbox">斜体</el-checkbox> |
|
|
|
<el-checkbox v-model="element.fontUnderline" size="small" class="inline-checkbox">下划线</el-checkbox> |
|
|
|
<div class="spacing-controls"> |
|
|
|
<span class="spacing-label">字符间距:</span> |
|
|
|
<el-input |
|
|
|
v-model="element.letterSpacing" |
|
|
|
:min="0" |
|
|
|
:max="20" |
|
|
|
controls-position="right" |
|
|
|
size="mini" |
|
|
|
class="spacing-input" |
|
|
|
placeholder="0" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-form-item>--> |
|
|
|
|
|
|
|
<template v-if="element.newline"> |
|
|
|
<div class="form-row"> |
|
|
|
<el-form-item label="文本宽度(mm)" class="form-item-half"> |
|
|
|
@ -249,7 +312,14 @@ |
|
|
|
<el-form label-position="top" size="small"> |
|
|
|
<el-form-item label="数据内容"> |
|
|
|
<div class="input-with-button"> |
|
|
|
<el-input v-model="element.data" placeholder="请输入一维码数据" /> |
|
|
|
<el-input |
|
|
|
v-model="element.data" |
|
|
|
placeholder="请输入一维码数据" |
|
|
|
type="textarea" |
|
|
|
:rows="2" |
|
|
|
maxlength="1000" |
|
|
|
show-word-limit |
|
|
|
/> |
|
|
|
<el-button type="primary" size="mini" @click="$emit('data-source', element)"> |
|
|
|
数据源 |
|
|
|
</el-button> |
|
|
|
@ -480,6 +550,7 @@ |
|
|
|
|
|
|
|
<script> |
|
|
|
import comShowLabelSerialInfo from "../com_show_label_serial_info"; |
|
|
|
import { availableFont } from '@/api/labelSetting/label_setting.js' |
|
|
|
|
|
|
|
export default { |
|
|
|
name: 'PropertyForm', |
|
|
|
@ -490,6 +561,42 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
emits: ['data-source', 'image-upload', 'element-combination'], |
|
|
|
data() { |
|
|
|
return { |
|
|
|
availableFonts: [], |
|
|
|
fontLoading: false, |
|
|
|
fontsLoaded: false |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
groupedFonts() { |
|
|
|
if (!this.availableFonts.length) { |
|
|
|
return [] |
|
|
|
} |
|
|
|
|
|
|
|
const groups = {} |
|
|
|
|
|
|
|
this.availableFonts.forEach(font => { |
|
|
|
const category = font.category || 'other' |
|
|
|
if (!groups[category]) { |
|
|
|
groups[category] = { |
|
|
|
category: category, |
|
|
|
label: this.getCategoryLabel(category), |
|
|
|
fonts: [] |
|
|
|
} |
|
|
|
} |
|
|
|
groups[category].fonts.push(font) |
|
|
|
}) |
|
|
|
|
|
|
|
// 排序分组 |
|
|
|
const sortedGroups = Object.values(groups).sort((a, b) => { |
|
|
|
const order = ['system', 'chinese', 'english', 'monospace', 'decorative', 'other'] |
|
|
|
return order.indexOf(a.category) - order.indexOf(b.category) |
|
|
|
}) |
|
|
|
|
|
|
|
return sortedGroups |
|
|
|
} |
|
|
|
}, |
|
|
|
/*组件*/ |
|
|
|
components: { |
|
|
|
comShowLabelSerialInfo,/*标签内容流水号信息的組件*/ |
|
|
|
@ -499,6 +606,9 @@ export default { |
|
|
|
if (this.element.type === 'text' && !this.element.dataType) { |
|
|
|
this.$set(this.element, 'dataType', 'text') |
|
|
|
} |
|
|
|
|
|
|
|
// 初始化字体设置 |
|
|
|
this.initializeFontSettings() |
|
|
|
}, |
|
|
|
watch: { |
|
|
|
// 监听元素变化,确保文件输入框状态正确 |
|
|
|
@ -663,7 +773,145 @@ export default { |
|
|
|
const paddedNumber = startValue.toString().padStart(digits, '0') |
|
|
|
|
|
|
|
return `${prefix}${paddedNumber}` |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 初始化字体设置 |
|
|
|
initializeFontSettings() { |
|
|
|
if (this.element.type === 'text') { |
|
|
|
// 设置默认字体属性 |
|
|
|
if (!this.element.fontFamily) { |
|
|
|
this.$set(this.element, 'fontFamily', 'default') |
|
|
|
} |
|
|
|
if (!this.element.textAlign) { |
|
|
|
this.$set(this.element, 'textAlign', 'left') |
|
|
|
} |
|
|
|
if (this.element.letterSpacing === undefined) { |
|
|
|
this.$set(this.element, 'letterSpacing', 0) |
|
|
|
} |
|
|
|
if (this.element.fontItalic === undefined) { |
|
|
|
this.$set(this.element, 'fontItalic', false) |
|
|
|
} |
|
|
|
if (this.element.fontUnderline === undefined) { |
|
|
|
this.$set(this.element, 'fontUnderline', false) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 获取字体预览样式 |
|
|
|
getFontPreviewStyle() { |
|
|
|
if (this.element.type !== 'text') return {} |
|
|
|
|
|
|
|
const style = {} |
|
|
|
|
|
|
|
// 字体族 |
|
|
|
if (this.element.fontFamily && this.element.fontFamily !== 'default') { |
|
|
|
style.fontFamily = this.element.fontFamily |
|
|
|
} |
|
|
|
|
|
|
|
// 字体大小 |
|
|
|
if (this.element.fontSize) { |
|
|
|
style.fontSize = this.element.fontSize + 'px' |
|
|
|
} |
|
|
|
|
|
|
|
// 加粗 |
|
|
|
if (this.element.bold) { |
|
|
|
style.fontWeight = 'bold' |
|
|
|
} |
|
|
|
|
|
|
|
// 斜体 |
|
|
|
if (this.element.fontItalic) { |
|
|
|
style.fontStyle = 'italic' |
|
|
|
} |
|
|
|
|
|
|
|
// 下划线 |
|
|
|
if (this.element.fontUnderline) { |
|
|
|
style.textDecoration = 'underline' |
|
|
|
} |
|
|
|
|
|
|
|
// 文本对齐 |
|
|
|
if (this.element.textAlign) { |
|
|
|
style.textAlign = this.element.textAlign |
|
|
|
} |
|
|
|
|
|
|
|
// 字符间距 |
|
|
|
if (this.element.letterSpacing) { |
|
|
|
style.letterSpacing = this.element.letterSpacing + 'px' |
|
|
|
} |
|
|
|
|
|
|
|
return style |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载可用字体 |
|
|
|
async loadAvailableFonts() { |
|
|
|
if (this.fontsLoaded || this.fontLoading) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.fontLoading = true |
|
|
|
|
|
|
|
try { |
|
|
|
const response = await availableFont({}) |
|
|
|
if (response.data.success) { |
|
|
|
this.availableFonts = response.data.data || [] |
|
|
|
this.fontsLoaded = true |
|
|
|
console.log('加载字体列表成功,共', this.availableFonts.length, '个字体') |
|
|
|
} else { |
|
|
|
console.error('加载字体列表失败:', response.data.message) |
|
|
|
this.$message.warning('加载字体列表失败,使用默认字体') |
|
|
|
this.availableFonts = this.getDefaultFonts() |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('加载字体列表异常:', error) |
|
|
|
this.$message.error('加载字体列表异常') |
|
|
|
this.availableFonts = this.getDefaultFonts() |
|
|
|
} finally { |
|
|
|
this.fontLoading = false |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 获取分类标签 |
|
|
|
getCategoryLabel(category) { |
|
|
|
const labels = { |
|
|
|
'system': '系统字体', |
|
|
|
'chinese': '中文字体', |
|
|
|
'english': '英文字体', |
|
|
|
'monospace': '等宽字体', |
|
|
|
'decorative': '装饰字体', |
|
|
|
'other': '其他字体' |
|
|
|
} |
|
|
|
return labels[category] || '其他字体' |
|
|
|
}, |
|
|
|
|
|
|
|
// 获取默认字体列表(备用方案) |
|
|
|
getDefaultFonts() { |
|
|
|
return [ |
|
|
|
{ name: '默认字体', value: 'default', category: 'system', description: '系统默认', supported: true }, |
|
|
|
{ name: '微软雅黑', value: 'Microsoft YaHei', category: 'chinese', description: '中文字体', supported: true }, |
|
|
|
{ name: '宋体', value: 'SimSun', category: 'chinese', description: '中文字体', supported: true }, |
|
|
|
{ name: '黑体', value: 'SimHei', category: 'chinese', description: '中文字体', supported: true }, |
|
|
|
{ name: 'Arial', value: 'Arial', category: 'english', description: '英文字体', supported: true }, |
|
|
|
{ name: 'Times New Roman', value: 'Times New Roman', category: 'english', description: '英文字体', supported: true }, |
|
|
|
{ name: 'Courier New', value: 'Courier New', category: 'monospace', description: '等宽字体', supported: true } |
|
|
|
] |
|
|
|
}, |
|
|
|
|
|
|
|
// 字体族变化处理 |
|
|
|
onFontFamilyChange(value) { |
|
|
|
console.log('字体族变化:', value) |
|
|
|
console.log('当前元素:', this.element) |
|
|
|
|
|
|
|
// 确保字体值正确设置 |
|
|
|
this.$set(this.element, 'fontFamily', value) |
|
|
|
|
|
|
|
// 触发父组件更新 |
|
|
|
this.$emit('font-changed', { |
|
|
|
elementId: this.element.id, |
|
|
|
fontFamily: value |
|
|
|
}) |
|
|
|
|
|
|
|
console.log('字体设置完成,当前字体族:', this.element.fontFamily) |
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
@ -958,6 +1206,69 @@ export default { |
|
|
|
padding-left: 4px !important; |
|
|
|
} |
|
|
|
|
|
|
|
/* 字体样式行布局 */ |
|
|
|
.font-style-row { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 12px; |
|
|
|
flex-wrap: wrap; |
|
|
|
} |
|
|
|
|
|
|
|
.font-style-row .inline-checkbox { |
|
|
|
margin-right: 0 !important; |
|
|
|
} |
|
|
|
|
|
|
|
.spacing-controls { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
.spacing-label { |
|
|
|
font-size: 12px; |
|
|
|
color: #606266; |
|
|
|
white-space: nowrap; |
|
|
|
} |
|
|
|
|
|
|
|
.spacing-input { |
|
|
|
width: 80px !important; |
|
|
|
} |
|
|
|
|
|
|
|
.spacing-input .el-input__inner { |
|
|
|
height: 28px !important; |
|
|
|
font-size: 12px !important; |
|
|
|
padding: 0 30px 0 8px !important; |
|
|
|
} |
|
|
|
|
|
|
|
/* 字体预览样式 */ |
|
|
|
.font-preview { |
|
|
|
background: #f8f9fa; |
|
|
|
border: 1px solid #e4e7ed; |
|
|
|
border-radius: 4px; |
|
|
|
padding: 8px; |
|
|
|
margin-top: 8px; |
|
|
|
text-align: center; |
|
|
|
min-height: 40px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
} |
|
|
|
|
|
|
|
.font-preview-text { |
|
|
|
font-size: 16px; |
|
|
|
color: #333; |
|
|
|
transition: all 0.3s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.font-debug-info { |
|
|
|
margin-top: 4px; |
|
|
|
text-align: center; |
|
|
|
font-size: 11px; |
|
|
|
line-height: 1.2; |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.form-item-half .el-radio__inner { |
|
|
|
width: 12px !important; |
|
|
|
height: 12px !important; |
|
|
|
|