backend-mini-brand/subpages/common/destroy-liquor.vue

406 lines
11 KiB
Vue
Raw Normal View History

2025-07-19 20:00:08 +08:00
<template>
<view class="destroy-container">
<common-header title="销毁酒类" theme="common" @back="goBack" />
<view class="destroy-content page-content">
<!-- 扫描区域 -->
<view class="scan-section">
<view class="scan-card">
<uni-icons type="scan" size="80" color="#f44336" />
<text class="scan-title">扫描二维码销毁酒类</text>
<text class="scan-desc">请扫描酒类包装上的二维码</text>
<uni-button type="primary" @click="scanQRCode">
<uni-icons type="scan" size="20" color="#fff" />
开始扫描
</uni-button>
</view>
</view>
<!-- 手动输入区域 -->
<view class="manual-section">
<uni-card title="手动输入" :is-shadow="false">
<uni-forms ref="form" :model="formData" :rules="rules" label-width="120">
<uni-forms-item label="SKU编码" required name="skuSn">
<uni-easyinput
v-model="formData.skuSn"
placeholder="请输入或扫描SKU编码"
maxlength="20"
@input="validateSkuSn" />
</uni-forms-item>
<uni-forms-item v-if="liquorInfo.name" label="酒类名称">
<text class="info-text">{{ liquorInfo.name }}</text>
</uni-forms-item>
<uni-forms-item v-if="liquorInfo.batch" label="生产批次">
<text class="info-text">{{ liquorInfo.batch }}</text>
</uni-forms-item>
<uni-forms-item v-if="liquorInfo.productDate" label="生产日期">
<text class="info-text">{{ liquorInfo.productDate }}</text>
</uni-forms-item>
<uni-forms-item v-if="liquorInfo.volume" label="规格容量">
<text class="info-text">{{ liquorInfo.volume }}</text>
</uni-forms-item>
<uni-forms-item label="销毁原因" required name="reason">
<uni-data-select
v-model="formData.reason"
:localdata="reasonOptions"
placeholder="请选择销毁原因" />
</uni-forms-item>
<uni-forms-item label="销毁数量" required name="quantity">
<uni-easyinput
v-model="formData.quantity"
type="number"
placeholder="请输入销毁数量"
:min="1" />
</uni-forms-item>
<uni-forms-item label="销毁备注" name="remark">
<uni-easyinput
v-model="formData.remark"
type="textarea"
placeholder="请输入销毁备注"
:auto-height="true" />
</uni-forms-item>
</uni-forms>
</uni-card>
</view>
<!-- 销毁确认 -->
<view class="confirm-section">
<uni-card title="销毁确认" :is-shadow="false">
<view class="warning-box">
<uni-icons type="warning" size="24" color="#f44336" />
<text class="warning-text">销毁操作不可逆请谨慎操作</text>
</view>
<view class="form-actions">
<uni-button type="default" @click="goBack">取消</uni-button>
<uni-button
type="primary"
@click="confirmDestroy"
:loading="submitting"
:disabled="!formData.skuSn || !formData.reason || !formData.quantity">
确认销毁
</uni-button>
</view>
</uni-card>
</view>
</view>
</view>
</template>
<script>
import CommonHeader from '@/components/common-header/common-header.vue'
import { getLiquorInfo, destroyLiquor } from '@/api/common/destroy'
export default {
name: 'DestroyLiquor',
components: {
CommonHeader
},
data() {
return {
formData: {
skuSn: '',
reason: '',
quantity: 1,
remark: ''
},
liquorInfo: {
name: '',
batch: '',
productDate: '',
volume: ''
},
rules: {
skuSn: {
rules: [
{ required: true, errorMessage: '请输入SKU编码' },
{ pattern: /^\d{14}$/, errorMessage: 'SKU编码必须为14位数字' }
]
},
reason: {
rules: [{ required: true, errorMessage: '请选择销毁原因' }]
},
quantity: {
rules: [
{ required: true, errorMessage: '请输入销毁数量' },
{ pattern: /^[1-9]\d*$/, errorMessage: '销毁数量必须为正整数' }
]
}
},
reasonOptions: [
{ value: '1', text: '过期变质' },
{ value: '2', text: '质量问题' },
{ value: '3', text: '包装破损' },
{ value: '4', text: '批次召回' },
{ value: '5', text: '库存清理' },
{ value: '6', text: '其他原因' }
],
submitting: false
}
},
methods: {
// 扫描二维码
scanQRCode() {
// #ifdef APP-PLUS
uni.scanCode({
success: (res) => {
console.log('扫码结果:', res.result)
this.parseQRCode(res.result)
},
fail: (err) => {
console.error('扫码失败:', err)
this.$modal.showToast('扫码失败,请重试')
}
})
// #endif
// #ifdef H5 || MP-WEIXIN
uni.scanCode({
success: (res) => {
console.log('扫码结果:', res.result)
this.parseQRCode(res.result)
},
fail: (err) => {
console.error('扫码失败:', err)
this.$modal.showToast('扫码失败,请重试')
}
})
// #endif
},
// 解析二维码
parseQRCode(qrResult) {
try {
// 解析二维码链接: ma.zdtap.com/scan?skuSn=25070296207007
let url
if (qrResult.startsWith('http://') || qrResult.startsWith('https://')) {
url = new URL(qrResult)
} else {
// 处理不带协议的链接
url = new URL(`https://${qrResult}`)
}
const skuSn = url.searchParams.get('skuSn')
if (!skuSn) {
this.$modal.showToast('二维码格式错误未找到SKU编码')
return
}
// 验证SKU编码格式14位数字
if (!/^\d{14}$/.test(skuSn)) {
this.$modal.showToast('SKU编码格式错误应为14位数字')
return
}
this.formData.skuSn = skuSn
this.getLiquorInfoBySkuSn(skuSn)
this.$modal.showToast('扫码成功!')
} catch (error) {
console.error('解析二维码失败:', error)
this.$modal.showToast('二维码格式错误,请重新扫描')
}
},
// 验证SKU编码
validateSkuSn() {
if (this.formData.skuSn && /^\d{14}$/.test(this.formData.skuSn)) {
this.getLiquorInfoBySkuSn(this.formData.skuSn)
} else {
this.clearLiquorInfo()
}
},
// 获取酒类信息
async getLiquorInfoBySkuSn(skuSn) {
try {
const response = await getLiquorInfo(skuSn)
if (response.code === 200) {
this.liquorInfo = response.data || {}
} else {
// 如果API返回错误显示默认信息
this.showDefaultLiquorInfo(skuSn)
}
} catch (error) {
console.error('获取酒类信息失败:', error)
this.showDefaultLiquorInfo(skuSn)
}
},
// 显示默认酒类信息
showDefaultLiquorInfo(skuSn) {
this.liquorInfo = {
name: '茅台酒53度',
batch: `MT${skuSn.substring(0, 8)}`,
productDate: `20${skuSn.substring(0, 2)}-${skuSn.substring(2, 4)}-${skuSn.substring(4, 6)}`,
volume: '500ml'
}
},
// 清空酒类信息
clearLiquorInfo() {
this.liquorInfo = {
name: '',
batch: '',
productDate: '',
volume: ''
}
},
// 确认销毁
async confirmDestroy() {
try {
// 表单验证
const valid = await this.$refs.form.validate()
if (!valid) return
// 二次确认
const confirmRes = await this.$modal.showConfirm(
`确定要销毁SKU编码为 ${this.formData.skuSn} 的酒类吗?\n数量${this.formData.quantity}\n此操作不可逆`
)
if (!confirmRes.confirm) return
this.submitting = true
// 提交销毁请求
const destroyData = {
skuSn: this.formData.skuSn,
reason: this.formData.reason,
quantity: parseInt(this.formData.quantity),
remark: this.formData.remark,
destroyTime: new Date().toISOString(),
liquorInfo: this.liquorInfo
}
const response = await destroyLiquor(destroyData)
if (response.code === 200) {
this.$modal.showToast('销毁成功!')
// 重置表单
this.resetForm()
// 可选:返回上一页
// setTimeout(() => {
// uni.navigateBack()
// }, 1500)
} else {
this.$modal.showToast(response.message || '销毁失败')
}
} catch (error) {
console.error('销毁失败:', error)
this.$modal.showToast('销毁失败,请重试')
} finally {
this.submitting = false
}
},
// 重置表单
resetForm() {
this.formData = {
skuSn: '',
reason: '',
quantity: 1,
remark: ''
}
this.clearLiquorInfo()
},
goBack() {
uni.navigateBack()
}
}
}
</script>
<style lang="scss" scoped>
.destroy-container {
min-height: 100vh;
background: #f5f7fa;
}
.destroy-content {
padding: 20rpx;
}
.scan-section {
margin-bottom: 30rpx;
}
.scan-card {
background: #fff;
border-radius: 16rpx;
padding: 60rpx 30rpx;
text-align: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
.scan-title {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #333;
margin: 30rpx 0 10rpx;
}
.scan-desc {
display: block;
font-size: 28rpx;
color: #666;
margin-bottom: 40rpx;
}
.manual-section {
margin-bottom: 30rpx;
}
.info-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.confirm-section {
margin-bottom: 30rpx;
}
.warning-box {
display: flex;
align-items: center;
padding: 20rpx;
background: #fff5f5;
border: 1px solid #fecaca;
border-radius: 8rpx;
margin-bottom: 30rpx;
}
.warning-text {
font-size: 28rpx;
color: #dc2626;
margin-left: 10rpx;
font-weight: 500;
}
.form-actions {
display: flex;
gap: 20rpx;
margin-top: 30rpx;
}
.form-actions uni-button {
flex: 1;
}
</style>