feat(secondTop): 添加营期阶段调控功能并优化KPI显示

- 在secondTop页面添加营期阶段调控UI,支持修改"接数据"天数
- 计算并显示当前营期阶段及日期范围
- 优化PersonalDashboard中的KPI指标名称显示
- 隐藏topOne页面中不需要的CampManagement组件
This commit is contained in:
2025-08-20 21:02:49 +08:00
parent 80bb9784ae
commit 5635bcd4be
4 changed files with 110 additions and 8 deletions

View File

@@ -58,7 +58,6 @@ export const getCustomerChatInfo = (params) => {
// 客户表单详情 /api/v1/sales/get_customer_form_info
export const getCustomerFormInfo = (params) => {
return https.post('/api/v1/sales_timeline/get_customer_form_info', params)
}
// 客户通话录音 /api/v1/sales/get_customer_call_info

View File

@@ -17,15 +17,15 @@
</div>
<div class="kpi-item">
<div class="kpi-value">{{ props.kpiData.successRate }}%</div>
<p>成功</p>
<p>电话接通</p>
</div>
<div class="kpi-item">
<div class="kpi-value">{{ props.kpiData.avgDuration }}<span class="kpi-unit">min</span></div>
<p>平均时长</p>
<p>平均通话时长</p>
</div>
<div class="kpi-item">
<div class="kpi-value">{{ props.kpiData.conversionRate }}</div>
<p>转化率</p>
<p>成交转化率</p>
</div>
<div class="kpi-item">
<div class="kpi-value">{{ props.kpiData.assignedData }}</div>

View File

@@ -24,10 +24,20 @@
<p>统筹多组运营优化资源配置驱动业绩增长实现团队协同发展</p>
</div>
<!-- 营期阶段信息 -->
<!-- 营期阶段信息与调控 -->
<div class="stage-info" style="margin-left: 100px;">
<span class="stage-label">营期所属阶段</span>
<span class="stage-value">接数据</span>
<span class="stage-value">{{ currentStage }}</span>
<!-- 仅在接数据阶段显示调控UI -->
<div v-if="isDataReceivingStage" class="stage-control">
<span class="control-label">调整接数据天数:</span>
<input type="number" v-model.number="dataReceivingStage.days" min="1" class="days-input" />
<button @click="saveCampSettings" class="save-button">保存</button>
</div>
<div v-for="stage in centerData.stages" :key="stage.name" class="stage-dates">
<span>{{ stage.name }}: {{ stage.startDate }} to {{ stage.endDate }}</span>
</div>
</div>
</template>
@@ -174,6 +184,76 @@
} from '@/api/secondTop.js'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user.js'
// 营期调控逻辑
// This would ideally come from a prop or API call based on the logged-in user
const centerData = ref({
id: 1,
name: '一中心',
startDate: '2025-08-18',
stages: [
{ name: '接数据', days: 3, color: '#ffc107', startDate: '', endDate: '' },
{ name: '课一', days: 1, color: '#0dcaf0', startDate: '', endDate: '' },
{ name: '课二', days: 1, color: '#0d6efd', startDate: '', endDate: '' },
{ name: '课三', days: 1, color: '#6f42c1', startDate: '', endDate: '' },
{ name: '课四', days: 1, color: '#d63384', startDate: '', endDate: '' }
]
});
const getCurrentStage = (center) => {
const today = new Date();
today.setHours(0, 0, 0, 0);
const startDate = new Date(center.startDate);
startDate.setHours(0, 0, 0, 0);
if (today < startDate) {
return '未开始';
}
const diffTime = Math.abs(today - startDate);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1; // 当天算第一天
let cumulativeDays = 0;
for (let i = 0; i < center.stages.length; i++) {
const stage = center.stages[i];
cumulativeDays += stage.days;
if (diffDays <= cumulativeDays) {
return stage.name;
}
}
return '已结束';
};
const currentStage = computed(() => getCurrentStage(centerData.value));
const isDataReceivingStage = computed(() => currentStage.value === '接数据');
// The '接数据' stage object
const dataReceivingStage = computed(() => centerData.value.stages.find(s => s.name === '接数据'));
const recalculateStageDates = () => {
const startDate = new Date(centerData.value.startDate);
let cumulativeDays = 0;
centerData.value.stages.forEach(stage => {
const stageStartDate = new Date(startDate);
stageStartDate.setDate(startDate.getDate() + cumulativeDays);
stage.startDate = stageStartDate.toISOString().split('T')[0];
cumulativeDays += stage.days;
const stageEndDate = new Date(startDate);
stageEndDate.setDate(startDate.getDate() + cumulativeDays - 1);
stage.endDate = stageEndDate.toISOString().split('T')[0];
});
};
const saveCampSettings = () => {
recalculateStageDates();
console.log('Saving camp settings for', centerData.value.name);
console.log('Updated data:', JSON.parse(JSON.stringify(centerData.value)));
alert('营期设置已保存!');
};
// 组别数据
const groups = ref([])
// loading 状态
@@ -511,6 +591,7 @@ const conversionRateVsAverage = ref({})
return statusMap[status] || '未知'
}
onMounted(async () => {
recalculateStageDates();
try {
isLoading.value = true
await CenterOverallCenterPerformance()
@@ -1134,4 +1215,26 @@ const conversionRateVsAverage = ref({})
border: 1px solid rgba(0, 0, 0, 0.1);
}
}
.stage-control {
margin-left: 20px;
display: flex;
align-items: center;
}
.control-label {
margin-right: 10px;
font-size: 14px;
color: #606266;
}
.days-input {
width: 60px;
text-align: center;
margin-right: 10px;
}
.save-button {
padding: 5px 10px;
font-size: 12px;
}
</style>

View File

@@ -57,11 +57,11 @@
<problem-ranking :ranking-data="problemRankingData" />
</div>
<!-- 第四行详细数据表格和数据详情 -->
<div class="dashboard-row">
<div class="dashboard-row" v-show="false">
<CampManagement />
</div>
<!-- 第五行 -->
<div class="dashboard-row">
<div class="dashboard-row" >
<DetailedDataTable
:table-data="detailData"
:level-tree="levelTree"