Compare commits
2 Commits
2a52e8f0f6
...
6d22aecc29
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d22aecc29 | |||
| 4eea8f8a8a |
@@ -21,6 +21,12 @@
|
|||||||
</svg>
|
</svg>
|
||||||
结束营期
|
结束营期
|
||||||
</button>
|
</button>
|
||||||
|
<button @click="showHistory" class="history-btn">
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16">
|
||||||
|
<path fill="currentColor" d="M13,3A9,9 0 0,0 4,12H1L4.89,15.89L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3Z"/>
|
||||||
|
</svg>
|
||||||
|
历史
|
||||||
|
</button>
|
||||||
<button @click="nextMonth" class="nav-btn">
|
<button @click="nextMonth" class="nav-btn">
|
||||||
<svg viewBox="0 0 24 24" width="16" height="16">
|
<svg viewBox="0 0 24 24" width="16" height="16">
|
||||||
<path fill="currentColor" d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
<path fill="currentColor" d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
||||||
@@ -88,15 +94,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
|
||||||
<label for="campStartDate">营期开始时间:</label>
|
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
id="campStartDate"
|
|
||||||
v-model="campStartDate"
|
|
||||||
class="form-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="campDays">接数据天数:</label>
|
<label for="campDays">接数据天数:</label>
|
||||||
<input
|
<input
|
||||||
@@ -197,6 +194,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 历史营期弹框 -->
|
||||||
|
<div v-if="showHistoryModal" class="modal-overlay" @click="showHistoryModal = false">
|
||||||
|
<div class="modal-content" @click.stop>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>历史营期记录</h3>
|
||||||
|
<button @click="showHistoryModal = false" class="close-btn">
|
||||||
|
<svg viewBox="0 0 24 24" width="20" height="20">
|
||||||
|
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div v-if="historyPeriods.length === 0" class="no-history">
|
||||||
|
<svg viewBox="0 0 24 24" width="48" height="48" class="no-data-icon">
|
||||||
|
<path fill="currentColor" d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4M12,6A6,6 0 0,0 6,12A6,6 0 0,0 12,18A6,6 0 0,0 18,12A6,6 0 0,0 12,6M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8Z"/>
|
||||||
|
</svg>
|
||||||
|
<p>暂无历史营期记录</p>
|
||||||
|
</div>
|
||||||
|
<div v-else class="history-list">
|
||||||
|
<div v-for="(period, index) in historyPeriods" :key="index" class="history-item">
|
||||||
|
<div class="period-info">
|
||||||
|
<div class="period-title">第 {{ index + 1 }} 期营期</div>
|
||||||
|
<div class="period-details">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">开始时间:</span>
|
||||||
|
<span class="value">{{ period.startDate }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">结束时间:</span>
|
||||||
|
<span class="value">{{ period.endDate }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">接数据天数:</span>
|
||||||
|
<span class="value">{{ period.dataDays }} 天</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">休息天数:</span>
|
||||||
|
<span class="value">{{ period.restDays }} 天</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="period-status" :class="period.status">
|
||||||
|
{{ period.status === 'completed' ? '已完成' : '进行中' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -227,6 +274,10 @@ const nextCampStartDate = ref('');
|
|||||||
const nextCampDataDays = ref();
|
const nextCampDataDays = ref();
|
||||||
const nextCampRestDays = ref();
|
const nextCampRestDays = ref();
|
||||||
|
|
||||||
|
// 历史营期弹框相关
|
||||||
|
const showHistoryModal = ref(false);
|
||||||
|
const historyPeriods = ref([]);
|
||||||
|
|
||||||
// 获取本地时区的今日日期字符串
|
// 获取本地时区的今日日期字符串
|
||||||
const getTodayString = () => {
|
const getTodayString = () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -334,6 +385,54 @@ const hideTooltip = () => {
|
|||||||
showTooltip.value = false;
|
showTooltip.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 方法:显示历史记录
|
||||||
|
const showHistory = async () => {
|
||||||
|
try {
|
||||||
|
// 加载历史营期数据
|
||||||
|
await loadHistoryPeriods();
|
||||||
|
showHistoryModal.value = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载历史营期数据失败:', error);
|
||||||
|
alert('加载历史营期数据失败,请重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 方法:加载历史营期数据
|
||||||
|
const loadHistoryPeriods = async () => {
|
||||||
|
try {
|
||||||
|
// 这里可以调用API获取历史营期数据
|
||||||
|
// const result = await getHistoryCampPeriods();
|
||||||
|
|
||||||
|
// 模拟历史营期数据
|
||||||
|
historyPeriods.value = [
|
||||||
|
{
|
||||||
|
startDate: '2024-01-15',
|
||||||
|
endDate: '2024-01-28',
|
||||||
|
dataDays: 10,
|
||||||
|
restDays: 4,
|
||||||
|
status: 'completed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
startDate: '2024-02-01',
|
||||||
|
endDate: '2024-02-14',
|
||||||
|
dataDays: 8,
|
||||||
|
restDays: 6,
|
||||||
|
status: 'completed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
startDate: '2024-02-20',
|
||||||
|
endDate: '2024-03-05',
|
||||||
|
dataDays: 12,
|
||||||
|
restDays: 2,
|
||||||
|
status: 'completed'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载历史营期数据失败:', error);
|
||||||
|
historyPeriods.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 方法:保存营期设置
|
// 方法:保存营期设置
|
||||||
const saveCampSettings = async () => {
|
const saveCampSettings = async () => {
|
||||||
if (!campStartDate.value) {
|
if (!campStartDate.value) {
|
||||||
@@ -458,11 +557,26 @@ const isRestDay = (dateStr) => {
|
|||||||
const shouldShowFinishCamp = () => {
|
const shouldShowFinishCamp = () => {
|
||||||
if (isCampFinished.value) return false;
|
if (isCampFinished.value) return false;
|
||||||
|
|
||||||
// 检查是否有营期相关的事件(接数据、课程、休息日等)
|
// 检查是否有营期相关的事件
|
||||||
const campEvents = events.value.filter(event => event.isCampEvent);
|
const campEvents = events.value.filter(event => event.isCampEvent);
|
||||||
|
if (campEvents.length === 0) return false;
|
||||||
|
|
||||||
// 如果有营期事件,就显示结束营期按钮
|
// 获取所有休息日事件
|
||||||
return campEvents.length > 0;
|
const restEvents = events.value.filter(event => event.isCampEvent && event.type === 'rest');
|
||||||
|
if (restEvents.length === 0) return false;
|
||||||
|
|
||||||
|
// 获取当前日期
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// 检查是否所有休息日都已经过完
|
||||||
|
const allRestDaysPassed = restEvents.every(restEvent => {
|
||||||
|
const restDate = new Date(restEvent.date);
|
||||||
|
restDate.setHours(0, 0, 0, 0);
|
||||||
|
return today > restDate; // 当前日期要大于休息日(即休息日已经过完)
|
||||||
|
});
|
||||||
|
|
||||||
|
return allRestDaysPassed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 方法:结束营期
|
// 方法:结束营期
|
||||||
@@ -967,6 +1081,28 @@ onMounted(async () => {
|
|||||||
box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
|
box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 历史按钮 */
|
||||||
|
.history-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: linear-gradient(135deg, #17a2b8, #138496);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-btn:hover {
|
||||||
|
background: linear-gradient(135deg, #138496, #117a8b);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 8px rgba(23, 162, 184, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
/* 弹窗样式 */
|
/* 弹窗样式 */
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -1229,4 +1365,101 @@ onMounted(async () => {
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
|
box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 历史营期弹框样式 */
|
||||||
|
.no-history {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 20px;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-data-icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-history p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-list {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row .label {
|
||||||
|
color: #6c757d;
|
||||||
|
min-width: 100px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row .value {
|
||||||
|
color: #495057;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-status {
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-status.completed {
|
||||||
|
background: linear-gradient(135deg, #28a745, #20c997);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-status.active {
|
||||||
|
background: linear-gradient(135deg, #ffc107, #fd7e14);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -747,7 +747,7 @@ const conversionRateVsAverage = ref({})
|
|||||||
deals: member.deals_this_period || 0,
|
deals: member.deals_this_period || 0,
|
||||||
rank: member.rank || 0
|
rank: member.rank || 0
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => b.deals - a.deals) // 根据成交单数从高到低排序
|
.sort((a, b) => a.rank - b.rank) // 根据排名降序排列(排名数字越大越靠后)
|
||||||
|
|
||||||
// 更新selectedGroup的members数据
|
// 更新selectedGroup的members数据
|
||||||
selectedGroup.value = {
|
selectedGroup.value = {
|
||||||
@@ -893,7 +893,7 @@ const excellentRecord = ref({});
|
|||||||
await CenterUrgentNeedToAddress()
|
await CenterUrgentNeedToAddress()
|
||||||
await CenterConversionRateVsAverage()
|
await CenterConversionRateVsAverage()
|
||||||
await CenterSeniorManagerList()
|
await CenterSeniorManagerList()
|
||||||
// await CentergetGoodRecord()
|
await CentergetGoodRecord()
|
||||||
await CenterGroupList('all')
|
await CenterGroupList('all')
|
||||||
|
|
||||||
console.log('[强制刷新] 所有数据已重新加载')
|
console.log('[强制刷新] 所有数据已重新加载')
|
||||||
@@ -929,7 +929,7 @@ const excellentRecord = ref({});
|
|||||||
await CenterConversionRateVsAverage()
|
await CenterConversionRateVsAverage()
|
||||||
await CenterSeniorManagerList()
|
await CenterSeniorManagerList()
|
||||||
// 获取优秀录音
|
// 获取优秀录音
|
||||||
// await CentergetGoodRecord()
|
await CentergetGoodRecord()
|
||||||
await CenterGroupList('all') // 初始化加载全部高级经理数据
|
await CenterGroupList('all') // 初始化加载全部高级经理数据
|
||||||
|
|
||||||
// 输出缓存信息
|
// 输出缓存信息
|
||||||
|
|||||||
Reference in New Issue
Block a user