|
|
@@ -3,10 +3,12 @@
|
|
|
<div class="page-title"><i class="title-bar"></i><span>订单管理</span></div>
|
|
|
<!-- 搜索栏 -->
|
|
|
<div class="search-bar">
|
|
|
- <el-input v-model="queryParams.keyword" placeholder="搜索" style="width: 150px" clearable>
|
|
|
+ <el-input v-model="queryParams.keyword" placeholder="搜索订单号" style="width: 200px" clearable @keyup.enter="handleQuery">
|
|
|
<template #prefix><el-icon><Search /></el-icon></template>
|
|
|
</el-input>
|
|
|
<el-date-picker v-model="queryParams.dateRange" type="daterange" range-separator="—" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 240px" />
|
|
|
+ <el-button type="primary" @click="handleQuery">搜索</el-button>
|
|
|
+ <el-button @click="handleReset">重置</el-button>
|
|
|
</div>
|
|
|
<!-- 筛选栏 -->
|
|
|
<div class="filter-bar">
|
|
|
@@ -33,14 +35,14 @@
|
|
|
</div>
|
|
|
<!-- 订单列表 -->
|
|
|
<div class="order-list">
|
|
|
- <div v-for="(order, orderIndex) in orderList" :key="orderIndex" class="order-card">
|
|
|
+ <div v-for="(order, orderIndex) in orderList" :key="order.id" class="order-card">
|
|
|
<div class="order-header">
|
|
|
<el-checkbox v-model="order.checked" @change="handleOrderCheck" />
|
|
|
<span class="order-time">{{ order.orderTime }}</span>
|
|
|
<span class="order-info">订单号:{{ order.orderNo }}</span>
|
|
|
<span class="order-info">下单人:{{ order.orderPerson }}</span>
|
|
|
<span class="order-info">部门:{{ order.department }}</span>
|
|
|
- <el-button type="primary" link class="expand-btn" @click="order.expanded = !order.expanded">{{ order.expanded ? '收起' : '展开' }} <el-icon><ArrowDown /></el-icon></el-button>
|
|
|
+ <el-button type="primary" link class="expand-btn" @click="handleExpand(order)">{{ order.expanded ? '收起' : '展开' }} <el-icon><ArrowDown /></el-icon></el-button>
|
|
|
</div>
|
|
|
<div v-if="order.countdown" class="countdown-bar">订单锁定剩余时间:{{ order.countdown }}</div>
|
|
|
<div class="product-list">
|
|
|
@@ -65,7 +67,7 @@
|
|
|
<el-button v-if="order.fileCount" type="primary" link size="small">审核文件({{ order.fileCount }})</el-button>
|
|
|
</div>
|
|
|
<div class="product-cell action-cell" v-if="itemIndex === 0">
|
|
|
- <el-button v-for="action in getOrderActions(order)" :key="action" type="primary" link size="small">{{ action }}</el-button>
|
|
|
+ <el-button v-for="action in getOrderActions(order)" :key="action" type="primary" link size="small" @click="handleAction(action, order)">{{ action }}</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -88,15 +90,19 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive, computed } from 'vue'
|
|
|
+import { ref, reactive, computed, onMounted, watch } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
import { Search, ArrowDown, Delete, Document, Clock, Box, CircleCheck, CircleClose, Picture } from '@element-plus/icons-vue'
|
|
|
import type { CheckboxValueType } from 'element-plus'
|
|
|
import { TablePagination } from '@/components'
|
|
|
+import { getOrderList, getOrderStatusStats, getOrderProducts, cancelOrder, deleteOrder } from '@/api/pc/enterprise/order'
|
|
|
+import type { OrderMain, OrderStatusStats } from '@/api/pc/enterprise/orderTypes'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const activeTab = ref('all')
|
|
|
const selectAll = ref(false)
|
|
|
+const loading = ref(false)
|
|
|
|
|
|
const statusTabs = [
|
|
|
{ key: 'all', label: '全部订单', icon: Document },
|
|
|
@@ -106,18 +112,121 @@ const statusTabs = [
|
|
|
{ key: 'cancelled', label: '已取消', icon: CircleClose }
|
|
|
]
|
|
|
|
|
|
-const queryParams = reactive({ keyword: '', dateRange: null, department: '', status: '', payType: '', pageNum: 1, pageSize: 10 })
|
|
|
-const total = ref(100)
|
|
|
+// 监听标签页切换,重置页码并重新获取数据
|
|
|
+watch(activeTab, (newTab) => {
|
|
|
+ queryParams.pageNum = 1
|
|
|
+ // 根据标签页设置后端查询的状态参数
|
|
|
+ if (newTab === 'all') {
|
|
|
+ queryParams.status = ''
|
|
|
+ } else {
|
|
|
+ // 将前端标签页key映射回后端状态值
|
|
|
+ const tabToStatusMap: Record<string, string> = {
|
|
|
+ 'preOrder': '0,1', // 待支付,待确认
|
|
|
+ 'shipping': '2,3,4', // 待发货,部分发货,发货完成
|
|
|
+ 'completed': '5', // 已完成
|
|
|
+ 'cancelled': '6,7' // 已关闭,已取消
|
|
|
+ }
|
|
|
+ queryParams.status = tabToStatusMap[newTab] || ''
|
|
|
+ }
|
|
|
+ fetchOrderList()
|
|
|
+})
|
|
|
+
|
|
|
+const queryParams = reactive({ keyword: '', dateRange: null, department: '', status: '', payType: '', pageNum: 1, pageSize: 5 })
|
|
|
+const total = ref(0)
|
|
|
+const allOrders = ref<any[]>([])
|
|
|
+
|
|
|
+// 将后端状态映射为前端标签页key
|
|
|
+const mapBackendStatusToTabKey = (backendStatus: string) => {
|
|
|
+ const statusMap: Record<string, string> = {
|
|
|
+ '0': 'preOrder', // 待支付
|
|
|
+ '1': 'preOrder', // 待确认
|
|
|
+ '2': 'shipping', // 待发货
|
|
|
+ '3': 'shipping', // 部分发货
|
|
|
+ '4': 'shipping', // 发货完成
|
|
|
+ '5': 'completed', // 已完成
|
|
|
+ '6': 'cancelled', // 已关闭
|
|
|
+ '7': 'cancelled' // 已取消
|
|
|
+ }
|
|
|
+ return statusMap[backendStatus] || backendStatus
|
|
|
+}
|
|
|
+
|
|
|
+// 根据订单状态获取状态文本
|
|
|
+const getStatusText = (status: string) => {
|
|
|
+ const statusMap: Record<string, string> = {
|
|
|
+ '0': '待支付',
|
|
|
+ '1': '待确认',
|
|
|
+ '2': '待发货',
|
|
|
+ '3': '部分发货',
|
|
|
+ '4': '发货完成',
|
|
|
+ '5': '已完成',
|
|
|
+ '6': '已关闭',
|
|
|
+ '7': '已取消'
|
|
|
+ }
|
|
|
+ return statusMap[status] || status
|
|
|
+}
|
|
|
+
|
|
|
+// 获取订单列表
|
|
|
+const fetchOrderList = async () => {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const params: any = {
|
|
|
+ pageNum: queryParams.pageNum,
|
|
|
+ pageSize: queryParams.pageSize
|
|
|
+ }
|
|
|
|
|
|
-const allOrders = ref([
|
|
|
- { orderTime: '2025/12/05 16:15:06', orderNo: '489283929283298392', orderPerson: '某某某', department: '某某部门', payAmount: '181', freight: '12', status: 'preOrder', statusText: '待支付', countdown: '13天 0:16:49', auditStatus: '', fileCount: 0, checked: false, expanded: false, products: [{ id: 1, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }] },
|
|
|
- { orderTime: '2025/12/05 16:15:06', orderNo: '489283929283298393', orderPerson: '某某某', department: '某某部门', payAmount: '181', freight: '12', status: 'shipping', statusText: '待确认', countdown: '13天 0:16:49', auditStatus: '待审批', fileCount: 0, checked: false, expanded: false, products: [{ id: 1, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }] },
|
|
|
- { orderTime: '2025/12/05 16:15:06', orderNo: '489283929283298394', orderPerson: '某某某', department: '某某部门', payAmount: '181', freight: '12', status: 'completed', statusText: '已完成', countdown: '', auditStatus: '审批通过', fileCount: 1, checked: false, expanded: false, products: [{ id: 1, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }] },
|
|
|
- { orderTime: '2025/12/05 16:15:06', orderNo: '489283929283298395', orderPerson: '某某某', department: '某某部门', payAmount: '181', freight: '12', status: 'cancelled', statusText: '已取消', countdown: '', auditStatus: '审批驳回', fileCount: 1, checked: false, expanded: false, products: [{ id: 1, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }] }
|
|
|
-])
|
|
|
+ // 添加筛选条件
|
|
|
+ if (queryParams.keyword) params.orderNo = queryParams.keyword
|
|
|
+ if (queryParams.department) params.department = queryParams.department
|
|
|
+ if (queryParams.status) params.orderStatuses = queryParams.status // 使用orderStatuses支持多状态查询
|
|
|
+ if (queryParams.payType) params.payType = queryParams.payType
|
|
|
+ if (queryParams.dateRange && queryParams.dateRange.length === 2) {
|
|
|
+ params.beginTime = queryParams.dateRange[0]
|
|
|
+ params.endTime = queryParams.dateRange[1]
|
|
|
+ }
|
|
|
|
|
|
-const orderList = computed(() => activeTab.value === 'all' ? allOrders.value : allOrders.value.filter(order => order.status === activeTab.value))
|
|
|
-const totalOrders = computed(() => orderList.value.length)
|
|
|
+ console.log('发送到后端的参数:', params)
|
|
|
+ const res = await getOrderList(params)
|
|
|
+ console.log('后端返回的数据:', res)
|
|
|
+ if (res.code === 200) {
|
|
|
+ // 调试:打印后端返回的第一条订单数据
|
|
|
+ if (res.rows && res.rows.length > 0) {
|
|
|
+ console.log('后端���回的订单状态值:', res.rows[0].orderStatus)
|
|
|
+ console.log('完整的订单数据:', res.rows[0])
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将后端数据转换为前端需要的格式
|
|
|
+ allOrders.value = (res.rows || []).map((order: OrderMain) => ({
|
|
|
+ id: order.id,
|
|
|
+ orderTime: order.createTime,
|
|
|
+ orderNo: order.orderNo,
|
|
|
+ orderPerson: order.userId, // 需要关联用户信息
|
|
|
+ department: order.customerId, // 需要关联部门信息
|
|
|
+ payAmount: order.payableAmount || 0,
|
|
|
+ freight: order.shippingFee || 0,
|
|
|
+ status: mapBackendStatusToTabKey(order.orderStatus || ''),
|
|
|
+ statusText: getStatusText(order.orderStatus || ''),
|
|
|
+ countdown: '',
|
|
|
+ auditStatus: order.checkStatus,
|
|
|
+ fileCount: 0,
|
|
|
+ checked: false,
|
|
|
+ expanded: false,
|
|
|
+ products: [] // 商品信息需要单独加载
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 调试:打印转换后的订单状态
|
|
|
+ console.log('转换后的订单状态分布:', allOrders.value.map(o => o.status))
|
|
|
+
|
|
|
+ total.value = res.total || 0
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取订单列表失败:', error)
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const orderList = computed(() => allOrders.value)
|
|
|
+const totalOrders = computed(() => total.value)
|
|
|
const selectedCount = computed(() => orderList.value.filter(o => o.checked).length)
|
|
|
const selectedAmount = computed(() => orderList.value.filter(o => o.checked).reduce((sum, o) => sum + parseFloat(o.payAmount), 0).toFixed(2))
|
|
|
|
|
|
@@ -133,19 +242,160 @@ const getOrderActions = (order: any) => {
|
|
|
}
|
|
|
return actions
|
|
|
}
|
|
|
+const handleExpand = async (order: any) => {
|
|
|
+ console.log('handleExpand 被调用, order.id:', order.id, 'order.expanded:', order.expanded)
|
|
|
+
|
|
|
+ const orderIndex = allOrders.value.findIndex(o => o.id === order.id)
|
|
|
+ if (orderIndex === -1) return
|
|
|
+
|
|
|
+ const currentOrder = allOrders.value[orderIndex]
|
|
|
+ console.log('找到订单, currentOrder.expanded:', currentOrder.expanded)
|
|
|
+
|
|
|
+ if (!currentOrder.expanded && currentOrder.products.length === 0) {
|
|
|
+ console.log('需要加载商品')
|
|
|
+ try {
|
|
|
+ const res = await getOrderProducts([order.id])
|
|
|
+ if (res.code === 200 && res.rows) {
|
|
|
+ console.log('后端返回的商品数据:', res.rows)
|
|
|
+ const products = res.rows.map((p: any) => ({
|
|
|
+ image: p.productImage || '',
|
|
|
+ name: p.productName || '',
|
|
|
+ spec1: p.productUnit || '',
|
|
|
+ spec2: p.productNo || '',
|
|
|
+ price: p.orderPrice || 0,
|
|
|
+ quantity: p.orderQuantity || 0
|
|
|
+ }))
|
|
|
+ console.log('商品加载完成, products.length:', products.length)
|
|
|
+
|
|
|
+ // 替换整个数组以触发响应式更新
|
|
|
+ allOrders.value = allOrders.value.map((o, i) =>
|
|
|
+ i === orderIndex ? { ...o, expanded: true, products } : o
|
|
|
+ )
|
|
|
+ console.log('已更新数组,expanded 设置为 true')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载商品失败:', error)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('切换 expanded 状态, 从', currentOrder.expanded, '到', !currentOrder.expanded)
|
|
|
+ // 替换整个数组以触发响应式更新
|
|
|
+ allOrders.value = allOrders.value.map((o, i) =>
|
|
|
+ i === orderIndex ? { ...o, expanded: !o.expanded } : o
|
|
|
+ )
|
|
|
+ console.log('已更新数组,expanded 已切换')
|
|
|
+}
|
|
|
const handleSelectAll = (val: CheckboxValueType) => { orderList.value.forEach(order => { order.checked = !!val }) }
|
|
|
const handleOrderCheck = () => { selectAll.value = orderList.value.every(order => order.checked) }
|
|
|
const handleViewDetail = (order: any) => { router.push(`/trade/orderManage/detail/${order.orderNo}`) }
|
|
|
-const handleQuery = () => {}
|
|
|
+const handleQuery = () => {
|
|
|
+ queryParams.pageNum = 1
|
|
|
+ fetchOrderList()
|
|
|
+}
|
|
|
+const handleReset = () => {
|
|
|
+ queryParams.keyword = ''
|
|
|
+ queryParams.dateRange = null
|
|
|
+ queryParams.department = ''
|
|
|
+ queryParams.payType = ''
|
|
|
+ queryParams.pageNum = 1
|
|
|
+ fetchOrderList()
|
|
|
+}
|
|
|
+const handleAction = (action: string, order: any) => {
|
|
|
+ switch (action) {
|
|
|
+ case '取消订单':
|
|
|
+ handleCancelOrder(order)
|
|
|
+ break
|
|
|
+ case '删除订单':
|
|
|
+ handleDeleteOrder(order)
|
|
|
+ break
|
|
|
+ case '查看详情':
|
|
|
+ handleViewDetail(order)
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ ElMessage.info(`${action}功能开发中`)
|
|
|
+ }
|
|
|
+}
|
|
|
+const handleCancelOrder = async (order: any) => {
|
|
|
+ try {
|
|
|
+ await ElMessageBox.confirm('确定要取消该订单吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ const res = await cancelOrder({ id: order.id, orderStatus: '7' })
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success('订单已取消')
|
|
|
+ fetchOrderList()
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg || '取消订单失败')
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ if (error !== 'cancel') {
|
|
|
+ ElMessage.error('取消订单失败')
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+const handleDeleteOrder = async (order: any) => {
|
|
|
+ try {
|
|
|
+ await ElMessageBox.confirm('确定要删除该订单吗?删除后无法恢复。', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ const res = await deleteOrder([order.id])
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success('订单已删除')
|
|
|
+ fetchOrderList()
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg || '删除订单失败')
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ if (error !== 'cancel') {
|
|
|
+ ElMessage.error('删除订单失败')
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 页面加载时获取订单列表
|
|
|
+onMounted(() => {
|
|
|
+ fetchOrderList()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.order-manage-container { padding: 20px; background: #fff; min-height: 100%; }
|
|
|
+.order-manage-container {
|
|
|
+ padding: 20px;
|
|
|
+ background: #fff;
|
|
|
+ min-height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ max-height: calc(100vh - 120px); // 减去顶部导航栏和其他元素高度
|
|
|
+}
|
|
|
.page-title { font-size: 16px; font-weight: bold; display: flex; align-items: center; gap: 8px; margin-bottom: 20px; }
|
|
|
.title-bar { display: inline-block; width: 3px; height: 16px; background: #e60012; border-radius: 2px; }
|
|
|
.search-bar { display: flex; align-items: center; gap: 15px; margin-bottom: 15px; }
|
|
|
.filter-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; .filter-label { font-size: 14px; color: #666; } .filter-right { flex: 1; display: flex; justify-content: flex-end; gap: 10px; } }
|
|
|
.tab-bar { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #eee; margin-bottom: 15px; .tab-left { display: flex; gap: 25px; } .tab-item { display: flex; align-items: center; gap: 5px; padding: 12px 0; cursor: pointer; color: #666; font-size: 14px; border-bottom: 2px solid transparent; margin-bottom: -1px; &:hover, &.active { color: #333; } &.active { border-bottom-color: #e60012; } } }
|
|
|
-.order-list { .order-card { border: 1px solid #eee; border-radius: 4px; margin-bottom: 15px; overflow: hidden; .order-header { display: flex; align-items: center; gap: 15px; padding: 12px 15px; background: #f9f9f9; border-bottom: 1px solid #eee; font-size: 13px; color: #666; .order-time { color: #333; } .expand-btn { margin-left: auto; } } .countdown-bar { background: #fff5e6; color: #e6a23c; padding: 8px 15px; font-size: 13px; border-bottom: 1px solid #eee; } .product-list { .product-row { display: flex; border-bottom: 1px solid #f5f5f5; &:last-child { border-bottom: none; } } .product-cell { padding: 15px; display: flex; flex-direction: column; justify-content: center; } .product-info-cell { flex: 1; flex-direction: row; align-items: center; gap: 15px; .product-image { width: 80px; height: 80px; background: #f5f5f5; border-radius: 4px; overflow: hidden; flex-shrink: 0; .el-image { width: 100%; height: 100%; } .image-placeholder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } } .product-detail { flex: 1; .product-name { font-size: 14px; color: #333; margin-bottom: 5px; line-height: 1.4; } .product-spec { font-size: 12px; color: #999; margin-bottom: 5px; } .product-price { font-size: 16px; font-weight: bold; color: #e60012; } } .product-quantity { font-size: 13px; color: #666; } } .amount-cell { width: 120px; border-left: 1px solid #f5f5f5; .amount-info { margin-bottom: 5px; .label { font-size: 12px; color: #999; } .value { font-size: 14px; color: #333; &.highlight { font-size: 16px; font-weight: bold; color: #e60012; } } } } .status-cell { width: 120px; border-left: 1px solid #f5f5f5; align-items: flex-start; gap: 5px; .status-text { font-size: 14px; font-weight: 500; } .audit-status { font-size: 12px; &.success { color: #e60012; } &.warning { color: #e6a23c; } &.danger { color: #e60012; } } } .action-cell { width: 100px; border-left: 1px solid #f5f5f5; align-items: flex-start; gap: 3px; } } } }
|
|
|
-.bottom-bar { background: #fafafa; border: 1px solid #eee; border-radius: 4px; padding: 15px 20px; margin-top: 15px; display: flex; justify-content: space-between; align-items: center; .bottom-right { display: flex; align-items: center; gap: 15px; .selected-info { font-size: 14px; color: #666; em { color: #e60012; font-style: normal; font-weight: bold; } } } }
|
|
|
+.order-list {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ .order-card { border: 1px solid #eee; border-radius: 4px; margin-bottom: 15px; overflow: hidden; .order-header { display: flex; align-items: center; gap: 15px; padding: 12px 15px; background: #f9f9f9; border-bottom: 1px solid #eee; font-size: 13px; color: #666; .order-time { color: #333; } .expand-btn { margin-left: auto; } } .countdown-bar { background: #fff5e6; color: #e6a23c; padding: 8px 15px; font-size: 13px; border-bottom: 1px solid #eee; } .product-list { .product-row { display: flex; border-bottom: 1px solid #f5f5f5; &:last-child { border-bottom: none; } } .product-cell { padding: 15px; display: flex; flex-direction: column; justify-content: center; } .product-info-cell { flex: 1; flex-direction: row; align-items: center; gap: 15px; .product-image { width: 80px; height: 80px; background: #f5f5f5; border-radius: 4px; overflow: hidden; flex-shrink: 0; .el-image { width: 100%; height: 100%; } .image-placeholder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } } .product-detail { flex: 1; .product-name { font-size: 14px; color: #333; margin-bottom: 5px; line-height: 1.4; } .product-spec { font-size: 12px; color: #999; margin-bottom: 5px; } .product-price { font-size: 16px; font-weight: bold; color: #e60012; } } .product-quantity { font-size: 13px; color: #666; } } .amount-cell { width: 120px; border-left: 1px solid #f5f5f5; .amount-info { margin-bottom: 5px; .label { font-size: 12px; color: #999; } .value { font-size: 14px; color: #333; &.highlight { font-size: 16px; font-weight: bold; color: #e60012; } } } } .status-cell { width: 120px; border-left: 1px solid #f5f5f5; align-items: flex-start; gap: 5px; .status-text { font-size: 14px; font-weight: 500; } .audit-status { font-size: 12px; &.success { color: #e60012; } &.warning { color: #e6a23c; } &.danger { color: #e60012; } } } .action-cell { width: 100px; border-left: 1px solid #f5f5f5; align-items: flex-start; gap: 3px; } } } }
|
|
|
+.bottom-bar {
|
|
|
+ background: #fafafa;
|
|
|
+ border: 1px solid #eee;
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 15px 20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ .bottom-right { display: flex; align-items: center; gap: 15px; .selected-info { font-size: 14px; color: #666; em { color: #e60012; font-style: normal; font-weight: bold; } } }
|
|
|
+}
|
|
|
+:deep(.table-pagination) {
|
|
|
+ flex-shrink: 0;
|
|
|
+ margin-top: 15px;
|
|
|
+}
|
|
|
</style>
|