pda-cli/src/pages/storefabric/storeFabricBusinessOutList.vue
xuan 567da03aea feat(storefabric): 新增坯布出库相关页面及功能
- 在 manifest.json 中添加 Android 包名配置
- 在 package.json 中添加 pnpm 依赖覆盖配置
- 在 pages.json 中注册坯布出库相关页面路由
- 重命名 storefabricBusinessOutAdd.vue 为 storeFabricBusinessOutAdd.vue
- 重构坯布出库新增页面,优化界面布局和交互逻辑
- 添加坯布出库列表、编辑、查看等功能页面
- 集成订单状态栏、面料信息弹窗、细码弹窗等组件
- 实现坯布出库详情列表和扫码功能模块
- 优化表单验证和数据提交流程
2026-06-17 16:59:31 +08:00

269 lines
9.1 KiB
Vue

<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>
<text>筛选</text>
</view>
</view>
<scroll-view scroll-y :style="{ height: scrollHeight }" refresher-enabled
:refresher-triggered="triggered" @refresherrefresh="onRefresh">
<dataNull v-if="list.length === 0" src="/src/static/img/chahua/gjNull.png"
title="暂无坯布出仓单" title1="请点击右下角按钮新增">
</dataNull>
<view v-for="(item, index) in list" :key="item.id" @click="goView(item)">
<FabricOutItem :item="item" :index="index" />
</view>
</scroll-view>
<addBtn url="./storeFabricBusinessOutAdd"></addBtn>
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true">
<view class="filterPanel">
<view class="filterTitle">筛选条件</view>
<view class="filterItem">
<text class="filterLabel">出仓单号</text>
<u-input v-model="filters.order_no" placeholder="请输入出仓单号" />
</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>
<text>~</text>
<picker mode="date" :value="filters.end_date" @change="e => filters.end_date = e.detail.value">
<view class="dateInput">{{ filters.end_date || '结束日期' }}</view>
</picker>
</view>
</view>
<view class="filterItem" @click="openDeliveryUnitSelect">
<text class="filterLabel">出仓单位</text>
<view class="filterValue">{{ deliveryUnitLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
</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>
<view class="filterItem" @click="openStatusSelect">
<text class="filterLabel">订单状态</text>
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="28"></u-icon></view>
</view>
<view class="filterActions">
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
<u-button type="primary" size="medium" @click="applyFilter">确定</u-button>
</view>
</view>
</u-popup>
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" @confirm="onUnitConfirm"></u-select>
</view>
</template>
<script>
import addBtn from '@/components/addBtn/addBtn.vue';
import FabricOutItem from '@/components/card/storeFabricBusinessOutItem.vue';
import {
getStatusOptions,
AUDIT_STATUS_MAP,
BILL_TYPES,
formatRoll,
mapToSelectOptions,
fetchAllOrderList,
} from '@/common/storeFabricBusinessOut';
export default {
components: { addBtn, FabricOutItem },
data() {
return {
list: [],
scrollHeight: '667px',
triggered: false,
filterShow: false,
statusSelectShow: false,
unitSelectShow: false,
unitSelectType: '',
unitOptions: [],
unitOptionsLoading: false,
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: '',
},
statusSelectList: [
{ value: '', label: '全部' },
...getStatusOptions(),
],
};
},
computed: {
statusLabel() {
if (this.filters.audit_status === '' || this.filters.audit_status === null) return '';
return AUDIT_STATUS_MAP[Number(this.filters.audit_status)] || '';
},
deliveryUnitLabel() {
return this.filters.delivery_unit_name || '';
},
businessUnitLabel() {
return this.filters.business_unit_name || '';
},
unitSelectList() {
return [{ value: '', label: '全部' }, ...this.unitOptions];
},
},
onLoad() {
uni.setNavigationBarTitle({ title: '坯布出库列表' });
uni.getSystemInfo({
success: (res) => {
this.scrollHeight = `${res.windowHeight - 50}px`;
},
});
this.loadUnitOptions();
this.loadList();
},
onShow() {
this.loadList();
},
methods: {
loadUnitOptions() {
if (this.unitOptions.length || this.unitOptionsLoading) return Promise.resolve(this.unitOptions);
this.unitOptionsLoading = true;
return this.$u.api.businessUnit.list({})
.then((res) => {
this.unitOptions = mapToSelectOptions(res);
return this.unitOptions;
})
.catch(() => {
this.unitOptions = [];
return this.unitOptions;
})
.finally(() => {
this.unitOptionsLoading = false;
});
},
openUnitSelect(type) {
this.loadUnitOptions().then((list) => {
if (!list.length) {
uni.showToast({ title: '暂无可选单位', icon: 'none' });
return;
}
this.unitSelectType = type;
this.unitSelectShow = true;
});
},
openDeliveryUnitSelect() {
this.openUnitSelect('delivery');
},
openBusinessUnitSelect() {
this.openUnitSelect('business');
},
onUnitConfirm(e) {
const item = e[0] || {};
if (this.unitSelectType === 'delivery') {
this.filters.delivery_unit_id = item.value;
this.filters.delivery_unit_name = item.value ? item.label : '';
} else {
this.filters.business_unit_id = item.value;
this.filters.business_unit_name = item.value ? item.label : '';
}
},
loadList() {
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;
}
fetchAllOrderList((p) => this.$u.api.gfmOtherDeliveryOrder.list(p), params)
.then((rows) => {
this.triggered = false;
this.list = rows.map(this.mapToCard).filter(this.matchClientFilter);
})
.catch((err) => {
this.triggered = false;
this.list = [];
uni.showToast({ title: err.message || '加载失败', icon: 'none' });
});
},
mapToCard(order) {
return {
id: order.id,
order_no: order.order_no || '',
out_date: (order.delivery_time || '').slice(0, 10),
bill_type_name: this.billTypeName,
delivery_unit_id: order.delivery_unit_id || '',
delivery_unit_name: order.delivery_unit_name || '',
business_unit_id: order.business_unit_id || '',
business_unit_name: order.business_unit_name || '',
create_user_name: order.creator_name || '',
create_time: order.create_time || '',
auditor_name: order.auditer_name || '',
audit_date: order.audit_time || '',
audit_status: order.audit_status,
audit_status_name: order.audit_status_name || AUDIT_STATUS_MAP[order.audit_status] || '',
total_roll: formatRoll(order.total_roll),
};
},
// 后端列表仅支持 单号/状态 过滤,出仓日期与单位在前端做本地过滤
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)) {
return false;
}
if (this.filters.business_unit_id && String(item.business_unit_id) !== String(this.filters.business_unit_id)) {
return false;
}
return true;
},
onRefresh() {
this.triggered = true;
this.loadList();
},
goView(item) {
uni.navigateTo({ url: `./storeFabricBusinessOutView?id=${item.id}` });
},
openStatusSelect() { this.statusSelectShow = true; },
onStatusConfirm(e) { this.filters.audit_status = 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: '',
};
},
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; }
.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>