From cc3001ab9e0ab8ce673b812a22ebea1edd332f2a Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期六, 14 三月 2026 15:38:33 +0800
Subject: [PATCH] fix: 完成仓储物流的功能开发
---
src/pages/inventoryManagement/dispatchLog/index.vue | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 333 insertions(+), 0 deletions(-)
diff --git a/src/pages/inventoryManagement/dispatchLog/index.vue b/src/pages/inventoryManagement/dispatchLog/index.vue
new file mode 100644
index 0000000..1ab16fe
--- /dev/null
+++ b/src/pages/inventoryManagement/dispatchLog/index.vue
@@ -0,0 +1,333 @@
+<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 { ref, reactive, toRefs, watch } from 'vue'
+import { onShow, onReachBottom } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+import { getStockOutPage, delStockOut } from '@/api/inventoryManagement/stockOutRecord.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 })
+ }
+ getStockOutPage({
+ ...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
+ if (tableData.value.length >= totalCount || totalCount === 0) {
+ loadStatus.value = 'nomore'
+ } else {
+ loadStatus.value = '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/inventoryManagement/dispatchLog/view?id=' + item.id
+ })
+}
+
+const handleDeleteSingle = (item) => {
+ uni.showModal({
+ title: '鍒犻櫎',
+ content: '纭鍒犻櫎璇ユ潯鍑哄簱璁板綍锛�',
+ success: res => {
+ if (res.confirm) {
+ delStockOut([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: 180rpx;
+ 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;
+}
+.btn-search text { line-height: 1; vertical-align: middle; }
+:deep(.btn-search-inner > *),
+:deep(.btn-search > *) {
+ flex-shrink: 0;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+.list-section { padding: 0 24rpx; }
+.card-item {
+ background: #fff;
+ border-radius: 16rpx;
+ padding: 24rpx;
+ margin-bottom: 24rpx;
+ box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.card-header { padding: 8rpx 0; }
+.header-main {
+ display: flex;
+ flex-direction: column;
+ gap: 8rpx;
+}
+.product-name { font-size: 30rpx; font-weight: 500; color: #333; }
+.outbound-date { font-size: 24rpx; color: #999; }
+.card-body .row {
+ display: flex;
+ justify-content: space-between;
+ padding: 12rpx 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 {
+ margin-top: 16rpx;
+ padding-top: 16rpx;
+ border-top: 1rpx solid #eee;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.btn-delete {
+ font-size: 28rpx;
+ color: #f56c6c;
+ padding: 12rpx 32rpx;
+}
+.no-data {
+ text-align: center;
+ padding: 80rpx 0;
+ color: #999;
+ font-size: 28rpx;
+}
+.load-more-wrap { padding: 24rpx 0 40rpx; }
+</style>
--
Gitblit v1.9.3