前端:增加批次管理与旧数据纳入
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="纳入测试批次"
|
||||
width="min(820px, 94vw)"
|
||||
top="5vh"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
:close-on-click-modal="!submitting"
|
||||
:close-on-press-escape="!submitting"
|
||||
:show-close="!submitting"
|
||||
:before-close="beforeClose"
|
||||
@closed="resetState"
|
||||
>
|
||||
<el-alert
|
||||
title="将所选正式数据及其关联闭包纳入测试批次。请先核对完整预览,再输入批次全名确认。"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb8"
|
||||
/>
|
||||
<el-alert v-if="errorMessage" :title="errorMessage" type="error" :closable="false" show-icon class="mb8" />
|
||||
|
||||
<el-form label-width="100px" @submit.prevent>
|
||||
<el-form-item label="目标批次">
|
||||
<el-select v-model="batchId" :loading="batchLoading" :disabled="batchLoading || previewLoading || submitting" placeholder="暂无可用测试批次" @change="handleBatchChange">
|
||||
<el-option v-for="item in activeBatches" :key="item.batchId" :label="`${item.batchName} (${item.batchCode})`" :value="item.batchId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择数量">
|
||||
<span>{{ roots[0]?.resourceIds.length || 0 }} 条 {{ rootType }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-skeleton v-if="previewLoading" :rows="5" animated />
|
||||
<el-empty v-else-if="!preview && !errorMessage && !batchLoading" description="暂无可预览的范围" :image-size="72" />
|
||||
<template v-else-if="preview">
|
||||
<el-descriptions :column="2" border size="small" class="mb8">
|
||||
<el-descriptions-item label="目标批次">{{ preview.batchName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="影响总数">{{ preview.totalCount }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-table :data="preview.impacts" size="small" max-height="280" empty-text="无受影响数据">
|
||||
<el-table-column label="分类" prop="label" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="数量" prop="count" width="88" align="right" />
|
||||
<el-table-column label="全部编号" min-width="300">
|
||||
<template #default="scope">
|
||||
<span class="impact-keys">{{ (scope.row.keys || []).join(', ') || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-form label-width="100px" class="confirm-form" @submit.prevent>
|
||||
<el-form-item label="批次全名">
|
||||
<el-input v-model="batchName" :disabled="submitting" :placeholder="`请输入 ${preview.batchName}`" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :disabled="submitting" @click="close">取消</el-button>
|
||||
<el-button type="primary" :loading="previewLoading" :disabled="batchLoading || previewLoading || submitting || !batchId" @click="requestPreview">重新预览</el-button>
|
||||
<el-button type="danger" :loading="submitting" :disabled="!canExecute" @click="execute">确认纳入</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { listAvailableTestBatches, previewTestBatchAdoption, executeTestBatchAdoption } from '@/api/system/testBatch'
|
||||
|
||||
const props = defineProps({
|
||||
rootType: { type: String, required: true },
|
||||
resourceIds: { type: Array, required: true }
|
||||
})
|
||||
const emit = defineEmits(['success'])
|
||||
const { proxy } = getCurrentInstance()
|
||||
const visible = ref(false)
|
||||
const batchLoading = ref(false)
|
||||
const previewLoading = ref(false)
|
||||
const submitting = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const activeBatches = ref([])
|
||||
const batchId = ref(undefined)
|
||||
const preview = ref(null)
|
||||
const previewToken = ref('')
|
||||
const batchName = ref('')
|
||||
let requestVersion = 0
|
||||
|
||||
const roots = computed(() => [{
|
||||
resourceType: props.rootType,
|
||||
resourceIds: [...new Set(props.resourceIds.map(Number).filter((id) => Number.isInteger(id) && id > 0))]
|
||||
}])
|
||||
const canExecute = computed(() => Boolean(
|
||||
preview.value && previewToken.value && batchName.value === preview.value.batchName && !previewLoading.value && !submitting.value
|
||||
))
|
||||
|
||||
function invalidatePreview() {
|
||||
requestVersion += 1
|
||||
previewLoading.value = false
|
||||
preview.value = null
|
||||
previewToken.value = ''
|
||||
batchName.value = ''
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
invalidatePreview()
|
||||
batchLoading.value = false
|
||||
submitting.value = false
|
||||
errorMessage.value = ''
|
||||
activeBatches.value = []
|
||||
batchId.value = undefined
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (!submitting.value) visible.value = false
|
||||
}
|
||||
|
||||
function beforeClose(done) {
|
||||
if (submitting.value) return
|
||||
done()
|
||||
}
|
||||
|
||||
function normalizePreview(data) {
|
||||
return {
|
||||
batchName: data.batchName,
|
||||
totalCount: data.totalCount,
|
||||
impacts: Array.isArray(data.impacts) ? data.impacts : []
|
||||
}
|
||||
}
|
||||
|
||||
function requestPreview() {
|
||||
if (!batchId.value || !roots.value[0].resourceIds.length || previewLoading.value || submitting.value) {
|
||||
if (!roots.value[0].resourceIds.length) errorMessage.value = '请至少选择一条有效数据'
|
||||
return
|
||||
}
|
||||
invalidatePreview()
|
||||
const currentVersion = ++requestVersion
|
||||
const targetBatchId = batchId.value
|
||||
previewLoading.value = true
|
||||
errorMessage.value = ''
|
||||
previewTestBatchAdoption(targetBatchId, { roots: roots.value }).then((response) => {
|
||||
if (currentVersion !== requestVersion || targetBatchId !== batchId.value) return
|
||||
const data = response.data || {}
|
||||
if (!data.previewToken || !data.batchName) throw new Error('预览响应不完整')
|
||||
preview.value = normalizePreview(data)
|
||||
previewToken.value = data.previewToken
|
||||
}).catch(() => {
|
||||
if (currentVersion !== requestVersion || targetBatchId !== batchId.value) return
|
||||
invalidatePreview()
|
||||
errorMessage.value = '预览已失效或目标批次不可用,请重新预览'
|
||||
}).finally(() => {
|
||||
if (currentVersion === requestVersion && targetBatchId === batchId.value) previewLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleBatchChange() {
|
||||
invalidatePreview()
|
||||
requestPreview()
|
||||
}
|
||||
|
||||
function loadBatches() {
|
||||
batchLoading.value = true
|
||||
errorMessage.value = ''
|
||||
return listAvailableTestBatches().then((response) => {
|
||||
activeBatches.value = (Array.isArray(response.data) ? response.data : []).filter((item) => item.status === 'ACTIVE')
|
||||
batchId.value = activeBatches.value[0]?.batchId
|
||||
if (!batchId.value) {
|
||||
errorMessage.value = '暂无可用测试批次'
|
||||
return
|
||||
}
|
||||
requestPreview()
|
||||
}).catch(() => {
|
||||
activeBatches.value = []
|
||||
batchId.value = undefined
|
||||
errorMessage.value = '测试批次加载失败,请稍后重试'
|
||||
}).finally(() => {
|
||||
batchLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function open() {
|
||||
if (!roots.value[0].resourceIds.length) {
|
||||
proxy.$modal.msgWarning('请至少选择一条有效数据')
|
||||
return
|
||||
}
|
||||
resetState()
|
||||
visible.value = true
|
||||
loadBatches()
|
||||
}
|
||||
|
||||
function execute() {
|
||||
if (!preview.value || batchName.value !== preview.value.batchName || !canExecute.value || submitting.value) return
|
||||
const targetBatchId = batchId.value
|
||||
const token = previewToken.value
|
||||
submitting.value = true
|
||||
errorMessage.value = ''
|
||||
executeTestBatchAdoption(targetBatchId, { roots: roots.value, batchName: batchName.value, previewToken: previewToken.value }).then((response) => {
|
||||
proxy.$modal.msgSuccess(response.msg || '数据已纳入测试批次')
|
||||
visible.value = false
|
||||
emit('success')
|
||||
}).catch(() => {
|
||||
if (targetBatchId !== batchId.value || token !== previewToken.value) return
|
||||
invalidatePreview()
|
||||
errorMessage.value = '预览令牌已失效或目标批次已关闭,请重新预览'
|
||||
}).finally(() => {
|
||||
submitting.value = false
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => props.resourceIds, () => {
|
||||
if (visible.value) invalidatePreview()
|
||||
}, { deep: true })
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.impact-keys { display: block; overflow-wrap: anywhere; white-space: normal; }
|
||||
.confirm-form { margin-top: 12px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user