前端:增加批次管理与旧数据纳入
This commit is contained in:
@@ -2414,3 +2414,74 @@ test('业务用户分配组件使用固定映射并允许空数组完整替换',
|
||||
assert.match(source, /<el-alert\b[^>]*v-if="loadError"/)
|
||||
assert.match(source, /width="min\(720px, 92vw\)"/)
|
||||
})
|
||||
|
||||
test('测试批次管理与旧数据纳入遵守 root、权限和预览提交契约', async () => {
|
||||
const apiPath = 'src/api/system/testBatch.js'
|
||||
const apiSource = await readFile(path.join(frontendRoot, apiPath), 'utf8')
|
||||
const expectedTestBatchRequests = [
|
||||
{ url: "'/system/test-batch/options'", method: 'get' },
|
||||
{ url: "'/system/test-batch/list'", method: 'get' },
|
||||
{ url: "'/system/test-batch/' + batchId", method: 'get' },
|
||||
{ url: "'/system/test-batch'", method: 'post' },
|
||||
{ url: "'/system/test-batch/' + batchId", method: 'put' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/users'", method: 'put' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/close'", method: 'put' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/reopen'", method: 'put' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/adoption/preview'", method: 'post' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/adoption/execute'", method: 'post' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/purge/preview'", method: 'post' },
|
||||
{ url: "'/system/test-batch/' + batchId + '/purge'", method: 'post' }
|
||||
]
|
||||
assert.deepEqual(extractRequests(apiSource), expectedTestBatchRequests)
|
||||
|
||||
const adoptionRoots = {
|
||||
strain: { path: 'src/views/master/strain/index.vue', id: 'strainId' },
|
||||
customer: { path: 'src/views/master/customer/index.vue', id: 'customerId' },
|
||||
site: { path: 'src/views/master/site/index.vue', id: 'siteId' },
|
||||
line: { path: 'src/views/master/line/index.vue', id: 'lineId' },
|
||||
warehouse: { path: 'src/views/master/warehouse/index.vue', id: 'warehouseId' },
|
||||
pallet: { path: 'src/views/master/pallet/index.vue', id: 'palletId' },
|
||||
inbound: { path: 'src/views/business/inbound/index.vue', id: 'inboundId' },
|
||||
filling: { path: 'src/views/business/filling/index.vue', id: 'fillingId' },
|
||||
shipment: { path: 'src/views/business/shipment/index.vue', id: 'shipmentId' },
|
||||
usage: { path: 'src/views/business/usage/index.vue', id: 'usageId' },
|
||||
return: { path: 'src/views/business/return/index.vue', id: 'returnId' }
|
||||
}
|
||||
assert.equal(Object.keys(adoptionRoots).length, 11, '纳入来源必须固定为 11 类')
|
||||
for (const [rootType, contract] of Object.entries(adoptionRoots)) {
|
||||
const source = await readFile(path.join(frontendRoot, contract.path), 'utf8')
|
||||
assert.match(source, /import TestBatchAdoptionDialog from ['"]@\/components\/TestBatchAdoptionDialog['"]/)
|
||||
assert.match(source, /useUserStore\(\)/, `${rootType} 必须读取 admin 可见性`)
|
||||
assert.match(source, /useTestBatchStore\(\)/, `${rootType} 必须读取测试模式`)
|
||||
assert.match(source, /userStore\.admin === true\s*&&\s*!testBatchStore\.isTestMode/, `${rootType} 纳入入口必须只在管理员正式模式显示`)
|
||||
assert.match(source, new RegExp(`<test-batch-adoption-dialog\\b[\\s\\S]*?:root-type="['\"]${rootType}['\"][\\s\\S]*?:resource-ids="selectedIds"`))
|
||||
assert.match(source, new RegExp(`selectedIds\\.value\\s*=\\s*selection\\.map\\(\\(item\\)\\s*=>\\s*item\\.${contract.id}\\)`), `${rootType} 必须传递正整数根 ID`)
|
||||
}
|
||||
|
||||
for (const rootType of ['strain', 'customer', 'site', 'line', 'warehouse', 'pallet']) {
|
||||
const source = await readFile(path.join(frontendRoot, adoptionRoots[rootType].path), 'utf8')
|
||||
assert.match(source, /userStore\.admin === true\s*\|\|\s*!testBatchStore\.isTestMode/, `${rootType} 测试模式主数据写操作必须要求管理员`)
|
||||
}
|
||||
|
||||
const adoptionDialogPath = 'src/components/TestBatchAdoptionDialog/index.vue'
|
||||
const adoptionDialog = await readFile(path.join(frontendRoot, adoptionDialogPath), 'utf8')
|
||||
assert.match(adoptionDialog, /item\.status === ['"]ACTIVE['"]/)
|
||||
assert.match(adoptionDialog, /Number\.isInteger\(id\)\s*&&\s*id\s*>\s*0/)
|
||||
assert.match(adoptionDialog, /previewTestBatchAdoption\(.*\{\s*roots:\s*roots\.value\s*}\s*\)/s)
|
||||
assert.match(adoptionDialog, /executeTestBatchAdoption\([^,]+,\s*\{\s*roots:\s*roots\.value,\s*batchName:\s*batchName\.value,\s*previewToken:\s*previewToken\.value\s*}\s*\)/s)
|
||||
assert.match(adoptionDialog, /batchName\.value\s*!==\s*preview\.value\.batchName/)
|
||||
assert.match(adoptionDialog, /function invalidatePreview\(\)[\s\S]*?previewToken\.value\s*=\s*['"][\s\S]*?batchName\.value\s*=\s*['"]/)
|
||||
|
||||
const managementPath = 'src/views/system/testBatch/index.vue'
|
||||
const management = await readFile(path.join(frontendRoot, managementPath), 'utf8')
|
||||
assert.match(management, /const actionsFor\s*=\s*row\s*=>\s*\(\{[\s\S]*?edit:\s*row\.status\s*!==\s*['"]PURGED['"][\s\S]*?assign:\s*row\.status\s*===\s*['"]ACTIVE['"][\s\S]*?close:\s*row\.status\s*===\s*['"]ACTIVE['"][\s\S]*?reopen:\s*row\.status\s*===\s*['"]CLOSED['"][\s\S]*?purgePreview:\s*row\.status\s*===\s*['"]CLOSED['"][\s\S]*?audit:\s*row\.status\s*===\s*['"]PURGED['"][\s\S]*?}\)/)
|
||||
assert.match(management, /onlinePurgeAllowed\.value\s*===\s*false/)
|
||||
assert.match(management, /blockingReason/)
|
||||
assert.match(management, /testBatchStore\.leaveTestMode\(\)/)
|
||||
|
||||
const reportPaths = Object.values(reportPageContracts).map((contract) => contract.relativePath)
|
||||
for (const reportPath of reportPaths) {
|
||||
const source = await readFile(path.join(frontendRoot, reportPath), 'utf8')
|
||||
assert.doesNotMatch(source, /TestBatchAdoptionDialog/, `${reportPath} 不得提供纳入入口`)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,3 +7,87 @@ export function listAvailableTestBatches() {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function listTestBatches(params) {
|
||||
return request({
|
||||
url: '/system/test-batch/list',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
export function getTestBatch(batchId) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addTestBatch(data) {
|
||||
return request({
|
||||
url: '/system/test-batch',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateTestBatch(batchId, data) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function assignTestBatchUsers(batchId, data) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/users',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function closeTestBatch(batchId) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/close',
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export function reopenTestBatch(batchId) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/reopen',
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export function previewTestBatchAdoption(batchId, data) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/adoption/preview',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function executeTestBatchAdoption(batchId, data) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/adoption/execute',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function previewTestBatchPurge(batchId) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/purge/preview',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function purgeTestBatch(batchId, data) {
|
||||
return request({
|
||||
url: '/system/test-batch/' + batchId + '/purge',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -32,7 +32,9 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="fillingList" class="data-table">
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="fillingList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="装填单号" prop="fillingNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="托盘" min-width="120">
|
||||
<template #default="scope">{{ scope.row.palletCode || `#${scope.row.palletId}` }}</template>
|
||||
@@ -56,6 +58,7 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'filling'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -161,9 +164,16 @@
|
||||
<script setup name="BusinessFilling">
|
||||
import PalletScanInput from '@/components/PalletScanInput'
|
||||
import { createIdempotencyKey } from '@/utils/palletScan'
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import { addFilling, getFillingStrainOptions, listFilling, scanFillingPallet } from '@/api/business/filling'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const adoptionDialogRef = ref()
|
||||
const selectedIds = ref([])
|
||||
const fillingList = ref([])
|
||||
const strainOptions = ref([])
|
||||
const scannedPallet = ref(null)
|
||||
@@ -246,6 +256,9 @@ function getList() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) { selectedIds.value = selection.map((item) => item.fillingId) }
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function invalidateOptionRequest() {
|
||||
optionGeneration += 1
|
||||
optionLoading.value = false
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="inboundList" class="data-table">
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="inboundList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="入库单号" prop="inboundNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="仓库" min-width="120">
|
||||
<template #default="scope">{{ optionLabel(warehouseOptions, scope.row.warehouseId) }}</template>
|
||||
@@ -99,6 +101,7 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'inbound'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -199,6 +202,9 @@
|
||||
<script setup name="BusinessInbound">
|
||||
import PalletScanInput from '@/components/PalletScanInput'
|
||||
import { createIdempotencyKey } from '@/utils/palletScan'
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import {
|
||||
addInbound,
|
||||
confirmInbound,
|
||||
@@ -211,6 +217,10 @@ import {
|
||||
} from '@/api/business/inbound'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const adoptionDialogRef = ref()
|
||||
const selectedIds = ref([])
|
||||
const inboundList = ref([])
|
||||
const warehouseOptions = ref([])
|
||||
const scannedPallets = ref([])
|
||||
@@ -287,6 +297,9 @@ function getList() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) { selectedIds.value = selection.map((item) => item.inboundId) }
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function invalidateOptionRequest() {
|
||||
optionGeneration += 1
|
||||
optionLoading.value = false
|
||||
|
||||
@@ -173,7 +173,9 @@
|
||||
</el-form>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="returnList" class="data-table">
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="returnList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="退回单号" prop="returnNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="来源现场" min-width="120">
|
||||
<template #default="scope">#{{ scope.row.sourceSiteId }}</template>
|
||||
@@ -212,12 +214,16 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'return'" :resource-ids="selectedIds" @success="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="BusinessReturn">
|
||||
import PalletScanInput from '@/components/PalletScanInput'
|
||||
import { createIdempotencyKey } from '@/utils/palletScan'
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import {
|
||||
confirmReturn,
|
||||
getReturn,
|
||||
@@ -228,6 +234,10 @@ import {
|
||||
} from '@/api/business/return'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const adoptionDialogRef = ref()
|
||||
const selectedIds = ref([])
|
||||
const returnList = ref([])
|
||||
const warehouseOptions = ref([])
|
||||
const requestScannedPallets = ref([])
|
||||
@@ -307,6 +317,9 @@ function getList() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) { selectedIds.value = selection.map((item) => item.returnId) }
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function invalidateOptionRequest() {
|
||||
optionGeneration += 1
|
||||
optionLoading.value = false
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="shipmentList" class="data-table">
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="shipmentList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="发货单号" prop="shipmentNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="来源仓库" min-width="130">
|
||||
<template #default="scope">{{ optionLabel(warehouseOptions, scope.row.sourceWarehouseId) }}</template>
|
||||
@@ -96,6 +98,7 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'shipment'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -210,6 +213,9 @@
|
||||
<script setup name="BusinessShipment">
|
||||
import PalletScanInput from '@/components/PalletScanInput'
|
||||
import { createIdempotencyKey } from '@/utils/palletScan'
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import {
|
||||
addShipment,
|
||||
confirmShipment,
|
||||
@@ -223,6 +229,10 @@ import {
|
||||
} from '@/api/business/shipment'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const adoptionDialogRef = ref()
|
||||
const selectedIds = ref([])
|
||||
const shipmentList = ref([])
|
||||
const warehouseOptions = ref([])
|
||||
const siteOptions = ref([])
|
||||
@@ -301,6 +311,9 @@ function getList() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) { selectedIds.value = selection.map((item) => item.shipmentId) }
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function invalidateOptionRequest() {
|
||||
optionGeneration += 1
|
||||
optionLoading.value = false
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
</el-form>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="usageList" class="data-table">
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="usageList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="使用记录号" prop="usageNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="托盘" min-width="120">
|
||||
<template #default="scope">{{ scope.row.palletCode || `#${scope.row.palletId}` }}</template>
|
||||
@@ -133,15 +135,23 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'usage'" :resource-ids="selectedIds" @success="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="BusinessUsage">
|
||||
import PalletScanInput from '@/components/PalletScanInput'
|
||||
import { createIdempotencyKey } from '@/utils/palletScan'
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import { addUsage, getUsageLineOptions, listUsage, scanUsagePallet } from '@/api/business/usage'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const adoptionDialogRef = ref()
|
||||
const selectedIds = ref([])
|
||||
const usageList = ref([])
|
||||
const lineOptions = ref([])
|
||||
const scannedPallet = ref(null)
|
||||
@@ -212,6 +222,9 @@ function getList() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) { selectedIds.value = selection.map((item) => item.usageId) }
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function invalidateOptionRequest() {
|
||||
optionGeneration += 1
|
||||
optionLoading.value = false
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:customer:add']">新增</el-button></el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -29,6 +29,9 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:customer:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table class="master-table data-table" v-loading="loading" empty-text="暂无数据" :data="customerList" @selection-change="handleSelectionChange">
|
||||
@@ -42,7 +45,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:customer:query', 'master:customer:edit'])"
|
||||
@@ -60,6 +63,7 @@
|
||||
v-show="total > 0" :total="total"
|
||||
v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'customer'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -114,8 +118,15 @@
|
||||
|
||||
<script setup name="Customer">
|
||||
import { addCustomer, delCustomer, getCustomer, listCustomer, updateCustomer } from "@/api/master/customer";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const customerList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
@@ -218,6 +229,8 @@ function handleSelectionChange(selection) {
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:line:add']">新增</el-button></el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -32,6 +32,9 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:line:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table class="master-table data-table" v-loading="loading" empty-text="暂无数据" :data="lineList" @selection-change="handleSelectionChange">
|
||||
@@ -46,7 +49,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:line:query', 'master:line:edit'])"
|
||||
@@ -64,6 +67,7 @@
|
||||
v-show="total > 0" :total="total"
|
||||
v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'line'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -116,8 +120,15 @@
|
||||
|
||||
<script setup name="Line">
|
||||
import { addLine, delLine, getLine, listLine, updateLine } from "@/api/master/line";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const lineList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
@@ -227,6 +238,8 @@ function handleSelectionChange(selection) {
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:pallet:add']">新增</el-button></el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -26,6 +26,9 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:pallet:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table class="master-table data-table" v-loading="loading" empty-text="暂无数据" :data="palletList" @selection-change="handleSelectionChange">
|
||||
@@ -39,7 +42,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="250" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" width="250" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link type="primary" icon="Printer" :loading="isPrinting(scope.row.palletId)"
|
||||
@@ -61,6 +64,7 @@
|
||||
v-show="total > 0" :total="total"
|
||||
v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'pallet'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -116,8 +120,15 @@
|
||||
|
||||
<script setup name="Pallet">
|
||||
import { addPallet, delPallet, getPallet, getPalletQrcode, listPallet, updatePallet } from "@/api/master/pallet";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const palletList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
@@ -227,6 +238,8 @@ function handleSelectionChange(selection) {
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:site:add']">新增</el-button></el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -33,6 +33,9 @@
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:site:remove']">删除</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="User" :disabled="single" @click="handleAssign()" v-hasPermi="['master:site:assign']">分配用户</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table class="master-table data-table" v-loading="loading" empty-text="暂无数据" :data="siteList" @selection-change="handleSelectionChange">
|
||||
@@ -48,7 +51,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="260" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" width="260" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="User" @click="handleAssign(scope.row)" v-hasPermi="['master:site:assign']">分配</el-button>
|
||||
<el-button
|
||||
@@ -67,6 +70,7 @@
|
||||
v-show="total > 0" :total="total"
|
||||
v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'site'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -125,8 +129,15 @@
|
||||
<script setup name="Site">
|
||||
import BusinessUserAssignDialog from "@/components/BusinessUserAssignDialog";
|
||||
import { addSite, delSite, getSite, listSite, updateSite } from "@/api/master/site";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const siteList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
@@ -239,6 +250,8 @@ function handleSelectionChange(selection) {
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:strain:add']">新增</el-button>
|
||||
</el-col>
|
||||
@@ -38,6 +38,9 @@
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:strain:remove']">删除</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
|
||||
@@ -54,7 +57,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:strain:query', 'master:strain:edit'])"
|
||||
@@ -84,6 +87,7 @@
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'strain'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -133,8 +137,15 @@
|
||||
|
||||
<script setup name="Strain">
|
||||
import { addStrain, delStrain, getStrain, listStrain, updateStrain } from "@/api/master/strain";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
|
||||
const strainList = ref([]);
|
||||
@@ -252,6 +263,8 @@ function handleSelectionChange(selection) {
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8 master-toolbar">
|
||||
<el-row v-if="isMasterWriteAllowed" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['master:warehouse:add']">新增</el-button></el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -30,6 +30,9 @@
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:warehouse:remove']">删除</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="User" :disabled="single" @click="handleAssign()" v-hasPermi="['master:warehouse:assign']">分配用户</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table class="master-table data-table" v-loading="loading" empty-text="暂无数据" :data="warehouseList" @selection-change="handleSelectionChange">
|
||||
@@ -44,7 +47,7 @@
|
||||
<el-table-column label="创建时间" prop="createTime" align="center" width="180">
|
||||
<template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="260" class-name="small-padding fixed-width">
|
||||
<el-table-column v-if="isMasterWriteAllowed" label="操作" align="center" width="260" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="User" @click="handleAssign(scope.row)" v-hasPermi="['master:warehouse:assign']">分配</el-button>
|
||||
<el-button
|
||||
@@ -63,6 +66,7 @@
|
||||
v-show="total > 0" :total="total"
|
||||
v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"
|
||||
/>
|
||||
<test-batch-adoption-dialog ref="adoptionDialogRef" :root-type="'warehouse'" :resource-ids="selectedIds" @success="getList" />
|
||||
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
@@ -118,8 +122,15 @@
|
||||
<script setup name="Warehouse">
|
||||
import BusinessUserAssignDialog from "@/components/BusinessUserAssignDialog";
|
||||
import { addWarehouse, delWarehouse, getWarehouse, listWarehouse, updateWarehouse } from "@/api/master/warehouse";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const isMasterWriteAllowed = computed(() => userStore.admin === true || !testBatchStore.isTestMode)
|
||||
const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const warehouseList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
@@ -224,6 +235,8 @@ function handleSelectionChange(selection) {
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
function handleAdd() {
|
||||
invalidateDetailRequest();
|
||||
reset();
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div v-if="userStore.admin === true" class="app-container test-batch-page">
|
||||
<div class="page-toolbar mb8">
|
||||
<div>
|
||||
<h2>测试数据批次</h2>
|
||||
<p>管理测试数据的生命周期、参与用户和清理审计。</p>
|
||||
</div>
|
||||
<el-button type="primary" icon="Plus" :disabled="operationLoading" @click="openCreate">创建批次</el-button>
|
||||
</div>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-table v-loading="loading" :data="batchList" class="data-table" empty-text="暂无测试批次">
|
||||
<el-table-column label="批次编码" prop="batchCode" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="批次名称" prop="batchName" min-width="170" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" prop="status" width="100" align="center">
|
||||
<template #default="scope"><el-tag :type="statusType(scope.row.status)">{{ scope.row.status }}</el-tag></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="参与用户" min-width="100" align="center">
|
||||
<template #default="scope">{{ scope.row.userCount ?? '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="180"><template #default="scope">{{ parseTime(scope.row.createTime) }}</template></el-table-column>
|
||||
<el-table-column label="关闭时间" prop="closedAt" width="180"><template #default="scope">{{ parseTime(scope.row.closedAt) }}</template></el-table-column>
|
||||
<el-table-column label="清理时间" prop="purgedAt" width="180"><template #default="scope">{{ parseTime(scope.row.purgedAt) }}</template></el-table-column>
|
||||
<el-table-column label="操作" width="310" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="actionsFor(scope.row).edit" link type="primary" :disabled="operationLoading" @click="openEdit(scope.row)">编辑</el-button>
|
||||
<el-button v-if="actionsFor(scope.row).assign" link type="primary" :disabled="operationLoading" @click="openAssign(scope.row)">用户</el-button>
|
||||
<el-button v-if="actionsFor(scope.row).close" link type="warning" :loading="operationName === `close:${scope.row.batchId}`" :disabled="operationLoading" @click="closeBatch(scope.row)">关闭</el-button>
|
||||
<el-button v-if="actionsFor(scope.row).reopen" link type="success" :loading="operationName === `reopen:${scope.row.batchId}`" :disabled="operationLoading" @click="reopenBatch(scope.row)">重新开启</el-button>
|
||||
<el-button v-if="actionsFor(scope.row).purgePreview" link type="danger" :disabled="operationLoading" @click="openPurge(scope.row)">清理</el-button>
|
||||
<el-button v-if="actionsFor(scope.row).audit" link type="info" :disabled="operationLoading" @click="openAudit(scope.row)">审计</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<el-dialog v-model="formVisible" :title="form.batchId ? '编辑测试批次' : '创建测试批次'" width="min(560px, 92vw)" append-to-body :close-on-click-modal="!formSubmitting" :close-on-press-escape="!formSubmitting" :show-close="!formSubmitting">
|
||||
<el-alert v-if="formError" :title="formError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="90px">
|
||||
<el-form-item label="批次名称" prop="batchName"><el-input v-model="form.batchName" :disabled="Boolean(form.batchId) || formSubmitting" maxlength="100" /></el-form-item>
|
||||
<el-form-item label="备注" prop="remark"><el-input v-model="form.remark" type="textarea" :rows="3" :disabled="formSubmitting" maxlength="500" show-word-limit /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer><el-button :disabled="formSubmitting" @click="formVisible = false">取消</el-button><el-button type="primary" :loading="formSubmitting" @click="submitForm">确定</el-button></template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="assignVisible" title="授权测试批次用户" width="min(620px, 92vw)" append-to-body :close-on-click-modal="!assignSubmitting" :close-on-press-escape="!assignSubmitting" :show-close="!assignSubmitting">
|
||||
<el-alert v-if="assignError" :title="assignError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-skeleton v-if="assignLoading" :rows="3" animated />
|
||||
<el-form v-else label-width="100px">
|
||||
<el-form-item label="批次">{{ assignBatch?.batchName }}</el-form-item>
|
||||
<el-form-item label="用户 ID"><el-input v-model="assignedUserIds" :disabled="assignSubmitting" placeholder="多个 ID 用英文逗号分隔;留空将取消全部授权" /></el-form-item>
|
||||
</el-form>
|
||||
<template #footer><el-button :disabled="assignSubmitting" @click="assignVisible = false">取消</el-button><el-button type="primary" :loading="assignSubmitting" :disabled="assignLoading" @click="submitAssign">保存授权</el-button></template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="purgeVisible" title="清理测试批次" width="min(860px, 94vw)" top="5vh" append-to-body :close-on-click-modal="!purgeSubmitting" :close-on-press-escape="!purgeSubmitting" :show-close="!purgeSubmitting">
|
||||
<el-alert v-if="purgeError" :title="purgeError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<el-skeleton v-if="purgePreviewLoading" :rows="5" animated />
|
||||
<template v-else-if="purgePreview">
|
||||
<el-descriptions :column="2" border size="small" class="mb8">
|
||||
<el-descriptions-item label="批次">{{ purgePreview.batchName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="影响总数">{{ purgePreview.totalCount }}</el-descriptions-item>
|
||||
<el-descriptions-item label="在线清理上限">{{ purgePreview.onlinePurgeLimit }}</el-descriptions-item>
|
||||
<el-descriptions-item label="在线清理">{{ onlinePurgeAllowed ? '允许' : '不允许' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-alert v-if="isOnlinePurgeBlocked" :title="purgePreview.blockingReason || '当前范围不允许在线清理'" type="warning" :closable="false" show-icon class="mb8" />
|
||||
<el-table :data="purgePreview.impacts" size="small" max-height="280" empty-text="无受影响数据">
|
||||
<el-table-column label="分类" prop="label" min-width="150" />
|
||||
<el-table-column label="数量" prop="count" width="90" align="right" />
|
||||
<el-table-column label="全部编号" min-width="320"><template #default="scope"><span class="impact-keys">{{ (scope.row.keys || []).join(', ') || '-' }}</span></template></el-table-column>
|
||||
</el-table>
|
||||
<el-form label-width="100px" class="purge-confirm"><el-form-item label="批次全名"><el-input v-model="purgeBatchName" :disabled="purgeSubmitting" :placeholder="`请输入 ${purgePreview.batchName}`" /></el-form-item></el-form>
|
||||
</template>
|
||||
<el-empty v-else-if="!purgePreviewLoading && !purgeError" description="暂无清理预览" :image-size="72" />
|
||||
<template #footer><el-button :disabled="purgeSubmitting" @click="purgeVisible = false">取消</el-button><el-button type="primary" :loading="purgePreviewLoading" :disabled="purgePreviewLoading || purgeSubmitting" @click="loadPurgePreview">重新预览</el-button><el-button type="danger" :loading="purgeSubmitting" :disabled="!canPurge" @click="submitPurge">确认清理</el-button></template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="auditVisible" title="清理审计汇总" width="min(620px, 92vw)" append-to-body>
|
||||
<el-descriptions :column="1" border><el-descriptions-item label="批次">{{ auditBatch?.batchName }}</el-descriptions-item><el-descriptions-item label="清理时间">{{ parseTime(auditBatch?.purgedAt) }}</el-descriptions-item><el-descriptions-item label="清理汇总"><pre class="audit-summary">{{ JSON.stringify(auditBatch?.purgeSummary || {}, null, 2) }}</pre></el-descriptions-item></el-descriptions>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<el-empty v-else description="无测试批次管理权限" />
|
||||
</template>
|
||||
|
||||
<script setup name="TestBatch">
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import { addTestBatch, assignTestBatchUsers, closeTestBatch, getTestBatch, listTestBatches, previewTestBatchPurge, purgeTestBatch, reopenTestBatch, updateTestBatch } from '@/api/system/testBatch'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
const testBatchStore = useTestBatchStore()
|
||||
const batchList = ref([])
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
const loadError = ref('')
|
||||
const operationLoading = ref(false)
|
||||
const operationName = ref('')
|
||||
const formVisible = ref(false)
|
||||
const formSubmitting = ref(false)
|
||||
const formError = ref('')
|
||||
const formRef = ref()
|
||||
const form = reactive({ batchId: undefined, batchName: '', remark: '' })
|
||||
const assignVisible = ref(false)
|
||||
const assignLoading = ref(false)
|
||||
const assignSubmitting = ref(false)
|
||||
const assignError = ref('')
|
||||
const assignBatch = ref(null)
|
||||
const assignedUserIds = ref('')
|
||||
const purgeVisible = ref(false)
|
||||
const purgePreviewLoading = ref(false)
|
||||
const purgeSubmitting = ref(false)
|
||||
const purgeError = ref('')
|
||||
const purgeBatch = ref(null)
|
||||
const purgePreview = ref(null)
|
||||
const purgeToken = ref('')
|
||||
const purgeBatchName = ref('')
|
||||
const onlinePurgeAllowed = ref(false)
|
||||
const auditVisible = ref(false)
|
||||
const auditBatch = ref(null)
|
||||
let purgeVersion = 0
|
||||
const queryParams = ref({ pageNum: 1, pageSize: 10 })
|
||||
const formRules = { batchName: [{ required: true, message: '请输入批次名称', trigger: 'blur' }] }
|
||||
const actionsFor = row => ({
|
||||
edit: row.status !== 'PURGED',
|
||||
assign: row.status === 'ACTIVE',
|
||||
close: row.status === 'ACTIVE',
|
||||
reopen: row.status === 'CLOSED',
|
||||
purgePreview: row.status === 'CLOSED',
|
||||
audit: row.status === 'PURGED'
|
||||
})
|
||||
const canPurge = computed(() => Boolean(purgePreview.value && purgeToken.value && onlinePurgeAllowed.value && purgeBatchName.value === purgePreview.value.batchName && !purgeSubmitting.value))
|
||||
const isOnlinePurgeBlocked = computed(() => onlinePurgeAllowed.value === false)
|
||||
|
||||
function statusType(status) { return status === 'ACTIVE' ? 'success' : status === 'CLOSED' ? 'warning' : 'info' }
|
||||
function getList() {
|
||||
loading.value = true
|
||||
loadError.value = ''
|
||||
return listTestBatches(queryParams.value).then((response) => {
|
||||
batchList.value = Array.isArray(response.rows) ? response.rows : []
|
||||
total.value = response.total || 0
|
||||
}).catch(() => {
|
||||
batchList.value = []
|
||||
total.value = 0
|
||||
loadError.value = '测试批次列表加载失败,请稍后重试'
|
||||
}).finally(() => { loading.value = false })
|
||||
}
|
||||
async function refreshAfterSuccess(message) { proxy.$modal.msgSuccess(message); await Promise.all([getList(), testBatchStore.refreshOptions()]) }
|
||||
function openCreate() { Object.assign(form, { batchId: undefined, batchName: '', remark: '' }); formError.value = ''; formVisible.value = true }
|
||||
function openEdit(row) { Object.assign(form, { batchId: row.batchId, batchName: row.batchName, remark: row.remark || '' }); formError.value = ''; formVisible.value = true }
|
||||
function submitForm() {
|
||||
if (formSubmitting.value) return
|
||||
formRef.value?.validate((valid) => {
|
||||
if (!valid) return
|
||||
formSubmitting.value = true
|
||||
formError.value = ''
|
||||
const request = form.batchId ? updateTestBatch(form.batchId, { remark: form.remark }) : addTestBatch({ batchName: form.batchName, remark: form.remark })
|
||||
request.then(async (response) => { formVisible.value = false; await refreshAfterSuccess(response.msg || '保存成功') }).catch(() => { formError.value = '保存失败,请根据提示修正后重试' }).finally(() => { formSubmitting.value = false })
|
||||
})
|
||||
}
|
||||
function runOperation(name, callback) {
|
||||
if (operationLoading.value) return
|
||||
operationLoading.value = true
|
||||
operationName.value = name
|
||||
callback().finally(() => { operationLoading.value = false; operationName.value = '' })
|
||||
}
|
||||
function closeBatch(row) {
|
||||
runOperation(`close:${row.batchId}`, () => proxy.$modal.confirm(`确认关闭测试批次“${row.batchName}”吗?`).then(() => closeTestBatch(row.batchId)).then((response) => refreshAfterSuccess(response.msg || '批次已关闭')).catch((error) => { if (error !== 'cancel' && error !== 'close') proxy.$modal.msgError('关闭批次失败') }))
|
||||
}
|
||||
function reopenBatch(row) {
|
||||
runOperation(`reopen:${row.batchId}`, () => reopenTestBatch(row.batchId).then((response) => refreshAfterSuccess(response.msg || '批次已重新开启')).catch(() => proxy.$modal.msgError('重新开启批次失败')))
|
||||
}
|
||||
function parseUserIds() { return [...new Set(assignedUserIds.value.split(',').map((value) => Number(value.trim())).filter((id) => Number.isInteger(id) && id > 0))] }
|
||||
function openAssign(row) {
|
||||
assignVisible.value = true; assignLoading.value = true; assignError.value = ''; assignBatch.value = row; assignedUserIds.value = ''
|
||||
getTestBatch(row.batchId).then((response) => { const detail = response.data || {}; assignBatch.value = detail; assignedUserIds.value = (detail.userIds || []).join(', ') }).catch(() => { assignError.value = '批次详情加载失败,请稍后重试' }).finally(() => { assignLoading.value = false })
|
||||
}
|
||||
function submitAssign() {
|
||||
if (assignSubmitting.value || !assignBatch.value) return
|
||||
const userIds = parseUserIds()
|
||||
const source = assignedUserIds.value.trim()
|
||||
if (source && !userIds.length) { assignError.value = '用户 ID 必须是正整数,多个 ID 用英文逗号分隔'; return }
|
||||
assignSubmitting.value = true; assignError.value = ''
|
||||
assignTestBatchUsers(assignBatch.value.batchId, { userIds }).then(async (response) => { assignVisible.value = false; await refreshAfterSuccess(response.msg || '用户授权已更新') }).catch(() => { assignError.value = '用户授权失败,请稍后重试' }).finally(() => { assignSubmitting.value = false })
|
||||
}
|
||||
function invalidatePurgePreview() { purgeVersion += 1; purgePreview.value = null; purgeToken.value = ''; purgeBatchName.value = ''; onlinePurgeAllowed.value = false }
|
||||
function openPurge(row) { purgeBatch.value = row; purgeError.value = ''; purgeVisible.value = true; invalidatePurgePreview(); loadPurgePreview() }
|
||||
function loadPurgePreview() {
|
||||
if (!purgeBatch.value || purgePreviewLoading.value || purgeSubmitting.value) return
|
||||
invalidatePurgePreview(); const version = ++purgeVersion; purgePreviewLoading.value = true; purgeError.value = ''
|
||||
previewTestBatchPurge(purgeBatch.value.batchId).then((response) => {
|
||||
if (version !== purgeVersion) return
|
||||
const data = response.data || {}
|
||||
if (!data.previewToken || !data.batchName) throw new Error('预览响应不完整')
|
||||
purgePreview.value = data; purgeToken.value = data.previewToken; onlinePurgeAllowed.value = data.onlinePurgeAllowed === true
|
||||
}).catch(() => { if (version === purgeVersion) { invalidatePurgePreview(); purgeError.value = '清理预览已失效或批次状态已变化,请重新预览' } }).finally(() => { if (version === purgeVersion) purgePreviewLoading.value = false })
|
||||
}
|
||||
function submitPurge() {
|
||||
if (!canPurge.value || purgeSubmitting.value || !purgeBatch.value) return
|
||||
purgeSubmitting.value = true; purgeError.value = ''; const token = purgeToken.value
|
||||
purgeTestBatch(purgeBatch.value.batchId, { batchName: purgeBatchName.value, previewToken: purgeToken.value }).then(async (response) => { purgeVisible.value = false; testBatchStore.leaveTestMode(); await refreshAfterSuccess(response.msg || '批次已清理') }).catch(() => { if (token === purgeToken.value) { invalidatePurgePreview(); purgeError.value = '清理预览令牌已失效,请重新预览' } }).finally(() => { purgeSubmitting.value = false })
|
||||
}
|
||||
function openAudit(row) { auditBatch.value = row; auditVisible.value = true }
|
||||
onMounted(getList)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-toolbar { display:flex; align-items:center; justify-content:space-between; gap:16px; padding-bottom:12px; border-bottom:1px solid var(--el-border-color-lighter); }
|
||||
.page-toolbar h2 { margin:0; font-size:18px; font-weight:600; }.page-toolbar p { margin:4px 0 0; color:var(--el-text-color-secondary); font-size:13px; }.impact-keys { display:block; overflow-wrap:anywhere; }.purge-confirm { margin-top:12px; }.audit-summary { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; }@media (max-width:768px) { .page-toolbar { align-items:flex-start; flex-direction:column; }.page-toolbar :deep(.el-button) { width:100%; } }
|
||||
</style>
|
||||
Reference in New Issue
Block a user