<template>
|
<view class="dispatch-page">
|
<PageHeader title="出库台账" @back="goBack" />
|
<view class="tabs-wrap">
|
<view
|
v-for="tab in tabs"
|
:key="tab.name"
|
class="tab-item"
|
:class="{ active: activeTab === tab.name }"
|
@click="activeTab = tab.name"
|
>
|
<text>{{ tab.label }}</text>
|
</view>
|
</view>
|
<view class="search-section">
|
<view class="search-row">
|
<view class="search-input-wrap">
|
<up-input v-model="searchForm.productName" placeholder="产品大类" clearable />
|
</view>
|
<view class="btn-search" @click="handleQuery">
|
<view class="btn-search-inner">
|
<up-icon name="search" size="22" color="#fff"></up-icon>
|
<text>搜索</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
<view class="list-section">
|
<view v-if="tableData.length > 0">
|
<view v-for="(item, index) in tableData" :key="item.id || index" class="card-item">
|
<view class="card-click" @click="goDetail(item)">
|
<view class="card-header">
|
<view class="header-main">
|
<text class="product-name">{{ item.productName }}</text>
|
<text class="outbound-date">{{ item.createTime }}</text>
|
</view>
|
</view>
|
<up-divider />
|
<view class="card-body">
|
<view class="row"><text class="l">规格型号</text><text class="r">{{ item.model }}</text></view>
|
<view class="row"><text class="l">单位</text><text class="r">{{ item.unit }}</text></view>
|
<view class="row"><text class="l">出库数量</text><text class="r highlight">{{ item.stockOutNum }}</text></view>
|
<view class="row"><text class="l">出库人</text><text class="r">{{ item.createBy }}</text></view>
|
<view class="row" v-if="item.recordType !== undefined"><text class="l">来源</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view>
|
<view class="row"><text class="l">毛重(吨)</text><text class="r">{{ item.grossWeight ?? '-' }}</text></view>
|
<view class="row"><text class="l">皮重(吨)</text><text class="r">{{ item.tareWeight ?? '-' }}</text></view>
|
<view class="row"><text class="l">净重(吨)</text><text class="r">{{ item.netWeight ?? '-' }}</text></view>
|
<view class="row"><text class="l">过磅日期</text><text class="r">{{ item.weighingDate || '-' }}</text></view>
|
<view class="row"><text class="l">过磅员</text><text class="r">{{ item.weighingOperator || '-' }}</text></view>
|
</view>
|
</view>
|
<view class="card-actions">
|
<view class="btn-delete" @click.stop="handleDeleteSingle(item)">删除</view>
|
</view>
|
</view>
|
</view>
|
<view v-else class="no-data">暂无数据</view>
|
</view>
|
<view class="load-more-wrap" v-if="tableData.length > 0">
|
<u-loadmore :status="loadStatus" @loadmore="loadMore" />
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { reactive, ref, toRefs, watch } from "vue";
|
import { onReachBottom, onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import { getConsumablesOutRecordPage, delConsumablesOutRecord } from "@/api/consumablesLogistics/consumablesOutRecord.js";
|
import { findAllQualifiedStockOutRecordTypeOptions, findAllUnQualifiedStockOutRecordTypeOptions } from "@/api/basicData/enum.js";
|
|
const activeTab = ref("qualified");
|
const stockRecordTypeOptions = ref([]);
|
const tabs = [
|
{ label: "合格出库", name: "qualified", type: "0" },
|
{ label: "不合格出库", name: "unqualified", type: "1" },
|
];
|
const tableData = ref([]);
|
const total = ref(0);
|
const loadStatus = ref("loadmore");
|
const page = reactive({ current: 1, size: 20 });
|
const data = reactive({ searchForm: { productName: "" } });
|
const { searchForm } = toRefs(data);
|
|
const currentType = () => tabs.find((t) => t.name === activeTab.value)?.type || "0";
|
|
function getRecordType(recordType) {
|
if (recordType == null || recordType === "") return "";
|
return stockRecordTypeOptions.value.find((item) => item.value === recordType)?.label || "";
|
}
|
|
function fetchRecordTypeOptions() {
|
const api =
|
currentType() === "1"
|
? findAllUnQualifiedStockOutRecordTypeOptions
|
: findAllQualifiedStockOutRecordTypeOptions;
|
api()
|
.then((res) => {
|
const list = res.data != null ? res.data : res;
|
stockRecordTypeOptions.value = Array.isArray(list) ? list : [];
|
})
|
.catch(() => {
|
stockRecordTypeOptions.value = [];
|
});
|
}
|
|
const getList = () => {
|
const isFirstPage = page.current === 1;
|
if (isFirstPage) {
|
uni.showLoading({ title: "加载中...", mask: true });
|
}
|
getConsumablesOutRecordPage({
|
...page,
|
type: currentType(),
|
productName: searchForm.value.productName,
|
})
|
.then((res) => {
|
uni.hideLoading();
|
const records = res.data?.records || [];
|
const totalCount = res.data?.total || 0;
|
if (isFirstPage) {
|
tableData.value = records;
|
fetchRecordTypeOptions();
|
} else {
|
tableData.value = [...tableData.value, ...records];
|
}
|
total.value = totalCount;
|
loadStatus.value = tableData.value.length >= totalCount || totalCount === 0 ? "nomore" : "loadmore";
|
})
|
.catch(() => {
|
uni.hideLoading();
|
loadStatus.value = "error";
|
if (isFirstPage) {
|
uni.showToast({ title: "加载失败", icon: "none" });
|
}
|
});
|
};
|
|
const loadMore = () => {
|
if (loadStatus.value === "nomore" || loadStatus.value === "loading") return;
|
loadStatus.value = "loading";
|
page.current++;
|
getList();
|
};
|
|
watch(activeTab, () => {
|
page.current = 1;
|
loadStatus.value = "loadmore";
|
stockRecordTypeOptions.value = [];
|
getList();
|
});
|
|
const handleQuery = () => {
|
page.current = 1;
|
loadStatus.value = "loadmore";
|
getList();
|
};
|
|
const goDetail = (item) => {
|
if (!item?.id) return;
|
try {
|
uni.setStorageSync(
|
"dispatchDetailItem",
|
JSON.stringify({
|
item,
|
type: currentType(),
|
})
|
);
|
} catch (e) {}
|
uni.navigateTo({
|
url: "/pages/consumablesLogistics/dispatchLog/view?id=" + item.id,
|
});
|
};
|
|
const handleDeleteSingle = (item) => {
|
if (!item?.id) return;
|
uni.showModal({
|
title: "删除",
|
content: "确认删除该条出库记录?",
|
success: (res) => {
|
if (!res.confirm) return;
|
delConsumablesOutRecord([item.id])
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
getList();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
});
|
},
|
});
|
};
|
|
const goBack = () => uni.navigateBack();
|
onShow(() => getList());
|
onReachBottom(() => loadMore());
|
</script>
|
|
<style lang="scss" scoped>
|
.dispatch-page { min-height: 100vh; background: #f5f5f5; padding-bottom: 40rpx; }
|
.tabs-wrap { display: flex; background: #fff; padding: 24rpx; gap: 24rpx; }
|
.tab-item { flex: 1; text-align: center; padding: 20rpx; border-radius: 12rpx; background: #f0f0f0; font-size: 28rpx; color: #666; }
|
.tab-item.active { background: #2979ff; color: #fff; }
|
.search-section { background: #fff; margin: 24rpx; padding: 24rpx; border-radius: 16rpx; }
|
.search-row { display: flex; align-items: center; }
|
.search-input-wrap { flex: 1; margin-right: 20rpx; min-width: 0; }
|
.btn-search { display: flex; align-items: center; justify-content: center; width: 160rpx; min-height: 72rpx; flex-shrink: 0; padding: 20rpx 24rpx; background: #2979ff; color: #fff; border-radius: 12rpx; font-size: 28rpx; box-sizing: border-box; text-align: center; }
|
.btn-search-inner { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 8rpx; }
|
.list-section { margin: 24rpx; }
|
.card-item { background: #fff; border-radius: 16rpx; padding: 20rpx 24rpx; margin-bottom: 20rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
|
.card-header { padding: 4rpx 0 12rpx; }
|
.header-main { display: flex; justify-content: space-between; gap: 16rpx; }
|
.product-name { font-size: 30rpx; font-weight: 500; color: #333; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
.outbound-date { font-size: 24rpx; color: #999; }
|
.card-body .row { display: flex; justify-content: space-between; padding: 6rpx 0; font-size: 26rpx; }
|
.card-body .l { color: #666; }
|
.card-body .r { color: #333; }
|
.card-body .r.highlight { color: #2979ff; font-weight: 500; }
|
.card-actions { display: flex; justify-content: flex-end; margin-top: 12rpx; }
|
.btn-delete { color: #f56c6c; font-size: 28rpx; }
|
.no-data { text-align: center; padding: 60rpx 0; color: #999; font-size: 28rpx; }
|
.load-more-wrap { padding: 24rpx 24rpx 8rpx; }
|
</style>
|