feat: 实现卡片可见性管理并优化多个组件功能
- 在UserDropdown组件中添加卡片名称映射 - 为sale.vue、seniorManager.vue、topone.vue和secondTop.vue添加卡片可见性控制 - 在CustomerDetail.vue中添加通话数据检查逻辑 - 将https.js中的API基础路径切换为生产环境
This commit is contained in:
@@ -271,11 +271,35 @@ watch(() => props.cardVisibility, (newVal) => {
|
||||
// 获取卡片显示名称
|
||||
const getCardDisplayName = (key) => {
|
||||
const nameMap = {
|
||||
// sale.vue 页面的卡片
|
||||
timeline: '销售时间线',
|
||||
rawData: '原始数据',
|
||||
customerDetail: '客户详情',
|
||||
analytics: '数据分析',
|
||||
weekAnalysis: '周期分析'
|
||||
weekAnalysis: '周期分析',
|
||||
// seniorManager.vue 页面的卡片
|
||||
centerOverview: '中心概览',
|
||||
teamAlerts: '团队预警',
|
||||
statisticalIndicators: '统计指标',
|
||||
groupRanking: '组别排名',
|
||||
problemRanking: '问题排名',
|
||||
groupComparison: '组别对比',
|
||||
teamDetail: '团队详情',
|
||||
// secondTop.vue 页面的卡片
|
||||
actionItems: '行动项目',
|
||||
customerType: '客户类型',
|
||||
goodMusic: '优秀录音',
|
||||
// topone.vue 页面的卡片
|
||||
kpiMetrics: '核心业绩指标',
|
||||
salesProgress: '销售实时进度',
|
||||
periodStage: '各中心营期阶段',
|
||||
funnelChart: '转化漏斗',
|
||||
personalSalesRanking: '销售个人业绩排行榜',
|
||||
qualityCalls: '优质通话',
|
||||
rankingList: '业绩排行榜',
|
||||
problemRanking: '客户迫切解决的问题排行榜',
|
||||
campManagement: '营期管理',
|
||||
detailedDataTable: '详细数据表格'
|
||||
}
|
||||
return nameMap[key] || key
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import { useUserStore } from '@/stores/user'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
// baseURL: 'https://mldash.nycjy.cn/' || '', // API基础路径,支持完整URL
|
||||
baseURL: 'http://192.168.15.121:8889' || '', // API基础路径,支持完整URL
|
||||
baseURL: 'https://mldash.nycjy.cn/' || '', // API基础路径,支持完整URL
|
||||
// baseURL: 'http://192.168.15.121:8889' || '', // API基础路径,支持完整URL
|
||||
timeout: 100000, // 请求超时时间
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
@@ -45,12 +45,7 @@ service.interceptors.request.use(
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
// 隐藏加载状态
|
||||
// console.log('隐藏加载中...')
|
||||
|
||||
// 对响应数据做点什么
|
||||
// console.log('收到响应:', response)
|
||||
|
||||
|
||||
const { data, status } = response
|
||||
|
||||
// HTTP状态码检查
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<button
|
||||
@click="startSopAnalysis"
|
||||
class="analysis-button sop-button"
|
||||
:disabled="isSopAnalysisLoading"
|
||||
:disabled="isSopAnalysisLoading || !hasCallData"
|
||||
>
|
||||
{{ isSopAnalysisLoading ? 'SOP分析中...' : 'SOP通话分析' }}
|
||||
{{ isSopAnalysisLoading ? 'SOP分析中...' : (hasCallData ? 'SOP通话分析' : '暂无通话数据') }}
|
||||
</button>
|
||||
<!-- <button
|
||||
@click="startDemandAnalysis"
|
||||
@@ -157,6 +157,11 @@ const formattedDemandAnalysis = computed(() => {
|
||||
return md.render(demandAnalysisResult.value);
|
||||
});
|
||||
|
||||
// 计算属性:检查是否有通话数据
|
||||
const hasCallData = computed(() => {
|
||||
return props.callRecords && props.callRecords.length > 0;
|
||||
});
|
||||
|
||||
// 监听selectedContact变化,重置所有分析结果
|
||||
watch(() => props.selectedContact, (newContact) => {
|
||||
if (newContact) {
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
<div class="user-name">
|
||||
{{ routeUserName }}
|
||||
</div>
|
||||
<UserDropdown
|
||||
:card-visibility="cardVisibility"
|
||||
@update-card-visibility="updateCardVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +62,7 @@
|
||||
</section>
|
||||
|
||||
<!-- 原始数据卡片区域 -->
|
||||
<section v-if="cardVisibility.rawData" class="raw-data-section">
|
||||
<section v-if="cardVisibility.rawData && selectedContact" class="raw-data-section">
|
||||
<div class="section-header">
|
||||
<h2>原始数据</h2>
|
||||
<p class="section-subtitle">客户互动的原始记录和数据</p>
|
||||
@@ -89,7 +85,7 @@
|
||||
<!-- 主要工作区域 -->
|
||||
<main class="main-content">
|
||||
<!-- 客户详情区域 -->
|
||||
<section v-if="cardVisibility.customerDetail" class="detail-section">
|
||||
<section v-if="cardVisibility.customerDetail && selectedContact" class="detail-section">
|
||||
<div class="section-header">
|
||||
<h2>客户详情</h2>
|
||||
</div>
|
||||
@@ -125,7 +121,7 @@
|
||||
</section>
|
||||
|
||||
<!-- 周期分析区域 -->
|
||||
<section v-if="cardVisibility.weekAnalysis" class="week-analysis-section" style="width: 100%; margin-top: 24px;">
|
||||
<section v-if="cardVisibility.weekAnalysis===false" class="week-analysis-section" style="width: 100%; margin-top: 24px;">
|
||||
<div class="section-content">
|
||||
<WeekAnalize :week-data="weekAnalysisData" />
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
|
||||
<div v-if="!isRouteNavigation">
|
||||
<!-- 用户下拉菜单 -->
|
||||
<UserDropdown />
|
||||
<UserDropdown
|
||||
:card-visibility="cardVisibility"
|
||||
@update-card-visibility="updateCardVisibility"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -39,37 +42,52 @@
|
||||
<!-- Top Section - Center Overview and Action Items -->
|
||||
<div class="top-section">
|
||||
<!-- Center Performance Overview -->
|
||||
<CenterOverview :key="CheckType" :overall-data="overallCenterPerformance" @update-check-type="updateCheckType" />
|
||||
<CenterOverview
|
||||
v-if="cardVisibility.centerOverview"
|
||||
:key="CheckType"
|
||||
:overall-data="overallCenterPerformance"
|
||||
@update-check-type="updateCheckType"
|
||||
/>
|
||||
|
||||
<!-- Action Items (Compact) -->
|
||||
<div class="action-items-compact">
|
||||
<div v-if="cardVisibility.actionItems" class="action-items-compact">
|
||||
<ActionItems :selected-group="selectedGroup" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="BB-section">
|
||||
<!--客户类型占比-->
|
||||
<CustomerType :customer-data="customerTypeDistribution" @category-change="handleCustomerTypeChange" />
|
||||
<CustomerType
|
||||
v-if="cardVisibility.customerType"
|
||||
:customer-data="customerTypeDistribution"
|
||||
@category-change="handleCustomerTypeChange"
|
||||
/>
|
||||
<!-- 优秀录音 -->
|
||||
<GoodMusic :quality-calls="excellentRecord" />
|
||||
<GoodMusic
|
||||
v-if="cardVisibility.goodMusic"
|
||||
:quality-calls="excellentRecord"
|
||||
/>
|
||||
<!-- 客户问题排行 -->
|
||||
<ProblemRanking :ranking-data="formattedUrgentNeedData" />
|
||||
<ProblemRanking
|
||||
v-if="cardVisibility.problemRanking"
|
||||
:ranking-data="formattedUrgentNeedData"
|
||||
/>
|
||||
</div>
|
||||
<!-- Bottom Section -->
|
||||
<div class="bottom-section">
|
||||
<!-- Left Section - Group Performance Ranking -->
|
||||
<div class="left-section">
|
||||
<div v-if="cardVisibility.groupRanking" class="left-section">
|
||||
<GroupRanking :groups="groups" :selected-group="selectedGroup" :conversion-data="conversionRateVsAverage" @select-group="selectGroup" />
|
||||
</div>
|
||||
|
||||
<!-- Right Section - Group Comparison -->
|
||||
<div class="right-section">
|
||||
<div v-if="cardVisibility.groupComparison" class="right-section">
|
||||
<GroupComparison :groups="groups" :senior-manager-data="seniorManagerList" :group-list="groupList" @select-group="selectGroup" @manager-change="handleManagerChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Team Members Detail Section -->
|
||||
<div class="team-detail-section" v-if="selectedGroup">
|
||||
<div class="team-detail-section" v-if="selectedGroup && cardVisibility.teamDetail">
|
||||
<div class="team-detail-header">
|
||||
<h2>{{ selectedGroup.name }} - 团队成员详情</h2>
|
||||
<div class="team-summary">
|
||||
@@ -241,6 +259,24 @@
|
||||
// 用户store实例
|
||||
const userStore = useUserStore();
|
||||
const CheckType = ref('month')
|
||||
|
||||
// 卡片显示状态
|
||||
const cardVisibility = ref({
|
||||
centerOverview: true,
|
||||
actionItems: true,
|
||||
customerType: true,
|
||||
goodMusic: true,
|
||||
problemRanking: true,
|
||||
groupRanking: true,
|
||||
groupComparison: true,
|
||||
teamDetail: true
|
||||
})
|
||||
|
||||
// 更新卡片显示状态
|
||||
const updateCardVisibility = (newVisibility) => {
|
||||
Object.assign(cardVisibility.value, newVisibility)
|
||||
console.log('卡片显示状态已更新:', cardVisibility.value)
|
||||
}
|
||||
// 营期调控逻辑
|
||||
// This would ideally come from a prop or API call based on the logged-in user
|
||||
const centerData = ref({
|
||||
|
||||
@@ -27,7 +27,12 @@
|
||||
|
||||
<div v-if="!isRouteNavigation">
|
||||
<!-- 用户下拉菜单 -->
|
||||
<UserDropdown class="header-ringht" style="margin-left: auto;" />
|
||||
<UserDropdown
|
||||
class="header-ringht"
|
||||
style="margin-left: auto;"
|
||||
:card-visibility="cardVisibility"
|
||||
@update-card-visibility="updateCardVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,15 +41,17 @@
|
||||
<main class="dashboard-main">
|
||||
<div class="top-section">
|
||||
<CenterOverview
|
||||
v-if="cardVisibility.centerOverview"
|
||||
style="height: 330px;"
|
||||
:overallTeamPerformance="overallTeamPerformance"
|
||||
@update-check-type="updateCheckType"
|
||||
/>
|
||||
<div class="action-items-compact">
|
||||
<div v-if="cardVisibility.teamAlerts" class="action-items-compact">
|
||||
<TeamAlerts style="height: 300px;" :abnormalData="teamAlerts" />
|
||||
</div>
|
||||
</div>
|
||||
<StatisticalIndicators
|
||||
v-if="cardVisibility.statisticalIndicators"
|
||||
:customerCommunicationRate="statisticalIndicators.customerCommunicationRate"
|
||||
:averageResponseTime="statisticalIndicators.averageResponseTime"
|
||||
:timeoutResponseRate="statisticalIndicators.timeoutResponseRate"
|
||||
@@ -54,19 +61,19 @@
|
||||
<!-- Bottom Section -->
|
||||
<div class="bottom-section">
|
||||
<!-- Left Section - Group Performance Ranking -->
|
||||
<div class="left-section">
|
||||
<div v-if="cardVisibility.groupRanking" class="left-section">
|
||||
<GroupRanking
|
||||
:groups="groups"
|
||||
:selected-group="selectedGroup"
|
||||
@select-group="selectGroup"
|
||||
/>
|
||||
</div>
|
||||
<div class="problem-ranking">
|
||||
<div v-if="cardVisibility.problemRanking" class="problem-ranking">
|
||||
<!-- 客户迫切解决的问题 -->
|
||||
<ProblemRanking :problemRanking="problemRanking" />
|
||||
</div>
|
||||
<!-- Right Section - Group Comparison -->
|
||||
<div class="right-section">
|
||||
<div v-if="cardVisibility.groupComparison" class="right-section">
|
||||
<GroupComparison
|
||||
:groups="groups"
|
||||
:teamRanking="teamRanking"
|
||||
@@ -76,7 +83,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Team Members Detail Section -->
|
||||
<div class="team-detail-section" v-if="selectedGroup">
|
||||
<div class="team-detail-section" v-if="selectedGroup && cardVisibility.teamDetail">
|
||||
<!-- 团队详情加载状态 -->
|
||||
<div v-if="isTeamDetailLoading" class="team-loading">
|
||||
<div class="loading-spinner"></div>
|
||||
@@ -311,6 +318,23 @@ const updateCheckType = async (newValue) => {
|
||||
console.log('数据已根据新的统计模式重新加载')
|
||||
}
|
||||
|
||||
// 卡片显示状态
|
||||
const cardVisibility = ref({
|
||||
centerOverview: true,
|
||||
teamAlerts: true,
|
||||
statisticalIndicators: true,
|
||||
groupRanking: true,
|
||||
problemRanking: true,
|
||||
groupComparison: true,
|
||||
teamDetail: true
|
||||
})
|
||||
|
||||
// 更新卡片显示状态
|
||||
const updateCardVisibility = (newVisibility) => {
|
||||
Object.assign(cardVisibility.value, newVisibility)
|
||||
console.log('卡片显示状态已更新:', cardVisibility.value)
|
||||
}
|
||||
|
||||
const userStore = useUserStore()
|
||||
// 路由实例
|
||||
const router = useRouter()
|
||||
|
||||
@@ -4,28 +4,33 @@
|
||||
<div class="dashboard-header">
|
||||
<h1>管理者数据看板</h1>
|
||||
<!-- 头像 -->
|
||||
<UserDropdown />
|
||||
<UserDropdown
|
||||
:card-visibility="cardVisibility"
|
||||
@update-card-visibility="updateCardVisibility"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 第一行:核心业绩指标、销售实时进度 -->
|
||||
<div class="dashboard-row row-1">
|
||||
<!-- 核心业绩指标 -->
|
||||
<kpi-metrics :kpi-data="totalDeals" :format-number="formatNumber" />
|
||||
<kpi-metrics v-if="cardVisibility.kpiMetrics" :kpi-data="totalDeals" :format-number="formatNumber" />
|
||||
<!-- 销售实时进度 -->
|
||||
<sales-progress :sales-data="realTimeProgress" />
|
||||
<sales-progress v-if="cardVisibility.salesProgress" :sales-data="realTimeProgress" />
|
||||
<!-- 各中心营期阶段 -->
|
||||
<period-stage />
|
||||
<period-stage v-if="cardVisibility.periodStage" />
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
<div class="dashboard-row row-3">
|
||||
<!-- 转化漏斗 -->
|
||||
<funnel-chart
|
||||
v-if="cardVisibility.funnelChart"
|
||||
:funnel-data="formattedFunnelData"
|
||||
:comparison-data="formattedComparisonData"
|
||||
@time-range-change="handleTimeRangeChange"
|
||||
/>
|
||||
<!-- 销售个人业绩排行榜 -->
|
||||
<personal-sales-ranking
|
||||
v-if="cardVisibility.personalSalesRanking"
|
||||
:ranking-data="formattedSalesRankingData"
|
||||
:format-number="formatNumber"
|
||||
:get-rank-class="getRankClass"
|
||||
@@ -34,6 +39,7 @@
|
||||
/>
|
||||
<!-- 优质通话 -->
|
||||
<quality-calls
|
||||
v-if="cardVisibility.qualityCalls"
|
||||
:quality-calls="excellentRecord"
|
||||
@play-call="playCall"
|
||||
@download-call="downloadCall"
|
||||
@@ -43,21 +49,23 @@
|
||||
<div class="dashboard-row row-3">
|
||||
<!-- 业绩排行榜 -->
|
||||
<ranking-list
|
||||
v-if="cardVisibility.rankingList"
|
||||
:format-number="formatNumber"
|
||||
:get-rank-class="getRankClass"
|
||||
/>
|
||||
<!-- 客户类型占比 -->
|
||||
<customer-type :customer-data="customerTypeRatio" @category-change="getCustomerTypeRatio" />
|
||||
<customer-type v-if="cardVisibility.customerType" :customer-data="customerTypeRatio" @category-change="getCustomerTypeRatio" />
|
||||
<!-- 客户迫切解决的问题排行榜 -->
|
||||
<problem-ranking :ranking-data="problemRankingData" />
|
||||
<problem-ranking v-if="cardVisibility.problemRanking" :ranking-data="problemRankingData" />
|
||||
</div>
|
||||
<!-- 第四行:详细数据表格和数据详情 -->
|
||||
<div class="dashboard-row" v-show="false">
|
||||
<CampManagement />
|
||||
<CampManagement v-if="cardVisibility.campManagement" />
|
||||
</div>
|
||||
<!-- 第五行 -->
|
||||
<div class="dashboard-row" >
|
||||
<DetailedDataTable
|
||||
v-if="cardVisibility.detailedDataTable"
|
||||
:table-data="detailData"
|
||||
:level-tree="levelTree"
|
||||
v-model:selected-person="selectedPerson"
|
||||
@@ -213,6 +221,26 @@ const selectedPerson = ref(null);
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 卡片显示状态管理
|
||||
const cardVisibility = ref({
|
||||
kpiMetrics: true,
|
||||
salesProgress: true,
|
||||
periodStage: true,
|
||||
funnelChart: true,
|
||||
personalSalesRanking: true,
|
||||
qualityCalls: true,
|
||||
rankingList: true,
|
||||
customerType: true,
|
||||
problemRanking: true,
|
||||
campManagement: true,
|
||||
detailedDataTable: true
|
||||
});
|
||||
|
||||
// 更新卡片显示状态
|
||||
const updateCardVisibility = (newVisibility) => {
|
||||
Object.assign(cardVisibility.value, newVisibility);
|
||||
};
|
||||
|
||||
// 计算属性
|
||||
const filteredTableData = computed(() => {
|
||||
let filtered = tableData.value;
|
||||
|
||||
Reference in New Issue
Block a user