diff --git a/excel-handle/src/main/java/com/ruoyi/excel/wecom/domain/CorpDepartment.java b/excel-handle/src/main/java/com/ruoyi/excel/wecom/domain/CorpDepartment.java
index 6977f19..979191a 100644
--- a/excel-handle/src/main/java/com/ruoyi/excel/wecom/domain/CorpDepartment.java
+++ b/excel-handle/src/main/java/com/ruoyi/excel/wecom/domain/CorpDepartment.java
@@ -23,8 +23,6 @@ public class CorpDepartment implements Serializable {
private Long orderNo;
- private String unitId;
-
private String name;
private Date createTime;
diff --git a/ruoyi-ui/src/views/wecom/customerStatisticsV2/index.vue b/ruoyi-ui/src/views/wecom/customerStatisticsV2/index.vue
index 63ba535..5d23e47 100644
--- a/ruoyi-ui/src/views/wecom/customerStatisticsV2/index.vue
+++ b/ruoyi-ui/src/views/wecom/customerStatisticsV2/index.vue
@@ -185,6 +185,8 @@
row-key="id"
border
style="width: 100%"
+ show-summary
+ :summary-method="getSummaries"
>
@@ -238,6 +240,7 @@
@keyup.enter.native="handleInputCost(scope.row, scope.row[col.prop], col.costType || 'total')"
/>
+ {{ formatPercent(scope.row[col.prop]) }}
{{ scope.row[col.prop] }}
@@ -311,14 +314,14 @@ export default {
columns: [
{ prop: 'orderCount', label: '成单数', width: 80 },
{ prop: 'customerCount', label: '进粉数', width: 80 },
- { prop: 'conversionRate', label: '转化率', width: 80 }
+ { prop: 'conversionRate', label: '转化率', width: 80, isPercent: true }
]
},
{
label: '及时单指标',
columns: [
- { prop: 'timelyRate', label: '及时单占比', width: 100 },
- { prop: 'nonTimelyRate', label: '非及时单占比', width: 110 }
+ { prop: 'timelyRate', label: '及时单占比', width: 100, isPercent: true },
+ { prop: 'nonTimelyRate', label: '非及时单占比', width: 110, isPercent: true }
]
},
{
@@ -353,10 +356,10 @@ export default {
{
label: '出单率',
columns: [
- { prop: 'parentOrderRate', label: '家长出单率', width: 100 },
- { prop: 'studentOrderRate', label: '学生出单率', width: 100 },
- { prop: 'teacherOrderRate', label: '老师出单率', width: 100 },
- { prop: 'unknownOrderRate', label: '未知出单率', width: 100 }
+ { prop: 'parentOrderRate', label: '家长出单率', width: 100, isPercent: true },
+ { prop: 'studentOrderRate', label: '学生出单率', width: 100, isPercent: true },
+ { prop: 'teacherOrderRate', label: '老师出单率', width: 100, isPercent: true },
+ { prop: 'unknownOrderRate', label: '未知出单率', width: 100, isPercent: true }
]
}
]
@@ -375,6 +378,33 @@ export default {
treeFilterData() {
// 直接使用/tree接口返回的数据
return this.treeData
+ },
+ // 计算合计行数据
+ summaryData() {
+ if (!this.dataList || this.dataList.length === 0) {
+ return []
+ }
+ const summary = {
+ groupName: '合计',
+ tagName: '',
+ curDate: ''
+ }
+ // 只计算非百分比列的合计
+ this.allColumns.forEach(col => {
+ if (!col.isPercent) {
+ let sum = 0
+ let hasValue = false
+ this.dataList.forEach(row => {
+ const val = parseFloat(row[col.prop])
+ if (!isNaN(val)) {
+ sum += val
+ hasValue = true
+ }
+ })
+ summary[col.prop] = hasValue ? sum.toFixed(2) : '-'
+ }
+ })
+ return [summary]
}
},
created() {
@@ -431,6 +461,56 @@ export default {
}
},
methods: {
+ // 合计行计算方法
+ getSummaries(param) {
+ const { columns, data } = param
+ const sums = []
+ columns.forEach((column, index) => {
+ if (index === 0) {
+ sums[index] = '合计'
+ return
+ }
+ if (index === 1 || index === 2) {
+ sums[index] = ''
+ return
+ }
+
+ // 检查是否是百分比列
+ const col = this.allColumns.find(c => c.prop === column.property)
+ if (col && col.isPercent) {
+ sums[index] = ''
+ return
+ }
+
+ // 计算非百分比列的合计
+ const values = data.map(item => Number(item[column.property]))
+ if (!values.every(value => isNaN(value))) {
+ const sum = values.reduce((prev, curr) => {
+ const value = Number(curr)
+ if (!isNaN(value)) {
+ return prev + value
+ } else {
+ return prev
+ }
+ }, 0)
+ sums[index] = sum.toFixed(2)
+ } else {
+ sums[index] = ''
+ }
+ })
+ return sums
+ },
+ // 格式化百分比显示
+ formatPercent(value) {
+ if (value === null || value === undefined || value === '') {
+ return '-'
+ }
+ const num = parseFloat(value)
+ if (isNaN(num)) {
+ return '-'
+ }
+ return num.toFixed(2) + '%'
+ },
// 更新周日期范围显示(修复跨年周问题)
updateWeekDateRange() {
if (this.queryParams.year && this.queryParams.week) {
@@ -904,4 +984,34 @@ export default {
margin-bottom: 8px;
width: 120px;
}
+
+/* 合计表格样式 */
+.summary-table {
+ margin-bottom: 0;
+}
+
+.summary-table.el-table {
+ background-color: #f5f7fa;
+}
+
+.summary-table.el-table td.el-table__cell {
+ background-color: #f5f7fa;
+ font-weight: bold;
+ color: #606266;
+}
+
+.summary-table.el-table--border {
+ border-bottom: none;
+}
+
+/* 隐藏合计表格的滚动条 */
+.summary-table .el-table__body-wrapper {
+ overflow-x: auto;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE 10+ */
+}
+
+.summary-table .el-table__body-wrapper::-webkit-scrollbar {
+ display: none; /* Chrome, Safari, Opera */
+}
diff --git a/ruoyi-ui/src/views/wecom/departmentStatistics/index.vue b/ruoyi-ui/src/views/wecom/departmentStatistics/index.vue
index 8483012..52eaed2 100644
--- a/ruoyi-ui/src/views/wecom/departmentStatistics/index.vue
+++ b/ruoyi-ui/src/views/wecom/departmentStatistics/index.vue
@@ -146,7 +146,7 @@
-
+
@@ -156,11 +156,31 @@
-
-
-
-
-
+
+
+ {{ formatPercent(scope.row.dailyConversionRate) }}
+
+
+
+
+ {{ formatPercent(scope.row.dailyTimelyOrderRatio) }}
+
+
+
+
+ {{ formatPercent(scope.row.dailyNonTimelyOrderRatio) }}
+
+
+
+
+ {{ formatPercent(scope.row.dailyParentOrderRate) }}
+
+
+
+
+ {{ formatPercent(scope.row.dailyStudentOrderRate) }}
+
+
{
+ if (index === 0) {
+ sums[index] = '合计'
+ return
+ }
+
+ // 检查是否是需要合计的列
+ if (sumColumns.includes(column.property)) {
+ const values = data.map(item => Number(item[column.property]))
+ if (!values.every(value => isNaN(value))) {
+ const sum = values.reduce((prev, curr) => {
+ const value = Number(curr)
+ if (!isNaN(value)) {
+ return prev + value
+ } else {
+ return prev
+ }
+ }, 0)
+ sums[index] = sum
+ } else {
+ sums[index] = ''
+ }
+ } else {
+ // 百分比列和其他列不显示合计
+ sums[index] = ''
+ }
+ })
+ return sums
+ },
+ // 格式化百分比显示
+ formatPercent(value) {
+ if (value === null || value === undefined || value === '') {
+ return '-'
+ }
+ const num = parseFloat(value)
+ if (isNaN(num)) {
+ return '-'
+ }
+ return num.toFixed(2) + '%'
+ },
// 获取部门树数据
getDepartmentTreeData() {
getDepartmentTree().then(response => {