feat(topOne): 添加各中心营期阶段组件并优化API调用

- 新增PeriodStage组件展示各中心营期阶段信息
- 移除任务管理相关代码,替换为营期阶段展示
- 修改API端点路径,优化优秀录音文件接口调用
- 调整TeamAlerts组件样式,减小最大高度
This commit is contained in:
2025-08-26 13:55:55 +08:00
parent b7d46c3dde
commit 11e686d4d9
4 changed files with 319 additions and 248 deletions

View File

@@ -7,19 +7,14 @@
<UserDropdown />
</div>
<!-- 第一行核心业绩指标销售实时进度下发任务 -->
<!-- 第一行核心业绩指标销售实时进度 -->
<div class="dashboard-row row-1">
<!-- 核心业绩指标 -->
<kpi-metrics :kpi-data="totalDeals" :format-number="formatNumber" />
<!-- 销售实时进度 -->
<sales-progress :sales-data="realTimeProgress" />
<!-- 下发任务 -->
<task-list
:tasks="tasks"
:format-date="formatDate"
:get-task-status-text="getTaskStatusText"
@show-task-modal="showTaskModal = true"
/>
<!-- 各中心营期阶段 -->
<period-stage />
</div>
<!-- 第二行 -->
<div class="dashboard-row row-3">
@@ -69,59 +64,7 @@
@filter-change="handleFilterChange"
/>
</div>
<!-- 新建任务模态框 -->
<div
v-if="showTaskModal"
class="modal-overlay"
@click="showTaskModal = false"
>
<div class="modal-content" @click.stop>
<div class="modal-header">
<h3>新建任务</h3>
<button class="close-btn" @click="showTaskModal = false">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>任务标题</label>
<input
v-model="newTask.title"
type="text"
placeholder="请输入任务标题"
/>
</div>
<div class="form-group">
<label>分配给</label>
<select v-model="newTask.assignee">
<option value="">请选择员工</option>
<option
v-for="employee in assigneeOptions"
:key="employee.wechat_id"
:value="employee.wechat_id"
>
{{ employee.name }}
</option>
</select>
</div>
<div class="form-group">
<label>截止日期</label>
<input v-model="newTask.deadline" type="date" />
</div>
<div class="form-group">
<label>任务描述</label>
<textarea
v-model="newTask.description"
placeholder="请输入任务描述"
></textarea>
</div>
</div>
<div class="modal-footer">
<button class="cancel-btn" @click="showTaskModal = false">
取消
</button>
<button class="confirm-btn" @click="createTask">创建任务</button>
</div>
</div>
</div>
</div>
</template>
@@ -144,7 +87,6 @@ import axios from "axios";
import UserDropdown from "@/components/UserDropdown.vue";
import KpiMetrics from "./components/KpiMetrics.vue";
import SalesProgress from "./components/SalesProgress.vue";
import TaskList from "./components/TaskList.vue";
import FunnelChart from "./components/FunnelChart.vue";
import CustomerProfile from "./components/CustomerProfile.vue";
import CustomerType from "./components/CustomerType.vue";
@@ -157,8 +99,10 @@ import QualityCalls from "./components/QualityCalls.vue";
import DataDetail from "./components/DataDetail.vue";
import CampManagement from "./components/CampManagement.vue";
import DetailedDataTable from "./components/DetailedDataTable.vue";
import PeriodStage from "./components/PeriodStage.vue";
import { getOverallCompanyPerformance,getCompanyDepositConversionRate,getCompanyTotalCallCount,getCompanyNewCustomer,getCompanyConversionRate,getCompanyRealTimeProgress
,getCompanyConversionRateVsLast,getSalesMonthlyPerformance,getCustomerTypeDistribution,getUrgentNeedToAddress,getLevelTree,getDetailedDataTable,assignTasks } from "@/api/top";
,getCompanyConversionRateVsLast,getSalesMonthlyPerformance,getCustomerTypeDistribution,getUrgentNeedToAddress,getLevelTree,getDetailedDataTable,getExcellentRecordFile } from "@/api/top";
import { useUserStore } from "@/stores/user.js";
const rankingPeriod = ref("month");
const rankingData = ref([
@@ -173,131 +117,8 @@ const sortField = ref("dealRate");
const sortOrder = ref("desc");
const selectedPerson = ref(null);
const tasks = ref([]);
const userStore = useUserStore();
const employees = ref([
{ id: 1, name: "张三" }
]);
const showTaskModal = ref(false);
const newTask = reactive({
title: "",
assignee: "",
deadline: "",
description: "",
});
// 获取任务列表
const getTaskList = async () => {
try {
const res = await axios.post('http://192.168.15.60:8890/api/v1/level_five/overview/view_tasks', {}, {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})
console.log(888888,res)
if (res.data.code === 200) {
const apiTasks = res.data.data.tasks || res.data.data
// 将API数据格式转换为TaskList组件期望的格式
tasks.value = apiTasks.map(task => ({
id: task.task_id,
title: task.task_title,
assignee: task.assignee || '未分配',
deadline: task.expiration_date,
status: task.state === '待处理' ? 'pending' : task.state === '正在处理' ? 'in-progress' : 'completed',
description: task.task_content,
created_at: task.created_at
}))
console.log(777777,tasks.value)
/**
* tasks
:
[,…]
0
:
{task_id: "1755748690560728_22d55cc618784537973481228a15956a", task_title: "55", task_content: "222",…}
created_at
:
"2025-08-21 11:58:10"
expiration_date
:
"20250808"
state
:
"待处理"
task_content
:
"222"
task_id
:
"1755748690560728_22d55cc618784537973481228a15956a"
task_title
:
"55"
1
:
{task_id: "1755745331126891_650206e5b6d345699de3e3e406a2600e", task_title: "测试任务",…}
created_at
:
"2025-08-21 11:02:11"
expiration_date
:
"121221"
state
:
"待处理"
task_content
:
"测试任务"
task_id
:
"1755745331126891_650206e5b6d345699de3e3e406a2600e"
task_title
:
"测试任务"
2
:
{task_id: "1755745330094989_528dd87dc13a4a5bb33c9c272fb1a482", task_title: "测试任务",…}
created_at
:
"2025-08-21 11:02:10"
expiration_date
:
"121221"
state
:
"已完成"
task_content
:
"测试任务"
task_id
:
"1755745330094989_528dd87dc13a4a5bb33c9c272fb1a482"
task_title
:
"测试任务"
*/
}
} catch (error) {
console.error('获取任务列表失败:', error)
}
}
// 下拉框人员
const assigneeOptions = ref([]);
async function name() {
try {
console.log('开始获取下属人员列表...');
const res = await axios.get('http://192.168.15.60:8890/api/v1/level_five/overview/get_subordinates',{
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
assigneeOptions.value = res.data.data;
console.log('assigneeOptions设置后:', assigneeOptions.value);
} catch (error) {
console.error('获取下属人员列表失败:', error);
}
}
// 计算属性
const filteredTableData = computed(() => {
let filtered = tableData.value;
@@ -418,14 +239,7 @@ const selectPerson = (person) => {
selectedPerson.value = person;
};
const getTaskStatusText = (status) => {
const statusMap = {
pending: "待处理",
"in-progress": "进行中",
completed: "已完成",
};
return statusMap[status] || status;
};
const playCall = (callId) => {
console.log("播放通话录音:", callId);
@@ -435,51 +249,7 @@ const downloadCall = (callId) => {
console.log("下载通话录音:", callId);
};
const createTask = async () => {
if (!newTask.title || !newTask.assignee || !newTask.deadline) {
alert("请填写完整信息");
return;
}
try {
// 构造API请求参数
const params = {
task_title: newTask.title,
task_assignee: [newTask.assignee], // 转换为数组格式
expiration_date: newTask.deadline.replace(/-/g, ''), // 移除日期中的横线
task_content: newTask.description || newTask.title
};
// 调用API
const response = await assignTasks(params);
console.log('任务创建成功:', response);
// 创建本地任务对象用于显示
const task = {
id: Date.now(),
title: newTask.title,
assignee: newTask.assignee,
deadline: newTask.deadline,
status: "pending",
};
tasks.value.unshift(task);
// 重置表单
Object.assign(newTask, {
title: "",
assignee: "",
deadline: "",
description: "",
});
showTaskModal.value = false;
alert('任务创建成功!');
} catch (error) {
console.error('创建任务失败:', error);
alert('创建任务失败,请重试');
}
};
// 核心数据
const totalDeals = ref({});
@@ -505,6 +275,9 @@ async function getTotalDeals() {
}
// 实时进度
const realTimeProgress = ref({});
async function getRealTimeProgress() {
try {
const res = await getCompanyRealTimeProgress()
@@ -706,7 +479,6 @@ async function getDetailData(params) {
console.error("获取详细数据表格失败:", error);
}
}
}
// 处理筛选器变化
@@ -714,19 +486,31 @@ const handleFilterChange = (filterParams) => {
console.log('筛选器变化:', filterParams)
getDetailData(filterParams)
}
// 优秀录音
const excellentRecord = ref({});
async function CenterExcellentRecord() {
const params={
user_level:userStore.userInfo.user_level.toString(),
user_name:userStore.userInfo.username
}
try {
const res = await getExcellentRecordFile(params)
excellentRecord.value = res.data
} catch (error) {
console.error("获取优秀录音失败:", error);
}
}
onMounted(async() => {
// 页面初始化逻辑
await getRealTimeProgress()
await getTotalDeals()
await getTaskList()
await getConversionComparison('month')
await getCompanySalesRank('red')
await getCustomerTypeRatio('child_education')
await getCustomerUrgency()
await CusotomGetLevelTree()
await getDetailData()
await name() // 获取下属人员列表
await CenterExcellentRecord()
});
</script>