208 lines
6.3 KiB
Vue
208 lines
6.3 KiB
Vue
<template>
|
|
<div class="catalog-ver">
|
|
<div class="ver-head">
|
|
<div class="ver-title">
|
|
<i class="ver-bar" />
|
|
<span class="ver-text">{{ title }}</span>
|
|
<el-tag size="small" type="info" effect="plain" round>{{ filteredVersions.length }}</el-tag>
|
|
</div>
|
|
<el-button
|
|
type="primary"
|
|
plain
|
|
size="small"
|
|
:disabled="hasDraft"
|
|
v-hasPermi="[createPerm]"
|
|
@click="emit('create')"
|
|
>{{ createLabel }}</el-button>
|
|
</div>
|
|
|
|
<el-tabs v-model="statusTab" class="ver-tabs">
|
|
<el-tab-pane :label="tabLabel('all')" name="all" />
|
|
<el-tab-pane :label="tabLabel('pending')" name="pending" />
|
|
<el-tab-pane :label="tabLabel('1')" name="1" />
|
|
<el-tab-pane :label="tabLabel('2')" name="2" />
|
|
</el-tabs>
|
|
|
|
<el-table v-loading="loading" :data="filteredVersions" border :empty-text="emptyText" @row-click="onRowClick">
|
|
<el-table-column :label="colNo" width="120">
|
|
<template #default="{ row }">
|
|
<el-button link type="primary" @click.stop="emit('view-products', row)">{{ row.versionNo || '-' }}</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column :label="colEff" min-width="170">
|
|
<template #default="{ row }">{{ row.effectiveTime || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column :label="colExp" min-width="170">
|
|
<template #default="{ row }">{{ row.expireTime || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column :label="colStatus" width="100" align="center">
|
|
<template #default="{ row }">
|
|
<el-tag :type="versionStatusTag(row.status)" size="small">{{ versionStatusLabel(row.status) }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column :label="colProducts" prop="productCount" width="90" align="center" />
|
|
<el-table-column :label="colRows" prop="detailCount" width="100" align="center" />
|
|
<el-table-column :label="colAction" width="420" align="center" fixed="right">
|
|
<template #default="{ row }">
|
|
<el-button link type="primary" @click.stop="emit('view-products', row)">{{ labViewProducts }}</el-button>
|
|
<el-button link type="primary" @click.stop="emit('view-attach', row)" v-hasPermi="[queryPerm]">{{ labViewAttach }}</el-button>
|
|
<el-button
|
|
v-if="showEditButton(row)"
|
|
link
|
|
type="primary"
|
|
@click.stop="emit('edit', row)"
|
|
>{{ labEdit }}</el-button>
|
|
<el-button
|
|
v-if="isDraftVersion(row)"
|
|
link
|
|
type="success"
|
|
@click.stop="emit('activate', row)"
|
|
v-hasPermi="[editPerm]"
|
|
>{{ labStart }}</el-button>
|
|
<el-button
|
|
v-if="isDraftVersion(row) || isPendingVersion(row) || isEffectVersion(row)"
|
|
link
|
|
type="danger"
|
|
:loading="isRemoving(row)"
|
|
:disabled="removingPsvId != null"
|
|
@click.stop="emit('remove', row)"
|
|
v-hasPermi="[removePerm]"
|
|
>{{ labDelete }}</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup name="CatalogVersionTable">
|
|
import {
|
|
versionStatusLabel,
|
|
versionStatusTag,
|
|
isDraftVersion,
|
|
isPendingVersion,
|
|
isEffectVersion,
|
|
isExpiredVersion,
|
|
isPriceEditableVersion
|
|
} from '@/views/price/set/utils/priceSet'
|
|
import { checkPermi } from '@/utils/permission'
|
|
|
|
const props = defineProps({
|
|
versions: { type: Array, default: () => [] },
|
|
loading: { type: Boolean, default: false },
|
|
title: { type: String, required: true },
|
|
createLabel: { type: String, required: true },
|
|
createPerm: { type: String, required: true },
|
|
editPerm: { type: String, required: true },
|
|
removePerm: { type: String, required: true },
|
|
queryPerm: { type: String, required: true },
|
|
removingPsvId: { type: [Number, String], default: null }
|
|
})
|
|
|
|
const emit = defineEmits(['create', 'edit', 'view-products', 'view-attach', 'activate', 'remove'])
|
|
|
|
const colNo = '版本号'
|
|
const colEff = '生效时间'
|
|
const colExp = '失效时间'
|
|
const colStatus = '状态'
|
|
const colProducts = '产品数'
|
|
const colRows = '明细行数'
|
|
const colAction = '操作'
|
|
const emptyText = '暂无版本'
|
|
const labViewProducts = '查看产品'
|
|
const labViewAttach = '查看附件'
|
|
const labEdit = '编辑'
|
|
const labStart = '启动'
|
|
const labDelete = '删除'
|
|
|
|
const statusTab = ref('all')
|
|
|
|
const counts = computed(() => {
|
|
const map = { all: 0, pending: 0, '1': 0, '2': 0 }
|
|
;(props.versions || []).forEach(v => {
|
|
map.all++
|
|
const st = String(v.status == null ? '' : v.status)
|
|
if (st === '0' || st === '3') map.pending++
|
|
else if (map[st] != null) map[st]++
|
|
})
|
|
return map
|
|
})
|
|
|
|
function tabLabel(key) {
|
|
const labels = {
|
|
all: '全部',
|
|
pending: '待生效',
|
|
'1': '已生效',
|
|
'2': '已失效'
|
|
}
|
|
return labels[key] + ' (' + (counts.value[key] || 0) + ')'
|
|
}
|
|
|
|
const hasDraft = computed(() => (props.versions || []).some(v => isDraftVersion(v)))
|
|
|
|
const filteredVersions = computed(() => {
|
|
const list = props.versions || []
|
|
if (statusTab.value === 'all') return list
|
|
if (statusTab.value === 'pending') {
|
|
return list.filter(v => {
|
|
const st = String(v.status == null ? '' : v.status)
|
|
return st === '0' || st === '3'
|
|
})
|
|
}
|
|
return list.filter(v => String(v.status) === statusTab.value)
|
|
})
|
|
|
|
function showEditButton(row) {
|
|
if (!checkPermi([props.editPerm])) return false
|
|
// draft / pending / effect / expired can edit
|
|
return isPriceEditableVersion(row) || isEffectVersion(row) || isExpiredVersion(row)
|
|
}
|
|
|
|
function isRemoving(row) {
|
|
return props.removingPsvId != null && row && String(props.removingPsvId) === String(row.psvId)
|
|
}
|
|
|
|
function onRowClick(row) {
|
|
emit('view-products', row)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.catalog-ver {
|
|
background: #fff;
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
border-radius: 8px;
|
|
padding: 12px 16px 16px;
|
|
}
|
|
.ver-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-bottom: 4px;
|
|
}
|
|
.ver-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
min-width: 0;
|
|
}
|
|
.ver-bar {
|
|
width: 3px;
|
|
height: 14px;
|
|
border-radius: 2px;
|
|
background: #52c41a;
|
|
flex: none;
|
|
}
|
|
.ver-text {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
}
|
|
.ver-tabs {
|
|
margin-bottom: 8px;
|
|
}
|
|
.ver-tabs :deep(.el-tabs__header) {
|
|
margin-bottom: 8px;
|
|
}
|
|
</style>
|