Files
uni-pda/pages/waste/reprint.vue
T
2026-07-23 14:49:31 +08:00

237 lines
9.1 KiB
Vue

<template>
<view class="page-container">
<!-- 标签补打 -->
<view class="page-body">
<view class="form-section">
<view class="form-group">
<view class="form-item">
<text class="form-label required">数字识别码</text>
<view class="input-row">
<input class="form-input" placeholder="请输入数字识别码" v-model="form.code" />
<view class="input-extra">
<button class="btn btn-sm btn-outline" @click="scanCode">扫码</button>
</view>
</view>
</view>
<view class="form-item">
<text class="form-label">危废名称</text>
<text class="form-value">{{ previewData.fwmc || '-' }}</text>
</view>
<view class="form-item">
<text class="form-label">产生时间</text>
<text class="form-value">{{ previewData.cssj || '-' }}</text>
</view>
</view>
</view>
<!-- 标签预览 -->
<view class="label-preview">
<view class="label-header" @click="expanded = !expanded">
<text>危废标签</text>
<text class="label-toggle">{{ expanded ? '收起 ▲' : '更多 ▼' }}</text>
</view>
<view class="label-content" :class="{ collapsed: !expanded }">
<view class="label-row"><text class="label-key">废物名称</text><text class="label-val">{{ previewData.fwmc }}</text></view>
<view class="label-row"><text class="label-key">废物代码</text><text class="label-val">{{ previewData.fwdm }}</text></view>
<view class="label-row"><text class="label-key">废物类别</text><text class="label-val">{{ previewData.fwlb }}</text></view>
<view class="label-row"><text class="label-key">废物形态</text><text class="label-val">{{ previewData.fwxt }}</text></view>
<view class="label-row"><text class="label-key">数字识别码</text><text class="label-val label-code">{{ previewData.szsbm }}</text></view>
<view class="label-row"><text class="label-key">主要成分</text><text class="label-val">{{ previewData.zycf }}</text></view>
<view class="label-row"><text class="label-key">有害成分</text><text class="label-val">{{ previewData.yhcf }}</text></view>
<view class="label-row"><text class="label-key">危险特性</text><text class="label-val">{{ previewData.wxtx }}</text></view>
<view class="label-row"><text class="label-key">注意事项</text><text class="label-val">{{ previewData.zysx }}</text></view>
<view class="label-row"><text class="label-key">产生数量</text><text class="label-val">{{ previewData.csl }} {{ previewData.jldw }}</text></view>
<view class="label-row"><text class="label-key">产生时间</text><text class="label-val">{{ previewData.cssj }}</text></view>
<view class="label-row"><text class="label-key">单位名称</text><text class="label-val">{{ previewData.dwmc }}</text></view>
<view class="label-row"><text class="label-key">联系人</text><text class="label-val">{{ previewData.lxr }}</text></view>
<view class="label-row"><text class="label-key">联系电话</text><text class="label-val">{{ previewData.lxrsj }}</text></view>
<view class="label-row"><text class="label-key">容器类型</text><text class="label-val">{{ previewData.rqlx }}</text></view>
<view class="label-row"><text class="label-key">容器材质</text><text class="label-val">{{ previewData.rqcz }}</text></view>
<view class="label-row"><text class="label-key">容器容量</text><text class="label-val">{{ previewData.rqrl }}</text></view>
</view>
</view>
<view class="btn-area">
<button class="btn btn-outline" @click="handleQuery">查询</button>
<button class="btn btn-primary" @click="handlePrint" :disabled="!previewData.fwmc">打印标签</button>
</view>
</view>
</view>
</template>
<script>
import { api } from '@/api/index'
import scanMixin from '@/utils/barcodeMixin.js'
// #ifdef APP-PLUS
import printerService from '@/utils/BluetoothPrinterService.new.js'
// #endif
export default {
mixins: [scanMixin],
data() {
return {
form: { code: '' },
previewData: {},
expanded: false
}
},
methods: {
/** 扫码结果回调:填充数字识别码 -> 自动查询 */
onBarcodeScanned(barcode) {
this.form.code = barcode
uni.showToast({ title: '扫码成功 ' + barcode, icon: 'none' })
this.handleQuery()
},
// 查询
async handleQuery() {
if (!this.form.code) return uni.showToast({ title: '请输入数字识别码', icon: 'none' })
try {
const res = await api.labelPrint({ code: this.form.code })
console.log(res)
if (res.data) {
this.previewData = res.data
uni.showToast({ title: '查询成功', icon: 'none' })
} else {
this.previewData = {}
uni.showToast({ title: res.msg || '未查询到数据', icon: 'none' })
}
} catch (e) {
// request.js 已处理 loading 和错误提示
console.error('[补打] 查询失败:', e)
}
},
async handlePrint() {
if (!this.previewData.fwmc) {
return uni.showToast({ title: '请先查询危废信息', icon: 'none' })
}
// #ifdef APP-PLUS
const printData = this.printData()
console.log(printData)
uni.showToast({ title: '打印中...', icon: 'none' })
try {
await printerService.init()
await printerService.autoConnect()
await printerService.printWasteLabel(printData)
await this.handleDisconnect()
uni.showToast({ title: '打印成功', icon: 'success' })
} catch (error) {
console.error('[补打] 打印失败:', error)
uni.showToast({ title: '打印失败: ' + error, icon: 'none' })
}
// #endif
// #ifdef MP
uni.showToast({ title: '小程序暂不支持蓝牙打印', icon: 'none' })
// #endif
},
// #ifdef APP-PLUS
/** 断开蓝牙连接 */
async handleDisconnect() {
try {
await printerService.disconnect()
} catch (err) {
console.warn('[补打] 蓝牙断开失败:', err)
}
},
// #endif
printData() {
const printData = {
'mingcheng': this.previewData.fwmc || '', // 危废名称
'leibie': this.previewData.fwlb || '', // 危废类别
'daima': this.previewData.fwdm || '', // 危废代码
'xingtai': this.previewData.fwxt || '-', // 废物形态
'zhuyaochengfen': this.previewData.zycf || '-', // 主要成分
'youhaichengfen': this.previewData.yhcf || '-', // 有害成分
'zhuyi': this.previewData.zysx || '-', // 注意事项
'shibiema': this.previewData.szsbm || '', // 数字识别码
'danwei': this.previewData.dwmc || '', // 单位名称
'lianxi': (this.previewData.lxr || '') + ' ' + (this.previewData.lxrsj || ''), // 联系人
'riqi': (this.previewData.cssj || '').split(' ')[0], // 产生时间(仅日期)
'zhongliang': (this.previewData.csl || '') + ' ' + (this.previewData.jldw || ''), // 重量
'beizhu': this.previewData.wxtx || '-', // 备注 危险特征
'biaoshi': '', // 标识
'qrcode': this.previewData.wxfwbqewm || '', // 二维码
'lianxidianhua': this.previewData.lxrsj || '', // 联系电话
'rongqileixing': this.previewData.rqlx || '', // 容器类型
'rongqicaizhi': this.previewData.rqcz || '', // 容器材质
'rongqirongliang': this.previewData.rqrl || '', // 容器容量
}
return printData
}
}
}
</script>
<style lang="scss" scoped>
.label-preview {
background: #ffffff;
margin: 0 $spacing-md $spacing-md;
border-radius: $border-radius-md;
border: 2px dashed $border-color;
overflow: hidden;
}
.label-header {
background: $primary-color;
color: #ffffff;
text-align: center;
padding: 8px 12px;
font-size: $font-size-md;
font-weight: 600;
display: flex;
justify-content: space-between;
align-items: center;
}
.label-toggle {
font-size: $font-size-xs;
font-weight: 400;
opacity: 0.9;
}
// 收起时隐藏第6条及以后的行
.label-content.collapsed .label-row:nth-child(n+6) {
display: none;
}
.label-content {
padding: $spacing-md;
}
.label-row {
display: flex;
justify-content: space-between;
padding: 6px 0;
border-bottom: 1px solid $border-light;
&:last-child { border-bottom: none; }
}
.label-section-title {
padding: 10px 0 6px;
font-size: $font-size-xs;
font-weight: 600;
color: $primary-color;
border-bottom: 1px solid $border-light;
margin-bottom: 4px;
&:first-child { padding-top: 0; }
}
.label-key { color: $text-secondary; font-size: $font-size-base; }
.label-val { color: $text-primary; font-size: $font-size-base; font-weight: 500; }
.label-code {
font-size: $font-size-xs !important;
word-break: break-all;
text-align: right;
max-width: 60%;
}
.label-reprint {
text-align: center;
font-size: $font-size-xl;
font-weight: 700;
color: $danger-color;
margin-top: 8px;
}
</style>