| | |
| | | "name" : "GS-MES-AP", |
| | | "appid" : "__UNI__F08FAE3", |
| | | "description" : "", |
| | | "versionName" : "1.1.2.4", |
| | | "versionName" : "1.1.2.6", |
| | | "versionCode" : 1, |
| | | "transformPx" : false, |
| | | /* 5+App特有相关 */ |
| | |
| | | <view class="info-value highlight">{{formData.phsy}}</view> |
| | | </view> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | <!-- 表单上方操作按钮区 --> |
| | | <view class="top-action-buttons"> |
| | | <button class="action-btn" @click="getInspectionItems" v-if="this.current">获取检验项目</button> |
| | | <button class="action-btn" @click="handleEmergencyRelease" v-if="this.current">紧急放行</button> |
| | | <button class="action-btn" @click="handleWithdraw" v-if="this.current">撤回</button> |
| | | </view> |
| | | |
| | | <!-- 检验项目表格 --> |
| | | <view class="inspection-table"> |
| | |
| | | </table> |
| | | </view> |
| | | |
| | | <!-- 页面内容区域 --> |
| | | <view class="content-wrapper"> |
| | | <!-- 为底部按钮留出空间 --> |
| | | </view> |
| | | |
| | | <!-- 固定在底部的操作按钮区 --> |
| | | <view class="fixed-action-buttons"> |
| | | <button class="action-btn" @click="handleEmergencyRelease" v-if="this.current">紧急放行</button> |
| | | <button class="action-btn" @click="handleWithdraw" v-if="this.current">撤回</button> |
| | | <button class="action-btn" @click="getInspectionItems" v-if="this.current">获取检验项目</button> |
| | | <button class="action-btn" @click="addDestruction" v-if="this.current">破坏实验</button> |
| | | <button class="action-btn" @click="uploadImages">上传/查看图片</button> |
| | | <button class="action-btn" @click="fetchDrawingNumber">调取PLM图纸</button> |
| | | <button class="action-btn" @click="viewAttachmentInfo">查看附件信息</button> |
| | | <button class="action-btn" @click="addDefectDescription" v-if="this.current">添加不良描述</button> |
| | | <button class="action-btn primary" @click="submitInspection" v-if="this.current">检验提交</button> |
| | | <!-- 表单下方操作按钮区 --> |
| | | <view class="bottom-action-buttons"> |
| | | <button class="action-btn small" @click="addDestruction" v-if="this.current">破坏实验</button> |
| | | <button class="action-btn small" @click="uploadImages">上传/查看图片</button> |
| | | <button class="action-btn small" @click="fetchDrawingNumber">调取PLM图纸</button> |
| | | <button class="action-btn small" @click="viewAttachmentInfo">查看附件信息</button> |
| | | <button class="action-btn small" @click="addDefectDescription" v-if="this.current">添加不良描述</button> |
| | | <button class="action-btn small primary" @click="submitInspection" v-if="this.current">检验提交</button> |
| | | </view> |
| | | <view v-if="remarksPopup" class="overlay"> |
| | | <view class="popup"> |
| | |
| | | font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif; |
| | | max-width: 1000px; |
| | | margin: 0 auto; |
| | | padding: 20px 20px 160px 20px; /* 底部增加padding为固定按钮留空间 */ |
| | | padding: 20px; |
| | | background-color: #fff; |
| | | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); |
| | | min-height: 100vh; |
| | |
| | | background-color: #f1f5f9; |
| | | } |
| | | |
| | | /* 固定底部按钮样式 */ |
| | | .fixed-action-buttons { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: #fff; |
| | | box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); |
| | | padding: 10px 15px 20px 15px; |
| | | z-index: 100; |
| | | /* 表单上方操作按钮区样式 */ |
| | | .top-action-buttons { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 8px; |
| | | max-height: 150px; |
| | | overflow-y: auto; |
| | | justify-content: flex-end; |
| | | gap: 10px; |
| | | margin: 20px 0; |
| | | padding: 15px; |
| | | background-color: #f8f9fa; |
| | | border-radius: 8px; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | |
| | | /* 表单下方操作按钮区样式 */ |
| | | .bottom-action-buttons { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | gap: 10px; |
| | | margin: 20px 0; |
| | | padding: 10px; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .action-btn { |
| | |
| | | background-color: #2980b9; |
| | | } |
| | | |
| | | /* 内容包装器,为底部按钮留出空间 */ |
| | | .content-wrapper { |
| | | height: 20px; /* 额外的空白区域 */ |
| | | /* 小尺寸按钮样式 */ |
| | | .action-btn.small { |
| | | padding: 8px 12px; |
| | | font-size: 12px; |
| | | min-height: 36px; |
| | | } |
| | | |
| | | /* 原有按钮样式保持兼容 */ |
| | |
| | | .attachment-popup-close:hover { |
| | | background: #bdbdbd; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 500px) { |
| | | |
| | | .info-row, |
| | | .info-block { |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | |
| | | .doc-links { |
| | | margin-left: 0; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .top-action-buttons { |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | } |
| | | |
| | | .bottom-action-buttons { |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | } |
| | | |
| | | .action-btn { |
| | | width: 100%; |
| | | } |
| | | |
| | | .inspection-table table { |
| | | display: block; |
| | | overflow-x: auto; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | }); |
| | | }, |
| | | previewImage(index) { |
| | | // uni.previewImage({ |
| | | // current: index, // 设置当前显示图片的链接 |
| | | // urls: this.qsImage.map(s=>s.img), // 需要预览的图片链接列表 |
| | | // loop: false, // 是否开启图片轮播,默认为 false |
| | | // indicator: 'default',// 图片指示器类型,可选值为 "default"、"number"、"pointer",默认为 "default" |
| | | // }); |
| | | // 检查当前图片是否存在 |
| | | const currentImage = this.qsImage[index]; |
| | | if (!currentImage || !currentImage.img) { |
| | | uni.showToast({ |
| | | title: '图片数据异常', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '加载中...' |
| | | }); |
| | | |
| | | // 如果是base64格式,需要转换为临时文件路径 |
| | | if (currentImage.img.startsWith('data:')) { |
| | | // 转换所有base64图片为临时文件路径 |
| | | const convertPromises = this.qsImage.map(item => { |
| | | if (item.img.startsWith('data:')) { |
| | | return base64ToPath(item.img); |
| | | } |
| | | return Promise.resolve(item.img); |
| | | }); |
| | | |
| | | Promise.all(convertPromises) |
| | | .then(tempFilePaths => { |
| | | uni.hideLoading(); |
| | | uni.previewImage({ |
| | | current: tempFilePaths[index], |
| | | urls: tempFilePaths, |
| | | loop: false, |
| | | indicator: 'default', |
| | | fail: (err) => { |
| | | console.error('预览失败:', err); |
| | | uni.showToast({ |
| | | title: '预览失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | }) |
| | | .catch(error => { |
| | | uni.hideLoading(); |
| | | console.error('转换失败:', error); |
| | | uni.showToast({ |
| | | title: '图片转换失败', |
| | | icon: 'none' |
| | | }); |
| | | }); |
| | | } else { |
| | | // 如果不是base64格式,直接预览 |
| | | uni.hideLoading(); |
| | | uni.previewImage({ |
| | | current: index, |
| | | urls: this.qsImage.map(s => s.img), |
| | | loop: false, |
| | | indicator: 'default', |
| | | fail: (err) => { |
| | | console.error('预览失败:', err); |
| | | uni.showToast({ |
| | | title: '预览失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | init() { |
| | | this.$post({ |
| | |
| | | let tableData = res.data.tbBillList; |
| | | this.qsImage = tableData; |
| | | this.qsImage.forEach(s => { |
| | | s.img = 'data:image/png;base64,' + s.base64Date; |
| | | // 根据文件扩展名判断图片类型,默认为jpeg |
| | | let imageType = 'jpeg'; |
| | | if (s.Picturename) { |
| | | const ext = s.Picturename.toLowerCase().split('.').pop(); |
| | | if (ext === 'png') { |
| | | imageType = 'png'; |
| | | } else if (ext === 'gif') { |
| | | imageType = 'gif'; |
| | | } else if (ext === 'webp') { |
| | | imageType = 'webp'; |
| | | } |
| | | } |
| | | s.img = `data:image/${imageType};base64,${s.base64Date}`; |
| | | }); |
| | | }); |
| | | }, |
| | |
| | | <span class="info-label">创建时间:</span> |
| | | <span class="info-value">{{formData.createTime}}</span> |
| | | <span class="info-label">检验类型:</span> |
| | | <span class="info-value">{{formData.SJ_MJ}}</span> |
| | | <span class="info-value">{{formData.sJ_MJ}}</span> |
| | | </view> |
| | | <view class="info-row" v-if="isUpdate"> |
| | | <span class="info-label">检验类型:</span> |
| | |
| | | </view> |
| | | |
| | | <view class="info-block"> |
| | | <view class="info-label">计划编号:</view> |
| | | <view class="info-label">工单单号:</view> |
| | | <picker v-if="isUpdate" class="info-picker" name="selector" :range="DAA001List" |
| | | @change="onDaa001Change"> |
| | | <text>{{ DAA001List[DAA001Index] }}</text> |
| | |
| | | <view v-else class="info-value">{{formData.daa001}}</view> |
| | | </view> |
| | | |
| | | <view class="info-block"> |
| | | <view class="info-label">销售订单号:</view> |
| | | <view class="info-value">{{formData.caa015}}</view> |
| | | </view> |
| | | |
| | | <view class="info-block"> |
| | | <view class="info-label">客户:</view> |
| | | <view class="info-value">{{formData.cust}}</view> |
| | | </view> |
| | | |
| | | |
| | | |
| | | <view class="info-block"> |
| | | <view class="info-label">产品名称:</view> |
| | |
| | | <button class="action-btn primary" v-if="isShowTable && isUpdate" @click="saveTable"> |
| | | 生成检验项目 |
| | | </button> |
| | | <button class="action-btn success" v-if="!isUpdate && formData.fsubmit == 0 && !isShowTable" @click="getGenUpdate"> |
| | | 获取检验项目 |
| | | </button> |
| | | <button class="action-btn success" v-if="!isUpdate && formData.fsubmit ==0 && !isShowTable" @click="submitInspection"> |
| | | 提交检验 |
| | | </button> |
| | | </view> |
| | | <!-- 弹出框 --> |
| | | <view v-if="remarksPopup" class="overlay"> |
| | |
| | | comments: "", |
| | | statusUser: "", |
| | | SJ_MJ: '首检', |
| | | fsubmit:"", |
| | | }, |
| | | |
| | | DAA020List: [], |
| | |
| | | } |
| | | }).then(res => { |
| | | if (res.data.tbBillList) { |
| | | this.$showMessage("巡检生成成功"); |
| | | this.$showMessage("首检生成成功"); |
| | | this.init(); |
| | | } |
| | | }); |
| | |
| | | }, |
| | | save() { |
| | | |
| | | if (this.tableData.length === 0) { |
| | | this.$showMessage(this.formData.itemNo + "物料没有检验项目"); |
| | | return; |
| | | } |
| | | //if (this.tableData.length === 0) { |
| | | //this.$showMessage(this.formData.itemNo + "物料没有检验项目"); |
| | | //return; |
| | | //} |
| | | |
| | | if (!this.formData.daa001) { |
| | | this.$showMessage("请选择计划编号"); |
| | |
| | | this.SJ_MJIndex = e.mp.detail.value; |
| | | this.formData.SJ_MJ = this.SJ_MJList[this.SJ_MJIndex]; |
| | | }, |
| | | submitInspection() { |
| | | if (this.formData.id) { |
| | | this.$post({ |
| | | url: "/SJ/SjSubmit", |
| | | data: { |
| | | id: this.formData.id, |
| | | userNo: this.$loginInfo.account |
| | | } |
| | | }).then(res => { |
| | | if (res.data.tbBillList) { |
| | | this.$showMessage("提交成功"); |
| | | this.init(); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | getGenUpdate() { |
| | | if (!this.formData.id || !this.formData.billNo) { |
| | | this.$showMessage("请先保存检验单!"); |
| | | return; |
| | | } |
| | | this.$post({ |
| | | url: "/SJ/GenUpdate", |
| | | data: { |
| | | id: this.formData.id, |
| | | no: this.formData.billNo, |
| | | user: this.$loginInfo.account |
| | | } |
| | | }).then(res => { |
| | | if (res.data.result === 0) { |
| | | this.$showMessage("获取检验项目成功"); |
| | | this.init(); |
| | | } else { |
| | | this.$showMessage(res.data.message || "获取失败"); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | onShow() { |
| | | //每次进入页面都会执行的方法 |
| | |
| | | background-color: #c0392b; |
| | | } |
| | | |
| | | .action-btn.success { |
| | | background-color: #2ecc71; |
| | | color: white; |
| | | } |
| | | |
| | | .action-btn.success:hover { |
| | | background-color: #27ae60; |
| | | } |
| | | |
| | | /* 弹出框样式 */ |
| | | .overlay { |
| | | position: fixed; |
| | |
| | | <view v-else class="info-value">{{ formData.itemNo }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="info-label">计划编号</view> |
| | | <view class="info-label">工单单号</view> |
| | | <picker v-if="isUpdate" class="picker-input" name="selector" :range="DAA001List" |
| | | @change="onDaa001Change"> |
| | | <view class="picker-value">{{ DAA001List[DAA001Index] || '请选择' }}</view> |
| | |
| | | <button class="action-btn warning" v-if="!isUpdate && !isShowTable" @click="saveRemarks">添加不合格描述</button> |
| | | <button class="action-btn primary" v-if="isShowTable" @click="getTable">获取检验项目</button> |
| | | <button class="action-btn primary" v-if="isShowTable && isUpdate" @click="saveTable">生成检验项目</button> |
| | | <button class="action-btn success" v-if="!isUpdate && !isShowTable" @click="getGenUpdate">获取检验项目</button> |
| | | <button class="action-btn success" v-if="!isUpdate && !isShowTable" @click="submitInspection">提交检验</button> |
| | | </view> |
| | | <!-- 修改不合格描述弹出框 --> |
| | | <view v-if="remarksPopup" class="overlay"> |
| | |
| | | }, |
| | | getItem() { |
| | | |
| | | if (this.isSubmit) { |
| | | this.$showMessage("此物料无启用的检验项目,请维护!"); |
| | | return; |
| | | } |
| | | |
| | | |
| | | if (!this.formData.billNo) { |
| | | this.$showMessage("请选择计划编号"); |
| | | this.$showMessage("请选择工单单号"); |
| | | return; |
| | | } |
| | | |
| | |
| | | this.isUpdate = false; |
| | | this.init(); |
| | | }) |
| | | }, |
| | | submitInspection() { |
| | | if (this.formData.id) { |
| | | this.$post({ |
| | | url: "/XJ/SjSubmit", |
| | | data: { |
| | | id: this.formData.id, |
| | | userNo: this.$loginInfo.account |
| | | } |
| | | }).then(res => { |
| | | if (res.data.tbBillList) { |
| | | this.$showMessage("提交成功"); |
| | | this.init(); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | getGenUpdate() { |
| | | if (!this.formData.id || !this.formData.releaseNo) { |
| | | this.$showMessage("请先保存检验单!"); |
| | | return; |
| | | } |
| | | this.$post({ |
| | | url: "/XJ/GenUpdate", |
| | | data: { |
| | | id: this.formData.id, |
| | | no: this.formData.releaseNo, |
| | | user: this.$loginInfo.account |
| | | } |
| | | }).then(res => { |
| | | if (res.data.result === 0) { |
| | | this.$showMessage("获取检验项目成功"); |
| | | this.init(); |
| | | } else { |
| | | this.$showMessage(res.data.message || "获取失败"); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | onShow() { |
| | |
| | | color: white; |
| | | } |
| | | |
| | | .action-btn.success { |
| | | background-color: #2ecc71; |
| | | color: white; |
| | | } |
| | | |
| | | /* 弹出框样式 */ |
| | | .overlay { |
| | | position: fixed; |