221 lines
7.8 KiB
Vue
221 lines
7.8 KiB
Vue
<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>
|