887 lines
27 KiB
Vue
887 lines
27 KiB
Vue
<template>
|
|
<div class="order-list-container">
|
|
<!-- 主容器 -->
|
|
<el-card class="main-container" shadow="never">
|
|
<!-- 搜索和操作栏 -->
|
|
<div class="filter-section">
|
|
<div class="filter-content">
|
|
<el-form :inline="true" :model="queryParams" class="filter-form">
|
|
<el-form-item label="关键词">
|
|
<el-input v-model="queryParams.key" placeholder="订单名称/ID" clearable style="width: 150px" @keyup.enter="handleQuery" />
|
|
</el-form-item>
|
|
<el-form-item label="用户ID">
|
|
<el-input v-model="queryParams.user_id" placeholder="用户ID" clearable style="width: 120px" @keyup.enter="handleQuery" />
|
|
</el-form-item>
|
|
<el-form-item label="用户关键词">
|
|
<el-input v-model="queryParams.user_key" placeholder="用户名/手机号/邮箱" clearable style="width: 180px" @keyup.enter="handleQuery" />
|
|
</el-form-item>
|
|
<el-form-item label="状态">
|
|
<el-select v-model="queryParams.state" placeholder="全部" clearable style="width: 120px">
|
|
<el-option label="待支付" value="0" />
|
|
<el-option label="已支付" value="1" />
|
|
<el-option label="已失效" value="2" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="handleQuery">
|
|
<el-icon><Search /></el-icon>搜索
|
|
</el-button>
|
|
<el-button @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div class="action-bar">
|
|
<el-button type="primary" @click="handleAdd">
|
|
<el-icon><Plus /></el-icon>新增订单
|
|
</el-button>
|
|
<el-button type="success" @click="fetchOrderList">
|
|
<el-icon><Refresh /></el-icon>刷新
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 订单列表 -->
|
|
<div class="table-section">
|
|
<!-- 骨架屏 -->
|
|
<div v-if="loading" class="skeleton-container">
|
|
<div v-for="i in 5" :key="i" class="skeleton-row">
|
|
<div class="skeleton-cell skeleton-checkbox"></div>
|
|
<div class="skeleton-cell skeleton-id"></div>
|
|
<div class="skeleton-cell skeleton-name"></div>
|
|
<div class="skeleton-cell skeleton-user"></div>
|
|
<div class="skeleton-cell skeleton-price"></div>
|
|
<div class="skeleton-cell skeleton-status"></div>
|
|
<div class="skeleton-cell skeleton-time"></div>
|
|
<div class="skeleton-cell skeleton-action"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<el-table
|
|
v-else
|
|
v-loading="loading"
|
|
:data="orderList"
|
|
@selection-change="handleSelectionChange"
|
|
style="width: 100%"
|
|
:header-cell-style="{ background: '#fafafa', color: '#333', fontWeight: 600 }"
|
|
>
|
|
<el-table-column type="selection" width="55" />
|
|
<el-table-column prop="id" label="订单ID" width="100" />
|
|
<el-table-column prop="name" label="订单名称" min-width="180" />
|
|
<el-table-column prop="userId" label="用户ID" width="100" />
|
|
<el-table-column prop="commodityId" label="商品ID" width="100" />
|
|
<el-table-column label="表名" width="120">
|
|
<template #default="{ row }">
|
|
<el-tag size="small">{{ row.table || '未知' }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="订单金额" width="120">
|
|
<template #default="{ row }">
|
|
<span class="amount">¥{{ (row.price / 100).toFixed(2) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="续费价格" width="120">
|
|
<template #default="{ row }">
|
|
<span class="renew-price">¥{{ (row.renewPrice / 100).toFixed(2) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="数量" width="80">
|
|
<template #default="{ row }">
|
|
<span>{{ row.payNum }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="订单状态" width="100">
|
|
<template #default="{ row }">
|
|
<el-tag :type="getStatusType(row.state)">
|
|
{{ getStatusText(row.state) }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="支付方式" width="100">
|
|
<template #default="{ row }">
|
|
<span>{{ row.payType || '-' }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="过期时间" width="170">
|
|
<template #default="{ row }">
|
|
<span>{{ formatDate(row.expireTime) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="创建时间" width="170">
|
|
<template #default="{ row }">
|
|
<span>{{ formatDate(row.CreatedAt) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" width="200" fixed="right">
|
|
<template #default="{ row }">
|
|
<div class="action-buttons">
|
|
<el-button type="primary" link @click="handleView(row)">查看</el-button>
|
|
<el-button type="warning" link @click="handleEdit(row)">编辑</el-button>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<el-pagination
|
|
v-model:current-page="queryParams.page"
|
|
v-model:page-size="queryParams.count"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
:total="total"
|
|
@size-change="handleSizeChange"
|
|
@current-change="handleCurrentChange"
|
|
background
|
|
class="pagination"
|
|
/>
|
|
</div>
|
|
</el-card>
|
|
|
|
<!-- 订单详情对话框 -->
|
|
<el-dialog
|
|
v-model="detailDialogVisible"
|
|
title="订单详情"
|
|
width="800px"
|
|
append-to-body
|
|
>
|
|
<el-descriptions :column="2" border v-if="orderDetail">
|
|
<el-descriptions-item label="订单ID">{{ orderDetail.id }}</el-descriptions-item>
|
|
<el-descriptions-item label="订单名称">{{ orderDetail.name }}</el-descriptions-item>
|
|
<el-descriptions-item label="用户ID">{{ orderDetail.userId }}</el-descriptions-item>
|
|
<el-descriptions-item label="商品ID">{{ orderDetail.commodityId }}</el-descriptions-item>
|
|
<el-descriptions-item label="表名">{{ orderDetail.table }}</el-descriptions-item>
|
|
<el-descriptions-item label="数量">{{ orderDetail.payNum }}</el-descriptions-item>
|
|
<el-descriptions-item label="订单金额">¥{{ (orderDetail.price / 100).toFixed(2) }}</el-descriptions-item>
|
|
<el-descriptions-item label="续费价格">¥{{ (orderDetail.renewPrice / 100).toFixed(2) }}</el-descriptions-item>
|
|
<el-descriptions-item label="订单状态">
|
|
<el-tag :type="getStatusType(orderDetail.state)">
|
|
{{ getStatusText(orderDetail.state) }}
|
|
</el-tag>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="支付方式">{{ orderDetail.payType || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="过期时间">{{ formatDate(orderDetail.expireTime) }}</el-descriptions-item>
|
|
<el-descriptions-item label="创建时间">{{ formatDate(orderDetail.CreatedAt) }}</el-descriptions-item>
|
|
<el-descriptions-item label="更新时间">{{ formatDate(orderDetail.UpdatedAt) }}</el-descriptions-item>
|
|
<el-descriptions-item label="参数信息">{{ orderDetail.args || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="备注" :span="2">{{ orderDetail.note || '无' }}</el-descriptions-item>
|
|
</el-descriptions>
|
|
</el-dialog>
|
|
|
|
<!-- 订单表单对话框 -->
|
|
<el-dialog
|
|
v-model="dialogVisible"
|
|
:title="dialogType === 'add' ? '新增订单' : '编辑订单'"
|
|
width="700px"
|
|
append-to-body
|
|
>
|
|
<el-form
|
|
ref="orderFormRef"
|
|
:model="orderForm"
|
|
:rules="orderRules"
|
|
label-width="120px"
|
|
>
|
|
<el-form-item label="订单名称" prop="name">
|
|
<el-input v-model="orderForm.name" placeholder="请输入订单名称" />
|
|
</el-form-item>
|
|
<el-form-item label="所属表" prop="table">
|
|
<el-input v-model="orderForm.table" placeholder="请输入所属表" />
|
|
</el-form-item>
|
|
<el-form-item label="用户ID" prop="user_id">
|
|
<div class="selector-field">
|
|
<div class="selector-info" v-if="selectedUserInfo">
|
|
<el-tag type="primary" effect="plain">
|
|
ID: {{ orderForm.user_id }} - {{ selectedUserInfo.user_name }}
|
|
</el-tag>
|
|
</div>
|
|
<div class="selector-actions">
|
|
<el-button type="primary" @click="userSelectorVisible = true">
|
|
<el-icon><User /></el-icon>
|
|
{{ orderForm.user_id ? '更换用户' : '选择用户' }}
|
|
</el-button>
|
|
<el-button v-if="orderForm.user_id" @click="clearUser">清除</el-button>
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="商品ID" prop="commodity_id">
|
|
<div class="selector-field">
|
|
<div class="selector-info" v-if="selectedProductInfo">
|
|
<el-tag type="success" effect="plain">
|
|
ID: {{ orderForm.commodity_id }} - {{ selectedProductInfo.name }}
|
|
</el-tag>
|
|
</div>
|
|
<div class="selector-actions">
|
|
<el-button type="success" @click="productSelectorVisible = true">
|
|
<el-icon><ShoppingCart /></el-icon>
|
|
{{ orderForm.commodity_id ? '更换商品' : '选择商品' }}
|
|
</el-button>
|
|
<el-button v-if="orderForm.commodity_id" @click="clearProduct">清除</el-button>
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="购买数量" prop="pay_num">
|
|
<el-input-number v-model="orderForm.pay_num" :min="1" placeholder="请输入数量" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="价格(分)" prop="price">
|
|
<el-input-number v-model="orderForm.price" :min="0" placeholder="请输入价格(分)" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="续费价格(分)" prop="renew_price">
|
|
<el-input-number v-model="orderForm.renew_price" :min="0" placeholder="请输入续费价格(分)" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="过期时间" prop="expire_time">
|
|
<el-input-number v-model="orderForm.expire_time" :min="0" placeholder="请输入过期时间(时间戳)" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="优惠码ID" prop="discount_code_id">
|
|
<div class="selector-field">
|
|
<div class="selector-info" v-if="selectedDiscountCodeInfo">
|
|
<el-tag type="warning" effect="plain">
|
|
ID: {{ orderForm.discount_code_id }} - {{ selectedDiscountCodeInfo.name || selectedDiscountCodeInfo.code }}
|
|
</el-tag>
|
|
</div>
|
|
<div class="selector-actions">
|
|
<el-button type="warning" @click="discountCodeSelectorVisible = true">
|
|
<el-icon><Ticket /></el-icon>
|
|
{{ orderForm.discount_code_id ? '更换优惠码' : '选择优惠码' }}
|
|
</el-button>
|
|
<el-button v-if="orderForm.discount_code_id" @click="clearDiscountCode">清除</el-button>
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="代金券ID" prop="coupon_id">
|
|
<div class="selector-field">
|
|
<div class="selector-info" v-if="selectedVoucherInfo">
|
|
<el-tag type="danger" effect="plain">
|
|
ID: {{ orderForm.coupon_id }} - {{ selectedVoucherInfo.name || selectedVoucherInfo.code }}
|
|
</el-tag>
|
|
</div>
|
|
<div class="selector-actions">
|
|
<el-button type="danger" @click="voucherSelectorVisible = true">
|
|
<el-icon><Money /></el-icon>
|
|
{{ orderForm.coupon_id ? '更换代金券' : '选择代金券' }}
|
|
</el-button>
|
|
<el-button v-if="orderForm.coupon_id" @click="clearVoucher">清除</el-button>
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="订单状态" prop="state">
|
|
<el-radio-group v-model="orderForm.state">
|
|
<el-radio :label="0">待支付</el-radio>
|
|
<el-radio :label="1">已支付</el-radio>
|
|
<el-radio :label="2">已失效</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="支付方式" prop="pay_type">
|
|
<el-input v-model="orderForm.pay_type" placeholder="请输入支付类型" />
|
|
</el-form-item>
|
|
<el-form-item label="订单参数" prop="args">
|
|
<el-input v-model="orderForm.args" placeholder="请输入订单参数" />
|
|
</el-form-item>
|
|
<el-form-item label="备注" prop="note">
|
|
<el-input v-model="orderForm.note" type="textarea" :rows="3" placeholder="请输入备注" />
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<div class="dialog-footer">
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<!-- 用户选择器 -->
|
|
<UserListSelector
|
|
v-model="userSelectorVisible"
|
|
:current-user-id="orderForm.user_id"
|
|
@confirm="handleUserSelect"
|
|
/>
|
|
|
|
<!-- 商品选择器 -->
|
|
<ProductSelector
|
|
v-model="productSelectorVisible"
|
|
:current-product-id="orderForm.commodity_id"
|
|
@confirm="handleProductSelect"
|
|
/>
|
|
|
|
<!-- 优惠码选择器 -->
|
|
<DiscountCodeSelector
|
|
v-model="discountCodeSelectorVisible"
|
|
:current-code-id="orderForm.discount_code_id"
|
|
@confirm="handleDiscountCodeSelect"
|
|
/>
|
|
|
|
<!-- 代金券选择器 -->
|
|
<VoucherSelector
|
|
v-model="voucherSelectorVisible"
|
|
:current-voucher-id="orderForm.coupon_id"
|
|
@confirm="handleVoucherSelect"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, reactive, onMounted } from 'vue'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { Plus, Delete, Search, Download, Refresh, User, ShoppingCart, Ticket, Money } from '@element-plus/icons-vue'
|
|
import { getOrderList, getOrderDetail, createOrder, updateOrder, deleteOrder } from '@/api/admin/order'
|
|
import UserListSelector from '@/components/admin/UserListSelector.vue'
|
|
import ProductSelector from '@/components/admin/ProductSelector.vue'
|
|
import DiscountCodeSelector from '@/components/admin/DiscountCodeSelector.vue'
|
|
import VoucherSelector from '@/components/admin/VoucherSelector.vue'
|
|
|
|
// 查询参数
|
|
const queryParams = reactive({
|
|
page: 1,
|
|
count: 10,
|
|
key: '',
|
|
state: '',
|
|
user_id: '',
|
|
user_key: ''
|
|
})
|
|
|
|
// 订单表单
|
|
const orderForm = reactive({
|
|
order_id: undefined,
|
|
name: '',
|
|
table: '',
|
|
user_id: undefined,
|
|
commodity_id: 0,
|
|
pay_num: 1,
|
|
price: 0,
|
|
renew_price: 0,
|
|
expire_time: 0,
|
|
discount_code_id: 0,
|
|
coupon_id: 0,
|
|
state: 0,
|
|
pay_type: '',
|
|
args: '',
|
|
note: ''
|
|
})
|
|
|
|
const orderRules = {
|
|
name: [
|
|
{ required: true, message: '请输入订单名称', trigger: 'blur' }
|
|
],
|
|
table: [
|
|
{ required: true, message: '请输入所属表', trigger: 'blur' }
|
|
],
|
|
user_id: [
|
|
{ required: true, message: '请输入用户ID', trigger: 'blur' },
|
|
{ type: 'number', message: '用户ID必须是数字', trigger: 'blur' }
|
|
],
|
|
coupon_id: [
|
|
{ required: true, message: '请输入代金券ID', trigger: 'blur' },
|
|
{ type: 'number', message: '代金券ID必须是数字', trigger: 'blur' }
|
|
],
|
|
pay_num: [
|
|
{ required: true, message: '请输入购买数量', trigger: 'blur' }
|
|
],
|
|
price: [
|
|
{ required: true, message: '请输入价格', trigger: 'blur' }
|
|
]
|
|
}
|
|
|
|
// 状态数据
|
|
const loading = ref(false)
|
|
const orderList = ref([])
|
|
const orderDetail = ref(null)
|
|
const total = ref(0)
|
|
const selectedRows = ref([])
|
|
const dialogVisible = ref(false)
|
|
const detailDialogVisible = ref(false)
|
|
const dialogType = ref('add')
|
|
const orderFormRef = ref(null)
|
|
|
|
// 选择器弹窗状态
|
|
const userSelectorVisible = ref(false)
|
|
const productSelectorVisible = ref(false)
|
|
const discountCodeSelectorVisible = ref(false)
|
|
const voucherSelectorVisible = ref(false)
|
|
|
|
// 选择的显示信息
|
|
const selectedUserInfo = ref(null)
|
|
const selectedProductInfo = ref(null)
|
|
const selectedDiscountCodeInfo = ref(null)
|
|
const selectedVoucherInfo = ref(null)
|
|
|
|
// 获取订单列表
|
|
const fetchOrderList = async () => {
|
|
loading.value = true
|
|
try {
|
|
// 过滤空值参数
|
|
const params = {}
|
|
Object.keys(queryParams).forEach(key => {
|
|
if (queryParams[key] !== '' && queryParams[key] !== null && queryParams[key] !== undefined) {
|
|
params[key] = queryParams[key]
|
|
}
|
|
})
|
|
const res = await getOrderList(params)
|
|
console.log('订单列表数据:', res.data)
|
|
if (res.data.code === 200) {
|
|
orderList.value = res.data.data.list || []
|
|
total.value = res.data.data.all_count || 0
|
|
}
|
|
} catch (error) {
|
|
console.error('获取订单列表失败:', error)
|
|
ElMessage.error('获取订单列表失败')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 格式化日期
|
|
const formatDate = (dateStr) => {
|
|
if (!dateStr) return '-'
|
|
const date = new Date(dateStr)
|
|
const year = date.getFullYear()
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
const hours = String(date.getHours()).padStart(2, '0')
|
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`
|
|
}
|
|
|
|
// 获取订单状态类型
|
|
const getStatusType = (status) => {
|
|
const statusMap = {
|
|
0: 'warning', // 待支付
|
|
1: 'success', // 已支付
|
|
2: 'info', // 已失效
|
|
}
|
|
return statusMap[status] || 'info'
|
|
}
|
|
|
|
// 获取订单状态文本
|
|
// state 0:未支付 1:已支付 2:已失效
|
|
const getStatusText = (status) => {
|
|
const statusMap = {
|
|
0: '待支付',
|
|
1: '已支付',
|
|
2: '已失效'
|
|
}
|
|
return statusMap[status] || '未知'
|
|
}
|
|
|
|
// 查询
|
|
const handleQuery = () => {
|
|
queryParams.page = 1
|
|
fetchOrderList()
|
|
}
|
|
|
|
// 重置查询
|
|
const resetQuery = () => {
|
|
queryParams.key = ''
|
|
queryParams.state = ''
|
|
queryParams.user_id = ''
|
|
queryParams.user_key = ''
|
|
queryParams.page = 1
|
|
fetchOrderList()
|
|
}
|
|
|
|
// 选择项变化
|
|
const handleSelectionChange = (selection) => {
|
|
selectedRows.value = selection
|
|
}
|
|
|
|
// 分页
|
|
const handleSizeChange = (size) => {
|
|
queryParams.count = size
|
|
fetchOrderList()
|
|
}
|
|
|
|
const handleCurrentChange = (page) => {
|
|
queryParams.page = page
|
|
fetchOrderList()
|
|
}
|
|
|
|
// 新增订单
|
|
const handleAdd = () => {
|
|
dialogType.value = 'add'
|
|
dialogVisible.value = true
|
|
clearAllSelections()
|
|
Object.assign(orderForm, {
|
|
order_id: undefined,
|
|
name: '',
|
|
table: '',
|
|
user_id: undefined,
|
|
commodity_id: 0,
|
|
pay_num: 1,
|
|
price: 0,
|
|
renew_price: 0,
|
|
expire_time: 0,
|
|
discount_code_id: 0,
|
|
coupon_id: 0,
|
|
state: 0,
|
|
pay_type: '',
|
|
args: '',
|
|
note: ''
|
|
})
|
|
orderFormRef.value?.resetFields()
|
|
}
|
|
|
|
// 查看订单详情
|
|
const handleView = async (row) => {
|
|
try {
|
|
const res = await getOrderDetail({ order_id: row.id })
|
|
if (res.data.code === 200) {
|
|
orderDetail.value = res.data.data
|
|
detailDialogVisible.value = true
|
|
}
|
|
} catch (error) {
|
|
console.error('获取订单详情失败:', error)
|
|
ElMessage.error('获取订单详情失败')
|
|
}
|
|
}
|
|
|
|
// 编辑订单
|
|
const handleEdit = (row) => {
|
|
dialogType.value = 'edit'
|
|
dialogVisible.value = true
|
|
clearAllSelections()
|
|
|
|
Object.assign(orderForm, {
|
|
order_id: row.id,
|
|
name: row.name,
|
|
table: row.table,
|
|
user_id: row.userId,
|
|
commodity_id: row.commodityId,
|
|
pay_num: row.payNum,
|
|
price: row.price,
|
|
renew_price: row.renewPrice,
|
|
expire_time: row.expireTime ? new Date(row.expireTime).getTime() / 1000 : 0,
|
|
discount_code_id: 0, // 从详情接口获取
|
|
coupon_id: 0, // 从详情接口获取
|
|
state: row.state,
|
|
pay_type: row.payType || '',
|
|
args: row.args || '',
|
|
note: row.note || ''
|
|
})
|
|
|
|
// 设置显示信息(只显示ID,名称需要从选择器中获取)
|
|
if (row.userId) {
|
|
selectedUserInfo.value = { user_id: row.userId, user_name: `用户${row.userId}` }
|
|
}
|
|
if (row.commodityId) {
|
|
selectedProductInfo.value = { id: row.commodityId, name: `商品${row.commodityId}` }
|
|
}
|
|
}
|
|
|
|
// 删除订单
|
|
const handleDelete = (row) => {
|
|
ElMessageBox.confirm(`确认删除订单 ${row.name} 吗?`, '警告', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(async () => {
|
|
try {
|
|
const res = await deleteOrder({ id: row.id })
|
|
if (res.data.code === 200) {
|
|
ElMessage.success('删除成功')
|
|
fetchOrderList()
|
|
}
|
|
} catch (error) {
|
|
console.error('删除失败:', error)
|
|
ElMessage.error(error.response?.data?.message || '删除失败')
|
|
}
|
|
}).catch(() => {})
|
|
}
|
|
|
|
// 批量删除
|
|
const handleBatchDelete = () => {
|
|
if (selectedRows.value.length === 0) {
|
|
ElMessage.warning('请至少选择一条记录')
|
|
return
|
|
}
|
|
ElMessageBox.confirm(`确认删除选中的 ${selectedRows.value.length} 条记录吗?`, '警告', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
ElMessage.success('批量删除成功')
|
|
fetchOrderList()
|
|
}).catch(() => {})
|
|
}
|
|
|
|
// 提交表单
|
|
const submitForm = () => {
|
|
orderFormRef.value?.validate(async (valid) => {
|
|
if (valid) {
|
|
try {
|
|
// 准备提交的数据
|
|
const submitData = {
|
|
name: orderForm.name,
|
|
table: orderForm.table,
|
|
user_id: Number(orderForm.user_id),
|
|
commodity_id: Number(orderForm.commodity_id),
|
|
pay_num: Number(orderForm.pay_num),
|
|
price: Number(orderForm.price),
|
|
renew_price: Number(orderForm.renew_price),
|
|
expire_time: Number(orderForm.expire_time),
|
|
discount_code_id: Number(orderForm.discount_code_id),
|
|
coupon_id: Number(orderForm.coupon_id),
|
|
state: Number(orderForm.state),
|
|
pay_type: orderForm.pay_type || '',
|
|
args: orderForm.args || '',
|
|
note: orderForm.note || ''
|
|
}
|
|
|
|
// 如果是编辑,添加order_id
|
|
if (dialogType.value === 'edit') {
|
|
submitData.order_id = Number(orderForm.order_id)
|
|
}
|
|
|
|
console.log('提交订单数据:', submitData)
|
|
|
|
let res
|
|
if (dialogType.value === 'add') {
|
|
res = await createOrder(submitData)
|
|
} else {
|
|
res = await updateOrder(submitData)
|
|
}
|
|
|
|
if (res.data.code === 200) {
|
|
ElMessage.success(dialogType.value === 'add' ? '新增成功' : '修改成功')
|
|
dialogVisible.value = false
|
|
fetchOrderList()
|
|
}
|
|
} catch (error) {
|
|
console.error('操作失败:', error)
|
|
ElMessage.error(error.response?.data?.message || '操作失败')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// 用户选择处理
|
|
const handleUserSelect = (user) => {
|
|
orderForm.user_id = user.user_id
|
|
selectedUserInfo.value = user
|
|
}
|
|
|
|
const clearUser = () => {
|
|
orderForm.user_id = undefined
|
|
selectedUserInfo.value = null
|
|
}
|
|
|
|
// 商品选择处理
|
|
const handleProductSelect = (product) => {
|
|
orderForm.commodity_id = product.id
|
|
selectedProductInfo.value = product
|
|
// 自动填充表名
|
|
if (product.table) {
|
|
orderForm.table = product.table
|
|
}
|
|
}
|
|
|
|
const clearProduct = () => {
|
|
orderForm.commodity_id = 0
|
|
selectedProductInfo.value = null
|
|
}
|
|
|
|
// 优惠码选择处理
|
|
const handleDiscountCodeSelect = (code) => {
|
|
orderForm.discount_code_id = code.id
|
|
selectedDiscountCodeInfo.value = code
|
|
}
|
|
|
|
const clearDiscountCode = () => {
|
|
orderForm.discount_code_id = 0
|
|
selectedDiscountCodeInfo.value = null
|
|
}
|
|
|
|
// 代金券选择处理
|
|
const handleVoucherSelect = (voucher) => {
|
|
orderForm.coupon_id = voucher.id
|
|
selectedVoucherInfo.value = voucher
|
|
}
|
|
|
|
const clearVoucher = () => {
|
|
orderForm.coupon_id = 0
|
|
selectedVoucherInfo.value = null
|
|
}
|
|
|
|
// 清除所有选择信息
|
|
const clearAllSelections = () => {
|
|
selectedUserInfo.value = null
|
|
selectedProductInfo.value = null
|
|
selectedDiscountCodeInfo.value = null
|
|
selectedVoucherInfo.value = null
|
|
}
|
|
|
|
// 初始化
|
|
onMounted(() => {
|
|
fetchOrderList()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.order-list-container {
|
|
padding: 0;
|
|
}
|
|
|
|
.main-container {
|
|
border: 1px solid #e1e8ed;
|
|
background: #ffffff;
|
|
}
|
|
|
|
.filter-section {
|
|
padding: 0;
|
|
border-bottom: 1px solid #e1e8ed;
|
|
background: #fafbfc;
|
|
}
|
|
|
|
.filter-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
padding: 16px 20px;
|
|
gap: 20px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.filter-form {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
|
|
.filter-form :deep(.el-form-item) {
|
|
margin-bottom: 0;
|
|
margin-right: 8px;
|
|
}
|
|
|
|
.filter-form :deep(.el-form-item__label) {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.action-bar {
|
|
display: flex;
|
|
gap: 12px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.table-section {
|
|
padding: 0;
|
|
}
|
|
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
|
|
.amount {
|
|
color: #f56c6c;
|
|
font-weight: bold;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.renew-price {
|
|
color: #409eff;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.pagination {
|
|
margin-top: 20px;
|
|
padding: 16px 20px;
|
|
border-top: 1px solid #e1e8ed;
|
|
background: #fafbfc;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.dialog-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 12px;
|
|
padding: 0;
|
|
}
|
|
|
|
/* 表格样式优化 */
|
|
:deep(.el-table) {
|
|
border: none;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
:deep(.el-table__header) {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
:deep(.el-table th) {
|
|
background: #f8f9fa !important;
|
|
border-bottom: 2px solid #e1e8ed;
|
|
color: #2c3e50;
|
|
font-weight: 600;
|
|
font-size: 13px;
|
|
}
|
|
|
|
:deep(.el-table td) {
|
|
border-bottom: 1px solid #f0f2f5;
|
|
color: #34495e;
|
|
}
|
|
|
|
:deep(.el-table tr:hover > td) {
|
|
background-color: #f8f9fa !important;
|
|
}
|
|
|
|
:deep(.el-card__body) {
|
|
padding: 0;
|
|
}
|
|
|
|
/* 骨架屏样式 */
|
|
.skeleton-container {
|
|
padding: 20px;
|
|
}
|
|
|
|
.skeleton-row {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 16px 0;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
gap: 16px;
|
|
}
|
|
|
|
.skeleton-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.skeleton-cell {
|
|
height: 20px;
|
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
background-size: 200% 100%;
|
|
animation: skeleton-loading 1.5s ease-in-out infinite;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.skeleton-checkbox { width: 55px; }
|
|
.skeleton-id { width: 100px; }
|
|
.skeleton-name { width: 180px; }
|
|
.skeleton-user { width: 100px; }
|
|
.skeleton-price { width: 120px; }
|
|
.skeleton-status { width: 100px; }
|
|
.skeleton-time { width: 170px; }
|
|
.skeleton-action { width: 200px; height: 32px; }
|
|
|
|
@keyframes skeleton-loading {
|
|
0% { background-position: 200% 0; }
|
|
100% { background-position: -200% 0; }
|
|
}
|
|
|
|
/* 选择器字段样式 */
|
|
.selector-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
width: 100%;
|
|
}
|
|
|
|
.selector-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.selector-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
</style>
|