From 346a988f537228ae44731cd31007f1412b482e83 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 19 十月 2026 16:32:10 +0800
Subject: [PATCH] refactor(mdm): 移除物料主数据中废弃的字段配置
---
src/views/mes/qc/seedQuality/record.vue | 155 +++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 124 insertions(+), 31 deletions(-)
diff --git a/src/views/mes/qc/seedQuality/record.vue b/src/views/mes/qc/seedQuality/record.vue
index a03ccd8..15396a1 100644
--- a/src/views/mes/qc/seedQuality/record.vue
+++ b/src/views/mes/qc/seedQuality/record.vue
@@ -10,12 +10,16 @@
getSeedQualityPage,
getSeedQualityIndicators,
getSeedQualityActions,
+ getSeedIndicatorRanges,
retestSeedQuality,
+ resolveSeedRetestScope,
+ submitSeedRetestScope,
approveSeedQuality,
approveSeedQualityBatch,
type SeedQualityRecord,
type SeedQualityIndicator,
type SeedQualityAction,
+ type SeedRetestScope,
} from '#/api/mes/qc/seedQuality';
const records = ref<SeedQualityRecord[]>([]);
@@ -37,13 +41,13 @@
);
const { hasAccessByCodes } = useAccess();
const workflowLabels: Record<number, string> = {
- 10: '寰呭妫�', 20: '寰呭姞宸ラ儴瀹℃壒', 30: '寰呭叕鍙歌川妫�瀹℃壒',
- 40: '宸叉斁琛�', 50: '寰呭姞宸ラ儴涓嶅悎鏍艰瘎瀹�', 60: '寰呭叕鍙镐笉鍚堟牸瀹℃壒', 70: '宸叉姤搴�',
+ 10: '寰呭妫�', 20: '寰呭垵妫�瀹℃牳', 25: '寰呭垵妫�涓嶅悎鏍煎鐞�', 30: '寰呭妫�瀹℃牳',
+ 40: '宸叉斁琛�', 50: '鍒濇椹冲洖寰呴噸妫�', 60: '寰呭妫�涓嶅悎鏍煎鐞�', 70: '宸叉姤搴�',
};
const actionLabels: Record<string, string> = {
- INITIAL: '鍒濇', RETEST: '澶嶆', PROCESS_APPROVE: '鍔犲伐閮ㄩ�氳繃',
- PROCESS_REJECT: '鍔犲伐閮ㄩ┏鍥�', COMPANY_APPROVE: '鍏徃璐ㄦ閫氳繃',
- COMPANY_REJECT: '鍏徃璐ㄦ椹冲洖',
+ INITIAL: '鍒濇', INITIAL_RECHECK: '閲嶆柊鍒濇', RETEST: '澶嶆', PROCESS_APPROVE: '鍒濇瀹℃牳閫氳繃',
+ PROCESS_REJECT: '鍒濇瀹℃牳椹冲洖', COMPANY_APPROVE: '澶嶆瀹℃牳閫氳繃',
+ COMPANY_REJECT: '澶嶆瀹℃牳椹冲洖',
};
const indicatorLabels: Record<string, string> = {
purity: '绾害', cleanliness: '鍑�搴�', germination_rate: '鍙戣娊鐜�', moisture: '姘村垎',
@@ -73,6 +77,13 @@
const retestBusy = ref(false);
const retestIndicators = ref<SeedQualityIndicator[]>([]);
const retestReason = ref('');
+const scopeOpen = ref(false);
+const scopeType = ref<'PALLET' | 'BATCH'>('PALLET');
+const scopeCode = ref('');
+const retestScope = ref<SeedRetestScope>();
+const scopeStatus = ref<10 | 50>(10);
+const scopeBusy = ref(false);
+const scopeIds = computed(() => scopeStatus.value === 10 ? retestScope.value?.retestIds || [] : retestScope.value?.initialRecheckIds || []);
const reviewOpen = ref(false);
const reviewBusy = ref(false);
const reviewStage = ref<'process' | 'company'>('process');
@@ -84,7 +95,7 @@
const selectableStage = computed(() => {
if (!selectedRows.value.length) return undefined;
if (!selectedRows.value.every((record) => record.workflowStatus === selectedRows.value[0]?.workflowStatus)) return undefined;
- if (selectedRows.value.every((record) => [20, 50].includes(record.workflowStatus))) return 'process';
+ if (selectedRows.value.every((record) => [20, 25].includes(record.workflowStatus))) return 'process';
if (selectedRows.value.every((record) => [30, 60].includes(record.workflowStatus))) return 'company';
return undefined;
});
@@ -92,13 +103,65 @@
async function openRetest(record: SeedQualityRecord) {
activeRecord.value = record;
try {
- retestIndicators.value = await getSeedQualityIndicators(record.id);
+ const previous = await getSeedQualityIndicators(record.id);
+ const ranges = await getSeedIndicatorRanges().catch(() => []);
+ retestIndicators.value = previous.map((item) => {
+ const range = ranges.find((row) => row.indicatorCode === item.indicatorCode);
+ return { ...item, minValue: range ? Number(range.minValue) : Number(item.minValue), maxValue: range ? Number(range.maxValue) : Number(item.maxValue) };
+ });
if (retestIndicators.value.length !== 4) throw new Error('璐ㄦ鎸囨爣涓嶅畬鏁�');
+ retestIndicators.value = retestIndicators.value.map((item) => ({ ...item, value: undefined }));
retestReason.value = '';
retestOpen.value = true;
} catch (error) {
message.error((error as Error).message || '璇诲彇璐ㄦ鎸囨爣澶辫触');
}
+}
+function openScopeRetest() {
+ scopeOpen.value = true; retestScope.value = undefined; scopeCode.value = ''; retestReason.value = '';
+}
+async function identifyScope() {
+ if (!scopeCode.value.trim()) { message.warning('璇锋壂鎻忔垨杈撳叆鎵樼洏鐮� / 鐢熶骇鎵规鐮�'); return; }
+ scopeBusy.value = true; retestScope.value = undefined;
+ try {
+ const data = await resolveSeedRetestScope(scopeCode.value.trim(), scopeType.value);
+ if (!data.retestIds.length && !data.initialRecheckIds.length) {
+ const pending = [
+ data.pendingProcessCount ? `${data.pendingProcessCount} 鏉″緟鍒濇瀹℃牳鎴栦笉鍚堟牸澶勭悊` : '',
+ data.pendingCompanyCount ? `${data.pendingCompanyCount} 鏉″緟澶嶆瀹℃牳鎴栦笉鍚堟牸澶勭悊` : '',
+ ].filter(Boolean).join('銆�');
+ throw new Error(pending
+ ? `褰撳墠鑼冨洿鏈�${pending}锛岃鍏堝畬鎴愬搴斿鏍告垨澶勭悊`
+ : '褰撳墠鑼冨洿娌℃湁寰呭妫�鎴栧緟閲嶆柊鍒濇鐨勮鐮�');
+ }
+ retestScope.value = data; scopeStatus.value = data.retestIds.length ? 10 : 50;
+ const ranges = await getSeedIndicatorRanges().catch(() => []);
+ retestIndicators.value = Object.entries(indicatorLabels).map(([indicatorCode]) => {
+ const range = ranges.find((row) => row.indicatorCode === indicatorCode);
+ return { indicatorCode, value: undefined, minValue: range ? Number(range.minValue) : undefined as unknown as number,
+ maxValue: range ? Number(range.maxValue) : undefined as unknown as number };
+ });
+ retestReason.value = '';
+ } catch (error) { message.error((error as Error).message || '璇嗗埆澶辫触'); }
+ finally { scopeBusy.value = false; }
+}
+async function saveScopeRetest() {
+ if (!retestScope.value || !scopeIds.value.length) return;
+ if (retestIndicators.value.some(item => item.value === undefined || item.value === null || item.minValue === undefined || item.maxValue === undefined
+ || Number(item.minValue) < 0 || Number(item.maxValue) > 100 || Number(item.minValue) > Number(item.maxValue))) {
+ message.warning('璇峰~鍐欏洓椤规寚鏍囩殑瀹炴祴鍊间笌鏈鍚堟牸鑼冨洿'); return;
+ }
+ const passed = retestIndicators.value.every(item => Number(item.value) >= Number(item.minValue) && Number(item.value) <= Number(item.maxValue));
+ if (!passed && !retestReason.value.trim()) { message.warning('涓嶅悎鏍艰濉啓鍘熷洜'); return; }
+ scopeBusy.value = true;
+ try {
+ const result = await submitSeedRetestScope({ code: retestScope.value.code, scanType: retestScope.value.scanType, workflowStatus: scopeStatus.value,
+ qualityIds: scopeIds.value, reason: retestReason.value.trim(), indicators: retestIndicators.value.map(item => ({
+ code: item.indicatorCode, value: Number(item.value), minValue: Number(item.minValue), maxValue: Number(item.maxValue),
+ })) });
+ message.success(`宸插畬鎴� ${result.processedCount} 琚嬭川妫�`); scopeOpen.value = false; refreshAll();
+ } catch (error) { message.error((error as Error).message || '鎵归噺璐ㄦ澶辫触'); retestScope.value = undefined; }
+ finally { scopeBusy.value = false; }
}
async function saveRetest() {
const record = activeRecord.value;
@@ -106,27 +169,30 @@
if (retestIndicators.value.some((item) => item.value === null || item.value === undefined
|| item.minValue === null || item.minValue === undefined || item.maxValue === null || item.maxValue === undefined
|| Number(item.minValue) > Number(item.maxValue))) {
- message.warning('璇峰~鍐欏畬鏁寸殑瀹炴祴鍊煎強鏈夋晥涓婁笅闄�');
+ message.warning('璇峰~鍐欏畬鏁寸殑瀹炴祴鍊�');
return;
}
const passed = retestIndicators.value.every((item) =>
Number(item.value) >= Number(item.minValue) && Number(item.value) <= Number(item.maxValue));
if (!passed && !retestReason.value.trim()) {
- message.warning('澶嶆涓嶅悎鏍艰濉啓鍘熷洜');
+ message.warning('妫�楠屼笉鍚堟牸璇峰~鍐欏師鍥�');
return;
}
retestBusy.value = true;
try {
- await retestSeedQuality(record.id, {
- code: record.code,
+ const payload = {
reason: retestReason.value.trim(),
indicators: retestIndicators.value.map((item) => ({
code: item.indicatorCode, value: Number(item.value),
minValue: Number(item.minValue), maxValue: Number(item.maxValue),
})),
- });
- message.success(passed ? '澶嶆鍚堟牸锛屽緟鍔犲伐閮ㄥ鎵�' : '澶嶆涓嶅悎鏍硷紝寰呭姞宸ラ儴璇勫');
+ };
+ await retestSeedQuality(record.id, { ...payload, code: record.code });
+ message.success(record.workflowStatus === 50
+ ? passed ? '閲嶆柊鍒濇鍚堟牸锛屽緟鍒濇瀹℃牳' : '閲嶆柊鍒濇涓嶅悎鏍硷紝寰呬笉鍚堟牸澶勭悊'
+ : passed ? '澶嶆鍚堟牸锛屽緟澶嶆瀹℃牳' : '澶嶆涓嶅悎鏍硷紝寰呬笉鍚堟牸澶勭悊');
retestOpen.value = false;
+ selectedIds.value = [];
refreshAll();
} catch (error) {
message.error((error as Error).message || '澶嶆鎻愪氦澶辫触');
@@ -154,8 +220,8 @@
}
async function saveReview() {
if (!reviewIds.value.length) return;
- if (!reviewOpinion.value.trim()) {
- message.warning('璇峰~鍐欏鎵规剰瑙�');
+ if (!reviewApproved.value && !reviewOpinion.value.trim()) {
+ message.warning('椹冲洖鏃惰濉啓瀹℃壒鎰忚');
return;
}
reviewBusy.value = true;
@@ -254,7 +320,7 @@
<div class="header-copy">
<div class="eyebrow">MES / 璐ㄩ噺绠$悊</div>
<h1>璐ㄦ璁板綍</h1>
- <p>璺熻釜鍒濇銆佸妫�銆佸姞宸ラ儴瀹℃壒鍜屽叕鍙歌川妫�瀹℃壒锛涘畬鎴愬鎵瑰悗鎵嶆祦杞簱瀛�</p>
+ <p>鍒濇瀹℃牳閫氳繃鍚庤繘琛屽妫�锛屽妫�瀹℃牳閫氳繃鍚庢墠鏀捐鍏ュ簱鎴栧缃笉鍚堟牸鍝�</p>
</div>
<div class="header-badge">
<span class="badge-pulse" />
@@ -291,7 +357,8 @@
<span class="count-chip">{{ total.toLocaleString() }} 鏉�</span>
</div>
<div class="filters">
- <a-button v-if="selectableStage && hasAccessByCodes([`mes:qc-seed-quality:${selectableStage === 'process' ? 'process-approve' : 'company-approve'}`])" @click="openBatchReview">鎵归噺{{ selectableStage === 'process' ? '鍔犲伐閮ㄥ鎵�' : '鍏徃璐ㄦ瀹℃壒' }}锛坽{ selectedRows.length }}锛�</a-button>
+ <a-button v-if="hasAccessByCodes(['mes:qc-seed-quality:retest'])" type="primary" @click="openScopeRetest">鎸夋墭鐩� / 鎵规鎵归噺澶嶆</a-button>
+ <a-button v-if="selectableStage && hasAccessByCodes([`mes:qc-seed-quality:${selectableStage === 'process' ? 'process-approve' : 'company-approve'}`])" @click="openBatchReview">鎵归噺{{ selectableStage === 'process' ? selectedRows[0]?.workflowStatus === 25 ? '鍒濇涓嶅悎鏍煎鐞�' : '鍒濇瀹℃牳' : selectedRows[0]?.workflowStatus === 60 ? '澶嶆涓嶅悎鏍煎鐞�' : '澶嶆瀹℃牳' }}锛坽{ selectedRows.length }}锛�</a-button>
<a-input v-model:value="code" allow-clear placeholder="琚嬬爜" @press-enter="searchRecords">
<template #prefix><IconifyIcon icon="ep:box" /></template>
</a-input>
@@ -320,7 +387,7 @@
:data-source="records"
:row-selection="{ selectedRowKeys: selectedIds, onChange: (keys: (string | number)[]) => { selectedIds = keys.map(Number); } }"
:loading="loading"
- :scroll="{ x: 1120 }"
+ :scroll="{ x: 1900 }"
:pagination="{
current: page,
pageSize,
@@ -343,6 +410,9 @@
</a-table-column>
<a-table-column key="code" title="琚嬬爜" data-index="code" min-width="220">
<template #default="{ record }"><span class="mono strong">{{ record.code }}</span></template>
+ </a-table-column>
+ <a-table-column key="palletCode" title="鎵樼洏鐮�" data-index="palletCode" min-width="190">
+ <template #default="{ record }"><span class="mono">{{ record.palletCode || '鈥�' }}</span></template>
</a-table-column>
<a-table-column key="batchCode" title="鐢熶骇鎵规" data-index="batchCode" min-width="190">
<template #default="{ record }">{{ record.batchCode || '鈥�' }}</template>
@@ -373,32 +443,53 @@
<a-table-column key="actions" title="鎿嶄綔" width="260" fixed="right">
<template #default="{ record }">
<a-space>
- <a-button v-if="record.workflowStatus === 10 && hasAccessByCodes(['mes:qc-seed-quality:retest'])" type="link" @click="openRetest(record)">澶嶆</a-button>
- <a-button v-if="[20, 50].includes(record.workflowStatus) && hasAccessByCodes(['mes:qc-seed-quality:process-approve'])" type="link" @click="openReview(record, 'process')">鍔犲伐閮ㄥ鎵�</a-button>
- <a-button v-if="[30, 60].includes(record.workflowStatus) && hasAccessByCodes(['mes:qc-seed-quality:company-approve'])" type="link" @click="openReview(record, 'company')">鍏徃璐ㄦ瀹℃壒</a-button>
+ <a-button v-if="[10, 50].includes(record.workflowStatus) && hasAccessByCodes(['mes:qc-seed-quality:retest'])" type="link" @click="openRetest(record)">{{ record.workflowStatus === 50 ? '閲嶆柊鍒濇' : '澶嶆' }}</a-button>
+ <a-button v-if="[20, 25].includes(record.workflowStatus) && hasAccessByCodes(['mes:qc-seed-quality:process-approve'])" type="link" @click="openReview(record, 'process')">{{ record.workflowStatus === 25 ? '涓嶅悎鏍煎鐞�' : '鍒濇瀹℃牳' }}</a-button>
+ <a-button v-if="[30, 60].includes(record.workflowStatus) && hasAccessByCodes(['mes:qc-seed-quality:company-approve'])" type="link" @click="openReview(record, 'company')">{{ record.workflowStatus === 60 ? '涓嶅悎鏍煎鐞�' : '澶嶆瀹℃牳' }}</a-button>
<a-button v-if="hasAccessByCodes(['mes:qc-seed-quality:query'])" type="link" @click="openHistory(record)">娴佺▼璁板綍</a-button>
</a-space>
</template>
</a-table-column>
</a-table>
</section>
- <a-modal v-model:open="retestOpen" title="绉嶅瓙璐ㄦ澶嶆" :confirm-loading="retestBusy" ok-text="鎻愪氦澶嶆" @ok="saveRetest">
- <p class="muted">琚嬬爜锛歿{ activeRecord?.code }}銆傚師鎸囨爣鑼冨洿宸插甫鍏ワ紝璇峰綍鍏ユ湰娆″疄娴嬪�煎苟鏍稿涓婁笅闄愩��</p>
+ <a-modal v-model:open="retestOpen" :title="activeRecord?.workflowStatus === 50 ? '閲嶆柊鍒濇' : '绉嶅瓙璐ㄦ澶嶆'" :confirm-loading="retestBusy" :ok-text="activeRecord?.workflowStatus === 50 ? '鎻愪氦鍒濇' : '鎻愪氦澶嶆'" @ok="saveRetest">
+ <p class="muted">琚嬬爜锛歿{ activeRecord?.code }}銆傚洓椤规寚鏍囦笌鍒濇涓�鑷达紱璇峰綍鍏ユ湰娆″疄娴嬪�煎苟鏍稿鍚堟牸鑼冨洿銆�</p>
<div v-for="item in retestIndicators" :key="item.indicatorCode" class="retest-row">
<strong>{{ indicatorLabels[item.indicatorCode] || item.indicatorCode }}</strong>
- <a-input-number v-model:value="item.value" :min="0" :precision="3" placeholder="瀹炴祴鍊�" />
- <a-input-number v-model:value="item.minValue" :min="0" :precision="3" placeholder="涓嬮檺" />
- <a-input-number v-model:value="item.maxValue" :min="0" :precision="3" placeholder="涓婇檺" />
+ <a-input-number v-model:value="item.value" :min="0" :precision="3" placeholder="鏈瀹炴祴鍊�" />
+ <a-input-number v-model:value="item.minValue" :min="0" :max="100" :precision="3" placeholder="涓嬮檺" />
+ <a-input-number v-model:value="item.maxValue" :min="0" :max="100" :precision="3" placeholder="涓婇檺" />
</div>
- <a-textarea v-model:value="retestReason" :rows="3" :maxlength="500" placeholder="澶嶆涓嶅悎鏍兼椂濉啓鍘熷洜" />
+ <a-textarea v-model:value="retestReason" :rows="3" :maxlength="500" placeholder="鏈妫�楠屼笉鍚堟牸鏃跺~鍐欏師鍥�" />
</a-modal>
- <a-modal v-model:open="reviewOpen" :title="reviewStage === 'process' ? '鍔犲伐閮ㄥ鎵�' : '鍏徃璐ㄦ瀹℃壒'" :confirm-loading="reviewBusy" ok-text="鎻愪氦瀹℃壒" @ok="saveReview">
+ <a-modal v-model:open="scopeOpen" title="鎸夋墭鐩� / 鐢熶骇鎵规鎵归噺澶嶆鎴栭噸鏂板垵妫�" :confirm-loading="scopeBusy" ok-text="鎻愪氦鏈樁娈靛叏閮ㄨ鐮�" :ok-button-props="{ disabled: !scopeIds.length }" @ok="saveScopeRetest">
+ <a-space class="scope-scan">
+ <a-select v-model:value="scopeType" style="width: 130px" :options="[{ label: '鎵樼洏鐮�', value: 'PALLET' }, { label: '鐢熶骇鎵规鐮�', value: 'BATCH' }]" @change="retestScope = undefined" />
+ <a-input-search v-model:value="scopeCode" placeholder="鎵弿鎴栬緭鍏ョ爜鍊�" enter-button="璇嗗埆" :loading="scopeBusy" @search="identifyScope" />
+ </a-space>
+ <template v-if="retestScope">
+ <p>宸茶瘑鍒� {{ retestScope.code }} 路 鏈夋晥琚� {{ retestScope.totalCount }} 路 鐢熶骇鎵规 {{ retestScope.batchCode || '鈥�' }}</p>
+ <a-radio-group v-model:value="scopeStatus">
+ <a-radio-button v-if="retestScope.retestIds.length" :value="10">澶嶆 {{ retestScope.retestIds.length }} 琚�</a-radio-button>
+ <a-radio-button v-if="retestScope.initialRecheckIds.length" :value="50">閲嶆柊鍒濇 {{ retestScope.initialRecheckIds.length }} 琚�</a-radio-button>
+ </a-radio-group>
+ <p class="muted">鍚屼竴缁勬寚鏍囧皢搴旂敤浜庢湰闃舵鍏ㄩ儴 {{ scopeIds.length }} 琚嬨�傛ā鏉胯寖鍥村彲浠ヤ慨鏀广��</p>
+ <div v-for="item in retestIndicators" :key="item.indicatorCode" class="retest-row">
+ <strong>{{ indicatorLabels[item.indicatorCode] }}</strong>
+ <a-input-number v-model:value="item.value" :min="0" :max="100" :precision="3" placeholder="瀹炴祴鍊�" />
+ <a-input-number v-model:value="item.minValue" :min="0" :max="100" :precision="3" placeholder="涓嬮檺" />
+ <a-input-number v-model:value="item.maxValue" :min="0" :max="100" :precision="3" placeholder="涓婇檺" />
+ </div>
+ <a-textarea v-model:value="retestReason" :rows="3" :maxlength="500" placeholder="涓嶅悎鏍兼椂濉啓鍘熷洜" />
+ </template>
+ </a-modal>
+ <a-modal v-model:open="reviewOpen" :title="[25, 60].includes(activeRecord?.workflowStatus ?? 0) ? '涓嶅悎鏍煎鐞�' : reviewStage === 'process' ? '鍒濇瀹℃牳' : '澶嶆瀹℃牳'" :confirm-loading="reviewBusy" ok-text="鎻愪氦瀹℃牳" @ok="saveReview">
<p>{{ reviewIds.length > 1 ? `鍏� ${reviewIds.length} 鏉¤褰昤 : activeRecord?.code }} 路 {{ workflowLabels[activeRecord?.workflowStatus ?? 0] }}</p>
<a-radio-group v-model:value="reviewApproved" class="review-choice">
- <a-radio :value="true">鍚屾剰{{ reviewStage === 'company' ? activeRecord?.workflowStatus === 30 ? '鏀捐鍏ュ簱' : '鎶ュ簾澶勭疆' : '涓婃姤鍏徃璐ㄦ' }}</a-radio>
- <a-radio :value="false">椹冲洖閲嶆</a-radio>
+ <a-radio :value="true">{{ reviewStage === 'process' ? activeRecord?.workflowStatus === 25 ? '纭涓嶅悎鏍硷紝瀹夋帓澶嶆' : '閫氳繃锛岃繘鍏ュ妫�' : activeRecord?.workflowStatus === 30 ? '閫氳繃锛屾斁琛屽叆搴�' : '纭涓嶅悎鏍硷紝鎶ュ簾澶勭疆' }}</a-radio>
+ <a-radio :value="false">{{ reviewStage === 'process' ? '椹冲洖锛岄噸鏂板垵妫�' : '椹冲洖锛岄噸鏂板妫�' }}</a-radio>
</a-radio-group>
- <a-textarea v-model:value="reviewOpinion" :rows="3" :maxlength="500" placeholder="璇峰~鍐欏鎵规剰瑙�" />
+ <a-textarea v-model:value="reviewOpinion" :rows="3" :maxlength="500" :placeholder="reviewApproved ? '瀹℃壒鎰忚锛堥�夊~锛�' : '璇峰~鍐欓┏鍥炴剰瑙�'" />
</a-modal>
<a-modal v-model:open="historyOpen" :title="`娴佺▼璁板綍 路 ${activeRecord?.code || ''}`" :footer="null">
<a-timeline v-if="historyActions.length">
@@ -458,6 +549,8 @@
.filters :deep(.ant-btn .iconify) { font-size: 14px; }
.retest-row { display: grid; grid-template-columns: 60px repeat(3, 1fr); gap: 8px; align-items: center; margin-bottom: 10px; }
.retest-row :deep(.ant-input-number) { width: 100%; }
+.scope-scan { display: flex; width: 100%; margin-bottom: 16px; }
+.scope-scan :deep(.ant-space-item:last-child) { flex: 1; }
.review-choice { display: flex; gap: 16px; margin: 10px 0 18px; }
/* ===== 鍗曞厓鏍� ===== */
--
Gitblit v1.9.3