feat: 备件模块仓库默认为备件仓,优化盘点和筛选交互

master
zhongwenkai 4 days ago
parent 099e3ae386
commit 35065a0027

@ -1458,8 +1458,8 @@ export default {
sparepartInventory: {
moduleName: '备件库存查询',
searchPlaceholder: '请输入备件编码或名称',
allWarehouse: '全部仓库',
warehousePlaceholder: '仓库筛选',
allArea: '全部库区',
areaPlaceholder: '库区筛选',
productName: '物料名称',
barCode: '物料编码',
warehouse: '仓库',

@ -1,15 +1,20 @@
<template>
<view class="page-container">
<NavBar :title="'新增盘点单'" />
<NavBar :title="'新增备件盘点单'" />
<!-- 盘点时间 -->
<view class="section-title-bar">
<view class="section-bar-line"></view>
<text class="section-title"><text class="required">*</text>盘点时间</text>
</view>
<view class="form-row-card" @click="openDateTimePicker">
<text :class="{ placeholder: !checkTime }">{{ checkTime || '请选择盘点时间' }}</text>
<text class="form-row-arrow"></text>
<view class="form-row-card datetime-picker-card">
<uni-datetime-picker
v-model="checkTime"
type="datetime"
placeholder="请选择盘点时间"
:clear-icon="false"
return-type="string"
/>
</view>
<!-- 生成来源 -->
@ -26,15 +31,6 @@
</view>
</view>
<!-- 分类固定为备件 -->
<view class="section-title-bar">
<view class="section-bar-line"></view>
<text class="section-title">分类</text>
</view>
<view class="form-row-card" style="margin-bottom: 16rpx;">
<text>备件</text>
</view>
<!-- 按库存仓库/库区/盘点项 -->
<template v-if="sourceType === 1">
<view class="section-title-bar">
@ -43,27 +39,17 @@
</view>
<view class="select-row-card">
<view class="warehouse-area-rows">
<!-- 仓库 -->
<!-- 仓库固定为备件仓不可选 -->
<view class="warehouse-area-row">
<text class="warehouse-area-label">仓库</text>
<view class="warehouse-area-dropdown" @click="toggleWarehouseDropdown">
<view class="warehouse-area-dropdown">
<view class="dropdown-input">
<text :class="['dropdown-value', { placeholder: !selectedWarehouse }]">{{ selectedWarehouse ? selectedWarehouse.label : '请选择' }}</text>
<text class="dropdown-arrow"></text>
</view>
<view v-if="showWarehouseDropdown" class="dropdown-panel">
<view class="dropdown-scroll">
<view v-for="w in warehouseOptions" :key="w.value" class="dropdown-item" :class="{ active: selectedWarehouse?.value === w.value }" @click.stop="handleSelectWarehouse(w)">
<text class="dropdown-item-text">{{ w.label }}</text>
<text v-if="selectedWarehouse?.value === w.value" class="dropdown-check"></text>
</view>
<view v-if="!warehouseOptions.length" class="dropdown-empty"></view>
</view>
<text class="dropdown-value">备件仓</text>
</view>
</view>
</view>
<!-- 库区 -->
<view class="warehouse-area-row" v-if="selectedWarehouse">
<view class="warehouse-area-row">
<text class="warehouse-area-label">库区</text>
<view class="warehouse-area-dropdown" @click="toggleAreaDropdown">
<view class="dropdown-input">
@ -181,6 +167,7 @@
import { ref } from 'vue'
import { onShow, onHide } from '@dcloudio/uni-app'
import NavBar from '@/components/common/NavBar.vue'
import UniDatetimePicker from '@dcloudio/uni-ui/lib/uni-datetime-picker/uni-datetime-picker.vue'
import { getWarehousePage, getWarehouseAreaSimpleList } from '@/api/mes/moldget'
import { createCheck } from '@/api/mes/sparepartCheck'
@ -198,13 +185,11 @@ function switchSourceType(type) {
items.value = []
selectedProducts.value = []
selectedArea.value = null
selectedWarehouse.value = null
}
//
const warehouseOptions = ref([])
const selectedWarehouse = ref(null)
const showWarehouseDropdown = ref(false)
//
const areaOptions = ref([])
@ -226,32 +211,23 @@ function textValue(v) {
return s || '-'
}
function openDateTimePicker() {
uni.showToast({ title: '默认当前时间', icon: 'none' })
}
//
//
async function loadWarehouses() {
try {
const res = await getWarehousePage({ pageNo: 1, pageSize: 100, categoryType: 3 })
const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : (Array.isArray(res?.data?.list) ? res.data.list : []))
console.log('[loadWarehouses] categoryType=3, data:', data)
warehouseOptions.value = data.map(w => ({ value: w.id, label: w.name || String(w.id) }))
//
if (warehouseOptions.value.length && !selectedWarehouse.value) {
selectedWarehouse.value = warehouseOptions.value[0]
loadAreas(selectedWarehouse.value.value)
}
} catch (e) {
console.error('loadWarehouses error', e)
}
}
//
function toggleWarehouseDropdown() { showWarehouseDropdown.value = !showWarehouseDropdown.value }
function handleSelectWarehouse(w) {
selectedWarehouse.value = w
showWarehouseDropdown.value = false
selectedArea.value = null
areaOptions.value = []
items.value = []
loadAreas(w.value)
}
async function loadAreas(warehouseId) {
if (!warehouseId) return
loadingAreas.value = true
@ -374,7 +350,6 @@ onShow(() => {
})
onHide(() => {
showWarehouseDropdown.value = false
showAreaDropdown.value = false
})
</script>
@ -402,6 +377,14 @@ onHide(() => {
.placeholder { color: #9ca3af; }
}
.form-row-arrow { font-size: 20rpx; color: #999; }
.datetime-picker-card {
flex-direction: column;
align-items: stretch;
padding: 16rpx 24rpx;
:deep(.uni-date) {
width: 100%;
}
}
/* 单选组 */
.radio-group { display: flex; gap: 12rpx; padding: 0 24rpx 16rpx; }

@ -61,29 +61,12 @@
</view>
<view class="select-row-card warehouse-area-card">
<view class="warehouse-area-rows">
<!-- 仓库固定为备件仓不可选 -->
<view class="warehouse-area-row">
<text class="warehouse-area-label">仓库</text>
<view class="warehouse-area-dropdown" @click="toggleWarehouseDropdown">
<view class="warehouse-area-dropdown">
<view class="dropdown-input">
<text :class="['dropdown-value', { placeholder: !selectedWarehouse }]">
{{ selectedWarehouse ? selectedWarehouse.label : '请选择' }}
</text>
<text class="dropdown-arrow"></text>
</view>
<view v-if="showWarehouseDropdown" class="dropdown-panel">
<view class="dropdown-scroll">
<view
v-for="item in warehouseOptions"
:key="item.value"
class="dropdown-item"
:class="{ active: selectedWarehouse?.value === item.value }"
@click.stop="handleSelectWarehouse(item)"
>
<text class="dropdown-item-text">{{ item.label }}</text>
<text v-if="selectedWarehouse?.value === item.value" class="dropdown-check"></text>
</view>
<view v-if="!warehouseOptions.length" class="dropdown-empty"></view>
</view>
<text class="dropdown-value">备件仓</text>
</view>
</view>
</view>
@ -176,10 +159,9 @@ const inboundQty = ref(null)
const supplierId = ref(undefined)
const supplierName = ref('')
//
//
const warehouseOptions = ref([])
const selectedWarehouse = ref(null)
const showWarehouseDropdown = ref(false)
//
const areaOptions = ref([])
@ -287,16 +269,6 @@ function handleConfirm() {
}
//
function toggleWarehouseDropdown() {
showWarehouseDropdown.value = !showWarehouseDropdown.value
}
function handleSelectWarehouse(item) {
selectedWarehouse.value = item
showWarehouseDropdown.value = false
selectedArea.value = null
areaOptions.value = []
loadAreas(item.value)
}
async function loadWarehouses() {
try {
const res = await getWarehouseSimpleList()
@ -305,6 +277,11 @@ async function loadWarehouses() {
value: w.id,
label: w.name || String(w.id || '')
}))
//
if (warehouseOptions.value.length && !selectedWarehouse.value) {
selectedWarehouse.value = warehouseOptions.value[0]
loadAreas(selectedWarehouse.value.value)
}
} catch (e) {
console.error('loadWarehouses error', e)
}
@ -377,7 +354,6 @@ async function loadStockCount() {
}
onHide(() => {
showWarehouseDropdown.value = false
showAreaDropdown.value = false
})
</script>

@ -15,8 +15,8 @@
@confirm="onScanInputConfirm"
/>
</view>
<view class="warehouse-box" @click="openWarehousePicker">
<text class="warehouse-box-text">{{ selectedWarehouseLabel || t('sparepartInventory.allWarehouse') }}</text>
<view class="area-box" @click="openAreaPicker">
<text class="area-box-text">{{ selectedAreaLabel || t('sparepartInventory.allArea') }}</text>
<uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons>
</view>
<view class="reset-filter-btn" @click="resetFilters">{{ t('functionCommon.reset') }}</view>
@ -86,23 +86,23 @@
<sv-focus-no-keyboard ref="focusNoKeyboardRef"></sv-focus-no-keyboard>
<uni-popup ref="warehousePickerRef" type="bottom" background-color="#fff">
<uni-popup ref="areaPickerRef" type="bottom" background-color="#fff">
<view class="picker-content">
<view class="picker-header">
<text class="picker-title">{{ t('sparepartInventory.warehousePlaceholder') }}</text>
<view class="picker-clear" @click="resetWarehouse">
<text class="picker-title">{{ t('sparepartInventory.areaPlaceholder') }}</text>
<view class="picker-clear" @click="resetArea">
<text class="picker-clear-text">{{ t('functionCommon.reset') }}</text>
</view>
</view>
<scroll-view scroll-y class="picker-list">
<view
v-for="item in warehouseOptions"
v-for="item in areaOptions"
:key="String(item.value)"
class="picker-item"
@click="selectWarehouse(item)"
@click="selectArea(item)"
>
<text class="picker-text">{{ item.label }}</text>
<text v-if="selectedWarehouse === item.value" class="picker-check"></text>
<text v-if="selectedArea === item.value" class="picker-check"></text>
</view>
</scroll-view>
</view>
@ -115,10 +115,11 @@ import { ref, computed, nextTick } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { useI18n } from 'vue-i18n'
import NavBar from '@/components/common/NavBar.vue'
import { getSparepartInventoryPage, getWarehouseSimpleList } from '@/api/mes/sparepart'
import { getSparepartInventoryPage } from '@/api/mes/sparepart'
import { getWarehousePage, getWarehouseAreaSimpleList } from '@/api/mes/moldget'
const { t } = useI18n()
const warehousePickerRef = ref(null)
const areaPickerRef = ref(null)
const list = ref([])
const loading = ref(false)
@ -128,9 +129,10 @@ const pageNo = ref(1)
const pageSize = ref(10)
const total = ref(0)
const searchKeyword = ref('')
const selectedWarehouse = ref('')
const selectedArea = ref('')
const warehouseOptions = ref([])
const areaOptions = ref([])
const sparepartWarehouseId = ref(null)
//
const focusNoKeyboardRef = ref(null)
@ -144,13 +146,13 @@ function focusKeywordNoKeyboard() {
})
}
const selectedWarehouseLabel = computed(() => {
const current = warehouseOptions.value.find((item) => item.value === selectedWarehouse.value)
const selectedAreaLabel = computed(() => {
const current = areaOptions.value.find((item) => item.value === selectedArea.value)
return current ? current.label : ''
})
onLoad(async () => {
await loadWarehouseList()
await loadWarehouseThenAreas()
await fetchList(true)
})
@ -158,23 +160,30 @@ onReady(() => {
focusKeywordNoKeyboard()
})
async function loadWarehouseList() {
async function loadWarehouseThenAreas() {
try {
const res = await getWarehouseSimpleList()
const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : [])
warehouseOptions.value = data.map((w) => ({
value: String(w.id),
label: w.name || w.warehouseName || String(w.id)
}))
// categoryType=3
const whRes = await getWarehousePage({ pageNo: 1, pageSize: 1, categoryType: 3 })
const whData = Array.isArray(whRes) ? whRes : (Array.isArray(whRes?.data) ? whRes.data : (Array.isArray(whRes?.data?.list) ? whRes.data.list : []))
if (whData.length) {
sparepartWarehouseId.value = whData[0].id
//
const areaRes = await getWarehouseAreaSimpleList(sparepartWarehouseId.value)
const areaData = Array.isArray(areaRes) ? areaRes : (Array.isArray(areaRes?.data) ? areaRes.data : [])
areaOptions.value = areaData.map((a) => ({
value: String(a.id),
label: a.name || a.areaName || String(a.id)
}))
}
} catch (e) {
console.error('loadWarehouseList error', e)
console.error('loadWarehouseThenAreas error', e)
}
}
//
const allList = ref([])
async function fetchAllForSearch(warehouseId) {
async function fetchAllForSearch(areaId) {
const all = []
let currentPage = 1
const maxPage = 10 // 10
@ -183,7 +192,7 @@ async function fetchAllForSearch(warehouseId) {
pageNo: currentPage,
pageSize: 100,
categoryType: 3,
warehouseId: warehouseId || undefined
areaId: areaId || undefined
})
const page = normalizePageData(res)
all.push(...page.list)
@ -208,7 +217,7 @@ async function fetchList(reset) {
if (keyword && reset) {
//
const allData = await fetchAllForSearch(selectedWarehouse.value)
const allData = await fetchAllForSearch(selectedArea.value)
allList.value = allData
// ID PRODUCTMATERIAL-330
const scanMatch = keyword.match(/(?:productmaterial|spare|material|product)[-_](\d+)/i)
@ -232,7 +241,7 @@ async function fetchList(reset) {
pageNo: pageNo.value,
pageSize: pageSize.value,
categoryType: 3,
warehouseId: selectedWarehouse.value || undefined
areaId: selectedArea.value || undefined
})
const page = normalizePageData(res)
total.value = page.total
@ -270,7 +279,7 @@ async function onScanInputConfirm() {
async function resetFilters() {
searchKeyword.value = ''
selectedWarehouse.value = ''
selectedArea.value = ''
allList.value = []
//
pageNo.value = 1
@ -278,22 +287,22 @@ async function resetFilters() {
await fetchList(true)
}
function openWarehousePicker() {
warehousePickerRef.value?.open()
function openAreaPicker() {
areaPickerRef.value?.open()
}
async function selectWarehouse(item) {
selectedWarehouse.value = item.value
warehousePickerRef.value?.close()
async function selectArea(item) {
selectedArea.value = item.value
areaPickerRef.value?.close()
allList.value = []
pageNo.value = 1
finished.value = false
await fetchList(true)
}
async function resetWarehouse() {
selectedWarehouse.value = ''
warehousePickerRef.value?.close()
async function resetArea() {
selectedArea.value = ''
areaPickerRef.value?.close()
allList.value = []
pageNo.value = 1
finished.value = false
@ -385,7 +394,7 @@ function formatDateTime(value) {
color: #9ca3af;
}
.warehouse-box {
.area-box {
flex-shrink: 0;
display: flex;
align-items: center;
@ -399,7 +408,7 @@ function formatDateTime(value) {
box-sizing: border-box;
}
.warehouse-box-text {
.area-box-text {
color: #374151;
font-size: 26rpx;
max-width: 110rpx;

@ -100,20 +100,12 @@
</view>
<view class="select-row-card warehouse-area-card">
<view class="warehouse-area-rows">
<!-- 仓库固定为备件仓不可选 -->
<view class="warehouse-area-row">
<text class="warehouse-area-label">仓库</text>
<view class="warehouse-area-dropdown" @click="toggleWarehouseDropdown">
<view class="warehouse-area-dropdown">
<view class="dropdown-input">
<text :class="['dropdown-value', { placeholder: !selectedWarehouse }]">{{ selectedWarehouse ? selectedWarehouse.label : '请选择' }}</text>
<text class="dropdown-arrow"></text>
</view>
<view v-if="showWarehouseDropdown" class="dropdown-panel">
<view class="dropdown-scroll">
<view v-for="item in warehouseOptions" :key="item.value" class="dropdown-item" :class="{ active: selectedWarehouse?.value === item.value }" @click.stop="handleSelectWarehouse(item)">
<text class="dropdown-item-text">{{ item.label }}</text>
<text v-if="selectedWarehouse?.value === item.value" class="dropdown-check"></text>
</view>
</view>
<text class="dropdown-value">备件仓</text>
</view>
</view>
</view>
@ -228,7 +220,6 @@ const currentOrderOptions = computed(() => selectedPurpose.value === 'repair' ?
const warehouseOptions = ref([])
const selectedWarehouse = ref(null)
const showWarehouseDropdown = ref(false)
const areaOptions = ref([])
const selectedArea = ref(null)
const showAreaDropdown = ref(false)
@ -458,13 +449,16 @@ async function loadRepairOrdersById(deviceId) {
} catch (e) { console.error('loadRepairOrdersById error', e) }
}
function toggleWarehouseDropdown() { showWarehouseDropdown.value = !showWarehouseDropdown.value }
function handleSelectWarehouse(item) { selectedWarehouse.value = item; showWarehouseDropdown.value = false; selectedArea.value = null; areaOptions.value = []; warehouseAreaStockCount.value = 0; loadAreas(item.value) }
async function loadWarehouses() {
try {
const res = await getWarehouseSimpleList()
const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : [])
warehouseOptions.value = data.map(w => ({ value: w.id, label: w.name || String(w.id || '') }))
//
if (warehouseOptions.value.length && !selectedWarehouse.value) {
selectedWarehouse.value = warehouseOptions.value[0]
loadAreas(selectedWarehouse.value.value)
}
} catch (e) {}
}

Loading…
Cancel
Save