backend-mini-brand/subpages/common/destroy-liquor.vue
2025-07-19 20:00:08 +08:00

406 lines
11 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>