优化
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import { computed, onActivated, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Eye, FileText, Pencil, Plus, Power } from '@lucide/vue'
|
||||
import { Plus } from '@lucide/vue'
|
||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||||
@@ -97,7 +98,7 @@ async function toggleStatus(row: Supplier) {
|
||||
const next: SupplierStatus = row.status === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE'
|
||||
const verb = next === 'ACTIVE' ? '启用' : '停用'
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${verb}供应商“${row.name}”吗?`, `${verb}供应商`, { type: 'warning', confirmButtonText: `确认${verb}`, cancelButtonText: '取消' })
|
||||
await ElMessageBox.confirm(`确认${verb}供应商“${row.name}”吗?`, `${verb}供应商`, { customClass: 'admin-density-confirm', type: 'warning', confirmButtonText: `确认${verb}`, cancelButtonText: '取消' })
|
||||
actionId.value = row.id
|
||||
await changeSupplierStatus(row.id, next)
|
||||
ElMessage.success(`供应商已${verb}`)
|
||||
@@ -119,18 +120,13 @@ onActivated(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AdminPage>
|
||||
<AdminPage class="admin-density">
|
||||
<ListPageLayout aria-label="供应商列表">
|
||||
<template #toolbar>
|
||||
<div class="supplier-list-top">
|
||||
<div class="supplier-metrics" aria-label="供应商分类统计">
|
||||
<button v-for="item in metricItems" :key="item.category" type="button" :class="{ active: activeCategory === item.category }" @click="switchCategory(item.category)">
|
||||
<span>{{ item.label }}</span><strong>{{ item.value }}<small>家</small></strong>
|
||||
</button>
|
||||
</div>
|
||||
<div class="supplier-query-panel">
|
||||
<nav class="supplier-tabs" aria-label="供应商分类">
|
||||
<button v-for="item in metricItems" :key="item.category" type="button" :class="{ active: activeCategory === item.category }" @click="switchCategory(item.category)">{{ categoryLabels[item.category] }}</button>
|
||||
<nav class="supplier-tabs density-tabs" role="tablist" aria-label="供应商分类统计">
|
||||
<button role="tab" :aria-selected="activeCategory === item.category" v-for="item in metricItems" :key="item.category" type="button" :class="{ active: activeCategory === item.category }" @click="switchCategory(item.category)"><span class="density-tab-icon" aria-hidden="true">{{ ({ BOOKING: '🚢', CUSTOMS: '📋', TRUCKING: '🚚', CERTIFICATE: '📄' })[item.category] }}</span>{{ categoryLabels[item.category] }}({{ item.value }})</button>
|
||||
</nav>
|
||||
<QueryToolbar v-model="filters" class="supplier-query-toolbar" ariaLabel="供应商筛选" :fields="queryFields" @search="search" />
|
||||
</div>
|
||||
@@ -148,16 +144,16 @@ onActivated(() => {
|
||||
<el-button v-if="access.can('platform:supplier:create')" type="primary" @click="router.push({ name: 'supplier-create' })"><Plus :size="16" />新增供应商</el-button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<div class="row-actions">
|
||||
<el-button size="small" plain type="primary" @click="router.push({ name: 'supplier-detail', params: { id: row.id } })"><Eye :size="15" />详情</el-button>
|
||||
<el-button v-if="access.can('platform:supplier:edit')" size="small" plain type="primary" @click="router.push({ name: 'supplier-edit', params: { id: row.id } })"><Pencil :size="15" />编辑</el-button>
|
||||
<el-button v-if="access.can('platform:supplier:status')" size="small" plain :type="row.status === 'ACTIVE' ? 'danger' : 'success'" :loading="actionId === row.id" @click="toggleStatus(supplierRow(row))"><Power :size="15" />{{ row.status === 'ACTIVE' ? '停用' : '启用' }}</el-button>
|
||||
<div class="row-actions density-actions">
|
||||
<el-button data-tone="neutral" class="density-action" size="small" @click="router.push({ name: 'supplier-detail', params: { id: row.id } })">详情</el-button>
|
||||
<el-button data-tone="neutral" class="density-action" v-if="access.can('platform:supplier:edit')" size="small" @click="router.push({ name: 'supplier-edit', params: { id: row.id } })">编辑</el-button>
|
||||
<el-button class="density-action" v-if="access.can('platform:supplier:status')" size="small" :data-tone="row.status === 'ACTIVE' ? 'danger' : 'success'" :loading="actionId === row.id" @click="toggleStatus(supplierRow(row))">{{ row.status === 'ACTIVE' ? '停用' : '启用' }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #name="{ row }"><LineClampText :content="row.name" /></template>
|
||||
<template #category="{ row }">{{ categoryLabels[row.category as SupplierCategory] }}</template>
|
||||
<template #carrierCodes="{ row }"><LineClampText :content="supplierRow(row).category === 'BOOKING' ? formatCarrierCodes(supplierRow(row).carrierCodes) : null" /></template>
|
||||
<template #license="{ row }"><el-button size="small" plain type="primary" @click="showLicense(supplierRow(row))"><FileText :size="15" />查看</el-button></template>
|
||||
<template #license="{ row }"><el-button data-tone="neutral" class="density-action" size="small" @click="showLicense(supplierRow(row))">查看</el-button></template>
|
||||
<template #status="{ row }"><StatusBadge :status="statusLabels[supplierRow(row).status] ?? '—'" /></template>
|
||||
<template #settlement="{ row }">{{ settlementLabels[supplierRow(row).settlementPeriod] }}</template>
|
||||
</DataTable>
|
||||
@@ -168,8 +164,7 @@ onActivated(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.supplier-list-top { display: grid; gap: 16px; }.supplier-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }.supplier-metrics button { min-width: 0; padding: 12px 14px; border: 1px solid #e7edf5; border-radius: 8px; background: #f8fafc; color: var(--cc-text); text-align: left; cursor: pointer; }.supplier-metrics button.active { border-color: var(--cc-primary); background: #f7f8ff; box-shadow: inset 0 3px 0 var(--cc-primary); }.supplier-metrics span { display: block; margin-bottom: 6px; color: #64748b; font-size: 12px; }.supplier-metrics strong { color: #1e293b; font-size: 20px; }.supplier-metrics small { margin-left: 3px; color: #64748b; font-size: 12px; }.supplier-query-panel { overflow: hidden; border: 1px solid var(--cc-border); border-radius: 8px; background: #fff; }.supplier-query-toolbar { border: 0; }.supplier-tabs { display: flex; gap: 6px; padding: 10px 14px; overflow-x: auto; border-bottom: 1px solid var(--cc-border); background: #fafbfc; }.supplier-tabs button { min-width: 76px; padding: 7px 20px; border: 0; border-radius: 6px; background: #f1f3f5; color: #555; cursor: pointer; }.supplier-tabs button.active { background: var(--cc-primary); color: #fff; font-weight: 650; }
|
||||
.row-actions { display: flex; align-items: center; white-space: nowrap; }.row-actions :deep(.el-button + .el-button) { margin-left: 8px; }
|
||||
.supplier-list-top { display: grid; gap: var(--admin-space-6); }.supplier-query-panel { overflow: hidden; border: 1px solid var(--cc-border); border-radius: var(--admin-radius); background: #fff; }.supplier-query-toolbar { border: 0; }
|
||||
@media (max-width: 720px) { .supplier-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||
@media (max-width: 380px) { .supplier-metrics { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user