297 lines
9.2 KiB
Vue
297 lines
9.2 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 required">调整重量(KG)</text>
|
|
<input class="form-input" type="digit" placeholder="请输入调整后的重量" v-model="form.weight" />
|
|
</view>
|
|
<view class="form-item">
|
|
<text class="form-label required">调整原因</text>
|
|
<picker class="form-value" mode="selector" :range="reasonOptions" range-key="label" @change="onReasonChange">
|
|
<text>{{ reasonLabel || '请选择' }}</text>
|
|
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
|
</picker>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="data-list">
|
|
<view class="data-card">
|
|
<view class="data-card-header">
|
|
<text class="data-card-title">{{ (recordData.list && recordData.list[1]) || '' }}</text>
|
|
<text class="data-card-tag orange">待调整</text>
|
|
</view>
|
|
<view class="data-card-row"><text>当前状态:</text><text class="val">{{ recordData.lx || '' }}</text></view>
|
|
<view class="data-card-row"><text>数字识别码:</text><text class="val">{{ recordData.list && recordData.list[2] || '' }}</text></view>
|
|
<view class="data-card-row"><text>当前重量:</text><text class="val">{{ (recordData.list && recordData.list[0]) || '' }}</text></view>
|
|
<view class="data-card-row"><text>登记时间:</text><text class="val">{{ (recordData.list && recordData.list[3]) || '' }}</text></view>
|
|
<!-- <view class="data-card-actions">
|
|
<button class="btn btn-sm btn-outline" @click="handleGoSelect">选择</button>
|
|
</view> -->
|
|
</view>
|
|
</view>
|
|
|
|
<view class="btn-area">
|
|
<button class="btn btn-outline" @click="handleQuery">查询</button>
|
|
<button class="btn btn-primary" @click="handleSubmit" :disabled="!canSubmit">提交调整</button>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 台账类型选择弹窗 -->
|
|
<view class="type-modal-mask" v-if="showTypeModal" @click="showTypeModal = false">
|
|
<view class="type-modal" @click.stop>
|
|
<view class="type-modal-head">
|
|
<text class="type-modal-title">选择台账类型</text>
|
|
<text class="type-modal-close" @click="showTypeModal = false">✕</text>
|
|
</view>
|
|
<scroll-view class="type-modal-body" scroll-y>
|
|
<view
|
|
class="type-modal-item"
|
|
v-for="item in ledgerTypeList"
|
|
:key="item.id"
|
|
@click="onTypeSelect(item)"
|
|
>
|
|
<text>{{ item.alias }}</text>
|
|
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { api } from '@/api/index'
|
|
import scanMixin from '@/utils/barcodeMixin.js'
|
|
import { getDateTime } from '@/utils/common.js'
|
|
// 库存调整
|
|
export default {
|
|
mixins: [scanMixin],
|
|
data() {
|
|
return {
|
|
reasonOptions: [
|
|
{ value: 'SAR1', label: '贮存一段时间后库存发生变化' },
|
|
{ value: 'SAR2', label: '不同称重设备导致的重量差异或原先库存重量为预估值' }
|
|
],
|
|
form: {
|
|
code: '',
|
|
weight: '',
|
|
reason: 'SAR1',
|
|
time: ''
|
|
},
|
|
recordData: {},
|
|
/* 选择模式回传标记 */
|
|
isSelected: false,
|
|
selectedItem: null,
|
|
/* 台账类型选择弹窗 */
|
|
showTypeModal: false,
|
|
ledgerTypeList: []
|
|
}
|
|
},
|
|
computed: {
|
|
canSubmit() {
|
|
return this.recordData.list && this.recordData.list.length && this.form.weight && this.form.reason
|
|
},
|
|
reasonLabel() {
|
|
const found = this.reasonOptions.find(item => item.value === this.form.reason)
|
|
return found ? found.label : ''
|
|
}
|
|
},
|
|
onLoad() {
|
|
if (this.reasonOptions.length) {
|
|
this.form.reason = this.reasonOptions[0].value
|
|
}
|
|
},
|
|
onShow() {
|
|
// 从选择页返回时,处理选中的数据
|
|
if (this.isSelected && this.selectedItem) {
|
|
const item = this.selectedItem
|
|
this.isSelected = false
|
|
this.selectedItem = null
|
|
|
|
let ledgerCode = ''
|
|
if (typeof item === 'object' && item !== null) {
|
|
ledgerCode = item.digital_id || item.code || ''
|
|
if (!ledgerCode) {
|
|
const keys = Object.keys(item)
|
|
ledgerCode = keys.length ? (item[keys[0]] || '') : ''
|
|
}
|
|
} else {
|
|
// 字符串类型:按空格分割,取第一部分作为台账编号
|
|
const parts = String(item).split(/\s+/).filter(p => p)
|
|
ledgerCode = parts.length > 0 ? parts[0] : ''
|
|
}
|
|
if (ledgerCode) {
|
|
this.handleClickQuery(ledgerCode)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
/** 扫码结果回调:填充数字识别码 -> 自动查询 */
|
|
onBarcodeScanned(barcode) {
|
|
this.form.code = barcode
|
|
uni.showToast({ title: '扫码成功 ' + barcode, icon: 'none' })
|
|
this.handleQuery()
|
|
},
|
|
handleQuery() {
|
|
if (!this.form.code) return uni.showToast({ title: '请输入数字识别码', icon: 'none' })
|
|
api.scanGet({ code: this.form.code }).then(res => {
|
|
console.log('res', res)
|
|
this.recordData = res.data
|
|
this.form.weight = ''
|
|
// this.form.reason = ''
|
|
uni.showToast({ title: '查询成功', icon: 'success' })
|
|
}).catch(() => {
|
|
this.recordData = {}
|
|
})
|
|
},
|
|
onReasonChange(e) {
|
|
const index = e.detail.value
|
|
this.form.reason = this.reasonOptions[index].value
|
|
},
|
|
/** 选择回传后调用 clickGet 查询数据,ledgerCode 为台账编号 */
|
|
handleClickQuery(ledgerCode) {
|
|
if (!ledgerCode) return
|
|
api.clickGet({ code: ledgerCode }).then(res => {
|
|
console.log('ledgerCode', ledgerCode)
|
|
console.log('res', res)
|
|
this.recordData = res.data
|
|
// 处理 data 字段:如果是字符串则按空格分割成数组
|
|
if (this.recordData.data && typeof this.recordData.data === 'string') {
|
|
this.recordData.data = this.recordData.data.split(/\s+/).filter(item => item)
|
|
}
|
|
this.form.code = res.data.digital_id || ''
|
|
this.form.weight = ''
|
|
// this.form.reason = ''
|
|
}).catch(() => {
|
|
this.recordData = {}
|
|
})
|
|
},
|
|
/** 跳转到台账列表选择页 */
|
|
async handleGoSelect() {
|
|
try {
|
|
const res = await api.ledgetType()
|
|
if (res.data.length) {
|
|
this.ledgerTypeList = res.data.sort((a, b) => a.sort_order - b.sort_order)
|
|
this.showTypeModal = true
|
|
} else {
|
|
uni.showToast({ title: '暂无可选台账类型', icon: 'none' })
|
|
}
|
|
} catch (e) {
|
|
// request.js 已处理 loading 和错误提示
|
|
}
|
|
},
|
|
/** 选择台账类型后跳转 detail 页 */
|
|
onTypeSelect(item) {
|
|
this.showTypeModal = false
|
|
uni.navigateTo({
|
|
url: '/pages/ledger/detail?mode=select&item=' + encodeURIComponent(JSON.stringify(item))
|
|
})
|
|
},
|
|
handleSubmit() {
|
|
if (!this.canSubmit) return
|
|
api.adjust({
|
|
code: this.form.code,
|
|
weight: parseFloat(this.form.weight),
|
|
time: getDateTime(),
|
|
reason: this.form.reason
|
|
}).then(res => {
|
|
uni.showToast({ title: '提交成功', icon: 'success' })
|
|
setTimeout(() => {
|
|
this.recordData = {};
|
|
this.form = {
|
|
code: '',
|
|
weight: '',
|
|
reason: this.reasonOptions[0].value,
|
|
time: ''
|
|
}
|
|
}, 1500)
|
|
}).catch(() => {
|
|
// request.js 已处理 loading 和错误提示
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.data-card-tag.orange {
|
|
background-color: #fff7e6;
|
|
color: #fa8c16;
|
|
border: 1px solid #ffd591;
|
|
}
|
|
|
|
/* 台账类型选择弹窗 */
|
|
.type-modal-mask {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: flex-end;
|
|
z-index: 999;
|
|
}
|
|
|
|
.type-modal {
|
|
width: 100%;
|
|
max-height: 60vh;
|
|
background: #ffffff;
|
|
border-radius: $border-radius-xl $border-radius-xl 0 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.type-modal-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: $spacing-md;
|
|
border-bottom: 1px solid $border-color;
|
|
}
|
|
|
|
.type-modal-title {
|
|
font-size: $font-size-lg;
|
|
font-weight: 600;
|
|
color: $text-primary;
|
|
}
|
|
|
|
.type-modal-close {
|
|
font-size: 18px;
|
|
color: $text-placeholder;
|
|
padding: 4px;
|
|
}
|
|
|
|
.type-modal-body {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.type-modal-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: $spacing-md;
|
|
border-bottom: 1px solid $border-light;
|
|
font-size: $font-size-base;
|
|
color: $text-primary;
|
|
|
|
&:active {
|
|
background: $bg-primary;
|
|
}
|
|
}
|
|
</style> |