From 3fdcf1d5e6468c735532e67bde5ff1cdf85bb0c6 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 30 三月 2026 09:14:16 +0800
Subject: [PATCH] refactor: simplify role page and fix pagination keys
---
rsf-design/src/views/system/role/index.vue | 409 ++++++++++++++++------------------------------------------
1 files changed, 115 insertions(+), 294 deletions(-)
diff --git a/rsf-design/src/views/system/role/index.vue b/rsf-design/src/views/system/role/index.vue
index b6787aa..49d2e34 100644
--- a/rsf-design/src/views/system/role/index.vue
+++ b/rsf-design/src/views/system/role/index.vue
@@ -20,6 +20,7 @@
<ElButton v-auth="'add'" @click="showDialog('add')" v-ripple>鏂板瑙掕壊</ElButton>
<ElButton
v-auth="'delete'"
+ type="danger"
:disabled="selectedRows.length === 0"
@click="handleBatchDelete"
v-ripple
@@ -85,13 +86,14 @@
fetchUpdateRole
} from '@/api/system-manage'
import { useTable } from '@/hooks/core/useTable'
+ import { useCrudPage } from '@/views/system/common/useCrudPage'
+ import { usePrintExportPage } from '@/views/system/common/usePrintExportPage'
import ListExportPrint from '@/components/biz/list-export-print/index.vue'
import RoleSearch from './modules/role-search.vue'
import RoleEditDialog from './modules/role-edit-dialog.vue'
import RolePermissionDialog from './modules/role-permission-dialog.vue'
- import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue'
+ import { createRoleTableColumns } from './roleTable.columns'
import { defaultResponseAdapter } from '@/utils/table/tableUtils'
- import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
import {
buildRoleDialogModel,
buildRolePageQueryParams,
@@ -100,7 +102,7 @@
buildRoleSavePayload,
buildRoleSearchParams,
createRoleSearchState,
- getRoleStatusMeta,
+ getRolePaginationKey,
normalizeRoleListRow,
ROLE_REPORT_STYLE,
ROLE_REPORT_TITLE,
@@ -111,184 +113,19 @@
const searchForm = ref(createRoleSearchState())
const showSearchBar = ref(false)
- const dialogVisible = ref(false)
- const dialogType = ref('add')
- const currentRoleData = ref(buildRoleDialogModel())
const permissionDialogVisible = ref(false)
const permissionScopeType = ref('menu')
- const selectedRows = ref([])
- const previewVisible = ref(false)
- const previewRows = ref([])
- const previewMeta = ref({})
- const previewToken = ref(0)
- const activePrintToken = ref(0)
const userStore = useUserStore()
const reportTitle = ROLE_REPORT_TITLE
const reportQueryParams = computed(() => buildRoleSearchParams(searchForm.value))
- const {
- columns,
- columnChecks,
- data,
- loading,
- pagination,
- getData,
- replaceSearchParams,
- resetSearchParams,
- handleSizeChange,
- handleCurrentChange,
- refreshData,
- refreshCreate,
- refreshUpdate,
- refreshRemove
- } = useTable({
- core: {
- apiFn: fetchRolePage,
- apiParams: buildRolePageQueryParams(searchForm.value),
- columnsFactory: () => [
- { type: 'selection', width: 52, fixed: 'left' },
- {
- prop: 'name',
- label: '瑙掕壊鍚嶇О',
- minWidth: 140,
- showOverflowTooltip: true
- },
- {
- prop: 'code',
- label: '瑙掕壊缂栫爜',
- minWidth: 140,
- showOverflowTooltip: true
- },
- {
- prop: 'memo',
- label: '澶囨敞',
- minWidth: 180,
- showOverflowTooltip: true
- },
- {
- prop: 'status',
- label: '鐘舵��',
- width: 120,
- formatter: (row) => {
- const statusMeta = getRoleStatusMeta(row.statusBool ?? row.status)
- return h(ElTag, { type: statusMeta.type, effect: 'light' }, () => statusMeta.text)
- }
- },
- {
- prop: 'updateTimeText',
- label: '鏇存柊鏃堕棿',
- minWidth: 180,
- sortable: true,
- formatter: (row) => row.updateTimeText || '-'
- },
- {
- prop: 'createTimeText',
- label: '鍒涘缓鏃堕棿',
- minWidth: 180,
- sortable: true,
- formatter: (row) => row.createTimeText || '-'
- },
- {
- prop: 'operation',
- label: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- formatter: (row) =>
- h('div', [
- h(ArtButtonMore, {
- list: [
- {
- key: 'scope-menu',
- label: '缃戦〉鏉冮檺',
- icon: 'ri:layout-2-line',
- auth: 'edit'
- },
- {
- key: 'scope-pda',
- label: 'PDA鏉冮檺',
- icon: 'ri:smartphone-line',
- auth: 'edit'
- },
- {
- key: 'scope-matnr',
- label: '鐗╂枡鏉冮檺',
- icon: 'ri:archive-line',
- auth: 'edit'
- },
- {
- key: 'scope-warehouse',
- label: '浠撳簱鏉冮檺',
- icon: 'ri:store-2-line',
- auth: 'edit'
- },
- {
- key: 'edit',
- label: '缂栬緫瑙掕壊',
- icon: 'ri:edit-2-line',
- auth: 'edit'
- },
- {
- key: 'delete',
- label: '鍒犻櫎瑙掕壊',
- icon: 'ri:delete-bin-4-line',
- color: '#f56c6c',
- auth: 'delete'
- }
- ],
- onClick: (item) => handleActionClick(item, row)
- })
- ])
- }
- ]
- },
- transform: {
- dataTransformer: (records) => {
- if (!Array.isArray(records)) {
- return []
- }
- return records.map((item) => normalizeRoleListRow(item))
- }
- }
- })
-
- const roleReportColumns = computed(() => resolveRoleReportColumns(columns.value))
- const resolvedPreviewMeta = computed(() =>
- buildRoleReportMeta({
- previewMeta: previewMeta.value,
- count: previewRows.value.length,
- titleAlign: ROLE_REPORT_STYLE.titleAlign,
- titleLevel: ROLE_REPORT_STYLE.titleLevel
- })
- )
-
- const handleSearch = (params) => {
- replaceSearchParams(buildRoleSearchParams(params))
- getData()
+ function openScopeDialog(scopeType, row) {
+ permissionScopeType.value = scopeType
+ currentRoleData.value = buildRoleDialogModel(row)
+ permissionDialogVisible.value = true
}
- const handleReset = () => {
- Object.assign(searchForm.value, createRoleSearchState())
- resetSearchParams()
- }
-
- const handleSelectionChange = (rows) => {
- selectedRows.value = Array.isArray(rows) ? rows : []
- }
-
- const handlePreviewVisibleChange = (visible) => {
- previewVisible.value = Boolean(visible)
- if (!visible) {
- activePrintToken.value = 0
- }
- }
-
- const showDialog = (type, row) => {
- dialogType.value = type
- currentRoleData.value = type === 'edit' ? buildRoleDialogModel(row) : buildRoleDialogModel()
- dialogVisible.value = true
- }
-
- const handleActionClick = (item, row) => {
+ function handleActionClick(item, row) {
switch (item.key) {
case 'scope-menu':
openScopeDialog('menu', row)
@@ -313,137 +150,121 @@
}
}
- const openScopeDialog = (scopeType, row) => {
- permissionScopeType.value = scopeType
- currentRoleData.value = buildRoleDialogModel(row)
- permissionDialogVisible.value = true
- }
-
- const handleDialogSubmit = async (formData) => {
- const payload = buildRoleSavePayload(formData)
- try {
- if (dialogType.value === 'edit') {
- await fetchUpdateRole(payload)
- ElMessage.success('淇敼鎴愬姛')
- dialogVisible.value = false
- currentRoleData.value = buildRoleDialogModel()
- await refreshUpdate()
- return
+ const {
+ columns,
+ columnChecks,
+ data,
+ loading,
+ pagination,
+ getData,
+ replaceSearchParams,
+ resetSearchParams,
+ handleSizeChange,
+ handleCurrentChange,
+ refreshData,
+ refreshCreate,
+ refreshUpdate,
+ refreshRemove
+ } = useTable({
+ core: {
+ apiFn: fetchRolePage,
+ apiParams: buildRolePageQueryParams(searchForm.value),
+ paginationKey: getRolePaginationKey(),
+ columnsFactory: () => createRoleTableColumns(handleActionClick)
+ },
+ transform: {
+ dataTransformer: (records) => {
+ if (!Array.isArray(records)) {
+ return []
+ }
+ return records.map((item) => normalizeRoleListRow(item))
}
- await fetchSaveRole(payload)
- ElMessage.success('鏂板鎴愬姛')
- dialogVisible.value = false
- currentRoleData.value = buildRoleDialogModel()
- await refreshCreate()
- } catch (error) {
- ElMessage.error(error?.message || '鎻愪氦澶辫触')
+ }
+ })
+
+ const {
+ dialogVisible,
+ dialogType,
+ currentRecord: currentRoleData,
+ selectedRows,
+ handleSelectionChange,
+ showDialog,
+ handleDialogSubmit,
+ handleDelete,
+ handleBatchDelete
+ } = useCrudPage({
+ createEmptyModel: () => buildRoleDialogModel(),
+ buildEditModel: (record) => buildRoleDialogModel(record),
+ buildSavePayload: (formData) => buildRoleSavePayload(formData),
+ saveRequest: fetchSaveRole,
+ updateRequest: fetchUpdateRole,
+ deleteRequest: fetchDeleteRole,
+ entityName: '瑙掕壊',
+ resolveRecordLabel: (record) => record?.name || record?.code || record?.id,
+ refreshCreate,
+ refreshUpdate,
+ refreshRemove
+ })
+
+ const buildPreviewDialogMeta = (rows) => {
+ const now = new Date()
+ return {
+ reportTitle,
+ reportDate: now.toLocaleDateString('zh-CN'),
+ printedAt: now.toLocaleString('zh-CN', { hour12: false }),
+ operator: userStore.getUserInfo?.name || userStore.getUserInfo?.username || '',
+ count: rows.length
}
}
- const handleDelete = async (row) => {
- try {
- await ElMessageBox.confirm(`纭畾瑕佸垹闄よ鑹层��${row.name || row.code || row.id}銆嶅悧锛焋, '鍒犻櫎纭', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
- await fetchDeleteRole(row.id)
- ElMessage.success('鍒犻櫎鎴愬姛')
- await refreshRemove()
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error(error?.message || '鍒犻櫎澶辫触')
- }
- }
+ const resolvePrintRecords = async (payload) => {
+ const response = Array.isArray(payload?.ids) && payload.ids.length > 0
+ ? await fetchGetRoleMany(payload.ids)
+ : await fetchRolePrintPage({
+ ...reportQueryParams.value,
+ current: 1,
+ pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20
+ })
+ return defaultResponseAdapter(response).records
}
- const handleBatchDelete = async () => {
- if (!selectedRows.value.length) return
- const ids = selectedRows.value.map((item) => item.id).filter((id) => id !== void 0 && id !== null)
- if (!ids.length) return
-
- try {
- await ElMessageBox.confirm(`纭畾瑕佹壒閲忓垹闄ら�変腑鐨� ${ids.length} 涓鑹插悧锛焋, '鎵归噺鍒犻櫎纭', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
- await fetchDeleteRole(ids.join(','))
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
- selectedRows.value = []
- await refreshRemove()
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error(error?.message || '鎵归噺鍒犻櫎澶辫触')
- }
- }
- }
-
- const handleExport = async (payload) => {
- try {
- const response = await fetchExportRoleReport(payload, {
+ const {
+ previewVisible,
+ previewRows,
+ previewMeta,
+ handlePreviewVisibleChange,
+ handleExport,
+ handlePrint
+ } = usePrintExportPage({
+ downloadFileName: 'role.xlsx',
+ requestExport: (payload) =>
+ fetchExportRoleReport(payload, {
headers: {
Authorization: userStore.accessToken || ''
}
- })
- if (!response.ok) {
- throw new Error(`瀵煎嚭澶辫触 (${response.status})`)
- }
- const blob = await response.blob()
- const downloadUrl = window.URL.createObjectURL(blob)
- const link = document.createElement('a')
- link.href = downloadUrl
- link.download = 'role.xlsx'
- document.body.appendChild(link)
- link.click()
- link.remove()
- window.URL.revokeObjectURL(downloadUrl)
- ElMessage.success('瀵煎嚭鎴愬姛')
- } catch (error) {
- ElMessage.error(error?.message || '瀵煎嚭澶辫触')
- }
+ }),
+ resolvePrintRecords,
+ buildPreviewRows: (records) => buildRolePrintRows(records),
+ buildPreviewMeta: (rows) => buildPreviewDialogMeta(rows)
+ })
+
+ const roleReportColumns = computed(() => resolveRoleReportColumns(columns.value))
+ const resolvedPreviewMeta = computed(() =>
+ buildRoleReportMeta({
+ previewMeta: previewMeta.value,
+ count: previewRows.value.length,
+ titleAlign: ROLE_REPORT_STYLE.titleAlign,
+ titleLevel: ROLE_REPORT_STYLE.titleLevel
+ })
+ )
+
+ const handleSearch = (params) => {
+ replaceSearchParams(buildRoleSearchParams(params))
+ getData()
}
- const handlePrint = async (payload) => {
- const token = previewToken.value + 1
- previewToken.value = token
- activePrintToken.value = token
- previewVisible.value = false
- previewRows.value = []
- previewMeta.value = {}
-
- try {
- const response = Array.isArray(payload?.ids) && payload.ids.length > 0
- ? await fetchGetRoleMany(payload.ids)
- : await fetchRolePrintPage({
- ...reportQueryParams.value,
- current: 1,
- pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20
- })
- if (activePrintToken.value !== token) {
- return
- }
- const records = defaultResponseAdapter(response).records
- if (activePrintToken.value !== token) {
- return
- }
-
- const rows = buildRolePrintRows(records)
- const now = new Date()
- previewRows.value = rows
- previewMeta.value = {
- reportTitle,
- reportDate: now.toLocaleDateString('zh-CN'),
- printedAt: now.toLocaleString('zh-CN', { hour12: false }),
- operator: userStore.getUserInfo?.name || userStore.getUserInfo?.username || '',
- count: rows.length
- }
- handlePreviewVisibleChange(true)
- } catch (error) {
- if (activePrintToken.value !== token) {
- return
- }
- ElMessage.error(error?.message || '鎵撳嵃澶辫触')
- }
+ const handleReset = () => {
+ Object.assign(searchForm.value, createRoleSearchState())
+ resetSearchParams()
}
</script>
--
Gitblit v1.9.1