| | |
| | | <template> |
| | | <view class="sockpage"> |
| | | <view class="column"> |
| | | <!-- 托盘编码 --> |
| | | <view class="form-card"> |
| | | <view class="form-row"> |
| | | <view class="label"> |
| | | <text class="required">*</text>托盘编码: |
| | | </view> |
| | | <view class="picker-wrap" hover-class="picker-hover"> |
| | | <view class="picker-wrap"> |
| | | <view class="input-box"> |
| | | <input |
| | | id="pdacode" |
| | | type="text" |
| | | v-model="barcode" |
| | | placeholder="请扫码" |
| | | type="text" |
| | | v-model="barcode" |
| | | placeholder="请扫码" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 箱型栏(对应后端boxType) --> |
| | | <!-- 箱型选择 --> |
| | | <view class="form-card"> |
| | | <view class="form-row"> |
| | | <view class="label"> |
| | | <text class="required">*</text>箱 型: |
| | | <text class="required">*</text>箱型: |
| | | </view> |
| | | <view class="picker-wrap" hover-class="picker-hover"> |
| | | <view class="picker-wrap"> |
| | | <picker @change="modePickerChange" :value="index_mode" :range="mode"> |
| | | <view class="input-box"> |
| | | <text class="input-placeholder" v-if="!mode.length || !mode[index_mode]">请选择箱型</text> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="form-card"> |
| | | <view class="form-row"> |
| | | <view class="label"> |
| | | <text class="required">*</text>物料码: |
| | | </view> |
| | | <view class="picker-wrap" hover-class="picker-hover"> |
| | | <view class="textareainput"> |
| | | <textarea |
| | | style="max-height: 15px;overflow: hidden;" |
| | | id="pdacode" |
| | | <!-- 物料码扫码(隐藏但可用) --> |
| | | <!-- <view class="form-card" style="height: 0; overflow: hidden; padding: 0; margin: 0;"> --> |
| | | <view class="form-card" style=" overflow: hidden; padding: 0; margin: 0;"> |
| | | <view class="form-row"> |
| | | <view class="label"> |
| | | <text class="required">*</text>物料码: |
| | | </view> |
| | | <view class="picker-wrap"> |
| | | <view class="input-box"> |
| | | <input |
| | | type="text" |
| | | v-model="thingCode" |
| | | v-model="scanBuffer" |
| | | placeholder="请扫码" |
| | | @input="handleBarcodeInput" |
| | | @input="handleMaterialScan" |
| | | ref="scanInput" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 物料信息 --> |
| | | <view class="form-card material-card"> |
| | | <view class="card-title">物料信息</view> |
| | | |
| | | <!-- 多物料列表 --> |
| | | <view class="material-list" v-if="matList.length > 0"> |
| | | <view class="material-item" v-for="(mat, index) in matList" :key="mat.id"> |
| | | <view class="material-header"> |
| | | <text class="material-title">物料 {{ index + 1 }}</text> |
| | | <view class="material-actions"> |
| | | <view class="action-btn" @click="removeMaterial(index)">删除</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="material-grid"> |
| | | <view class="material-item"> |
| | | <text class="material-label"><text class="required">*</text>位置:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="mat.position" |
| | | placeholder="请选择位置" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label"><text class="required">*</text>箱号:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="mat.batch" |
| | | placeholder="请扫码或输入箱号" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label"><text class="required">*</text>卷号:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="mat.model" |
| | | placeholder="请扫码或输入卷号" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">规格:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="mat.matnr" |
| | | placeholder="请输入规格" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">长度:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="mat.rollExtent" |
| | | placeholder="请输入长度" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">净重:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="mat.weight" |
| | | placeholder="请输入净重" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">毛重:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="mat.roughWeight" |
| | | placeholder="请输入毛重" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">接头:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="mat.joint" |
| | | placeholder="请输入接头数" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- 物料信息输入栏(对应后端MatList) --> |
| | | <view class="form-card material-card"> |
| | | <view class="card-title">物料信息</view> |
| | | <view class="material-grid"> |
| | | <view class="material-item"> |
| | | <text class="material-label"><text class="required">*</text>卷号:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="matList.model" |
| | | placeholder="请扫码或输入卷号" |
| | | placeholder-class="input-placeholder" |
| | | ref="modelInput" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label"><text class="required">*</text>箱号:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="matList.batch" |
| | | placeholder="请扫码或输入箱号" |
| | | placeholder-class="input-placeholder" |
| | | ref="batchInput" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">规格:</text> |
| | | <input |
| | | class="material-input" |
| | | type="text" |
| | | v-model="matList.matnr" |
| | | placeholder="请输入规格" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">长度:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="matList.rollExtent" |
| | | placeholder="请输入长度" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">净重:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="matList.weight" |
| | | placeholder="请输入净重" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">毛重:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="matList.roughWeight" |
| | | placeholder="请输入毛重" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | <view class="material-item"> |
| | | <text class="material-label">接头:</text> |
| | | <input |
| | | class="material-input" |
| | | type="number" |
| | | v-model="matList.joint" |
| | | placeholder="请输入接头数" |
| | | placeholder-class="input-placeholder" |
| | | /> |
| | | </view> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <view class="empty-state" v-else> |
| | | <view class="empty-icon">📦</view> |
| | | <text class="empty-text">暂无物料信息</text> |
| | | <text class="empty-tip">请扫描物料码添加物料</text> |
| | | </view> |
| | | |
| | | <!-- 扫码按钮 --> |
| | | <view class="scan-btn" @click="focusScanInput"> |
| | | <text class="scan-icon">+</text> |
| | | <text class="scan-text">扫码添加物料</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮组 --> |
| | | <view class="btn-group"> |
| | | <button class="operate-btn submit-btn" @click="submit">成品入库</button> |
| | | <button class="operate-btn submit-btn" @click="submit">组托</button> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 扫码确认弹窗 --> |
| | | <view class="modal-mask" v-if="showScanModal" @click="closeModal"> |
| | | <view class="modal-content" @click.stop> |
| | | <view class="modal-header"> |
| | | <text class="modal-title">扫码确认</text> |
| | | </view> |
| | | <view class="modal-body"> |
| | | <view class="scan-preview"> |
| | | <text class="scan-label">扫描到物料:</text> |
| | | <text class="scan-code">{{ tempMaterial.model || '未知物料' }}</text> |
| | | </view> |
| | | |
| | | <view class="preview-grid"> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">箱号:</text> |
| | | <text class="preview-value">{{ tempMaterial.batch || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">卷号:</text> |
| | | <text class="preview-value">{{ tempMaterial.model || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">规格:</text> |
| | | <text class="preview-value">{{ tempMaterial.matnr || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">长度:</text> |
| | | <text class="preview-value">{{ tempMaterial.rollExtent || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">净重:</text> |
| | | <text class="preview-value">{{ tempMaterial.weight || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">毛重:</text> |
| | | <text class="preview-value">{{ tempMaterial.roughWeight || '未识别' }}</text> |
| | | </view> |
| | | <view class="preview-item"> |
| | | <text class="preview-label">接头:</text> |
| | | <text class="preview-value">{{ tempMaterial.joint || '未识别' }}</text> |
| | | </view> |
| | | |
| | | <view class="preview-item full-width"> |
| | | <text class="preview-label">物料位置:</text> |
| | | <view class="position-selector" @click.stop="togglePositionPicker"> |
| | | <view class="position-display"> |
| | | <text v-if="positionIndex >= 0">{{ positionOptions[positionIndex].label }}</text> |
| | | <text v-else class="placeholder">请选择位置</text> |
| | | <text class="position-arrow">▼</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 新增:自定义选择器弹出层 --> |
| | | <view v-if="showPositionPicker" class="custom-picker-overlay" @click.stop="closePositionPicker"> |
| | | <view class="custom-picker-content" @click.stop> |
| | | <view class="custom-picker-header"> |
| | | <text class="custom-picker-title">选择物料位置</text> |
| | | <view class="custom-picker-close" @click="closePositionPicker">×</view> |
| | | </view> |
| | | <view class="custom-picker-list"> |
| | | <view |
| | | v-for="(item, index) in positionOptions" |
| | | :key="index" |
| | | class="custom-picker-item" |
| | | :class="{'selected': positionIndex === index}" |
| | | @click="selectPosition(index)" |
| | | > |
| | | <text class="custom-picker-text">{{ item.label }}</text> |
| | | <text v-if="positionIndex === index" class="custom-picker-check">✓</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="modal-footer"> |
| | | <button class="modal-btn cancel" @click="cancelAddMaterial">取消</button> |
| | | <button class="modal-btn confirm" @click="confirmAddMaterial">确定添加</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | onLoad(options){ |
| | | onLoad(options) { |
| | | this.checkLoginStatus(); |
| | | this.POSTinfo(); |
| | | this.POSTinfo(); |
| | | }, |
| | | |
| | | onShow() { |
| | |
| | | } |
| | | }, |
| | | |
| | | onReady() { |
| | | // 在页面准备就绪后初始化扫码监听 |
| | | setTimeout(() => { |
| | | this.initScanListener(); |
| | | }, 500); |
| | | }, |
| | | |
| | | data() { |
| | | return { |
| | | thingCode:'', |
| | | focusState: false, |
| | | baseUrl: '', |
| | | token: '', |
| | | barcode: '', |
| | | palletizingNo: '1', |
| | | boxType: '', |
| | | matList: { |
| | | matnr: '', |
| | | maktx: '', |
| | | batch: '', |
| | | model: '', |
| | | position: '1', |
| | | weight: '', |
| | | roughWeight: '', |
| | | anfme: 1.0, |
| | | rollExtent: '', |
| | | joint: 0, |
| | | cutting: 2, |
| | | qualified: 0, |
| | | modelFront: '', |
| | | batchFront: '' |
| | | }, |
| | | mode: [], |
| | | mode: [], |
| | | index_mode: 0, |
| | | submitData: {}, |
| | | |
| | | // 扫码相关 |
| | | scanBuffer: '', |
| | | scanTimeout: null, |
| | | lastScanTime: 0, |
| | | isProcessingScan: false |
| | | |
| | | // 物料列表 |
| | | matList: [], |
| | | materialId: 1, |
| | | |
| | | // 弹窗相关 |
| | | showScanModal: false, |
| | | tempMaterial: { |
| | | model: '', |
| | | batch: '', |
| | | matnr: '', |
| | | rollExtent: '', |
| | | weight: '', |
| | | roughWeight: '', |
| | | joint: 0, |
| | | position: '1' // 新增:物料位置,默认值为"1"(左) |
| | | }, |
| | | |
| | | // 新增:物料位置下拉框相关数据 |
| | | positionIndex: 0, // 默认选中第一个(左) |
| | | |
| | | // 新增:控制自定义选择器显示 |
| | | showPositionPicker: false, |
| | | positionOptions: [ |
| | | { label: '1', value: '1' }, |
| | | { label: '2', value: '2' } |
| | | ] |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | // 新增:切换位置选择器显示 |
| | | togglePositionPicker() { |
| | | this.showPositionPicker = !this.showPositionPicker; |
| | | }, |
| | | |
| | | // 新增:关闭位置选择器 |
| | | closePositionPicker() { |
| | | this.showPositionPicker = false; |
| | | }, |
| | | |
| | | // 新增:选择位置 |
| | | selectPosition(index) { |
| | | this.positionIndex = index; |
| | | this.tempMaterial.position = this.positionOptions[index].value; |
| | | this.closePositionPicker(); |
| | | }, |
| | | |
| | | // 初始化扫码监听 |
| | | initScanListener() { |
| | | // 在uni-app中,可以通过ref获取DOM节点,但要注意平台差异 |
| | | // 这里我们通过一个安全的方法来聚焦输入框 |
| | | this.$nextTick(() => { |
| | | const input = this.$refs.scanInput; |
| | | if (input && typeof input.focus === 'function') { |
| | | input.focus(); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 聚焦扫码输入框 |
| | | focusScanInput() { |
| | | // 使用uni-app的安全方法 |
| | | this.$nextTick(() => { |
| | | const input = this.$refs.scanInput; |
| | | if (input) { |
| | | // 在uni-app中,input可能是一个组件实例 |
| | | // 我们需要获取其DOM节点或使用平台特定的方法 |
| | | // 这里我们尝试调用focus,如果不可用则跳过 |
| | | try { |
| | | if (typeof input.focus === 'function') { |
| | | input.focus(); |
| | | } else if (input.$el && typeof input.$el.focus === 'function') { |
| | | // 如果是Vue组件实例 |
| | | input.$el.focus(); |
| | | } |
| | | } catch (error) { |
| | | console.log('聚焦失败,但不影响功能:', error); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 处理扫码输入 |
| | | handleMaterialScan(e) { |
| | | const value = e.detail ? e.detail.value : e.target.value; |
| | | |
| | | // 防抖处理 |
| | | if (this.scanTimeout) { |
| | | clearTimeout(this.scanTimeout); |
| | | } |
| | | |
| | | this.scanTimeout = setTimeout(() => { |
| | | if (value && value.trim()) { |
| | | this.parseBarcodeContent(value.trim()); |
| | | this.showScanModal = true; |
| | | this.scanBuffer = ''; // 清空缓冲区 |
| | | |
| | | // 每次打开弹窗时重置位置选择为默认值 |
| | | this.positionIndex = 0; |
| | | this.tempMaterial.position = '1'; |
| | | } |
| | | }, 300); |
| | | }, |
| | | |
| | | // 解析条码内容 |
| | | parseBarcodeContent(content) { |
| | | // const lines = content.split(/\\n/).filter(line => line.trim() !== ''); |
| | | const lines = content.split(' ').filter(line => line.trim().length > 0); |
| | | |
| | | // 清空临时数据 |
| | | this.tempMaterial = { |
| | | model: '', |
| | | batch: '', |
| | | matnr: '', |
| | | rollExtent: '', |
| | | weight: '', |
| | | roughWeight: '', |
| | | joint: 0, |
| | | position: '1' // 重置位置为默认值 |
| | | }; |
| | | |
| | | // 使用正则表达式提取键值对[6,7](@ref) |
| | | const extractKeyValue = (line) => { |
| | | const match = line.match(/([^:]+):(.+)/); |
| | | if (match && match.length === 3) { |
| | | return { |
| | | key: match[1].trim(), |
| | | value: match[2].trim() |
| | | }; |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | // 提取数字(包括小数)[6,7](@ref) |
| | | const extractNumber = (str) => { |
| | | const match = str.match(/[\d.]+/); |
| | | return match ? match[0] : ''; |
| | | }; |
| | | |
| | | // 遍历每一行,解析键值对 |
| | | lines.forEach(line => { |
| | | const keyValue = extractKeyValue(line); |
| | | if (keyValue) { |
| | | const { key, value } = keyValue; |
| | | |
| | | switch (key) { |
| | | case '卷号': |
| | | this.tempMaterial.model = value; |
| | | break; |
| | | case '箱号': |
| | | this.tempMaterial.batch = value; |
| | | break; |
| | | case '规格': |
| | | this.tempMaterial.matnr = value; |
| | | break; |
| | | case '长度': |
| | | this.tempMaterial.rollExtent = extractNumber(value); |
| | | break; |
| | | case '净重': |
| | | this.tempMaterial.weight = extractNumber(value); |
| | | break; |
| | | case '毛重': |
| | | this.tempMaterial.roughWeight = extractNumber(value); |
| | | break; |
| | | case '接头': |
| | | this.tempMaterial.joint = extractNumber(value) || 0; |
| | | break; |
| | | default: |
| | | // 可以处理未知键或忽略 |
| | | break; |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 确认添加物料 |
| | | confirmAddMaterial() { |
| | | this.closePositionPicker(); |
| | | if (!this.tempMaterial.model) { |
| | | uni.showToast({ |
| | | title: '卷号不能为空', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否已存在相同物料 |
| | | const exists = this.matList.some(item => |
| | | item.model === this.tempMaterial.model && |
| | | item.batch === this.tempMaterial.batch |
| | | ); |
| | | |
| | | if (exists) { |
| | | uni.showToast({ |
| | | title: '该物料已存在', |
| | | icon: 'none' |
| | | }); |
| | | this.closeModal(); |
| | | return; |
| | | }; |
| | | |
| | | // 添加到物料列表 |
| | | const newMaterial = { |
| | | id: this.materialId++, |
| | | ...this.tempMaterial, |
| | | position: (this.matList.length + 1).toString(), |
| | | cutting: 2, |
| | | qualified: 0 |
| | | }; |
| | | |
| | | this.matList.push(newMaterial); |
| | | |
| | | uni.showToast({ |
| | | title: '物料添加成功', |
| | | icon: 'success' |
| | | }); |
| | | |
| | | this.closeModal(); |
| | | }, |
| | | |
| | | // 取消添加 |
| | | cancelAddMaterial() { |
| | | this.closeModal(); |
| | | }, |
| | | |
| | | // 关闭弹窗 |
| | | closeModal() { |
| | | this.showPositionPicker = false; |
| | | this.showScanModal = false; |
| | | this.tempMaterial = { |
| | | model: '', |
| | | batch: '', |
| | | matnr: '', |
| | | rollExtent: '', |
| | | weight: '', |
| | | roughWeight: '', |
| | | joint: 0, |
| | | position: '1' // 重置位置 |
| | | }; |
| | | |
| | | // 重置位置选择 |
| | | this.positionIndex = 0; |
| | | |
| | | // 重新聚焦到扫码输入框 |
| | | setTimeout(() => { |
| | | this.focusScanInput(); |
| | | }, 100); |
| | | }, |
| | | |
| | | // 删除物料 |
| | | removeMaterial(index) { |
| | | uni.showModal({ |
| | | title: '确认删除', |
| | | content: '确定要删除这个物料吗?', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | this.matList.splice(index, 1); |
| | | uni.showToast({ |
| | | title: '删除成功', |
| | | icon: 'success' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 检查登录状态 |
| | | checkLoginStatus() { |
| | | this.token = uni.getStorageSync('token'); |
| | |
| | | }, |
| | | |
| | | // 获取箱型数据 |
| | | POSTinfo(){ |
| | | POSTinfo() { |
| | | if (!this.checkLoginStatus()) return; |
| | | |
| | | uni.showLoading({ |
| | |
| | | }, |
| | | success: (res) => { |
| | | uni.hideLoading(); |
| | | console.log('箱型接口返回:', res.data); |
| | | |
| | | if (res.data && res.data.code === 200) { |
| | | if (Array.isArray(res.data.data)) { |
| | | // 尝试多种可能的字段名 |
| | | this.mode = res.data.data |
| | | .map(item => item.boxSpecs || item.boxType || item.typeName || item.name || '') |
| | | .filter(item => item && item.trim() !== ''); |
| | | |
| | | console.log('提取的箱型列表:', this.mode); |
| | | |
| | | if (this.mode.length === 0) { |
| | | uni.showToast({ |
| | | title: '无可用箱型', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | } else { |
| | | console.warn('返回数据格式不符,不是数组:', res.data.data); |
| | | if (res.data && res.data.code === 200 && Array.isArray(res.data.data)) { |
| | | this.mode = res.data.data |
| | | .map(item => item.boxSpecs || item.boxType || item.typeName || item.name || '') |
| | | .filter(item => item && item.trim() !== ''); |
| | | if (this.mode.length === 0) { |
| | | uni.showToast({ |
| | | title: '数据格式错误', |
| | | title: '无可用箱型', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | modePickerChange(e) { |
| | | this.index_mode = e.detail.value; |
| | | this.boxType = this.mode[this.index_mode]; |
| | | console.log('选择的箱型:', this.boxType); |
| | | }, |
| | | |
| | | handleBarcodeInput(e) { |
| | | // 在uni-app中,textarea的input事件可能是e.detail.value |
| | | const value = e.detail ? e.detail.value : e.target.value; |
| | | this.thingCode = value; |
| | | this.parseBarcodeContent(value); |
| | | }, |
| | | |
| | | parseBarcodeContent(content) { |
| | | if (!content) return; |
| | | |
| | | // 按行分割内容 |
| | | const lines = content.split('\n').filter(line => line.trim() !== ''); |
| | | |
| | | console.log('解析的行数据:', lines); |
| | | |
| | | // 根据你提供的样例格式解析 |
| | | // 格式为: |
| | | // 2511080305A22B6 (卷号) |
| | | // Y251113764 (箱号) |
| | | // 5μm×1050mm (规格) |
| | | // 8700 m (长度) |
| | | // 418.0 kg (净重) |
| | | // 441.0 kg (毛重) |
| | | // 0 个 (接头) |
| | | |
| | | if (lines.length >= 7) { |
| | | // 卷号 (第一行) |
| | | this.matList.model = lines[0].trim(); |
| | | |
| | | // 箱号 (第二行) |
| | | this.matList.batch = lines[1].trim(); |
| | | |
| | | // 规格 (第三行) |
| | | this.matList.matnr = lines[2].trim(); |
| | | |
| | | // 长度 (第四行) - 提取数字部分 |
| | | const lengthMatch = lines[3].match(/([\d.]+)/); |
| | | if (lengthMatch) { |
| | | this.matList.rollExtent = lengthMatch[1]; |
| | | } |
| | | |
| | | // 净重 (第五行) - 提取数字部分 |
| | | const weightMatch = lines[4].match(/([\d.]+)/); |
| | | if (weightMatch) { |
| | | this.matList.weight = weightMatch[1]; |
| | | } |
| | | |
| | | // 毛重 (第六行) - 提取数字部分 |
| | | const roughWeightMatch = lines[5].match(/([\d.]+)/); |
| | | if (roughWeightMatch) { |
| | | this.matList.roughWeight = roughWeightMatch[1]; |
| | | } |
| | | |
| | | // 接头 (第七行) - 提取数字部分 |
| | | const jointMatch = lines[6].match(/([\d.]+)/); |
| | | if (jointMatch) { |
| | | this.matList.joint = jointMatch[1]; |
| | | } |
| | | |
| | | console.log('解析后的数据:', this.matList); |
| | | } else if (lines.length > 0) { |
| | | // 如果行数不够,也可以尝试智能匹配 |
| | | this.autoMatchFields(lines); |
| | | } |
| | | }, |
| | | |
| | | // 智能匹配方法,用于处理可能的不规则数据 |
| | | autoMatchFields(lines) { |
| | | lines.forEach((line, index) => { |
| | | line = line.trim(); |
| | | |
| | | // 根据内容特征匹配 |
| | | if (index === 0 && !this.matList.model) { |
| | | // 假设第一行总是卷号 |
| | | this.matList.model = line; |
| | | } else if (index === 1 && !this.matList.batch) { |
| | | // 假设第二行总是箱号 |
| | | this.matList.batch = line; |
| | | } else if (line.includes('μm') || line.includes('mm') || line.includes('×')) { |
| | | // 包含规格特征的 |
| | | this.matList.matnr = line; |
| | | } else if (line.includes('m') && line.match(/[\d.]+ m/)) { |
| | | // 长度特征 |
| | | const match = line.match(/([\d.]+)/); |
| | | if (match) this.matList.rollExtent = match[1]; |
| | | } else if (line.includes('kg') && line.match(/[\d.]+ kg/)) { |
| | | // 重量特征,需要区分净重和毛重 |
| | | const match = line.match(/([\d.]+)/); |
| | | if (match) { |
| | | const weightValue = match[1]; |
| | | if (!this.matList.weight) { |
| | | this.matList.weight = weightValue; |
| | | } else if (!this.matList.roughWeight) { |
| | | this.matList.roughWeight = weightValue; |
| | | } |
| | | } |
| | | } else if (line.includes('个') && line.match(/[\d.]+ 个/)) { |
| | | // 接头特征 |
| | | const match = line.match(/([\d.]+)/); |
| | | if (match) this.matList.joint = match[1]; |
| | | } |
| | | }); |
| | | }, |
| | | // 重置表单 |
| | | resetForm() { |
| | | this.barcode = ''; |
| | | this.boxType = ''; |
| | | this.index_mode = 0; |
| | | this.matList = { |
| | | matnr: '', |
| | | maktx: '', |
| | | batch: '', |
| | | model: '', |
| | | position: '1', |
| | | weight: '', |
| | | roughWeight: '', |
| | | anfme: 1.0, |
| | | rollExtent: '', |
| | | joint: 0, |
| | | cutting: 2, |
| | | qualified: 0, |
| | | modelFront: '', |
| | | batchFront: '' |
| | | }; |
| | | this.scanBuffer = ''; |
| | | this.focusState = false; |
| | | }, |
| | | |
| | | // 提交数据 |
| | | submit() { |
| | | // 1. 验证登录 |
| | | if (!this.checkLoginStatus()) return; |
| | | |
| | | // 2. 验证必填项 |
| | | // 验证必填项 |
| | | if (!this.barcode) { |
| | | uni.showToast({title: '请扫描托盘编码', icon: 'none'}); |
| | | return; |
| | | } |
| | | |
| | | |
| | | this.boxType = 999; |
| | | if (!this.boxType) { |
| | | uni.showToast({title: '请选择箱型', icon: 'none'}); |
| | | return; |
| | | } |
| | | |
| | | if (!this.matList.model) { |
| | | uni.showToast({title: '请填写卷号', icon: 'none'}); |
| | | if (this.matList.length === 0) { |
| | | uni.showToast({title: '请至少添加一个物料', icon: 'none'}); |
| | | return; |
| | | } |
| | | |
| | | if (!this.matList.batch) { |
| | | uni.showToast({title: '请填写箱号', icon: 'none'}); |
| | | return; |
| | | // 验证每个物料的必填字段 |
| | | for (let i = 0; i < this.matList.length; i++) { |
| | | const mat = this.matList[i]; |
| | | if (!mat.model) { |
| | | uni.showToast({title: `物料${i+1}卷号不能为空`, icon: 'none'}); |
| | | return; |
| | | } |
| | | if (!mat.batch) { |
| | | uni.showToast({title: `物料${i+1}箱号不能为空`, icon: 'none'}); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 3. 准备数据 |
| | | const matItem = { |
| | | ...this.matList, |
| | | weight: this.matList.weight ? Number(this.matList.weight) : null, |
| | | roughWeight: this.matList.roughWeight ? Number(this.matList.roughWeight) : null, |
| | | rollExtent: this.matList.rollExtent ? Number(this.matList.rollExtent) : null, |
| | | joint: this.matList.joint ? Number(this.matList.joint) : 0 |
| | | }; |
| | | |
| | | // 准备提交数据 |
| | | const submitData = { |
| | | barcode: this.barcode, |
| | | palletizingNo: this.palletizingNo, |
| | | boxType: this.boxType, |
| | | matList: [matItem] |
| | | matList: this.matList.map(mat => ({ |
| | | ...mat, |
| | | weight: mat.weight ? Number(mat.weight) : null, |
| | | roughWeight: mat.roughWeight ? Number(mat.roughWeight) : null, |
| | | rollExtent: mat.rollExtent ? Number(mat.rollExtent) : null, |
| | | joint: mat.joint ? Number(mat.joint) : 0, |
| | | position: mat.position // 包含位置信息 |
| | | })) |
| | | }; |
| | | |
| | | console.log('提交数据:', submitData); |
| | | |
| | | // 4. 发送请求 |
| | | // 发送请求 |
| | | uni.showLoading({ |
| | | title: '提交中...', |
| | | mask: true |
| | |
| | | data: submitData, |
| | | success: (res) => { |
| | | uni.hideLoading(); |
| | | console.log('提交返回:', res.data); |
| | | |
| | | if (res.data.code === 200) { |
| | | uni.showToast({ |
| | |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 清空表单 |
| | | setTimeout(() => { |
| | | this.resetForm(); |
| | | }, 1500); |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.data.message || '提交失败', |
| | | title: res.data.msg || '提交失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 重置表单 |
| | | resetForm() { |
| | | this.barcode = ''; |
| | | this.boxType = ''; |
| | | this.index_mode = 0; |
| | | this.matList = []; |
| | | this.materialId = 1; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 全局样式 */ |
| | | |
| | | /* 物料位置选择器样式 */ |
| | | .full-width { |
| | | grid-column: 1 / -1; /* 占满整行 */ |
| | | margin-top: 8rpx; |
| | | position: relative; |
| | | z-index: 100; /* 确保在弹窗内部层级正常 */ |
| | | } |
| | | |
| | | .position-selector { |
| | | width: 200rpx; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | .position-picker { |
| | | width: 200rpx; |
| | | } |
| | | |
| | | .position-display { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 8rpx 16rpx; |
| | | border: 1rpx solid #e5e7eb; |
| | | border-radius: 6rpx; |
| | | background-color: #ffffff; |
| | | color: #333; |
| | | font-size: 28rpx; |
| | | min-height: 40rpx; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #999; |
| | | } |
| | | |
| | | .position-arrow { |
| | | font-size: 20rpx; |
| | | color: #666; |
| | | margin-left: 8rpx; |
| | | } |
| | | /* 全局样式 - 保持原有风格 */ |
| | | .sockpage { |
| | | background-color: #f5f7fa; |
| | | padding: 24rpx; |
| | | padding: 20rpx; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* 表单列容器 */ |
| | | .column { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 24rpx; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | /* 表单卡片 */ |
| | | .form-card { |
| | | background: #ffffff; |
| | | border-radius: 12rpx; |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); |
| | | padding: 24rpx; |
| | | transition: all 0.2s ease; |
| | | } |
| | | .textareainput{ |
| | | width: 60%; |
| | | height: 15px; |
| | | font-size: 28rpx; |
| | | padding: 16rpx 12rpx; |
| | | border: 1rpx solid #e5e7eb; |
| | | border-radius: 8rpx; |
| | | transition: border-color 0.2s ease; |
| | | } |
| | | /* 物料信息卡片特殊样式 */ |
| | | .material-card { |
| | | padding: 0; |
| | | } |
| | | .card-title { |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | color: #1f2937; |
| | | padding: 24rpx 24rpx 16rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | padding: 20rpx; |
| | | box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* 表单行 */ |
| | | .form-row { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | gap: 16rpx; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | /* 标签样式 */ |
| | | .label { |
| | | font-size: 28rpx; |
| | | color: #374151; |
| | | color: #333; |
| | | font-weight: 500; |
| | | min-width: 140rpx; |
| | | } |
| | | |
| | | /* 必填项标红 */ |
| | | .required { |
| | | color: #ef4444; |
| | | color: #e64340; |
| | | margin-right: 4rpx; |
| | | } |
| | | |
| | | /* 选择器容器 */ |
| | | .picker-wrap { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | /* 选择器hover态 */ |
| | | .picker-hover { |
| | | background-color: #f9fafb; |
| | | border-radius: 8rpx; |
| | | } |
| | | |
| | | /* 输入框容器 */ |
| | | .input-box { |
| | | flex: 1; |
| | | font-size: 28rpx; |
| | | padding: 16rpx 12rpx; |
| | | border: 1rpx solid #e5e7eb; |
| | | border-radius: 8rpx; |
| | | transition: border-color 0.2s ease; |
| | | border-radius: 6rpx; |
| | | padding: 16rpx 20rpx; |
| | | background: #fff; |
| | | } |
| | | |
| | | .input-box:focus-within { |
| | | border-color: #f97316; |
| | | .input-placeholder { |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | /* 输入值样式 */ |
| | | .input-value { |
| | | color: #1f2937; |
| | | color: #333; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | /* 扫码图标 */ |
| | | .scan-icon { |
| | | /* 物料信息卡片 */ |
| | | .material-card { |
| | | padding: 0; |
| | | } |
| | | |
| | | .card-title { |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | padding: 20rpx 20rpx 16rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | /* 物料列表 */ |
| | | .material-list { |
| | | padding: 0 20rpx; |
| | | } |
| | | |
| | | .material-item { |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .material-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 16rpx; |
| | | padding-bottom: 12rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .material-title { |
| | | font-size: 28rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | } |
| | | |
| | | .material-actions { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | .action-btn { |
| | | font-size: 24rpx; |
| | | margin-left: 8rpx; |
| | | color: #6b7280; |
| | | color: #e64340; |
| | | padding: 6rpx 12rpx; |
| | | border-radius: 4rpx; |
| | | background: #fff0f0; |
| | | } |
| | | |
| | | /* 物料信息网格布局 */ |
| | | /* 物料网格 */ |
| | | .material-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(2, 1fr); |
| | | gap: 20rpx; |
| | | padding: 24rpx; |
| | | gap: 16rpx; |
| | | } |
| | | |
| | | /* 物料信息项 */ |
| | | .material-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 8rpx; |
| | | } |
| | | |
| | | /* 物料标签 */ |
| | | .material-label { |
| | | font-size: 26rpx; |
| | | color: #4b5563; |
| | | color: #666; |
| | | } |
| | | |
| | | /* 物料输入框 */ |
| | | .material-input { |
| | | width: 45%; |
| | | font-size: 28rpx; |
| | | color: #1f2937; |
| | | padding: 16rpx 12rpx; |
| | | color: #333; |
| | | padding: 12rpx; |
| | | border: 1rpx solid #e5e7eb; |
| | | border-radius: 8rpx; |
| | | border-radius: 6rpx; |
| | | background-color: #ffffff; |
| | | transition: border-color 0.2s ease; |
| | | } |
| | | |
| | | .material-input:focus { |
| | | border-color: #f97316; |
| | | outline: none; |
| | | /* 空状态 */ |
| | | .empty-state { |
| | | text-align: center; |
| | | padding: 40rpx 20rpx; |
| | | } |
| | | |
| | | /* 按钮组 */ |
| | | .btn-group { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | justify-content: center; |
| | | margin-top: 16rpx; |
| | | padding: 8rpx 0; |
| | | .empty-icon { |
| | | font-size: 60rpx; |
| | | display: block; |
| | | margin-bottom: 20rpx; |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | /* 操作按钮通用样式 */ |
| | | .operate-btn { |
| | | flex: 1; |
| | | max-width: 200rpx; |
| | | height: 80rpx; |
| | | line-height: 80rpx; |
| | | .empty-text { |
| | | display: block; |
| | | font-size: 28rpx; |
| | | font-weight: 500; |
| | | border-radius: 12rpx; |
| | | border: none; |
| | | transition: all 0.2s ease; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | color: #999; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .empty-tip { |
| | | display: block; |
| | | font-size: 24rpx; |
| | | color: #ccc; |
| | | } |
| | | |
| | | /* 扫码按钮 */ |
| | | .scan-btn { |
| | | background-color: #3b82f6; |
| | | color: #ffffff; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 10rpx; |
| | | padding: 20rpx; |
| | | margin: 20rpx 20rpx 20rpx; |
| | | background: #f0f7ff; |
| | | border: 1rpx dashed #1989fa; |
| | | border-radius: 8rpx; |
| | | color: #1989fa; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .scan-btn:active { |
| | | background-color: #2563eb; |
| | | transform: scale(0.98); |
| | | .scan-icon { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | /* 提交按钮 */ |
| | | .submit-btn { |
| | | background-color: #f97316; |
| | | color: #ffffff; |
| | | /* 按钮组 */ |
| | | .btn-group { |
| | | margin-top: 20rpx; |
| | | padding: 8rpx 0; |
| | | text-align: center; |
| | | } |
| | | |
| | | .submit-btn:active { |
| | | background-color: #ea580c; |
| | | transform: scale(0.98); |
| | | .operate-btn { |
| | | width: 200rpx; |
| | | height: 80rpx; |
| | | line-height: 80rpx; |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | border-radius: 8rpx; |
| | | border: none; |
| | | background: #333; |
| | | color: #fff; |
| | | } |
| | | |
| | | /* 适配小屏幕 */ |
| | | @media (max-width: 375px) { |
| | | /* 弹窗样式 */ |
| | | .modal-mask { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .modal-content { |
| | | background: #fff; |
| | | border-radius: 12rpx; |
| | | width: 600rpx; |
| | | max-width: 90%; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .modal-header { |
| | | padding: 30rpx 30rpx 20rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .modal-title { |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | } |
| | | |
| | | .modal-body { |
| | | padding: 30rpx; |
| | | } |
| | | |
| | | .scan-preview { |
| | | margin-bottom: 20rpx; |
| | | padding-bottom: 20rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .scan-label { |
| | | font-size: 28rpx; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .scan-code { |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | font-weight: bold; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .preview-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(2, 1fr); |
| | | gap: 15rpx; |
| | | } |
| | | |
| | | .preview-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .preview-label { |
| | | font-size: 28rpx; |
| | | color: #666; |
| | | } |
| | | |
| | | .preview-value { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .modal-footer { |
| | | display: flex; |
| | | border-top: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .modal-btn { |
| | | flex: 1; |
| | | height: 90rpx; |
| | | line-height: 90rpx; |
| | | font-size: 30rpx; |
| | | border: none; |
| | | background: transparent; |
| | | border-radius: 0; |
| | | } |
| | | |
| | | .modal-btn.cancel { |
| | | color: #999; |
| | | border-right: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .modal-btn.confirm { |
| | | color: #1989fa; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 自定义选择器样式 */ |
| | | .custom-picker-overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 9999; /* 确保在最上层 */ |
| | | } |
| | | |
| | | .custom-picker-content { |
| | | background-color: #ffffff; |
| | | border-radius: 12rpx; |
| | | width: 600rpx; |
| | | max-width: 80%; |
| | | max-height: 70vh; |
| | | overflow: hidden; |
| | | box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15); |
| | | animation: fadeIn 0.3s ease; |
| | | } |
| | | |
| | | @keyframes fadeIn { |
| | | from { |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | } |
| | | to { |
| | | opacity: 1; |
| | | transform: translateY(0); |
| | | } |
| | | } |
| | | |
| | | .custom-picker-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | } |
| | | |
| | | .custom-picker-title { |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | color: #333; |
| | | } |
| | | |
| | | .custom-picker-close { |
| | | font-size: 40rpx; |
| | | color: #999; |
| | | line-height: 1; |
| | | padding: 0 10rpx; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .custom-picker-list { |
| | | max-height: 50vh; |
| | | overflow-y: auto; |
| | | padding: 0; |
| | | } |
| | | |
| | | .custom-picker-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 25rpx 30rpx; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | cursor: pointer; |
| | | transition: background-color 0.2s; |
| | | } |
| | | |
| | | .custom-picker-item:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .custom-picker-item:hover { |
| | | background-color: #f8f9fa; |
| | | } |
| | | |
| | | .custom-picker-item.selected { |
| | | background-color: #f0f7ff; |
| | | color: #1989fa; |
| | | } |
| | | |
| | | .custom-picker-text { |
| | | font-size: 30rpx; |
| | | } |
| | | |
| | | .custom-picker-check { |
| | | font-size: 28rpx; |
| | | color: #1989fa; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | /* 弹窗样式调整,确保层级关系 */ |
| | | .modal-mask { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 1000; /* 弹窗基础层级 */ |
| | | } |
| | | |
| | | .modal-content { |
| | | position: relative; /* 确保子元素相对定位 */ |
| | | z-index: 1001; /* 比蒙版高一级 */ |
| | | background: #fff; |
| | | border-radius: 12rpx; |
| | | width: 600rpx; |
| | | max-width: 90%; |
| | | overflow: visible; /* 改为 visible 允许选择器弹出 */ |
| | | } |
| | | |
| | | /* 响应式适配 */ |
| | | @media (max-width: 750rpx) { |
| | | .material-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .operate-btn { |
| | | max-width: 160rpx; |
| | | height: 72rpx; |
| | | line-height: 72rpx; |
| | | font-size: 26rpx; |
| | | .preview-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .modal-content { |
| | | width: 90%; |
| | | } |
| | | .custom-picker-content { |
| | | width: 90%; |
| | | max-width: 90%; |
| | | } |
| | | |
| | | .custom-picker-item { |
| | | padding: 20rpx 25rpx; |
| | | } |
| | | } |
| | | </style> |