Files
sh-app/pipe/packaging/list.vue
T
2026-06-11 15:49:17 +08:00

251 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page-list">
<!-- 头部过滤区域 -->
<view class="filter-header">
<!-- 第一行搜索框 + 刷新 -->
<view class="search-row">
<u-search v-model="keyword" placeholder="请输入包装编号" :show-action="false" shape="round" bg-color="#f5f6f8" @change="handleSearch" />
<view class="refresh-btn" @click="handleRefresh">
<u-icon name="reload" :size="32" :class="{ rotating: loading }"></u-icon>
</view>
</view>
<!-- 第二行车次关联 + 单位选择 -->
<view class="filter-row has-radio">
<u-radio-group v-model="hasTrainNumber" @change="onTrainNumberChange">
<u-radio :name="true" shape="button" label="已关联"></u-radio>
<u-radio :name="false" shape="button" label="未关联"></u-radio>
</u-radio-group>
<view class="unit-select-btn" @click="handleShowUnitSelect">
<text class="unit-name">{{ selectedUnit?.UnitName || '单位' }}</text>
<u-icon name="arrow-down" :size="18" color="#999"></u-icon>
</view>
</view>
</view>
<!-- 列表内容 -->
<scroll-view class="list-scroll" scroll-y @scrolltolower="loadMore" refresher-enabled
:refresher-triggered="refreshing" @refresh="handleRefresh">
<view class="list-wrap">
<view v-for="(item, index) in listData" :key="item.PackagingManageId || index" class="card-item"
@click="handleItemClick(item)">
<view class="card-header">
<text class="card-code">{{ item.PackagingCode || '--' }}</text>
<text class="card-tag" :class="'status-' + item.State">
{{ getStatus(item.State) }}
</text>
</view>
<view class="card-body">
<view class="card-row">
<text class="row-label">包装单位</text>
<text class="row-value">{{ item.UnitName || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">预制工作包</text>
<text class="row-value">{{ item.StackingPosition || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">车次</text>
<text class="row-value">{{ item.TrainNumber || '未关联' }}</text>
</view>
<view class="card-row">
<text class="row-label">数量</text>
<text class="row-value">{{ item.ComponentCount || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">分类</text>
<text class="row-value">{{ item.CategoryString || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">签收人</text>
<text class="row-value">{{ item.ReceiveMan || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">签收时间</text>
<text class="row-value">{{ item.ReceiveDate || '--' }}</text>
</view>
</view>
</view>
<!-- 空状态 -->
<u-empty v-if="!loading && listData.length === 0" mode="list" text="暂无数据"></u-empty>
<!-- 加载提示 -->
<view v-if="loading && listData.length > 0" class="loading-more">
<u-loading mode="circle" size="32"></u-loading>
<text>加载中...</text>
</view>
<!-- 没有更多 -->
<view v-if="!loading && !hasMore && listData.length > 0" class="no-more">
<text> 没有更多了 </text>
</view>
</view>
</scroll-view>
n <!-- 新增按钮 -->
<view class="fab-btn" @click="handleAdd">
<u-icon name="plus" :size="60" color="#ffffff"></u-icon>
</view>
<!-- 单位选择弹窗 -->
<nbd-select v-model="showUnitSelect" v-model:model="selectedUnit" :show-search="true" title="选择单位" :list="unitList" label-key="UnitName"
value-key="UnitId" @confirm="handleUnitConfirm" />
</view>
</template>
<script setup>
import {
ref,
computed
} from 'vue'
import {
useUserStore
} from '@/store'
import {
storeToRefs
} from 'pinia'
import {
reqUnitByProjectIdUnitType
} from '@/api/base.js'
import {
reqPackagingInformationList
} from '@/api/hj.js'
import {
onShow } from '@dcloudio/uni-app'
const userStore = useUserStore()
const {
currentProject
} = storeToRefs(userStore)
// ===== 搜索 =====
const keyword = ref('')
// ===== 车次关联 true:已关联 false:未关联 =====
const hasTrainNumber = ref(true)
const onTrainNumberChange = () => {
resetAndLoad()
}
// ===== 单位选择 =====
const showUnitSelect = ref(false)
const selectedUnit = ref({
UnitId: '',
UnitName: '全部单位'
})
const unitList = ref([])
const handleShowUnitSelect = async () => {
// TODO: 请求单位列表
const res = await reqUnitByProjectIdUnitType(currentProject.value.ProjectId)
unitList.value = [{ UnitId: '', UnitName: '全部单位' }, ...(res.data || [])]
showUnitSelect.value = true
}
const handleUnitConfirm = (item) => {
selectedUnit.value = item
showUnitSelect.value = false
resetAndLoad()
}
// ===== 列表数据 =====
const listData = ref([])
const loading = ref(false)
const refreshing = ref(false)
const hasMore = ref(true)
const currentPage = ref(1)
const pageSize = 20
// 加载数据
const fetchData = async (isRefresh = false) => {
if (loading.value || (!isRefresh && !hasMore.value)) return
loading.value = true
if (isRefresh) {
refreshing.value = true
}
try {
const res = await reqPackagingInformationList({
projectId: currentProject.value?.ProjectId,
pageIndex: currentPage.value,
pageSize,
packagingCode: keyword.value,
unitId: selectedUnit.value?.UnitId || '',
hasTrainNumber: hasTrainNumber.value
})
const pageData = res.data?.list || res.data?.getDataList || []
hasMore.value = pageData.length === pageSize
if (isRefresh) {
listData.value = pageData
} else {
listData.value = [...listData.value, ...pageData]
}
} catch (error) {
console.error('加载数据失败:', error)
uni.showToast({
title: '加载失败,请重试',
icon: 'none'
})
} finally {
loading.value = false
refreshing.value = false
}
}
// 重置并重新加载
const resetAndLoad = () => {
currentPage.value = 1
hasMore.value = true
listData.value = []
fetchData(true)
}
// 下拉刷新
const handleRefresh = () => {
resetAndLoad()
}
// 搜索
const handleSearch = () => {
resetAndLoad()
}
// 加载更多
const loadMore = () => {
if (!loading.value && hasMore.value) {
currentPage.value++
fetchData(false)
}
}
// 到场状态
const getStatus = (val) => {
const map = {
'0': '未到场',
'1': '已发货',
'2': '已到场'
}
return map[String(val)] || '--'
}
// 列表项点击
const handleItemClick = (item) => {
uni.navigateTo({
url: `/pipe/packaging/detail?id=${item.PackagingManageId}`
})
}
// 新增
const handleAdd = () => {
uni.navigateTo({
url: '/pipe/packaging/add'
})
}
// ===== 生命周期 =====
onShow(() => {
resetAndLoad()
})
</script>