From 6cf6829334a669169a75e1922e455fb3d18563d3 Mon Sep 17 00:00:00 2001 From: chenpanliang <3245129380@qq.com> Date: Tue, 25 Nov 2025 16:11:07 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat(=E5=9B=A2=E9=98=9F=E5=88=86=E6=9E=90):?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E5=9B=A2=E9=98=9F=E5=92=8C=E9=83=A8?= =?UTF-8?q?=E9=97=A8=E5=88=86=E6=9E=90=E5=8A=9F=E8=83=BD=E5=8F=8A=E5=BC=B9?= =?UTF-8?q?=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在api中添加获取团队各组分析报告的接口 - 在secondTop和seniorManager视图中添加团队分析弹窗组件 - 实现部门分析弹窗功能 - 添加样式和交互逻辑处理团队分析数据展示 --- my-vue-app/src/api/senorManger.js | 5 + my-vue-app/src/views/secondTop/secondTop.vue | 97 +++++- .../src/views/senorManger/seniorManager.vue | 317 +++++++++++++++++- 3 files changed, 406 insertions(+), 13 deletions(-) diff --git a/my-vue-app/src/api/senorManger.js b/my-vue-app/src/api/senorManger.js index 492bae9..078d545 100644 --- a/my-vue-app/src/api/senorManger.js +++ b/my-vue-app/src/api/senorManger.js @@ -84,4 +84,9 @@ export const getExcellentRecordFile = (params) => { return https.post('/api/v1/level_three/overview/get_current_center_excellent_record_file', params) } +// 团队下各组分析报告 /api/v1/level_three/overview/team_every_group_report +export const getTeamEveryGroupReport = (params) => { + return https.post('/api/v1/level_three/overview/team_every_group_report', params) +} + diff --git a/my-vue-app/src/views/secondTop/secondTop.vue b/my-vue-app/src/views/secondTop/secondTop.vue index fe854ea..8c6162f 100644 --- a/my-vue-app/src/views/secondTop/secondTop.vue +++ b/my-vue-app/src/views/secondTop/secondTop.vue @@ -113,7 +113,20 @@
- + +
+ + + +
+
@@ -286,6 +299,9 @@ const cardVisibility = ref({ // FeedbackForm 控制变量 const showFeedbackForm = ref(false) +// 团队整体分析弹窗控制变量 +const showTeamAnalysis = ref(false) + // 更新卡片显示状态 const updateCardVisibility = (newVisibility) => { Object.assign(cardVisibility.value, newVisibility) @@ -300,6 +316,15 @@ const showFeedbackFormModal = () => { const closeFeedbackFormModal = () => { showFeedbackForm.value = false } + +// 团队整体分析弹窗控制方法 +const showTeamAnalysisModal = () => { + showTeamAnalysis.value = true +} + +const closeTeamAnalysisModal = () => { + showTeamAnalysis.value = false +} // 营期调控逻辑 // This would ideally come from a prop or API call based on the logged-in user const centerData = ref({ @@ -1638,7 +1663,77 @@ const hideTooltip = () => { } } } + + /* 团队分析弹窗样式 */ + .team-analysis-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + } + .team-analysis-modal .modal-content { + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + width: 80%; + max-width: 600px; + max-height: 80vh; + overflow: hidden; + display: flex; + flex-direction: column; + } + + .team-analysis-modal .modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + border-bottom: 1px solid #e2e8f0; + } + + .team-analysis-modal .modal-header h3 { + margin: 0; + color: #1a202c; + font-size: 1.25rem; + } + + .team-analysis-modal .close-btn { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #718096; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + } + + .team-analysis-modal .close-btn:hover { + color: #1a202c; + } + + .team-analysis-modal .modal-body { + padding: 1rem; + overflow-y: auto; + flex: 1; + } + + .team-analysis-modal .modal-body p { + margin: 0; + color: #4a5568; + line-height: 1.5; + } + // 路由导航顶栏样式 .route-header { display: flex; diff --git a/my-vue-app/src/views/senorManger/seniorManager.vue b/my-vue-app/src/views/senorManger/seniorManager.vue index aecaecb..ffd3ce8 100644 --- a/my-vue-app/src/views/senorManger/seniorManager.vue +++ b/my-vue-app/src/views/senorManger/seniorManager.vue @@ -28,17 +28,31 @@
+ - - -
+ + +
+ +
+ +
@@ -131,10 +145,34 @@
- +
+ +
+ +
+
{ @@ -371,6 +415,60 @@ const closeFeedbackFormModal = () => { showFeedbackForm.value = false } +// 部门分析弹窗控制方法 +const showDepartmentAnalysisModal = () => { + showDepartmentAnalysis.value = true +} + +const closeDepartmentAnalysisModal = () => { + showDepartmentAnalysis.value = false +} + +// 团队分析弹窗控制方法 +const showTeamAnalysisModal = async () => { + showTeamAnalysis.value = true + // 获取团队分析数据 + try { + const params = { + department_name: selectedGroup.value.name + '-' + selectedGroup.value.leader + } + const response = await getTeamEveryGroupReport(params) + // 根据API响应结构调整数据处理逻辑 + if (response.data) { + if (Array.isArray(response.data)) { + // 如果response.data本身就是数组 + teamAnalysisData.value = response.data + } else if (response.data.data && Array.isArray(response.data.data)) { + // 如果response.data.data是数组 + teamAnalysisData.value = response.data.data + } else { + // 其他情况,可能是单个对象 + teamAnalysisData.value = [response.data] + } + } + } catch (error) { + console.error('获取团队分析数据失败:', error) + } +} + +const closeTeamAnalysisModal = () => { + showTeamAnalysis.value = false +} + +// 格式化报告内容 +const formatReportContent = (content) => { + if (!content) return '' + // 将Markdown格式的标题转换为HTML标签 + return content + .replace(/### (.*?)(?=\n|$)/g, '

$1

') + .replace(/## (.*?)(?=\n|$)/g, '

$1

') + .replace(/# (.*?)(?=\n|$)/g, '

$1

') + .replace(/\*\*(.*?)\*\*/g, '$1') + .replace(/\*(.*?)\*/g, '$1') + .replace(/\n\n/g, '

') + .replace(/\n/g, '
') +} + // 卡片显示状态 const cardVisibility = ref({ centerOverview: true, @@ -1618,4 +1716,199 @@ const hideTooltip = () => { .feedback-btn:hover { background-color: #3182ce; } + +/* 部门分析弹窗样式 */ +.department-analysis-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + width: 80%; + 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: 1rem; + border-bottom: 1px solid #e2e8f0; +} + +.modal-header h3 { + margin: 0; + color: #1a202c; + font-size: 1.25rem; +} + +.close-btn { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #718096; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.close-btn:hover { + color: #1a202c; +} + +.modal-body { + padding: 1rem; + overflow-y: auto; + flex: 1; +} + +.modal-body p { + margin: 0; + color: #4a5568; + line-height: 1.5; +} + +/* 团队分析弹窗样式 */ +.team-analysis-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.team-analysis-modal .modal-content { + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + width: 80%; + max-width: 600px; + max-height: 80vh; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.team-analysis-modal .modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + border-bottom: 1px solid #e2e8f0; +} + +.team-analysis-modal .modal-header h3 { + margin: 0; + color: #1a202c; + font-size: 1.25rem; +} + +.team-analysis-modal .close-btn { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #718096; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.team-analysis-modal .close-btn:hover { + color: #1a202c; +} + +.team-analysis-modal .modal-body { + padding: 1rem; + overflow-y: auto; + flex: 1; +} + +.team-analysis-modal .modal-body p { + margin: 0; + color: #4a5568; + line-height: 1.5; +} + +.team-analysis-modal .report-item { + margin-bottom: 20px; + padding: 15px; + border: 1px solid #e2e8f0; + border-radius: 5px; + background-color: #f8fafc; +} + +.team-analysis-modal .report-item h4 { + margin-top: 0; + color: #1a202c; + border-bottom: 1px solid #e2e8f0; + padding-bottom: 5px; +} + +.team-analysis-modal .report-content { + margin-top: 10px; + color: #4a5568; + line-height: 1.6; +} + +.team-analysis-modal .report-content h1, +.team-analysis-modal .report-content h2, +.team-analysis-modal .report-content h3 { + margin-top: 15px; + margin-bottom: 10px; + color: #1a202c; +} + +.team-analysis-modal .report-content h1 { + font-size: 1.5rem; +} + +.team-analysis-modal .report-content h2 { + font-size: 1.3rem; +} + +.team-analysis-modal .report-content h3 { + font-size: 1.1rem; +} + +.team-analysis-modal .report-content strong { + font-weight: bold; +} + +.team-analysis-modal .report-content em { + font-style: italic; +} + +.team-analysis-modal .no-report { + text-align: center; + color: #718096; + font-style: italic; +} \ No newline at end of file From 2ba88eff08dd4cf38536cea946e359c641786a2b Mon Sep 17 00:00:00 2001 From: chenpanliang <3245129380@qq.com> Date: Tue, 25 Nov 2025 16:59:43 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat(=E9=83=A8=E9=97=A8=E5=88=86=E6=9E=90):?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E9=83=A8=E9=97=A8=E6=95=B4=E4=BD=93?= =?UTF-8?q?=E5=88=86=E6=9E=90=E6=8A=A5=E5=91=8A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现部门分析弹窗的数据获取与展示功能,新增getTeamEntiretyReport API接口 调整多个组件高度以优化布局 --- my-vue-app/src/api/senorManger.js | 5 ++ .../views/secondTop/components/GoodMusic.vue | 2 +- .../senorManger/components/GoodMusic.vue | 4 +- .../src/views/senorManger/seniorManager.vue | 53 +++++++++++++++++-- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/my-vue-app/src/api/senorManger.js b/my-vue-app/src/api/senorManger.js index 078d545..538ad30 100644 --- a/my-vue-app/src/api/senorManger.js +++ b/my-vue-app/src/api/senorManger.js @@ -89,4 +89,9 @@ export const getTeamEveryGroupReport = (params) => { return https.post('/api/v1/level_three/overview/team_every_group_report', params) } +// 部门整体分析报告 /api/v1/level_three/overview/team_entirety_report +export const getTeamEntiretyReport = (params) => { + return https.post('/api/v1/level_three/overview/team_entirety_report', params) +} + diff --git a/my-vue-app/src/views/secondTop/components/GoodMusic.vue b/my-vue-app/src/views/secondTop/components/GoodMusic.vue index b744fa4..73425fd 100644 --- a/my-vue-app/src/views/secondTop/components/GoodMusic.vue +++ b/my-vue-app/src/views/secondTop/components/GoodMusic.vue @@ -504,7 +504,7 @@ const downloadRecording = (index) => { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - height: 400px; + height: 420px; } .chart-header { diff --git a/my-vue-app/src/views/senorManger/components/GoodMusic.vue b/my-vue-app/src/views/senorManger/components/GoodMusic.vue index b744fa4..3663473 100644 --- a/my-vue-app/src/views/senorManger/components/GoodMusic.vue +++ b/my-vue-app/src/views/senorManger/components/GoodMusic.vue @@ -504,7 +504,7 @@ const downloadRecording = (index) => { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - height: 400px; + height: 416px; } .chart-header { @@ -554,7 +554,7 @@ const downloadRecording = (index) => { .recording-section { width: 100%; min-height: 200px; - max-height: 300px; + max-height: 330px; overflow-y: auto; } diff --git a/my-vue-app/src/views/senorManger/seniorManager.vue b/my-vue-app/src/views/senorManger/seniorManager.vue index ffd3ce8..80d2837 100644 --- a/my-vue-app/src/views/senorManger/seniorManager.vue +++ b/my-vue-app/src/views/senorManger/seniorManager.vue @@ -43,8 +43,18 @@

@@ -257,7 +267,8 @@ import PerformanceComparison from './components/PerformanceComparison.vue'; // 1 import { getOverallTeamPerformance,getTotalGroupCount,getConversionRate,getTotalCallCount, getNewCustomer,getDepositConversionRate,getActiveCustomerCommunicationRate,getAverageAnswerTime, getTimeoutRate,getTableFillingRate,getUrgentNeedToAddress,getTeamRanking,getTeamRankingInfo, - getAbnormalResponseRate,getTeamSalesFunnel,getExcellentRecordFile,getTeamEveryGroupReport } from '@/api/senorManger.js' + getAbnormalResponseRate,getTeamSalesFunnel,getExcellentRecordFile,getTeamEveryGroupReport, + getTeamEntiretyReport } from '@/api/senorManger.js' import { useUserStore } from '@/stores/user.js' import FeedbackForm from "@/components/FeedbackForm.vue"; @@ -395,6 +406,8 @@ const showDepartmentAnalysis = ref(false) const showTeamAnalysis = ref(false) // 团队分析数据 const teamAnalysisData = ref([]) +// 部门分析数据 +const departmentAnalysisData = ref([]) // 更新CheckType的方法 const updateCheckType = async (newValue) => { @@ -416,8 +429,37 @@ const closeFeedbackFormModal = () => { } // 部门分析弹窗控制方法 -const showDepartmentAnalysisModal = () => { +const showDepartmentAnalysisModal = async () => { showDepartmentAnalysis.value = true + // 获取部门分析数据 + try { + // 获取当前登录的高级经理信息 + const currentUser = userStore.userInfo; + const params = { + user_name: currentUser.username, + user_level: currentUser.user_level.toString(), + part_count: 1 // 默认获取最近1份报告 + } + + const response = await getTeamEntiretyReport(params) + + // 根据API响应结构调整数据处理逻辑 + if (response.data) { + if (Array.isArray(response.data)) { + // 如果response.data本身就是数组 + departmentAnalysisData.value = response.data + } else if (response.data.data && Array.isArray(response.data.data)) { + // 如果response.data.data是数组 + departmentAnalysisData.value = response.data.data + } else { + // 其他情况,可能是单个对象 + departmentAnalysisData.value = [response.data] + } + } + } catch (error) { + console.error('获取部门分析数据失败:', error) + departmentAnalysisData.value = [] + } } const closeDepartmentAnalysisModal = () => { @@ -430,7 +472,8 @@ const showTeamAnalysisModal = async () => { // 获取团队分析数据 try { const params = { - department_name: selectedGroup.value.name + '-' + selectedGroup.value.leader + department_name: selectedGroup.value.name + '-' + selectedGroup.value.leader, + part_count: 1 // 默认获取最近1份报告 } const response = await getTeamEveryGroupReport(params) // 根据API响应结构调整数据处理逻辑 From b48b7749f20c4c482c01aa6b6037d695bc492c0a Mon Sep 17 00:00:00 2001 From: chenpanliang <3245129380@qq.com> Date: Tue, 25 Nov 2025 17:53:54 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(=E5=9B=A2=E9=98=9F=E5=88=86=E6=9E=90):?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E5=9B=A2=E9=98=9F=E6=95=B4=E4=BD=93?= =?UTF-8?q?=E4=B8=89=E9=98=B6=E5=88=86=E6=9E=90=E6=8A=A5=E5=91=8A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在api/manager.js中添加获取团队分析报告的接口 - 在TeamReport组件中添加分析按钮并触发事件 - 在manager.vue中实现团队分析弹窗及相关逻辑 - 添加样式美化分析报告展示 --- my-vue-app/src/api/manager.js | 5 + .../views/maneger/components/TeamReport.vue | 37 +- my-vue-app/src/views/maneger/manager.vue | 369 +++++++++++++++++- 3 files changed, 405 insertions(+), 6 deletions(-) diff --git a/my-vue-app/src/api/manager.js b/my-vue-app/src/api/manager.js index d4da093..3d2139f 100644 --- a/my-vue-app/src/api/manager.js +++ b/my-vue-app/src/api/manager.js @@ -54,3 +54,8 @@ export const getMemberCallClassify = (params) => { return https.post('/api/v1/manager/get_member_call_classify', params) } +// 团队整体三阶分析报告 /api/v1/manager/group_entirety_third_report +export const getGroupEntiretyThirdReport = (params) => { + return https.post('/api/v1/manager/group_entirety_third_report', params) +} + diff --git a/my-vue-app/src/views/maneger/components/TeamReport.vue b/my-vue-app/src/views/maneger/components/TeamReport.vue index 467af42..8def8c7 100644 --- a/my-vue-app/src/views/maneger/components/TeamReport.vue +++ b/my-vue-app/src/views/maneger/components/TeamReport.vue @@ -1,6 +1,9 @@