1.优化后台菜单页面

This commit is contained in:
2026-06-24 16:55:04 +08:00
parent ceb4386440
commit 58b22cfb64
6 changed files with 114 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
<template> <template>
<div v-memo="[field]"> <div v-memo="[field]" class="ba-table-operate-buttons">
<template v-for="(btn, idx) in field.buttons" :key="idx"> <template v-for="(btn, idx) in field.buttons" :key="idx">
<template v-if="btn.display ? btn.display(row, field) : true"> <template v-if="btn.display ? btn.display(row, field) : true">
<!-- 常规按钮 --> <!-- 常规按钮 -->
@@ -147,16 +147,34 @@ const getTranslation = (key?: string) => {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.ba-table-operate-buttons {
display: inline-flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
width: 100%;
gap: 0;
vertical-align: middle;
}
.ba-table-render-buttons-item { .ba-table-render-buttons-item {
width: 40px;
min-width: 40px;
height: 32px;
padding: 0 !important;
margin: 0 !important;
display: inline-flex;
align-items: center;
justify-content: center;
.text { .text {
font-size: 14px; font-size: 12px;
line-height: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
} }
.icon + .text { .icon + .text {
padding-left: 5px; padding-left: 2px;
}
&.el-button--small {
padding: 4px 5px;
height: auto;
} }
} }
.ba-table-render-buttons-move { .ba-table-render-buttons-move {
@@ -164,9 +182,10 @@ const getTranslation = (key?: string) => {
} }
.buttons-popconfirm-reference-box { .buttons-popconfirm-reference-box {
display: inline-flex; display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
min-width: 40px;
vertical-align: middle; vertical-align: middle;
} }
.buttons-ml-6 + .buttons-ml-6 {
margin-left: 6px;
}
</style> </style>

View File

@@ -37,6 +37,8 @@ export const getCellValue = (row: TableRow, field: TableColumn, column: TableCol
return cellValue return cellValue
} }
type DefaultOptButType = 'weigh-sort' | 'edit' | 'delete'
/* /*
* 默认按钮组 * 默认按钮组
*/ */
@@ -138,4 +140,29 @@ export const invokeTableContextDataFun = <T>(
return fun return fun
} }
type DefaultOptButType = 'weigh-sort' | 'edit' | 'delete' /** 操作列单个按钮占位宽度px */
export const OPERATE_BUTTON_WIDTH = 40
/**
* 根据按钮数量计算操作列宽度
*/
export const getButtonsColumnWidth = (buttons?: OptButton[]): number => {
const count = buttons?.length ?? 1
return count * OPERATE_BUTTON_WIDTH
}
/**
* 统一操作列:右侧固定,宽度 = 按钮数 × OPERATE_BUTTON_WIDTH
*/
export const normalizeButtonsColumn = (column: TableColumn): TableColumn => {
if (column.render !== 'buttons') {
return column
}
const className = column.className ? `${column.className} ba-table-operate-column` : 'ba-table-operate-column'
return {
...column,
fixed: 'right',
width: getButtonsColumnWidth(column.buttons),
className,
}
}

View File

