From d661b77afaf26afb879833460488d11dba003e03 Mon Sep 17 00:00:00 2001
From: lbw_9527443 <780139497@qq.com>
Date: Thu, 9 Oct 2025 21:21:44 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E9=94=80=E5=94=AE=E5=88=86=E6=9E=90):=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=8C=E9=98=B6=E5=88=86=E6=9E=90=E6=8A=A5?=
=?UTF-8?q?=E5=91=8A=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在api.js和manager.js中添加获取二阶分析报告的API接口
- 在个人仪表板中添加阶段分析报告按钮和模态框
- 移除不再使用的周分析组件
- 添加分析报告数据结构和样式
---
my-vue-app/src/api/api.js | 5 +
my-vue-app/src/api/manager.js | 5 +-
.../person/components/PersonalDashboard.vue | 330 ++++++++++++++++--
my-vue-app/src/views/person/sale.vue | 7 -
4 files changed, 309 insertions(+), 38 deletions(-)
diff --git a/my-vue-app/src/api/api.js b/my-vue-app/src/api/api.js
index c8a7dc3..ada2a25 100644
--- a/my-vue-app/src/api/api.js
+++ b/my-vue-app/src/api/api.js
@@ -81,3 +81,8 @@ export const getAvgCallTime = (params) => {
export const getCallSuccessRate = (params) => {
return https.post('/api/v1/sales/get_call_success_rate', params)
}
+
+// 二阶分析报告
+export const getSecondOrderAnalysisReport = (params) => {
+ return https.post('/api/v1/sales/get_call_text', params)
+}
\ No newline at end of file
diff --git a/my-vue-app/src/api/manager.js b/my-vue-app/src/api/manager.js
index 1b7acbd..0728b45 100644
--- a/my-vue-app/src/api/manager.js
+++ b/my-vue-app/src/api/manager.js
@@ -44,6 +44,9 @@ export const getGroupDetail = (params) => {
export const getGroupCallDuration = (params) => {
return https.post('/api/v1/manager/group_call_duration', params)
}
-
+// 二二阶分析报告 /api/v1/sales/get_call_text
+export const getSecondOrderAnalysisReport = (params) => {
+ return https.post('/api/v1/manager/group_call_text', params)
+}
diff --git a/my-vue-app/src/views/person/components/PersonalDashboard.vue b/my-vue-app/src/views/person/components/PersonalDashboard.vue
index c7f69fc..42e2ffc 100644
--- a/my-vue-app/src/views/person/components/PersonalDashboard.vue
+++ b/my-vue-app/src/views/person/components/PersonalDashboard.vue
@@ -1,8 +1,9 @@
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
当日分析报告
+
这里是当日分析报告的占位文本。
+
+
+
当期分析报告
+
这里是当期分析报告的占位文本。
+
+
+
当月分析报告
+
这里是当月分析报告的占位文本。
+
+
+
+
+
+
@@ -159,6 +191,112 @@ const props = defineProps({
}
});
+// 分析报告数据
+const analysisData = ref({
+ today: {
+ overallScore: 82,
+ targetCompletion: 72,
+ keyMetrics: [
+ {
+ name: '通话量',
+ current: 42,
+ target: 50,
+ trend: 'positive',
+ trendText: '↗ +5%'
+ },
+ {
+ name: '接通率',
+ current: 75,
+ target: 80,
+ trend: 'neutral',
+ trendText: '→ 持平'
+ },
+ {
+ name: '转化率',
+ current: 15,
+ target: 15,
+ trend: 'positive',
+ trendText: '↗ +2%'
+ },
+ {
+ name: '客户满意度',
+ current: 4.5,
+ target: 4.5,
+ trend: 'positive',
+ trendText: '↗ +0.3'
+ }
+ ]
+ },
+ current: {
+ overallScore: 78,
+ targetCompletion: 65,
+ keyMetrics: [
+ {
+ name: '通话量',
+ current: 185,
+ target: 200,
+ trend: 'neutral',
+ trendText: '→ -2%'
+ },
+ {
+ name: '接通率',
+ current: 68,
+ target: 80,
+ trend: 'negative',
+ trendText: '↘ -5%'
+ },
+ {
+ name: '转化率',
+ current: 12,
+ target: 15,
+ trend: 'negative',
+ trendText: '↘ -3%'
+ },
+ {
+ name: '客户满意度',
+ current: 4.2,
+ target: 4.5,
+ trend: 'neutral',
+ trendText: '→ -0.1'
+ }
+ ]
+ },
+ month: {
+ overallScore: 85,
+ targetCompletion: 78,
+ keyMetrics: [
+ {
+ name: '通话量',
+ current: 520,
+ target: 600,
+ trend: 'positive',
+ trendText: '↗ +8%'
+ },
+ {
+ name: '接通率',
+ current: 72,
+ target: 80,
+ trend: 'neutral',
+ trendText: '→ -1%'
+ },
+ {
+ name: '转化率',
+ current: 14,
+ target: 15,
+ trend: 'neutral',
+ trendText: '→ -0.5%'
+ },
+ {
+ name: '客户满意度',
+ current: 4.3,
+ target: 4.5,
+ trend: 'positive',
+ trendText: '↗ +0.1'
+ }
+ ]
+ }
+});
+
// Chart.js 实例
const chartInstances = {};
@@ -177,6 +315,10 @@ const tooltip = reactive({
// 指标说明配置
const kpiDescriptions = {
+ totalCalls: {
+ title: '今日通话',
+ description: '今日总共通话的次数。'
+ },
successRate: {
title: '电话接通率',
description: '拨通电话 ÷ 拨打的电话'
@@ -189,6 +331,10 @@ const kpiDescriptions = {
title: '成交转化率',
description: '成交人数 ÷ 本期总数据。'
},
+ assignedData: {
+ title: '本期分配数据',
+ description: '本期内分配到的数据总量。'
+ },
wechatAddRate: {
title: '加微率',
description: '加微人数 ÷ 本期数据总人数'
@@ -306,6 +452,25 @@ const hideTooltip = () => {
tooltip.visible = false;
};
+// 阶段分析报告模态框状态
+const showAnalysisModal = ref(false);
+const analysisPeriod = ref('today'); // 'today', 'current', 'month'
+
+// 显示阶段分析报告模态框
+const showSecondOrderAnalysisReport = () => {
+ showAnalysisModal.value = true;
+};
+
+// 关闭阶段分析报告模态框
+const closeAnalysisModal = () => {
+ showAnalysisModal.value = false;
+};
+
+// 切换分析周期
+const switchAnalysisPeriod = (period) => {
+ analysisPeriod.value = period;
+};
+
watch(() => props.contactTimeData, () => {
@@ -464,7 +629,7 @@ $white: #ffffff;
justify-content: center;
min-height: 120px;
padding: 1rem 0.5rem;
-
+
.stat-icon {
width: 40px;
height: 40px;
@@ -475,14 +640,14 @@ $white: #ffffff;
font-size: 18px;
color: $white;
margin-bottom: 0.75rem;
-
+
&.customer-rate { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
&.response-time { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
&.timeout-rate { background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); }
&.form-rate { background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); }
&.severe-timeout-rate { background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); }
}
-
+
.kpi-value {
margin-bottom: 0.25rem;
}
@@ -586,19 +751,19 @@ $white: #ffffff;
.personal-dashboard { padding: 15px; }
.stats-grid, .charts-section { grid-template-columns: 1fr; }
.stat-card { flex-direction: row; }
-
+
.dashboard-header {
padding: 16px;
h2 {
font-size: 20px;
}
}
-
+
.kpi-grid {
grid-template-columns: repeat(2, 1fr);
gap: 0.75rem;
}
-
+
.kpi-item {
padding: 0.5rem;
.kpi-value {
@@ -608,49 +773,49 @@ $white: #ffffff;
font-size: 0.75rem;
}
}
-
+
.stats-grid-inner {
grid-template-columns: repeat(2, 1fr);
gap: 0.5rem;
}
-
+
.stat-item {
min-height: 100px;
padding: 0.75rem 0.25rem;
-
+
.stat-icon {
width: 32px;
height: 32px;
font-size: 16px;
margin-bottom: 0.5rem;
}
-
+
.kpi-value {
font-size: 1.125rem;
}
-
+
p {
font-size: 0.75rem;
}
}
-
+
.chart-container {
min-height: 300px;
}
-
+
.chart-header {
padding: 16px 16px 12px;
h3 {
font-size: 16px;
}
}
-
+
.chart-content {
padding-left: 16px;
padding-right: 16px;
padding-bottom: 16px;
}
-
+
}
@@ -659,52 +824,52 @@ $white: #ffffff;
.personal-dashboard {
padding: 10px;
}
-
+
.dashboard-header {
padding: 12px;
h2 {
font-size: 18px;
}
}
-
+
.kpi-grid {
grid-template-columns: 1fr;
gap: 0.5rem;
}
-
+
.kpi-item {
padding: 0.75rem;
.kpi-value {
font-size: 1.5rem;
}
}
-
+
.stats-grid-inner {
grid-template-columns: 1fr;
gap: 0.75rem;
}
-
+
.stat-item {
min-height: 80px;
padding: 1rem;
flex-direction: row;
text-align: left;
-
+
.stat-icon {
margin-bottom: 0;
margin-right: 0.75rem;
}
}
-
+
.chart-container {
min-height: 250px;
}
-
+
.charts-section {
grid-template-columns: 1fr;
gap: 16px;
}
-
+
}
@@ -719,7 +884,7 @@ $white: #ffffff;
opacity: 0.7;
cursor: pointer;
transition: all 0.3s ease;
-
+
&:hover {
opacity: 1;
color: #007bff;
@@ -735,4 +900,109 @@ $white: #ffffff;
position: relative;
transition: all 0.2s ease;
}
-
\ No newline at end of file
+
+/* 模态框样式 */
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-container {
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ width: 90%;
+ max-width: 600px;
+ max-height: 80vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20px;
+ border-bottom: 1px solid #ebeef5;
+}
+
+.modal-title {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 600;
+ color: #303133;
+}
+
+.modal-close-btn {
+ background: none;
+ border: none;
+ font-size: 24px;
+ cursor: pointer;
+ color: #909399;
+ padding: 0;
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &:hover {
+ color: #303133;
+ }
+}
+
+.modal-body {
+ padding: 20px;
+ flex: 1;
+ overflow-y: auto;
+}
+
+.period-switcher {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 20px;
+}
+
+.period-switcher button {
+ flex: 1;
+ padding: 10px 15px;
+ border: 1px solid #dcdfe6;
+ background: white;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ transition: all 0.3s ease;
+
+ &:hover {
+ border-color: #409eff;
+ color: #409eff;
+ }
+
+ &.active {
+ background: #409eff;
+ border-color: #409eff;
+ color: white;
+ }
+}
+
+.analysis-content h4 {
+ margin-top: 0;
+ margin-bottom: 15px;
+ color: #303133;
+ font-size: 16px;
+}
+
+.analysis-content p {
+ color: #606266;
+ line-height: 1.6;
+}
+```
\ No newline at end of file
diff --git a/my-vue-app/src/views/person/sale.vue b/my-vue-app/src/views/person/sale.vue
index b9ac3a1..9cc6a6e 100644
--- a/my-vue-app/src/views/person/sale.vue
+++ b/my-vue-app/src/views/person/sale.vue
@@ -132,13 +132,6 @@
-
-
-