| | |
| | | color="#999"></up-icon> |
| | | </view> |
| | | </view> |
| | | <!-- 检验状态筛选 --> |
| | | <view class="filter-row"> |
| | | <view class="filter-item" |
| | | @click="showStateSheet = true"> |
| | | <text class="filter-label">检验状态</text> |
| | | <text class="filter-value">{{ stateFilterLabel }}</text> |
| | | <up-icon name="arrow-down" |
| | | size="14" |
| | | color="#999"></up-icon> |
| | | </view> |
| | | </view> |
| | | <!-- 日期选择 --> |
| | | <!-- <view class="date-range" |
| | | v-if="searchForm.entryDate"> |
| | |
| | | <u-tag :type="getStateTagType(item.inspectState)" |
| | | size="mini" |
| | | class="status-tag"> |
| | | {{ item.inspectState ? '已提交' : '未提交' }} |
| | | {{ item.inspectState ? '已提交' : '待提交' }} |
| | | </u-tag> |
| | | </view> |
| | | </view> |
| | |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | | <text class="detail-value">{{ item.checkCompany || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ item.qualifiedQuantity != null ? item.qualifiedQuantity : '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ item.unqualifiedQuantity != null ? item.unqualifiedQuantity : '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检验结论</text> |
| | | <text class="detail-value">{{ item.checkResult || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 操作按钮 --> |
| | |
| | | :disabled="item.inspectState || item.checkName !== ''" |
| | | @click.stop="assignInspector(item)"> |
| | | 分配检验员 |
| | | </u-button> |
| | | </view> |
| | | <view class="action-buttons"> |
| | | <u-button type="error" |
| | | size="small" |
| | | class="action-btn" |
| | | :disabled="!(Number(item.unqualifiedQuantity) > 0)" |
| | | @click.stop="openUnqualified(item)"> |
| | | 不合格处理 |
| | | </u-button> |
| | | </view> |
| | | </view> |
| | |
| | | :actions="userSheetOptions" |
| | | @select="selectInspector" |
| | | title="选择检验员" /> |
| | | <!-- 检验状态筛选 --> |
| | | <up-action-sheet :show="showStateSheet" |
| | | :actions="stateSheetOptions" |
| | | @select="selectState" |
| | | @close="showStateSheet = false" |
| | | title="选择检验状态" /> |
| | | <!-- 不合格处理弹窗 --> |
| | | <up-popup v-model:show="showUnqualifiedPopup" |
| | | mode="bottom" |
| | | round> |
| | | <view class="unqualified-dialog"> |
| | | <view class="dialog-header"> |
| | | <text class="dialog-title">不合格处理</text> |
| | | <up-icon name="close" |
| | | size="20" |
| | | color="#999" |
| | | @click="showUnqualifiedPopup = false"></up-icon> |
| | | </view> |
| | | <view class="dialog-content"> |
| | | <view v-if="unqualifiedLoading" |
| | | class="unqualified-empty">加载中...</view> |
| | | <view v-else-if="unqualifiedList.length === 0" |
| | | class="unqualified-empty">暂无待处理不合格记录</view> |
| | | <view v-for="(row, idx) in unqualifiedList" |
| | | :key="idx" |
| | | class="unqualified-item"> |
| | | <view class="unqualified-info"> |
| | | <text class="unqualified-label">不合格现象</text> |
| | | <text class="unqualified-value">{{ row.defectivePhenomena || '-' }}</text> |
| | | </view> |
| | | <view class="unqualified-info"> |
| | | <text class="unqualified-label">数量</text> |
| | | <text class="unqualified-value">{{ row.quantity != null ? row.quantity : '-' }}</text> |
| | | </view> |
| | | <u-button type="primary" |
| | | size="small" |
| | | class="unqualified-btn" |
| | | @click="openDealSheet(row)"> |
| | | 处理 |
| | | </u-button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </up-popup> |
| | | <!-- 处理结果选择 --> |
| | | <up-action-sheet :show="showDealSheet" |
| | | :actions="dealSheetOptions" |
| | | @select="selectDeal" |
| | | @close="showDealSheet = false" |
| | | title="选择处理结果" /> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | submitQualityInspect, |
| | | qualityInspectUpdate, |
| | | qualityInspectListPage, |
| | | qualityUnqualifiedListPage, |
| | | qualityUnqualifiedDeal, |
| | | } from "@/api/qualityManagement/materialInspection.js"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | |
| | | // 原料检验 inspectType=0 |
| | | const currentInspectType = 0; |
| | | |
| | | // 显示提示信息 |
| | | const showToast = message => { |
| | |
| | | value: item.nickName, |
| | | })); |
| | | }); |
| | | |
| | | // 检验状态筛选 |
| | | const showStateSheet = ref(false); |
| | | const stateFilter = ref(""); |
| | | const stateSheetOptions = [ |
| | | { name: "全部", value: "" }, |
| | | { name: "待提交", value: 0 }, |
| | | { name: "已提交", value: 1 }, |
| | | ]; |
| | | const stateFilterLabel = computed(() => { |
| | | const hit = stateSheetOptions.find(o => o.value === stateFilter.value); |
| | | return hit ? hit.name : "全部"; |
| | | }); |
| | | const selectState = e => { |
| | | stateFilter.value = e.value; |
| | | showStateSheet.value = false; |
| | | getList(); |
| | | }; |
| | | |
| | | // 不合格处理相关 |
| | | const showUnqualifiedPopup = ref(false); |
| | | const unqualifiedLoading = ref(false); |
| | | const unqualifiedList = ref([]); |
| | | const currentInspectRow = ref(null); |
| | | const showDealSheet = ref(false); |
| | | const currentUnqualifiedRow = ref(null); |
| | | // 原料类仅支持 报废/让步放行 |
| | | const dealSheetOptions = computed(() => { |
| | | return ["报废", "让步放行"].map(name => ({ name, value: name })); |
| | | }); |
| | | |
| | | // 打开不合格处理弹窗:按检验单id拉取待处理不合格记录 |
| | | const openUnqualified = async item => { |
| | | currentInspectRow.value = item; |
| | | showUnqualifiedPopup.value = true; |
| | | unqualifiedLoading.value = true; |
| | | unqualifiedList.value = []; |
| | | try { |
| | | const res = await qualityUnqualifiedListPage({ |
| | | inspectType: currentInspectType, |
| | | inspectState: 0, |
| | | inspectId: item.id, |
| | | current: -1, |
| | | size: -1, |
| | | }); |
| | | let records = res.data?.records || res.data || []; |
| | | // 若后端未按检验单过滤,前端兜底按检验单id过滤 |
| | | const hasInspectRef = records.some( |
| | | r => r.inspectId != null || r.qualityInspectId != null |
| | | ); |
| | | if (hasInspectRef) { |
| | | records = records.filter( |
| | | r => (r.inspectId ?? r.qualityInspectId) == item.id |
| | | ); |
| | | } |
| | | // 只保留待处理记录 |
| | | unqualifiedList.value = records.filter( |
| | | r => Number(r.inspectState) !== 1 |
| | | ); |
| | | } catch (error) { |
| | | // request.ts 已统一 toast 后端 msg,这里只记录 |
| | | console.error("获取不合格记录失败:", error); |
| | | unqualifiedList.value = []; |
| | | } finally { |
| | | unqualifiedLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // 打开处理结果选择 |
| | | const openDealSheet = row => { |
| | | currentUnqualifiedRow.value = row; |
| | | showDealSheet.value = true; |
| | | }; |
| | | |
| | | // 选择处理结果 |
| | | const selectDeal = e => { |
| | | showDealSheet.value = false; |
| | | if (!currentUnqualifiedRow.value) return; |
| | | doDeal(currentUnqualifiedRow.value, e.value); |
| | | }; |
| | | |
| | | // 提交不合格处理 |
| | | const doDeal = async (row, dealResult) => { |
| | | try { |
| | | await qualityUnqualifiedDeal({ id: row.id, dealResult }); |
| | | showToast("处理成功"); |
| | | if (currentInspectRow.value) { |
| | | await openUnqualified(currentInspectRow.value); |
| | | } |
| | | if (unqualifiedList.value.length === 0) { |
| | | showUnqualifiedPopup.value = false; |
| | | } |
| | | getList(); |
| | | } catch (error) { |
| | | // request.ts 已统一 toast 后端 msg,这里只记录 |
| | | console.error("不合格处理失败:", error); |
| | | } |
| | | }; |
| | | |
| | | // 返回上一页 |
| | | const goBack = () => { |
| | |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page.value }; |
| | | params.entryDate = undefined; |
| | | qualityInspectListPage({ ...params, inspectType: 0 }) |
| | | params.inspectState = |
| | | stateFilter.value === "" ? undefined : stateFilter.value; |
| | | qualityInspectListPage({ ...params, inspectType: currentInspectType }) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | inspectionList.value = res.data.records || []; |
| | |
| | | }; |
| | | |
| | | // 提交检验 |
| | | const submitInspection = async item => { |
| | | const submitInspection = item => { |
| | | if (!item) { |
| | | showToast("参数错误"); |
| | | return; |
| | | } |
| | | try { |
| | | const res = await submitQualityInspect({ id: item.id }); |
| | | if (res.code === 200) { |
| | | showToast("提交成功"); |
| | | setTimeout(() => { |
| | | getList(); |
| | | }, 1000); |
| | | } else { |
| | | showToast("提交失败:" + (res.msg || "未知错误")); |
| | | } |
| | | } catch (error) { |
| | | console.error("提交失败:", error); |
| | | showToast("提交失败,请重试"); |
| | | } |
| | | uni.showModal({ |
| | | title: "提示", |
| | | content: "提交后将生成入库记录且不可修改,是否继续?", |
| | | success: async res => { |
| | | if (!res.confirm) return; |
| | | try { |
| | | await submitQualityInspect({ id: item.id }); |
| | | showToast( |
| | | "提交成功,合格部分已生成入库记录(待审核),不合格部分已生成处理单" |
| | | ); |
| | | setTimeout(() => { |
| | | getList(); |
| | | }, 1500); |
| | | } catch (error) { |
| | | // request.ts 已统一 toast 后端 msg,这里只记录 |
| | | console.error("提交失败:", error); |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // 分配检验员 |
| | |
| | | padding: 5px; |
| | | } |
| | | |
| | | // 检验状态筛选 |
| | | .filter-row { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .filter-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 4px 10px; |
| | | background: #f2f3f5; |
| | | border-radius: 12px; |
| | | } |
| | | |
| | | .filter-label { |
| | | font-size: 12px; |
| | | color: #666; |
| | | margin-right: 4px; |
| | | } |
| | | |
| | | .filter-value { |
| | | font-size: 12px; |
| | | color: #2979ff; |
| | | margin-right: 4px; |
| | | } |
| | | |
| | | // 不合格处理弹窗 |
| | | .unqualified-dialog { |
| | | background: #ffffff; |
| | | border-radius: 16px 16px 0 0; |
| | | padding: 20px; |
| | | max-height: 70vh; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .unqualified-empty { |
| | | padding: 30px 0; |
| | | text-align: center; |
| | | font-size: 13px; |
| | | color: #999; |
| | | } |
| | | |
| | | .unqualified-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 12px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .unqualified-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .unqualified-label { |
| | | font-size: 12px; |
| | | color: #999; |
| | | } |
| | | |
| | | .unqualified-value { |
| | | font-size: 13px; |
| | | color: #333; |
| | | margin-top: 2px; |
| | | } |
| | | |
| | | .unqualified-btn { |
| | | width: 70px; |
| | | } |
| | | |
| | | // 统计卡片 |
| | | .stats-cards { |
| | | display: flex; |