feat(web-admin): align sample-freight page cancel UX with two-button rules
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
8c0cbb8ab8
commit
f659ec602e
1 file changed
+66
-111
@@ -79,7 +79,7 @@
|
||||
@click="handleBatchUnlink"
|
||||
>
|
||||
<el-icon><Link /></el-icon>
|
||||
取消关联
|
||||
取消运费
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
@@ -238,7 +238,7 @@
|
||||
</el-button>
|
||||
<el-button class="btn-op-item" @click="openUnlinkDialog(row.freightId)">
|
||||
<el-icon><Link /></el-icon>
|
||||
取消关联
|
||||
取消运费
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -261,72 +261,28 @@
|
||||
<FreightConfigDialog ref="configDialogRef" @success="loadData" />
|
||||
<FreightEditDialog ref="editDialogRef" @success="loadData" />
|
||||
|
||||
<el-dialog
|
||||
<FreightUnlinkDialog
|
||||
v-model="unlinkVisible"
|
||||
title="取消关联"
|
||||
width="720px"
|
||||
class="dialog-form-layout"
|
||||
align-center
|
||||
append-to-body
|
||||
modal-class="protocol-dialog-mask"
|
||||
destroy-on-close
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<p class="unlink-hint">勾选要从该运费批次解除关联的样本:</p>
|
||||
<el-table
|
||||
:data="unlinkItems"
|
||||
stripe
|
||||
class="list-table"
|
||||
max-height="360"
|
||||
row-key="sampleId"
|
||||
@selection-change="(rows: UnlinkItem[]) => (unlinkSelected = rows)"
|
||||
>
|
||||
<el-table-column type="selection" min-width="48" align="center" header-align="center" />
|
||||
<el-table-column label="来源" min-width="100" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.sampleSource === 'cell_storage' ? 'success' : 'warning'" size="small">
|
||||
{{ row.sampleSource === 'cell_storage' ? '细胞存储' : '科研捐赠' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="protocolNo" label="协议单号" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="sampleCode" label="样本编码" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column
|
||||
prop="sampleTypeName"
|
||||
label="样本类型"
|
||||
min-width="110"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button class="btn-ghost" @click="unlinkVisible = false">
|
||||
<el-icon><Close /></el-icon>
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-main"
|
||||
type="primary"
|
||||
:loading="unlinkSubmitting"
|
||||
@click="confirmUnlink"
|
||||
>
|
||||
<el-icon><Check /></el-icon>
|
||||
确定解除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
:items="unlinkDialogItems"
|
||||
:default-selected-keys="unlinkDefaultKeys"
|
||||
:submitting="unlinkSubmitting"
|
||||
@confirm="confirmUnlinkFromDialog"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Check, Close, Edit, Link, Plus, RefreshLeft, Search } from '@element-plus/icons-vue'
|
||||
import { Edit, Link, Plus, RefreshLeft, Search } from '@element-plus/icons-vue'
|
||||
import { fetchDictDataOptions } from '@/api/admin'
|
||||
import {
|
||||
fetchSampleFreightDetail,
|
||||
fetchSampleFreightList,
|
||||
fetchUnlinkSampleFreight,
|
||||
type SampleFreight,
|
||||
type SampleFreightItem
|
||||
type SampleFreight
|
||||
} from '@/api/sample-freight'
|
||||
import FreightUnlinkDialog, {
|
||||
type FreightUnlinkRow
|
||||
} from '@/components/business/freight-unlink-dialog/index.vue'
|
||||
import { formatDisplayOrDash } from '@/utils/datetime-display'
|
||||
import { formatMoneyDisplay } from '@/utils/money-format'
|
||||
import {
|
||||
@@ -340,7 +296,6 @@
|
||||
defineOptions({ name: 'CellStorageSampleFreight' })
|
||||
|
||||
type FlatRow = SampleFreightFlatRow
|
||||
type UnlinkItem = SampleFreightItem
|
||||
|
||||
const loading = ref(false)
|
||||
const flatRows = ref<FlatRow[]>([])
|
||||
@@ -351,9 +306,8 @@
|
||||
const editDialogRef = ref<InstanceType<typeof FreightEditDialog>>()
|
||||
|
||||
const unlinkVisible = ref(false)
|
||||
const unlinkFreightId = ref('')
|
||||
const unlinkItems = ref<UnlinkItem[]>([])
|
||||
const unlinkSelected = ref<UnlinkItem[]>([])
|
||||
const unlinkDialogItems = ref<FreightUnlinkRow[]>([])
|
||||
const unlinkDefaultKeys = ref<string[]>([])
|
||||
const unlinkSubmitting = ref(false)
|
||||
|
||||
const searchForm = reactive({
|
||||
@@ -462,63 +416,40 @@
|
||||
openEditById(selectedFreightIds.value[0])
|
||||
}
|
||||
|
||||
function toUnlinkRow(it: NonNullable<SampleFreight['items']>[number], freightId: string): FreightUnlinkRow {
|
||||
return {
|
||||
...it,
|
||||
freightId,
|
||||
rowKey: `${it.sampleSource}:${it.sampleId}`
|
||||
}
|
||||
}
|
||||
|
||||
async function openUnlinkDialog(freightId: string) {
|
||||
unlinkFreightId.value = freightId
|
||||
unlinkSelected.value = []
|
||||
try {
|
||||
const res = await fetchSampleFreightDetail(freightId)
|
||||
const data = ((res as any)?.data || res) as SampleFreight
|
||||
unlinkItems.value = data.items || []
|
||||
unlinkDialogItems.value = (data.items || []).map((it) => toUnlinkRow(it, freightId))
|
||||
unlinkDefaultKeys.value = unlinkDialogItems.value.map((r) => r.rowKey)
|
||||
unlinkVisible.value = true
|
||||
} catch {
|
||||
ElMessage.error('加载关联样本失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmUnlink() {
|
||||
if (!unlinkSelected.value.length) {
|
||||
ElMessage.warning('请勾选要解除关联的样本')
|
||||
return
|
||||
}
|
||||
async function confirmUnlinkFromDialog(rows: FreightUnlinkRow[]) {
|
||||
unlinkSubmitting.value = true
|
||||
try {
|
||||
await fetchUnlinkSampleFreight(
|
||||
unlinkFreightId.value,
|
||||
unlinkSelected.value.map((x) => ({
|
||||
sampleSource: x.sampleSource,
|
||||
sampleId: x.sampleId,
|
||||
protocolId: x.protocolId,
|
||||
sampleCode: x.sampleCode
|
||||
}))
|
||||
)
|
||||
unlinkVisible.value = false
|
||||
await loadData()
|
||||
} finally {
|
||||
unlinkSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBatchUnlink() {
|
||||
if (!selectedFreightIds.value.length) return
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`将解除已选 ${selectedFreightIds.value.length} 笔运费下的全部样本关联,是否继续?`,
|
||||
'批量取消关联',
|
||||
{ type: 'warning', confirmButtonText: '确定', cancelButtonText: '取消' }
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
for (const id of selectedFreightIds.value) {
|
||||
const res = await fetchSampleFreightDetail(id)
|
||||
const data = ((res as any)?.data || res) as SampleFreight
|
||||
const items = data.items || []
|
||||
if (!items.length) continue
|
||||
const byFreight = new Map<string, FreightUnlinkRow[]>()
|
||||
for (const row of rows) {
|
||||
const fid = String(row.freightId || '').trim()
|
||||
if (!fid) continue
|
||||
if (!byFreight.has(fid)) byFreight.set(fid, [])
|
||||
byFreight.get(fid)!.push(row)
|
||||
}
|
||||
for (const [fid, list] of byFreight) {
|
||||
await fetchUnlinkSampleFreight(
|
||||
id,
|
||||
items.map((x) => ({
|
||||
fid,
|
||||
list.map((x) => ({
|
||||
sampleSource: x.sampleSource,
|
||||
sampleId: x.sampleId,
|
||||
protocolId: x.protocolId,
|
||||
@@ -526,7 +457,37 @@
|
||||
}))
|
||||
)
|
||||
}
|
||||
unlinkVisible.value = false
|
||||
await loadData()
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.message || '取消运费失败')
|
||||
} finally {
|
||||
unlinkSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBatchUnlink() {
|
||||
if (!selectedFreightIds.value.length) return
|
||||
loading.value = true
|
||||
try {
|
||||
const byKey = new Map<string, FreightUnlinkRow>()
|
||||
for (const id of selectedFreightIds.value) {
|
||||
const res = await fetchSampleFreightDetail(id)
|
||||
const data = ((res as any)?.data || res) as SampleFreight
|
||||
for (const it of data.items || []) {
|
||||
const row = toUnlinkRow(it, id)
|
||||
byKey.set(row.rowKey, row)
|
||||
}
|
||||
}
|
||||
unlinkDialogItems.value = [...byKey.values()]
|
||||
unlinkDefaultKeys.value = unlinkDialogItems.value.map((r) => r.rowKey)
|
||||
if (!unlinkDialogItems.value.length) {
|
||||
ElMessage.warning('所选运费下没有关联样本')
|
||||
return
|
||||
}
|
||||
unlinkVisible.value = true
|
||||
} catch {
|
||||
ElMessage.error('加载关联样本失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -549,12 +510,6 @@
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
}
|
||||
|
||||
.unlink-hint {
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
}
|
||||
|
||||
/* 按运费批次交替底色(同批次多样本行同色) */
|
||||
:deep(.freight-batch-table) {
|
||||
.el-table__body tr.freight-batch-even > td.el-table__cell {
|
||||
|
||||
Reference in new issue
Block a user