请假 巡检
Some checks failed
Uniapp 自动化打包 CI/CD / 打包 Uniapp 项目 (push) Has been cancelled

This commit is contained in:
2025-09-12 09:24:59 +08:00
parent 9ed827a227
commit 57fe929080
14 changed files with 973 additions and 499 deletions

View File

@@ -1,12 +1,12 @@
<template>
<view class="calendar-container">
<!-- 展开/收起按钮可以外部隐藏 -->
<view class="calendar-header">
<!-- <view class="calendar-header">
<button size="mini" @click="toggleMode">
{{ mode === 'month' ? '收起为周' : '展开为月' }}
</button>
<text>{{ displayTitle }}</text>
</view>
</view> -->
<view
class="calendar-content"
@@ -46,7 +46,7 @@ export default {
props: {
initialMode: { type: String, default: 'month' }, // 'month' or 'week'
initialDate: { type: String, default: '' },
allowWeekSwitch: { type: Boolean, default: true } // 控制是否允许上下滑切换
allowWeekSwitch: { type: Boolean, default: false } // 控制是否允许上下滑切换
},
data() {
const today = new Date()
@@ -68,8 +68,10 @@ export default {
}
},
watch: {
mode() {
mode(newMode, oldMode) {
this.generateRenderDays()
// 通知父组件mode已改变
this.$emit('modeChange', newMode);
},
selected() {
this.generateRenderDays()
@@ -224,22 +226,34 @@ export default {
else this.slide(-1)
}
},
slide(direction) {
if (this.mode === 'month') {
const y = this.anchorDate.getFullYear()
let m = this.anchorDate.getMonth() + 1 + direction
let year = y
if (m > 12) { m = 1; year++ }
if (m < 1) { m = 12; year-- }
this.anchorDate = new Date(year, m - 1, 1)
} else {
const d = this.safeDate(this.selected)
d.setDate(d.getDate() + direction * 7)
this.selected = this.formatDate(d)
this.anchorDate = this.startOfWeek(d)
}
this.generateRenderDays()
}
slide(direction) {
if (this.mode === 'month') {
const y = this.anchorDate.getFullYear()
let m = this.anchorDate.getMonth() + 1 + direction
let year = y
if (m > 12) { m = 1; year++ }
if (m < 1) { m = 12; year-- }
// 切换后的基准日期设为该月1号
this.anchorDate = new Date(year, m - 1, 1)
this.selected = this.formatDate(this.anchorDate) // ✅ 选中当月1号
this.$emit('dateChange', this.selected)
} else {
// 以当前 anchorDate 为基准移动周
const d = this.safeDate(this.anchorDate)
d.setDate(d.getDate() + direction * 7)
// 更新基准周
this.anchorDate = this.startOfWeek(d)
// ✅ 选中该周周日startOfWeek返回的就是周日
this.selected = this.formatDate(this.anchorDate)
this.$emit('dateChange', this.selected)
}
this.generateRenderDays()
}
}
}
</script>
@@ -249,7 +263,7 @@ export default {
width: 100%;
background: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 16rpx #eee;
/* box-shadow: 0 2rpx 16rpx #eee; */
padding: 12rpx;
}
.calendar-header {

View File

@@ -0,0 +1,140 @@
<template>
<view>
<view v-if="visible" class="mask" @click="close"></view>
<!-- 底部弹窗 -->
<view class="popup" v-if="visible">
<!-- 弹窗标题 -->
<view class="dialog-title">选择时间</view>
<!-- 日期显示区域 -->
<view class="date-display">
{{ selectedDate }}
</view>
<!-- 日历组件 -->
<view class="calendar-wrapper">
<CommonCalendar :initial-date="selectedDate" @dateChange="handleDateSelected" />
</view>
<!-- 确认按钮 -->
<view class="confirm-btn" @click="confirmSelection">
确认
</view>
</view>
</view>
</template>
<script>
import CommonCalendar from '@/components/CommonCalendar.vue'
export default {
components: {
CommonCalendar
},
name: "SelectCalendarDialog",
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
selectedDate: this.getCurrentDate(), // 默认选中的日期
showCalendar: true // 控制日历是否显示
};
},
methods: {
close() {
this.$emit('update:visible', false);
},
// 获取当前日期
getCurrentDate() {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
// 处理日期选择
handleDateSelected(date) {
this.selectedDate = date;
// 不再需要手动关闭日历,因为日历会一直显示在弹窗中
},
// 确认选择
confirmSelection() {
this.$emit('confirm', this.selectedDate);
this.close()
}
}
};
</script>
<style scoped>
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 998;
}
.popup {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
max-height: 80%;
background: #fff;
border-radius: 24rpx 24rpx 0 0;
overflow: hidden;
display: flex;
flex-direction: column;
z-index: 999;
animation: slideUp 0.3s ease;
}
.dialog-title {
font-size: 36rpx;
color: #333;
margin-bottom: 20rpx;
margin-top: 45rpx;
text-align: center;
}
.date-display {
width: 100%;
height: 73rpx;
line-height: 73rpx;
text-align: start;
background: #EBF5FF;
border-radius: 10rpx;
font-size: 28rpx;
color: #0B0B0B;
margin-bottom: 6rpx;
margin-left: 35rpx;
margin-right: 35rpx;
padding-left: 35rpx;
}
.calendar-wrapper {
width: 100%;
margin-bottom: 89rpx;
}
.confirm-btn {
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #0090FF;
color: white;
border-radius: 44rpx;
font-size: 36rpx;
margin-left: 65rpx;
margin-right: 65rpx;
margin-bottom: 40rpx;
}
</style>

115
components/punchInfo.vue Normal file
View File

@@ -0,0 +1,115 @@
<template>
<!-- 上班 -->
<view class="timeline-item">
<view class="timeline-dot"></view>
<view class="timeline-content">
<text class="timeline-label">应上班 09:00</text>
<view class="clock-card late">
<text class="clock-text">已打卡 08:48:32</text>
<text class="status orange">迟到</text>
<text class="buka" @click="goBuka">申请补卡</text>
<view class="location">
<text class="icon">📍</text>
<text class="loc-text">某综合服务中心1栋</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
props:{
info:{}
},
methods:{
goBuka(){
uni.navigateTo({
url: '/pages/sys/user/myRecord/cardReplacement'
});
}
}
}
</script>
<style>
.timeline-item {
position: relative;
padding-left: 20rpx;
margin-left: 60rpx;
margin-right: 90rpx;
margin-bottom: 40rpx;
border-left: 2rpx solid #e0e0e0; /* 竖线 */
}
.timeline-item:last-child {
margin-bottom: 0;
}
.timeline-dot {
position: absolute;
left: -10rpx;
top: -10rpx;
width: 16rpx;
height: 16rpx;
background-color: #666;
border-radius: 50%;
}
.timeline-content {
margin-left: 20rpx;
}
.timeline-label {
font-size: 28rpx;
color: #737373;
}
/* 打卡卡片 */
.clock-card {
background: #fff;
border-radius: 12rpx;
padding: 24rpx;
margin-top: 23rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}
.clock-text {
font-size: 34rpx;
color: #000000;
font-weight: 500;
}
.status {
margin-left: 20rpx;
font-size: 28rpx;
}
.status.orange {
color: #ff6b35;
}
.buka {
margin-left: 20rpx;
font-size: 28rpx;
color: #3370FF;
}
/* 地点 */
.location {
display: flex;
align-items: center;
margin-top: 12rpx;
}
.icon {
margin-right: 6rpx;
}
.loc-text {
font-size: 28rpx;
color: #1C9BFF;
}
</style>