939 lines
23 KiB
Vue
939 lines
23 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-row :gutter="20">
|
||
<!-- 左侧区域 -->
|
||
<el-col :span="8">
|
||
<!-- 表单区域 -->
|
||
<div class="form-container">
|
||
<div class="section-header">
|
||
<h3>生成条码</h3>
|
||
</div>
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||
<el-row :gutter="20">
|
||
<el-col
|
||
v-for="field in formFields"
|
||
:key="field.prop"
|
||
:span="24"
|
||
>
|
||
<el-form-item :label="field.label" :prop="field.prop">
|
||
<el-input
|
||
v-model="form[field.prop]"
|
||
:placeholder="field.placeholder"
|
||
:disabled="loading"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-form-item class="form-actions">
|
||
<el-button
|
||
type="warning"
|
||
@click="handlePreview"
|
||
:loading="previewLoading"
|
||
icon="el-icon-view"
|
||
>
|
||
预览
|
||
</el-button>
|
||
<el-button
|
||
@click="resetForm"
|
||
icon="el-icon-refresh"
|
||
>
|
||
重置
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
|
||
|
||
</el-col>
|
||
|
||
<!-- 右侧预览区域 -->
|
||
<el-col :span="16">
|
||
<!-- 预览弹框 -->
|
||
<el-dialog
|
||
title="标签预览"
|
||
:visible.sync="showPreview"
|
||
width="900px"
|
||
:close-on-click-modal="false"
|
||
append-to-body
|
||
>
|
||
<div class="preview-container">
|
||
<div class="label-content">
|
||
<div class="preview-box">
|
||
<div class="preview-content">
|
||
<div class="preview-row">
|
||
<span class="preview-label">MODEL:</span>
|
||
<span class="preview-value">{{ previewData.model }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<span class="preview-label">SERIAL:</span>
|
||
<span class="preview-value">{{ previewData.serial }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<span class="preview-label">COLOR:</span>
|
||
<span class="preview-value">{{ previewData.color }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<div class="preview-col">
|
||
<span class="preview-label">V:</span>
|
||
<span class="preview-value">{{ previewData.v }}</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">Hz:</span>
|
||
<span class="preview-value">{{ previewData.hz }}</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">PH:</span>
|
||
<span class="preview-value">{{ previewData.ph }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="preview-row">
|
||
<div class="preview-col">
|
||
<span class="preview-label">N.W.:</span>
|
||
<span class="preview-value">{{ previewData.nW }}kg</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">G.W.:</span>
|
||
<span class="preview-value">{{ previewData.gW }}kg</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 二维码区域 -->
|
||
<div class="qrcode-container">
|
||
<vue-qr
|
||
:text="qrCodeValue"
|
||
:size="180"
|
||
:margin="0"
|
||
:correctLevel="2"
|
||
error-correction-level="M"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 打印专用区域(隐藏) -->
|
||
<vue-easy-print style="display: none;" ref="easyPrint2">
|
||
<div class="vue-easy-print" style="page-break-after:always">
|
||
<div class="label-content">
|
||
<div class="preview-box">
|
||
<div class="preview-content">
|
||
<div class="preview-row">
|
||
<span class="preview-label">MODEL:</span>
|
||
<span class="preview-value">{{ previewData.model }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<span class="preview-label">SERIAL:</span>
|
||
<span class="preview-value">{{ previewData.serial }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<span class="preview-label">COLOR:</span>
|
||
<span class="preview-value">{{ previewData.color }}</span>
|
||
</div>
|
||
<div class="preview-row">
|
||
<div class="preview-col">
|
||
<span class="preview-label">V:</span>
|
||
<span class="preview-value">{{ previewData.v }}</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">Hz:</span>
|
||
<span class="preview-value">{{ previewData.hz }}</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">PH:</span>
|
||
<span class="preview-value">{{ previewData.ph }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="preview-row">
|
||
<div class="preview-col">
|
||
<span class="preview-label">N.W.:</span>
|
||
<span class="preview-value">{{ previewData.nW }}</span>
|
||
</div>
|
||
<div class="preview-col">
|
||
<span class="preview-label">G.W.:</span>
|
||
<span class="preview-value">{{ previewData.gW }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 二维码区域 -->
|
||
<div class="qrcode-container">
|
||
<vue-qr
|
||
:text="qrCodeValue"
|
||
:size="180"
|
||
:margin="0"
|
||
:correctLevel="2"
|
||
error-correction-level="M"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</vue-easy-print>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="showPreview = false">关 闭</el-button>
|
||
<el-button type="primary" @click="submitForm" :loading="submitLoading">保存并打印</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 历史数据区域 -->
|
||
<div class="list-container" style="padding-bottom: 60px;">
|
||
<div class="section-header" style="margin-bottom: 40px;">
|
||
<h3>历史数据</h3>
|
||
<div class="header-actions">
|
||
<el-button
|
||
type="danger"
|
||
size="small"
|
||
@click="handleBatchDelete"
|
||
:disabled="!hasSelection"
|
||
icon="el-icon-delete"
|
||
>
|
||
批量删除
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table
|
||
ref="table"
|
||
v-loading="loading"
|
||
:data="tableData"
|
||
@selection-change="handleSelectionChange"
|
||
stripe
|
||
border
|
||
style="width: 100%;margin-bottom: 40px;height: 550px;"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center"/>
|
||
<el-table-column
|
||
v-for="column in tableColumns"
|
||
:key="column.prop"
|
||
:label="column.label"
|
||
:prop="column.prop"
|
||
:width="column.width"
|
||
:formatter="column.formatter"
|
||
show-overflow-tooltip
|
||
/>
|
||
<el-table-column label="操作" width="180" align="center" fixed="right">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" type="text" @click="handleEdit(scope.row)" icon="el-icon-edit">编辑</el-button>
|
||
<el-button size="mini" type="text" @click="handlePrint(scope.row)" icon="el-icon-printer">打印</el-button>
|
||
<el-button size="mini" type="text" @click="handleDelete(scope.row)" icon="el-icon-delete" class="danger-text">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import VueQr from 'vue-qr'
|
||
import VueEasyPrint from 'vue-easy-print'
|
||
import {
|
||
listBasProductCode,
|
||
getBasProductCode,
|
||
delBasProductCode,
|
||
addBasProductCode,
|
||
updateBasProductCode
|
||
} from "@/api/bas/BasProductCode"
|
||
|
||
// 常量配置
|
||
const FORM_FIELDS = [
|
||
{ prop: 'model', label: '型号', placeholder: '请输入型号', required: true },
|
||
{ prop: 'serial', label: '序列号', placeholder: '请输入序列号', required: true },
|
||
{ prop: 'color', label: '颜色', placeholder: '请输入颜色', required: true },
|
||
{ prop: 'v', label: '电压', placeholder: '请输入电压' },
|
||
{ prop: 'hz', label: '功率', placeholder: '请输入功率' },
|
||
{ prop: 'ph', label: '相位', placeholder: '请输入相位' },
|
||
{ prop: 'nW', label: '净重', placeholder: '请输入净重', required: true },
|
||
{ prop: 'gW', label: '毛重', placeholder: '请输入毛重', required: true },
|
||
{ prop: 'spare1', label: '订单号', placeholder: '请输入订单号' },
|
||
{ prop: 'spare2', label: '机型', placeholder: '请输入机型' },
|
||
{ prop: 'spare3', label: '分销', placeholder: '请输入分销' }
|
||
]
|
||
|
||
const TABLE_COLUMNS = [
|
||
{ prop: 'model', label: '型号', width: 120 },
|
||
{ prop: 'color', label: '颜色', width: 100 },
|
||
{ prop: 'serial', label: '序列号', width: 150 },
|
||
{ prop: 'v', label: '电压', width: 100 },
|
||
{ prop: 'hz', label: '功率', width: 100 },
|
||
{ prop: 'ph', label: '相位', width: 100 },
|
||
{ prop: 'nW', label: '净重', width: 100 },
|
||
{ prop: 'gW', label: '毛重', width: 100 },
|
||
{
|
||
prop: 'type',
|
||
label: '状态',
|
||
width: 100,
|
||
formatter: (row) => row.type === '1' ? '未打印' : '已打印'
|
||
},
|
||
{ prop: 'spare1', label: '订单号', width: 150 },
|
||
{ prop: 'spare2', label: '机型', width: 120 },
|
||
{ prop: 'spare3', label: '分箱', width: 100 }
|
||
]
|
||
|
||
const DEFAULT_FORM = {
|
||
model: '',
|
||
color: '',
|
||
serial: '',
|
||
v: '',
|
||
hz: '',
|
||
ph: '',
|
||
nW: '',
|
||
gW: '',
|
||
type: '1',
|
||
spare1: '',
|
||
spare2: '',
|
||
spare3: ''
|
||
}
|
||
|
||
const DEFAULT_PREVIEW_DATA = {
|
||
model: '',
|
||
color: '',
|
||
serial: '',
|
||
v: '',
|
||
hz: '',
|
||
ph: '',
|
||
nW: '',
|
||
gW: ''
|
||
}
|
||
|
||
export default {
|
||
name: 'BasProductCode',
|
||
components: {
|
||
VueQr,
|
||
VueEasyPrint
|
||
},
|
||
data() {
|
||
return {
|
||
// 表单对象
|
||
form: { ...DEFAULT_FORM },
|
||
// 表单校验规则
|
||
rules: this.generateRules(),
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
searchText: ''
|
||
},
|
||
// 表格数据
|
||
tableData: [],
|
||
// 加载状态
|
||
loading: false,
|
||
previewLoading: false,
|
||
submitLoading: false,
|
||
// 总条数
|
||
total: 0,
|
||
// 预览数据
|
||
previewData: { ...DEFAULT_PREVIEW_DATA },
|
||
// 选中数据
|
||
selectedRows: [],
|
||
// 是否显示预览
|
||
showPreview: false,
|
||
// 表单字段配置
|
||
formFields: FORM_FIELDS,
|
||
// 表格列配置
|
||
tableColumns: TABLE_COLUMNS
|
||
}
|
||
},
|
||
computed: {
|
||
// 二维码内容
|
||
qrCodeValue() {
|
||
console.log(this.previewData)
|
||
const text = `${this.previewData.spare1}@${this.previewData.model}@${this.previewData.spare2}@${this.previewData.spare3}@${this.previewData.serial}`
|
||
return this.procode(text)
|
||
},
|
||
// 是否有选中项
|
||
hasSelection() {
|
||
return this.selectedRows.length > 0
|
||
}
|
||
},
|
||
created() {
|
||
this.init()
|
||
},
|
||
methods: {
|
||
// 初始化
|
||
async init() {
|
||
try {
|
||
await this.getList()
|
||
} catch (error) {
|
||
this.$message.error('初始化失败:' + error.message)
|
||
}
|
||
},
|
||
|
||
// 生成表单验证规则
|
||
generateRules() {
|
||
const rules = {}
|
||
FORM_FIELDS.forEach(field => {
|
||
if (field.required) {
|
||
rules[field.prop] = [
|
||
{ required: true, message: `请输入${field.label}`, trigger: 'blur' }
|
||
]
|
||
}
|
||
})
|
||
return rules
|
||
},
|
||
|
||
// 获取列表数据
|
||
async getList() {
|
||
this.loading = true
|
||
try {
|
||
const response = await listBasProductCode(this.queryParams)
|
||
this.tableData = response.rows || []
|
||
this.total = response.total || 0
|
||
} catch (error) {
|
||
this.$message.error('获取数据失败:' + error.message)
|
||
this.tableData = []
|
||
this.total = 0
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
|
||
// 查询按钮操作
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
|
||
// 重置表单
|
||
resetForm() {
|
||
this.$refs.form.resetFields()
|
||
this.form = { ...DEFAULT_FORM }
|
||
this.previewData = { ...DEFAULT_PREVIEW_DATA }
|
||
this.showPreview = false
|
||
},
|
||
|
||
// 预览按钮操作
|
||
async handlePreview() {
|
||
try {
|
||
await this.$refs.form.validate()
|
||
this.previewLoading = true
|
||
|
||
// 模拟预览加载
|
||
setTimeout(() => {
|
||
this.previewData = { ...this.form }
|
||
this.showPreview = true
|
||
this.previewLoading = false
|
||
this.$message.success('预览生成成功')
|
||
}, 300)
|
||
} catch (error) {
|
||
this.$message.warning('请完善必填信息')
|
||
}
|
||
},
|
||
|
||
// 表单提交
|
||
async submitForm() {
|
||
try {
|
||
await this.$refs.form.validate()
|
||
this.submitLoading = true
|
||
|
||
const apiCall = this.form.id != null
|
||
? updateBasProductCode(this.form)
|
||
: addBasProductCode(this.form)
|
||
|
||
await apiCall
|
||
|
||
const message = this.form.id != null ? '修改成功' : '新增成功'
|
||
this.$message.success(message)
|
||
|
||
await this.getList()
|
||
await this.autoPrint()
|
||
|
||
} catch (error) {
|
||
this.$message.error('保存失败:' + error.message)
|
||
} finally {
|
||
this.submitLoading = false
|
||
}
|
||
},
|
||
|
||
// 新增按钮操作
|
||
handleAdd() {
|
||
this.resetForm()
|
||
},
|
||
|
||
// 编辑按钮操作
|
||
handleEdit(row) {
|
||
this.form = { ...row }
|
||
this.previewData = { ...row }
|
||
// this.showPreview = true
|
||
},
|
||
|
||
// 删除按钮操作
|
||
async handleDelete(row) {
|
||
try {
|
||
await this.$confirm(
|
||
`是否确认删除条码打印编号为"${row.id}"的数据项?`,
|
||
'警告',
|
||
{
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}
|
||
)
|
||
|
||
await delBasProductCode(row.id)
|
||
this.$message.success('删除成功')
|
||
await this.getList()
|
||
|
||
} catch (error) {
|
||
if (error !== 'cancel') {
|
||
this.$message.error('删除失败:' + error.message)
|
||
}
|
||
}
|
||
},
|
||
|
||
// 批量删除
|
||
async handleBatchDelete() {
|
||
if (!this.hasSelection) {
|
||
this.$message.warning('请选择要删除的数据')
|
||
return
|
||
}
|
||
|
||
try {
|
||
await this.$confirm(
|
||
`是否确认删除选中的${this.selectedRows.length}条数据?`,
|
||
'警告',
|
||
{
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}
|
||
)
|
||
|
||
const ids = this.selectedRows.map(row => row.id)
|
||
await delBasProductCode(ids.join(','))
|
||
|
||
this.$message.success('批量删除成功')
|
||
await this.getList()
|
||
|
||
} catch (error) {
|
||
if (error !== 'cancel') {
|
||
this.$message.error('批量删除失败:' + error.message)
|
||
}
|
||
}
|
||
},
|
||
|
||
// 打印按钮操作
|
||
async handlePrint(row) {
|
||
try {
|
||
this.previewData = { ...row }
|
||
this.showPreview = true
|
||
|
||
await this.$nextTick()
|
||
setTimeout(() => {
|
||
this.$refs.easyPrint2.print()
|
||
}, 100)
|
||
|
||
} catch (error) {
|
||
this.$message.error('打印失败:' + error.message)
|
||
}
|
||
},
|
||
|
||
// 自动打印功能
|
||
async autoPrint() {
|
||
try {
|
||
this.previewData = { ...this.form }
|
||
this.showPreview = true
|
||
|
||
await this.$nextTick()
|
||
setTimeout(() => {
|
||
this.$refs.easyPrint2.print()
|
||
}, 500)
|
||
|
||
} catch (error) {
|
||
this.$message.error('自动打印失败:' + error.message)
|
||
}
|
||
},
|
||
|
||
// 多选框选中数据
|
||
handleSelectionChange(selection) {
|
||
this.selectedRows = selection
|
||
},
|
||
|
||
// 二维码编码方法
|
||
procode(text) {
|
||
const key = "0"
|
||
|
||
const mystr = text.split("@")
|
||
const text1 = `@${mystr[1]}@${mystr[2]}@${mystr[3]}@`
|
||
|
||
let str = key + text1
|
||
let str1 = ""
|
||
|
||
for (let i = 0; i < str.length; i++) {
|
||
// 获取字符的Unicode编码并转换为16进制
|
||
let str2 = str.charCodeAt(i).toString(16).toUpperCase()
|
||
// 补齐到4位
|
||
while (str2.length < 4) {
|
||
str2 = "0" + str2
|
||
}
|
||
str1 += str2
|
||
}
|
||
|
||
// 反转字符串
|
||
str1 = str1.split('').reverse().join('')
|
||
|
||
// 替换操作
|
||
str1 = str1.replace(/100/g, "Q")
|
||
str1 = str1.replace(/200/g, "R")
|
||
str1 = str1.replace(/300/g, "S")
|
||
str1 = str1.replace(/400/g, "T")
|
||
str1 = str1.replace(/500/g, "U")
|
||
str1 = str1.replace(/600/g, "V")
|
||
str1 = str1.replace(/700/g, "W")
|
||
str1 = str1.replace(/800/g, "X")
|
||
str1 = str1.replace(/900/g, "Y")
|
||
str1 = str1.replace(/00/g, "Z")
|
||
|
||
// 最终结果反转
|
||
const result = `${mystr[0]}$${str1}$${mystr[4]}`
|
||
return result.split('').reverse().join('')
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 基础布局 */
|
||
.app-container {
|
||
padding: 20px;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.list-container {
|
||
background: #fff;
|
||
padding: 20px;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.section-header h3 {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.header-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
.el-table {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.el-table .danger-text {
|
||
color: #F56C6C;
|
||
}
|
||
|
||
.el-table .danger-text:hover {
|
||
color: #f78989;
|
||
}
|
||
|
||
/* 容器样式 */
|
||
.form-container,
|
||
.list-container,
|
||
.preview-container {
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.form-container {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.preview-container {
|
||
padding: 20px;
|
||
}
|
||
|
||
.preview-box {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
padding: 20px;
|
||
border: 1px solid #dcdfe6;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.preview-content {
|
||
flex: 1;
|
||
margin-right: 20px;
|
||
}
|
||
|
||
.preview-row {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.preview-label {
|
||
font-weight: bold;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.qrcode-container {
|
||
width: 180px;
|
||
height: 180px;
|
||
}
|
||
|
||
.list-container .el-table {
|
||
height: 100%;
|
||
}
|
||
|
||
.preview-container {
|
||
position: sticky;
|
||
top: 20px;
|
||
height: 450px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.preview-display {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 区域标题 */
|
||
.section-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20px 20px 0;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.section-header h3 {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
}
|
||
|
||
.header-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* 表单样式 */
|
||
.form-container .el-form {
|
||
padding: 0 20px 20px;
|
||
}
|
||
|
||
.form-actions {
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.form-actions .el-button {
|
||
margin: 0 10px;
|
||
}
|
||
|
||
/* 表格样式 */
|
||
.list-container .el-table {
|
||
margin: 0 20px;
|
||
}
|
||
|
||
.list-container .pagination {
|
||
margin: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.danger-text {
|
||
color: #f56c6c !important;
|
||
}
|
||
|
||
.danger-text:hover {
|
||
color: #f78989 !important;
|
||
}
|
||
|
||
/* 预览区域样式 */
|
||
.preview-container {
|
||
padding: 0;
|
||
}
|
||
|
||
.empty-preview {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 300px;
|
||
margin: 0 20px 20px;
|
||
border: 2px dashed #dcdfe6;
|
||
border-radius: 8px;
|
||
color: #909399;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.empty-preview i {
|
||
font-size: 48px;
|
||
margin-bottom: 16px;
|
||
color: #c0c4cc;
|
||
}
|
||
|
||
.empty-preview p {
|
||
margin: 0;
|
||
}
|
||
|
||
.preview-display {
|
||
padding: 0 20px 20px;
|
||
}
|
||
|
||
.label-content {
|
||
border: 1px solid #e4e7ed;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.preview-box {
|
||
padding: 20px;
|
||
font-family: 'Arial', sans-serif;
|
||
position: relative;
|
||
background-color: #fff;
|
||
height: 350px;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.preview-content {
|
||
margin-right: 200px;
|
||
}
|
||
|
||
.preview-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 25px;
|
||
min-height: 40px;
|
||
}
|
||
|
||
.preview-row:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.preview-col {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.preview-label {
|
||
font-weight: 600;
|
||
margin-right: 15px;
|
||
min-width: 80px;
|
||
font-size: 24px;
|
||
color: #303133;
|
||
}
|
||
|
||
.preview-value {
|
||
flex: 1;
|
||
font-size: 24px;
|
||
color: #606266;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.qrcode-container {
|
||
position: absolute;
|
||
top: 20px;
|
||
right: 20px;
|
||
padding: 0;
|
||
background-color: transparent;
|
||
border: none;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 1200px) {
|
||
.app-container {
|
||
padding: 10px;
|
||
}
|
||
|
||
.preview-container {
|
||
position: static;
|
||
max-height: none;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.section-header {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 10px;
|
||
}
|
||
|
||
.header-actions {
|
||
width: 100%;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.preview-content {
|
||
margin-right: 0;
|
||
margin-bottom: 140px;
|
||
}
|
||
|
||
.qrcode-container {
|
||
position: static;
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
/* 动画效果 */
|
||
.preview-display {
|
||
animation: fadeIn 0.3s ease-in-out;
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* 加载状态 */
|
||
.el-button.is-loading {
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 打印样式 */
|
||
@media print {
|
||
@page {
|
||
margin: 0;
|
||
size: auto;
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
}
|
||
|
||
.preview-box {
|
||
border: none;
|
||
box-shadow: none;
|
||
position: relative;
|
||
}
|
||
|
||
.qrcode-container {
|
||
border: none;
|
||
position: absolute !important;
|
||
top: 20px !important;
|
||
right: 20px !important;
|
||
padding: 0;
|
||
background-color: transparent;
|
||
}
|
||
}
|
||
</style>
|