feat(order): 重构订单页面- 新增 config.js 文件,定义订单搜索和表格配置

- 添加自定义搜索表单和内容组件
- 优化订单列表页面布局和功能
- 实现订单状态标签和操作按钮的自定义渲染
This commit is contained in:
2025-04-28 11:19:47 +08:00
parent 0e5f07eaf7
commit 5dcda80717
4 changed files with 637 additions and 64 deletions

View File

@@ -0,0 +1,287 @@
<template>
<div class="content">
<el-table
:border="!!config?.border"
:data="computedData"
ref="table"
row-key="nanoId"
v-bind="computedStyle"
:show-overflow-tooltip="config.tooltip"
:header-row-style="headerRowStyle"
:highlight-current-row="!!config.radio ? true : false"
:span-method="config?.spanMethod"
:tooltip-options="config?.tooltipOptions"
@current-change="handleTableCurrentChange"
@selection-change="hanldleTableSelectChange"
>
<el-table-column v-if="config.drag" label="排序" align="center" width="50px" prop="nanoId">
<!-- <template #default="{ row, column }"> -->
<!-- <span v-show="false">{{ row[column.property] }}</span> -->
<div class="move" style="width: 100%; height: 100%">
<svg-icon style="cursor: move" icon-class="move" />
</div>
<!-- </template> -->
</el-table-column>
<el-table-column v-if="config.select" type="selection" width="50px" />
<el-table-column
:index="indexMethod"
v-if="config.index"
type="index"
align="center"
width="50px"
label="序号"
/>
<template v-for="scheme in config.schemes" :key="scheme.attrs.label">
<el-table-column v-bind="scheme.attrs">
<template #default="{ row, column, $index }">
<slot
v-if="!!scheme.slot"
:name="scheme.slot"
:row="row"
:column="column"
:index="$index"
></slot>
</template>
</el-table-column>
</template>
<template #empty>
<el-empty description="获取数据为空" />
</template>
</el-table>
<div class="bottom">
<el-pagination
class="pagination"
v-show="isShow"
v-model:current-page="current"
v-model:page-size="size"
:background="props.background"
:layout="props.layout"
:total="props.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script setup>
import { computed, onBeforeMount, onMounted, watch } from 'vue'
import Sortable from 'sortablejs'
import { nanoid } from '@/utils/jsencrypt'
const props = defineProps({
data: {
type: Array,
default: () => []
},
config: {
type: Object,
required: true
},
maxHeight: {
type: [String, Number],
default: () => ''
},
headerRowStyle: {
type: [Function, Object],
default: () => ({
background: '#F1F3F7'
})
},
showPagination: {
type: Boolean,
default: () => true
},
layout: {
type: String,
default: () => 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: () => true
},
minHieght: {
type: String,
default: ''
},
pageSize: {
type: Number,
default: () => 10
},
total: {
type: Number,
default: () => 400
},
currentPage: {
type: Number,
default: () => 1
}
})
const emits = defineEmits([
'update:page-size',
'update:current-page',
'update:checkData',
'selection',
'changePage',
'changeSize',
'rowSort'
])
const current = ref(props.currentPage)
const size = ref(props.pageSize)
const computedData = ref([])
const table = ref(null)
const isShow = computed(() => {
return props.showPagination && !!computedData.value.length
})
const computedStyle = computed(() => {
if (props.maxHeight) {
return {
'max-height': props.maxHeight
}
} else {
return null
}
})
watch(
() => props.data,
(data) => {
// if (props.config.drag) {
computedData.value = data.map((item) => {
if (!item.nanoId) {
item.nanoId = nanoid()
}
return item
})
// } else {
// computedData.value = data
// }
},
{
deep: true
}
)
watch(
() => current.value,
(newVal) => {
emits('update:current-page', newVal)
}
)
watch(
() => size.value,
(newVal) => {
emits('update:page-size', newVal)
}
)
watch(
() => props.currentPage,
(newVal) => {
current.value = newVal
}
)
watch(
() => props.pageSize,
(newVal) => {
size.value = newVal
}
)
function reset() {
current.value = 1
size.value = 10
}
function handleSizeChange(v) {
emits('changeSize', v)
}
function handleCurrentChange(v) {
emits('changePage', v)
}
function hanldleTableSelectChange(newSelection) {
console.log(newSelection, 'newSelection')
emits('selection', { newSelection })
}
function handleTableCurrentChange(data) {
console.log(data, 'data')
emits('update:checkData', data)
}
function indexMethod(index) {
const cur = size.value * (current.value - 1) + index + 1
return cur
}
function rowDrag() {
const tbody = table.value.$refs.bodyWrapper.querySelector('tbody')
Sortable.create(tbody, {
ghostClass: 'sortable-ghost',
animation: 150,
handle: '.move',
onEnd: (event) => {
if (event.oldIndex !== undefined && event.newIndex !== undefined) {
let newArr = computedData.value
const curRow = newArr.splice(event.oldIndex, 1)[0]
newArr.splice(event.newIndex, 0, curRow)
computedData.value = [...newArr]
emits('rowSort', newArr)
}
}
})
}
onBeforeMount(() => {
// if (props.config.drag) {
computedData.value = props.data.map((item) => {
if (!item.nanoId) {
item.nanoId = nanoid()
}
return item
})
// } else {
// computedData.value = props.data
// }
})
onMounted(() => {
props.config.drag && rowDrag()
})
defineExpose({
table,
reset
})
</script>
<style lang="scss" scoped>
.content {
background: #fff;
border-radius: 4px;
padding: 20px 20px 0 20px;
box-sizing: border-box;
:deep(.el-table) {
.current-row {
background-color: #e5f1fd;
}
.sortable-ghost {
opacity: 1;
cursor: grab !important;
background-color: #ebf5ff !important;
}
}
.bottom {
display: flex;
align-items: center;
justify-content: flex-end;
.right {
margin-top: 20px;
flex: 1 0 auto;
}
.pagination {
margin-top: 20px;
height: 75px;
}
}
}
</style>