2025-10-09 18:03:47 +08:00

784 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="orderManagement">
<!-- 移动端搜索框 -->
<el-card class="mobileCaed" v-if="isMobile">
<el-row :span="24">
<el-col :span="24" class="search">
<el-select v-model="select" filterable @change="selectSearch" class="searchSelect" placeholder="请选择"
size="small">
<el-option label="订单号" value="id" />
<el-option label="订单日期" value="order_date" />
<el-option label="订单状态:未支付" value="0" />
<el-option label="订单状态:已支付" value="1" />
<el-option label="订单状态:已取消" value="3" />
</el-select>
<el-input size="small" v-show="this.select == 'id'" placeholder="请输入内容" class="input-with-select"
@input="input" v-model="searchValue" clearable></el-input>
</el-col>
</el-row>
<el-row>
<el-col :span="24" style="margin-top:5px;">
<div v-if="select == 'order_date'">
<div class="datePicker">
<el-date-picker size="small" @change="change" v-model="value1" type="daterange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd">
</el-date-picker>
</div>
</div>
</el-col>
</el-row>
<!-- 筛选状态显示 -->
<el-row v-if="hasActiveFilters" style="margin-top: 5px;">
<el-col :span="24">
<div class="filter-status">
<span class="filter-label">当前筛选: </span>
<el-tag v-if="businessOpFilter" size="small" closable @close="clearBusinessOpFilter">
{{ getOrderTypeConfig(businessOpFilter).text }}
</el-tag>
<el-tag v-if="orderStatusFilter" size="small" closable @close="clearOrderStatusFilter"
:type="orderStatusFilter === '1' ? 'success' : orderStatusFilter === '0' ? 'danger' : 'info'">
{{ getOrderStatusText(orderStatusFilter) }}
</el-tag>
</div>
</el-col>
</el-row>
<!-- 移动端类型筛选 -->
<el-row style="margin-top: 10px;">
<el-col :span="24">
<div class="mobile-filter">
<span class="filter-label">类型:</span>
<el-button
v-for="(config, type) in orderTypes"
:key="type"
size="mini"
:type="businessOpFilter === type ? config.buttonType : ''"
@click="handleBusinessOpFilter(type)">
{{ config.text }}
</el-button>
</div>
</el-col>
</el-row>
<!-- 移动端状态筛选 -->
<el-row style="margin-top: 5px;">
<el-col :span="24">
<div class="mobile-filter">
<span class="filter-label">状态:</span>
<el-button
v-for="status in orderStatuses"
:key="status.value"
size="mini"
:type="orderStatusFilter === status.value ? status.buttonType : ''"
@click="handleOrderStatusFilter(status.value)">
{{ status.text }}
</el-button>
</div>
</el-col>
</el-row>
<el-row class="allPrice">
<el-col :span="24">
<span class="price" style="font-size: 18px">支付总金额:¥ {{ all_price }}</span>
<el-button type="primary" class="searchSelectIcon" @click="resetAllFilters">重置</el-button>
</el-col>
</el-row>
</el-card>
<!-- PC端头部 -->
<el-card class="pcCard" v-else>
<div class="header-container">
<div class="search-group">
<el-select v-model="select" filterable @change="selectSearch" class="search-select" placeholder="请选择"
size="small" style="width: 100px">
<el-option label="订单号" value="id" />
<el-option label="订单日期" value="order_date" />
<!-- <el-option label="订单状态:未支付" value="0" />
<el-option label="订单状态:已支付" value="1" />
<el-option label="订单状态:已取消" value="3" /> -->
</el-select>
<el-input size="small" v-show="select == 'id'" placeholder="请输入内容" class="search-input" @input="input"
v-model="searchValue" clearable style="width: 180px; margin-left: 10px">
</el-input>
<div v-if="select == 'order_date'" class="date-picker-container">
<el-date-picker size="small" @change="change" v-model="value1" type="daterange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd"
style="width: 240px; margin-left: 10px">
</el-date-picker>
</div>
</div>
<!-- 筛选状态显示 -->
<div v-if="hasActiveFilters" class="filter-status-pc">
<span class="filter-label">当前筛选: </span>
<el-tag v-if="businessOpFilter" size="small" closable @close="clearBusinessOpFilter">
{{ getOrderTypeConfig(businessOpFilter).text }}
</el-tag>
<el-tag v-if="orderStatusFilter" size="small" closable @close="clearOrderStatusFilter"
:type="orderStatusFilter === '1' ? 'success' : orderStatusFilter === '0' ? 'danger' : 'info'">
{{ getOrderStatusText(orderStatusFilter) }}
</el-tag>
</div>
<div class="stats-group">
<div class="stat-item">
<span class="stat-label">累计支付总金额:</span>
<div class="stat-value">
<el-skeleton animated v-if="all_price_show" :rows="1" style="width: 80px" />
<span v-else class="price-text">¥ {{ all_price || '0.00' }}</span>
</div>
</div>
<div class="stat-item">
<span class="stat-label">累计优惠总金额:</span>
<div class="stat-value">
<el-skeleton animated v-if="all_price_show" :rows="1" style="width: 80px" />
<span v-else class="price-text">¥ {{ all_discount || '0.00' }}</span>
</div>
</div>
</div>
<!-- 类型筛选 -->
<div class="type-filter">
<span>订单类型筛选</span>
<el-button
v-for="(config, type) in orderTypes"
:key="type"
:type="businessOpFilter === type ? config.buttonType : ''"
@click="handleBusinessOpFilter(type)">
{{ config.text }}
</el-button>
</div>
<!-- 状态筛选 -->
<div class="status-filter">
<span>订单状态筛选</span>
<el-button
v-for="status in orderStatuses"
:key="status.value"
:type="orderStatusFilter === status.value ? status.buttonType : ''"
@click="handleOrderStatusFilter(status.value)">
{{ status.text }}
</el-button>
</div>
<!-- 重置按钮 -->
<div class="reset">
<el-button type="primary" size="small" class="reset-btn" @click="resetAllFilters"
style="margin-left: 10px; padding: 7px 15px">
重置
</el-button>
</div>
</div>
</el-card>
<!-- 表格部分 -->
<el-card class="orderList">
<el-table border :data="tableData" class="table" height="calc(100vh - 264px)" v-loading="all_price_show">
<el-table-column label="序号" width="180">
<template slot-scope="scope">
{{ (pagination.page - 1) * pagination.size + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column align="center" min-width="180" header-align="center" prop="product_name" label="产品名称">
</el-table-column>
<el-table-column align="center" min-width="180" header-align="center" prop="id" label="订单号"></el-table-column>
<el-table-column align="center" header-align="center" label="订单原价" prop="list_price">
<template slot-scope="scope">
{{ scope.row.list_price }}
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="订单折后价">
<template slot-scope="scope">
{{ scope.row.amount ? "¥" + scope.row.amount : "-" }}
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="订单类型">
<template slot-scope="scope">
<el-tag :style="{ padding: '0 8px' }" :type="getOrderTypeConfig(scope.row.business_op).type">
{{ getOrderTypeConfig(scope.row.business_op).text }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="订单状态">
<template slot-scope="scope">
<el-tag :style="{ padding: '0 5px' }" :type="getOrderStatusConfig(scope.row.order_status).tagType" effect="dark">
{{ getOrderStatusConfig(scope.row.order_status).text }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" prop="order_date" label="订单日期"></el-table-column>
<el-table-column align="center" header-align="center" label="操作">
<template slot-scope="scope">
<el-button size="small" v-if="scope.row.order_status === '0'" type="primary"
@click="orderDetails(scope.row)" style="padding: 8px 15px">去支付
</el-button>
<el-button size="small" v-else type="primary" @click="orderDetails(scope.row)" style="padding: 8px">
查看详情
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="page">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="pagination.page" :page-sizes="[10, 20, 50, 100]" :page-size="pagination.size"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { getOrderAPI } from "@/api/product/product";
export default {
name: 'OrderManagement',
data() {
return {
pagination: {
page: 1,
size: 10,
total: 0
},
all_price_show: true,
userAgent: window.navigator.userAgent,
isMobile: false,
all_price: '',
all_discount: '0.00',
showDate: false,
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
value1: '',
select: "",
tableData: [],
searchValue: null,
order_status_select: null,
userId: sessionStorage.getItem("userId"),
dialogVisible: false,
// 订单类型筛选
businessOpFilter: null,
// 订单状态筛选
orderStatusFilter: null,
// 订单类型配置
orderTypes: {
'BUY_REVERSE': { text: '退费', type: 'danger', buttonType: 'danger' },
'RENEW': { text: '续费', type: 'primary', buttonType: 'primary' },
'BUY': { text: '购买', type: 'success', buttonType: 'success' }
},
// 订单状态配置
orderStatuses: [
{ value: '1', text: '已支付', buttonType: 'success', tagType: 'success' },
{ value: '0', text: '未支付', buttonType: 'danger', tagType: 'warning' },
{ value: '3', text: '已取消', buttonType: 'info', tagType: 'info' }
],
orderDetail: {
order_goods: [
{
productid: "",
amount: "",
list_price: "",
quantity: "",
discount: "",
price: "",
},
],
},
};
},
computed: {
// 检查是否有活跃的筛选条件
hasActiveFilters() {
return this.businessOpFilter || this.orderStatusFilter;
}
},
created() {
this.getOrder();
this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent);
},
methods: {
// 获取订单类型配置
getOrderTypeConfig(type) {
return this.orderTypes[type] || { text: "-", type: "primary", buttonType: "" };
},
// 获取订单状态配置
getOrderStatusConfig(status) {
const statusConfig = this.orderStatuses.find(s => s.value === status);
return statusConfig || { text: this.getOrderStatusText(status), tagType: 'info' };
},
// 获取订单状态文本
getOrderStatusText(status) {
switch (status) {
case "0":
return "未支付";
case "1":
return "已支付";
case "2":
return "已关闭";
case "3":
return "已取消";
case "4":
return "后付费";
default:
return "未知状态";
}
},
// 处理订单类型筛选
handleBusinessOpFilter(type) {
console.log("订单类型筛选:", type, this.getOrderTypeConfig(type).text);
// 如果点击已经选中的按钮,则取消筛选
if (this.businessOpFilter === type) {
this.businessOpFilter = null;
} else {
this.businessOpFilter = type;
}
this.pagination.page = 1;
this.getOrder();
},
// 清除订单类型筛选
clearBusinessOpFilter() {
this.businessOpFilter = null;
this.pagination.page = 1;
this.getOrder();
},
// 处理订单状态筛选
handleOrderStatusFilter(status) {
console.log("订单状态筛选:", status, this.getOrderStatusText(status));
// 如果点击已经选中的按钮,则取消筛选
if (this.orderStatusFilter === status) {
this.orderStatusFilter = null;
} else {
this.orderStatusFilter = status;
}
this.pagination.page = 1;
this.getOrder();
},
// 清除订单状态筛选
clearOrderStatusFilter() {
this.orderStatusFilter = null;
this.pagination.page = 1;
this.getOrder();
},
// 重置所有筛选条件
resetAllFilters() {
this.value1 = null;
this.searchValue = null;
this.select = null;
this.businessOpFilter = null;
this.orderStatusFilter = null;
this.pagination.page = 1;
this.getOrder();
},
// 获取订单数据
getOrder() {
let params = {
page: this.pagination.page,
size: this.pagination.size,
type: '200' // 确保始终传递type参数
};
// 订单号搜索
if (this.select === 'id' && this.searchValue) {
params['id'] = this.searchValue;
}
// 日期范围搜索
if (this.select === 'order_date' && this.value1) {
params['start_time'] = this.value1[0];
params['end_time'] = this.value1[1];
}
// 下拉选择的状态筛选
if (['0', '1', '3'].includes(this.select)) {
params['order_status'] = this.select;
}
// 按钮状态筛选 - 优先级高于下拉选择
if (this.orderStatusFilter) {
params['order_status'] = this.orderStatusFilter;
}
// 订单类型筛选
if (this.businessOpFilter) {
params['business_op'] = this.businessOpFilter;
}
console.log("API请求参数:", params);
this.all_price_show = true;
getOrderAPI(params).then((res) => {
this.all_price_show = false;
console.log("API响应数据:", res);
if (res.status === true || res.code === 200) {
this.tableData = res.data || [];
this.all_price = res.all_price || '0.00';
this.all_discount = res.all_discount || '0.00';
// 修复分页总数设置
if (res.pagination && res.pagination.total !== undefined) {
this.pagination.total = res.pagination.total;
} else if (res.total !== undefined) {
this.pagination.total = res.total;
} else {
this.pagination.total = this.tableData.length;
}
// 调试信息:显示筛选后的数据
if (this.businessOpFilter) {
const filteredData = this.tableData.filter(item => item.business_op === this.businessOpFilter);
console.log(`类型筛选结果: ${this.getOrderTypeConfig(this.businessOpFilter).text}`, filteredData);
}
} else {
this.$message.error(res.message || '获取数据失败');
}
}).catch(error => {
console.error("获取订单数据失败:", error);
this.all_price_show = false;
this.$message.error('请求失败,请检查网络连接');
});
},
handleSizeChange(val) {
this.pagination.size = val;
this.pagination.page = 1;
this.getOrder();
},
handleCurrentChange(val) {
this.pagination.page = val;
this.getOrder();
},
change(e) {
this.value1 = e;
this.pagination.page = 1;
this.getOrder();
},
selectSearch(e) {
this.select = e;
// 当选择状态选项时,直接触发搜索
if (['0', '1', '3'].includes(e)) {
this.getOrder();
} else {
// 对于其他选项(如订单号、日期),清空其他搜索条件
if (e !== 'order_date') {
this.value1 = null;
}
if (e !== 'id') {
this.searchValue = null;
}
}
},
input(e) {
this.searchValue = e;
this.pagination.page = 1;
this.getOrder();
},
orderDetails(row) {
this.$router.push({ name: "orderDetil", query: { id: row.id } });
}
}
};
</script>
<style lang="less" scoped>
.orderManagement {
height: calc(100vh - 180px);
.mobileCaed {
height: auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
padding: 10px;
.search {
display: flex;
justify-content: flex-start;
align-items: center;
width: 100%;
.searchSelect {
width: 150px;
}
.input-with-select {
width: 150px;
margin-left: 10px;
}
}
.filter-status {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
.filter-label {
font-size: 14px;
color: #606266;
white-space: nowrap;
}
.el-tag {
cursor: pointer;
}
}
.mobile-filter {
display: flex;
align-items: center;
margin-bottom: 5px;
.filter-label {
margin-right: 8px;
font-size: 14px;
color: #606266;
white-space: nowrap;
}
.el-button {
margin-right: 5px;
padding: 4px 8px;
font-size: 12px;
}
}
.allPrice {
margin-top: 10px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.searchSelectIcon {
padding: 0 5px;
height: 20px;
}
.price {
font-weight: 600;
font-size: 14px;
}
.datePicker {
display: flex;
margin-left: 10px;
width: auto;
}
}
}
// PC端优化样式
.pcCard {
margin-bottom: 10px;
.header-container {
display: flex;
align-items: center;
justify-content: flex-start;
// height: 60px;
flex-wrap: wrap;
.search-group {
display: flex;
align-items: center;
.search-select {
width: 130px;
}
.search-input {
width: 180px;
}
.date-picker-container {
display: flex;
align-items: center;
}
}
.filter-status-pc {
display: flex;
align-items: center;
gap: 8px;
margin-left: 8px;
.filter-label {
font-size: 14px;
color: #606266;
white-space: nowrap;
}
.el-tag {
cursor: pointer;
}
}
.stats-group {
display: flex;
align-items: center;
.stat-item {
display: flex;
align-items: center;
font-size: 14px;
margin-left: 10px;
.stat-label {
color: #606266;
margin-right: 8px;
white-space: nowrap;
}
.stat-value {
min-width: 80px;
.price-text {
color: #e6a23c;
font-weight: 600;
font-size: 16px;
}
}
}
}
.type-filter, .status-filter {
display: flex;
align-items: center;
margin-left: 20px;
span {
margin-right: 8px;
font-size: 14px;
color: #606266;
white-space: nowrap;
}
.el-button {
margin-right: 5px;
padding: 7px 12px;
}
}
.reset {
display: flex;
align-items: center;
}
}
}
.orderList {
margin-top: 10px;
height: calc(100vh - 180px);
.table {
width: 100%;
}
}
}
.page {
text-align: center;
margin: 20px;
}
// 全局样式调整
::v-deep .el-table .el-table__header {
background-color: #d0cff8;
}
::v-deep .el-tag {
padding: 0 8px !important;
}
// 响应式调整
@media screen and (max-width: 1200px) {
.pcCard .header-container {
height: auto;
padding: 10px 0;
.search-group,
.stats-group,
.type-filter,
.status-filter,
.reset {
margin-bottom: 10px;
}
}
}
// 按钮选中状态优化
::v-deep .el-button--primary:focus,
::v-deep .el-button--primary:hover,
::v-deep .el-button--success:focus,
::v-deep .el-button--success:hover,
::v-deep .el-button--danger:focus,
::v-deep .el-button--danger:hover {
opacity: 0.8;
}
// 移动端适配
@media screen and (max-width: 768px) {
.mobile-filter {
flex-wrap: wrap;
.filter-label {
width: 100%;
margin-bottom: 5px;
}
.el-button {
margin-bottom: 5px;
}
}
}
</style>