refactor(分析模块): 优化组件结构和搜索功能
- 合并和简化模板中的header部分,提升代码可读性 - 统一搜索条件的布局,增强用户体验 - 更新数据绑定逻辑,确保搜索参数的正确处理 - 精简和优化表格及分页组件的实现,提升性能和可维护性
This commit is contained in:
@@ -6,29 +6,6 @@
|
||||
<span>分销效果核算</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 搜索条件 -->
|
||||
<div class="search-container">
|
||||
<el-form :model="searchParams" :inline="true" class="search-form">
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="searchParams.dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="达人名称">
|
||||
<el-input v-model="searchParams.anchorName" placeholder="请输入达人名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- 分销效果趋势 -->
|
||||
<div class="chart-container">
|
||||
<el-card>
|
||||
<template #header>
|
||||
@@ -37,32 +14,25 @@
|
||||
<div ref="effectChartRef" class="chart"></div>
|
||||
</el-card>
|
||||
</div>
|
||||
<!-- 核心指标 -->
|
||||
<div class="stats-cards">
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-card-title">总销售额</div>
|
||||
<div class="stats-card-value">{{ statsData.totalSales || 0 }}</div>
|
||||
</el-card>
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-card-title">总佣金金额</div>
|
||||
<div class="stats-card-value">{{ statsData.totalCommission || 0 }}</div>
|
||||
</el-card>
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-card-title">平均佣金率</div>
|
||||
<div class="stats-card-value">{{ statsData.avgCommissionRate || 0 }}%</div>
|
||||
</el-card>
|
||||
<el-card class="stats-card">
|
||||
<div class="stats-card-title">达人数量</div>
|
||||
<div class="stats-card-value">{{ statsData.anchorCount || 0 }}</div>
|
||||
</el-card>
|
||||
<el-card class="stats-card"><div class="stats-card-title">总销售额</div><div class="stats-card-value">{{ statsData.totalSales || 0 }}</div></el-card>
|
||||
<el-card class="stats-card"><div class="stats-card-title">总佣金金额</div><div class="stats-card-value">{{ statsData.totalCommission || 0 }}</div></el-card>
|
||||
<el-card class="stats-card"><div class="stats-card-title">平均佣金率</div><div class="stats-card-value">{{ statsData.avgCommissionRate || 0 }}%</div></el-card>
|
||||
<el-card class="stats-card"><div class="stats-card-title">达人数量</div><div class="stats-card-value">{{ statsData.anchorCount || 0 }}</div></el-card>
|
||||
</div>
|
||||
<!-- 达人推广效果 -->
|
||||
<div class="anchor-effect">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">达人推广效果</div>
|
||||
</template>
|
||||
<el-table :data="anchorList" style="width: 100%">
|
||||
<template #header><div class="card-header">达人推广效果</div></template>
|
||||
<div class="search-container">
|
||||
<el-form :model="searchParams" :inline="true" class="search-form">
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker v-model="searchParams.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
<el-form-item label="达人名称"><el-input v-model="searchParams.anchorName" placeholder="请输入达人名称" clearable /></el-form-item>
|
||||
<el-form-item><el-button type="primary" @click="handleSearch">查询</el-button><el-button @click="handleReset">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table :data="pagedAnchorList" style="width: 100%">
|
||||
<el-table-column prop="rank" label="排名" width="80" />
|
||||
<el-table-column prop="anchorName" label="达人名称" />
|
||||
<el-table-column prop="sales" label="销售额" />
|
||||
@@ -72,15 +42,7 @@
|
||||
<el-table-column prop="conversionRate" label="转化率" />
|
||||
</el-table>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.currentPage"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -89,223 +51,74 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
const searchParams = reactive({
|
||||
dateRange: [],
|
||||
anchorName: '',
|
||||
});
|
||||
|
||||
const statsData = reactive({
|
||||
totalSales: 0,
|
||||
totalCommission: 0,
|
||||
avgCommissionRate: 0,
|
||||
anchorCount: 0,
|
||||
});
|
||||
|
||||
interface AnchorItem {
|
||||
rank: number;
|
||||
anchorName: string;
|
||||
sales: number;
|
||||
commission: number;
|
||||
commissionRate: number;
|
||||
orderCount: number;
|
||||
conversionRate: number;
|
||||
}
|
||||
|
||||
const searchParams = reactive({ dateRange: [], anchorName: '' });
|
||||
const statsData = reactive({ totalSales: 0, totalCommission: 0, avgCommissionRate: 0, anchorCount: 0 });
|
||||
interface AnchorItem { rank: number; anchorName: string; sales: number; commission: number; commissionRate: number; orderCount: number; conversionRate: number }
|
||||
const anchorList = ref<AnchorItem[]>([]);
|
||||
|
||||
const pagination = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const pagination = reactive({ currentPage: 1, pageSize: 10, total: 0 });
|
||||
const pagedAnchorList = computed(() => anchorList.value.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize));
|
||||
const effectChartRef = ref();
|
||||
let effectChart: echarts.ECharts | null = null;
|
||||
|
||||
// 模拟分销效果趋势数据
|
||||
const getMockEffectTrend = () => {
|
||||
const dates = ['1月', '2月', '3月', '4月', '5月', '6月'];
|
||||
return dates.map((date) => ({
|
||||
date,
|
||||
sales: 500000 + Math.random() * 1000000,
|
||||
commission: 50000 + Math.random() * 200000,
|
||||
}));
|
||||
};
|
||||
|
||||
// 模拟达人推广效果数据
|
||||
const getMockAnchorList = () => {
|
||||
const anchors: AnchorItem[] = [];
|
||||
for (let i = 1; i <= 20; i++) {
|
||||
anchors.push({
|
||||
rank: i,
|
||||
anchorName: `达人${i}`,
|
||||
sales: 100000 + Math.random() * 900000,
|
||||
commission: 10000 + Math.random() * 180000,
|
||||
commissionRate: 10 + Math.random() * 10,
|
||||
orderCount: 100 + Math.floor(Math.random() * 900),
|
||||
conversionRate: parseFloat((1 + Math.random() * 9).toFixed(2)),
|
||||
});
|
||||
}
|
||||
return anchors;
|
||||
const dates = searchParams.anchorName ? ['本期'] : ['1月', '2月', '3月', '4月', '5月', '6月'];
|
||||
return dates.map((date) => ({ date, sales: 500000 + Math.random() * 1000000, commission: 50000 + Math.random() * 200000 }));
|
||||
};
|
||||
const getMockAnchorList = () => Array.from({ length: 24 }, (_, i) => ({ rank: i + 1, anchorName: `达人${i + 1}`, sales: 100000 + Math.random() * 900000, commission: 10000 + Math.random() * 180000, commissionRate: +(10 + Math.random() * 10).toFixed(2), orderCount: 100 + Math.floor(Math.random() * 900), conversionRate: +(1 + Math.random() * 9).toFixed(2) }));
|
||||
|
||||
const handleSearch = () => {
|
||||
// 使用模拟数据
|
||||
statsData.totalSales = 5000000 + Math.random() * 5000000;
|
||||
statsData.totalCommission = 500000 + Math.random() * 500000;
|
||||
statsData.avgCommissionRate = 15 + Math.random() * 5;
|
||||
statsData.avgCommissionRate = +(15 + Math.random() * 5).toFixed(2);
|
||||
statsData.anchorCount = 50 + Math.floor(Math.random() * 50);
|
||||
anchorList.value = getMockAnchorList();
|
||||
pagination.total = 20;
|
||||
pagination.total = anchorList.value.length;
|
||||
pagination.currentPage = 1;
|
||||
initEffectChart(getMockEffectTrend());
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
searchParams.dateRange = [];
|
||||
searchParams.anchorName = '';
|
||||
pagination.currentPage = 1;
|
||||
pagination.pageSize = 10;
|
||||
};
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size;
|
||||
handleSearch();
|
||||
};
|
||||
|
||||
const handleCurrentChange = (current: number) => {
|
||||
pagination.currentPage = current;
|
||||
handleSearch();
|
||||
};
|
||||
const handleReset = () => { searchParams.dateRange = []; searchParams.anchorName = ''; pagination.currentPage = 1; pagination.pageSize = 10; handleSearch(); };
|
||||
const handleSizeChange = (size: number) => { pagination.pageSize = size; pagination.currentPage = 1; };
|
||||
const handleCurrentChange = (current: number) => { pagination.currentPage = current; };
|
||||
|
||||
const initEffectChart = (effectTrend: any[]) => {
|
||||
if (!effectChartRef.value) return;
|
||||
|
||||
if (effectChart) {
|
||||
effectChart.dispose();
|
||||
}
|
||||
|
||||
if (effectChart) effectChart.dispose();
|
||||
effectChart = echarts.init(effectChartRef.value);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985',
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['销售额', '佣金金额'],
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: effectTrend.map((item) => item.date),
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '金额',
|
||||
position: 'left',
|
||||
},
|
||||
],
|
||||
const isSingle = effectTrend.length <= 1;
|
||||
effectChart.setOption({
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } } },
|
||||
legend: { data: ['销售额', '佣金金额'] },
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: { type: 'category', boundaryGap: isSingle, data: effectTrend.map((item) => item.date) },
|
||||
yAxis: [{ type: 'value', name: '金额', position: 'left' }],
|
||||
series: [
|
||||
{
|
||||
name: '销售额',
|
||||
type: 'line',
|
||||
data: effectTrend.map((item) => item.sales),
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: '佣金金额',
|
||||
type: 'line',
|
||||
data: effectTrend.map((item) => item.commission),
|
||||
smooth: true,
|
||||
},
|
||||
{ name: '销售额', type: 'line', data: effectTrend.map((item) => item.sales), smooth: true, showSymbol: true, symbolSize: isSingle ? 10 : 6 },
|
||||
{ name: '佣金金额', type: 'line', data: effectTrend.map((item) => item.commission), smooth: true, showSymbol: true, symbolSize: isSingle ? 10 : 6 },
|
||||
],
|
||||
};
|
||||
|
||||
effectChart.setOption(option);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleSearch();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
effectChart?.resize();
|
||||
});
|
||||
window.addEventListener('resize', () => effectChart?.resize());
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.trade-operation-distribution-effect {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.stats-card-title {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stats-card-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.anchor-effect {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
.trade-operation-distribution-effect { padding: 20px; }
|
||||
.card-header { display: flex; align-items: center; justify-content: space-between; font-size: 16px; font-weight: 600; }
|
||||
.search-container { margin-bottom: 16px; }
|
||||
.search-form { display: flex; align-items: center; flex-wrap: wrap; }
|
||||
.search-form :deep(.el-form-item) { margin-right: 12px; margin-bottom: 12px; }
|
||||
.stats-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 20px; }
|
||||
.stats-card { text-align: center; padding: 20px; }
|
||||
.stats-card-title { font-size: 14px; color: #606266; margin-bottom: 10px; }
|
||||
.stats-card-value { font-size: 24px; font-weight: bold; }
|
||||
.anchor-effect { margin-bottom: 20px; }
|
||||
.pagination-container { margin-top: 16px; display: flex; justify-content: flex-end; }
|
||||
.chart-container { margin: 0 0 20px; }
|
||||
.chart { width: 100%; height: 400px; }
|
||||
</style>
|
||||
|
||||
@@ -1,85 +1,37 @@
|
||||
<template>
|
||||
<div class="trade-operation-distribution-order">
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>分销订单查询</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 搜索条件 -->
|
||||
<div class="search-container">
|
||||
<el-form :model="searchParams" :inline="true" class="search-form">
|
||||
<el-form-item label="订单类型">
|
||||
<el-select v-model="searchParams.orderType" placeholder="选择订单类型">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="快分销二创订单" value="quick_distribution" />
|
||||
<el-option label="分销达人推广订单" value="anchor_promotion" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单号">
|
||||
<el-input v-model="searchParams.orderNo" placeholder="请输入订单号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="达人名称">
|
||||
<el-input v-model="searchParams.anchorName" placeholder="请输入达人名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
<el-date-picker
|
||||
v-model="searchParams.dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- 订单列表 -->
|
||||
<template #header><div class="card-header"><span>分销订单查询</span></div></template>
|
||||
<div class="order-list">
|
||||
<el-table :data="orderList" style="width: 100%">
|
||||
<el-table-column prop="orderNo" label="订单号" />
|
||||
<el-table-column prop="orderType" label="订单类型">
|
||||
<template #default="scope">
|
||||
<el-tag size="small">
|
||||
{{ scope.row.orderType === 'quick_distribution' ? '快分销二创' : '达人推广' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="anchorName" label="达人名称" />
|
||||
<el-table-column prop="productName" label="商品名称" />
|
||||
<el-table-column prop="amount" label="订单金额" />
|
||||
<el-table-column prop="commission" label="佣金金额" />
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="handleOrderDetail(scope.row.id)">查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.currentPage"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
<el-card>
|
||||
<template #header><div class="card-header">订单列表</div></template>
|
||||
<div class="search-container">
|
||||
<el-form :model="searchParams" :inline="true" class="search-form">
|
||||
<el-form-item label="订单类型"><el-select v-model="selectedOrderType" placeholder="选择订单类型"><el-option v-for="option in orderTypeOptions" :key="option.value || 'all'" :label="option.label" :value="option.value" /></el-select></el-form-item>
|
||||
<el-form-item label="订单号"><el-input v-model="searchParams.orderNo" placeholder="请输入订单号" clearable /></el-form-item>
|
||||
<el-form-item label="达人名称"><el-input v-model="searchParams.anchorName" placeholder="请输入达人名称" clearable /></el-form-item>
|
||||
<el-form-item label="时间范围"><el-date-picker v-model="searchParams.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" /></el-form-item>
|
||||
<el-form-item><el-button type="primary" @click="handleSearch">查询</el-button><el-button @click="handleReset">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table :data="pagedOrderList" style="width: 100%">
|
||||
<el-table-column prop="orderNo" label="订单号" />
|
||||
<el-table-column prop="orderType" label="订单类型"><template #default="scope"><el-tag size="small">{{ scope.row.orderType === 'quick_distribution' ? '快分销二创' : '达人推广' }}</el-tag></template></el-table-column>
|
||||
<el-table-column prop="anchorName" label="达人名称" />
|
||||
<el-table-column prop="productName" label="商品名称" />
|
||||
<el-table-column prop="amount" label="订单金额" />
|
||||
<el-table-column prop="commission" label="佣金金额" />
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column label="操作"><template #default="scope"><el-button type="primary" size="small" @click="handleOrderDetail(scope.row.id)">查看详情</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination-container"><el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /></div>
|
||||
</el-card>
|
||||
</div>
|
||||
<!-- 订单详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="订单详情" width="80%">
|
||||
<div v-if="orderDetail" class="order-detail">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="订单号">{{ orderDetail.orderNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单类型">{{
|
||||
orderDetail.orderType === 'quick_distribution' ? '快分销二创' : '达人推广'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单类型">{{ orderDetail.orderType === 'quick_distribution' ? '快分销二创' : '达人推广' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="达人名称">{{ orderDetail.anchorName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单金额">{{ orderDetail.amount }}</el-descriptions-item>
|
||||
<el-descriptions-item label="佣金金额">{{ orderDetail.commission }}</el-descriptions-item>
|
||||
@@ -87,27 +39,8 @@
|
||||
<el-descriptions-item label="创建时间">{{ orderDetail.createTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">{{ orderDetail.status }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 商品信息 -->
|
||||
<div class="detail-section">
|
||||
<h3>商品信息</h3>
|
||||
<el-table :data="orderDetail.products" style="width: 100%">
|
||||
<el-table-column prop="productName" label="商品名称" />
|
||||
<el-table-column prop="sku" label="SKU" />
|
||||
<el-table-column prop="quantity" label="数量" />
|
||||
<el-table-column prop="price" label="单价" />
|
||||
<el-table-column prop="commission" label="佣金" />
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 推广信息 -->
|
||||
<div class="detail-section">
|
||||
<h3>推广信息</h3>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="推广渠道">{{ orderDetail.promotion.channel }}</el-descriptions-item>
|
||||
<el-descriptions-item label="推广时间">{{ orderDetail.promotion.time }}</el-descriptions-item>
|
||||
<el-descriptions-item label="推广链接">{{ orderDetail.promotion.link }}</el-descriptions-item>
|
||||
<el-descriptions-item label="推广效果">{{ orderDetail.promotion.effect }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="detail-section"><h3>商品信息</h3><el-table :data="orderDetail.products" style="width: 100%"><el-table-column prop="productName" label="商品名称" /><el-table-column prop="sku" label="SKU" /><el-table-column prop="quantity" label="数量" /><el-table-column prop="price" label="单价" /><el-table-column prop="commission" label="佣金" /></el-table></div>
|
||||
<div class="detail-section"><h3>推广信息</h3><el-descriptions :column="2" border><el-descriptions-item label="推广渠道">{{ orderDetail.promotion.channel }}</el-descriptions-item><el-descriptions-item label="推广时间">{{ orderDetail.promotion.time }}</el-descriptions-item><el-descriptions-item label="推广链接">{{ orderDetail.promotion.link }}</el-descriptions-item><el-descriptions-item label="推广效果">{{ orderDetail.promotion.effect }}</el-descriptions-item></el-descriptions></div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
@@ -115,193 +48,49 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
|
||||
const searchParams = reactive({
|
||||
orderType: '',
|
||||
orderNo: '',
|
||||
anchorName: '',
|
||||
dateRange: [],
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
const searchParams = reactive({ orderType: '', orderNo: '', anchorName: '', dateRange: [] });
|
||||
const orderTypeOptions = [
|
||||
{ label: '全部', value: '' },
|
||||
{ label: '快分销二创订单', value: 'quick_distribution' },
|
||||
{ label: '分销达人推广订单', value: 'anchor_promotion' },
|
||||
];
|
||||
const selectedOrderType = computed({
|
||||
get: () => searchParams.orderType,
|
||||
set: (value: string) => {
|
||||
searchParams.orderType = value;
|
||||
},
|
||||
});
|
||||
|
||||
interface OrderItem {
|
||||
id: number;
|
||||
orderNo: string;
|
||||
orderType: string;
|
||||
anchorName: string;
|
||||
productName: string;
|
||||
amount: number;
|
||||
commission: number;
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
interface OrderItem { id: number; orderNo: string; orderType: string; anchorName: string; productName: string; amount: number; commission: number; createTime: string }
|
||||
const orderList = ref<OrderItem[]>([]);
|
||||
|
||||
const pagination = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
interface OrderDetail {
|
||||
orderNo: string;
|
||||
orderType: string;
|
||||
anchorName: string;
|
||||
amount: number;
|
||||
commission: number;
|
||||
commissionRate: number;
|
||||
createTime: string;
|
||||
status: string;
|
||||
products: {
|
||||
productName: string;
|
||||
sku: string;
|
||||
quantity: number;
|
||||
price: number;
|
||||
commission: number;
|
||||
}[];
|
||||
promotion: {
|
||||
channel: string;
|
||||
time: string;
|
||||
link: string;
|
||||
effect: string;
|
||||
};
|
||||
}
|
||||
|
||||
const pagination = reactive({ currentPage: 1, pageSize: 10, total: 0 });
|
||||
const pagedOrderList = computed(() => orderList.value.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize));
|
||||
interface OrderDetail { orderNo: string; orderType: string; anchorName: string; amount: number; commission: number; commissionRate: number; createTime: string; status: string; products: { productName: string; sku: string; quantity: number; price: number; commission: number }[]; promotion: { channel: string; time: string; link: string; effect: string } }
|
||||
const dialogVisible = ref(false);
|
||||
const orderDetail = ref<OrderDetail | null>(null);
|
||||
|
||||
// 模拟分销订单列表数据
|
||||
const getMockOrderList = () => {
|
||||
const orderTypes = ['quick_distribution', 'anchor_promotion'];
|
||||
const orders: OrderItem[] = [];
|
||||
for (let i = 1; i <= 20; i++) {
|
||||
orders.push({
|
||||
id: i,
|
||||
orderNo: `DO${Date.now() + i}`,
|
||||
orderType: orderTypes[Math.floor(Math.random() * orderTypes.length)],
|
||||
anchorName: `达人${i}`,
|
||||
productName: `商品${i}`,
|
||||
amount: 1000 + Math.random() * 9000,
|
||||
commission: 100 + Math.random() * 900,
|
||||
createTime: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
});
|
||||
}
|
||||
return orders;
|
||||
};
|
||||
|
||||
// 模拟分销订单详情数据
|
||||
const getMockOrderDetail = (id: number) => {
|
||||
return {
|
||||
orderNo: `DO${Date.now() + id}`,
|
||||
orderType: Math.random() > 0.5 ? 'quick_distribution' : 'anchor_promotion',
|
||||
anchorName: `达人${id}`,
|
||||
amount: 5000 + Math.random() * 5000,
|
||||
commission: 500 + Math.random() * 500,
|
||||
commissionRate: 10 + Math.random() * 10,
|
||||
createTime: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
status: '已完成',
|
||||
products: [
|
||||
{
|
||||
productName: '商品1',
|
||||
sku: 'SKU001',
|
||||
quantity: 2,
|
||||
price: 1500,
|
||||
commission: 300,
|
||||
},
|
||||
{
|
||||
productName: '商品2',
|
||||
sku: 'SKU002',
|
||||
quantity: 1,
|
||||
price: 2500,
|
||||
commission: 500,
|
||||
},
|
||||
],
|
||||
promotion: {
|
||||
channel: '抖音',
|
||||
time: new Date(Date.now() - 11 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
link: `https://example.com/promotion/${id}`,
|
||||
effect: '良好',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
// 使用模拟数据
|
||||
orderList.value = getMockOrderList();
|
||||
pagination.total = 20;
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
searchParams.orderType = '';
|
||||
searchParams.orderNo = '';
|
||||
searchParams.anchorName = '';
|
||||
searchParams.dateRange = [];
|
||||
pagination.currentPage = 1;
|
||||
pagination.pageSize = 10;
|
||||
};
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size;
|
||||
handleSearch();
|
||||
};
|
||||
|
||||
const handleCurrentChange = (current: number) => {
|
||||
pagination.currentPage = current;
|
||||
handleSearch();
|
||||
};
|
||||
|
||||
const handleOrderDetail = (id: number) => {
|
||||
// 使用模拟数据
|
||||
orderDetail.value = getMockOrderDetail(id);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleSearch();
|
||||
});
|
||||
const getMockOrderList = () => Array.from({ length: 24 }, (_, i) => ({ id: i + 1, orderNo: `DO${Date.now() + i}`, orderType: Math.random() > 0.5 ? 'quick_distribution' : 'anchor_promotion', anchorName: `达人${i + 1}`, productName: `商品${i + 1}`, amount: 1000 + Math.random() * 9000, commission: 100 + Math.random() * 900, createTime: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toISOString() }));
|
||||
const getMockOrderDetail = (id: number) => ({ orderNo: `DO${Date.now() + id}`, orderType: Math.random() > 0.5 ? 'quick_distribution' : 'anchor_promotion', anchorName: `达人${id}`, amount: 5000 + Math.random() * 5000, commission: 500 + Math.random() * 500, commissionRate: +(10 + Math.random() * 10).toFixed(2), createTime: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(), status: '已完成', products: [{ productName: '商品1', sku: 'SKU001', quantity: 2, price: 1500, commission: 300 }, { productName: '商品2', sku: 'SKU002', quantity: 1, price: 2500, commission: 500 }], promotion: { channel: '抖音', time: new Date(Date.now() - 11 * 24 * 60 * 60 * 1000).toISOString(), link: `https://example.com/promotion/${id}`, effect: '良好' } });
|
||||
const handleSearch = () => { orderList.value = getMockOrderList(); pagination.total = orderList.value.length; pagination.currentPage = 1; };
|
||||
const handleReset = () => { searchParams.orderType = ''; searchParams.orderNo = ''; searchParams.anchorName = ''; searchParams.dateRange = []; pagination.currentPage = 1; pagination.pageSize = 10; handleSearch(); };
|
||||
const handleSizeChange = (size: number) => { pagination.pageSize = size; pagination.currentPage = 1; };
|
||||
const handleCurrentChange = (current: number) => { pagination.currentPage = current; };
|
||||
const handleOrderDetail = (id: number) => { orderDetail.value = getMockOrderDetail(id); dialogVisible.value = true; };
|
||||
onMounted(() => handleSearch());
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.trade-operation-distribution-order {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.order-detail {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.detail-section h3 {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
color: #606266;
|
||||
}
|
||||
.trade-operation-distribution-order { padding: 20px; }
|
||||
.card-header { display: flex; align-items: center; justify-content: space-between; font-size: 16px; font-weight: 600; }
|
||||
.search-container { margin-bottom: 16px; }
|
||||
.search-form { display: flex; align-items: center; flex-wrap: wrap; }
|
||||
.search-form :deep(.el-form-item) { margin-right: 12px; margin-bottom: 12px; }
|
||||
.trade-operation-distribution-order :deep(.el-select) { width: 180px; }
|
||||
.trade-operation-distribution-order :deep(.el-select__wrapper),
|
||||
.trade-operation-distribution-order :deep(.el-select__selected-item),
|
||||
.trade-operation-distribution-order :deep(.el-select__placeholder) { color: #303133; }
|
||||
.order-list { margin-top: 20px; }
|
||||
.pagination-container { margin-top: 16px; display: flex; justify-content: flex-end; }
|
||||
.order-detail { padding: 20px 0; }
|
||||
.detail-section { margin-top: 30px; }
|
||||
.detail-section h3 { font-size: 14px; font-weight: bold; margin-bottom: 15px; color: #606266; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user