feat: add bit sample warehouse pda pages

besure_bit
ck-chenkang 2 weeks ago
parent 872c0b58e1
commit cb58f0e815

@ -0,0 +1,41 @@
import request from '@/utils/request'
export function scanBitWmsCode(code) {
return request({
url: '/admin-api/erp/bit-wms/scan',
method: 'get',
params: { code }
})
}
export function createBitWmsInbound(data) {
return request({
url: '/admin-api/erp/bit-wms/inbound',
method: 'post',
data
})
}
export function createBitWmsOutbound(data) {
return request({
url: '/admin-api/erp/bit-wms/outbound',
method: 'post',
data
})
}
export function createBitWmsMove(data) {
return request({
url: '/admin-api/erp/bit-wms/move',
method: 'post',
data
})
}
export function getBitWmsLocationLabel(locationId) {
return request({
url: '/admin-api/erp/bit-wms/location-label',
method: 'get',
params: { locationId }
})
}

@ -452,6 +452,48 @@
"navigationStyle": "custom"
}
},
{
"path": "bitWms/scan",
"style": {
"navigationBarTitleText": "BIT样品仓",
"navigationStyle": "custom"
}
},
{
"path": "bitWms/shelf",
"style": {
"navigationBarTitleText": "贴码上架",
"navigationStyle": "custom"
}
},
{
"path": "bitWms/in",
"style": {
"navigationBarTitleText": "样品入库",
"navigationStyle": "custom"
}
},
{
"path": "bitWms/out",
"style": {
"navigationBarTitleText": "样品出库",
"navigationStyle": "custom"
}
},
{
"path": "bitWms/move",
"style": {
"navigationBarTitleText": "样品移库",
"navigationStyle": "custom"
}
},
{
"path": "bitWms/stock",
"style": {
"navigationBarTitleText": "样品库存查询",
"navigationStyle": "custom"
}
},
{
"path": "product/index",
"style": {

@ -0,0 +1,86 @@
<template>
<view class="page">
<NavBar title="样品入库" />
<view class="section">
<view class="scan-row">
<input v-model="sampleCode" class="input" placeholder="扫描或输入样品码" @confirm="scanSample" />
<view class="scan-btn" @click="openScanner('sample')"></view>
</view>
<InfoCard label="样品" :value="sample.name || sample.code || '未选择'" />
<view class="scan-row">
<input v-model="locationCode" class="input" placeholder="扫描或输入库位码" @confirm="scanLocation" />
<view class="scan-btn" @click="openScanner('location')"></view>
</view>
<InfoCard label="库位" :value="location.name || location.code || '未选择'" />
<FormInput v-model="form.count" label="数量" type="digit" placeholder="请输入入库数量" />
<FormInput v-model="form.supplierId" label="供应商ID" type="number" placeholder="可选" />
<FormInput v-model="form.remark" label="备注" placeholder="可选" />
</view>
<view class="submit" @click="submit"></view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import NavBar from '@/components/common/NavBar.vue'
import { scanBitWmsCode, getBitWmsLocationLabel, createBitWmsInbound } from '@/api/erp/bitwms'
import InfoCard from './parts/InfoCard.vue'
import FormInput from './parts/FormInput.vue'
const sampleCode = ref('')
const locationCode = ref('')
const sample = reactive({})
const location = reactive({})
const form = reactive({ count: '', supplierId: '', remark: '' })
const unwrap = (res) => res?.data || res
function openScanner(kind) {
uni.scanCode({
scanType: ['qrCode', 'barCode'],
success: (res) => {
if (kind === 'sample') {
sampleCode.value = String(res.result || '').trim()
scanSample()
} else {
locationCode.value = String(res.result || '').trim()
scanLocation()
}
}
})
}
async function scanSample() {
const data = unwrap(await scanBitWmsCode(sampleCode.value.trim()))
if (data?.type !== 'SAMPLE') return uni.showToast({ title: '请扫描样品码', icon: 'none' })
Object.assign(sample, data)
}
async function scanLocation() {
const data = unwrap(await scanBitWmsCode(locationCode.value.trim()))
if (data?.type !== 'LOCATION') return uni.showToast({ title: '请扫描库位码', icon: 'none' })
const label = unwrap(await getBitWmsLocationLabel(data.id))
Object.assign(location, data, label?.printData || {})
}
async function submit() {
if (!sample.id || !location.warehouseId || !form.count) return uni.showToast({ title: '请完善样品、库位和数量', icon: 'none' })
await createBitWmsInbound({
productId: Number(sample.id),
warehouseId: Number(location.warehouseId),
areaId: location.areaId ? Number(location.areaId) : undefined,
count: Number(form.count),
supplierId: form.supplierId ? Number(form.supplierId) : undefined,
remark: form.remark
})
uni.showToast({ title: '入库成功', icon: 'success' })
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding-bottom: 130rpx; }
.section { padding: 24rpx; }
.scan-row { display: flex; gap: 14rpx; margin-bottom: 18rpx; }
.input { flex: 1; height: 82rpx; padding: 0 22rpx; background: #fff; border-radius: 12rpx; font-size: 28rpx; }
.scan-btn { width: 130rpx; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 12rpx; background: #22486e; color: #fff; font-size: 28rpx; }
.submit { position: fixed; left: 24rpx; right: 24rpx; bottom: 28rpx; height: 88rpx; line-height: 88rpx; text-align: center; border-radius: 16rpx; background: #22486e; color: #fff; font-size: 30rpx; font-weight: 700; }
</style>

@ -0,0 +1,90 @@
<template>
<view class="page">
<NavBar title="样品移库" />
<view class="section">
<view class="scan-row">
<input v-model="sampleCode" class="input" placeholder="扫描或输入样品码" @confirm="scanSample" />
<view class="scan-btn" @click="openScanner('sample')"></view>
</view>
<InfoCard label="样品" :value="sample.name || sample.code || '未选择'" />
<view class="scan-row">
<input v-model="fromLocationCode" class="input" placeholder="扫描或输入调出库位码" @confirm="scanFromLocation" />
<view class="scan-btn" @click="openScanner('from')"></view>
</view>
<InfoCard label="调出库位" :value="fromLocation.name || fromLocation.code || '未选择'" />
<view class="scan-row">
<input v-model="toLocationCode" class="input" placeholder="扫描或输入调入库位码" @confirm="scanToLocation" />
<view class="scan-btn" @click="openScanner('to')"></view>
</view>
<InfoCard label="调入库位" :value="toLocation.name || toLocation.code || '未选择'" />
<FormInput v-model="form.count" label="数量" type="digit" placeholder="请输入移库数量" />
<FormInput v-model="form.remark" label="备注" placeholder="可选" />
</view>
<view class="submit" @click="submit"></view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import NavBar from '@/components/common/NavBar.vue'
import { scanBitWmsCode, getBitWmsLocationLabel, createBitWmsMove } from '@/api/erp/bitwms'
import InfoCard from './parts/InfoCard.vue'
import FormInput from './parts/FormInput.vue'
const sampleCode = ref('')
const fromLocationCode = ref('')
const toLocationCode = ref('')
const sample = reactive({})
const fromLocation = reactive({})
const toLocation = reactive({})
const form = reactive({ count: '', remark: '' })
const unwrap = (res) => res?.data || res
function openScanner(kind) {
uni.scanCode({ scanType: ['qrCode', 'barCode'], success: (res) => {
const value = String(res.result || '').trim()
if (kind === 'sample') { sampleCode.value = value; scanSample() }
if (kind === 'from') { fromLocationCode.value = value; scanFromLocation() }
if (kind === 'to') { toLocationCode.value = value; scanToLocation() }
} })
}
async function scanSample() {
const data = unwrap(await scanBitWmsCode(sampleCode.value.trim()))
if (data?.type !== 'SAMPLE') return uni.showToast({ title: '请扫描样品码', icon: 'none' })
Object.assign(sample, data)
}
async function fillLocation(target, code) {
const data = unwrap(await scanBitWmsCode(code.trim()))
if (data?.type !== 'LOCATION') return uni.showToast({ title: '请扫描库位码', icon: 'none' })
const label = unwrap(await getBitWmsLocationLabel(data.id))
Object.assign(target, data, label?.printData || {})
}
const scanFromLocation = () => fillLocation(fromLocation, fromLocationCode.value)
const scanToLocation = () => fillLocation(toLocation, toLocationCode.value)
async function submit() {
if (!sample.id || !fromLocation.warehouseId || !toLocation.warehouseId || !form.count) return uni.showToast({ title: '请完善样品、库位和数量', icon: 'none' })
await createBitWmsMove({
productId: Number(sample.id),
fromWarehouseId: Number(fromLocation.warehouseId),
fromAreaId: fromLocation.areaId ? Number(fromLocation.areaId) : undefined,
toWarehouseId: Number(toLocation.warehouseId),
toAreaId: toLocation.areaId ? Number(toLocation.areaId) : undefined,
count: Number(form.count),
remark: form.remark
})
uni.showToast({ title: '移库成功', icon: 'success' })
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding-bottom: 130rpx; }
.section { padding: 24rpx; }
.scan-row { display: flex; gap: 14rpx; margin-bottom: 18rpx; }
.input { flex: 1; height: 82rpx; padding: 0 22rpx; background: #fff; border-radius: 12rpx; font-size: 28rpx; }
.scan-btn { width: 130rpx; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 12rpx; background: #22486e; color: #fff; font-size: 28rpx; }
.submit { position: fixed; left: 24rpx; right: 24rpx; bottom: 28rpx; height: 88rpx; line-height: 88rpx; text-align: center; border-radius: 16rpx; background: #22486e; color: #fff; font-size: 30rpx; font-weight: 700; }
</style>

@ -0,0 +1,93 @@
<template>
<view class="page">
<NavBar title="样品出库" />
<view class="section">
<view class="scan-row">
<input v-model="sampleCode" class="input" placeholder="扫描或输入样品码" @confirm="scanSample" />
<view class="scan-btn" @click="openScanner('sample')"></view>
</view>
<InfoCard label="样品" :value="sample.name || sample.code || '未选择'" />
<view class="scan-row">
<input v-model="locationCode" class="input" placeholder="扫描或输入出库库位码" @confirm="scanLocation" />
<view class="scan-btn" @click="openScanner('location')"></view>
</view>
<InfoCard label="库位" :value="location.name || location.code || '未选择'" />
<FormInput v-model="form.count" label="数量" type="digit" placeholder="请输入出库数量" />
<picker :range="reasonLabels" @change="handleReasonChange">
<InfoCard label="出库原因" :value="selectedReasonLabel || '请选择出库原因'" />
</picker>
<FormInput v-model="form.remark" label="备注" placeholder="可选" />
</view>
<view class="submit" @click="submit"></view>
</view>
</template>
<script setup>
import { reactive, ref, computed } from 'vue'
import NavBar from '@/components/common/NavBar.vue'
import { scanBitWmsCode, getBitWmsLocationLabel, createBitWmsOutbound } from '@/api/erp/bitwms'
import InfoCard from './parts/InfoCard.vue'
import FormInput from './parts/FormInput.vue'
const outReasons = [
{ label: '测试', value: 'TEST' },
{ label: '寄样', value: 'SEND_SAMPLE' },
{ label: '领用', value: 'USE' },
{ label: '报废', value: 'SCRAP' },
{ label: '其他', value: 'OTHER' }
]
const sampleCode = ref('')
const locationCode = ref('')
const sample = reactive({})
const location = reactive({})
const form = reactive({ count: '', outReason: '', remark: '' })
const unwrap = (res) => res?.data || res
const reasonLabels = computed(() => outReasons.map((item) => item.label))
const selectedReasonLabel = computed(() => outReasons.find((item) => item.value === form.outReason)?.label || '')
function openScanner(kind) {
uni.scanCode({ scanType: ['qrCode', 'barCode'], success: (res) => {
if (kind === 'sample') { sampleCode.value = String(res.result || '').trim(); scanSample() }
else { locationCode.value = String(res.result || '').trim(); scanLocation() }
} })
}
function handleReasonChange(e) {
form.outReason = outReasons[Number(e.detail.value)]?.value || ''
}
async function scanSample() {
const data = unwrap(await scanBitWmsCode(sampleCode.value.trim()))
if (data?.type !== 'SAMPLE') return uni.showToast({ title: '请扫描样品码', icon: 'none' })
Object.assign(sample, data)
}
async function scanLocation() {
const data = unwrap(await scanBitWmsCode(locationCode.value.trim()))
if (data?.type !== 'LOCATION') return uni.showToast({ title: '请扫描库位码', icon: 'none' })
const label = unwrap(await getBitWmsLocationLabel(data.id))
Object.assign(location, data, label?.printData || {})
}
async function submit() {
if (!sample.id || !location.warehouseId || !form.count || !form.outReason) return uni.showToast({ title: '请完善样品、库位、数量和原因', icon: 'none' })
await createBitWmsOutbound({
productId: Number(sample.id),
warehouseId: Number(location.warehouseId),
areaId: location.areaId ? Number(location.areaId) : undefined,
count: Number(form.count),
outReason: form.outReason,
remark: form.remark
})
uni.showToast({ title: '出库成功', icon: 'success' })
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding-bottom: 130rpx; }
.section { padding: 24rpx; }
.scan-row { display: flex; gap: 14rpx; margin-bottom: 18rpx; }
.input { flex: 1; height: 82rpx; padding: 0 22rpx; background: #fff; border-radius: 12rpx; font-size: 28rpx; }
.scan-btn { width: 130rpx; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 12rpx; background: #22486e; color: #fff; font-size: 28rpx; }
.submit { position: fixed; left: 24rpx; right: 24rpx; bottom: 28rpx; height: 88rpx; line-height: 88rpx; text-align: center; border-radius: 16rpx; background: #22486e; color: #fff; font-size: 30rpx; font-weight: 700; }
</style>

@ -0,0 +1,28 @@
<template>
<view class="form-card">
<text class="label">{{ label }}</text>
<input
class="input"
:value="modelValue"
:type="type"
:placeholder="placeholder"
@input="$emit('update:modelValue', $event.detail.value)"
/>
</view>
</template>
<script setup>
defineProps({
modelValue: { type: [String, Number], default: '' },
label: { type: String, default: '' },
type: { type: String, default: 'text' },
placeholder: { type: String, default: '' }
})
defineEmits(['update:modelValue'])
</script>
<style lang="scss" scoped>
.form-card { margin-bottom: 18rpx; padding: 18rpx 22rpx; background: #fff; border-radius: 12rpx; }
.label { display: block; color: #64748b; font-size: 26rpx; margin-bottom: 10rpx; }
.input { height: 64rpx; font-size: 28rpx; color: #0f172a; }
</style>

@ -0,0 +1,19 @@
<template>
<view class="info-card">
<text class="label">{{ label }}</text>
<text class="value">{{ value }}</text>
</view>
</template>
<script setup>
defineProps({
label: { type: String, default: '' },
value: { type: [String, Number], default: '' }
})
</script>
<style lang="scss" scoped>
.info-card { display: flex; align-items: center; justify-content: space-between; min-height: 82rpx; padding: 0 22rpx; margin-bottom: 18rpx; background: #fff; border-radius: 12rpx; }
.label { color: #64748b; font-size: 26rpx; }
.value { color: #0f172a; font-size: 28rpx; font-weight: 600; max-width: 460rpx; text-align: right; }
</style>

@ -0,0 +1,89 @@
<template>
<view class="page">
<NavBar title="BIT样品仓" />
<view class="hero">
<text class="hero-title">扫码作业</text>
<text class="hero-desc">扫描样品码或库位码快速查看库存信息</text>
</view>
<view class="card">
<input
v-model="code"
class="input"
placeholder="扫码或输入编码"
confirm-type="done"
@confirm="handleManualScan"
/>
<view class="primary-btn" @click="openScanner"></view>
<view class="ghost-btn" @click="handleManualScan"></view>
</view>
<view class="quick-grid">
<view class="quick-item" @click="goPage('shelf')"></view>
<view class="quick-item" @click="goPage('in')"></view>
<view class="quick-item" @click="goPage('out')"></view>
<view class="quick-item" @click="goPage('move')"></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import NavBar from '@/components/common/NavBar.vue'
import { scanBitWmsCode } from '@/api/erp/bitwms'
const code = ref('')
const unwrap = (res) => res?.data || res
function goPage(page) {
uni.navigateTo({ url: `/pages_function/pages/bitWms/${page}` })
}
function openScanner() {
uni.scanCode({
scanType: ['qrCode', 'barCode'],
success: (res) => {
code.value = String(res.result || '').trim()
handleManualScan()
},
fail: () => uni.showToast({ title: '扫码失败', icon: 'none' })
})
}
async function handleManualScan() {
const value = code.value.trim()
if (!value) {
uni.showToast({ title: '请输入或扫描编码', icon: 'none' })
return
}
try {
const data = unwrap(await scanBitWmsCode(value))
if (data?.type === 'SAMPLE') {
uni.navigateTo({ url: `/pages_function/pages/bitWms/stock?productId=${data.id}&code=${encodeURIComponent(data.code || value)}&name=${encodeURIComponent(data.name || '')}` })
return
}
if (data?.type === 'LOCATION') {
uni.navigateTo({ url: `/pages_function/pages/bitWms/stock?locationId=${data.id}&code=${encodeURIComponent(data.code || value)}&name=${encodeURIComponent(data.name || '')}` })
return
}
uni.showToast({ title: '未识别扫码结果', icon: 'none' })
} catch (e) {
uni.showToast({ title: '扫码查询失败', icon: 'none' })
}
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding-bottom: 40rpx; }
.hero { padding: 34rpx 28rpx; background: #22486e; display: flex; flex-direction: column; }
.hero-title { color: #fff; font-size: 42rpx; font-weight: 700; }
.hero-desc { color: rgba(255,255,255,.78); font-size: 26rpx; margin-top: 10rpx; }
.card { margin: 24rpx; padding: 24rpx; background: #fff; border-radius: 18rpx; box-shadow: 0 6rpx 22rpx rgba(15,23,42,.06); }
.input { height: 84rpx; padding: 0 22rpx; border-radius: 12rpx; background: #f8fafc; border: 1rpx solid #d8dee8; font-size: 28rpx; }
.primary-btn, .ghost-btn { height: 84rpx; line-height: 84rpx; text-align: center; border-radius: 14rpx; margin-top: 18rpx; font-size: 30rpx; font-weight: 600; }
.primary-btn { background: #22486e; color: #fff; }
.ghost-btn { background: #eef3f8; color: #22486e; }
.quick-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18rpx; padding: 0 24rpx; }
.quick-item { background: #fff; border-radius: 16rpx; padding: 32rpx 20rpx; text-align: center; color: #1f2937; font-size: 28rpx; box-shadow: 0 4rpx 16rpx rgba(15,23,42,.04); }
</style>

@ -0,0 +1,109 @@
<template>
<view class="page">
<NavBar title="贴码上架" />
<view class="section">
<view class="scan-row">
<input v-model="sampleCode" class="input" placeholder="扫描或输入样品码" @confirm="scanSample" />
<view class="scan-btn" @click="openScanner('sample')"></view>
</view>
<InfoCard label="样品" :value="sample.name || sample.code || '未选择'" />
<view class="scan-row">
<input v-model="fromLocationCode" class="input" placeholder="来源库位码,可选" @confirm="scanFromLocation" />
<view class="scan-btn" @click="openScanner('from')"></view>
</view>
<InfoCard label="来源库位" :value="fromLocation.name || fromLocation.code || '无,按入库处理'" />
<view class="scan-row">
<input v-model="toLocationCode" class="input" placeholder="目标库位码" @confirm="scanToLocation" />
<view class="scan-btn" @click="openScanner('to')"></view>
</view>
<InfoCard label="目标库位" :value="toLocation.name || toLocation.code || '未选择'" />
<FormInput v-model="form.count" label="数量" type="digit" placeholder="请输入上架数量" />
<FormInput v-model="form.remark" label="备注" placeholder="可选" />
</view>
<view class="submit" @click="submit">{{ fromLocation.warehouseId ? '' : '' }}</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import NavBar from '@/components/common/NavBar.vue'
import { scanBitWmsCode, getBitWmsLocationLabel, createBitWmsInbound, createBitWmsMove } from '@/api/erp/bitwms'
import InfoCard from './parts/InfoCard.vue'
import FormInput from './parts/FormInput.vue'
const sampleCode = ref('')
const fromLocationCode = ref('')
const toLocationCode = ref('')
const sample = reactive({})
const fromLocation = reactive({})
const toLocation = reactive({})
const form = reactive({ count: '', remark: '' })
const unwrap = (res) => res?.data || res
function openScanner(kind) {
uni.scanCode({
scanType: ['qrCode', 'barCode'],
success: (res) => {
const value = String(res.result || '').trim()
if (kind === 'sample') { sampleCode.value = value; scanSample() }
if (kind === 'from') { fromLocationCode.value = value; scanFromLocation() }
if (kind === 'to') { toLocationCode.value = value; scanToLocation() }
}
})
}
async function scanSample() {
const data = unwrap(await scanBitWmsCode(sampleCode.value.trim()))
if (data?.type !== 'SAMPLE') return uni.showToast({ title: '请扫描样品码', icon: 'none' })
Object.assign(sample, data)
}
async function fillLocation(target, code) {
const data = unwrap(await scanBitWmsCode(code.trim()))
if (data?.type !== 'LOCATION') {
uni.showToast({ title: '请扫描库位码', icon: 'none' })
return
}
const label = unwrap(await getBitWmsLocationLabel(data.id))
Object.assign(target, data, label?.printData || {})
}
const scanFromLocation = () => fillLocation(fromLocation, fromLocationCode.value)
const scanToLocation = () => fillLocation(toLocation, toLocationCode.value)
async function submit() {
if (!sample.id || !toLocation.warehouseId || !form.count) return uni.showToast({ title: '请完善样品、目标库位和数量', icon: 'none' })
if (fromLocation.warehouseId) {
await createBitWmsMove({
productId: Number(sample.id),
fromWarehouseId: Number(fromLocation.warehouseId),
fromAreaId: fromLocation.areaId ? Number(fromLocation.areaId) : undefined,
toWarehouseId: Number(toLocation.warehouseId),
toAreaId: toLocation.areaId ? Number(toLocation.areaId) : undefined,
count: Number(form.count),
remark: form.remark || '贴码上架'
})
uni.showToast({ title: '移库上架成功', icon: 'success' })
return
}
await createBitWmsInbound({
productId: Number(sample.id),
warehouseId: Number(toLocation.warehouseId),
areaId: toLocation.areaId ? Number(toLocation.areaId) : undefined,
count: Number(form.count),
remark: form.remark || '贴码上架'
})
uni.showToast({ title: '入库上架成功', icon: 'success' })
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding-bottom: 130rpx; }
.section { padding: 24rpx; }
.scan-row { display: flex; gap: 14rpx; margin-bottom: 18rpx; }
.input { flex: 1; height: 82rpx; padding: 0 22rpx; background: #fff; border-radius: 12rpx; font-size: 28rpx; }
.scan-btn { width: 130rpx; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 12rpx; background: #22486e; color: #fff; font-size: 28rpx; }
.submit { position: fixed; left: 24rpx; right: 24rpx; bottom: 28rpx; height: 88rpx; line-height: 88rpx; text-align: center; border-radius: 16rpx; background: #22486e; color: #fff; font-size: 30rpx; font-weight: 700; }
</style>

@ -0,0 +1,48 @@
<template>
<view class="page">
<NavBar title="样品库存查询" />
<view class="card">
<text class="label">扫码对象</text>
<text class="value">{{ typeText }}</text>
</view>
<view class="card">
<text class="label">编码</text>
<text class="value">{{ detail.code || '-' }}</text>
</view>
<view class="card">
<text class="label">名称</text>
<text class="value">{{ detail.name || '-' }}</text>
</view>
<view class="tip">库存明细以 Web 端样品库存查询为准PDA 当前用于扫码识别和现场作业</view>
</view>
</template>
<script setup>
import { reactive, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import NavBar from '@/components/common/NavBar.vue'
const detail = reactive({
productId: undefined,
locationId: undefined,
code: '',
name: ''
})
const typeText = computed(() => detail.productId ? '样品' : detail.locationId ? '库位' : '未识别')
onLoad((options = {}) => {
detail.productId = options.productId
detail.locationId = options.locationId
detail.code = decodeURIComponent(options.code || '')
detail.name = decodeURIComponent(options.name || '')
})
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f6f8; padding: 24rpx; }
.card { background: #fff; border-radius: 16rpx; padding: 26rpx; margin-bottom: 18rpx; display: flex; justify-content: space-between; box-shadow: 0 4rpx 16rpx rgba(15,23,42,.04); }
.label { color: #64748b; font-size: 26rpx; }
.value { color: #0f172a; font-size: 30rpx; font-weight: 600; max-width: 460rpx; text-align: right; }
.tip { margin-top: 26rpx; color: #64748b; font-size: 26rpx; line-height: 1.6; }
</style>

@ -17,6 +17,23 @@ const MENU_ROUTE_MAP = {
planprogress: '/page_report/planProgress',
'仓库信息': '/pages_function/pages/warehouse/index',
warehouse: '/pages_function/pages/warehouse/index',
'BIT样品仓': '/pages_function/pages/bitWms/scan',
bitwms: '/pages_function/pages/bitWms/scan',
'贴码上架': '/pages_function/pages/bitWms/shelf',
'样品入库': '/pages_function/pages/bitWms/in',
'样品出库': '/pages_function/pages/bitWms/out',
'样品移库': '/pages_function/pages/bitWms/move',
'样品库存查询': '/pages_function/pages/bitWms/stock',
'erp:bit-wms:shelf': '/pages_function/pages/bitWms/shelf',
'erp:bit-wms:inbound': '/pages_function/pages/bitWms/in',
'erp:bit-wms:outbound': '/pages_function/pages/bitWms/out',
'erp:bit-wms:move': '/pages_function/pages/bitWms/move',
'erp:bit-wms:stock:query': '/pages_function/pages/bitWms/stock',
erpbitwmsshelf: '/pages_function/pages/bitWms/shelf',
erpbitwmsinbound: '/pages_function/pages/bitWms/in',
erpbitwmsoutbound: '/pages_function/pages/bitWms/out',
erpbitwmsmove: '/pages_function/pages/bitWms/move',
erpbitwmsstockquery: '/pages_function/pages/bitWms/stock',
'检验类型': '/pages_function/pages/inspection/index',
inspection: '/pages_function/pages/inspection/index',
'检验项库': '/pages_function/pages/inspectionItem/index',

Loading…
Cancel
Save