|
|
@@ -0,0 +1,260 @@
|
|
|
+<!-- src/components/OrderSummaryTable.vue -->
|
|
|
+<template>
|
|
|
+ <div class="table-container">
|
|
|
+ <h3 class="table-title">{{ title }}</h3>
|
|
|
+ <el-table
|
|
|
+ :data="processedTableData"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ style="width: 100%; margin-top: 20px;"
|
|
|
+ :span-method="objectSpanMethod"
|
|
|
+ show-summary
|
|
|
+
|
|
|
+ height="500"
|
|
|
+ >
|
|
|
+ <el-table-column prop="name" :label="nameLable" min-width="70" class-name="sticky-column" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span :class="{'group-name': scope.row.isGroup}">{{ scope.row.name }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="totalCalls" label="总单数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="totalAmount" label="总金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.totalAmount ? scope.row.totalAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="validAmount" label="成单金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.validAmount ? scope.row.validAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="waitingOrders" label="待审数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="waitingAmount" label="待审金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.waitingAmount ? scope.row.waitingAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="unPassedOrders" label="未过数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="unPassedAmount" label="未过金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.unpassedAmount ? scope.row.unpassedAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="cancelOrders" label="取消数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="cancelAmount" label="取消金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.cancelAmount ? scope.row.cancelAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="completeOrders" label="成交数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="completeAmount" label="成交金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.completeAmount ? scope.row.completeAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="unshippedOrders" label="成交未发货数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="unshippedAmount" label="成交未发货金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.unshippedAmount ? scope.row.unshippedAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="shippedOrders" label="发货数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="shippedAmount" label="发货金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.shippedAmount ? scope.row.shippedAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="transitOrders" label="在途数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="transitAmount" label="在途金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.transitAmount ? scope.row.transitAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="receivedOrders" label="签收数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="receivedAmount" label="签收金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.receivedAmount ? scope.row.receivedAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="returnOrders" label="退货数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="returnAmount" label="退货金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.returnAmount ? scope.row.returnAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="paybackOrders" label="回款数" min-width="40" align="center"></el-table-column>
|
|
|
+ <el-table-column prop="paybackAmount" label="回款金额" min-width="70" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.paybackAmount ? scope.row.paybackAmount.toFixed(2) : '0.00' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: 'OrderSummaryTableNew',
|
|
|
+ props: {
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ tableData: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ nameLable: {
|
|
|
+ type: String,
|
|
|
+ default: '姓名/工号'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ tableKey: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 添加处理后的数据计算属性
|
|
|
+ processedTableData() {
|
|
|
+ if (!this.tableData || this.tableData.length === 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按部门分组数据处理逻辑
|
|
|
+ const result = [];
|
|
|
+ const deptMap = new Map();
|
|
|
+
|
|
|
+ // 分组数据
|
|
|
+ this.tableData.forEach(item => {
|
|
|
+ const deptName = item.groupName || '未分配部门';
|
|
|
+ if (!deptMap.has(deptName)) {
|
|
|
+ deptMap.set(deptName, []);
|
|
|
+ }
|
|
|
+ deptMap.get(deptName).push(item);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 构建展示数据
|
|
|
+ for (const [deptName, employees] of deptMap) {
|
|
|
+ // 部门标题行
|
|
|
+ result.push({
|
|
|
+ name: deptName,
|
|
|
+ isGroup: true,
|
|
|
+ isDeptTitle: true
|
|
|
+ });
|
|
|
+
|
|
|
+ // 员工数据行
|
|
|
+ employees.forEach(emp => {
|
|
|
+ result.push({ ...emp });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 部门小计行
|
|
|
+ const deptSummary = this.calculateDeptSummary(employees, deptName);
|
|
|
+ result.push(deptSummary);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加总计行
|
|
|
+ const totalSummary = this.calculateTotalSummary();
|
|
|
+ result.push(totalSummary);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 添加表格合并方法
|
|
|
+ objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ // 部门标题行合并
|
|
|
+ if (row.isDeptTitle) {
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ // 第一列显示部门名称,合并所有列
|
|
|
+ const totalColumns = 24;
|
|
|
+ return [1, totalColumns];
|
|
|
+ } else {
|
|
|
+ // 其他列不显示
|
|
|
+ return [0, 0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 部门小计行合并
|
|
|
+ if (row.isDeptSummary) {
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ // 第一列显示小计文本
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+ // 其他列正常显示数据
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 总计行合并
|
|
|
+ if (row.isTotalSummary) {
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ // 第一列显示总计文本
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+ // 其他列正常显示数据
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 普通行
|
|
|
+ return [1, 1];
|
|
|
+ },
|
|
|
+ // 计算部门小计
|
|
|
+ calculateDeptSummary(employees, deptName) {
|
|
|
+ const summary = {
|
|
|
+ name: `${deptName} 小计`,
|
|
|
+ isGroup: true,
|
|
|
+ isDeptSummary: true
|
|
|
+ };
|
|
|
+
|
|
|
+ const sumFields = ['totalCalls', 'totalAmount', 'validAmount', 'waitingOrders', 'waitingAmount',
|
|
|
+ 'unPassedOrders', 'unPassedAmount', 'cancelOrders', 'cancelAmount', 'completeOrders',
|
|
|
+ 'completeAmount', 'unshippedOrders', 'unshippedAmount', 'shippedOrders', 'shippedAmount',
|
|
|
+ 'transitOrders', 'transitAmount', 'receivedOrders', 'receivedAmount', 'returnOrders',
|
|
|
+ 'returnAmount', 'paybackOrders', 'paybackAmount'];
|
|
|
+
|
|
|
+ sumFields.forEach(field => {
|
|
|
+ summary[field] = employees.reduce((sum, emp) => sum + (Number(emp[field]) || 0), 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ return summary;
|
|
|
+ },
|
|
|
+ // 计算总计
|
|
|
+ calculateTotalSummary() {
|
|
|
+ const summary = {
|
|
|
+ name: '总计',
|
|
|
+ isGroup: true,
|
|
|
+ isTotalSummary: true
|
|
|
+ };
|
|
|
+
|
|
|
+ const sumFields = ['totalCalls', 'totalAmount', 'validAmount', 'waitingOrders', 'waitingAmount',
|
|
|
+ 'unPassedOrders', 'unPassedAmount', 'cancelOrders', 'cancelAmount', 'completeOrders',
|
|
|
+ 'completeAmount', 'unshippedOrders', 'unshippedAmount', 'shippedOrders', 'shippedAmount',
|
|
|
+ 'transitOrders', 'transitAmount', 'receivedOrders', 'receivedAmount', 'returnOrders',
|
|
|
+ 'returnAmount', 'paybackOrders', 'paybackAmount'];
|
|
|
+
|
|
|
+ // 从原始数据计算总计(排除部门标题和小计行)
|
|
|
+ const validData = this.tableData.filter(item => !item.isGroup);
|
|
|
+
|
|
|
+ sumFields.forEach(field => {
|
|
|
+ summary[field] = validData.reduce((sum, item) => sum + (Number(item[field]) || 0), 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ return summary;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+/* .table-container {
|
|
|
+ margin-top: 30px;
|
|
|
+} */
|
|
|
+
|
|
|
+.table-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+</style>
|