324 lines
7.9 KiB
Vue
324 lines
7.9 KiB
Vue
<template>
|
||
<view class="detail-page">
|
||
<!-- 任务单摘要 -->
|
||
<view class="section">
|
||
<view class="section__header">
|
||
<view class="section__bar"></view>
|
||
<text class="section__title">任务单信息</text>
|
||
</view>
|
||
<view class="card">
|
||
<view class="card__row">
|
||
<text class="card__label">任务单编号</text>
|
||
<text class="card__value card__value--mono">{{ detail.TaskCode || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">任务日期</text>
|
||
<text class="card__value">{{ fmtDate(detail.TaskDate) }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">单位工程</text>
|
||
<text class="card__value">{{ detail.UnitWorkName || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">施工单位</text>
|
||
<text class="card__value">{{ detail.UnitName || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">班组</text>
|
||
<text class="card__value">{{ detail.TeamGroupName || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">流水号</text>
|
||
<text class="card__value">{{ detail.SerialNumber || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">焊口数量</text>
|
||
<text class="card__value">{{ detail.WeldJointCount ?? joints.length }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 焊口明细 -->
|
||
<view class="section">
|
||
<view class="section__header">
|
||
<view class="section__bar"></view>
|
||
<text class="section__title">焊口明细({{ joints.length }})</text>
|
||
</view>
|
||
|
||
<view
|
||
v-for="(item, index) in joints"
|
||
:key="item.WeldTaskId || item.WeldJointId || index"
|
||
class="card joint-card"
|
||
>
|
||
<view class="joint-card__title">{{ item.WeldJointCode || '--' }}</view>
|
||
<view class="card__row">
|
||
<text class="card__label">管线编号</text>
|
||
<text class="card__value">{{ item.PipelineCode || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">焊口属性</text>
|
||
<text class="card__value">{{ item.JointAttribute || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">焊接模式</text>
|
||
<text class="card__value">{{ item.WeldingMode || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">焊接类型</text>
|
||
<text class="card__value">{{ item.WeldTypeCode || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">达因</text>
|
||
<text class="card__value">{{ formatSize(item.Size) }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">盖面焊工</text>
|
||
<text class="card__value">{{ item.CoverWelderId || '--' }}</text>
|
||
</view>
|
||
<view class="card__row">
|
||
<text class="card__label">打底焊工</text>
|
||
<text class="card__value">{{ item.BackingWelderId || '--' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<u-empty
|
||
v-if="!loading && joints.length === 0"
|
||
mode="list"
|
||
text="暂无焊口明细"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 生成出库申请 -->
|
||
<view class="submit-bar">
|
||
<view
|
||
class="btn-primary-gradient"
|
||
:class="{ 'btn-primary-gradient--disabled': submitting || !canGenerate }"
|
||
@click="handleGenerate"
|
||
>
|
||
<text class="btn-primary-gradient__text">
|
||
{{ submitting ? '处理中...' : '生成出库申请单' }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
/**
|
||
* 焊接任务单详情:展示 Joints,支持生成出库申请单
|
||
*/
|
||
import { computed, ref } from 'vue'
|
||
import { onLoad } from '@dcloudio/uni-app'
|
||
import { storeToRefs } from 'pinia'
|
||
import { useUserStore } from '@/store'
|
||
import { reqWeldTaskDetail, reqWeldTaskGenerateOutPlan } from '@/api/hj.js'
|
||
|
||
const userStore = useUserStore()
|
||
const { userInfo, token } = storeToRefs(userStore)
|
||
|
||
const projectId = ref('')
|
||
const taskCode = ref('')
|
||
const unitWorkId = ref('')
|
||
const detail = ref({})
|
||
const loading = ref(false)
|
||
const submitting = ref(false)
|
||
|
||
const joints = computed(() => {
|
||
const list = detail.value?.Joints
|
||
return Array.isArray(list) ? list : []
|
||
})
|
||
|
||
const canGenerate = computed(() => !!(projectId.value && taskCode.value))
|
||
|
||
const fmtDate = (val) => {
|
||
if (!val) return '--'
|
||
const d = new Date(val)
|
||
if (isNaN(d.getTime())) return String(val).slice(0, 10)
|
||
const y = d.getFullYear()
|
||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||
const day = String(d.getDate()).padStart(2, '0')
|
||
return `${y}-${m}-${day}`
|
||
}
|
||
|
||
const formatSize = (val) => {
|
||
if (val === undefined || val === null || val === '') return '--'
|
||
return String(val)
|
||
}
|
||
|
||
const loadDetail = async () => {
|
||
if (!projectId.value || !taskCode.value) {
|
||
uni.showToast({ title: '入口参数错误', icon: 'none' })
|
||
return
|
||
}
|
||
loading.value = true
|
||
try {
|
||
const res = await reqWeldTaskDetail({
|
||
projectId: projectId.value,
|
||
taskCode: taskCode.value,
|
||
unitWorkId: unitWorkId.value || undefined,
|
||
})
|
||
detail.value = res?.data || {}
|
||
if (!res?.data) {
|
||
uni.showToast({ title: '未找到任务单', icon: 'none' })
|
||
}
|
||
} catch (e) {
|
||
console.error('任务单详情加载失败:', e)
|
||
detail.value = {}
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
const handleGenerate = () => {
|
||
if (submitting.value || !canGenerate.value) return
|
||
uni.showModal({
|
||
title: '确认生成',
|
||
content: '确定根据当前任务单生成出库申请单吗?已生成过的不会重复建单。',
|
||
success: async (modalRes) => {
|
||
if (!modalRes.confirm) return
|
||
const personId = userInfo.value?.PersonId || token.value
|
||
if (!personId) {
|
||
uni.showToast({ title: '缺少登录人信息', icon: 'none' })
|
||
return
|
||
}
|
||
submitting.value = true
|
||
try {
|
||
await reqWeldTaskGenerateOutPlan({
|
||
ProjectId: projectId.value,
|
||
TaskCode: taskCode.value,
|
||
PersonId: personId,
|
||
})
|
||
// 接口成功也可能 data 为 null(首次/已存在/无材料均可能 code:1)
|
||
uni.showToast({
|
||
title: '生成请求已处理',
|
||
icon: 'none',
|
||
})
|
||
} catch (e) {
|
||
console.error('生成出库申请失败:', e)
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
},
|
||
})
|
||
}
|
||
|
||
onLoad((opt) => {
|
||
projectId.value = decodeURIComponent(opt.projectId || '')
|
||
taskCode.value = decodeURIComponent(opt.taskCode || '')
|
||
unitWorkId.value = decodeURIComponent(opt.unitWorkId || '')
|
||
loadDetail()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.detail-page {
|
||
min-height: 100vh;
|
||
padding: 24rpx 24rpx 160rpx;
|
||
background: #f5f6f8;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.section {
|
||
margin-bottom: 24rpx;
|
||
|
||
&__header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
&__bar {
|
||
width: 8rpx;
|
||
height: 28rpx;
|
||
border-radius: 4rpx;
|
||
background: #2979ff;
|
||
}
|
||
|
||
&__title {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #1a2332;
|
||
}
|
||
}
|
||
|
||
.card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 8rpx 24rpx;
|
||
margin-bottom: 16rpx;
|
||
|
||
&__row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 24rpx;
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
|
||
&__label {
|
||
flex-shrink: 0;
|
||
font-size: 26rpx;
|
||
color: #999;
|
||
}
|
||
|
||
&__value {
|
||
flex: 1;
|
||
text-align: right;
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
word-break: break-all;
|
||
|
||
&--mono {
|
||
font-family: monospace;
|
||
font-weight: 600;
|
||
color: #1a2332;
|
||
}
|
||
}
|
||
}
|
||
|
||
.joint-card {
|
||
&__title {
|
||
padding: 20rpx 0 4rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #1a2332;
|
||
font-family: monospace;
|
||
}
|
||
}
|
||
|
||
.submit-bar {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
||
background: #fff;
|
||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.btn-primary-gradient {
|
||
height: 88rpx;
|
||
border-radius: 44rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, #2979ff, #5a9aff);
|
||
|
||
&--disabled {
|
||
opacity: 0.55;
|
||
}
|
||
|
||
&__text {
|
||
font-size: 30rpx;
|
||
color: #fff;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
</style>
|