| | |
| | | <view class="info-label">备注:</view> |
| | | <input type="text" id="lotNo1" v-model="formData.lotNo1" |
| | | placeholder="请输入备注信息" |
| | | style="color: red; font-weight: bold;"/> |
| | | style="color: red; font-weight: bold; background-color: #fff !important; -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; pointer-events: auto !important; opacity: 1 !important; z-index: 1 !important;"/> |
| | | </view> |
| | | <view class="info-block" style="margin-top: 10px;"> |
| | | <view class="info-label">破坏实验数量:</view> |
| | |
| | | <!-- 表单上方操作按钮区 --> |
| | | <view class="top-action-buttons"> |
| | | <button class="action-btn" @click="getInspectionItems" v-if="this.current">获取检验项目</button> |
| | | <button class="action-btn" @click="openGlobalBlockHoleDialog" 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> |
| | |
| | | <form> |
| | | <view class="form-group"> |
| | | <label class="form-label">不合格描述:</label> |
| | | <input class="form-input" type="text" v-model="remarks" /> |
| | | <input class="info-input" type="text" v-model="remarks" placeholder="请输入不合格描述" /> |
| | | </view> |
| | | |
| | | </form> |
| | |
| | | </view> |
| | | |
| | | <view v-if="destructionPopup" class="overlay"> |
| | | <view class="popup"> |
| | | <h3>破坏实验数量</h3> |
| | | <form> |
| | | <view class="form-group"> |
| | | <label class="form-label">破坏实验数量:</label> |
| | | <input class="form-input" type="text" v-model="PHSY" placeholder="留空表示清除数量" /> |
| | | <view class="popup destruction-popup"> |
| | | <h3>破坏实验</h3> |
| | | |
| | | <!-- 第一步:扫描二维码(无记录时显示) --> |
| | | <view v-if="!hasExistingRecord && !scannedMaterialInfo" class="scan-step"> |
| | | <view class="scan-icon">📷</view> |
| | | <view class="scan-title">扫描物料二维码</view> |
| | | <view class="scan-description">请扫描要用于破坏实验的物料条码</view> |
| | | <view class="scan-actions"> |
| | | <button class="scan-btn" @click="scanQRCode">开始扫描</button> |
| | | <button class="destruction-btn cancel-btn" @click="closeDestructionPopup">返回</button> |
| | | </view> |
| | | </form> |
| | | <div v-if="!isInteger" class="error-message">请输入整数值或留空</div> |
| | | <button class="updateBut" @click="editDestruction">修改</button> |
| | | <button @click="clearDestruction">清除</button> |
| | | <button @click="destructionPopup = !destructionPopup">取消</button> |
| | | </view> |
| | | |
| | | <!-- 第二步:显示扫描结果和输入数量(无记录时扫描后显示) --> |
| | | <view v-if="!hasExistingRecord && scannedMaterialInfo" class="result-step"> |
| | | <view class="scan-success-icon">✅</view> |
| | | <view class="scan-success-title">扫描成功</view> |
| | | |
| | | <!-- 显示扫描到的物料信息 --> |
| | | <view class="material-info-display"> |
| | | <view class="material-detail"> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">扫描条码:</span> |
| | | <span class="detail-value barcode-value">{{ scannedMaterialInfo.itemBarcode || scannedMaterialInfo.itemNo }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">物料编码:</span> |
| | | <span class="detail-value">{{ scannedMaterialInfo.itemNo }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">物料名称:</span> |
| | | <span class="detail-value">{{ scannedMaterialInfo.itemName }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">规格型号:</span> |
| | | <span class="detail-value">{{ scannedMaterialInfo.itemModel }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">到货单号:</span> |
| | | <span class="detail-value">{{ scannedMaterialInfo.billNo }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">可用数量:</span> |
| | | <span class="detail-value">{{ scannedMaterialInfo.oldQty }}</span> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 重新设计的输入区域 --> |
| | | <view class="input-section"> |
| | | <view class="input-title">破坏实验数量</view> |
| | | <view class="input-container"> |
| | | <view class="input-box" @click="focusInput"> |
| | | <text v-if="destructionQuantity" class="input-value">{{ destructionQuantity }}</text> |
| | | <text v-else class="input-placeholder">点击输入数量</text> |
| | | </view> |
| | | </view> |
| | | <view v-if="!isInteger && destructionQuantity" class="error-tip">请输入有效的正整数</view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="destruction-actions"> |
| | | <!-- 无记录时显示:确认、修改、删除、返回 --> |
| | | <template v-if="!hasExistingRecord"> |
| | | <button class="destruction-btn confirm-btn" @click="confirmDestruction" :disabled="!isInteger || !destructionQuantity">确认</button> |
| | | <button class="destruction-btn modify-btn" @click="modifyDestruction">修改</button> |
| | | <button class="destruction-btn delete-btn" @click="deleteDestruction">删除</button> |
| | | <button class="destruction-btn cancel-btn" @click="resetDestruction">返回</button> |
| | | </template> |
| | | <!-- 有记录时显示:修改、删除、返回 --> |
| | | <template v-else> |
| | | <button class="destruction-btn modify-btn" @click="modifyDestruction">修改</button> |
| | | <button class="destruction-btn delete-btn" @click="deleteDestruction">删除</button> |
| | | <button class="destruction-btn cancel-btn" @click="resetDestruction">返回</button> |
| | | </template> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 第三步:显示已有记录信息(有记录时显示,复用扫描结果界面) --> |
| | | <view v-if="hasExistingRecord" class="result-step"> |
| | | <view class="scan-success-icon">✅</view> |
| | | <view class="scan-success-title">扫描成功</view> |
| | | |
| | | <!-- 显示扫描到的物料信息 --> |
| | | <view class="material-info-display"> |
| | | <view class="material-detail"> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">扫描条码:</span> |
| | | <span class="detail-value barcode-value">{{ (scannedMaterialInfo && scannedMaterialInfo.itemBarcode) || (scannedMaterialInfo && scannedMaterialInfo.itemNo) || '' }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">物料编码:</span> |
| | | <span class="detail-value">{{ (scannedMaterialInfo && scannedMaterialInfo.itemNo) || '' }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">物料名称:</span> |
| | | <span class="detail-value">{{ (scannedMaterialInfo && scannedMaterialInfo.itemName) || '' }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">规格型号:</span> |
| | | <span class="detail-value">{{ (scannedMaterialInfo && scannedMaterialInfo.itemModel) || '' }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">到货单号:</span> |
| | | <span class="detail-value">{{ (scannedMaterialInfo && scannedMaterialInfo.billNo) || formData.lotNo }}</span> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <span class="detail-label">可用数量:</span> |
| | | <span class="detail-value">{{ (scannedMaterialInfo && scannedMaterialInfo.oldQty) || '0' }}</span> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 重新设计的输入区域 --> |
| | | <view class="input-section"> |
| | | <view class="input-title">破坏实验数量</view> |
| | | <view class="input-container"> |
| | | <view class="input-box" @click="focusInput"> |
| | | <text v-if="destructionQuantity" class="input-value">{{ destructionQuantity }}</text> |
| | | <text v-else class="input-placeholder">点击输入数量</text> |
| | | </view> |
| | | </view> |
| | | <view v-if="!isInteger && destructionQuantity" class="error-tip">请输入有效的正整数</view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="destruction-actions"> |
| | | <button class="destruction-btn modify-btn" @click="modifyDestruction">修改</button> |
| | | <button class="destruction-btn delete-btn" @click="deleteDestruction">删除</button> |
| | | <button class="destruction-btn cancel-btn" @click="resetDestruction">返回</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 全局堵穴设置对话框 --> |
| | | <view v-if="globalBlockHolePopup" class="overlay"> |
| | | <view class="popup global-block-hole-popup"> |
| | | <h3>全局堵穴设置</h3> |
| | | <view class="block-hole-content"> |
| | | <view class="hole-info"> |
| | | <view class="info-label">检验单号:{{ formData.releaseNo }}</view> |
| | | <view class="info-label">将应用于所有有开穴数的检验项目</view> |
| | | </view> |
| | | <view class="input-section"> |
| | | <view class="input-label">堵穴数量:</view> |
| | | <input class="info-input" type="text" v-model="globalBlockHoleInput" |
| | | placeholder="请输入1,2,3" @input="onGlobalBlockHoleInput" /> |
| | | <view v-if="globalBlockHoleError" class="error-message">{{ globalBlockHoleError }}</view> |
| | | </view> |
| | | <view class="block-hole-actions"> |
| | | <button class="block-hole-btn confirm" @click="confirmGlobalBlockHole" |
| | | :disabled="!isGlobalBlockHoleValid">确认设置</button> |
| | | <button class="block-hole-btn cancel" @click="closeGlobalBlockHoleDialog">取消</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | destructionPopup: false, |
| | | PHSY: '', |
| | | isInteger: true, |
| | | scannedMaterialInfo: null, // 扫描到的物料信息 |
| | | destructionQuantity: '', // 破坏实验数量输入 |
| | | inputFocus: false, // 输入框焦点状态 |
| | | hasExistingRecord: false, // 是否有已存在的破坏实验记录 |
| | | attachments: [], |
| | | showAttachmentPopup: false, |
| | | attachmentsLoading: false, |
| | |
| | | previewTitle: '', |
| | | previewItemNo: '', |
| | | previewType: '', // 'text', 'image', 'excel', 'unsupported' |
| | | |
| | | // 全局堵穴相关数据 |
| | | globalBlockHolePopup: false, |
| | | globalBlockHoleInput: '', |
| | | globalBlockHoleError: '', |
| | | isGlobalBlockHoleValid: false, |
| | | |
| | | } |
| | | }, |
| | |
| | | this.remarks = this.formData.remarks || this.remarks || ''; |
| | | console.log('打开弹窗时的remarks值:', this.remarks); |
| | | }, |
| | | |
| | | // picker 事件处理方法 |
| | | onBadreasonChange(e) { |
| | | const index = e.detail.value; |
| | |
| | | }, |
| | | addDestruction() { |
| | | // 添加破坏实验的逻辑 |
| | | this.destructionPopup = !this.destructionPopup; |
| | | // 修复:确保PHSY变量正确初始化 |
| | | this.PHSY = this.formData.PHSY || ''; |
| | | this.destructionPopup = true; |
| | | |
| | | // 每次点击都查询是否已有破坏实验记录 |
| | | this.checkPhsyRecord(); |
| | | }, |
| | | |
| | | // 查询破坏实验记录是否存在 |
| | | checkPhsyRecord() { |
| | | uni.showLoading({ |
| | | title: '查询破坏实验记录...' |
| | | }); |
| | | |
| | | this.$post({ |
| | | url: "/LLJ/CheckPhsyRecord", |
| | | data: { |
| | | billNo: this.formData.lotNo, // 使用到货单号 |
| | | releaseNo: this.formData.releaseNo // 使用检验单号 |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | if (res.status === 0) { |
| | | const hasRecord = res.data.exists; |
| | | if (hasRecord) { |
| | | // 有记录,显示物料信息,只显示修改、删除、返回按钮 |
| | | this.showExistingRecord(); |
| | | } else { |
| | | // 无记录,显示扫描界面 |
| | | this.showScanInterface(); |
| | | } |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.message || '查询失败', |
| | | icon: 'none' |
| | | }); |
| | | this.destructionPopup = false; |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('查询破坏实验记录失败:', err); |
| | | uni.showToast({ |
| | | title: '查询失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | this.destructionPopup = false; |
| | | }); |
| | | }, |
| | | |
| | | // 显示已有记录 |
| | | showExistingRecord() { |
| | | // 设置已有记录状态 |
| | | this.hasExistingRecord = true; |
| | | // 获取破坏实验记录中的物料信息 |
| | | this.getPhsyRecordInfo(); |
| | | }, |
| | | |
| | | // 获取破坏实验记录信息 |
| | | getPhsyRecordInfo() { |
| | | uni.showLoading({ |
| | | title: '获取破坏实验记录...' |
| | | }); |
| | | |
| | | this.$post({ |
| | | url: "/LLJ/GetPhsyRecordInfo", |
| | | data: { |
| | | billNo: this.formData.lotNo, // 使用到货单号 |
| | | releaseNo: this.formData.releaseNo // 使用检验单号 |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | if (res.status === 0 && res.data && res.data.tbBillList && res.data.tbBillList.length > 0) { |
| | | // 获取到破坏实验记录,设置物料信息 |
| | | const record = res.data.tbBillList[0]; |
| | | this.scannedMaterialInfo = { |
| | | itemBarcode: record.itemBarcode, |
| | | itemNo: record.itemNo, |
| | | itemName: record.itemName, |
| | | itemModel: record.itemModel, |
| | | billNo: record.billNo, |
| | | oldQty: record.yqty |
| | | }; |
| | | // 设置破坏实验数量 |
| | | this.destructionQuantity = record.cqty ? record.cqty.toString() : ''; |
| | | } else { |
| | | // 如果没有获取到详细信息,显示提示 |
| | | uni.showToast({ |
| | | title: '已存在破坏实验记录', |
| | | icon: 'none', |
| | | duration: 1500 |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('获取破坏实验记录失败:', err); |
| | | uni.showToast({ |
| | | title: '获取记录失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 显示扫描界面 |
| | | showScanInterface() { |
| | | // 设置无记录状态 |
| | | this.hasExistingRecord = false; |
| | | // 如果已经有扫描的物料信息,直接显示结果步骤 |
| | | if (this.scannedMaterialInfo) { |
| | | // 保持当前扫描信息,不重置 |
| | | return; |
| | | } |
| | | |
| | | // 如果没有扫描信息,重置所有相关数据 |
| | | this.scannedMaterialInfo = null; |
| | | this.destructionQuantity = ''; |
| | | this.isInteger = true; |
| | | }, |
| | | |
| | | // 扫描二维码 |
| | | scanQRCode() { |
| | | // #ifdef APP-PLUS |
| | | // APP环境使用uni.scanCode |
| | | uni.scanCode({ |
| | | success: (res) => { |
| | | console.log('扫描结果:', res.result); |
| | | this.processQRCodeResult(res.result); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('扫描失败:', err); |
| | | uni.showToast({ |
| | | title: '扫描失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | // #endif |
| | | |
| | | // #ifdef H5 |
| | | // H5环境提示用户手动输入 |
| | | uni.showModal({ |
| | | title: '二维码扫描', |
| | | content: 'H5环境暂不支持摄像头扫描,请输入二维码内容', |
| | | editable: true, |
| | | placeholderText: '请输入二维码内容', |
| | | success: (res) => { |
| | | if (res.confirm && res.content) { |
| | | this.processQRCodeResult(res.content); |
| | | } |
| | | } |
| | | }); |
| | | // #endif |
| | | |
| | | // #ifdef MP |
| | | // 小程序环境使用wx.scanCode |
| | | wx.scanCode({ |
| | | success: (res) => { |
| | | console.log('扫描结果:', res.result); |
| | | this.processQRCodeResult(res.result); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('扫描失败:', err); |
| | | uni.showToast({ |
| | | title: '扫描失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | // #endif |
| | | }, |
| | | |
| | | // 处理二维码扫描结果 |
| | | processQRCodeResult(qrCodeResult) { |
| | | if (!qrCodeResult) { |
| | | uni.showToast({ |
| | | title: '二维码内容为空', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '查询物料信息...' |
| | | }); |
| | | |
| | | // 调用后端接口查询物料信息 |
| | | this.$post({ |
| | | url: "/LLJ/GetMaterialByBarcode", |
| | | data: { |
| | | itemBarcode: qrCodeResult, |
| | | currentBillNo: this.formData.lotNo // 传递当前检验单的到货单号 |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | if (res.status === 0 && res.data && res.data.tbBillList && res.data.tbBillList.length > 0) { |
| | | // 查询成功,验证物料ID是否与检验单一致 |
| | | const scannedMaterial = res.data.tbBillList[0]; |
| | | |
| | | // 检查扫描的物料ID是否与当前检验单的物料ID一致 |
| | | if (this.formData.itemId && scannedMaterial.itemId && |
| | | this.formData.itemId.toString() !== scannedMaterial.itemId.toString()) { |
| | | // 物料ID不一致,显示错误信息 |
| | | this.scannedMaterialInfo = null; |
| | | uni.showModal({ |
| | | title: '物料不匹配', |
| | | content: '扫秒的条码不为该检验单物料,请重新扫描', |
| | | showCancel: false |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 物料ID验证通过,显示物料信息 |
| | | this.scannedMaterialInfo = scannedMaterial; |
| | | // 保存扫描到的条码值,用于后续调用存储过程 |
| | | this.scannedMaterialInfo.itemBarcode = qrCodeResult; |
| | | uni.showToast({ |
| | | title: '查询成功', |
| | | icon: 'success' |
| | | }); |
| | | } else { |
| | | // 查询失败,显示错误信息 |
| | | this.scannedMaterialInfo = null; |
| | | uni.showModal({ |
| | | title: '查询失败', |
| | | content: res.message || '未找到对应的物料信息,请检查二维码是否正确', |
| | | showCancel: false |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('查询物料信息失败:', err); |
| | | this.scannedMaterialInfo = null; |
| | | uni.showModal({ |
| | | title: '查询失败', |
| | | content: '网络错误,请检查网络连接后重试', |
| | | showCancel: false |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 测试输入 |
| | | testInput() { |
| | | this.destructionQuantity = '5'; |
| | | this.validateInteger(); |
| | | uni.showToast({ |
| | | title: '测试输入完成', |
| | | icon: 'success' |
| | | }); |
| | | }, |
| | | |
| | | // 点击输入框 |
| | | focusInput() { |
| | | // 使用uni-app的输入弹窗 |
| | | uni.showModal({ |
| | | title: '输入破坏实验数量', |
| | | content: `可用数量: ${this.scannedMaterialInfo.oldQty}`, |
| | | editable: true, |
| | | placeholderText: '请输入数量', |
| | | success: (res) => { |
| | | if (res.confirm && res.content) { |
| | | this.destructionQuantity = res.content; |
| | | this.validateInteger(); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 验证输入是否为整数 |
| | | validateInteger() { |
| | | if (!this.destructionQuantity) { |
| | | this.isInteger = true; |
| | | return; |
| | | } |
| | | |
| | | const value = this.destructionQuantity.toString().trim(); |
| | | // 只允许正整数 |
| | | this.isInteger = /^[1-9]\d*$/.test(value); |
| | | }, |
| | | |
| | | // 确认破坏实验 |
| | | confirmDestruction() { |
| | | if (!this.isInteger || !this.destructionQuantity) { |
| | | uni.showToast({ |
| | | title: '请输入有效的整数数量', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 检查扫描的物料信息是否存在 |
| | | if (!this.scannedMaterialInfo) { |
| | | uni.showToast({ |
| | | title: '请先扫描物料二维码', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 验证破坏实验数量不能大于可用数量 |
| | | const destructionQty = parseInt(this.destructionQuantity); |
| | | const availableQty = parseInt(this.scannedMaterialInfo.oldQty); |
| | | |
| | | if (destructionQty > availableQty) { |
| | | uni.showModal({ |
| | | title: '数量错误', |
| | | content: `破坏实验数量(${destructionQty})不能大于可用数量(${availableQty}),请重新填写或重新扫码!`, |
| | | showCancel: false |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '调用存储过程中...' |
| | | }); |
| | | |
| | | // 调用破坏实验存储过程 |
| | | this.$post({ |
| | | url: "/LLJ/CallPhsyUpdateProcedure", |
| | | data: { |
| | | itemBarcode: this.scannedMaterialInfo.itemBarcode || this.scannedMaterialInfo.itemNo, // 使用扫描的条码 |
| | | yqty: availableQty, // 扫码查询出来的条码数量 |
| | | cqty: destructionQty, // 填写的破坏实验数量 |
| | | billNo: this.scannedMaterialInfo.billNo, // 查询到的到货单号 |
| | | lx: 1, // 操作类型:1新增 |
| | | releaseNo: this.formData.releaseNo, // 检验单号 |
| | | itemId: this.formData.itemId // 检验单的物料ID |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | // 检查存储过程返回的结果 |
| | | if (res.status === 0) { |
| | | // 存储过程执行成功 |
| | | this.formData.PHSY = this.destructionQuantity; |
| | | this.destructionPopup = false; |
| | | this.hasExistingRecord = true; // 设置为有记录状态 |
| | | uni.showToast({ |
| | | title: '破坏实验记录保存成功', |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | // 立即重新加载数据确保同步 |
| | | setTimeout(() => { |
| | | this.init(); |
| | | }, 500); |
| | | } else { |
| | | // 存储过程执行失败,显示错误信息 |
| | | uni.showModal({ |
| | | title: '操作失败', |
| | | content: res.message || '破坏实验记录保存失败', |
| | | showCancel: false |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('调用存储过程失败:', err); |
| | | uni.showModal({ |
| | | title: '网络错误', |
| | | content: '调用存储过程失败,请检查网络连接后重试', |
| | | showCancel: false |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 修改破坏实验(只修改数量) |
| | | modifyDestruction() { |
| | | // 显示数量输入界面 |
| | | uni.showModal({ |
| | | title: '修改破坏实验数量', |
| | | content: '请输入新的破坏实验数量', |
| | | editable: true, |
| | | placeholderText: '请输入数量', |
| | | success: (res) => { |
| | | if (res.confirm && res.content) { |
| | | const newQuantity = parseInt(res.content); |
| | | if (isNaN(newQuantity) || newQuantity <= 0) { |
| | | uni.showToast({ |
| | | title: '请输入有效的正整数', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 调用修改存储过程 |
| | | this.callModifyProcedure(newQuantity); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 调用修改存储过程 |
| | | callModifyProcedure(newQuantity) { |
| | | uni.showLoading({ |
| | | title: '修改中...' |
| | | }); |
| | | |
| | | // 获取当前扫描的物料信息 |
| | | const itemBarcode = (this.scannedMaterialInfo && this.scannedMaterialInfo.itemBarcode) || |
| | | (this.scannedMaterialInfo && this.scannedMaterialInfo.itemNo) || ''; |
| | | const yqty = (this.scannedMaterialInfo && this.scannedMaterialInfo.oldQty) || 0; |
| | | |
| | | this.$post({ |
| | | url: "/LLJ/CallPhsyUpdateProcedure", |
| | | data: { |
| | | itemBarcode: itemBarcode, // 使用扫描的条码 |
| | | yqty: yqty, // 使用扫码查询出来的条码数量 |
| | | cqty: newQuantity, // 新的破坏实验数量 |
| | | billNo: this.formData.lotNo, // 到货单号 |
| | | lx: 2, // 操作类型:2修改 |
| | | releaseNo: this.formData.releaseNo, // 检验单号 |
| | | itemId: this.formData.itemId // 检验单的物料ID |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | if (res.status === 0) { |
| | | // 修改成功 |
| | | this.formData.PHSY = newQuantity.toString(); |
| | | this.PHSY = newQuantity.toString(); |
| | | this.destructionPopup = false; |
| | | |
| | | uni.showToast({ |
| | | title: '修改成功', |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 重新加载数据 |
| | | setTimeout(() => { |
| | | this.init(); |
| | | }, 500); |
| | | } else { |
| | | uni.showModal({ |
| | | title: '修改失败', |
| | | content: res.message || '修改失败', |
| | | showCancel: false |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('修改失败:', err); |
| | | uni.showModal({ |
| | | title: '网络错误', |
| | | content: '修改失败,请检查网络连接后重试', |
| | | showCancel: false |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 删除破坏实验 |
| | | deleteDestruction() { |
| | | uni.showModal({ |
| | | title: '确认删除', |
| | | content: '确定要删除当前的破坏实验记录吗?', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // 调用存储过程删除记录 |
| | | this.callDeleteProcedure(); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 调用删除存储过程 |
| | | callDeleteProcedure() { |
| | | uni.showLoading({ |
| | | title: '删除中...' |
| | | }); |
| | | |
| | | // 获取当前扫描的物料信息 |
| | | const itemBarcode = (this.scannedMaterialInfo && this.scannedMaterialInfo.itemBarcode) || |
| | | (this.scannedMaterialInfo && this.scannedMaterialInfo.itemNo) || ''; |
| | | const yqty = (this.scannedMaterialInfo && this.scannedMaterialInfo.oldQty) || 0; |
| | | const cqty = parseFloat(this.destructionQuantity) || 0; // 使用当前记录的破坏数量 |
| | | |
| | | this.$post({ |
| | | url: "/LLJ/CallPhsyUpdateProcedure", |
| | | data: { |
| | | itemBarcode: itemBarcode, // 使用扫描的条码 |
| | | yqty: yqty, // 使用扫码查询出来的条码数量 |
| | | cqty: cqty, // 使用当前记录的破坏数量 |
| | | billNo: this.formData.lotNo, // 到货单号 |
| | | lx: 3, // 操作类型:3删除 |
| | | releaseNo: this.formData.releaseNo, // 检验单号 |
| | | itemId: this.formData.itemId // 检验单的物料ID |
| | | } |
| | | }).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | if (res.status === 0) { |
| | | // 删除成功 |
| | | this.scannedMaterialInfo = null; |
| | | this.destructionQuantity = ''; |
| | | this.isInteger = true; |
| | | this.formData.PHSY = ''; |
| | | this.PHSY = ''; |
| | | this.hasExistingRecord = false; |
| | | this.destructionPopup = false; |
| | | |
| | | uni.showToast({ |
| | | title: '删除成功', |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 重新加载数据 |
| | | setTimeout(() => { |
| | | this.init(); |
| | | }, 500); |
| | | } else { |
| | | uni.showModal({ |
| | | title: '删除失败', |
| | | content: res.message || '删除失败', |
| | | showCancel: false |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('删除失败:', err); |
| | | uni.showModal({ |
| | | title: '网络错误', |
| | | content: '删除失败,请检查网络连接后重试', |
| | | showCancel: false |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 重置破坏实验(返回上一步) |
| | | resetDestruction() { |
| | | this.scannedMaterialInfo = null; |
| | | this.destructionQuantity = ''; |
| | | this.isInteger = true; |
| | | this.hasExistingRecord = false; |
| | | this.destructionPopup = false; // 直接关闭弹窗,返回到表单 |
| | | }, |
| | | |
| | | // 关闭破坏实验弹窗 |
| | | closeDestructionPopup() { |
| | | this.destructionPopup = false; |
| | | // 重置所有相关数据 |
| | | this.scannedMaterialInfo = null; |
| | | this.destructionQuantity = ''; |
| | | this.isInteger = true; |
| | | }, |
| | | |
| | | editDestruction() { |
| | | // 验证输入是否为整数或空字符串 |
| | | if(this.PHSY === '') { |
| | |
| | | showFilePreview(content, fileName) { |
| | | this.previewContent = content; |
| | | this.previewTitle = fileName; |
| | | this.previewItemNo = this.selectedAttachment?.itemNo || ''; |
| | | this.previewItemNo = (this.selectedAttachment && this.selectedAttachment.itemNo) || ''; |
| | | this.previewType = this.getFileType(fileName); |
| | | this.showFilePreviewPopup = true; |
| | | }, |
| | |
| | | } |
| | | // #endif |
| | | }, |
| | | |
| | | |
| | | // 全局堵穴相关方法 |
| | | // 检查检验项目是否有穴数 |
| | | hasHoleCount(fcheckItem) { |
| | | if (!fcheckItem) return false; |
| | | const match = fcheckItem.match(/[((](\d+)穴[))]/); |
| | | return match ? true : false; |
| | | }, |
| | | |
| | | // 获取穴数 |
| | | getHoleCount(fcheckItem) { |
| | | if (!fcheckItem) return 0; |
| | | const match = fcheckItem.match(/[((](\d+)穴[))]/); |
| | | return match ? parseInt(match[1]) : 0; |
| | | }, |
| | | |
| | | // 打开全局堵穴对话框 |
| | | openGlobalBlockHoleDialog() { |
| | | console.log('点击堵穴设置按钮'); |
| | | console.log('tableData:', this.tableData); |
| | | |
| | | // 检查是否有有开穴数的检验项目 |
| | | const hasHoleItems = this.tableData.some(item => this.hasHoleCount(item.fcheckItem)); |
| | | console.log('hasHoleItems:', hasHoleItems); |
| | | |
| | | if (!hasHoleItems) { |
| | | uni.showModal({ |
| | | title: '提示', |
| | | content: '当前检验单没有有开穴数的检验项目', |
| | | showCancel: false |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | this.globalBlockHoleInput = ''; |
| | | this.globalBlockHolePopup = true; |
| | | console.log('设置globalBlockHolePopup为true'); |
| | | this.validateGlobalBlockHoleInput(); |
| | | }, |
| | | |
| | | // 关闭全局堵穴对话框 |
| | | closeGlobalBlockHoleDialog() { |
| | | this.globalBlockHolePopup = false; |
| | | this.globalBlockHoleInput = ''; |
| | | this.globalBlockHoleError = ''; |
| | | this.isGlobalBlockHoleValid = false; |
| | | }, |
| | | |
| | | |
| | | // 处理全局堵穴输入(保留原方法以防其他地方调用) |
| | | onGlobalBlockHoleInput(e) { |
| | | console.log('输入事件触发:', e); |
| | | // 兼容不同的事件格式 |
| | | const value = e.detail ? e.detail.value : e.target ? e.target.value : e; |
| | | console.log('输入值:', value); |
| | | this.globalBlockHoleInput = value; |
| | | this.validateGlobalBlockHoleInput(); |
| | | }, |
| | | |
| | | // 验证全局堵穴输入 |
| | | validateGlobalBlockHoleInput() { |
| | | const input = this.globalBlockHoleInput.trim(); |
| | | if (!input) { |
| | | this.globalBlockHoleError = ''; |
| | | this.isGlobalBlockHoleValid = false; |
| | | return; |
| | | } |
| | | |
| | | // 验证格式:1,2,3 或 1,2,3 |
| | | const blockedHoles = input.split(/[,,]/).map(s => s.trim()).filter(s => s); |
| | | |
| | | // 检查是否都是有效数字 |
| | | const isValid = blockedHoles.every(hole => { |
| | | const num = parseInt(hole); |
| | | return !isNaN(num) && num > 0; |
| | | }); |
| | | |
| | | if (!isValid) { |
| | | this.globalBlockHoleError = '请输入有效的穴号,用逗号分隔'; |
| | | this.isGlobalBlockHoleValid = false; |
| | | return; |
| | | } |
| | | |
| | | // 检查是否有重复 |
| | | const uniqueHoles = [...new Set(blockedHoles.map(h => parseInt(h)))]; |
| | | if (uniqueHoles.length !== blockedHoles.length) { |
| | | this.globalBlockHoleError = '不能输入重复的穴号'; |
| | | this.isGlobalBlockHoleValid = false; |
| | | return; |
| | | } |
| | | |
| | | this.globalBlockHoleError = ''; |
| | | this.isGlobalBlockHoleValid = true; |
| | | }, |
| | | |
| | | // 确认全局堵穴 |
| | | confirmGlobalBlockHole() { |
| | | if (!this.isGlobalBlockHoleValid) return; |
| | | |
| | | uni.showLoading({ |
| | | title: '设置堵穴中...' |
| | | }); |
| | | |
| | | // 获取所有有开穴数的检验项目 |
| | | const holeItems = this.tableData.filter(item => this.hasHoleCount(item.fcheckItem)); |
| | | |
| | | // 批量调用后端接口设置堵穴 |
| | | const promises = holeItems.map(item => { |
| | | return this.$post({ |
| | | url: "/LLJ/SetBlockedHoles", |
| | | data: { |
| | | releaseNo: this.formData.releaseNo, |
| | | blockedHoles: this.globalBlockHoleInput, |
| | | itemId: item.id |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | Promise.all(promises).then(results => { |
| | | uni.hideLoading(); |
| | | |
| | | // 检查所有请求是否成功 |
| | | const failedCount = results.filter(res => res.status !== 0).length; |
| | | |
| | | if (failedCount === 0) { |
| | | uni.showToast({ |
| | | title: `成功为${holeItems.length}个检验项目设置堵穴`, |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 立即关闭对话框 |
| | | this.closeGlobalBlockHoleDialog(); |
| | | |
| | | // 立即重新加载数据确保同步 |
| | | setTimeout(() => { |
| | | this.init(); |
| | | }, 500); |
| | | } else { |
| | | uni.showModal({ |
| | | title: '部分设置失败', |
| | | content: `${failedCount}个检验项目设置失败,请重试`, |
| | | showCancel: false |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | uni.hideLoading(); |
| | | console.error('全局堵穴设置失败:', err); |
| | | uni.showModal({ |
| | | title: '网络错误', |
| | | content: '堵穴设置失败,请检查网络连接后重试', |
| | | showCancel: false |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 1000; /* 提高层级,确保在固定按钮上方 */ |
| | | } |
| | | |
| | | /* 全局堵穴设置对话框需要更高的z-index */ |
| | | .global-block-hole-popup { |
| | | z-index: 1001; |
| | | } |
| | | |
| | | /* 弹窗整体美化 */ |
| | |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* 扫描按钮样式 */ |
| | | .scan-btn { |
| | | background: linear-gradient(135deg, #4CAF50, #45a049); |
| | | color: white; |
| | | border: none; |
| | | border-radius: 8px; |
| | | padding: 12px 20px; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 8px; |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
| | | } |
| | | |
| | | .scan-btn:hover { |
| | | background: linear-gradient(135deg, #45a049, #3d8b40); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 8px rgba(0,0,0,0.15); |
| | | } |
| | | |
| | | /* 物料信息显示样式 */ |
| | | .material-info-display { |
| | | margin-top: 16px; |
| | | padding: 16px; |
| | | background: linear-gradient(135deg, #f8f9fa, #e9ecef); |
| | | border-radius: 8px; |
| | | border: 1px solid #dee2e6; |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.05); |
| | | } |
| | | |
| | | .material-info-display h4 { |
| | | margin: 0 0 12px 0; |
| | | color: #495057; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | text-align: center; |
| | | } |
| | | |
| | | .material-detail { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .detail-row { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 6px 0; |
| | | border-bottom: 1px solid #e9ecef; |
| | | } |
| | | |
| | | .detail-row:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .detail-label { |
| | | min-width: 80px; |
| | | font-weight: 600; |
| | | color: #6c757d; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .detail-value { |
| | | flex: 1; |
| | | color: #212529; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .detail-value.barcode-value { |
| | | font-family: 'Courier New', monospace; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | background-color: #f8f9fa; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | border: 1px solid #dee2e6; |
| | | font-size: 13px; |
| | | letter-spacing: 0.5px; |
| | | } |
| | | |
| | | /* 破坏实验弹窗样式 */ |
| | | .destruction-popup { |
| | | width: 90vw; |
| | | max-width: 500px; |
| | | min-height: 300px; |
| | | } |
| | | |
| | | /* 扫描步骤样式 */ |
| | | .scan-step { |
| | | text-align: center; |
| | | padding: 40px 20px; |
| | | } |
| | | |
| | | /* 已有记录步骤样式 */ |
| | | .existing-record-step { |
| | | padding: 20px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .existing-icon { |
| | | font-size: 48px; |
| | | text-align: center; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .existing-title { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | text-align: center; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .existing-description { |
| | | font-size: 14px; |
| | | color: #7f8c8d; |
| | | text-align: center; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | /* 当前破坏实验数量显示 */ |
| | | .current-phsy-display { |
| | | margin: 20px 0; |
| | | padding: 16px; |
| | | background: linear-gradient(135deg, #f8f9fa, #e9ecef); |
| | | border-radius: 8px; |
| | | border: 1px solid #dee2e6; |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.05); |
| | | } |
| | | |
| | | .phsy-info { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .phsy-label { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #495057; |
| | | } |
| | | |
| | | .phsy-value { |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | color: #e74c3c; |
| | | background-color: #fff; |
| | | padding: 4px 12px; |
| | | border-radius: 4px; |
| | | border: 1px solid #e74c3c; |
| | | } |
| | | |
| | | .scan-icon { |
| | | font-size: 64px; |
| | | margin-bottom: 20px; |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | .scan-title { |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .scan-description { |
| | | font-size: 14px; |
| | | color: #7f8c8d; |
| | | margin-bottom: 30px; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | /* 扫描步骤按钮布局 */ |
| | | .scan-actions { |
| | | display: flex; |
| | | gap: 12px; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* 结果步骤样式 */ |
| | | .result-step { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .scan-success-icon { |
| | | font-size: 48px; |
| | | text-align: center; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .scan-success-title { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #27ae60; |
| | | text-align: center; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | /* 破坏实验操作按钮样式 */ |
| | | .destruction-actions { |
| | | display: flex; |
| | | gap: 8px; |
| | | margin-top: 24px; |
| | | justify-content: center; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .destruction-btn { |
| | | padding: 10px 16px; |
| | | border: none; |
| | | border-radius: 8px; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | min-width: 80px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | flex: 1; |
| | | max-width: 120px; |
| | | } |
| | | |
| | | .destruction-btn.confirm-btn { |
| | | background: linear-gradient(135deg, #27ae60, #2ecc71); |
| | | color: white; |
| | | box-shadow: 0 2px 8px rgba(39, 174, 96, 0.3); |
| | | } |
| | | |
| | | .destruction-btn.confirm-btn:hover:not(:disabled) { |
| | | background: linear-gradient(135deg, #229954, #27ae60); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 12px rgba(39, 174, 96, 0.4); |
| | | } |
| | | |
| | | .destruction-btn.confirm-btn:disabled { |
| | | background: #bdc3c7; |
| | | color: #7f8c8d; |
| | | cursor: not-allowed; |
| | | transform: none; |
| | | box-shadow: none; |
| | | } |
| | | |
| | | .destruction-btn.cancel-btn { |
| | | background: linear-gradient(135deg, #95a5a6, #7f8c8d); |
| | | color: white; |
| | | box-shadow: 0 2px 8px rgba(149, 165, 166, 0.3); |
| | | } |
| | | |
| | | .destruction-btn.cancel-btn:hover { |
| | | background: linear-gradient(135deg, #7f8c8d, #6c7b7d); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 12px rgba(149, 165, 166, 0.4); |
| | | } |
| | | |
| | | .destruction-btn.modify-btn { |
| | | background: linear-gradient(135deg, #f39c12, #e67e22); |
| | | color: white; |
| | | box-shadow: 0 2px 8px rgba(243, 156, 18, 0.3); |
| | | } |
| | | |
| | | .destruction-btn.modify-btn:hover { |
| | | background: linear-gradient(135deg, #e67e22, #d35400); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 12px rgba(243, 156, 18, 0.4); |
| | | } |
| | | |
| | | .destruction-btn.delete-btn { |
| | | background: linear-gradient(135deg, #e74c3c, #c0392b); |
| | | color: white; |
| | | box-shadow: 0 2px 8px rgba(231, 76, 60, 0.3); |
| | | } |
| | | |
| | | .destruction-btn.delete-btn:hover { |
| | | background: linear-gradient(135deg, #c0392b, #a93226); |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 4px 12px rgba(231, 76, 60, 0.4); |
| | | } |
| | | |
| | | /* 表单输入框样式优化 */ |
| | | .form-input { |
| | | width: 100%; |
| | | padding: 12px 16px; |
| | | border: 2px solid #e9ecef; |
| | | border-radius: 8px; |
| | | font-size: 16px; |
| | | transition: border-color 0.3s ease; |
| | | box-sizing: border-box; |
| | | background-color: #fff !important; |
| | | color: #333 !important; |
| | | -webkit-appearance: none; |
| | | -moz-appearance: none; |
| | | appearance: none; |
| | | -webkit-user-select: text !important; |
| | | -moz-user-select: text !important; |
| | | -ms-user-select: text !important; |
| | | user-select: text !important; |
| | | pointer-events: auto !important; |
| | | opacity: 1 !important; |
| | | z-index: 1 !important; |
| | | } |
| | | |
| | | .form-input:focus { |
| | | border-color: #3498db; |
| | | outline: none; |
| | | box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); |
| | | background-color: #fff; |
| | | } |
| | | |
| | | /* 简单输入框样式 - 参考SJ.vue */ |
| | | .info-input { |
| | | flex: 1; |
| | | padding: 12px 16px; |
| | | border: 2px solid #ddd; |
| | | border-radius: 6px; |
| | | background-color: white; |
| | | font-size: 16px; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | min-height: 44px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .info-input:focus { |
| | | border-color: #3498db; |
| | | outline: none; |
| | | box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); |
| | | } |
| | | |
| | | /* 输入框包装器 */ |
| | | .input-wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | } |
| | | |
| | | /* 破坏实验输入框特殊样式 */ |
| | | .destruction-input { |
| | | background-color: #fff !important; |
| | | border: 2px solid #e9ecef !important; |
| | | color: #333 !important; |
| | | font-size: 16px !important; |
| | | padding: 12px 16px !important; |
| | | width: 100% !important; |
| | | box-sizing: border-box !important; |
| | | -webkit-user-select: text !important; |
| | | -moz-user-select: text !important; |
| | | -ms-user-select: text !important; |
| | | user-select: text !important; |
| | | -webkit-appearance: none !important; |
| | | -moz-appearance: none !important; |
| | | appearance: none !important; |
| | | pointer-events: auto !important; |
| | | opacity: 1 !important; |
| | | z-index: 1 !important; |
| | | } |
| | | |
| | | .destruction-input:focus { |
| | | border-color: #3498db !important; |
| | | background-color: #fff !important; |
| | | outline: none !important; |
| | | box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1) !important; |
| | | } |
| | | |
| | | .destruction-input:disabled { |
| | | background-color: #f5f5f5 !important; |
| | | color: #999 !important; |
| | | cursor: not-allowed !important; |
| | | } |
| | | |
| | | /* uni-easyinput 样式 */ |
| | | .destruction-input-uni { |
| | | width: 100% !important; |
| | | } |
| | | |
| | | .destruction-input-uni .uni-easyinput__content { |
| | | border: 2px solid #e9ecef !important; |
| | | border-radius: 8px !important; |
| | | background-color: #fff !important; |
| | | } |
| | | |
| | | .destruction-input-uni .uni-easyinput__content-input { |
| | | font-size: 16px !important; |
| | | color: #333 !important; |
| | | padding: 12px 16px !important; |
| | | } |
| | | |
| | | /* 模拟输入框样式 */ |
| | | .fake-input { |
| | | width: 100%; |
| | | padding: 12px 16px; |
| | | border: 2px solid #e9ecef; |
| | | border-radius: 8px; |
| | | background-color: #fff; |
| | | font-size: 16px; |
| | | color: #333; |
| | | cursor: pointer; |
| | | transition: border-color 0.3s ease; |
| | | box-sizing: border-box; |
| | | min-height: 44px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .fake-input:hover { |
| | | border-color: #3498db; |
| | | } |
| | | |
| | | .fake-input.error { |
| | | border-color: #e74c3c; |
| | | } |
| | | |
| | | .fake-input .placeholder { |
| | | color: #999; |
| | | } |
| | | |
| | | /* 简化的输入框样式 */ |
| | | .simple-input { |
| | | width: 100%; |
| | | padding: 12px 16px; |
| | | border: 2px solid #e9ecef; |
| | | border-radius: 8px; |
| | | font-size: 16px; |
| | | color: #333; |
| | | background-color: #fff; |
| | | box-sizing: border-box; |
| | | outline: none; |
| | | -webkit-appearance: none; |
| | | -moz-appearance: none; |
| | | appearance: none; |
| | | -webkit-user-select: text; |
| | | -moz-user-select: text; |
| | | -ms-user-select: text; |
| | | user-select: text; |
| | | -webkit-tap-highlight-color: transparent; |
| | | } |
| | | |
| | | .simple-input:focus { |
| | | border-color: #3498db; |
| | | -webkit-user-select: text; |
| | | -moz-user-select: text; |
| | | -ms-user-select: text; |
| | | user-select: text; |
| | | } |
| | | |
| | | /* 重新设计的输入区域样式 */ |
| | | .input-section { |
| | | margin: 20px 0; |
| | | padding: 20px; |
| | | background: #f8f9fa; |
| | | border-radius: 12px; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | |
| | | .input-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | margin-bottom: 12px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .input-container { |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .input-box { |
| | | width: 200px; |
| | | height: 50px; |
| | | border: 2px solid #3498db; |
| | | border-radius: 8px; |
| | | background-color: #fff; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
| | | } |
| | | |
| | | .input-box:hover { |
| | | border-color: #2980b9; |
| | | box-shadow: 0 4px 8px rgba(0,0,0,0.15); |
| | | transform: translateY(-1px); |
| | | } |
| | | |
| | | .input-box:active { |
| | | transform: translateY(0); |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
| | | } |
| | | |
| | | .input-value { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | } |
| | | |
| | | .input-placeholder { |
| | | font-size: 16px; |
| | | color: #7f8c8d; |
| | | font-style: italic; |
| | | } |
| | | |
| | | .error-tip { |
| | | text-align: center; |
| | | color: #e74c3c; |
| | | font-size: 14px; |
| | | margin-top: 8px; |
| | | } |
| | | |
| | | .form-label { |
| | | display: block; |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | margin-bottom: 8px; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .form-group { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | /* 错误信息样式 */ |
| | | .error-message { |
| | | color: #e74c3c; |
| | | font-size: 12px; |
| | | margin-top: 4px; |
| | | text-align: center; |
| | | } |
| | | |
| | | /* 堵穴相关样式 */ |
| | | .block-hole-btn { |
| | | background-color: #f39c12; |
| | | color: white; |
| | | padding: 6px 12px; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | font-size: 12px; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .block-hole-btn:hover:not(.disabled) { |
| | | background-color: #e67e22; |
| | | transform: translateY(-1px); |
| | | } |
| | | |
| | | .block-hole-btn.disabled { |
| | | background-color: #bdc3c7; |
| | | color: #7f8c8d; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .blocked-info { |
| | | color: #e74c3c; |
| | | font-size: 12px; |
| | | margin-left: 8px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .block-hole-popup, |
| | | .global-block-hole-popup { |
| | | width: 80vw; |
| | | max-width: 500px; |
| | | min-height: 300px; |
| | | } |
| | | |
| | | .block-hole-content { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .hole-info { |
| | | margin-bottom: 20px; |
| | | padding: 15px; |
| | | background-color: #f8f9fa; |
| | | border-radius: 8px; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | |
| | | .hole-info .info-label { |
| | | font-weight: 600; |
| | | color: #495057; |
| | | margin-bottom: 8px; |
| | | display: block; |
| | | } |
| | | |
| | | .input-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .input-label { |
| | | font-weight: 600; |
| | | color: #495057; |
| | | margin-bottom: 8px; |
| | | display: block; |
| | | } |
| | | |
| | | .block-hole-input { |
| | | width: 100%; |
| | | padding: 12px 16px; |
| | | border: 2px solid #e9ecef; |
| | | border-radius: 8px; |
| | | font-size: 16px; |
| | | transition: border-color 0.3s ease; |
| | | box-sizing: border-box; |
| | | background-color: #fff !important; |
| | | color: #333 !important; |
| | | -webkit-user-select: text !important; |
| | | -moz-user-select: text !important; |
| | | -ms-user-select: text !important; |
| | | user-select: text !important; |
| | | pointer-events: auto !important; |
| | | opacity: 1 !important; |
| | | /* 移除z-index,避免遮挡弹窗 */ |
| | | } |
| | | |
| | | .block-hole-input:focus { |
| | | border-color: #3498db; |
| | | outline: none; |
| | | box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); |
| | | } |
| | | |
| | | .block-hole-actions { |
| | | display: flex; |
| | | gap: 12px; |
| | | justify-content: center; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .block-hole-btn.confirm { |
| | | background: linear-gradient(135deg, #27ae60, #2ecc71); |
| | | color: white; |
| | | padding: 12px 24px; |
| | | min-width: 100px; |
| | | } |
| | | |
| | | .block-hole-btn.confirm:hover:not(:disabled) { |
| | | background: linear-gradient(135deg, #229954, #27ae60); |
| | | } |
| | | |
| | | .block-hole-btn.confirm:disabled { |
| | | background: #bdc3c7; |
| | | color: #7f8c8d; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .block-hole-btn.cancel { |
| | | background: linear-gradient(135deg, #95a5a6, #7f8c8d); |
| | | color: white; |
| | | padding: 12px 24px; |
| | | min-width: 100px; |
| | | } |
| | | |
| | | .block-hole-btn.cancel:hover { |
| | | background: linear-gradient(135deg, #7f8c8d, #6c7b7d); |
| | | } |
| | | |
| | | |
| | | .blocked-holes-info { |
| | | color: #e74c3c; |
| | | font-weight: bold; |
| | | margin-left: 8px; |
| | | } |
| | | </style> |