jiaxing.zhou

feat(rebate): 返利列表页面功能增强和样式优化

- 添加表格行选择功能,支持单选和全选
- 优化分页组件,增加每页条数选择器
- 更新表格样式,改善视觉效果和响应式布局
- 修改搜索区域和操作按钮样式,统一设计风格
- 调整详情按钮样式,增加图标标识
- 修复分页跳转逻辑,确保页码正确更新
- 优化表格空数据显示和列宽适配
......@@ -136,6 +136,14 @@
<table class="data-table">
<thead>
<tr>
<th class="checkbox-col">
<input
type="checkbox"
:checked="selectAll"
@change="handleSelectAll"
class="table-checkbox"
/>
</th>
<th>返利编号</th>
<th>订单编号</th>
<th>经销商代码</th>
......@@ -151,9 +159,17 @@
</thead>
<tbody>
<tr v-if="rebateList.length === 0">
<td colspan="11" class="empty-data">暂无数据</td>
<td colspan="12" class="empty-data">暂无数据</td>
</tr>
<tr v-for="row in rebateList" :key="row.rebateId">
<td class="checkbox-col">
<input
type="checkbox"
:checked="selectedRebates.includes(row)"
@change="handleSelectRebate(row)"
class="table-checkbox"
/>
</td>
<td>{{ row.rebateNo }}</td>
<td>{{ row.orderNo }}</td>
<td>{{ row.dealerCode }}</td>
......@@ -173,7 +189,7 @@
</td>
<td>{{ formatDate(row.updateTime || '') }}</td>
<td>
<button @click="handleViewDetail(row)" class="action-link">详情</button>
<button @click="handleViewDetail(row)" class="table-btn view">✏️ 详情</button>
</td>
</tr>
</tbody>
......@@ -181,30 +197,46 @@
</div>
<!-- 分页 -->
<div class="pagination-wrapper">
<div class="pagination-info">
共 {{ pagination.total }} 条,{{ pagination.pageSize }}/页
<div class="table-footer">
<div class="pagination-left">
<div class="pagination-info">
共 {{ pagination.total }} 条记录,第 {{ pagination.pageNum }} / {{ getTotalPages() }} 页
</div>
<div class="page-size-selector">
<label>每页显示:</label>
<select v-model="pagination.pageSize" @change="handleSizeChange($event)" class="page-size-select">
<option value="10">10条</option>
<option value="20">20条</option>
<option value="50">50条</option>
<option value="100">100条</option>
</select>
</div>
</div>
<div class="pagination-controls">
<button @click="handlePrevPage" :disabled="pagination.pageNum <= 1" class="page-btn">‹</button>
<button
v-for="page in getPageNumbers()"
:key="page"
@click="handlePageChange(page)"
:class="['page-btn', { active: page === pagination.pageNum }]"
<div class="pagination-container">
<button
@click="handlePrevPage"
:disabled="pagination.pageNum <= 1"
class="pagination-btn prev-btn"
>
{{ page }}
上一页
</button>
<div class="pagination-pages">
<button
v-for="page in getPageNumbers()"
:key="page"
@click="handlePageChange(page)"
:class="['page-number', { active: page === pagination.pageNum }]"
>
{{ page }}
</button>
</div>
<button
@click="handleNextPage"
:disabled="pagination.pageNum >= getTotalPages()"
class="pagination-btn next-btn"
>
下一页
</button>
<button @click="handleNextPage" :disabled="pagination.pageNum >= getTotalPages()" class="page-btn">›</button>
</div>
<div class="pagination-jump">
前往
<input
v-model="jumpPage"
class="jump-input"
@keyup.enter="handleJumpPage"
/>
</div>
</div>
</div>
......@@ -421,6 +453,7 @@ const exportLoading = ref(false)
const auditLoading = ref(false)
const rebateList = ref<Rebate[]>([])
const selectedRebates = ref<Rebate[]>([])
const selectAll = ref(false)
const rebateDetail = ref<Rebate | null>(null)
// 图表引用
......@@ -872,8 +905,9 @@ const getCalcFlagClass = (flag: number) => {
}
// 分页变化
const handleSizeChange = (size: number) => {
pagination.pageSize = size
const handleSizeChange = (event: Event) => {
const target = event.target as HTMLSelectElement
pagination.pageSize = parseInt(target.value)
pagination.pageNum = 1
getRebateList()
}
......@@ -898,6 +932,27 @@ const handleSelectionChange = (selection: Rebate[]) => {
selectedRebates.value = selection
}
// 全选/取消全选
const handleSelectAll = () => {
if (selectAll.value) {
selectedRebates.value = [...rebateList.value]
} else {
selectedRebates.value = []
}
}
// 选择单个返利记录
const handleSelectRebate = (rebate: Rebate) => {
const index = selectedRebates.value.findIndex(r => r.rebateId === rebate.rebateId)
if (index > -1) {
selectedRebates.value.splice(index, 1)
} else {
selectedRebates.value.push(rebate)
}
// 更新全选状态
selectAll.value = selectedRebates.value.length === rebateList.value.length && rebateList.value.length > 0
}
// 查看详情
const handleViewDetail = async (row: Rebate) => {
try {
......@@ -1588,170 +1643,132 @@ onMounted(async () => {
<style scoped lang="scss">
.rebate-page {
padding: 20px;
background: #f5f7fa;
background: #f5f5f5;
min-height: 100vh;
}
/* 搜索区域 */
.search-section {
background: white;
padding: 16px 20px;
margin-bottom: 16px;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
.search-row {
display: flex;
align-items: center;
gap: 24px;
flex-wrap: wrap;
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
padding: 16px;
border-bottom: 1px solid #e0e0e0;
}
.search-item {
display: flex;
align-items: center;
gap: 8px;
.search-row {
display: flex;
gap: 16px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 12px;
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
min-width: 80px;
}
.search-row:last-child {
margin-bottom: 0;
}
.search-input {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
width: 160px;
transition: border-color 0.3s;
.search-item {
display: flex;
align-items: center;
gap: 8px;
}
&:focus {
outline: none;
border-color: #409eff;
}
}
.search-item label {
font-size: 12px;
color: #333;
white-space: nowrap;
}
.search-select {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
width: 120px;
background: white;
cursor: pointer;
transition: border-color 0.3s;
&:focus {
outline: none;
border-color: #409eff;
}
}
}
.search-input, .search-select {
padding: 6px 8px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 12px;
width: 120px;
}
.search-actions {
margin-left: auto;
display: flex;
gap: 8px;
.search-input:focus, .search-select:focus {
outline: none;
border-color: #1890ff;
}
.search-btn, .reset-btn {
padding: 8px 16px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
background: white;
.search-actions {
display: flex;
gap: 8px;
}
&:hover {
background: #f5f7fa;
}
.search-btn {
background: #1890ff;
color: white;
border: none;
padding: 4px 8px;
border-radius: 3px;
font-size: 11px;
cursor: pointer;
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
}
.search-btn:hover {
background: #40a9ff;
}
.search-btn {
background: #409eff;
color: white;
border-color: #409eff;
.reset-btn {
background: #ff7875;
color: white;
border: none;
padding: 4px 8px;
border-radius: 3px;
font-size: 11px;
cursor: pointer;
height: 24px;
display: flex;
align-items: center;
}
&:hover {
background: #66b1ff;
}
}
}
}
.reset-btn:hover {
background: #ff9c99;
}
/* 操作区域 */
.action-section {
background: white;
padding: 12px 20px;
margin-bottom: 16px;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
.action-buttons {
display: flex;
gap: 12px;
.action-btn {
padding: 8px 16px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
background: white;
&:hover {
background: #f5f7fa;
}
padding: 12px 16px;
border-bottom: 1px solid #e0e0e0;
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.action-buttons {
display: flex;
gap: 6px;
}
&.primary {
background: #409eff;
color: white;
border-color: #409eff;
.action-btn {
padding: 4px 8px;
border: none;
border-radius: 3px;
font-size: 11px;
cursor: pointer;
transition: all 0.2s;
}
&:hover {
background: #66b1ff;
}
}
.action-btn.primary {
background: #1890ff;
color: white;
}
&.secondary {
background: #67c23a;
color: white;
border-color: #67c23a;
.action-btn.primary:hover {
background: #40a9ff;
}
&:hover {
background: #85ce61;
}
}
.action-btn.secondary {
background: #52c41a;
color: white;
}
&.danger {
background: #f56c6c;
color: white;
border-color: #f56c6c;
.action-btn.secondary:hover {
background: #73d13d;
}
&:hover {
background: #f78989;
}
}
}
}
.action-btn.danger {
background: #ff4d4f;
color: white;
}
.charts-section {
......@@ -1825,42 +1842,45 @@ onMounted(async () => {
width: 100%;
}
/* 表格区域 */
.table-section {
background: white;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
margin: 16px;
border-radius: 6px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.table-header {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 12px 20px;
border-bottom: 1px solid #f0f0f0;
background: #fafafa;
.table-header {
padding: 8px 16px;
background: #fafafa;
border-bottom: 1px solid #e0e0e0;
display: flex;
justify-content: flex-end;
}
.table-controls {
display: flex;
gap: 8px;
.control-btn {
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
.table-controls {
display: flex;
gap: 4px;
}
&:hover {
background: #f5f7fa;
border-color: #409eff;
}
}
}
}
.control-btn {
background: white;
border: 1px solid #d9d9d9;
border-radius: 3px;
padding: 4px 8px;
font-size: 11px;
cursor: pointer;
transition: all 0.2s;
}
.control-btn:hover {
background: #f0f8ff;
border-color: #1890ff;
color: #1890ff;
}
.table-container {
.table-container {
position: relative;
.loading-overlay {
......@@ -1880,126 +1900,165 @@ onMounted(async () => {
color: #666;
}
}
}
.data-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
.data-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
thead {
background: #fafafa;
.data-table th,
.data-table td {
padding: 8px 12px;
text-align: left;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
}
th {
padding: 12px 16px;
text-align: left;
font-weight: 500;
color: #333;
border-bottom: 1px solid #e0e0e0;
white-space: nowrap;
}
}
.data-table th {
background: #fafafa;
font-weight: 600;
color: #333;
white-space: nowrap;
}
tbody {
tr {
transition: background-color 0.3s;
.data-table tbody tr:hover {
background: #f5f7fa;
}
&:hover {
background: #f5f7fa;
}
/* 表格复选框 */
.table-checkbox {
width: 14px;
height: 14px;
}
&:nth-child(even) {
background: #fafafa;
}
/* 表格操作按钮 */
.table-btn {
padding: 2px 6px;
margin-right: 4px;
border: none;
border-radius: 3px;
font-size: 10px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 2px;
}
&:nth-child(even):hover {
background: #f0f2f5;
}
.table-btn.view {
background: #1890ff;
color: white;
}
td {
padding: 12px 16px;
border-bottom: 1px solid #f0f0f0;
vertical-align: middle;
.table-btn.edit {
background: #1890ff;
color: white;
}
&.empty-data {
text-align: center;
color: #999;
font-style: italic;
padding: 40px;
}
}
}
}
}
}
.table-btn.delete {
background: #ff4d4f;
color: white;
}
.pagination-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 20px;
border-top: 1px solid #f0f0f0;
background: #fafafa;
.pagination-info {
font-size: 14px;
color: #666;
}
/* 分页样式 */
.table-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background: #f8f9fa;
border-top: 1px solid #e0e0e0;
}
.pagination-controls {
display: flex;
gap: 4px;
align-items: center;
.pagination-left {
display: flex;
align-items: center;
gap: 16px;
}
.page-btn {
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
min-width: 32px;
.pagination-info {
font-size: 12px;
color: #666;
}
&:hover:not(:disabled) {
background: #f5f7fa;
border-color: #409eff;
}
.page-size-selector {
display: flex;
align-items: center;
gap: 4px;
font-size: 11px;
color: #666;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.page-size-select {
padding: 2px 4px;
border: 1px solid #d9d9d9;
border-radius: 3px;
font-size: 10px;
background: white;
}
&.active {
background: #409eff;
color: white;
border-color: #409eff;
}
}
}
.pagination-container {
display: flex;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.pagination-jump {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #666;
.jump-input {
width: 50px;
padding: 4px 8px;
border: 1px solid #ddd;
border-radius: 4px;
text-align: center;
font-size: 14px;
.pagination-btn {
padding: 2px 6px;
border: none;
background: white;
color: #6c757d;
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
border-right: 1px solid #e9ecef;
height: 20px;
}
&:focus {
outline: none;
border-color: #409eff;
}
}
}
}
.pagination-btn:hover:not(:disabled) {
background: #e9ecef;
color: #495057;
}
.pagination-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination-pages {
display: flex;
}
.page-number {
padding: 2px 6px;
border: none;
background: white;
color: #6c757d;
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
border-right: 1px solid #e9ecef;
min-width: 28px;
text-align: center;
height: 20px;
}
.page-number:hover {
background: #e9ecef;
color: #495057;
}
.page-number.active {
background: #1890ff;
color: white;
font-weight: 600;
}
.status-tag {
......@@ -2049,7 +2108,7 @@ onMounted(async () => {
overflow-y: auto;
}
// 响应式设计
/* 响应式设计 */
@media (max-width: 1200px) {
.charts-container {
grid-template-columns: 1fr;
......@@ -2071,6 +2130,5 @@ onMounted(async () => {
margin-top: 12px;
}
}
}
</style>
......