400 lines
10 KiB
Vue
400 lines
10 KiB
Vue
<template>
|
|
<ArtTableFullScreen>
|
|
<div class="asset-allocation-records-page" id="table-full-screen">
|
|
<!-- 搜索栏 -->
|
|
<ArtSearchBar
|
|
v-model:filter="formFilters"
|
|
:items="formItems"
|
|
label-width="90"
|
|
@reset="handleReset"
|
|
@search="handleSearch"
|
|
></ArtSearchBar>
|
|
|
|
<ElCard shadow="never" class="art-table-card">
|
|
<!-- 表格头部 -->
|
|
<ArtTableHeader
|
|
:columnList="columnOptions"
|
|
v-model:columns="columnChecks"
|
|
@refresh="handleRefresh"
|
|
/>
|
|
|
|
<!-- 表格 -->
|
|
<ArtTable
|
|
ref="tableRef"
|
|
row-key="id"
|
|
:loading="loading"
|
|
:data="recordList"
|
|
:currentPage="pagination.page"
|
|
:pageSize="pagination.pageSize"
|
|
:total="pagination.total"
|
|
:marginTop="10"
|
|
:row-class-name="getRowClassName"
|
|
@size-change="handleSizeChange"
|
|
@current-change="handleCurrentChange"
|
|
@row-contextmenu="handleRowContextMenu"
|
|
@cell-mouse-enter="handleCellMouseEnter"
|
|
@cell-mouse-leave="handleCellMouseLeave"
|
|
>
|
|
<template #default>
|
|
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
|
</template>
|
|
</ArtTable>
|
|
|
|
<!-- 鼠标悬浮提示 -->
|
|
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
|
|
|
|
<!-- 右键菜单 -->
|
|
<ArtMenuRight
|
|
ref="contextMenuRef"
|
|
:menu-items="contextMenuItems"
|
|
:menu-width="120"
|
|
@select="handleContextMenuSelect"
|
|
/>
|
|
</ElCard>
|
|
</div>
|
|
</ArtTableFullScreen>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { h } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { CardService } from '@/api/modules'
|
|
import { ElMessage, ElTag } from 'element-plus'
|
|
import type { SearchFormItem } from '@/types'
|
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
|
import { useAuth } from '@/composables/useAuth'
|
|
import { useTableContextMenu } from '@/composables/useTableContextMenu'
|
|
import { formatDateTime } from '@/utils/business/format'
|
|
import type { AssetAllocationRecord, AllocationTypeEnum, AssetTypeEnum } from '@/types/api/card'
|
|
import { RoutesAlias } from '@/router/routesAlias'
|
|
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
|
|
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
|
|
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
|
|
|
|
defineOptions({ name: 'AssetAllocationRecords' })
|
|
|
|
const { hasAuth } = useAuth()
|
|
const router = useRouter()
|
|
|
|
// 使用表格右键菜单功能
|
|
const {
|
|
showContextMenuHint,
|
|
hintPosition,
|
|
getRowClassName,
|
|
handleCellMouseEnter,
|
|
handleCellMouseLeave
|
|
} = useTableContextMenu()
|
|
|
|
const loading = ref(false)
|
|
const tableRef = ref()
|
|
const contextMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
|
|
const currentRow = ref<AssetAllocationRecord | null>(null)
|
|
|
|
// 搜索表单初始值
|
|
const initialSearchState = {
|
|
allocation_type: undefined as AllocationTypeEnum | undefined,
|
|
asset_type: undefined as AssetTypeEnum | undefined,
|
|
asset_identifier: '',
|
|
allocation_no: '',
|
|
from_shop_id: undefined as number | undefined,
|
|
to_shop_id: undefined as number | undefined,
|
|
operator_id: undefined as number | undefined,
|
|
created_at_start: '',
|
|
created_at_end: ''
|
|
}
|
|
|
|
// 搜索表单
|
|
const formFilters = reactive({ ...initialSearchState })
|
|
|
|
// 分页
|
|
const pagination = reactive({
|
|
page: 1,
|
|
pageSize: 20,
|
|
total: 0
|
|
})
|
|
|
|
// 搜索表单配置
|
|
const formItems: SearchFormItem[] = [
|
|
{
|
|
label: '分配类型',
|
|
prop: 'allocation_type',
|
|
type: 'select',
|
|
config: {
|
|
clearable: true,
|
|
placeholder: '全部'
|
|
},
|
|
options: () => [
|
|
{ label: '分配', value: 'allocate' },
|
|
{ label: '回收', value: 'recall' }
|
|
]
|
|
},
|
|
{
|
|
label: '资产类型',
|
|
prop: 'asset_type',
|
|
type: 'select',
|
|
config: {
|
|
clearable: true,
|
|
placeholder: '全部'
|
|
},
|
|
options: () => [
|
|
{ label: '物联网卡', value: 'iot_card' },
|
|
{ label: '设备', value: 'device' }
|
|
]
|
|
},
|
|
{
|
|
label: '分配单号',
|
|
prop: 'allocation_no',
|
|
type: 'input',
|
|
config: {
|
|
clearable: true,
|
|
placeholder: '请输入分配单号'
|
|
}
|
|
},
|
|
{
|
|
label: '资产标识符',
|
|
prop: 'asset_identifier',
|
|
type: 'input',
|
|
config: {
|
|
clearable: true,
|
|
placeholder: 'ICCID或设备号'
|
|
}
|
|
},
|
|
{
|
|
label: '创建时间',
|
|
prop: 'created_at_range',
|
|
type: 'date',
|
|
config: {
|
|
type: 'datetimerange',
|
|
clearable: true,
|
|
startPlaceholder: '开始时间',
|
|
endPlaceholder: '结束时间',
|
|
valueFormat: 'YYYY-MM-DDTHH:mm:ssZ'
|
|
}
|
|
}
|
|
]
|
|
|
|
// 列配置
|
|
const columnOptions = [
|
|
{ label: '分配单号', prop: 'allocation_no' },
|
|
{ label: '分配类型', prop: 'allocation_name' },
|
|
{ label: '资产类型', prop: 'asset_type_name' },
|
|
{ label: '资产标识符', prop: 'asset_identifier' },
|
|
{ label: '来源所有者', prop: 'from_owner_name' },
|
|
{ label: '目标所有者', prop: 'to_owner_name' },
|
|
{ label: '操作人', prop: 'operator_name' },
|
|
{ label: '关联卡数量', prop: 'related_card_count' },
|
|
{ label: '创建时间', prop: 'created_at' }
|
|
]
|
|
|
|
const recordList = ref<AssetAllocationRecord[]>([])
|
|
|
|
// 获取分配类型标签类型
|
|
const getAllocationTypeType = (type: AllocationTypeEnum) => {
|
|
return type === 'allocate' ? 'success' : 'warning'
|
|
}
|
|
|
|
// 获取资产类型标签类型
|
|
const getAssetTypeType = (type: AssetTypeEnum) => {
|
|
return type === 'iot_card' ? 'primary' : 'info'
|
|
}
|
|
|
|
// 动态列配置
|
|
const { columnChecks, columns } = useCheckedColumns(() => [
|
|
{
|
|
prop: 'allocation_no',
|
|
label: '分配单号',
|
|
minWidth: 200,
|
|
formatter: (row: AssetAllocationRecord) => {
|
|
return h(
|
|
'span',
|
|
{
|
|
style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
|
|
onClick: (e: MouseEvent) => {
|
|
e.stopPropagation()
|
|
handleNameClick(row)
|
|
}
|
|
},
|
|
row.allocation_no
|
|
)
|
|
}
|
|
},
|
|
{
|
|
prop: 'allocation_name',
|
|
label: '分配类型',
|
|
width: 100,
|
|
formatter: (row: AssetAllocationRecord) => {
|
|
return h(
|
|
ElTag,
|
|
{ type: getAllocationTypeType(row.allocation_type) },
|
|
() => row.allocation_name
|
|
)
|
|
}
|
|
},
|
|
{
|
|
prop: 'asset_type_name',
|
|
label: '资产类型',
|
|
width: 100,
|
|
formatter: (row: AssetAllocationRecord) => {
|
|
return h(ElTag, { type: getAssetTypeType(row.asset_type) }, () => row.asset_type_name)
|
|
}
|
|
},
|
|
{
|
|
prop: 'asset_identifier',
|
|
label: '资产标识符',
|
|
minWidth: 200
|
|
},
|
|
{
|
|
prop: 'from_owner_name',
|
|
label: '来源所有者',
|
|
width: 150
|
|
},
|
|
{
|
|
prop: 'to_owner_name',
|
|
label: '目标所有者',
|
|
width: 150
|
|
},
|
|
{
|
|
prop: 'operator_name',
|
|
label: '操作人',
|
|
width: 120
|
|
},
|
|
{
|
|
prop: 'related_card_count',
|
|
label: '关联卡数量',
|
|
width: 120
|
|
},
|
|
{
|
|
prop: 'remark',
|
|
label: '备注',
|
|
minWidth: 150,
|
|
showOverflowTooltip: true
|
|
},
|
|
{
|
|
prop: 'created_at',
|
|
label: '创建时间',
|
|
width: 180,
|
|
formatter: (row: AssetAllocationRecord) => formatDateTime(row.created_at)
|
|
}
|
|
])
|
|
|
|
onMounted(() => {
|
|
getTableData()
|
|
})
|
|
|
|
// 获取分配记录列表
|
|
const getTableData = async () => {
|
|
loading.value = true
|
|
try {
|
|
const params = {
|
|
page: pagination.page,
|
|
page_size: pagination.pageSize,
|
|
...formFilters
|
|
}
|
|
|
|
// 处理日期范围
|
|
if ((params as any).created_at_range && (params as any).created_at_range.length === 2) {
|
|
params.created_at_start = (params as any).created_at_range[0]
|
|
params.created_at_end = (params as any).created_at_range[1]
|
|
delete (params as any).created_at_range
|
|
}
|
|
|
|
// 清理空值
|
|
Object.keys(params).forEach((key) => {
|
|
if (params[key] === '' || params[key] === undefined) {
|
|
delete params[key]
|
|
}
|
|
})
|
|
|
|
const res = await CardService.getAssetAllocationRecords(params)
|
|
if (res.code === 0) {
|
|
recordList.value = res.data.items || []
|
|
pagination.total = res.data.total || 0
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
ElMessage.error('获取分配记录列表失败')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 重置搜索
|
|
const handleReset = () => {
|
|
Object.assign(formFilters, { ...initialSearchState })
|
|
pagination.page = 1
|
|
getTableData()
|
|
}
|
|
|
|
// 搜索
|
|
const handleSearch = () => {
|
|
pagination.page = 1
|
|
getTableData()
|
|
}
|
|
|
|
// 刷新表格
|
|
const handleRefresh = () => {
|
|
getTableData()
|
|
}
|
|
|
|
// 处理表格分页变化
|
|
const handleSizeChange = (newPageSize: number) => {
|
|
pagination.pageSize = newPageSize
|
|
getTableData()
|
|
}
|
|
|
|
const handleCurrentChange = (newCurrentPage: number) => {
|
|
pagination.page = newCurrentPage
|
|
getTableData()
|
|
}
|
|
|
|
// 查看详情
|
|
const viewDetail = (row: AssetAllocationRecord) => {
|
|
router.push({
|
|
path: `${RoutesAlias.AssetAssign}/detail/${row.id}`
|
|
})
|
|
}
|
|
|
|
// 处理名称点击
|
|
const handleNameClick = (row: AssetAllocationRecord) => {
|
|
if (hasAuth('asset_assign:view_detail')) {
|
|
viewDetail(row)
|
|
} else {
|
|
ElMessage.warning('您没有查看详情的权限')
|
|
}
|
|
}
|
|
|
|
// 右键菜单项配置
|
|
const contextMenuItems = computed((): MenuItemType[] => {
|
|
const items: MenuItemType[] = []
|
|
|
|
return items
|
|
})
|
|
|
|
// 处理表格行右键菜单
|
|
const handleRowContextMenu = (row: AssetAllocationRecord, column: any, event: MouseEvent) => {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
currentRow.value = row
|
|
contextMenuRef.value?.show(event)
|
|
}
|
|
|
|
// 处理右键菜单选择
|
|
const handleContextMenuSelect = (item: MenuItemType) => {
|
|
if (!currentRow.value) return
|
|
|
|
switch (item.key) {
|
|
// No cases available
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.asset-allocation-records-page {
|
|
// Allocation records page styles
|
|
}
|
|
|
|
:deep(.el-table__row.table-row-with-context-menu) {
|
|
cursor: pointer;
|
|
}
|
|
</style>
|