diff --git a/api/base.js b/api/base.js
index 475ef05..289cc26 100644
--- a/api/base.js
+++ b/api/base.js
@@ -31,6 +31,16 @@ export const reqToDoItemByProjectIdUserId = (projectId, personId)=>get(`ToDoItem
*/
export const reqGetGrooveTypeList = ()=>get(`BaseInfo/GetGrooveType`)
+/**
+ * 获取焊缝类型列表
+ */
+export const reqGetWeldTypeList = () => get(`BaseInfo/GetWeldType`)
+
+/**
+ * 获取焊接方法列表
+ */
+export const reqGetWeldingMethodList = () => get(`BaseInfo/GetWeldingMethod`)
+
/**
* 附件上传
* @param {string} filePath - 本地文件路径
diff --git a/api/hj.js b/api/hj.js
index f44f2d3..cd5d7cf 100644
--- a/api/hj.js
+++ b/api/hj.js
@@ -15,7 +15,8 @@ export const reqHJIndexData = (projectId) => get(`HJGLIndex/GetJGLIndexItem?proj
export const reqGetWeldJointByWeldJointId = (id) => get(`PipeJoint/getWeldJointByWeldJointId?WeldJointId=${id}`)
/**
- * 焊接日报填报
+ * 焊接日报填报(提交时传 WeldTypeId / WeldingMethodId,后端同步更新焊口对应字段)
+ * @param {Object} data - { WeldJointId, Personid, time, weldingLocation, welderType, WeldTypeId, WeldingMethodId, PreWeldAttachUrl, PostWeldAttachUrl }
*/
export const reqSaveWeldingDailyByWeldJointId = (data={}) => post(
`PreWeldingDaily/SaveWeldingDailyByWeldJointId`,data
@@ -157,6 +158,12 @@ export const reqPreWeldJointByWeldJointId = (WeldJointId)=>get(`PreWeldInspectio
*/
export const reqCuttingCheckByWeldJointId = (weldJointId)=>get(`/PreWeldCuttingCheck/GetRecordsByWeldJointId?weldJointId=${weldJointId}`)
+/**
+ * 获取专项审核办理人列表
+ * @param {String} projectId
+ */
+export const reqGetSpecialReviewers = (projectId) => get(`/PreWeldCuttingCheck/GetSpecialReviewers`, { projectId })
+
/**
* 保存下料检查记录
* @param {Object} data
@@ -221,3 +228,22 @@ export const reqAuditWeldingDaily = (data = {}) => post(`/PreWeldingDaily/AuditP
*/
export const reqDeleteWeldingDaily = (data = {}) => post(`/PreWeldingDaily/DeletePendingWeldingDailyTempDetails`, data)
+// ========================= 焊缝外观检测 ====================================
+/**
+ * 分页查询当前项目中已焊接的焊口
+ * @param {Object} params - { projectId, pipelineCode?, weldJointCode?, pageIndex?, pageSize? }
+ */
+export const reqWeldedJoints = (params = {}) => get('/WeldAppearanceCheck/GetWeldedJoints', params)
+
+/**
+ * 查询焊口基础信息及历史外观检测记录
+ * @param {String} weldJointId 焊口ID
+ */
+export const reqWeldAppearanceJointDetail = (weldJointId) => get('/WeldAppearanceCheck/GetJointDetail', { weldJointId })
+
+/**
+ * 保存焊缝外观检测记录
+ * @param {Object} data - { AppearanceCheckId?, ProjectId, WeldJointId, IsQualified, CheckPerson, CheckTime, Remark, AttachUrl, CreateUser }
+ */
+export const reqSaveWeldAppearanceCheck = (data = {}) => post('/WeldAppearanceCheck/SaveRecord', data)
+
diff --git a/components/nbd-history-card.vue b/components/nbd-history-card.vue
new file mode 100644
index 0000000..9da0381
--- /dev/null
+++ b/components/nbd-history-card.vue
@@ -0,0 +1,322 @@
+
+
+
+
+ 暂无{{ title }}记录
+
+
+
+
+
+
+
+
+
+
+ 外观是否合格
+
+
+ {{ isPass(latest) ? '\u2713' : '\u2717' }}
+
+
+ {{ qualifiedText(latest) }}
+
+
+
+
+ 检测人
+ {{ latest.CheckPersonName || '--' }}
+
+
+ 检测时间
+ {{ latest.CheckTime || '--' }}
+
+
+ 备注
+ {{ latest.Remark || '--' }}
+
+
+ 照片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/nbd-select.vue b/components/nbd-select.vue
index c5d99d6..76c6eba 100644
--- a/components/nbd-select.vue
+++ b/components/nbd-select.vue
@@ -22,7 +22,8 @@
-
+
@@ -128,7 +129,8 @@
'cancel',
'confirm',
'searchChange',
- 'change'
+ 'change',
+ 'scrolltolower'
])
const localVisible = ref(false)
@@ -218,6 +220,11 @@
emit('searchChange', val)
}
+ // 列表触底
+ const handleScrollToLower = () => {
+ emit('scrolltolower')
+ }
+
// 取消
const handleCancel = () => {
emit('cancel')
diff --git a/pages.json b/pages.json
index 4069d49..65ce0e7 100644
--- a/pages.json
+++ b/pages.json
@@ -163,6 +163,12 @@
"style": {
"navigationBarTitleText": "日报审核详情"
}
+ },
+ {
+ "path": "hj/weld_appearance",
+ "style": {
+ "navigationBarTitleText": "焊缝检测"
+ }
}
]
}
diff --git a/scanpages/hj/daily_audit.vue b/scanpages/hj/daily_audit.vue
index ecc2a28..cbe391a 100644
--- a/scanpages/hj/daily_audit.vue
+++ b/scanpages/hj/daily_audit.vue
@@ -411,6 +411,7 @@
bottom: 0;
background: #ffffff;
padding: 20rpx 32rpx;
+ padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
gap: 20rpx;
@@ -447,8 +448,8 @@
}
}
- // 给底部操作栏留出空间
+ // 给底部操作栏留出空间(含安全区)
.list-scroll {
- padding-bottom: 140rpx;
+ padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
}
diff --git a/scanpages/hj/daily_paper.vue b/scanpages/hj/daily_paper.vue
index 579626c..8e64419 100644
--- a/scanpages/hj/daily_paper.vue
+++ b/scanpages/hj/daily_paper.vue
@@ -69,9 +69,14 @@
{{ form.Specification || '--' }}
-
+
焊缝类型
- {{ form.WeldTypeCode || '--' }}
+
+
+ {{ form.WeldTypeCode || '请选择' }}
+
+
+
@@ -119,10 +124,13 @@
-
+
焊接方法
-
-
+
+
+ {{ form.WeldingMethodCode || '请选择' }}
+
+
@@ -169,6 +177,14 @@
+
+
+
+
+
+
@@ -176,7 +192,7 @@
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { reqGetWeldJointByWeldJointId, reqSaveWeldingDailyByWeldJointId, reqGetManualPointSave, reqFitupCheckByWeldJointId } from '@/api/hj.js'
-import { reqWeldingLocation } from '@/api/base.js'
+import { reqWeldingLocation, reqGetWeldTypeList, reqGetWeldingMethodList } from '@/api/base.js'
import { useUserStore, useMenuStore } from '@/store'
@@ -193,7 +209,11 @@ const postWeldAttachUrl = ref('')
// ===== 弹窗 =====
const showLocationPicker = ref(false)
const showTypePicker = ref(false)
+const showWeldTypePicker = ref(false)
+const showWeldingMethodPicker = ref(false)
const locationList = ref([])
+const weldTypeList = ref([])
+const weldingMethodList = ref([])
const welderTypeList = ref([
{ BaseInfoName: '打底/盖面', BaseInfoCode: 0 },
{ BaseInfoName: '打底', BaseInfoCode: 1 },
@@ -246,6 +266,34 @@ const handleConfirmType = (item) => {
showTypePicker.value = false
}
+const handleShowWeldTypeSelect = () => {
+ reqGetWeldTypeList().then(res => {
+ weldTypeList.value = res.data || []
+ showWeldTypePicker.value = true
+ })
+}
+
+const handleConfirmWeldType = (item) => {
+ form.value.WeldTypeId = item.BaseInfoId
+ form.value.WeldTypeCode = item.BaseInfoCode
+ form.value.WeldTypeName = item.BaseInfoName
+ showWeldTypePicker.value = false
+}
+
+const handleShowWeldingMethodSelect = () => {
+ reqGetWeldingMethodList().then(res => {
+ weldingMethodList.value = res.data || []
+ showWeldingMethodPicker.value = true
+ })
+}
+
+const handleConfirmWeldingMethod = (item) => {
+ form.value.WeldingMethodId = item.BaseInfoId
+ form.value.WeldingMethodCode = item.BaseInfoCode
+ form.value.WeldingMethodName = item.BaseInfoName
+ showWeldingMethodPicker.value = false
+}
+
// ===== 操作 =====
const handlePoint = async () => {
await reqGetManualPointSave(form.value.WeldJointId)
@@ -279,6 +327,9 @@ const handleReport = () => {
time: form.value.WeldingDateTemp,
weldingLocation: form.value.WeldingLocationId || '',
welderType: form.value.welderType,
+ // 同步更新焊口焊缝类型 / 焊接方法
+ WeldTypeId: form.value.WeldTypeId || '',
+ WeldingMethodId: form.value.WeldingMethodId || '',
PreWeldAttachUrl: preWeldAttachUrl.value || form.value.PreWeldAttachUrl || '',
PostWeldAttachUrl: postWeldAttachUrl.value || form.value.PostWeldAttachUrl || ''
})
@@ -295,11 +346,42 @@ const handleMutualCheck = () => {
uni.navigateTo({ url: '/scanpages/hj/make_right?id=' + weldJointId.value })
}
+// 按 Code 回填 Id,保证未重选时提交仍能同步更新焊口
+const fillTypeMethodIds = async () => {
+ const needWeldType = form.value.WeldTypeCode && !form.value.WeldTypeId
+ const needMethod = form.value.WeldingMethodCode && !form.value.WeldingMethodId
+ if (!needWeldType && !needMethod) return
+ try {
+ const tasks = []
+ if (needWeldType) tasks.push(reqGetWeldTypeList())
+ else tasks.push(Promise.resolve(null))
+ if (needMethod) tasks.push(reqGetWeldingMethodList())
+ else tasks.push(Promise.resolve(null))
+ const [typeRes, methodRes] = await Promise.all(tasks)
+ if (typeRes?.data) {
+ const hit = typeRes.data.find(i => i.BaseInfoCode === form.value.WeldTypeCode)
+ if (hit) {
+ form.value.WeldTypeId = hit.BaseInfoId
+ form.value.WeldTypeName = hit.BaseInfoName
+ }
+ }
+ if (methodRes?.data) {
+ const hit = methodRes.data.find(i => i.BaseInfoCode === form.value.WeldingMethodCode)
+ if (hit) {
+ form.value.WeldingMethodId = hit.BaseInfoId
+ form.value.WeldingMethodName = hit.BaseInfoName
+ }
+ }
+ } catch (e) {
+ console.error('回填焊缝类型/焊接方法ID失败:', e)
+ }
+}
+
// ===== 生命周期 =====
onLoad((opt) => {
weldJointId.value = opt.id || ''
- reqGetWeldJointByWeldJointId(opt.id).then(res => {
+ reqGetWeldJointByWeldJointId(opt.id).then(async (res) => {
form.value = res.data || {}
if (form.value.CoverWelderName) {
form.value.welderName = form.value.CoverWelderName
@@ -316,6 +398,8 @@ onLoad((opt) => {
// 回显已有照片
preWeldAttachUrl.value = form.value.PreWeldAttachUrl || ''
postWeldAttachUrl.value = form.value.PostWeldAttachUrl || ''
+
+ await fillTypeMethodIds()
})
reqFitupCheckByWeldJointId(opt.id).then(res => {
diff --git a/scanpages/hj/material_sampling.vue b/scanpages/hj/material_sampling.vue
index a71c22d..5424444 100644
--- a/scanpages/hj/material_sampling.vue
+++ b/scanpages/hj/material_sampling.vue
@@ -62,6 +62,24 @@
failText="不准确" />
+
+
+ 专项审核办理人
+
+
+ {{ specialReviewerName || '请选择' }}
+
+
+
+
+
+
+
+ 两侧主编码反馈
+
+
+
+
@@ -174,6 +192,10 @@
提交结果
+
+
+
@@ -183,7 +205,7 @@ import { onLoad } from '@dcloudio/uni-app'
import { storeToRefs } from 'pinia'
import { useUserStore, useMenuStore } from '@/store'
-import { reqPreWeldJointByWeldJointId, reqSaveCuttingCheck, reqCuttingCheckByWeldJointId, reqGetAntiCorrosionCheck } from '@/api/hj'
+import { reqPreWeldJointByWeldJointId, reqSaveCuttingCheck, reqCuttingCheckByWeldJointId, reqGetAntiCorrosionCheck, reqGetSpecialReviewers } from '@/api/hj'
const cuttingFields = [
{ label: '下料长度', key: 'CuttingLength' },
@@ -191,6 +213,7 @@ const cuttingFields = [
{ label: '坡口角度', key: 'GrooveAngle' },
{ label: '材料编码批次', key: 'IsMaterialCodeBatchNoAccurate', type: 'tag', tagMatch: true, tagPassText: '准确', tagFailText: '不准确' },
{ label: '材料数量', key: 'IsMaterialQuantityAccurate', type: 'tag', tagMatch: true, tagPassText: '准确', tagFailText: '不准确' },
+ { label: '专项审核办理人', key: 'SpecialReviewerName' },
{ label: '检查人', key: 'CheckPersonName' },
{ label: '检查时间', key: 'CheckTime' },
{ label: '检查结果', key: 'CheckResult', type: 'tag', tagMatch: '合格' },
@@ -231,11 +254,21 @@ const layingOffForm = ref({
CheckResult: '合格',
IsMaterialCodeBatchNoAccurate: '准确',
IsMaterialQuantityAccurate: '准确',
+ SpecialReviewerId: '',
UnqualifiedReason: '',
RectifyRequirement: '',
Remark: ''
})
+const showReviewerPicker = ref(false)
+const reviewerList = ref([])
+const specialReviewerName = ref('')
+
+// 材料编码批次或材料数量不准确时,专项审核办理人必填
+const needSpecialReviewer = computed(() =>
+ layingOffForm.value.IsMaterialCodeBatchNoAccurate === '不准确' ||
+ layingOffForm.value.IsMaterialQuantityAccurate === '不准确'
+)
// 照片组件引用
const photoRef = ref(null)
@@ -260,11 +293,40 @@ watch(() => layingOffForm.value.CheckResult, async (val) => {
}
})
+const handleShowReviewerSelect = () => {
+ const projectId = currentProject.value?.ProjectId || info.value?.ProjectId
+ if (!projectId) {
+ uni.showToast({ title: '缺少项目信息', icon: 'none' })
+ return
+ }
+ reqGetSpecialReviewers(projectId).then(res => {
+ reviewerList.value = Array.isArray(res.data) ? res.data : []
+ showReviewerPicker.value = true
+ })
+}
+
+const handleConfirmReviewer = (item) => {
+ if (!item) return
+ layingOffForm.value.SpecialReviewerId = item.BaseInfoId || item.PersonId || ''
+ specialReviewerName.value = item.BaseInfoName || item.PersonName || ''
+ showReviewerPicker.value = false
+}
+
+const validateSpecialReviewer = () => {
+ if (!needSpecialReviewer.value) return true
+ if (!layingOffForm.value.SpecialReviewerId) {
+ uni.showToast({ title: '请选择专项审核办理人', icon: 'none' })
+ return false
+ }
+ return true
+}
+
const handleSubmit = () => {
if (!canEdit.value) {
uni.showToast({ title: '当前岗位仅可查看', icon: 'none' })
return
}
+ if (!validateSpecialReviewer()) return
uni.showModal({
title: '确认提交',
content: '确定提交吗?',
@@ -286,6 +348,7 @@ const handleSubmit = () => {
GrooveAngle: layingOffForm.value.GrooveAngle, // 坡口角度
IsMaterialCodeBatchNoAccurate: layingOffForm.value.IsMaterialCodeBatchNoAccurate === '准确', // 材料编码批次
IsMaterialQuantityAccurate: layingOffForm.value.IsMaterialQuantityAccurate === '准确', // 材料数量
+ SpecialReviewerId: layingOffForm.value.SpecialReviewerId || '', // 专项审核办理人
CheckPerson: userInfo.value?.PersonId, // 检查人员
CheckTime: uni.formatTime(new Date().getTime(), 'YYYY-MM-DD HH:mm'), // 检查时间
CreateUser: userInfo.value?.PersonId, // 创建人员
diff --git a/scanpages/hj/weld_appearance.vue b/scanpages/hj/weld_appearance.vue
new file mode 100644
index 0000000..46a9ffb
--- /dev/null
+++ b/scanpages/hj/weld_appearance.vue
@@ -0,0 +1,361 @@
+
+
+
+
+ {{ info.WeldJointCode || '--' }}
+
+
+ 管线编码
+ {{ info.PipelineCode || '--' }}
+
+
+ 项目名称
+ {{ info.ProjectName || info.ProjectId || '--' }}
+
+
+
+
+
+
+
+
+
+ 外观是否合格
+
+
+
+
+
+ 检测人
+
+ {{ checkPersonName || '--' }}
+
+
+
+ 备注
+
+
+
+
+
+ 照片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交结果
+
+
+
+
+
+
+
+
diff --git a/utils/constant.js b/utils/constant.js
index 9e491d2..d10044f 100644
--- a/utils/constant.js
+++ b/utils/constant.js
@@ -88,6 +88,15 @@ export const defaultApps = [{
funcKey: 'dailyAudit',
prefix: 'nbd-icon',
selected: false
+ },
+ {
+ name: '焊缝检测',
+ icon: 'daiban',
+ menuId: "",
+ path: "/scanpages/hj/weld_appearance",
+ isScan: true,
+ prefix: 'nbd-icon',
+ selected: false
}
]