| | |
| | | <table> |
| | | <thead> |
| | | <tr> |
| | | <th width="20%" style="text-align: center;">检验项目</th> |
| | | <th width="8%" style="text-align: center;">序号</th> |
| | | <th width="17%" style="text-align: center;">检验项目</th> |
| | | <th width="50%" style="text-align: center;">检验描述</th> |
| | | <th width="15%" style="text-align: center;">记录(点击)</th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr v-for="(item, index) in tableData" :key="index"> |
| | | <td style="text-align: center;">{{ item.forder || (index + 1) }}</td> |
| | | <td>{{ item.projName }}</td> |
| | | <td> |
| | | <view v-if="item.result=='合格'" class="watermark approved"> |
| | |
| | | <view v-if="item.result==null || item.result=='未完成'" class="watermark pending"> |
| | | {{ getStatusText(item.result) }} |
| | | </view> |
| | | <view class="description-text">{{ item.projName }}</view> |
| | | <view class="description-text">{{ getInspectionDescription(item) }}</view> |
| | | </td> |
| | | <td> |
| | | <button v-if="item.isCheck >= item.levelNum" class="record-btn" @click="toDetail(item)">查看</button> |
| | |
| | | |
| | | <!-- 已有单据的操作按钮 --> |
| | | <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="toImage">上传/查看图片</button> |
| | | <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="fetchDrawingNumber(formData.itemNo)"> |
| | | 调取PLM图纸 |
| | | </button> |
| | | <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="getBom"> |
| | | Bom用料清单 |
| | | </button> |
| | | <button class="action-btn secondary" v-if="!isUpdate && !isShowTable" @click="viewAttachmentInfo">查看附件信息</button> |
| | | |
| | | <button class="action-btn danger" v-if="!isUpdate && !formData.fcheckResu && !isShowTable && formData.fsubmit !== 1" @click="removeXJ">删除单据</button> |
| | | <button class="action-btn danger" v-if="!isUpdate && !formData.fcheckResu && !isShowTable && formData.fsubmit !== 1" @click="showDeleteConfirmDialog">删除单据</button> |
| | | <button class="action-btn warning" v-if="!isUpdate && !isShowTable && formData.fsubmit !== 1" @click="saveRemarks">添加不合格描述</button> |
| | | |
| | | <!-- 检验项目管理按钮 --> |
| | |
| | | </div> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <view class="barcode"> |
| | | <u-modal :show="itemShow" title="物料明细" @confirm="drawingConfirm" @cancel="itemCancel" |
| | | showCancelButton :z-index="1000"> |
| | | <uni-table border stripe emptyText="暂无更多数据" style="margin-left: 5px;margin-right: 5px;height: 400px;max-height: 60vh;overflow-y: auto;"> |
| | | <uni-tr> |
| | | <uni-th align="center">料号</uni-th> |
| | | <uni-th align="center" width="90">名称</uni-th> |
| | | <uni-th align="center" width="90">规格型号</uni-th> |
| | | <uni-th align="center" width="150">调取PLM图纸</uni-th> |
| | | </uni-tr> |
| | | <uni-tr v-for="(item,index) in (drawing || [])" style="height: 100px;"> |
| | | <uni-td align="center">{{item.itemNo}}</uni-td> |
| | | <uni-td align="center" > |
| | | <div >{{item.itemName}}</div> |
| | | </uni-td> |
| | | <uni-td align="center" > |
| | | <div>{{item.itemModel}}</div> |
| | | </uni-td> |
| | | <uni-td align="center" class="click-wd"> |
| | | <div @click="fetchDrawingNumber(item.itemNo)">调取图纸</div> |
| | | </uni-td> |
| | | </uni-tr> |
| | | </uni-table> |
| | | </u-modal> |
| | | </view> |
| | | |
| | | <view class="barcode"> |
| | | <u-modal :show="drawingShow" title="图纸明细" @confirm="drawingConfirm" @cancel="drawingCancel" |
| | | showCancelButton :z-index="1000"> |
| | | <uni-table border stripe emptyText="暂无更多数据" style="margin-left: 5px;margin-right: 5px;height: 400px;max-height: 60vh;overflow-y: auto;"> |
| | | <uni-tr> |
| | | <uni-th align="center">相关文档</uni-th> |
| | | <uni-th align="center" width="90">有无关联PDF文件</uni-th> |
| | | <uni-th align="center" width="90">能否打开文件</uni-th> |
| | | <uni-th align="center" width="150">操作(点击)</uni-th> |
| | | </uni-tr> |
| | | <uni-tr v-for="(item,index) in (drawing || [])" style="height: 100px;"> |
| | | <uni-td align="center">{{item.fName}}</uni-td> |
| | | <uni-td align="center" style="font-size:25px;"> |
| | | <div v-if="item.fRelevantObject==' '" style="color: #E47470;">×</div> |
| | | <div style="color: #90BA87;" v-else>√</div> |
| | | </uni-td> |
| | | <uni-td align="center" style="font-size:25px;"> |
| | | <div v-if="item.isSupported || item.fRelevantObject!=' '" style="color: #90BA87;">√</div> |
| | | <div style="color: #E47470;" v-else>×</div> |
| | | </uni-td> |
| | | <uni-td align="center" class="click-wd"> |
| | | <div @click="openDrawings(item)">打开文档</div> |
| | | </uni-td> |
| | | </uni-tr> |
| | | </uni-table> |
| | | </u-modal> |
| | | </view> |
| | | |
| | | <!-- 文件预览弹窗 --> |
| | | <view v-if="showFilePreviewPopup" class="overlay"> |
| | |
| | | <div class="file-preview-actions"> |
| | | <button v-if="previewType !== 'text'" class="file-preview-btn download-btn" @click="downloadPreviewFile">📥 下载文件</button> |
| | | <button class="file-preview-btn close-btn" @click="closeFilePreview">关闭</button> |
| | | </div> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 删除确认弹窗 --> |
| | | <view v-if="showDeleteConfirm" class="overlay"> |
| | | <view class="popup delete-confirm-popup"> |
| | | <h3 class="delete-confirm-title">⚠️ 确认删除</h3> |
| | | <div class="delete-confirm-divider"></div> |
| | | <div class="delete-confirm-content"> |
| | | <view class="delete-warning-icon">🗑️</view> |
| | | <view class="delete-warning-text">您确定要删除此检验单吗?</view> |
| | | <view class="delete-warning-detail">删除后将无法恢复,请谨慎操作!</view> |
| | | <view class="delete-countdown"> |
| | | <view class="countdown-text">确认按钮将在 <text class="countdown-number">{{ deleteCountdown }}</text> 秒后可用</view> |
| | | <view class="countdown-progress"> |
| | | <view class="countdown-bar" :style="{ width: countdownProgress + '%' }"></view> |
| | | </view> |
| | | </view> |
| | | </div> |
| | | <div class="delete-confirm-actions"> |
| | | <button class="delete-confirm-btn cancel-btn" @click="cancelDelete">取消</button> |
| | | <button class="delete-confirm-btn confirm-btn" |
| | | :disabled="deleteCountdown > 0" |
| | | :class="{ 'disabled': deleteCountdown > 0 }" |
| | | @click="confirmDelete">确认删除</button> |
| | | </div> |
| | | </view> |
| | | </view> |
| | |
| | | lineNo: "", |
| | | |
| | | tableData: [], |
| | | drawing: [], |
| | | |
| | | isSubmit: true, |
| | | isSubmit: true, |
| | | |
| | | isUpdate: true, |
| | | isUpdate: true, |
| | | |
| | | isShowTable: false, |
| | | |
| | | drawingShow: false, |
| | | itemShow: false, |
| | | |
| | | remarks: "", |
| | | remarksPopup: false, |
| | |
| | | previewTitle: '', |
| | | previewContent: '', |
| | | previewType: '', |
| | | previewFileUrl: '' |
| | | previewFileUrl: '', |
| | | |
| | | // 删除确认相关数据 |
| | | showDeleteConfirm: false, |
| | | deleteCountdown: 5, |
| | | countdownProgress: 0, |
| | | deleteTimer: null |
| | | |
| | | }; |
| | | }, |
| | |
| | | } else { |
| | | return statusMap['rejected'] || '不合格'; |
| | | } |
| | | }, |
| | | |
| | | getInspectionDescription(item) { |
| | | // 取ITEM_MOD字段的值 |
| | | if (item.itemMod && item.itemMod.trim() !== '') { |
| | | return item.itemMod; |
| | | } else { |
| | | return '检验项目详情'; |
| | | } |
| | | }, |
| | | |
| | | // 显示删除确认弹窗 |
| | | showDeleteConfirmDialog() { |
| | | this.showDeleteConfirm = true; |
| | | this.deleteCountdown = 5; |
| | | this.countdownProgress = 0; |
| | | this.startDeleteCountdown(); |
| | | }, |
| | | |
| | | // 开始倒计时 |
| | | startDeleteCountdown() { |
| | | this.deleteTimer = setInterval(() => { |
| | | this.deleteCountdown--; |
| | | this.countdownProgress = ((5 - this.deleteCountdown) / 5) * 100; |
| | | |
| | | if (this.deleteCountdown <= 0) { |
| | | clearInterval(this.deleteTimer); |
| | | this.deleteTimer = null; |
| | | } |
| | | }, 1000); |
| | | }, |
| | | |
| | | // 取消删除 |
| | | cancelDelete() { |
| | | this.showDeleteConfirm = false; |
| | | if (this.deleteTimer) { |
| | | clearInterval(this.deleteTimer); |
| | | this.deleteTimer = null; |
| | | } |
| | | this.deleteCountdown = 5; |
| | | this.countdownProgress = 0; |
| | | }, |
| | | |
| | | // 确认删除 |
| | | confirmDelete() { |
| | | if (this.deleteCountdown > 0) { |
| | | return; |
| | | } |
| | | |
| | | this.showDeleteConfirm = false; |
| | | if (this.deleteTimer) { |
| | | clearInterval(this.deleteTimer); |
| | | this.deleteTimer = null; |
| | | } |
| | | |
| | | this.removeXJ(); |
| | | }, |
| | | |
| | | removeXJ() { |
| | |
| | | pid: this.formData.id |
| | | } |
| | | }).then(res1 => { |
| | | let tableData = res1.data.tbBillList |
| | | //当已检验个数都不为空时按照检测结构排序 |
| | | let tableData = res1.data.tbBillList; |
| | | // 按FORDER序号排序 |
| | | tableData.sort((a, b) => { |
| | | if (a.result === '未完成' && b.result === '合格') { |
| | | return -1; |
| | | } else if (a.result === '合格' && b.result === '未完成') { |
| | | return 1; |
| | | } else { |
| | | return 0; |
| | | } |
| | | return (a.forder || 0) - (b.forder || 0); |
| | | }); |
| | | this.tableData = tableData; |
| | | if (this.tableData.length === 0) { |
| | |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | drawingConfirm() { |
| | | this.drawingShow = false |
| | | this.imageShow = false |
| | | this.productionShow = false |
| | | this.itemShow=false |
| | | }, |
| | | drawingCancel() { |
| | | this.drawingShow = false |
| | | this.imageShow = false |
| | | this.productionShow = false |
| | | // const item = '83040700101' |
| | | const item = this.formData.billNo; |
| | | console.log(this.formData.billNo ); |
| | | console.log('daa001:', item); |
| | | console.log('ItemNo:', this.formData.itemNo); |
| | | |
| | | const url = this.$store.state.serverInfo.serverAPI + "/LLJ/getWomdab"; |
| | | // 或者如果路径不同,请使用正确的端点 |
| | | // const url = "http://192.168.0.100:10054/api/getWomdab" |
| | | |
| | | let _this = this; |
| | | |
| | | uni.request({ |
| | | url: url, |
| | | method: 'POST', |
| | | header: { |
| | | 'Content-Type': 'application/json' |
| | | }, |
| | | data: { |
| | | daa001: item, // 根据DTO属性名传递 |
| | | ItemNo: this.formData.itemNo // 注意大小写匹配 |
| | | }, |
| | | success: (response) => { |
| | | console.log(response); |
| | | console.log("-------------------------------------"); |
| | | // 根据后端返回的数据结构进行调整 |
| | | if (response.data.status === 1) { |
| | | // 状态为1表示没有数据 |
| | | _this.drawing = []; |
| | | |
| | | } else if (response.data.status === 0) { |
| | | // 状态为0表示成功 |
| | | if (response.data.data && response.data.data.tbBillList) { |
| | | _this.drawing = response.data.data.tbBillList; |
| | | |
| | | // 遍历数据,判断文件后缀并添加字段 |
| | | _this.drawing.forEach((file) => { |
| | | // 获取文件名的后缀 |
| | | const fileExtension = file.fName ? file.fName.split('.').pop().toLowerCase() : ''; |
| | | |
| | | // 定义支持的文件类型 |
| | | const supportedExtensions = ['jpg', 'pdf', 'xlsx', 'doc', 'docx', 'xls']; |
| | | |
| | | // 判断是否支持该文件类型 |
| | | file.isSupported = supportedExtensions.includes(fileExtension); |
| | | }); |
| | | } else { |
| | | _this.drawing = []; |
| | | } |
| | | } else { |
| | | // 其他状态码处理 |
| | | _this.drawing = []; |
| | | uni.showToast({ |
| | | title: response.data.message || '请求失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }, |
| | | fail: (error) => { |
| | | uni.showToast({ |
| | | title: '请求图纸链接失败', |
| | | icon: 'none' |
| | | }); |
| | | console.error('请求失败:', error); |
| | | } |
| | | }); |
| | | }, |
| | | itemCancel() { |
| | | this.itemShow=false |
| | | }, |
| | | |
| | | fetchDrawingNumber(itemNo) { |
| | | // const item = '83040700101' |
| | | const item = itemNo; |
| | | console.log(itemNo) |
| | | // console.log(item) |
| | | const url = this.$store.state.serverInfo.serverAPI +"/PLM/RetrieveDrawings?ItemNo=" + item |
| | | |
| | | // const item = '5.06.04.4002'; |
| | | // const url = "http://192.168.0.100:10054/api/PLM/RetrieveDrawings?ItemNo=" + item |
| | | |
| | | let _this = this; |
| | | |
| | | uni.request({ |
| | | url: url, |
| | | method: 'POST', |
| | | success: (response) => { |
| | | console.log(response) |
| | | if (response.data.data == '返回结果为空') { |
| | | _this.drawing = [] |
| | | } else { |
| | | _this.drawing = response.data.data |
| | | // 遍历数据,判断文件后缀并添加字段 |
| | | _this.drawing.forEach((file) => { |
| | | // 获取文件名的后缀 |
| | | const fileExtension = file.fName.split('.').pop() |
| | | .toLowerCase(); |
| | | |
| | | // 定义支持的文件类型 |
| | | const supportedExtensions = ['jpg', 'pdf', 'xlsx', 'doc', |
| | | 'docx', |
| | | 'xls' |
| | | ]; |
| | | |
| | | // 判断是否支持该文件类型 |
| | | file.isSupported = supportedExtensions.includes(fileExtension); |
| | | }); |
| | | } |
| | | }, |
| | | fail: (error) => { |
| | | uni.showToast({ |
| | | title: '请求图纸链接失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | this.drawingShow = true |
| | | }, |
| | | |
| | | getBom(){ |
| | | // const item = '83040700101' |
| | | const item = this.formData.billNo; |
| | | console.log(this.formData.billNo ); |
| | | console.log('daa001:', item); |
| | | console.log('ItemNo:', this.formData.itemNo); |
| | | |
| | | const url = this.$store.state.serverInfo.serverAPI + "/LLJ/getWomdab"; |
| | | // 或者如果路径不同,请使用正确的端点 |
| | | // const url = "http://192.168.0.100:10054/api/getWomdab" |
| | | |
| | | let _this = this; |
| | | |
| | | uni.request({ |
| | | url: url, |
| | | method: 'POST', |
| | | header: { |
| | | 'Content-Type': 'application/json' |
| | | }, |
| | | data: { |
| | | daa001: item, // 根据DTO属性名传递 |
| | | ItemNo: this.formData.itemNo // 注意大小写匹配 |
| | | }, |
| | | success: (response) => { |
| | | console.log(response); |
| | | console.log("-------------------------------------"); |
| | | // 根据后端返回的数据结构进行调整 |
| | | if (response.data.status === 1) { |
| | | // 状态为1表示没有数据 |
| | | _this.drawing = []; |
| | | uni.showToast({ |
| | | title: response.data.message || '该检验单未上传附件信息', |
| | | icon: 'none' |
| | | }); |
| | | } else if (response.data.status === 0) { |
| | | // 状态为0表示成功 |
| | | if (response.data.data && response.data.data.tbBillList) { |
| | | _this.drawing = response.data.data.tbBillList; |
| | | |
| | | // 遍历数据,判断文件后缀并添加字段 |
| | | _this.drawing.forEach((file) => { |
| | | // 获取文件名的后缀 |
| | | const fileExtension = file.fName ? file.fName.split('.').pop().toLowerCase() : ''; |
| | | |
| | | // 定义支持的文件类型 |
| | | const supportedExtensions = ['jpg', 'pdf', 'xlsx', 'doc', 'docx', 'xls']; |
| | | |
| | | // 判断是否支持该文件类型 |
| | | file.isSupported = supportedExtensions.includes(fileExtension); |
| | | }); |
| | | } else { |
| | | _this.drawing = []; |
| | | } |
| | | } else { |
| | | // 其他状态码处理 |
| | | _this.drawing = []; |
| | | uni.showToast({ |
| | | title: response.data.message || '请求失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }, |
| | | fail: (error) => { |
| | | uni.showToast({ |
| | | title: '请求图纸链接失败', |
| | | icon: 'none' |
| | | }); |
| | | console.error('请求失败:', error); |
| | | } |
| | | }); |
| | | this.itemShow = true |
| | | }, |
| | | |
| | | //图纸相关文档 |
| | | openDrawings(item) { |
| | | console.log("jkjoi", item) |
| | | if (item.fRelevantObject.length > 2) { |
| | | // 生成请求URL(简化编码逻辑) |
| | | const encodedName = encodeURIComponent(item.fName); |
| | | const url = this.$store.state.serverInfo.serverAPI+`/PLM/OpenDrawingsGet?fileId=${item.fRelevantObject}&fName=${encodedName}`; |
| | | console.log('请求URL:', url); |
| | | |
| | | const now = new Date(); |
| | | const timestamp = [ |
| | | now.getFullYear(), |
| | | String(now.getMonth() + 1).padStart(2, '0'), |
| | | String(now.getDate()).padStart(2, '0'), |
| | | String(now.getHours()).padStart(2, '0'), |
| | | String(now.getMinutes()).padStart(2, '0'), |
| | | String(now.getSeconds()).padStart(2, '0') |
| | | ].join(''); |
| | | |
| | | // 生成新文件名(基础名_时间戳.后缀) |
| | | this.fileName = `${item.fName}_${timestamp}.pdf`; |
| | | console.log('新文件名:', this.fileName); |
| | | |
| | | uni.downloadFile({ |
| | | url: url, |
| | | success: (res) => { |
| | | console.log(res); |
| | | let fileName = this.fileName; |
| | | let fileExt = fileName.split('.').pop(); |
| | | // let newFilePath = "_doc/uniapp_temp_1742877118745/download" + "/" + fileName; |
| | | // console.log('newFilePath', newFilePath) |
| | | if (fileExt === 'xls' || fileExt === 'xlsx' || fileExt === 'pdf'|| fileExt === 'jpg'|| fileExt === 'png') { |
| | | plus.io.resolveLocalFileSystemURL(res.tempFilePath, (entry) => { |
| | | // 获取文件所在的目录 |
| | | entry.getParent((parentEntry) => { |
| | | let newFileName = this.fileName; // 新的文件名 |
| | | |
| | | // 移动并重命名文件 |
| | | entry.moveTo( |
| | | parentEntry, |
| | | newFileName, |
| | | (newEntry) => { |
| | | console.log('重命名成功:', newEntry.fullPath); |
| | | |
| | | // 打开 Excel 文件 |
| | | plus.runtime.openFile(newEntry.fullPath, {}, (e) => { |
| | | console.error('无法打开 Excel 文件:', e); |
| | | }); |
| | | |
| | | // let pages = getCurrentPages(); |
| | | // let beforePage = pages[pages.length - 2]; |
| | | // uni.navigateBack({ |
| | | // delta: 1, //返回的页面数,如果为1表示返回上一页 |
| | | // success: (event) => { |
| | | // beforePage.$vm.reload() |
| | | // } |
| | | // }); |
| | | |
| | | }, |
| | | (err) => { |
| | | console.error('重命名失败:', err); |
| | | } |
| | | ); |
| | | }, (err) => { |
| | | console.error('获取父目录失败:', err); |
| | | }); |
| | | }, (err) => { |
| | | console.error('获取文件失败:', err); |
| | | }); |
| | | } else { |
| | | console.error('文件格式不匹配:', fileExt); |
| | | uni.showToast({ |
| | | title: '文件格式不支持', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | } |
| | | }) |
| | | uni.request({ |
| | | url: url, |
| | | method: 'POST', |
| | | responseType: 'arraybuffer', |
| | | success: (response) => { |
| | | console.log(response.data) |
| | | if (!response) { |
| | | uni.showToast({ |
| | | title: "协议预览失败", |
| | | duration: 2000 |
| | | }); |
| | | } |
| | | |
| | | }, |
| | | fail: (error) => { |
| | | console.log(error) |
| | | uni.showToast({ |
| | | title: '请求预览链接失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | uni.showToast({ |
| | | title: '请求预览链接失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | previewOfficeFile(url, fileName) { |
| | | this.previewTitle = fileName; |
| | |
| | | <style scoped> |
| | | /* 基础样式 */ |
| | | .container { |
| | | padding: 10px; |
| | | padding: 20px; |
| | | padding-bottom: 120px; /* 为固定按钮留出更多空间,避免遮盖检验项目 */ |
| | | background-color: #f5f7fa; |
| | | min-height: 100vh; |
| | | } |
| | |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | margin: 25px 0; |
| | | } |
| | | |
| | | |
| | | .inspection-table table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | } |
| | | |
| | | |
| | | .inspection-table th { |
| | | background-color: #f8f9fa; |
| | | color: #34495e; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | color: white; |
| | | padding: 12px 15px; |
| | | font-weight: bold; |
| | | text-align: left; |
| | | border: 1px solid #ddd; |
| | | text-align: center; |
| | | border: none; |
| | | } |
| | | |
| | | |
| | | .inspection-table td { |
| | | padding: 12px 15px; |
| | | text-align: left; |
| | | border: 1px solid #ddd; |
| | | border: none; |
| | | vertical-align: middle; |
| | | } |
| | | |
| | | |
| | | .inspection-table tr:nth-child(even) { |
| | | background-color: #f9f9f9; |
| | | } |
| | | |
| | | |
| | | .inspection-table tr:hover { |
| | | background-color: #f1f5f9; |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* 水印样式 */ |
| | | .watermark { |
| | | position: absolute; |
| | | font-size: 40px; |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | opacity: 1; |
| | | opacity: 0.8; |
| | | z-index: 1; |
| | | pointer-events: none; |
| | | transform: rotate(-15deg); |
| | |
| | | left: 50%; |
| | | transform: translate(-50%, -50%) rotate(-15deg); |
| | | } |
| | | |
| | | |
| | | .watermark.approved { |
| | | color: #2ecc71; |
| | | } |
| | | |
| | | |
| | | .watermark.rejected { |
| | | color: #e74c3c; |
| | | } |
| | | |
| | | |
| | | .watermark.pending { |
| | | color: #f39c12; |
| | | } |
| | |
| | | } |
| | | |
| | | /* 调整表格单元格 */ |
| | | .inspection-table td:nth-child(2) { |
| | | .inspection-table td:nth-child(3) { |
| | | position: relative; |
| | | overflow: hidden; |
| | | padding: 0; |
| | | min-height: 80px; |
| | | } |
| | | |
| | | .record-btn { |
| | |
| | | |
| | | /* 操作按钮 */ |
| | | .action-buttons { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: white; |
| | | border-top: 1px solid #e9ecef; |
| | | padding: 12px; |
| | | box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); |
| | | z-index: 1000; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | margin-bottom: 20px; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | |
| | | .action-btn { |
| | | padding: 12px 20px; |
| | | background-color: #ecf0f1; |
| | | color: #34495e; |
| | | padding: 12px 15px; |
| | | border: none; |
| | | border-radius: 6px; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | cursor: pointer; |
| | | transition: all 0.2s; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | transition: all 0.3s ease; |
| | | text-align: center; |
| | | min-height: 44px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | white-space: nowrap; |
| | | flex-shrink: 0; |
| | | min-width: 80px; |
| | | max-width: 120px; |
| | | flex: 1; |
| | | } |
| | | |
| | | |
| | | .action-btn:hover { |
| | | background-color: #d5dbdb; |
| | | transform: translateY(-1px); |
| | | } |
| | | |
| | | .action-btn.primary { |
| | | background-color: #3498db; |
| | | color: white; |
| | | color: #fff; |
| | | } |
| | | |
| | | |
| | | .action-btn.primary:hover { |
| | | background-color: #2980b9; |
| | | } |
| | | |
| | | .action-btn.secondary { |
| | | background-color: #95a5a6; |
| | | color: white; |
| | | background-color: #ecf0f1; |
| | | color: #34495e; |
| | | } |
| | | |
| | | |
| | | .action-btn.secondary:hover { |
| | | background-color: #d5dbdb; |
| | | } |
| | | |
| | | .action-btn.danger { |
| | | background-color: #e74c3c; |
| | | color: white; |
| | | color: #fff; |
| | | } |
| | | |
| | | |
| | | .action-btn.danger:hover { |
| | | background-color: #c0392b; |
| | | } |
| | | |
| | | .action-btn.warning { |
| | | background-color: #f39c12; |
| | | color: white; |
| | | color: #fff; |
| | | } |
| | | |
| | | |
| | | .action-btn.warning:hover { |
| | | background-color: #e67e22; |
| | | } |
| | | |
| | | .action-btn.success { |
| | | background-color: #2ecc71; |
| | | color: white; |
| | | color: #fff; |
| | | } |
| | | |
| | | |
| | | .action-btn.success:hover { |
| | | background-color: #27ae60; |
| | | } |
| | | |
| | | .action-btn.info { |
| | | background-color: #17a2b8; |
| | | color: white; |
| | | color: #fff; |
| | | } |
| | | |
| | | .action-btn.info:hover { |
| | | background-color: #138496; |
| | | } |
| | | |
| | | .action-btn.small { |
| | | padding: 6px 12px; |
| | | padding: 10px 12px; |
| | | font-size: 12px; |
| | | min-height: 44px; |
| | | white-space: nowrap; |
| | | flex-shrink: 0; |
| | | min-width: 80px; |
| | | max-width: 120px; |
| | | } |
| | | |
| | | /* 弹出框样式 */ |
| | |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .container { |
| | | padding-bottom: 120px; /* 为固定按钮留出空间,避免遮盖检验项目 */ |
| | | } |
| | | |
| | | .info-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .action-buttons { |
| | | flex-direction: column; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 8px; |
| | | gap: 6px; |
| | | } |
| | | |
| | | .action-btn { |
| | | min-width: 70px; |
| | | max-width: 100px; |
| | | padding: 8px 10px; |
| | | font-size: 11px; |
| | | min-height: 40px; |
| | | flex: 1; |
| | | } |
| | | |
| | | .action-btn.small { |
| | | min-width: 70px; |
| | | max-width: 100px; |
| | | padding: 8px 10px; |
| | | font-size: 11px; |
| | | min-height: 40px; |
| | | } |
| | | |
| | | /* 附件弹窗响应式 */ |
| | |
| | | .attachment-icon { |
| | | font-size: 20px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 480px) { |
| | | |
| | | .attachment-popup-content { |
| | | padding: 16px; |
| | | } |
| | |
| | | font-size: 28px; |
| | | } |
| | | } |
| | | |
| | | /* 删除确认弹窗样式 */ |
| | | .delete-confirm-popup { |
| | | width: 90vw; |
| | | max-width: 400px; |
| | | max-height: 70vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .delete-confirm-title { |
| | | font-size: 20px; |
| | | font-weight: 700; |
| | | color: #e74c3c; |
| | | margin-bottom: 8px; |
| | | text-align: center; |
| | | letter-spacing: 1px; |
| | | } |
| | | |
| | | .delete-confirm-divider { |
| | | height: 2px; |
| | | background: linear-gradient(90deg, #e74c3c 0%, #c0392b 100%); |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .delete-confirm-content { |
| | | text-align: center; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .delete-warning-icon { |
| | | font-size: 48px; |
| | | margin-bottom: 16px; |
| | | animation: shake 0.5s ease-in-out infinite alternate; |
| | | } |
| | | |
| | | @keyframes shake { |
| | | 0% { transform: translateX(-2px); } |
| | | 100% { transform: translateX(2px); } |
| | | } |
| | | |
| | | .delete-warning-text { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .delete-warning-detail { |
| | | font-size: 14px; |
| | | color: #7f8c8d; |
| | | margin-bottom: 20px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .delete-countdown { |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | margin: 16px 0; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | |
| | | .countdown-text { |
| | | font-size: 14px; |
| | | color: #495057; |
| | | margin-bottom: 8px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .countdown-number { |
| | | font-weight: 700; |
| | | color: #e74c3c; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .countdown-progress { |
| | | width: 100%; |
| | | height: 6px; |
| | | background: #e9ecef; |
| | | border-radius: 3px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .countdown-bar { |
| | | height: 100%; |
| | | background: linear-gradient(90deg, #e74c3c, #c0392b); |
| | | border-radius: 3px; |
| | | transition: width 1s ease; |
| | | } |
| | | |
| | | .delete-confirm-actions { |
| | | display: flex; |
| | | gap: 12px; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .delete-confirm-btn { |
| | | padding: 12px 24px; |
| | | border: none; |
| | | border-radius: 8px; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 120px; |
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .delete-confirm-btn.cancel-btn { |
| | | background: linear-gradient(135deg, #95a5a6, #7f8c8d); |
| | | color: white; |
| | | } |
| | | |
| | | .delete-confirm-btn.cancel-btn:hover { |
| | | background: linear-gradient(135deg, #7f8c8d, #6c7b7d); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .delete-confirm-btn.confirm-btn { |
| | | background: linear-gradient(135deg, #e74c3c, #c0392b); |
| | | color: white; |
| | | } |
| | | |
| | | .delete-confirm-btn.confirm-btn:hover:not(.disabled) { |
| | | background: linear-gradient(135deg, #c0392b, #a93226); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .delete-confirm-btn.disabled { |
| | | background: #bdc3c7; |
| | | color: #7f8c8d; |
| | | cursor: not-allowed; |
| | | transform: none; |
| | | box-shadow: none; |
| | | } |
| | | </style> |