| | |
| | | </view> <!-- 这里闭合 top-section-grid --> |
| | | <!-- 操作按钮 - 移出 top-section-grid --> |
| | | <view class="button-row"> |
| | | <button class="save-btn" @click="handleUpTool" :disabled="submitting || loadingForm">上刀提交(=调机开始)</button> |
| | | <button class="save-btn" @click="handleUpTool" :disabled="submitting || loadingForm">上刀提交</button> |
| | | <button class="save-btn" @click="handleDownTool" :disabled="submitting || loadingForm">下刀提交</button> |
| | | <button class="cancel-btn" @click="cancel" :disabled="submitting || loadingForm">清空刀具选择</button> |
| | | </view> |
| | | |
| | | <!-- 新增:调机数据输入区域 --> |
| | | <view class="tiaoji-section"> |
| | | <view class="tiaoji-row"> |
| | | <!-- 当前调机师傅 --> |
| | | <view class="current-user-section"> |
| | | <text>当前调机师傅:</text> |
| | | <text class="current-user-name">{{ tiaojiStaffDisplay || '未选择' }}</text> |
| | | <button class="select-user-btn" @click="isTiaojiUserSelectShow = true">选人</button> |
| | | </view> |
| | | |
| | | <!-- 调机良品数 --> |
| | | <view class="tiaoji-input-section"> |
| | | <text>调机良品数:</text> |
| | | <input v-model="tiaojiOkQty" class="inp tiaoji-input" type="number" placeholder="请输入数量" /> |
| | | </view> |
| | | |
| | | <!-- 调机不良品数 --> |
| | | <view class="tiaoji-input-section"> |
| | | <text>调机不良品数:</text> |
| | | <input v-model="tiaojiBadQty" class="inp tiaoji-input" type="number" placeholder="请输入数量" /> |
| | | </view> |
| | | |
| | | <!-- 送检呼叫按钮 --> |
| | | <view class="tiaoji-submit-section"> |
| | | <button class="details-btn" @click="handleInspectionCall">送检呼叫</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 选择调机师傅弹窗 --> |
| | | <view v-if="isTiaojiUserSelectShow" class="overlay"> |
| | | <view class="popup user-select-popup"> |
| | | <!-- 搜索栏 --> |
| | | <view class="user-search-bar"> |
| | | <input v-model.trim="tiaojiUserSearch" |
| | | type="text" |
| | | class="user-search-input" |
| | | placeholder="输入工号或姓名搜索" |
| | | @keydown.enter.prevent /> |
| | | <button v-if="tiaojiUserSearch" class="user-search-clear" @click="tiaojiUserSearch=''">清空</button> |
| | | <view class="user-search-info"> |
| | | 匹配:{{ filteredTiaojiUsers.length }} / {{ tiaojiUsers.length }} |
| | | </view> |
| | | </view> |
| | | <view class="user-list-scroll"> |
| | | <template v-if="filteredTiaojiUsers.length"> |
| | | <view class="user-list-grid"> |
| | | <button v-for="(u, index) in filteredTiaojiUsers" |
| | | :key="index" |
| | | :class="['user-list-btn', {'selected': u===tiaojiStaffNo}]" |
| | | @click="selectTiaojiUser(u)"> |
| | | <span class="user-code">{{ u.split(':')[0] }}</span> |
| | | <span class="user-name">{{ u.split(':')[1] }}</span> |
| | | </button> |
| | | </view> |
| | | </template> |
| | | <view v-else class="no-user-result"> |
| | | 未找到匹配人员 |
| | | </view> |
| | | </view> |
| | | <view class="user-popup-footer"> |
| | | <button class="clean-btn wide-btn" @click="isTiaojiUserSelectShow = false">关闭</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 刀具目录弹窗 --> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 刀具使用记录表格 --> |
| | | <view class="table-section"> |
| | | <!-- 隐藏刀具使用记录表格 --> |
| | | <view v-if="false" class="table-section"> |
| | | <table class="styled-table"> |
| | | <thead> |
| | | <tr> |
| | |
| | | isDirty: false, // 表单是否有未保存变更 |
| | | autoSaveIntervalMs: 5 * 60 * 1000, // 默认 5 分钟 |
| | | autoSaveEnabled: true, |
| | | autoSaveActionName: 'handleUpTool' // 自动触发的方法名,可改为自定义保存方法 |
| | | autoSaveActionName: 'handleUpTool', // 自动触发的方法名,可改为自定义保存方法 |
| | | |
| | | // 新增:调机相关字段 |
| | | isTiaojiUserSelectShow: false, // 调机师傅选择弹窗 |
| | | tiaojiStaffNo: '', // 当前选中的调机师傅(格式: 工号:姓名) |
| | | tiaojiOkQty: '', // 调机良品数 |
| | | tiaojiBadQty: '', // 调机不良品数 |
| | | tiaojiUsers: [], // 调机师傅列表 |
| | | tiaojiUserSearch: '', // 搜索关键词 |
| | | |
| | | // 新增:报试产数所需字段 |
| | | orderId: null, // 工单ID |
| | | order: {} // 工单数据 |
| | | }; |
| | | }, |
| | | computed: { |
| | | totalPages() { |
| | | return Math.max(1, Math.ceil(this.total / this.pageSize) || 1); |
| | | }, |
| | | // 新增:调机师傅显示名称 |
| | | tiaojiStaffDisplay() { |
| | | if (!this.tiaojiStaffNo) return ''; |
| | | const segs = this.tiaojiStaffNo.split(':'); |
| | | return segs.length > 1 ? `${segs[0]} ${segs[1]}` : this.tiaojiStaffNo; |
| | | }, |
| | | // 新增:过滤后的调机师傅列表 |
| | | filteredTiaojiUsers() { |
| | | if (!this.tiaojiUserSearch) return this.tiaojiUsers; |
| | | const kw = this.tiaojiUserSearch.trim().toLowerCase(); |
| | | return this.tiaojiUsers.filter(u => u.toLowerCase().includes(kw)); |
| | | } |
| | | }, |
| | | watch: { |
| | |
| | | }); |
| | | if (res.status === 0 && Array.isArray(res.data?.tbBillList) && res.data.tbBillList.length > 0) { |
| | | const order = res.data.tbBillList[0]; |
| | | |
| | | // 新增:保存工单数据,用于报试产数 |
| | | this.order = order; |
| | | this.orderId = order.id || order.ID || order.orderId || null; |
| | | |
| | | this.selectedToolNo = order.cutterId || order.cutteR_ID || ''; |
| | | this.toolName = order.cutterName || order.cutteR_NAME || ''; |
| | | this.toolModel = order.cutterModel || order.cutteR_MODEL || ''; |
| | |
| | | } |
| | | } else { |
| | | this.workOrderCurrentCjNum = null; |
| | | this.order = {}; |
| | | this.orderId = null; |
| | | } |
| | | } catch (e) { |
| | | console.warn('自动带出工单刀具失败', e); |
| | | this.workOrderCurrentCjNum = null; |
| | | this.order = {}; |
| | | this.orderId = null; |
| | | } |
| | | }, |
| | | formatDateTime(dateTimeStr) { |
| | |
| | | } catch { |
| | | return String(dateTimeStr); |
| | | } |
| | | }, |
| | | |
| | | // 新增:选择调机师傅 |
| | | selectTiaojiUser(u) { |
| | | this.tiaojiStaffNo = u; |
| | | this.isTiaojiUserSelectShow = false; |
| | | this.tiaojiUserSearch = ''; |
| | | }, |
| | | |
| | | // 新增:送检呼叫 + 报试产数 |
| | | async handleInspectionCall() { |
| | | // 验证必填项 |
| | | if (!this.tiaojiStaffNo) { |
| | | this.$showMessage('请选择调机师傅'); |
| | | return; |
| | | } |
| | | |
| | | const okQty = Number(this.tiaojiOkQty); |
| | | const badQty = Number(this.tiaojiBadQty); |
| | | |
| | | if (isNaN(okQty) || okQty < 0) { |
| | | this.$showMessage('请输入有效的调机良品数'); |
| | | return; |
| | | } |
| | | |
| | | if (isNaN(badQty) || badQty < 0) { |
| | | this.$showMessage('请输入有效的调机不良品数'); |
| | | return; |
| | | } |
| | | |
| | | const staffNo = this.tiaojiStaffNo.split(':')[0]; |
| | | const totalQty = okQty + badQty; // 试产总数 = 良品数 + 不良品数 |
| | | |
| | | // 调用报试产数接口(使用报工界面的接口) |
| | | const payload = { |
| | | orderNo: this.workOrderNo, |
| | | orderId: this.orderId, // 需要从工单数据中获取 |
| | | bf: totalQty, // 试产总数 |
| | | staffNo: staffNo, |
| | | initCjNum: this.order?.initCjNum || 0, |
| | | currentCjNum: this.order?.currentCjNum || 0, |
| | | type: 'tiaoji', // 标识为调机报工 |
| | | tiaojiOkQty: okQty, // 新增:良品数 |
| | | tiaojiBadQty: badQty // 新增:不良品数 |
| | | }; |
| | | |
| | | try { |
| | | this.submitting = true; |
| | | // 调用报工界面的报试产数接口 |
| | | const res = await this.$post({ |
| | | url: '/MesInvItemBarcodes/AddBFToBarcodes', |
| | | data: payload |
| | | }); |
| | | |
| | | if (res.status == 1) { |
| | | this.$showMessage(res.message); |
| | | return; |
| | | } |
| | | |
| | | this.$showMessage('调机报工成功'); |
| | | // 清空输入 |
| | | this.tiaojiOkQty = ''; |
| | | this.tiaojiBadQty = ''; |
| | | // 刷新数据 |
| | | await this.fetchFormData(); |
| | | await this.fetchDefaultToolFromWorkOrder(); |
| | | } catch (err) { |
| | | console.error('调机报工错误:', err); |
| | | this.$showMessage('调机报工失败,请检查网络'); |
| | | } finally { |
| | | this.submitting = false; |
| | | } |
| | | }, |
| | | |
| | | // 新增:获取调机师傅列表 |
| | | async fetchTiaojiStaff() { |
| | | try { |
| | | const res = await this.$post({ |
| | | url: '/MesStaff/GetAllXS0101BYtj' // 与报工界面使用相同接口 |
| | | }); |
| | | if (res.status === 0 && res.data && res.data.tbBillList) { |
| | | const staff = res.data.tbBillList; |
| | | this.tiaojiUsers = staff.map(s => s.staffNo + ':' + s.staffName); |
| | | } |
| | | } catch (err) { |
| | | console.error('获取调机师傅列表失败:', err); |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.fetchTools(''); |
| | | this.machineNo = uni.getStorageSync('machineNo') || ''; |
| | | this.workOrderNo = uni.getStorageSync('daa001') || ''; |
| | | |
| | | // 新增:获取调机师傅列表 |
| | | this.fetchTiaojiStaff(); |
| | | |
| | | if (this.machineNo && this.workOrderNo) { |
| | | this.fetchFormData().then(async () => { |
| | |
| | | margin-right: 16px; |
| | | flex: none !important; /* 关键:彻底禁止flex拉伸 */ |
| | | } |
| | | |
| | | /* 新增:调机区域样式 */ |
| | | .tiaoji-section { |
| | | width: 100%; |
| | | margin: 2vh 0; |
| | | padding: 20px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | |
| | | .tiaoji-row { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | align-items: center; |
| | | gap: 20px; |
| | | } |
| | | |
| | | /* 当前调机师傅区域 - 与报工界面保持一致 */ |
| | | .current-user-section { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 22px; |
| | | border: 1.5px solid #f00; |
| | | border-radius: 10px; |
| | | padding: 14px 22px; |
| | | background: #fff; |
| | | gap: 14px; |
| | | flex: 0 0 auto; |
| | | } |
| | | |
| | | .current-user-name { |
| | | font-weight: bold; |
| | | font-size: 22px; |
| | | } |
| | | |
| | | /* 选人按钮 - 蓝色主题,与报工界面保持一致 */ |
| | | .select-user-btn { |
| | | background: #00a2e9; |
| | | color: #fff; |
| | | border: none; |
| | | padding: 12px 22px; |
| | | border-radius: 12px; |
| | | font-size: 22px; |
| | | cursor: pointer; |
| | | transition: background 0.15s; |
| | | height: 66px; |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .select-user-btn:hover { |
| | | background: #008ac2; |
| | | } |
| | | |
| | | /* 调机数量输入区域 */ |
| | | .tiaoji-input-section { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 14px; |
| | | font-size: 22px; |
| | | } |
| | | |
| | | .tiaoji-input { |
| | | width: 200px; |
| | | max-width: 100%; |
| | | height: 66px; |
| | | border: 2px solid #808080; |
| | | font-size: 28px; |
| | | text-align: center; |
| | | border-radius: 8px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | /* 送检呼叫按钮 - 与报工界面的确认提交按钮保持一致 */ |
| | | .details-btn { |
| | | padding: 12px 34px; |
| | | background: #00a2e9; |
| | | color: #fff; |
| | | font-size: 32px; |
| | | border: none; |
| | | cursor: pointer; |
| | | border-radius: 12px; |
| | | height: 66px; |
| | | min-width: 180px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | line-height: 1.1; |
| | | box-sizing: border-box; |
| | | transition: background 0.15s; |
| | | } |
| | | |
| | | .details-btn:hover { |
| | | background: #008ac2; |
| | | } |
| | | |
| | | .details-btn:disabled { |
| | | opacity: 0.6; |
| | | cursor: not-allowed; |
| | | background: #bae7ff; |
| | | } |
| | | |
| | | .tiaoji-submit-section { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* 选人弹窗样式 - 与报工界面保持一致 */ |
| | | .overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: rgba(0,0,0,.45); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .user-select-popup { |
| | | background: #fff; |
| | | width: 1600px; |
| | | max-width: 99vw; |
| | | min-width: 1000px; |
| | | height: auto; |
| | | min-height: 520px; |
| | | padding: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | font-size: 32px; |
| | | border-radius: 12px; |
| | | box-shadow: 0 8px 32px rgba(0,0,0,0.12); |
| | | z-index: 1001; |
| | | } |
| | | |
| | | .user-search-bar { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 18px; |
| | | padding: 24px 64px 0 64px; |
| | | background: #fff; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .user-search-input { |
| | | flex: 1 1 260px; |
| | | padding: 16px 20px; |
| | | font-size: 28px; |
| | | border: 1px solid #bbb; |
| | | border-radius: 8px; |
| | | outline: none; |
| | | height: 54px; |
| | | } |
| | | |
| | | .user-search-input:focus { |
| | | border-color: #007aff; |
| | | box-shadow: 0 0 0 2px rgba(0,122,255,.15); |
| | | } |
| | | |
| | | .user-search-clear { |
| | | padding: 12px 28px; |
| | | background: #ff9f43; |
| | | color: #fff; |
| | | border: none; |
| | | border-radius: 8px; |
| | | font-size: 24px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .user-search-clear:hover { |
| | | background: #ff8920; |
| | | } |
| | | |
| | | .user-search-info { |
| | | font-size: 22px; |
| | | color: #555; |
| | | } |
| | | |
| | | .user-list-scroll { |
| | | flex: 1 1 auto; |
| | | overflow-y: auto; |
| | | padding: 32px 64px 0 64px; |
| | | } |
| | | |
| | | .user-list-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); |
| | | gap: 22px 22px; |
| | | } |
| | | |
| | | .user-list-btn { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | gap: 2px; |
| | | padding: 10px 10px; |
| | | height: 100px; |
| | | font-size: 30px; |
| | | background: #00a2e9; |
| | | color: #fff; |
| | | border: none; |
| | | border-radius: 8px; |
| | | cursor: pointer; |
| | | box-sizing: border-box; |
| | | word-break: break-word; |
| | | } |
| | | |
| | | .user-list-btn .user-code { |
| | | font-weight: 700; |
| | | font-size: 36px; |
| | | line-height: 1.1; |
| | | } |
| | | |
| | | .user-list-btn .user-name { |
| | | font-size: 32px; |
| | | line-height: 1.1; |
| | | } |
| | | |
| | | .user-list-btn.selected { |
| | | background: #0072c9; |
| | | box-shadow: 0 0 0 3px rgba(255,255,255,.6) inset; |
| | | } |
| | | |
| | | .user-list-btn:hover { |
| | | background: #008ed0; |
| | | } |
| | | |
| | | .no-user-result { |
| | | padding: 40px 0; |
| | | text-align: center; |
| | | font-size: 28px; |
| | | color: #666; |
| | | } |
| | | |
| | | .user-popup-footer { |
| | | flex-shrink: 0; |
| | | padding: 24px 64px 32px 64px; |
| | | background: #fff; |
| | | text-align: center; |
| | | } |
| | | |
| | | .clean-btn { |
| | | width: 24%; |
| | | padding: 10px 0; |
| | | color: #fff; |
| | | font-size: 20px; |
| | | border: none; |
| | | text-align: center; |
| | | cursor: pointer; |
| | | border-radius: 0.6vw; |
| | | background: #007aff; |
| | | } |
| | | |
| | | .clean-btn.wide-btn { |
| | | width: 30%; |
| | | font-size: 22px; |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | .clean-btn:hover { |
| | | background: #0062c9; |
| | | } |
| | | </style> |