<script setup lang="tsx">
|
import type { DataTableColumns } from 'naive-ui'
|
import { NButton, NSpace, NTooltip } from 'naive-ui'
|
import { computed, onActivated, onMounted, ref } from 'vue'
|
import { useRouter } from 'vue-router'
|
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
|
import Pagination from '@/components/common/Pagination.vue'
|
import SearchPanel from '@/components/custom/SearchPanel.vue'
|
import { useBoolean } from '@/hooks'
|
import { deleteTestPlanById, fetchTestPlanPageList } from '@/service/api/copyText'
|
|
const router = useRouter()
|
const dialog = useDialog()
|
const message = useMessage()
|
|
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
|
|
interface TestPlanRow {
|
id: number
|
planName: string
|
pointNum: number
|
vehicleNum: number
|
orderNum: number
|
}
|
|
|
const initialModel = {
|
planName: '',
|
}
|
const model = ref({ ...initialModel })
|
|
const pageParams = ref({
|
pageNum: 1,
|
pageSize: 10,
|
})
|
const count = ref(0)
|
const listData = ref<TestPlanRow[]>([])
|
|
const tableScrollX = 1000
|
|
function handleResetSearch() {
|
model.value = { ...initialModel }
|
pageParams.value.pageNum = 1
|
getList()
|
}
|
|
async function getList() {
|
startLoading()
|
try {
|
const planName = model.value.planName?.trim()
|
const res = await fetchTestPlanPageList({
|
...pageParams.value,
|
planName: planName || undefined,
|
})
|
if (res.code === 200) {
|
listData.value = res.data?.records || []
|
count.value = res.data?.total || 0
|
return
|
}
|
listData.value = []
|
count.value = 0
|
}
|
finally {
|
endLoading()
|
}
|
}
|
|
function changePage(page: number, size: number) {
|
pageParams.value.pageNum = page
|
pageParams.value.pageSize = size
|
getList()
|
}
|
|
function handleSearch() {
|
pageParams.value.pageNum = 1
|
getList()
|
}
|
|
function handleAdd() {
|
router.push({ name: 'testPlanAdd' })
|
}
|
|
const showOperationLogModal = ref(false)
|
|
function handleOpenOperationLog() {
|
showOperationLogModal.value = true
|
}
|
|
function handleDetail(row: TestPlanRow) {
|
router.push({ name: 'testPlanAdd', query: { id: String(row.id), mode: 'detail' } })
|
}
|
|
function handleEdit(row: TestPlanRow) {
|
router.push({ name: 'testPlanAdd', query: { id: String(row.id), mode: 'edit' } })
|
}
|
|
function handleDelete(row: TestPlanRow) {
|
dialog.create({
|
title: '确认删除该测试计划吗?',
|
content: '',
|
positiveText: '确定',
|
negativeText: '取消',
|
maskClosable: false,
|
autoFocus: false,
|
onPositiveClick: async () => {
|
const res = await deleteTestPlanById(row.id)
|
if (res.code === 200) {
|
message.success('删除成功')
|
getList()
|
}
|
},
|
})
|
}
|
|
const columns = computed<DataTableColumns<TestPlanRow>>(() => [
|
{
|
title: '计划ID',
|
key: 'id',
|
width: 120,
|
align: 'left',
|
resizable: true,
|
ellipsis: true,
|
},
|
{
|
title: '计划名称',
|
key: 'planName',
|
width: 260,
|
align: 'left',
|
resizable: true,
|
ellipsis: true,
|
render(row) {
|
return (
|
<NTooltip trigger="hover">
|
{{
|
trigger: () => (
|
<div
|
class="cursor-pointer text-ellipsis whitespace-nowrap w-full overflow-hidden text-[#0068FF]"
|
onClick={() => handleDetail(row)}
|
>
|
{row.planName}
|
</div>
|
),
|
default: () => row.planName,
|
}}
|
</NTooltip>
|
)
|
},
|
},
|
{
|
title: '关联点位数',
|
key: 'pointNum',
|
width: 140,
|
align: 'left',
|
resizable: true,
|
ellipsis: true,
|
},
|
{
|
title: '关联订单数',
|
key: 'orderNum',
|
width: 140,
|
align: 'left',
|
resizable: true,
|
ellipsis: true,
|
},
|
{
|
title: '关联车辆数',
|
key: 'vehicleNum',
|
width: 140,
|
align: 'left',
|
resizable: true,
|
ellipsis: true,
|
},
|
{
|
title: '操作',
|
key: 'actions',
|
width: 200,
|
align: 'left',
|
fixed: 'right',
|
render: (row: TestPlanRow) => {
|
return (
|
<NSpace justify="start">
|
<NButton v-permission="112" text type="primary" onClick={() => handleDetail(row)}>
|
详情
|
</NButton>
|
<NButton v-permission="113" text type="primary" onClick={() => handleEdit(row)}>
|
编辑
|
</NButton>
|
<NButton v-permission="114" text type="primary" onClick={() => handleDelete(row)}>
|
删除
|
</NButton>
|
</NSpace>
|
)
|
},
|
},
|
])
|
|
const filterItems = computed(() => [
|
{
|
label: '计划名称',
|
path: 'planName',
|
render: () => <n-input v-model:value={model.value.planName} placeholder="请输入" clearable />,
|
},
|
])
|
|
onMounted(() => {
|
getList()
|
})
|
|
onActivated(() => {
|
if (window.sessionStorage.getItem('testPlanListNeedRefresh') === '1') {
|
window.sessionStorage.removeItem('testPlanListNeedRefresh')
|
getList()
|
}
|
})
|
</script>
|
|
<template>
|
<div class="roboTaxi">
|
<div class="roboTaxi-form-card mb-12px">
|
<n-form :model="model" label-placement="left" inline :show-feedback="false">
|
<SearchPanel>
|
<n-gi v-for="item in filterItems" :key="item.path">
|
<n-form-item :label="item.label" :path="item.path">
|
<component :is="item.render" />
|
</n-form-item>
|
</n-gi>
|
<template #action>
|
<NButton @click="handleResetSearch">
|
{{ $t('common.reset') }}
|
</NButton>
|
<NButton type="primary" @click="handleSearch">
|
{{ $t('common.search') }}
|
</NButton>
|
</template>
|
</SearchPanel>
|
</n-form>
|
</div>
|
|
<n-card
|
class="flex-1 robotaxi-table-card"
|
content-style="display: flex; flex-direction: column; flex: 1; min-height: 0; min-width: 0;"
|
>
|
<template #header>
|
<n-flex justify="space-between">
|
<NButton v-permission="115" @click="handleOpenOperationLog">
|
操作日志
|
</NButton>
|
<NButton v-permission="111" type="primary" secondary @click="handleAdd">
|
添加测试计划
|
</NButton>
|
</n-flex>
|
</template>
|
|
<div class="flex-1 flex flex-col h-full" style="min-width: 0; overflow: hidden">
|
<n-data-table
|
class="flex-1"
|
:columns="columns"
|
:data="listData"
|
:loading="loading"
|
flex-height
|
:bordered="false"
|
:scroll-x="tableScrollX"
|
:header-height="18"
|
:row-height="18"
|
>
|
<template #empty>
|
<div class="flex-center">
|
<img src="/src/assets/element-img/no-data.png" style="width:123px;height:125px">
|
</div>
|
</template>
|
</n-data-table>
|
<Pagination
|
:count="count"
|
:page="pageParams.pageNum"
|
:page-size="pageParams.pageSize"
|
class="robotaxi-pagination mt-12px"
|
@change="changePage"
|
/>
|
</div>
|
</n-card>
|
|
<OperationLogModal v-model:show="showOperationLogModal" />
|
</div>
|
</template>
|
|
<style scoped></style>
|