wz-management-fronted/src/views/art/school/modules/school-enroll-plan/index.vue

281 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="tsx">
import { computed, ref } from 'vue';
import { NButton, NDivider } from 'naive-ui';
import { useBoolean } from '@sa/hooks';
import { fetchBatchDeleteSchoolEnrollPlan, fetchGetSchoolEnrollPlanList } from '@/service/api/art/school-enroll-plan';
import { useAppStore } from '@/store/modules/app';
import { useAuth } from '@/hooks/business/auth';
import { useDownload } from '@/hooks/business/download';
import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table';
import { $t } from '@/locales';
import ButtonIcon from '@/components/custom/button-icon.vue';
import SchoolImportModal from '../school-import-modal.vue';
import SchoolEnrollPlanOperateDrawer from './modules/school-enroll-plan-operate-drawer.vue';
import SchoolEnrollPlanSearch from './modules/school-enroll-plan-search.vue';
defineOptions({
name: 'SchoolEnrollPlanList'
});
interface Props {
schoolId?: CommonType.IdType | null;
inModal?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
schoolId: null,
inModal: false
});
const appStore = useAppStore();
const { download } = useDownload();
const { hasAuth } = useAuth();
const { bool: importVisible, setTrue: openImportModal } = useBoolean();
const searchParams = ref<Api.Art.SchoolEnrollPlanSearchParams>({
pageNum: 1,
pageSize: 10,
schoolId: props.schoolId,
year: null,
province: null,
subjectType: null,
majorId: null,
majorName: null,
educationLevel: null,
planNum: null,
params: {}
});
const requestParams = computed<Api.Art.SchoolEnrollPlanSearchParams>(() => ({
...searchParams.value,
schoolId: props.schoolId ?? searchParams.value.schoolId
}));
const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagination, scrollX } =
useNaivePaginatedTable({
api: () => fetchGetSchoolEnrollPlanList(requestParams.value),
transform: response => defaultTransform(response),
onPaginationParamsChange: params => {
searchParams.value.pageNum = params.page;
searchParams.value.pageSize = params.pageSize;
},
columns: () => [
{
type: 'selection',
align: 'center',
width: 48
},
{
key: 'index',
title: $t('common.index'),
align: 'center',
width: 64,
render: (_, index) => index + 1
},
{
key: 'planId',
title: '主键ID',
align: 'center',
minWidth: 120
},
{
key: 'schoolId',
title: '学校ID',
align: 'center',
minWidth: 120
},
{
key: 'year',
title: '年份',
align: 'center',
minWidth: 120
},
{
key: 'province',
title: '招生省份',
align: 'center',
minWidth: 120
},
{
key: 'subjectType',
title: '分科:文/理/综(或物理/历史...)',
align: 'center',
minWidth: 120
},
{
key: 'majorId',
title: '专业ID(可选,有则填)',
align: 'center',
minWidth: 120
},
{
key: 'majorName',
title: '专业名称(冗余没专业ID也能落库)',
align: 'center',
minWidth: 120
},
{
key: 'educationLevel',
title: '学历层次:本科/专科',
align: 'center',
minWidth: 120
},
{
key: 'planNum',
title: '计划数',
align: 'center',
minWidth: 120
},
{
key: 'remark',
title: '备注',
align: 'center',
minWidth: 120
},
{
key: 'operate',
fixed: 'right',
title: $t('common.operate'),
align: 'center',
width: 130,
render: row => {
const divider = () => {
if (!hasAuth('art:schoolEnrollPlan:edit') || !hasAuth('art:schoolEnrollPlan:remove')) {
return null;
}
return <NDivider vertical />;
};
const editBtn = () => {
if (!hasAuth('art:schoolEnrollPlan:edit')) {
return null;
}
return (
<ButtonIcon
text
type="primary"
icon="material-symbols:drive-file-rename-outline-outline"
tooltipContent={$t('common.edit')}
onClick={() => edit(row.planId)}
/>
);
};
const deleteBtn = () => {
if (!hasAuth('art:schoolEnrollPlan:remove')) {
return null;
}
return (
<ButtonIcon
text
type="error"
icon="material-symbols:delete-outline"
tooltipContent={$t('common.delete')}
popconfirmContent={$t('common.confirmDelete')}
onPositiveClick={() => handleDelete(row.planId)}
/>
);
};
return (
<div class="flex-center gap-8px">
{editBtn()}
{divider()}
{deleteBtn()}
</div>
);
}
}
]
});
const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } =
useTableOperate(data, 'planId', getData);
async function handleBatchDelete() {
// request
const { error } = await fetchBatchDeleteSchoolEnrollPlan(checkedRowKeys.value);
if (error) return;
onBatchDeleted();
}
async function handleDelete(planId: CommonType.IdType) {
// request
const { error } = await fetchBatchDeleteSchoolEnrollPlan([planId]);
if (error) return;
onDeleted();
}
function edit(planId: CommonType.IdType) {
handleEdit(planId);
}
function handleExport() {
download('/art/schoolEnrollPlan/export', requestParams.value, `学校招生计划_${new Date().getTime()}.xlsx`);
}
function handleImport() {
openImportModal();
}
</script>
<template>
<div
:class="
props.inModal
? 'flex-col-stretch gap-16px'
: 'min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto'
"
>
<SchoolEnrollPlanSearch v-model:model="searchParams" @search="getDataByPage" />
<NCard title="学校招生计划列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
<template #header-extra>
<TableHeaderOperation
v-model:columns="columnChecks"
:disabled-delete="checkedRowKeys.length === 0"
:loading="loading"
:show-add="hasAuth('art:schoolEnrollPlan:add')"
:show-delete="hasAuth('art:schoolEnrollPlan:remove')"
:show-export="hasAuth('art:schoolEnrollPlan:export')"
@add="handleAdd"
@delete="handleBatchDelete"
@export="handleExport"
@refresh="getData"
>
<template #after>
<NButton v-if="hasAuth('art:school:import')" size="small" ghost @click="handleImport">
<template #icon>
<icon-material-symbols-upload-rounded class="text-icon" />
</template>
{{ $t('common.import') }}
</NButton>
</template>
</TableHeaderOperation>
</template>
<NDataTable
v-model:checked-row-keys="checkedRowKeys"
:columns="columns"
:data="data"
size="small"
:flex-height="!appStore.isMobile && !props.inModal"
:scroll-x="scrollX"
:loading="loading"
remote
:row-key="row => row.planId"
:pagination="mobilePagination"
class="sm:h-full"
/>
<SchoolEnrollPlanOperateDrawer
v-model:visible="drawerVisible"
:operate-type="operateType"
:row-data="editingData"
:default-school-id="props.schoolId"
@submitted="getDataByPage"
/>
<SchoolImportModal v-model:visible="importVisible" @submitted="getDataByPage" />
</NCard>
</div>
</template>
<style scoped></style>