feat(topone): 实现任务下发功能并优化界面布局
- 添加任务下发API接口并在任务列表组件中引入 - 修改任务创建逻辑,对接后端API - 获取下属人员列表用于任务分配 - 优化表格布局,移除总业绩列 - 删除不必要的指导建议模块
This commit is contained in:
@@ -65,4 +65,9 @@ export const getDetailedDataTable = (params) => {
|
||||
return https.post('/api/v1/level_five/overview/detailed_data_table', params)
|
||||
}
|
||||
|
||||
// 下发任务 /api/v1/level_five/overview/assign_tasks
|
||||
export const assignTasks = (params) => {
|
||||
return https.post('/api/v1/level_five/overview/assign_tasks', params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
<div class="detail-label">成交单数</div>
|
||||
<div class="detail-value">{{ selectedMember.deals || 0 }} 单</div>
|
||||
</div>
|
||||
<div class="detail-card">
|
||||
<div class="detail-label">总业绩</div>
|
||||
<div class="detail-value">¥{{ formatAmount(selectedMember.week_amount || selectedMember.performance) }}</div>
|
||||
</div>
|
||||
<div class="detail-card">
|
||||
<div class="detail-label">转化率</div>
|
||||
<div class="detail-value">{{ selectedMember.conversion_rate || selectedMember.conversion || '0%' }}</div>
|
||||
@@ -38,7 +34,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 指导建议 -->
|
||||
<div class="guidance-section">
|
||||
<!-- <div class="guidance-section">
|
||||
<div class="guidance-header" @click="toggleGuidanceCollapse">
|
||||
<h3>💡 指导建议</h3>
|
||||
<div class="collapse-toggle" :class="{ 'collapsed': isGuidanceCollapsed }">
|
||||
@@ -69,7 +65,7 @@
|
||||
<p>{{ selectedMember.user_name || selectedMember.name }} 的各项指标都很不错,继续保持这种状态!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 录音列表 -->
|
||||
<div class="recordings-section">
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<div class="table-header">
|
||||
<span>排名</span>
|
||||
<span>姓名</span>
|
||||
<span>总业绩</span>
|
||||
<span>转化率</span>
|
||||
<span>加微率</span>
|
||||
<span>入群率</span>
|
||||
@@ -21,7 +20,6 @@
|
||||
>
|
||||
<span class="rank">{{ index + 1 }}</span>
|
||||
<span class="name">{{ member.user_name || member.name }}</span>
|
||||
<span class="performance">¥{{ formatAmount(member.week_amount || member.performance) }}</span>
|
||||
<span class="conversion">{{ member.conversion_rate || member.conversion || '0%' }}</span>
|
||||
<span class="wechat-rate">{{ member.plus_v_rate || member.wechatRate || '0%' }}</span>
|
||||
<span class="group-rate">{{ member.group_rate || member.groupRate || '0%' }}</span>
|
||||
@@ -164,7 +162,7 @@ const handleDoubleClick = (member) => {
|
||||
|
||||
.table-header {
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr 120px 80px 90px 90px;
|
||||
grid-template-columns: 60px 1fr 80px 90px 90px;
|
||||
gap: 0.8rem;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
@@ -176,7 +174,7 @@ const handleDoubleClick = (member) => {
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr 120px 80px 90px 90px;
|
||||
grid-template-columns: 60px 1fr 80px 90px 90px;
|
||||
gap: 0.8rem;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
@@ -243,7 +241,7 @@ const handleDoubleClick = (member) => {
|
||||
|
||||
.ranking-table {
|
||||
.table-header {
|
||||
grid-template-columns: 40px 1fr 70px 55px 55px 55px;
|
||||
grid-template-columns: 40px 1fr 70px 55px 55px;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.5rem 0;
|
||||
@@ -251,7 +249,7 @@ const handleDoubleClick = (member) => {
|
||||
}
|
||||
|
||||
.table-row {
|
||||
grid-template-columns: 40px 1fr 70px 55px 55px 55px;
|
||||
grid-template-columns: 40px 1fr 70px 55px 55px;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.5rem 0;
|
||||
@@ -292,14 +290,14 @@ const handleDoubleClick = (member) => {
|
||||
|
||||
.ranking-table {
|
||||
.table-header {
|
||||
grid-template-columns: 30px 1fr 55px 45px 45px 45px;
|
||||
grid-template-columns: 30px 1fr 55px 45px 45px;
|
||||
gap: 0.2rem;
|
||||
font-size: 0.7rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
grid-template-columns: 30px 1fr 55px 45px 45px 45px;
|
||||
grid-template-columns: 30px 1fr 55px 45px 45px;
|
||||
gap: 0.2rem;
|
||||
font-size: 0.75rem;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -1288,7 +1288,7 @@ onMounted(async () => {
|
||||
|
||||
// PC端保持一致布局
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: 50px 1fr 100px 80px 90px 90px;
|
||||
grid-template-columns: 50px 1fr 80px 90px 90px;
|
||||
gap: 1rem;
|
||||
font-size: 0.875rem;
|
||||
padding: 1rem 0;
|
||||
@@ -1296,7 +1296,7 @@ onMounted(async () => {
|
||||
|
||||
// 平板端适配
|
||||
@media (max-width: 1023px) and (min-width: 769px) {
|
||||
grid-template-columns: 45px 1fr 90px 70px 90px 90px;
|
||||
grid-template-columns: 45px 1fr 70px 90px 90px;
|
||||
|
||||
gap: 0.75rem;
|
||||
font-size: 0.8125rem;
|
||||
@@ -1305,7 +1305,7 @@ onMounted(async () => {
|
||||
|
||||
// 移动端适配
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 40px 1fr 80px 60px 90px 90px;
|
||||
grid-template-columns: 40px 1fr 60px 90px 90px;
|
||||
|
||||
gap: 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
@@ -1343,7 +1343,7 @@ onMounted(async () => {
|
||||
|
||||
// PC端保持一致布局
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: 50px 1fr 100px 80px 90px 90px;
|
||||
grid-template-columns: 50px 1fr 80px 90px 90px;
|
||||
|
||||
gap: 1rem;
|
||||
font-size: 0.875rem;
|
||||
|
||||
@@ -5,154 +5,10 @@
|
||||
<div class="header-controls">
|
||||
<select v-model="filterPriority" class="priority-filter">
|
||||
<option value="all">全部优先级</option>
|
||||
<option value="urgent">紧急</option>
|
||||
<option value="high">高</option>
|
||||
<option value="medium">中</option>
|
||||
<option value="low">低</option>
|
||||
<option value="urgent">待处理</option>
|
||||
<option value="high">正在处理</option>
|
||||
<option value="medium">已完成</option>
|
||||
</select>
|
||||
<button class="add-btn" @click="showAddForm = true">+ 新增</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计概览 -->
|
||||
<div class="actions-summary">
|
||||
<div class="summary-item urgent">
|
||||
<div class="summary-count">{{ getCountByPriority('urgent') }}</div>
|
||||
<div class="summary-label">紧急事项</div>
|
||||
</div>
|
||||
<div class="summary-item high">
|
||||
<div class="summary-count">{{ getCountByPriority('high') }}</div>
|
||||
<div class="summary-label">高优先级</div>
|
||||
</div>
|
||||
<div class="summary-item medium">
|
||||
<div class="summary-count">{{ getCountByPriority('medium') }}</div>
|
||||
<div class="summary-label">中优先级</div>
|
||||
</div>
|
||||
<div class="summary-item completed">
|
||||
<div class="summary-count">{{ completedCount }}</div>
|
||||
<div class="summary-label">已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 事项列表 -->
|
||||
<div class="actions-list">
|
||||
<div
|
||||
v-for="action in filteredActions"
|
||||
:key="action.id"
|
||||
class="action-item"
|
||||
:class="[action.priority, { completed: action.completed, overdue: isOverdue(action.dueDate) }]"
|
||||
>
|
||||
<div class="action-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="action.completed"
|
||||
@change="toggleComplete(action.id)"
|
||||
class="checkbox"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="action-content">
|
||||
<div class="action-header">
|
||||
<h4 class="action-title" :class="{ completed: action.completed }">{{ action.title }}</h4>
|
||||
<div class="action-meta">
|
||||
<span class="priority-badge" :class="action.priority">{{ getPriorityText(action.priority) }}</span>
|
||||
<span class="due-date" :class="{ overdue: isOverdue(action.dueDate) }">
|
||||
{{ formatDueDate(action.dueDate) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="action-description">{{ action.description }}</p>
|
||||
|
||||
<div class="action-details">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">关联组别:</span>
|
||||
<span class="detail-value">{{ action.relatedGroup || '全部' }}</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="action.assignee">
|
||||
<span class="detail-label">负责人:</span>
|
||||
<span class="detail-value">{{ action.assignee }}</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="action.progress !== undefined">
|
||||
<span class="detail-label">进度:</span>
|
||||
<div class="progress-mini">
|
||||
<div class="progress-bar-mini">
|
||||
<div class="progress-fill-mini" :style="{ width: action.progress + '%' }"></div>
|
||||
</div>
|
||||
<span class="progress-text-mini">{{ action.progress }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-footer">
|
||||
<div class="action-tags">
|
||||
<span v-for="tag in action.tags" :key="tag" class="tag">{{ tag }}</span>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<button class="btn-edit" @click="editAction(action)">编辑</button>
|
||||
<button class="btn-delete" @click="deleteAction(action.id)">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-if="filteredActions.length === 0" class="empty-state">
|
||||
<div class="empty-icon">✅</div>
|
||||
<div class="empty-text">
|
||||
<h3>暂无待处理事项</h3>
|
||||
<p>{{ filterPriority === 'all' ? '所有事项都已处理完成' : '该优先级下暂无事项' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增表单模态框 -->
|
||||
<div v-if="showAddForm" class="modal-overlay" @click="showAddForm = false">
|
||||
<div class="modal-content" @click.stop>
|
||||
<div class="modal-header">
|
||||
<h3>新增待处理事项</h3>
|
||||
<button class="close-btn" @click="showAddForm = false">×</button>
|
||||
</div>
|
||||
<form @submit.prevent="addAction" class="add-form">
|
||||
<div class="form-group">
|
||||
<label>标题</label>
|
||||
<input v-model="newAction.title" type="text" required class="form-input">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>描述</label>
|
||||
<textarea v-model="newAction.description" class="form-textarea"></textarea>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>优先级</label>
|
||||
<select v-model="newAction.priority" class="form-select">
|
||||
<option value="low">低</option>
|
||||
<option value="medium">中</option>
|
||||
<option value="high">高</option>
|
||||
<option value="urgent">紧急</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>截止日期</label>
|
||||
<input v-model="newAction.dueDate" type="date" class="form-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>关联组别</label>
|
||||
<select v-model="newAction.relatedGroup" class="form-select">
|
||||
<option value="">全部</option>
|
||||
<option value="精英组">精英组</option>
|
||||
<option value="冲锋组">冲锋组</option>
|
||||
<option value="突破组">突破组</option>
|
||||
<option value="新星组">新星组</option>
|
||||
<option value="潜力组">潜力组</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" @click="showAddForm = false" class="btn-cancel">取消</button>
|
||||
<button type="submit" class="btn-submit">添加</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -292,34 +148,7 @@ const completedCount = computed(() => {
|
||||
return actions.value.filter(action => action.completed).length
|
||||
})
|
||||
|
||||
// 按优先级获取数量
|
||||
const getCountByPriority = (priority) => {
|
||||
return actions.value.filter(action => action.priority === priority && !action.completed).length
|
||||
}
|
||||
|
||||
// 切换完成状态
|
||||
const toggleComplete = (id) => {
|
||||
const action = actions.value.find(a => a.id === id)
|
||||
if (action) {
|
||||
action.completed = !action.completed
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否过期
|
||||
const isOverdue = (dueDate) => {
|
||||
return new Date(dueDate) < new Date()
|
||||
}
|
||||
|
||||
// 获取优先级文本
|
||||
const getPriorityText = (priority) => {
|
||||
const priorityMap = {
|
||||
urgent: '紧急',
|
||||
high: '高',
|
||||
medium: '中',
|
||||
low: '低'
|
||||
}
|
||||
return priorityMap[priority] || priority
|
||||
}
|
||||
|
||||
// 格式化截止日期
|
||||
const formatDueDate = (dueDate) => {
|
||||
|
||||
@@ -1122,7 +1122,7 @@ const selectMember = (member) => {
|
||||
|
||||
// PC端保持一致布局
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: 50px 1fr 100px 80px 90px 90px;
|
||||
grid-template-columns: 50px 1fr 80px 90px 90px;
|
||||
|
||||
gap: 1rem;
|
||||
font-size: 0.875rem;
|
||||
@@ -1131,7 +1131,7 @@ const selectMember = (member) => {
|
||||
|
||||
// 平板端适配
|
||||
@media (max-width: 1023px) and (min-width: 769px) {
|
||||
grid-template-columns: 45px 1fr 90px 70px 90px 90px;
|
||||
grid-template-columns: 45px 1fr 70px 90px 90px;
|
||||
|
||||
gap: 0.75rem;
|
||||
font-size: 0.8125rem;
|
||||
@@ -1140,7 +1140,7 @@ const selectMember = (member) => {
|
||||
|
||||
// 移动端适配
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 40px 1fr 80px 60px 90px 90px;
|
||||
grid-template-columns: 40px 1fr 60px 90px 90px;
|
||||
|
||||
gap: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
|
||||
@@ -346,8 +346,6 @@ async function fetchAbnormalResponseRate() {
|
||||
console.error('获取异常预警失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 统计指标--活跃客户沟通率
|
||||
async function fetchCustomerCommunicationRate() {
|
||||
const params = getRequestParams()
|
||||
@@ -401,57 +399,6 @@ async function fetchUrgentNeedToAddress() {
|
||||
try {
|
||||
const response = await getUrgentNeedToAddress(hasParams ? params : undefined)
|
||||
problemRanking.value = response.data
|
||||
/**
|
||||
* "data": {
|
||||
"user_name": "陈盼良",
|
||||
"user_level": 3,
|
||||
"calculate_urgent_issue_ratio": {
|
||||
"成绩提升": "0.00%",
|
||||
"少玩手机": "0.00%",
|
||||
"回归学校": "0.00%",
|
||||
"心理健康": "0.00%"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 团队详情加载样式
|
||||
.team-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3rem;
|
||||
|
||||
.loading-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); },
|
||||
"urgent_issue_consultations": {
|
||||
"成绩提升": 0,
|
||||
"少玩手机": 0,
|
||||
"回归学校": 0,
|
||||
"心理健康": 0
|
||||
}
|
||||
}
|
||||
*/
|
||||
// console.log('客户迫切解决的问题:', response.data)
|
||||
} catch (error) {
|
||||
console.error('获取客户迫切解决的问题失败:', error)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits } from 'vue';
|
||||
import { assignTasks } from '@/api/top.js';
|
||||
|
||||
defineProps({
|
||||
tasks: Array,
|
||||
|
||||
@@ -94,9 +94,9 @@
|
||||
<select v-model="newTask.assignee">
|
||||
<option value="">请选择员工</option>
|
||||
<option
|
||||
v-for="employee in employees"
|
||||
:key="employee.id"
|
||||
:value="employee.name"
|
||||
v-for="employee in assigneeOptions"
|
||||
:key="employee.wechat_id"
|
||||
:value="employee.wechat_id"
|
||||
>
|
||||
{{ employee.name }}
|
||||
</option>
|
||||
@@ -140,6 +140,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted, nextTick } from "vue";
|
||||
import axios from "axios";
|
||||
import UserDropdown from "@/components/UserDropdown.vue";
|
||||
import KpiMetrics from "./components/KpiMetrics.vue";
|
||||
import SalesProgress from "./components/SalesProgress.vue";
|
||||
@@ -157,8 +158,9 @@ import DataDetail from "./components/DataDetail.vue";
|
||||
import CampManagement from "./components/CampManagement.vue";
|
||||
import DetailedDataTable from "./components/DetailedDataTable.vue";
|
||||
import { getOverallCompanyPerformance,getCompanyDepositConversionRate,getCompanyTotalCallCount,getCompanyNewCustomer,getCompanyConversionRate,getCompanyRealTimeProgress
|
||||
,getCompanyConversionRateVsLast,getSalesMonthlyPerformance,getCustomerTypeDistribution,getUrgentNeedToAddress,getLevelTree,getDetailedDataTable
|
||||
,getCompanyConversionRateVsLast,getSalesMonthlyPerformance,getCustomerTypeDistribution,getUrgentNeedToAddress,getLevelTree,getDetailedDataTable,assignTasks
|
||||
} from "@/api/top";
|
||||
|
||||
const rankingPeriod = ref("month");
|
||||
const rankingData = ref([
|
||||
{ id: 1, name: "张三", department: "销售一部", performance: 125000 },
|
||||
@@ -172,15 +174,7 @@ const sortField = ref("dealRate");
|
||||
const sortOrder = ref("desc");
|
||||
const selectedPerson = ref(null);
|
||||
|
||||
const tasks = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: "完成Q4销售目标制定",
|
||||
assignee: "张三",
|
||||
deadline: "2024-01-15",
|
||||
status: "pending",
|
||||
}
|
||||
]);
|
||||
const tasks = ref([]);
|
||||
|
||||
const employees = ref([
|
||||
{ id: 1, name: "张三" }
|
||||
@@ -193,7 +187,51 @@ const newTask = reactive({
|
||||
deadline: "",
|
||||
description: "",
|
||||
});
|
||||
// 下拉框人员
|
||||
const assigneeOptions = ref([]);
|
||||
async function name() {
|
||||
try {
|
||||
console.log('开始获取下属人员列表...');
|
||||
const res = await axios.get('http://192.168.15.56: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);
|
||||
}
|
||||
/**
|
||||
* "data": [
|
||||
{
|
||||
"name": "程琦",
|
||||
"wechat_id": "1688856301330784"
|
||||
},
|
||||
{
|
||||
"name": "潘加俊",
|
||||
"wechat_id": "1688855836721980"
|
||||
},
|
||||
{
|
||||
"name": "伍晶晶",
|
||||
"wechat_id": "1688854476805987"
|
||||
},
|
||||
{
|
||||
"name": "张三丰",
|
||||
"wechat_id": "1212345648513"
|
||||
},
|
||||
{
|
||||
"name": "朱一航",
|
||||
"wechat_id": "1212345648513"
|
||||
},
|
||||
{
|
||||
"name": "王卓琳",
|
||||
"wechat_id": "1212345648513"
|
||||
}
|
||||
]
|
||||
*/
|
||||
}
|
||||
// 计算属性
|
||||
const filteredTableData = computed(() => {
|
||||
let filtered = tableData.value;
|
||||
@@ -321,12 +359,26 @@ const downloadCall = (callId) => {
|
||||
console.log("下载通话录音:", callId);
|
||||
};
|
||||
|
||||
const createTask = () => {
|
||||
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,
|
||||
@@ -346,6 +398,11 @@ const createTask = () => {
|
||||
});
|
||||
|
||||
showTaskModal.value = false;
|
||||
alert('任务创建成功!');
|
||||
} catch (error) {
|
||||
console.error('创建任务失败:', error);
|
||||
alert('创建任务失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 核心数据
|
||||
@@ -592,6 +649,7 @@ onMounted(async() => {
|
||||
await getCustomerUrgency()
|
||||
await CusotomGetLevelTree()
|
||||
await getDetailData()
|
||||
await name() // 获取下属人员列表
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user