feat: 统一列表筛选缓存高亮并精简底部Tab

This commit is contained in:
2026-10-08 17:59:54 +08:00
parent 30e20853df
commit b259e0c2e7
11 changed files with 704 additions and 255 deletions
@@ -1,9 +1,28 @@
<template>
<view>
<view class="filterBar">
<u-search v-model="filters.order_no" placeholder="出仓单号" :show-action="false" @search="loadList" @custom="loadList" />
<view class="filterBtn" @click="filterShow = true">
<u-icon name="list" size="40" color="#666"></u-icon>
<u-search
v-model="filters.order_no"
placeholder="出仓单号"
:show-action="false"
@search="applySearch"
@custom="applySearch"
@clear="applySearch"
/>
<view
class="filterBtn"
:class="{ 'filter-active': hasActiveFilter }"
@click="filterShow = true"
>
<view class="filterBtn__icon">
<u-icon
:key="hasActiveFilter ? 'on' : 'off'"
name="list"
size="44"
:color="hasActiveFilter ? '#2979ff' : '#666'"
></u-icon>
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
</view>
<text>筛选</text>
</view>
</view>
@@ -20,22 +39,34 @@
<addBtn url="./storeFabricBusinessOutAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">出仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入出仓单号" />
<view class="filterInput">
<u-input
v-model="filters.order_no"
placeholder="请输入出仓单号"
:height="100"
:custom-style="{ fontSize: '36rpx', color: '#202328' }"
placeholder-style="color: #aeb4bf; font-size: 34rpx;"
/>
</view>
</view>
<view class="filterItem">
<text class="filterLabel">出仓日期</text>
<view class="dateRow">
<picker mode="date" :value="filters.start_date" @change="e => filters.start_date = e.detail.value">
<view class="dateInput">{{ filters.start_date || '开始日期' }}</view>
<picker class="datePicker" mode="date" :value="filters.start_date" @change="e => filters.start_date = e.detail.value">
<view class="dateInput" :class="{ 'dateInput--placeholder': !filters.start_date }">
{{ filters.start_date || '开始日期' }}
</view>
</picker>
<text>~</text>
<picker mode="date" :value="filters.end_date" @change="e => filters.end_date = e.detail.value">
<view class="dateInput">{{ filters.end_date || '结束日期' }}</view>
<text class="dateSeparator">~</text>
<picker class="datePicker" mode="date" :value="filters.end_date" @change="e => filters.end_date = e.detail.value">
<view class="dateInput" :class="{ 'dateInput--placeholder': !filters.end_date }">
{{ filters.end_date || '结束日期' }}
</view>
</picker>
</view>
</view>
@@ -45,11 +76,11 @@
<!-- </view>-->
<view class="filterItem" @click="openBusinessUnitSelect">
<text class="filterLabel">染厂</text>
<view class="filterValue">{{ businessUnitLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ businessUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
@@ -58,8 +89,25 @@
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
<u-select
class="pdaSelect"
v-model="statusSelectShow"
title="选择订单状态"
:list="statusSelectList"
:default-value="statusSelectDefault"
@confirm="onStatusConfirm"
></u-select>
<u-select
class="pdaSelect"
v-model="unitSelectShow"
title="选择染厂"
:list="unitSelectList"
:default-value="unitSelectDefault"
remote
:loading="selectSearching"
@search="onUnitSearch"
@confirm="onUnitConfirm"
></u-select>
</view>
</template>
@@ -68,6 +116,7 @@ import addBtn from '@/components/addBtn/addBtn.vue';
import FabricOutItem from '@/components/card/storeFabricBusinessOutItem.vue';
import {
getStatusOptions,
AUDIT_STATUS,
AUDIT_STATUS_MAP,
BILL_TYPES,
BUSINESS_UNIT_TYPE_DYE_FACTORY,
@@ -77,6 +126,45 @@ import {
} from '@/common/storeFabricBusinessOut';
import { withNameParam } from '@/common/remoteSelect';
const FILTER_STORAGE_KEY = 'storeFabricBusinessOutListFilters_v2';
const hasFilterValue = (value) => value !== '' && value !== null && value !== undefined;
const normalizeAuditStatus = (value) => {
if (!hasFilterValue(value)) return '';
const status = Number(value);
return Number.isNaN(status) ? '' : status;
};
const createDefaultFilters = () => ({
order_no: '',
start_date: '',
end_date: '',
delivery_unit_id: '',
delivery_unit_name: '',
business_unit_id: '',
business_unit_name: '',
audit_status: AUDIT_STATUS.PENDING,
});
const normalizeFilters = (value) => {
const filters = createDefaultFilters();
if (!value || typeof value !== 'object' || Array.isArray(value)) return filters;
Object.keys(filters).forEach((key) => {
if (key === 'audit_status') return;
if (typeof value[key] === 'string' || typeof value[key] === 'number') {
filters[key] = value[key];
}
});
if (!filters.delivery_unit_id) filters.delivery_unit_name = '';
if (!filters.business_unit_id) filters.business_unit_name = '';
if (Object.prototype.hasOwnProperty.call(value, 'audit_status')) {
filters.audit_status = normalizeAuditStatus(value.audit_status);
}
return filters;
};
export default {
components: { addBtn, FabricOutItem },
data() {
@@ -95,16 +183,8 @@ export default {
unitSearchSeq: 0,
unitSelectList: [{ value: '', label: '全部' }],
billTypeName: (BILL_TYPES[0] || {}).label || '坯布其他出货单',
filters: {
order_no: '',
start_date: '',
end_date: '',
delivery_unit_id: '',
delivery_unit_name: '',
business_unit_id: '',
business_unit_name: '',
audit_status: '',
},
filters: createDefaultFilters(),
appliedFilters: createDefaultFilters(),
statusSelectList: [
{ value: '', label: '全部' },
...getStatusOptions(),
@@ -122,20 +202,85 @@ export default {
businessUnitLabel() {
return this.filters.business_unit_name || '';
},
statusSelectDefault() {
const index = this.statusSelectList.findIndex(
(item) => String(item.value) === String(this.filters.audit_status)
);
return [index >= 0 ? index : 0];
},
unitSelectDefault() {
const selectedValue = this.unitSelectType === 'delivery'
? this.filters.delivery_unit_id
: this.filters.business_unit_id;
const index = this.unitSelectList.findIndex(
(item) => String(item.value) === String(selectedValue)
);
return [index >= 0 ? index : 0];
},
hasActiveFilter() {
const filters = this.appliedFilters || {};
return Boolean(
String(filters.order_no || '').trim()
|| filters.start_date
|| filters.end_date
|| filters.delivery_unit_id
|| filters.business_unit_id
|| hasFilterValue(filters.audit_status)
);
},
},
onLoad() {
uni.setNavigationBarTitle({ title: '坯布出库列表' });
this.restoreFilterCache();
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
},
});
this.loadList();
},
onShow() {
this.loadList();
},
methods: {
restoreFilterCache() {
try {
const cached = uni.getStorageSync(FILTER_STORAGE_KEY);
if (!cached || typeof cached !== 'object' || Array.isArray(cached)) {
const filters = createDefaultFilters();
this.filters = { ...filters };
this.appliedFilters = { ...filters };
this.saveFilterCache();
return;
}
const filters = normalizeFilters(cached);
this.filters = { ...filters };
this.appliedFilters = { ...filters };
} catch (e) {
const filters = createDefaultFilters();
this.filters = { ...filters };
this.appliedFilters = { ...filters };
}
},
saveFilterCache() {
try {
uni.setStorageSync(FILTER_STORAGE_KEY, { ...this.appliedFilters });
} catch (e) {
// 缓存失败不影响列表筛选
}
},
commitFilters() {
const filters = normalizeFilters(this.filters);
this.filters = { ...filters };
this.appliedFilters = { ...filters };
this.saveFilterCache();
this.loadList();
},
applySearch() {
this.commitFilters();
},
cancelFilterEdit() {
this.filters = { ...this.appliedFilters };
},
loadDeliveryUnitOptions() {
if (this.deliveryUnitOptions.length) return Promise.resolve(this.deliveryUnitOptions);
return this.$u.api.businessUnit.list({})
@@ -160,8 +305,23 @@ export default {
return this.businessUnitOptions;
});
},
applyUnitSelectList(list) {
applyUnitSelectList(list, preserveSelected = true) {
const rows = Array.isArray(list) ? list.slice() : [];
if (preserveSelected) {
const isDelivery = this.unitSelectType === 'delivery';
const selectedValue = isDelivery
? this.filters.delivery_unit_id
: this.filters.business_unit_id;
const selectedLabel = isDelivery
? this.filters.delivery_unit_name
: this.filters.business_unit_name;
const selectedExists = rows.some(
(item) => String(item.value) === String(selectedValue)
);
if (selectedValue !== '' && selectedValue !== null && selectedValue !== undefined && !selectedExists) {
rows.unshift({ value: selectedValue, label: selectedLabel || String(selectedValue) });
}
}
this.unitSelectList = [{ value: '', label: '全部' }].concat(rows);
},
openUnitSelect(type) {
@@ -184,7 +344,7 @@ export default {
if (isDelivery) this.deliveryUnitOptions = list;
else this.businessUnitOptions = list;
}
this.applyUnitSelectList(list);
this.applyUnitSelectList(list, empty);
})
.catch((e) => {
if (seq !== this.unitSearchSeq) return;
@@ -213,10 +373,11 @@ export default {
}
},
loadList() {
const filters = this.appliedFilters;
const params = {};
if (this.filters.order_no) params.order_no = this.filters.order_no;
if (this.filters.audit_status !== '' && this.filters.audit_status !== null) {
params.audit_status = this.filters.audit_status;
if (filters.order_no) params.order_no = filters.order_no;
if (hasFilterValue(filters.audit_status)) {
params.audit_status = filters.audit_status;
}
fetchAllOrderList((p) => this.$u.api.gfmOtherDeliveryOrder.list(p), params)
.then((rows) => {
@@ -250,12 +411,13 @@ export default {
},
// 后端列表仅支持 单号/状态 过滤,出仓日期与单位在前端做本地过滤
matchClientFilter(item) {
if (this.filters.start_date && item.out_date < this.filters.start_date) return false;
if (this.filters.end_date && item.out_date > this.filters.end_date) return false;
if (this.filters.delivery_unit_id && String(item.delivery_unit_id) !== String(this.filters.delivery_unit_id)) {
const filters = this.appliedFilters;
if (filters.start_date && item.out_date < filters.start_date) return false;
if (filters.end_date && item.out_date > filters.end_date) return false;
if (filters.delivery_unit_id && String(item.delivery_unit_id) !== String(filters.delivery_unit_id)) {
return false;
}
if (this.filters.business_unit_id && String(item.business_unit_id) !== String(this.filters.business_unit_id)) {
if (filters.business_unit_id && String(item.business_unit_id) !== String(filters.business_unit_id)) {
return false;
}
return true;
@@ -268,37 +430,20 @@ export default {
uni.navigateTo({ url: `./storeFabricBusinessOutView?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
onStatusConfirm(e) {
this.filters.audit_status = normalizeAuditStatus((e[0] || {}).value);
},
resetFilter() {
this.filters = {
order_no: '',
start_date: '',
end_date: '',
delivery_unit_id: '',
delivery_unit_name: '',
business_unit_id: '',
business_unit_name: '',
audit_status: '',
};
this.filters = createDefaultFilters();
},
applyFilter() {
this.commitFilters();
this.filterShow = false;
this.loadList();
},
},
};
</script>
<style>
page { background-color: #F8F8F8; }
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
.filterBtn { display: flex; flex-direction: column; align-items: center; font-size: 22rpx; color: #666; min-width: 80rpx; }
.filterPanel { padding: 30rpx; }
.filterTitle { font-size: 32rpx; font-weight: bold; margin-bottom: 30rpx; }
.filterItem { margin-bottom: 24rpx; }
.filterLabel { display: block; font-size: 28rpx; color: #666; margin-bottom: 12rpx; }
.filterValue { display: flex; align-items: center; justify-content: space-between; padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 28rpx; }
.dateRow { display: flex; align-items: center; gap: 12rpx; }
.dateInput { padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 26rpx; min-width: 200rpx; text-align: center; }
.filterActions { display: flex; gap: 20rpx; margin-top: 40rpx; }
<style lang="scss">
@import '@/common/list-filter.scss';
</style>
@@ -1,9 +1,12 @@
<template>
<view>
<view class="filterBar">
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="loadList" @custom="loadList" />
<view class="filterBtn" @click="filterShow = true">
<u-icon name="list" size="40" color="#666"></u-icon>
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="applySearch" @custom="applySearch" @clear="applySearch" />
<view class="filterBtn" :class="{ 'filter-active': hasActiveFilter }" @click="filterShow = true">
<view class="filterBtn__icon">
<u-icon :key="filterIconColor" name="list" size="44" :color="filterIconColor"></u-icon>
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
</view>
<text>筛选</text>
</view>
</view>
@@ -20,24 +23,26 @@
<addBtn url="./storeGoodsProcessInAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">进仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" />
<view class="filterInput">
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" :height="100" :custom-style="{ fontSize: '36rpx', color: '#202328' }" placeholder-style="color: #aeb4bf; font-size: 34rpx;" />
</view>
</view>
<view class="filterItem" @click="openProcessUnitSelect">
<text class="filterLabel">加工单位</text>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openWarehouseSelect">
<text class="filterLabel">仓库</text>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
@@ -46,8 +51,8 @@
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
<u-select class="pdaSelect" v-model="statusSelectShow" title="选择订单状态" :list="statusSelectList" :default-value="statusSelectDefault" @confirm="onStatusConfirm"></u-select>
<u-select class="pdaSelect" v-model="unitSelectShow" :list="unitSelectList" :default-value="unitSelectDefault" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
</view>
</template>
@@ -56,6 +61,7 @@ import addBtn from '@/components/addBtn/addBtn.vue';
import ProcessInItem from '@/components/card/storeGoodsProcessInItem.vue';
import {
getStatusOptions,
AUDIT_STATUS,
AUDIT_STATUS_MAP,
BUSINESS_UNIT_TYPE_PROCESS,
WAREHOUSE_TYPE_FINISHED,
@@ -64,9 +70,11 @@ import {
fetchAllOrderList,
} from '@/common/storeGoodsProcessIn';
import { withNameParam } from '@/common/remoteSelect';
import listFilterMixin from '@/mixins/listFilterMixin';
export default {
components: { addBtn, ProcessInItem },
mixins: [listFilterMixin],
data() {
return {
list: [],
@@ -83,13 +91,14 @@ export default {
selectSearching: false,
unitSearchSeq: 0,
unitSelectList: [{ value: '', label: '全部' }],
filterStorageKey: 'storeGoodsProcessInListFilters_v2',
filters: {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
audit_status: AUDIT_STATUS.PENDING,
},
statusSelectList: [
{ value: '', label: '全部' },
@@ -111,6 +120,7 @@ export default {
},
onLoad() {
uni.setNavigationBarTitle({ title: '加工进仓列表' });
this.restoreFilterCache();
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
@@ -121,6 +131,16 @@ export default {
this.loadList();
},
methods: {
createDefaultFilters() {
return {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: AUDIT_STATUS.PENDING,
};
},
loadProcessUnitOptions() {
if (this.processUnitOptions.length) return Promise.resolve(this.processUnitOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_PROCESS })
@@ -145,10 +165,6 @@ export default {
return this.warehouseOptions;
});
},
applyUnitSelectList(list) {
const rows = Array.isArray(list) ? list.slice() : [];
this.unitSelectList = [{ value: '', label: '全部' }].concat(rows);
},
openUnitSelect(type) {
this.unitSelectType = type;
const cache = type === 'warehouse' ? this.warehouseOptions : this.processUnitOptions;
@@ -170,7 +186,7 @@ export default {
if (type === 'warehouse') this.warehouseOptions = list;
else this.processUnitOptions = list;
}
this.applyUnitSelectList(list);
this.applyUnitSelectList(list, empty);
}).catch((e) => {
if (seq !== this.unitSearchSeq) return;
uni.showToast({ title: (e && e.message) || '搜索失败', icon: 'none' });
@@ -199,12 +215,13 @@ export default {
loadList() {
if (this.listLoading) return;
this.listLoading = true;
const filters = this.appliedFilters || this.filters;
const params = {};
if (this.filters.order_no) params.order_no = this.filters.order_no;
if (this.filters.process_unit_id) params.process_unit_id = this.filters.process_unit_id;
if (this.filters.warehouse_id) params.warehouse_id = this.filters.warehouse_id;
if (this.filters.audit_status !== '' && this.filters.audit_status !== null) {
params.audit_status = this.filters.audit_status;
if (filters.order_no) params.order_no = filters.order_no;
if (filters.process_unit_id) params.process_unit_id = filters.process_unit_id;
if (filters.warehouse_id) params.warehouse_id = filters.warehouse_id;
if (this.hasFilterValue(filters.audit_status)) {
params.audit_status = filters.audit_status;
}
fetchAllOrderList((p) => this.$u.api.fpmProcessInOrder.list(p), params)
.then((rows) => {
@@ -249,33 +266,10 @@ export default {
uni.navigateTo({ url: `./${page}?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
resetFilter() {
this.filters = {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
};
},
applyFilter() {
this.filterShow = false;
this.loadList();
},
},
};
</script>
<style>
page { background-color: #F8F8F8; }
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
.filterBtn { display: flex; flex-direction: column; align-items: center; font-size: 22rpx; color: #666; min-width: 80rpx; }
.filterPanel { padding: 30rpx; }
.filterTitle { font-size: 32rpx; font-weight: bold; margin-bottom: 30rpx; }
.filterItem { margin-bottom: 24rpx; }
.filterLabel { display: block; font-size: 28rpx; color: #666; margin-bottom: 12rpx; }
.filterValue { display: flex; align-items: center; justify-content: space-between; padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 28rpx; }
.filterActions { display: flex; gap: 20rpx; margin-top: 40rpx; }
<style lang="scss">
@import '@/common/list-filter.scss';
</style>
@@ -1,9 +1,12 @@
<template>
<view>
<view class="filterBar">
<u-search v-model="filters.order_no" placeholder="出仓单号" :show-action="false" @search="loadList" @custom="loadList" />
<view class="filterBtn" @click="filterShow = true">
<u-icon name="list" size="40" color="#666"></u-icon>
<u-search v-model="filters.order_no" placeholder="出仓单号" :show-action="false" @search="applySearch" @custom="applySearch" @clear="applySearch" />
<view class="filterBtn" :class="{ 'filter-active': hasActiveFilter }" @click="filterShow = true">
<view class="filterBtn__icon">
<u-icon :key="filterIconColor" name="list" size="44" :color="filterIconColor"></u-icon>
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
</view>
<text>筛选</text>
</view>
</view>
@@ -20,24 +23,26 @@
<addBtn url="./storeGoodsProcessOutAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">出仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入出仓单号" />
<view class="filterInput">
<u-input v-model="filters.order_no" placeholder="请输入出仓单号" :height="100" :custom-style="{ fontSize: '36rpx', color: '#202328' }" placeholder-style="color: #aeb4bf; font-size: 34rpx;" />
</view>
</view>
<view class="filterItem" @click="openProcessUnitSelect">
<text class="filterLabel">加工单位</text>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openWarehouseSelect">
<text class="filterLabel">仓库</text>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
@@ -46,8 +51,8 @@
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
<u-select class="pdaSelect" v-model="statusSelectShow" title="选择订单状态" :list="statusSelectList" :default-value="statusSelectDefault" @confirm="onStatusConfirm"></u-select>
<u-select class="pdaSelect" v-model="unitSelectShow" :list="unitSelectList" :default-value="unitSelectDefault" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
</view>
</template>
@@ -56,6 +61,7 @@ import addBtn from '@/components/addBtn/addBtn.vue';
import ProcessOutItem from '@/components/card/storeGoodsProcessOutItem.vue';
import {
getStatusOptions,
AUDIT_STATUS,
AUDIT_STATUS_MAP,
BUSINESS_UNIT_TYPE_PROCESS,
WAREHOUSE_TYPE_FINISHED,
@@ -64,9 +70,11 @@ import {
fetchAllOrderList,
} from '@/common/storeGoodsProcessOut';
import { withNameParam } from '@/common/remoteSelect';
import listFilterMixin from '@/mixins/listFilterMixin';
export default {
components: { addBtn, ProcessOutItem },
mixins: [listFilterMixin],
data() {
return {
list: [],
@@ -83,13 +91,14 @@ export default {
selectSearching: false,
unitSearchSeq: 0,
unitSelectList: [{ value: '', label: '全部' }],
filterStorageKey: 'storeGoodsProcessOutListFilters_v2',
filters: {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
audit_status: AUDIT_STATUS.PENDING,
},
statusSelectList: [
{ value: '', label: '全部' },
@@ -111,6 +120,7 @@ export default {
},
onLoad() {
uni.setNavigationBarTitle({ title: '加工出仓列表' });
this.restoreFilterCache();
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
@@ -121,6 +131,16 @@ export default {
this.loadList();
},
methods: {
createDefaultFilters() {
return {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: AUDIT_STATUS.PENDING,
};
},
loadProcessUnitOptions() {
if (this.processUnitOptions.length) return Promise.resolve(this.processUnitOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_PROCESS })
@@ -145,10 +165,6 @@ export default {
return this.warehouseOptions;
});
},
applyUnitSelectList(list) {
const rows = Array.isArray(list) ? list.slice() : [];
this.unitSelectList = [{ value: '', label: '全部' }].concat(rows);
},
openUnitSelect(type) {
this.unitSelectType = type;
const cache = type === 'warehouse' ? this.warehouseOptions : this.processUnitOptions;
@@ -170,7 +186,7 @@ export default {
if (type === 'warehouse') this.warehouseOptions = list;
else this.processUnitOptions = list;
}
this.applyUnitSelectList(list);
this.applyUnitSelectList(list, empty);
}).catch((e) => {
if (seq !== this.unitSearchSeq) return;
uni.showToast({ title: (e && e.message) || '搜索失败', icon: 'none' });
@@ -199,12 +215,13 @@ export default {
loadList() {
if (this.listLoading) return;
this.listLoading = true;
const filters = this.appliedFilters || this.filters;
const params = {};
if (this.filters.order_no) params.order_no = this.filters.order_no;
if (this.filters.process_unit_id) params.process_unit_id = this.filters.process_unit_id;
if (this.filters.warehouse_id) params.warehouse_id = this.filters.warehouse_id;
if (this.filters.audit_status !== '' && this.filters.audit_status !== null) {
params.audit_status = this.filters.audit_status;
if (filters.order_no) params.order_no = filters.order_no;
if (filters.process_unit_id) params.process_unit_id = filters.process_unit_id;
if (filters.warehouse_id) params.warehouse_id = filters.warehouse_id;
if (this.hasFilterValue(filters.audit_status)) {
params.audit_status = filters.audit_status;
}
fetchAllOrderList((p) => this.$u.api.fpmProcessOutOrder.list(p), params)
.then((rows) => {
@@ -251,33 +268,10 @@ export default {
uni.navigateTo({ url: `./${page}?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
resetFilter() {
this.filters = {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
};
},
applyFilter() {
this.filterShow = false;
this.loadList();
},
},
};
</script>
<style>
page { background-color: #F8F8F8; }
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
.filterBtn { display: flex; flex-direction: column; align-items: center; font-size: 22rpx; color: #666; min-width: 80rpx; }
.filterPanel { padding: 30rpx; }
.filterTitle { font-size: 32rpx; font-weight: bold; margin-bottom: 30rpx; }
.filterItem { margin-bottom: 24rpx; }
.filterLabel { display: block; font-size: 28rpx; color: #666; margin-bottom: 12rpx; }
.filterValue { display: flex; align-items: center; justify-content: space-between; padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 28rpx; }
.filterActions { display: flex; gap: 20rpx; margin-top: 40rpx; }
<style lang="scss">
@import '@/common/list-filter.scss';
</style>
@@ -1,9 +1,12 @@
<template>
<view>
<view class="filterBar">
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="loadList" @custom="loadList" />
<view class="filterBtn" @click="filterShow = true">
<u-icon name="list" size="40" color="#666"></u-icon>
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="applySearch" @custom="applySearch" @clear="applySearch" />
<view class="filterBtn" :class="{ 'filter-active': hasActiveFilter }" @click="filterShow = true">
<view class="filterBtn__icon">
<u-icon :key="filterIconColor" name="list" size="44" :color="filterIconColor"></u-icon>
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
</view>
<text>筛选</text>
</view>
</view>
@@ -20,24 +23,26 @@
<addBtn url="./storeGoodsProcessReturnInAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">进仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" />
<view class="filterInput">
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" :height="100" :custom-style="{ fontSize: '36rpx', color: '#202328' }" placeholder-style="color: #aeb4bf; font-size: 34rpx;" />
</view>
</view>
<view class="filterItem" @click="openProcessUnitSelect">
<text class="filterLabel">加工单位</text>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ processUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openWarehouseSelect">
<text class="filterLabel">仓库</text>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
@@ -46,8 +51,8 @@
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
<u-select class="pdaSelect" v-model="statusSelectShow" title="选择订单状态" :list="statusSelectList" :default-value="statusSelectDefault" @confirm="onStatusConfirm"></u-select>
<u-select class="pdaSelect" v-model="unitSelectShow" :list="unitSelectList" :default-value="unitSelectDefault" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
</view>
</template>
@@ -56,6 +61,7 @@ import addBtn from '@/components/addBtn/addBtn.vue';
import ProcessReturnInItem from '@/components/card/storeGoodsProcessReturnInItem.vue';
import {
getStatusOptions,
AUDIT_STATUS,
AUDIT_STATUS_MAP,
BUSINESS_UNIT_TYPE_PROCESS,
WAREHOUSE_TYPE_FINISHED,
@@ -64,9 +70,11 @@ import {
fetchAllOrderList,
} from '@/common/storeGoodsProcessReturnIn';
import { withNameParam } from '@/common/remoteSelect';
import listFilterMixin from '@/mixins/listFilterMixin';
export default {
components: { addBtn, ProcessReturnInItem },
mixins: [listFilterMixin],
data() {
return {
list: [],
@@ -83,13 +91,14 @@ export default {
selectSearching: false,
unitSearchSeq: 0,
unitSelectList: [{ value: '', label: '全部' }],
filterStorageKey: 'storeGoodsProcessReturnInListFilters_v2',
filters: {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
audit_status: AUDIT_STATUS.PENDING,
},
statusSelectList: [
{ value: '', label: '全部' },
@@ -111,6 +120,7 @@ export default {
},
onLoad() {
uni.setNavigationBarTitle({ title: '加工退货进仓列表' });
this.restoreFilterCache();
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
@@ -121,6 +131,16 @@ export default {
this.loadList();
},
methods: {
createDefaultFilters() {
return {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: AUDIT_STATUS.PENDING,
};
},
loadProcessUnitOptions() {
if (this.processUnitOptions.length) return Promise.resolve(this.processUnitOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_PROCESS })
@@ -145,10 +165,6 @@ export default {
return this.warehouseOptions;
});
},
applyUnitSelectList(list) {
const rows = Array.isArray(list) ? list.slice() : [];
this.unitSelectList = [{ value: '', label: '全部' }].concat(rows);
},
openUnitSelect(type) {
this.unitSelectType = type;
const cache = type === 'warehouse' ? this.warehouseOptions : this.processUnitOptions;
@@ -170,7 +186,7 @@ export default {
if (type === 'warehouse') this.warehouseOptions = list;
else this.processUnitOptions = list;
}
this.applyUnitSelectList(list);
this.applyUnitSelectList(list, empty);
}).catch((e) => {
if (seq !== this.unitSearchSeq) return;
uni.showToast({ title: (e && e.message) || '搜索失败', icon: 'none' });
@@ -199,12 +215,13 @@ export default {
loadList() {
if (this.listLoading) return;
this.listLoading = true;
const filters = this.appliedFilters || this.filters;
const params = {};
if (this.filters.order_no) params.order_no = this.filters.order_no;
if (this.filters.process_unit_id) params.supplier_id = this.filters.process_unit_id;
if (this.filters.warehouse_id) params.warehouse_id = this.filters.warehouse_id;
if (this.filters.audit_status !== '' && this.filters.audit_status !== null) {
params.audit_status = this.filters.audit_status;
if (filters.order_no) params.order_no = filters.order_no;
if (filters.process_unit_id) params.supplier_id = filters.process_unit_id;
if (filters.warehouse_id) params.warehouse_id = filters.warehouse_id;
if (this.hasFilterValue(filters.audit_status)) {
params.audit_status = filters.audit_status;
}
fetchAllOrderList((p) => this.$u.api.fpmProcessReturnInOrder.list(p), params)
.then((rows) => {
@@ -249,33 +266,10 @@ export default {
uni.navigateTo({ url: `./${page}?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
resetFilter() {
this.filters = {
order_no: '',
process_unit_id: '',
process_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
};
},
applyFilter() {
this.filterShow = false;
this.loadList();
},
},
};
</script>
<style>
page { background-color: #F8F8F8; }
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
.filterBtn { display: flex; flex-direction: column; align-items: center; font-size: 22rpx; color: #666; min-width: 80rpx; }
.filterPanel { padding: 30rpx; }
.filterTitle { font-size: 32rpx; font-weight: bold; margin-bottom: 30rpx; }
.filterItem { margin-bottom: 24rpx; }
.filterLabel { display: block; font-size: 28rpx; color: #666; margin-bottom: 12rpx; }
.filterValue { display: flex; align-items: center; justify-content: space-between; padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 28rpx; }
.filterActions { display: flex; gap: 20rpx; margin-top: 40rpx; }
<style lang="scss">
@import '@/common/list-filter.scss';
</style>
@@ -1,9 +1,12 @@
<template>
<view>
<view class="filterBar">
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="loadList" @custom="loadList" />
<view class="filterBtn" @click="filterShow = true">
<u-icon name="list" size="40" color="#666"></u-icon>
<u-search v-model="filters.order_no" placeholder="进仓单号" :show-action="false" @search="applySearch" @custom="applySearch" @clear="applySearch" />
<view class="filterBtn" :class="{ 'filter-active': hasActiveFilter }" @click="filterShow = true">
<view class="filterBtn__icon">
<u-icon :key="filterIconColor" name="list" size="44" :color="filterIconColor"></u-icon>
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
</view>
<text>筛选</text>
</view>
</view>
@@ -20,24 +23,26 @@
<addBtn url="./storeGoodsPurchaseInAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">进仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" />
<view class="filterInput">
<u-input v-model="filters.order_no" placeholder="请输入进仓单号" :height="100" :custom-style="{ fontSize: '36rpx', color: '#202328' }" placeholder-style="color: #aeb4bf; font-size: 34rpx;" />
</view>
</view>
<view class="filterItem" @click="openSupplierSelect">
<text class="filterLabel">供应商</text>
<view class="filterValue">{{ supplierLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ supplierLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openWarehouseSelect">
<text class="filterLabel">仓库</text>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ warehouseLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
@@ -46,8 +51,8 @@
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
<u-select class="pdaSelect" v-model="statusSelectShow" title="选择订单状态" :list="statusSelectList" :default-value="statusSelectDefault" @confirm="onStatusConfirm"></u-select>
<u-select class="pdaSelect" v-model="unitSelectShow" :list="unitSelectList" :default-value="unitSelectDefault" remote :loading="selectSearching" @search="onUnitSearch" @confirm="onUnitConfirm"></u-select>
</view>
</template>
@@ -56,6 +61,7 @@ import addBtn from '@/components/addBtn/addBtn.vue';
import PurchaseInItem from '@/components/card/storeGoodsPurchaseInItem.vue';
import {
getStatusOptions,
AUDIT_STATUS,
AUDIT_STATUS_MAP,
BUSINESS_UNIT_TYPE_PRODUCT_SUPPLIER,
WAREHOUSE_TYPE_FINISHED,
@@ -64,9 +70,11 @@ import {
fetchAllOrderList,
} from '@/common/storeGoodsPurchaseIn';
import { withNameParam } from '@/common/remoteSelect';
import listFilterMixin from '@/mixins/listFilterMixin';
export default {
components: { addBtn, PurchaseInItem },
mixins: [listFilterMixin],
data() {
return {
list: [],
@@ -83,13 +91,14 @@ export default {
selectSearching: false,
unitSearchSeq: 0,
unitSelectList: [{ value: '', label: '全部' }],
filterStorageKey: 'storeGoodsPurchaseInListFilters_v2',
filters: {
order_no: '',
supplier_id: '',
supplier_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
audit_status: AUDIT_STATUS.PENDING,
},
statusSelectList: [
{ value: '', label: '全部' },
@@ -111,6 +120,7 @@ export default {
},
onLoad() {
uni.setNavigationBarTitle({ title: '成品采购进仓' });
this.restoreFilterCache();
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
@@ -121,6 +131,16 @@ export default {
this.loadList();
},
methods: {
createDefaultFilters() {
return {
order_no: '',
supplier_id: '',
supplier_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: AUDIT_STATUS.PENDING,
};
},
loadSupplierOptions() {
if (this.supplierOptions.length) return Promise.resolve(this.supplierOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_PRODUCT_SUPPLIER })
@@ -145,10 +165,6 @@ export default {
return this.warehouseOptions;
});
},
applyUnitSelectList(list) {
const rows = Array.isArray(list) ? list.slice() : [];
this.unitSelectList = [{ value: '', label: '全部' }].concat(rows);
},
openUnitSelect(type) {
this.unitSelectType = type;
const cache = type === 'warehouse' ? this.warehouseOptions : this.supplierOptions;
@@ -170,7 +186,7 @@ export default {
if (type === 'warehouse') this.warehouseOptions = list;
else this.supplierOptions = list;
}
this.applyUnitSelectList(list);
this.applyUnitSelectList(list, empty);
}).catch((e) => {
if (seq !== this.unitSearchSeq) return;
uni.showToast({ title: (e && e.message) || '搜索失败', icon: 'none' });
@@ -199,12 +215,13 @@ export default {
loadList() {
if (this.listLoading) return;
this.listLoading = true;
const filters = this.appliedFilters || this.filters;
const params = {};
if (this.filters.order_no) params.order_no = this.filters.order_no;
if (this.filters.supplier_id) params.supplier_id = this.filters.supplier_id;
if (this.filters.warehouse_id) params.warehouse_id = this.filters.warehouse_id;
if (this.filters.audit_status !== '' && this.filters.audit_status !== null) {
params.audit_status = this.filters.audit_status;
if (filters.order_no) params.order_no = filters.order_no;
if (filters.supplier_id) params.supplier_id = filters.supplier_id;
if (filters.warehouse_id) params.warehouse_id = filters.warehouse_id;
if (this.hasFilterValue(filters.audit_status)) {
params.audit_status = filters.audit_status;
}
fetchAllOrderList((p) => this.$u.api.fpmPrcInOrder.list(p), params)
.then((rows) => {
@@ -249,33 +266,10 @@ export default {
uni.navigateTo({ url: `./${page}?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
resetFilter() {
this.filters = {
order_no: '',
supplier_id: '',
supplier_name: '',
warehouse_id: '',
warehouse_name: '',
audit_status: '',
};
},
applyFilter() {
this.filterShow = false;
this.loadList();
},
},
};
</script>
<style>
page { background-color: #F8F8F8; }
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
.filterBtn { display: flex; flex-direction: column; align-items: center; font-size: 22rpx; color: #666; min-width: 80rpx; }
.filterPanel { padding: 30rpx; }
.filterTitle { font-size: 32rpx; font-weight: bold; margin-bottom: 30rpx; }
.filterItem { margin-bottom: 24rpx; }
.filterLabel { display: block; font-size: 28rpx; color: #666; margin-bottom: 12rpx; }
.filterValue { display: flex; align-items: center; justify-content: space-between; padding: 16rpx; background: #f5f5f5; border-radius: 8rpx; font-size: 28rpx; }
.filterActions { display: flex; gap: 20rpx; margin-top: 40rpx; }
<style lang="scss">
@import '@/common/list-filter.scss';
</style>