manifest.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pages/QC/LLJ/Add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pages/QC/LLJ/ImageItem.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pages/QC/SJ/Add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pages/QC/XJ/Add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
manifest.json
@@ -2,7 +2,7 @@ "name" : "GS-MES-AP", "appid" : "__UNI__F08FAE3", "description" : "", "versionName" : "1.1.2.4", "versionName" : "1.1.2.6", "versionCode" : 1, "transformPx" : false, /* 5+App特有相关 */ pages/QC/LLJ/Add.vue
@@ -104,12 +104,13 @@ <view class="info-label">破坏实验数量:</view> <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"> @@ -146,22 +147,14 @@ </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"> @@ -1889,7 +1882,7 @@ 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; @@ -2014,22 +2007,27 @@ 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: #ecf0f1; @@ -2062,9 +2060,11 @@ background-color: #2980b9; } /* 内容包装器,为底部按钮留出空间 */ .content-wrapper { height: 20px; /* 额外的空白区域 */ /* 小尺寸按钮样式 */ .action-btn.small { padding: 8px 12px; font-size: 12px; min-height: 36px; } /* 原有按钮样式保持兼容 */ @@ -2506,4 +2506,38 @@ .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> pages/QC/LLJ/ImageItem.vue
@@ -1,233 +1,306 @@ <template> <!-- #ifdef APP --> <scroll-view class="page-scroll-view"> <!-- #endif --> <view> <view class="uni-common-mt"> <view class="uni-list list-pd" style="padding: 15px;"> <view class="uni-flex" style="margin-bottom: 10px;"> <view class="uni-list-cell-left">点击可预览选好的图片</view> <view style="margin-left: auto;"> <text class="click-t">{{ qsImage.length }}/{{ countIndex + 1 }}</text> </view> </view> <view class="uni-flex" style="flex-wrap: wrap;"> <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box" style="position: relative; border: 0;"> <image :src="image.img" :data-src="image.img" @tap="previewImage(index)"></image> <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image> </view> <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image> </view> </view> </view> <view class="plus-button"> <button type="primary" class="upImg" @click="save">上传图片</button> </view> </view> <!-- #ifdef APP --> </scroll-view> <!-- #endif --> </template> <!-- #ifdef APP --> <scroll-view class="page-scroll-view"> <!-- #endif --> <view> <view class="uni-common-mt"> <view class="uni-list list-pd" style="padding: 15px;"> <view class="uni-flex" style="margin-bottom: 10px;"> <view class="uni-list-cell-left">点击可预览选好的图片</view> <view style="margin-left: auto;"> <text class="click-t">{{ qsImage.length }}/{{ countIndex + 1 }}</text> </view> </view> <view class="uni-flex" style="flex-wrap: wrap;"> <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box" style="position: relative; border: 0;"> <image :src="image.img" :data-src="image.img" @tap="previewImage(index)"></image> <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image> </view> <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image> </view> </view> </view> <view class="plus-button"> <button type="primary" class="upImg" @click="save">上传图片</button> </view> </view> <!-- #ifdef APP --> </scroll-view> <!-- #endif --> </template> <script> import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index' var sourceTypeArray = [ ['camera'], ['album'], ['camera', 'album'] ] var sizeTypeArray = [ ['compressed'], ['original'], ['compressed', 'original'] ] export default { data() { return { title: 'choose/previewImage', sourceTypeIndex: 2, sourceType: ['拍照', '相册', '拍照或相册'], sizeTypeIndex: 2, sizeType: ['压缩', '原图', '压缩或原图'], countIndex: 8, count: [1, 2, 3, 4, 5, 6, 7, 8, 9], isCrop: false, cropPercent: 80, cropWidth: 100, cropHeight: 100, cropResize: false, qsImage: [], fid: 0, } }, onLoad(options) { //options中包含了url附带的参数 let params = options; if (params["id"]) { this.fid = params["id"]; //getQaItemXj02 this.init(); } }, onUnload() { this.qsImage = []; this.sourceTypeIndex = 2 this.sourceType = ['拍照', '相册', '拍照或相册'] this.sizeTypeIndex = 2 this.sizeType = ['压缩', '原图', '压缩或原图'] this.countIndex = 8 }, methods: { removeImage(index, id) { this.qsImage.splice(index, 1); if (id) { this.$post({ url: "/Base/removeImage", data: { id: id } }).then(res => { }); } }, chooseImage() { if (this.qsImage.length >= 9) { uni.showToast({ position: "bottom", title: "已经有9张图片了,请删除部分图片之后重新选择" }); return; } uni.chooseImage({ sourceType: sourceTypeArray[this.sourceTypeIndex], sizeType: sizeTypeArray[this.sizeTypeIndex], crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } : null, count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex], success: (res) => { let url = res.tempFilePaths[0]; pathToBase64(url) .then(base64 => { // 找到最后一个斜杠的位置 let lastSlashIndex = url.lastIndexOf("/"); // 提取文件名 let fileName = url.substring(lastSlashIndex + 1); let entity = {}; entity.img = base64; entity.Picturename = fileName; entity.fid = this.fid; entity.qsType = 4; entity.base64Date = base64.split(',')[1]; this.qsImage.push(entity); }) .catch(error => { console.error(error) }) }, fail: (err) => { console.log("err: ", JSON.stringify(err)); } }); }, previewImage(index) { // 检查当前图片是否存在 const currentImage = this.qsImage[index]; if (!currentImage || !currentImage.img) { uni.showToast({ title: '图片数据异常', icon: 'none' }); return; } <script> // 显示加载提示 uni.showLoading({ title: '加载中...' }); import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index' // 如果是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); }); var sourceTypeArray = [ ['camera'], ['album'], ['camera', 'album'] ] var sizeTypeArray = [ ['compressed'], ['original'], ['compressed', 'original'] ] export default { data() { return { title: 'choose/previewImage', sourceTypeIndex: 2, sourceType: ['拍照', '相册', '拍照或相册'], sizeTypeIndex: 2, sizeType: ['压缩', '原图', '压缩或原图'], countIndex: 8, count: [1, 2, 3, 4, 5, 6, 7, 8, 9], isCrop: false, cropPercent: 80, cropWidth: 100, cropHeight: 100, cropResize: false, qsImage: [], fid: 0, } }, onLoad(options) { //options中包含了url附带的参数 let params = options; if (params["id"]) { this.fid = params["id"]; //getQaItemXj02 this.init(); } }, onUnload() { this.qsImage = []; this.sourceTypeIndex = 2 this.sourceType = ['拍照', '相册', '拍照或相册'] this.sizeTypeIndex = 2 this.sizeType = ['压缩', '原图', '压缩或原图'] this.countIndex = 8 }, methods: { removeImage(index, id) { this.qsImage.splice(index, 1); if (id) { this.$post({ url: "/Base/removeImage", data: { id: id } }).then(res => { }); } }, chooseImage() { if (this.qsImage.length >= 9) { uni.showToast({ position: "bottom", title: "已经有9张图片了,请删除部分图片之后重新选择" }); return; } uni.chooseImage({ sourceType: sourceTypeArray[this.sourceTypeIndex], sizeType: sizeTypeArray[this.sizeTypeIndex], crop: this.isCrop ? { "quality": this.cropPercent, "width": this.cropWidth, "height": this.cropHeight, "resize": this.cropResize } : null, count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex], success: (res) => { let url = res.tempFilePaths[0]; pathToBase64(url) .then(base64 => { // 找到最后一个斜杠的位置 let lastSlashIndex = url.lastIndexOf("/"); // 提取文件名 let fileName = url.substring(lastSlashIndex + 1); let entity = {}; entity.img = base64; entity.Picturename = fileName; entity.fid = this.fid; entity.qsType = 4; entity.base64Date = base64.split(',')[1]; this.qsImage.push(entity); }) .catch(error => { console.error(error) }) }, fail: (err) => { console.log("err: ", JSON.stringify(err)); } }); }, previewImage(index) { // uni.previewImage({ // current: index, // 设置当前显示图片的链接 // urls: this.qsImage.map(s=>s.img), // 需要预览的图片链接列表 // loop: false, // 是否开启图片轮播,默认为 false // indicator: 'default',// 图片指示器类型,可选值为 "default"、"number"、"pointer",默认为 "default" // }); }, init() { this.$post({ url: "/Base/getByFid", data: { fid: this.fid, qsType: 4 } }).then(res => { let tableData = res.data.tbBillList; this.qsImage = tableData; this.qsImage.forEach(s => { s.img = 'data:image/png;base64,' + s.base64Date; }); }); }, save() { this.$post({ url: "/Base/saveImage", data: { entity: this.qsImage } }).then(res => { this.init(); this.$showMessage("保存成功"); }); } 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({ url: "/Base/getByFid", data: { fid: this.fid, qsType: 4 } }).then(res => { let tableData = res.data.tbBillList; this.qsImage = tableData; this.qsImage.forEach(s => { // 根据文件扩展名判断图片类型,默认为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}`; }); }); }, save() { this.$post({ url: "/Base/saveImage", data: { entity: this.qsImage } }).then(res => { this.init(); this.$showMessage("保存成功"); }); } } } } </script> <style> .click-t { color: darkgray; } .list-pd { margin-top: 25px; } .uni-uploader__input-box { margin: 5px; border: 1px solid #D9D9D9; } .image-remove { transform: rotate(45deg); width: 25px; height: 25px; position: absolute; top: 0; right: 0; border-radius: 13px; background-color: #FF0000; } .uni-common-mt { background-color: #ffffff; /* 红色背景 */ } .plus-button { position: fixed; left: 0; bottom: 0; width: 100%; background-color: #ffffff; /* 背景颜色 */ /* padding: 10px; */ box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* 添加底部阴影效果 */ z-index: 999; /* 确保按钮位于顶层 */ } .uni-flex { max-height: calc(100vh - 240px); /* 屏幕高度减去上传按钮高度 */ overflow-y: auto; /* 当内容超出高度时出现垂直滚动条 */ } .upImg{ background-color: #3498db; color: white; } </style> </script> <style> .click-t { color: darkgray; } .list-pd { margin-top: 25px; } .uni-uploader__input-box { margin: 5px; border: 1px solid #D9D9D9; } .image-remove { transform: rotate(45deg); width: 25px; height: 25px; position: absolute; top: 0; right: 0; border-radius: 13px; background-color: #FF0000; } .uni-common-mt { background-color: #ffffff; /* 红色背景 */ } .plus-button { position: fixed; left: 0; bottom: 0; width: 100%; background-color: #ffffff; /* 背景颜色 */ /* padding: 10px; */ box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* 添加底部阴影效果 */ z-index: 999; /* 确保按钮位于顶层 */ } .uni-flex { max-height: calc(100vh - 240px); /* 屏幕高度减去上传按钮高度 */ overflow-y: auto; /* 当内容超出高度时出现垂直滚动条 */ } .upImg{ background-color: #3498db; color: white; } </style> pages/QC/SJ/Add.vue
@@ -12,7 +12,7 @@ <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> @@ -40,7 +40,7 @@ </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> @@ -48,15 +48,9 @@ <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> @@ -137,6 +131,12 @@ <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"> @@ -175,6 +175,7 @@ comments: "", statusUser: "", SJ_MJ: '首检', fsubmit:"", }, DAA020List: [], @@ -282,7 +283,7 @@ } }).then(res => { if (res.data.tbBillList) { this.$showMessage("巡检生成成功"); this.$showMessage("首检生成成功"); this.init(); } }); @@ -473,10 +474,10 @@ }, 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("请选择计划编号"); @@ -528,6 +529,43 @@ 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() { //每次进入页面都会执行的方法 @@ -785,6 +823,15 @@ background-color: #c0392b; } .action-btn.success { background-color: #2ecc71; color: white; } .action-btn.success:hover { background-color: #27ae60; } /* 弹出框样式 */ .overlay { position: fixed; pages/QC/XJ/Add.vue
@@ -40,7 +40,7 @@ <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> @@ -114,6 +114,8 @@ <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"> @@ -260,13 +262,10 @@ }, getItem() { if (this.isSubmit) { this.$showMessage("此物料无启用的检验项目,请维护!"); return; } if (!this.formData.billNo) { this.$showMessage("请选择计划编号"); this.$showMessage("请选择工单单号"); return; } @@ -480,6 +479,43 @@ 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() { @@ -725,6 +761,11 @@ color: white; } .action-btn.success { background-color: #2ecc71; color: white; } /* 弹出框样式 */ .overlay { position: fixed;