包装管理

This commit is contained in:
2026-06-11 17:58:29 +08:00
parent 5b3fc66a36
commit 0f8d5f4f7d
7 changed files with 492 additions and 16 deletions
+23 -8
View File
@@ -16,18 +16,19 @@
</view>
<view class="info-item">
<text class="info-label"><text class="required">*</text>包装分类</text>
<u-input v-model="form.CategoryName" :clearable="false" type="select" placeholder="请选择" @click="handleShowCategory" />
<u-input v-model="form.CategoryName" :clearable="false" type="select" placeholder="请选择"
@click="handleShowCategory" />
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-btns">
<u-button class="btn-submit" size="medium" type="primary" @click="handleSave">保存</u-button>
<u-button size="medium" type="primary" @click="handleSave">保存</u-button>
</view>
<!-- 包装分类选择弹窗 -->
<nbd-select v-model="showCategory" v-model:model="selectedCategory" title="选择包装分类" :list="categoryList" label-key="label" value-key="value"
@confirm="handleCategoryConfirm" />
<nbd-select v-model="showCategory" v-model:model="selectedCategory" title="选择包装分类" :list="categoryList"
label-key="label" value-key="value" @confirm="handleCategoryConfirm" />
</view>
</template>
@@ -68,7 +69,10 @@
// ===== 弹窗 =====
const showCategory = ref(false)
const categoryList = ref([])
const selectedCategory = ref({ label: '', value: '' })
const selectedCategory = ref({
label: '',
value: ''
})
// ===== 选择事件 =====
const handleShowCategory = () => {
@@ -93,7 +97,10 @@
const getCategoryList = async () => {
try {
const res = await reqPackagingManage()
categoryList.value = Object.entries(res.data || {}).map(([label, value]) => ({ label, value }))
categoryList.value = Object.entries(res.data || {}).map(([label, value]) => ({
label,
value
}))
// 设置默认值为第一个
if (categoryList.value.length > 0 && !form.value.CategoryName) {
form.value.CategoryName = categoryList.value[0].label
@@ -106,6 +113,14 @@
// ===== 保存 =====
const handleSave = async () => {
setTimeout(() => {
uni.redirectTo({
url: '/pipe/packaging/detail?id' + res.data.id
})
}, 1500)
return
if (!form.value.StackingPosition) {
uni.showToast({
title: '请输入预制工作包',
@@ -138,7 +153,7 @@
})
setTimeout(() => {
uni.redirectTo({
url: '/pipe/packaging/detail?id'+res.data.id
url: '/pipe/packaging/detail?id' + res.data.id
})
}, 1500)
}
@@ -166,4 +181,4 @@
getPackagingNo()
getCategoryList()
})
</script>
</script>
+305 -4
View File
@@ -1,8 +1,309 @@
<template>
<view class="page-detail">
<!-- 基本信息 -->
<view class="info-group">
<view class="info-item">
<text class="info-label">包装编号</text>
<text class="info-value">{{ info.PackagingCode || '--' }}</text>
</view>
<view class="info-item">
<text class="info-label">预制工作包</text>
<text class="info-value">{{ info.StackingPosition || '--' }}</text>
</view>
<view class="info-item">
<text class="info-label">到场状态</text>
<text class="card-tag" :class="'status-' + info.State">{{ getStatus(info.State) }}</text>
</view>
<view class="info-item">
<text class="info-label">签收人</text>
<text class="info-value">{{ info.ReceiveMan || '--' }}</text>
</view>
<view class="info-item">
<text class="info-label">签收时间</text>
<text class="info-value">{{ info.ReceiveDate || '--' }}</text>
</view>
<view class="info-item">
<text class="info-label">车次</text>
<text class="info-value">{{ info.TrainNumber || '--' }}</text>
</view>
<view v-if="info.State == 0" class="info-item info-link" @click="onScan">
<text class="info-label">扫码添加</text>
<view class="scan-icon">
<u-icon name="scan" :size="36" color="#3577FF"></u-icon>
</view>
</view>
</view>
<!-- 预制组件列表 -->
<view class="package-group">
<view class="section-title">
<text>预制组件</text>
<text class="section-count">({{ packages.length }})</text>
</view>
<view v-for="(item, index) in packages" :key="index" class="package-card">
<view class="card-header">
<text class="card-title">{{ item.PipelineComponentCode || '--' }}</text>
<view class="del-btn" @click="handleDelPackage(item)" v-if="info.State == 0">
<u-icon name="trash" :size="36" color="#ffffff"></u-icon>
</view>
</view>
<view class="card-body">
<view class="card-row">
<text class="row-label">数量/单位</text>
<text class="row-value">{{ item.PreUnit || '--' }}</text>
</view>
<view class="card-row">
<text class="row-label">所属主项</text>
<text class="row-value">{{ item.UnitWorkName || '--' }}</text>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view v-if="isShow" class="bottom-btns">
<u-button size="medium" type="primary" @click="saveModel">确定到场</u-button>
</view>
<view v-if="info.State == 0" class="bottom-btns">
<u-button size="medium" type="primary" @click="savePacks">确定</u-button>
</view>
</view>
</template>
<script>
</script>
<script setup>
import {
ref
} from 'vue'
import {
onLoad,
} from '@dcloudio/uni-app'
import {
storeToRefs
} from 'pinia'
import {
useUserStore
} from '@/store'
import {
reqPackagingInformationById,
reqPipelineComponentById,
reqSavePipelineComponentToPackaging,
reqDeletePipelineComponentFromPackaging,
reqPackingInfoConfirmArrival
} from '@/api/hj.js'
// ==== 状态库 ====
const userStore = useUserStore()
const {
currentProject,
userInfo
} = storeToRefs(userStore)
<style>
</style>
// ===== 数据 =====
const info = ref({})
const packages = ref([])
const setTime = ref('')
const from = ref('1')
const isShow = ref(false)
const id = ref(null)
// ===== 生命周期 =====
onLoad((query) => {
id.value = query.id
from.value = query.from
getInfo(query.id)
})
// ===== 方法 =====
const getStatus = (val) => {
const map = {
'0': '未到场',
'1': '已发货',
'2': '已到场'
}
return map[String(val)] || '--'
}
const getInfo = async (id) => {
try {
// TODO: 调用查看详情接口
let params = {
projectId: currentProject.value?.ProjectId,
personId: userInfo.value?.PersonId,
packagingManageId: id
}
let res = await reqPackagingInformationById(params)
if (res.code === 1) {
info.value = res.data.packagingManageDetailItem
packages.value = res.data.packagingPrepipeItems
if (res.data.packagingPrepipeItems.length > 0) {
setTime.value = res.data.packagingPrepipeItems[0].PlanStartDate || ''
}
if (from.value === '0' && res.data.isPower) {
isShow.value = true
}
}
} catch (error) {
console.error('获取详情失败:', error)
uni.showToast({
title: '加载失败',
icon: 'none'
})
}
}
const savePacks = () => {
uni.navigateBack()
}
const onScan = async () => {
// 1. 启动加载提示
uni.showLoading({
title: '扫码识别中...',
mask: true
})
try {
// 2. 调用扫码 API
const scanRes = await uni.scanCode()
const result = scanRes.result
// 3. 校验二维码格式
if (!result.includes('PrePipeline$')) {
uni.hideLoading()
return uni.showToast({
title: '不是预制组件二维码',
icon: 'none'
})
}
// 4. 解析 ID
const packageId = result.split('$')[1]
if (!packageId) {
uni.hideLoading()
return uni.showToast({
title: '二维码格式错误',
icon: 'none'
})
}
// 5. 校验是否已存在
if (packages.value.some(e => e.PipelineComponentId === packageId)) {
uni.hideLoading()
return uni.showToast({
title: '预制组件已存在',
icon: 'none'
})
}
// 6. 获取组件详情
const detailRes = await reqPipelineComponentById({
projectId: currentProject.value?.ProjectId,
personId: userInfo.value?.PersonId,
PipelineComponentId: packageId
})
if (detailRes.code !== 1 || !detailRes.data?.pipelineComponentItem) {
throw new Error(detailRes.msg || '获取组件详情失败')
}
const componentData = detailRes.data.pipelineComponentItem
// 7. 添加到包装包
const saveRes = await reqSavePipelineComponentToPackaging({
packagingManageId: info.value?.PackagingManageId,
pipelineComponentId: componentData.PipelineComponentId
})
if (saveRes.code === 1) {
uni.showToast({
title: '添加成功',
icon: 'success'
})
// 8. 刷新列表
await getInfo(id.value)
} else {
throw new Error(saveRes.msg || '添加失败')
}
} catch (error) {
console.error('扫码添加失败:', error)
// 区分是用户取消扫码还是其他错误
if (error.errMsg && error.errMsg.includes('cancel')) {
// 用户取消扫码
} else {
uni.showToast({
title: error.message || '操作失败,请重试',
icon: 'none'
})
}
} finally {
// 9. 关闭加载提示
uni.hideLoading()
}
}
const handleDelPackage = (item) => {
uni.showModal({
title: '确认删除',
content: '确定要删除该预制组件吗?',
success: async (res) => {
if (res.confirm) {
// TODO 调用删除接口
try {
let delRes = await reqDeletePipelineComponentFromPackaging(item
?.PipelineComponentId)
if (delRes.code == 1) {
await getInfo(id.value)
uni.showToast({
title: '删除成功',
icon: 'none'
})
}
} catch (error) {
//TODO handle the exception
}
}
}
})
}
const saveModel = () => {
uni.showModal({
title: '确认到场',
content: '确定要确认该包装信息已到场吗?',
success: (res) => {
if (res.confirm) {
reqPackingInfoConfirmArrival({
packagingManageId: id.value,
personId: userInfo.value.PersonId
}).then(res => {
if (res.code === 1) {
uni.showToast({
title: '验证成功',
icon: 'success',
duration: 3000
})
setTimeout(() => {
uni.reLaunch({
url: '/pages/index/index'
})
}, 2000)
} else {
uni.showToast({
title: res.msg || '网络异常',
icon: 'none'
})
}
}).catch(error => {
console.error('到场确认失败:', error)
uni.showToast({
title: '网络异常',
icon: 'none'
})
})
}
}
})
}
</script>
+1 -1
View File
@@ -233,7 +233,7 @@ n <!-- 新增按钮 -->
// 列表项点击
const handleItemClick = (item) => {
uni.navigateTo({
url: `/pipe/packaging/detail?id=${item.PackagingManageId}`
url: `/pipe/packaging/detail?id=${item.PackagingManageId}&from=1`
})
}