| | |
| | | <template> |
| | | <div class="page"> |
| | | <!-- 右上角刷新 --> |
| | | <div class="top-right"> |
| | | <button class="refresh-btn" @click="refresh" :disabled="loading">刷新</button> |
| | | </div> |
| | | <view class="page"> |
| | | <!--调机送检--> |
| | | <!-- 右上角刷新按钮 --> |
| | | <view class="top-right"> |
| | | <button class="refresh-btn" @click="refresh">刷新</button> |
| | | </view> |
| | | |
| | | <!-- 状态区 --> |
| | | <div class="middle-section"> |
| | | <div class="item notice"> |
| | | <h4>说明:先点击调机开始,再点击送检呼叫;成功后两个按钮隐藏。首次首检合格后系统自动写入开工/调机完成时间。</h4> |
| | | </div> |
| | | |
| | | <!-- 调机开始 --> |
| | | <div class="item" v-if="showStartBtn"> |
| | | <button class="btn-blue" |
| | | @click="onStartClick" |
| | | :disabled="loading"> |
| | | 点击调机开始 |
| | | <!-- 中间状态部分,上下结构,包含调机流程的三个步骤 --> |
| | | <view class="middle-section"> |
| | | <view class="item" style="height: 100px;"> |
| | | <h4> |
| | | <!--说明: |
| | | 1.点击'调机开始'、'送检呼叫'后再点击'保存生效'<br /> |
| | | 2.主界面首检合格后再点击'保存生效'<br /> |
| | | 3.首检不合格再点击'保存生效'会清空送检时间<br /> |
| | | 4.清空送检时间后点击‘检验不合格重新送检呼叫’再保存--> |
| | | </h4> |
| | | </view> |
| | | <view class="item"> |
| | | <!-- 调机开始按钮,maStartTime有值时禁用 --> |
| | | <button :class="maStartTime ? 'btn-disabled' : 'btn-blue'" |
| | | :disabled="!!maStartTime" |
| | | @click="handleMaStartTime"> |
| | | 调机开始 |
| | | </button> |
| | | <input class="txt-inp" |
| | | v-model="maStartTime" |
| | | placeholder="点击后记录调机时间" |
| | | disabled /> |
| | | <div class="hint">说明:点击调机开始后,该按钮与送检按钮将根据后续操作隐藏。</div> |
| | | </div> |
| | | |
| | | <!-- 已开始但按钮隐藏时仍显示时间 --> |
| | | <div class="item" v-else> |
| | | <button class="btn-hidden" disabled>调机开始(已记录)</button> |
| | | <input class="txt-inp" v-model="maStartTime" disabled /> |
| | | </div> |
| | | |
| | | <!-- 送检呼叫 --> |
| | | <div class="item" v-if="showShoutBtn"> |
| | | <button class="btn-blue" |
| | | @click="onShoutClick" |
| | | :disabled="loading || !maStartTime"> |
| | | 点击送检呼叫 |
| | | <!-- 显示调机开始时间 --> |
| | | <input class="txt-inp" v-model="maStartTime" placeholder="点击按钮带出调机时间" disabled="true" /> |
| | | </view> |
| | | <view class="item"> |
| | | <!-- 送检呼叫按钮,maShoutTime有值时禁用 --> |
| | | <button :class="maShoutTime ? 'btn-disabled' : 'btn-blue'" |
| | | :disabled="!!maShoutTime" |
| | | @click="handleMaShoutTime"> |
| | | 送检呼叫 |
| | | </button> |
| | | <!-- 显示送检呼叫时间 --> |
| | | <input class="txt-inp" v-model="maShoutTime" placeholder="点击按钮带出送检时间" disabled="true" /> |
| | | </view> |
| | | <!--<view class="item">--> |
| | | <!-- 调机完成按钮,maEndTime有值时禁用 --> |
| | | <!--<button :class="maEndTime ? 'btn-disabled' : 'btn-blue'" |
| | | :disabled="!!maEndTime" |
| | | @click="handleMaEndTime"> |
| | | 调机完成(=检验通过) |
| | | </button>--> |
| | | <!-- 显示调机完成时间 --> |
| | | <!--<input class="txt-inp" v-model="maEndTime" placeholder="首次首检确认通过写入" disabled="true" /> |
| | | </view>--> |
| | | <view class="item"> |
| | | <button class="btn-disabled" disabled> |
| | | 调机完成(=检验通过=开工) |
| | | </button> |
| | | <input class="txt-inp" v-model="maEndTime" placeholder="首次首检确认通过写入" disabled="true" /> |
| | | </view> |
| | | |
| | | <!--启用该功能--> |
| | | <!--新增:检验不合格送检呼叫 按钮(功能与送检呼叫一样,仅在特定 remark 下可以点击)--> |
| | | <view class="item"> |
| | | <!--检验不合格送检呼叫按钮,仅在 remark 为指定文本 且 当前无送检时间 时可点击--> |
| | | <button :class="canFailResend ? 'btn-blue' : 'btn-disabled'" |
| | | :disabled="!canFailResend" |
| | | @click="ReHandleMaShoutTime"> |
| | | 检验不合格重新送检呼叫 |
| | | </button> |
| | | <!--仍复用同一送检时间字段,避免重复状态--> |
| | | <input class="txt-inp" |
| | | v-model="maShoutTime" |
| | | placeholder="点击按钮带出时间" |
| | | disabled /> |
| | | <div class="hint">说明:需先调机开始后才能送检。</div> |
| | | </div> |
| | | placeholder="首检不合格重新呼叫时点击按钮带出送检时间" |
| | | disabled="true" /> |
| | | </view> |
| | | |
| | | <!-- 已送检 --> |
| | | <div class="item" v-else> |
| | | <button class="btn-hidden" disabled>送检呼叫(已记录)</button> |
| | | <input class="txt-inp" v-model="maShoutTime" disabled /> |
| | | </div> |
| | | </view> |
| | | |
| | | <!-- 调机完成(首检OK自动写入) --> |
| | | <div class="item"> |
| | | <button class="btn-disabled" disabled> |
| | | 首检OK=调机完成=开工 |
| | | </button> |
| | | <input class="txt-inp" |
| | | v-model="maEndTime" |
| | | placeholder="首次首检确认OK后系统写入" |
| | | disabled /> |
| | | <div class="hint"> |
| | | 若首检通过,后端调用 QualifiedInspection 自动写入 MaEndTime 与 StartTime。 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 底部保存/取消按钮 --> |
| | | <view class="bottom-section"> |
| | | <!-- 只有调机完成未填写时才可保存 --> |
| | | <button class="save-btn" v-if="!maEndTime" @click="save">保存并生效</button> |
| | | <!-- 已完成时保存按钮禁用 --> |
| | | <button class="btn-disabled" v-else>保存并生效</button> |
| | | <button class="cancel-btn" @click="cancel">取消</button> |
| | | </view> |
| | | |
| | | <!-- 底部操作 --> |
| | | <div class="bottom-section"> |
| | | <button class="save-btn" |
| | | v-if="!maEndTime" |
| | | :disabled="loading || !statusForm.id" |
| | | @click="save"> |
| | | 保存并生效 |
| | | </button> |
| | | <button class="btn-disabled" |
| | | v-else |
| | | disabled> |
| | | 保存并生效 |
| | | </button> |
| | | |
| | | <button class="cancel-btn" :disabled="loading" @click="cancel"> |
| | | 取消 |
| | | </button> |
| | | </div> |
| | | |
| | | <div class="footer-info" v-if="error"> |
| | | <span class="error">{{ error }}</span> |
| | | </div> |
| | | </div> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'AdjustInspect', |
| | | props: { |
| | | orderNo: { type: String, required: true }, |
| | | orderId: { type: Number, required: true }, |
| | | machineNo: { type: String, required: true } |
| | | orderNo: String, // 工单号 |
| | | orderId: Number, // 工单ID |
| | | machineNo: String // 机台号 |
| | | }, |
| | | data() { |
| | | return { |
| | | maShoutTime: '', |
| | | maStartTime: '', |
| | | maEndTime: '', |
| | | statusForm: {}, |
| | | flag: -1, |
| | | loading: false, |
| | | error: '', |
| | | showStartBtn: true, |
| | | showShoutBtn: true |
| | | maShoutTime: '', // 送检呼叫时间 |
| | | maStartTime: '', // 调机开始时间 |
| | | maEndTime: '', // 调机完成时间 |
| | | statusForm: {}, // 工单状态表单数据(包含 remark 字段) |
| | | flag: -1, // 操作标记 |
| | | failedRemark: '首检不合格,送检时间已清空,请重新送检呼叫生成新的首检单' // 首检不合格后由后端返回的提示 |
| | | } |
| | | }, |
| | | computed: { |
| | | // 满足首检不合格重新呼叫条件且当前尚未重新生成送检时间 => 按钮可用 |
| | | canFailResend() { |
| | | return this.statusForm && |
| | | this.statusForm.remark === this.failedRemark && |
| | | !this.maShoutTime; |
| | | } |
| | | }, |
| | | created() { |
| | | this.loadStatus(); |
| | | // 组件创建时自动加载工单数据 |
| | | if (!this.orderId && !this.orderNo) { |
| | | return; |
| | | } |
| | | this.findByOrderId(); |
| | | }, |
| | | methods: { |
| | | formatNow() { |
| | | // 使用项目已有的日期工具 (若必须用 this.$getDate 保留) |
| | | return this.$getDate('yyyy-mm-dd hh24:mi:ss'); |
| | | }, |
| | | async loadStatus() { |
| | | this.loading = true; |
| | | this.error = ''; |
| | | try { |
| | | const res = await this.$post({ |
| | | url: '/MesOrderSta/FindByOrderNo', |
| | | data: { |
| | | orderId: this.orderId, |
| | | orderNo: this.orderNo |
| | | } |
| | | }); |
| | | const row = res.data.tbBillList || {}; |
| | | this.statusForm = row; |
| | | this.maStartTime = row.maStartTime || ''; |
| | | this.maShoutTime = row.maShoutTime || ''; |
| | | this.maEndTime = row.maEndTime || ''; |
| | | // 控制按钮显隐 |
| | | this.showStartBtn = !this.maStartTime; |
| | | this.showShoutBtn = !this.maShoutTime; |
| | | } catch (e) { |
| | | this.error = '加载工单状态失败:' + (e.message || e); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | refresh() { |
| | | this.loadStatus(); |
| | | }, |
| | | onStartClick() { |
| | | if (this.maStartTime) return; |
| | | this.maStartTime = this.formatNow(); |
| | | this.showStartBtn = false; |
| | | // flag 保持 -1,不触发自动首检逻辑 |
| | | this.flag = -1; |
| | | }, |
| | | onShoutClick() { |
| | | // 处理调机开始按钮点击 |
| | | handleMaStartTime() { |
| | | if (!this.maStartTime) { |
| | | this.$showMessage('请先点击调机开始'); |
| | | return; |
| | | this.setMaStartTime(); |
| | | this.flag = -1; // 调机开始按钮按下时回传的flag=-1 |
| | | } |
| | | if (this.maShoutTime) return; |
| | | this.maShoutTime = this.formatNow(); |
| | | this.showShoutBtn = false; |
| | | this.flag = -1; |
| | | }, |
| | | async save() { |
| | | // 处理送检呼叫按钮点击(不含首检不合格重呼叫) |
| | | handleMaShoutTime() { |
| | | if (!this.maShoutTime) { |
| | | this.stateCheck(1); |
| | | } |
| | | }, |
| | | // 首检不合格重呼叫:flag = 2 |
| | | ReHandleMaShoutTime() { |
| | | if (!this.maShoutTime && this.canFailResend) { |
| | | this.stateCheck(2); |
| | | } |
| | | }, |
| | | // 处理调机完成按钮点击 |
| | | handleMaEndTime() { |
| | | if (!this.maEndTime) { |
| | | this.setMaEndTime(); |
| | | } |
| | | }, |
| | | // 设置调机开始时间为当前时间 |
| | | setMaStartTime() { |
| | | this.maStartTime = this.$getDate('yyyy-mm-dd hh24:mi:ss'); |
| | | }, |
| | | // 设置调机完成时间为当前时间 |
| | | setMaEndTime() { |
| | | console.log('调机完成按钮被点击'); |
| | | this.maEndTime = this.$getDate('yyyy-mm-dd hh24:mi:ss'); |
| | | }, |
| | | // 刷新工单数据 |
| | | refresh() { |
| | | this.findByOrderId(); |
| | | }, |
| | | // 保存并生效,将时间等信息提交到后端 |
| | | save() { |
| | | if (!this.statusForm.id) { |
| | | this.$showMessage('ID为空,不允许推送'); |
| | | this.$showMessage("id为空,不允许推送"); |
| | | return; |
| | | } |
| | | this.loading = true; |
| | | this.error = ''; |
| | | try { |
| | | const res = await this.$post({ |
| | | url: '/MesOrderSta/ChangeMachineTime', |
| | | data: { |
| | | maStartTime: this.maStartTime, |
| | | maShoutTime: this.maShoutTime, |
| | | maEndTime: this.maEndTime, // 这里通常为空,后端首检通过后自动写入 |
| | | id: this.statusForm.id, |
| | | orderId: this.orderId, |
| | | machineNo: this.machineNo, |
| | | flag: this.flag |
| | | } |
| | | }); |
| | | this.$post({ |
| | | url: "/MesOrderSta/ChangeMachineTime", |
| | | data: { |
| | | maStartTime: this.maStartTime, |
| | | maShoutTime: this.maShoutTime, |
| | | maEndTime: this.maEndTime, |
| | | id: this.statusForm.id, |
| | | orderId: this.orderId, |
| | | machineNo: this.machineNo, |
| | | flag: this.flag |
| | | } |
| | | }).then(res => { |
| | | if (res.data.tbBillList) { |
| | | this.$showMessage('保存成功'); |
| | | await this.loadStatus(); |
| | | this.$showMessage("呼叫成功"); |
| | | this.findByOrderId(); |
| | | } else { |
| | | this.$showMessage('保存失败'); |
| | | this.$showMessage("呼叫失败"); |
| | | this.cancel(); |
| | | } |
| | | } catch (e) { |
| | | this.error = '保存异常:' + (e.message || e); |
| | | this.$showMessage('保存异常'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }) |
| | | }, |
| | | // 取消操作,恢复为上次保存的数据 |
| | | cancel() { |
| | | // 回退到上次加载状态 |
| | | this.maStartTime = this.statusForm.maStartTime || ''; |
| | | this.maShoutTime = this.statusForm.maShoutTime || ''; |
| | | this.maEndTime = this.statusForm.maEndTime || ''; |
| | | this.showStartBtn = !this.maStartTime; |
| | | this.showShoutBtn = !this.maShoutTime; |
| | | this.maShoutTime = this.statusForm.maShoutTime; |
| | | this.maStartTime = this.statusForm.maStartTime; |
| | | this.maEndTime = this.statusForm.maEndTime; |
| | | }, |
| | | // 送检呼叫,item=1时设置送检呼叫时间 |
| | | // 送检呼叫与重新送检呼叫以及调机开始对应的 flag 值 |
| | | // flag 说明:-1 = 调机开始;1 = 首次送检呼叫;2 = 不合格重新送检呼叫 |
| | | stateCheck(item) { |
| | | switch (item) { |
| | | case 0: |
| | | break; |
| | | case 1:// 首次送检呼叫 |
| | | this.maShoutTime = this.$getDate('yyyy-mm-dd hh24:mi:ss'); |
| | | this.flag = -1; // 送检呼叫有值后,flag始终为-1 |
| | | break; |
| | | case 2:// 检验不合格重新送检呼叫 |
| | | this.maShoutTime = this.$getDate('yyyy-mm-dd hh24:mi:ss'); |
| | | //this.flag = -1; // 送检呼叫有值后,flag始终为-1 |
| | | break; |
| | | default: |
| | | // 其它值不处理 |
| | | break; |
| | | } |
| | | this.flag = item; |
| | | }, |
| | | // 根据工单号/ID获取工单状态数据 |
| | | findByOrderId() { |
| | | this.$post({ |
| | | url: "/MesOrderSta/FindByOrderNo", |
| | | data: { |
| | | orderId: this.orderId, |
| | | orderNo: this.orderNo |
| | | } |
| | | }).then(res => { |
| | | this.statusForm = res.data.tbBillList; |
| | | this.maShoutTime = res.data.tbBillList.maShoutTime; |
| | | this.maStartTime = res.data.tbBillList.maStartTime; |
| | | this.maEndTime = res.data.tbBillList.maEndTime; |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 页面整体布局 */ |
| | | .page { |
| | | padding: 2vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | box-sizing: border-box; |
| | | height: 100%; |
| | | position: relative; |
| | | } |
| | | |
| | | /* 右上角刷新按钮 */ |
| | | .top-right { |
| | | position: absolute; |
| | | top: 10px; |
| | | right: 50px; |
| | | z-index: 10; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .refresh-btn { |
| | | padding: 10px; |
| | | background-color: #00A2E9; |
| | | color: #fff; |
| | | font-size: 1.2vw; |
| | | color: white; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | font-size: 1.5vw; |
| | | border-radius: 5px; |
| | | } |
| | | |
| | | label { |
| | | margin-right: 1vw; |
| | | font-size: 1.6vw; |
| | | } |
| | | |
| | | input { |
| | | padding: 1vh; |
| | | font-size: 1.5vw; |
| | | border: 1px solid #ccc; |
| | | width: 100%; |
| | | margin-top: 1vh; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | /* 中间状态部分布局 */ |
| | | .middle-section { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 18px; |
| | | margin-top: 60px; |
| | | margin-bottom: 4vh; |
| | | } |
| | | |
| | | .item { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: flex-start; |
| | | gap: 20px; |
| | | margin-bottom: 2vh; |
| | | } |
| | | |
| | | .item.notice { |
| | | height: auto; |
| | | } |
| | | |
| | | button { |
| | | width: 28%; |
| | | min-width: 200px; |
| | | padding: 14px; |
| | | font-size: 1.1vw; |
| | | width: 100%; |
| | | padding: 1.5vh; |
| | | font-size: 1.5vw; |
| | | border: none; |
| | | cursor: pointer; |
| | | border-radius: 4px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .btn-disabled { |
| | | background-color: #ccc; |
| | | color: white; |
| | | } |
| | | |
| | | .btn-blue { |
| | | background-color: #00A2E9; |
| | | color: #fff; |
| | | color: white; |
| | | } |
| | | |
| | | .btn-disabled { |
| | | background-color: #9d9d9d; |
| | | color: #fff; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .btn-hidden { |
| | | background-color: #d0d0d0; |
| | | color: #666; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .txt-inp { |
| | | flex: 1; |
| | | height: 54px; |
| | | input { |
| | | margin-top: 10px; |
| | | padding: 10px; |
| | | font-size: 1.0vw; |
| | | font-size: 14px; |
| | | border: 1px solid #ccc; |
| | | border-radius: 4px; |
| | | box-sizing: border-box; |
| | | width: 100%; |
| | | } |
| | | |
| | | .hint { |
| | | flex: 0 0 240px; |
| | | font-size: 0.9vw; |
| | | color: #b40000; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | /* 底部保存/取消按钮布局 */ |
| | | .bottom-section { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: auto; |
| | | gap: 20px; |
| | | padding-top: 30px; |
| | | margin-top: 4vh; |
| | | } |
| | | |
| | | .save-btn, |
| | | .cancel-btn { |
| | | width: 48%; |
| | | padding: 16px; |
| | | padding: 1.5vh; |
| | | background-color: #00A2E9; |
| | | color: #fff; |
| | | font-size: 1.2vw; |
| | | color: white; |
| | | font-size: 1.6vw; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | text-align: center; |
| | | } |
| | | |
| | | .save-btn:disabled, |
| | | .cancel-btn:disabled { |
| | | background-color: #7fbfdc; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .footer-info { |
| | | margin-top: 16px; |
| | | font-size: 0.9vw; |
| | | } |
| | | |
| | | .error { |
| | | color: #d40000; |
| | | .txt-inp { |
| | | height: 8vh; |
| | | padding: 1vh; |
| | | font-size: 1.5vw; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | </style> |