@@ -27,7 +27,7 @@
<el-table-column <el-table-column
v-else v-else
:key="key + '-column'" :key="key + '-column'"
v-bind="item" v-bind="getColumnBindProps(item)"
:column-key="(item['columnKey'] ? item['columnKey'] : `table-column-${item.prop}`) || shortUuid()" :column-key="(item['columnKey'] ? item['columnKey'] : `table-column-${item.prop}`) || shortUuid()"
> >
<!-- ./fieldRender/ 文件夹内的每个组件为一种字段渲染器组件名称为渲染器名称 --> <!-- ./fieldRender/ 文件夹内的每个组件为一种字段渲染器组件名称为渲染器名称 -->
@@ -68,8 +68,11 @@ import type { Component } from 'vue'
import { computed, inject, nextTick, useTemplateRef } from 'vue' import { computed, inject, nextTick, useTemplateRef } from 'vue'
import { useConfig } from '/@/stores/config' import { useConfig } from '/@/stores/config'
import type baTableClass from '/@/utils/baTable' import type baTableClass from '/@/utils/baTable'
import { normalizeButtonsColumn } from '/@/components/table/index'
import { shortUuid } from '/@/utils/random' import { shortUuid } from '/@/utils/random'
const getColumnBindProps = (item: TableColumn) => normalizeButtonsColumn(item)
const config = useConfig() const config = useConfig()
const tableRef = useTemplateRef('tableRef') const tableRef = useTemplateRef('tableRef')
const baTable = inject('baTable') as baTableClass const baTable = inject('baTable') as baTableClass
@@ -236,6 +239,13 @@ defineExpose({
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.ba-data-table :deep(.ba-table-operate-column) {
.cell {
padding-left: 0;
padding-right: 0;
overflow: visible;
}
}
.table-pagination { .table-pagination {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;

View File

@@ -33,4 +33,11 @@ export default {
create_time: 'create_time', create_time: 'create_time',
update_time: 'update_time', update_time: 'update_time',
'quick Search Fields': 'ID', 'quick Search Fields': 'ID',
manual_retry: 'Retry grant',
retry_confirm: 'Queue this order for grant retry?',
ship: 'Ship',
ship_shipping_no_prompt: 'Enter tracking number',
ship_shipping_company_prompt: 'Enter carrier',
reject: 'Reject',
reject_reason_prompt: 'Enter rejection reason',
} }

View File

@@ -33,5 +33,12 @@ export default {
create_time: '创建时间', create_time: '创建时间',
update_time: '修改时间', update_time: '修改时间',
'quick Search Fields': 'ID', 'quick Search Fields': 'ID',
manual_retry: '手动重试',
retry_confirm: '确认将该订单加入重试队列?',
ship: '发货',
ship_shipping_no_prompt: '请输入物流单号',
ship_shipping_company_prompt: '请输入物流公司',
reject: '驳回',
reject_reason_prompt: '请输入驳回原因',
} }

View File

@@ -107,24 +107,24 @@ const baTable = new baTableClass(
{ {
label: t('Operate'), label: t('Operate'),
align: 'center', align: 'center',
width: 220,
render: 'buttons', render: 'buttons',
buttons: [ buttons: [
{ {
render: 'confirmButton', render: 'confirmButton',
name: 'retry', name: 'retry',
title: 'Retry', title: 'mall.playxOrder.manual_retry',
text: '手动重试', text: '',
type: 'warning', type: 'warning',
icon: '', icon: 'fa fa-refresh',
class: 'table-row-edit',
display: (row: TableRow) => display: (row: TableRow) =>
row.type === 'BONUS' && row.type === 'BONUS' &&
row.status === 'PENDING' && row.status === 'PENDING' &&
['NOT_SENT', 'SENT_PENDING', 'FAILED_RETRYABLE', 'FAILED_FINAL'].includes(String(row.grant_status)), ['NOT_SENT', 'SENT_PENDING', 'FAILED_RETRYABLE', 'FAILED_FINAL'].includes(String(row.grant_status)),
popconfirm: { popconfirm: {
title: '确认将该订单加入重试队列?', title: t('mall.playxOrder.retry_confirm'),
confirmButtonText: '确认', confirmButtonText: t('Confirm'),
cancelButtonText: '取消', cancelButtonText: t('Cancel'),
confirmButtonType: 'warning', confirmButtonType: 'warning',
}, },
click: async (row: TableRow) => { click: async (row: TableRow) => {
@@ -144,23 +144,28 @@ const baTable = new baTableClass(
}, },
}, },
{ {
render: 'basicButton', render: 'tipButton',
name: 'ship', name: 'ship',
title: 'Ship', title: 'mall.playxOrder.ship',
text: '发货', text: '',
type: 'success', type: 'success',
icon: '', icon: 'fa fa-truck',
class: 'table-row-ship',
display: (row: TableRow) => row.type === 'PHYSICAL' && row.status === 'PENDING', display: (row: TableRow) => row.type === 'PHYSICAL' && row.status === 'PENDING',
click: async (row: TableRow) => { click: async (row: TableRow) => {
try { try {
const shippingNoRes = await ElMessageBox.prompt('请输入物流单号', '发货', { const shippingNoRes = await ElMessageBox.prompt(t('mall.playxOrder.ship_shipping_no_prompt'), t('mall.playxOrder.ship'), {
confirmButtonText: '确认', confirmButtonText: t('Confirm'),
cancelButtonText: '取消', cancelButtonText: t('Cancel'),
})
const shippingCompanyRes = await ElMessageBox.prompt('请输入物流公司', '发货', {
confirmButtonText: '确认',
cancelButtonText: '取消',
}) })
const shippingCompanyRes = await ElMessageBox.prompt(
t('mall.playxOrder.ship_shipping_company_prompt'),
t('mall.playxOrder.ship'),
{
confirmButtonText: t('Confirm'),
cancelButtonText: t('Cancel'),
}
)
const shippingNo = shippingNoRes.value const shippingNo = shippingNoRes.value
const shippingCompany = shippingCompanyRes.value const shippingCompany = shippingCompanyRes.value
@@ -186,18 +191,19 @@ const baTable = new baTableClass(
}, },
}, },
{ {
render: 'basicButton', render: 'tipButton',
name: 'reject', name: 'reject',
title: 'Reject', title: 'mall.playxOrder.reject',
text: '驳回', text: '',
type: 'danger', type: 'danger',
icon: '', icon: 'fa fa-times',
class: 'table-row-reject',
display: (row: TableRow) => row.type === 'PHYSICAL' && row.status === 'PENDING', display: (row: TableRow) => row.type === 'PHYSICAL' && row.status === 'PENDING',
click: async (row: TableRow) => { click: async (row: TableRow) => {
try { try {
const res = await ElMessageBox.prompt('请输入驳回原因', '驳回', { const res = await ElMessageBox.prompt(t('mall.playxOrder.reject_reason_prompt'), t('mall.playxOrder.reject'), {
confirmButtonText: '确认', confirmButtonText: t('Confirm'),
cancelButtonText: '取消', cancelButtonText: t('Cancel'),
}) })
await createAxios( await createAxios(
{ {
@@ -219,6 +225,7 @@ const baTable = new baTableClass(
}, },
}, },
], ],
operator: false,
}, },
], ],
dblClickNotEditColumn: [undefined], dblClickNotEditColumn: [undefined],