@@ -21,6 +21,12 @@
< / svg >
结束营期
< / 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" >
< 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" / >
@@ -88,15 +94,6 @@
< / button >
< / div >
< 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" >
< label for = "campDays" > 接数据天数 : < / label >
< input
@@ -197,6 +194,56 @@
< / 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 >
< script setup >
@@ -227,6 +274,10 @@ const nextCampStartDate = ref('');
const nextCampDataDays = ref ( ) ;
const nextCampRestDays = ref ( ) ;
// 历史营期弹框相关
const showHistoryModal = ref ( false ) ;
const historyPeriods = ref ( [ ] ) ;
// 获取本地时区的今日日期字符串
const getTodayString = ( ) => {
const now = new Date ( ) ;
@@ -334,6 +385,54 @@ const hideTooltip = () => {
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 ( ) => {
if ( ! campStartDate . value ) {
@@ -458,11 +557,26 @@ const isRestDay = (dateStr) => {
const shouldShowFinishCamp = ( ) => {
if ( isCampFinished . value ) return false ;
// 检查是否有营期相关的事件(接数据、课程、休息日等)
// 检查是否有营期相关的事件
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 4 px 8 px rgba ( 40 , 167 , 69 , 0.3 ) ;
}
/* 历史按钮 */
. history - btn {
display : flex ;
align - items : center ;
gap : 6 px ;
padding : 8 px 12 px ;
background : linear - gradient ( 135 deg , # 17 a2b8 , # 138496 ) ;
color : white ;
border : none ;
border - radius : 6 px ;
font - size : 14 px ;
font - weight : 500 ;
cursor : pointer ;
transition : all 0.2 s ease ;
}
. history - btn : hover {
background : linear - gradient ( 135 deg , # 138496 , # 117 a8b ) ;
transform : translateY ( - 1 px ) ;
box - shadow : 0 4 px 8 px rgba ( 23 , 162 , 184 , 0.3 ) ;
}
/* 弹窗样式 */
. modal - overlay {
position : fixed ;
@@ -1229,4 +1365,101 @@ onMounted(async () => {
transform : translateY ( - 1 px ) ;
box - shadow : 0 4 px 8 px rgba ( 40 , 167 , 69 , 0.3 ) ;
}
/* 历史营期弹框样式 */
. no - history {
text - align : center ;
padding : 40 px 20 px ;
color : # 6 c757d ;
}
. no - data - icon {
margin - bottom : 16 px ;
opacity : 0.5 ;
}
. no - history p {
margin : 0 ;
font - size : 16 px ;
}
. history - list {
max - height : 400 px ;
overflow - y : auto ;
}
. history - item {
display : flex ;
justify - content : space - between ;
align - items : flex - start ;
padding : 20 px ;
border : 1 px solid # e9ecef ;
border - radius : 8 px ;
margin - bottom : 12 px ;
background : # f8f9fa ;
transition : all 0.2 s ease ;
}
. history - item : hover {
background : # e9ecef ;
transform : translateY ( - 1 px ) ;
box - shadow : 0 2 px 8 px rgba ( 0 , 0 , 0 , 0.1 ) ;
}
. history - item : last - child {
margin - bottom : 0 ;
}
. period - info {
flex : 1 ;
}
. period - title {
font - size : 16 px ;
font - weight : 600 ;
color : # 495057 ;
margin - bottom : 12 px ;
}
. period - details {
display : flex ;
flex - direction : column ;
gap : 6 px ;
}
. detail - row {
display : flex ;
align - items : center ;
font - size : 14 px ;
}
. detail - row . label {
color : # 6 c757d ;
min - width : 100 px ;
font - weight : 500 ;
}
. detail - row . value {
color : # 495057 ;
font - weight : 600 ;
}
. period - status {
padding : 6 px 12 px ;
border - radius : 20 px ;
font - size : 12 px ;
font - weight : 600 ;
text - align : center ;
min - width : 60 px ;
}
. period - status . completed {
background : linear - gradient ( 135 deg , # 28 a745 , # 20 c997 ) ;
color : white ;
}
. period - status . active {
background : linear - gradient ( 135 deg , # ffc107 , # fd7e14 ) ;
color : white ;
}
< / style >