|
|
|
|
@ -6,9 +6,15 @@
|
|
|
|
|
<view class="keyword-box">
|
|
|
|
|
<input v-model="searchKeyword" class="keyword-input" :placeholder="t('sparepartOutbound.searchPlaceholder')" confirm-type="search" @input="handleKeywordInput" @confirm="handleSearch" />
|
|
|
|
|
</view>
|
|
|
|
|
<picker mode="selector" :range="statusLabels" :value="statusIndex" @change="onStatusChange">
|
|
|
|
|
<view class="status-box"><text class="status-box-text">{{ currentStatusLabel }}</text><uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons></view>
|
|
|
|
|
</picker>
|
|
|
|
|
<view class="status-box-wrapper">
|
|
|
|
|
<view class="status-box" @click="toggleStatusDropdown"><text class="status-box-text">{{ currentStatusLabel }}</text><uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons></view>
|
|
|
|
|
<view v-if="showStatusDropdown" class="status-dropdown-panel">
|
|
|
|
|
<view v-for="(item, idx) in statusOptions" :key="idx" class="status-dropdown-item" :class="{ active: selectedStatus === item.value }" @click.stop="selectStatus(item, idx)">
|
|
|
|
|
<text class="status-dropdown-item-text">{{ item.label }}</text>
|
|
|
|
|
<text v-if="selectedStatus === item.value" class="status-dropdown-check">✓</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="reset-filter-btn" @click="resetFilters">{{ t('functionCommon.reset') }}</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
@ -83,7 +89,7 @@
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
|
import { onShow, onUnload } from '@dcloudio/uni-app'
|
|
|
|
|
import { onShow, onUnload, onHide } from '@dcloudio/uni-app'
|
|
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
|
import NavBar from '@/components/common/NavBar.vue'
|
|
|
|
|
import { getSparepartOutboundPage, auditSparepartOutbound, submitSparepartOutbound } from '@/api/mes/sparepartOutbound'
|
|
|
|
|
@ -93,14 +99,14 @@ const { t } = useI18n()
|
|
|
|
|
|
|
|
|
|
const selectedStatus = ref('')
|
|
|
|
|
const searchKeyword = ref('')
|
|
|
|
|
const showStatusDropdown = ref(false)
|
|
|
|
|
const statusOptions = computed(() => [
|
|
|
|
|
{ label: t('functionCommon.all'), value: '' },
|
|
|
|
|
{ label: t('sparepartOutbound.tabPending'), value: '0' },
|
|
|
|
|
{ label: t('sparepartOutbound.tabAuditing'), value: '10' },
|
|
|
|
|
{ label: t('sparepartOutbound.approve'), value: '20' }
|
|
|
|
|
{ label: t('sparepartOutbound.approve'), value: '20' },
|
|
|
|
|
{ label: '已驳回', value: '1' }
|
|
|
|
|
])
|
|
|
|
|
const statusLabels = computed(() => statusOptions.value.map(i => i.label))
|
|
|
|
|
const statusIndex = computed(() => { const idx = statusOptions.value.findIndex(i => i.value === selectedStatus.value); return idx >= 0 ? idx : 0 })
|
|
|
|
|
const currentStatusLabel = computed(() => { const cur = statusOptions.value.find(i => i.value === selectedStatus.value); return cur ? cur.label : t('functionCommon.all') })
|
|
|
|
|
const list = ref([])
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
@ -142,7 +148,7 @@ async function fetchList(reset) {
|
|
|
|
|
if (reset) { pageNo.value = 1; finished.value = false }
|
|
|
|
|
if (pageNo.value === 1) loading.value = true; else loadingMore.value = true
|
|
|
|
|
try {
|
|
|
|
|
const params = { pageNo: pageNo.value, pageSize: pageSize.value, no: searchKeyword.value.trim() || undefined, status: selectedStatus.value || undefined }
|
|
|
|
|
const params = { pageNo: pageNo.value, pageSize: pageSize.value, no: searchKeyword.value.trim() || undefined, statusList: selectedStatus.value !== '' ? [Number(selectedStatus.value)] : undefined }
|
|
|
|
|
const res = await getSparepartOutboundPage(params)
|
|
|
|
|
const page = normalizePageData(res)
|
|
|
|
|
list.value = reset ? page.list : [...list.value, ...page.list]
|
|
|
|
|
@ -151,7 +157,8 @@ async function fetchList(reset) {
|
|
|
|
|
finally { loading.value = false; loadingMore.value = false }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onStatusChange(e) { const idx = Number(e?.detail?.value || 0); selectedStatus.value = statusOptions.value[idx]?.value ?? ''; fetchList(true) }
|
|
|
|
|
function toggleStatusDropdown() { showStatusDropdown.value = !showStatusDropdown.value }
|
|
|
|
|
function selectStatus(item, _idx) { selectedStatus.value = item.value; showStatusDropdown.value = false; fetchList(true) }
|
|
|
|
|
function handleSearch() { clearSearchTimer(); uni.hideKeyboard(); fetchList(true) }
|
|
|
|
|
function handleKeywordInput() { clearSearchTimer(); searchTimer = setTimeout(() => fetchList(true), 300) }
|
|
|
|
|
function resetFilters() { clearSearchTimer(); searchKeyword.value = ''; selectedStatus.value = ''; fetchList(true) }
|
|
|
|
|
@ -198,6 +205,7 @@ function clearSearchTimer() { if (searchTimer) { clearTimeout(searchTimer); sear
|
|
|
|
|
|
|
|
|
|
onShow(() => { fetchList(true) })
|
|
|
|
|
onUnload(() => { clearSearchTimer() })
|
|
|
|
|
onHide(() => { showStatusDropdown.value = false })
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
@ -205,7 +213,12 @@ onUnload(() => { clearSearchTimer() })
|
|
|
|
|
.filter-bar { display: flex; align-items: center; gap: 12rpx; padding: 18rpx 24rpx; background: #fff; }
|
|
|
|
|
.keyword-box { flex: 1; min-width: 0; height: 66rpx; padding: 0 28rpx; background: #f4f5f7; border: 1rpx solid #e5e7eb; border-radius: 12rpx; display: flex; align-items: center; }
|
|
|
|
|
.keyword-input { width: 100%; font-size: 24rpx; color: #374151; }
|
|
|
|
|
.status-box { flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; height: 66rpx; padding: 0 28rpx; min-width: 160rpx; background: #fff; border: 1rpx solid #e5e7eb; border-radius: 12rpx; }
|
|
|
|
|
.status-box-wrapper { position: relative; flex-shrink: 0; }
|
|
|
|
|
.status-box { display: flex; align-items: center; justify-content: space-between; height: 66rpx; padding: 0 28rpx; min-width: 160rpx; background: #fff; border: 1rpx solid #e5e7eb; border-radius: 12rpx; }
|
|
|
|
|
.status-dropdown-panel { position: absolute; top: 74rpx; left: 0; right: 0; z-index: 200; background: #fff; border: 1rpx solid #e0e0e0; border-radius: 12rpx; box-shadow: 0 8rpx 30rpx rgba(0,0,0,0.12); overflow: hidden; }
|
|
|
|
|
.status-dropdown-item { display: flex; align-items: center; justify-content: space-between; padding: 18rpx 24rpx; border-bottom: 1rpx solid #f0f0f0; &:last-child { border-bottom: 0; } &.active { background: #f0f5ff; } }
|
|
|
|
|
.status-dropdown-item-text { font-size: 26rpx; color: #374151; }
|
|
|
|
|
.status-dropdown-check { font-size: 26rpx; color: #2563eb; font-weight: 700; }
|
|
|
|
|
.status-box-text { font-size: 24rpx; color: #374151; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
.reset-filter-btn { height: 66rpx; line-height: 66rpx; padding: 0 28rpx; font-size: 24rpx; color: #4b5563; background: #fff; border: 1rpx solid #e5e7eb; border-radius: 12rpx; flex-shrink: 0; }
|
|
|
|
|
|
|
|
|
|
|