小程序实现下班倒计时和薪资计算的功能

实现效果如下图,写了定时器。

这是可以进行一些设置,基础版本,都是正常班,没有考虑夜班。如果有需要的话可以自行实现。

 

 样式也可以自行调整,内容样式有参考小程序  加油摸鱼侠。

小程序体验

代码如下,我使用的是uniapp,技术有限,没有思考太多,觉得代码冗余的可以自行在加以封装,样式可自行修改。可能会有bug,如果遇到的话可以私信,看到的话会进行修复和完善。

显示页面 

<template>
	<view class="pageHome">
		<view class="offDuty">
			<p>距离{{text}}还剩 </p>
			<text class="offDutyTime">{{offDutyTime}}</text>
		</view>
		<view class="todayPay">
			<p>今日生活费到账</p>
			<span class="pay animate__animated animate__flash">{{ salary.toFixed(2) }}</span>
			<button @click="goEdit" class="edit">设置</button>

		</view>
	</view>
</template>

<script>
	import {
		getTimestamp,
		formatTime
	} from "@/utils/pay.js"
	export default {
		data() {
			return {
				salary: 10.2175,
				increase: 0,
				settledWages: 0,
				dataFrom: null,
				remainSeconds: 0,
				offDutyTime: 0,
				text:'下班',
				timer:null
			};
		},
		onLoad(options) {
			// this.toDayPay()
			if (uni.getStorageSync('pay')) {
				this.dataFrom = uni.getStorageSync('pay')
			}
		},
		onShow() {
			this.dataFrom = uni.getStorageSync('pay')
			this.initData()
		},
		mounted() {
				this.initData()
		},
		methods: {
			// 倒计时函数
			updateCountdown(endTime) {
				// 获取当前时间
				const now = new Date();
				// 构造指定时间点
				const [hour, minute] = endTime.split(':'); // 将时间字符串按冒号分隔成时和分两个数字
				const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0);
				// 计算剩余时间(单位:毫秒)
				let timeDiff = targetTime.getTime() - now.getTime();
				this.remainSeconds = Math.floor(timeDiff / 1000); // 将剩余时间转换为秒数
				this.offDutyTime = formatTime(this.remainSeconds)
			},

			goEdit() {
				uni.navigateTo({
					url: '/pages/luckydraw/index'
				})
			},
			// 当前时间到开始上班时间过了多少秒
			getSecondsByTime(hour, minute, second) {
				// 获取当前时间戳
				const now = new Date();
				const timestamp = now.getTime();
				// 获取今天的指定时间的时间戳
				const year = now.getFullYear();
				const month = now.getMonth() + 1;
				const day = now.getDate();
				const target = new Date(year, month - 1, day, hour, minute, second);
				const targetTimestamp = target.getTime();
				// 计算已经过了多少秒
				const seconds = Math.floor((timestamp - targetTimestamp) / 1000);
				return seconds;
			},
			initData(){
				this.timer = setInterval(()=>{
					this.toDayPay()
				},1000)
			},
			toDayPay() {
				if (this.dataFrom) {
					const timestamp = Date.now() / 1000; // 当前时间秒

					const [hour, minute] = this.dataFrom.startTime.split(':')
					const seconds = this.getSecondsByTime(hour, minute, 0)

					// 上班时间(秒)

					let startTime = getTimestamp(this.dataFrom.startTime)

					let endTime = getTimestamp(this.dataFrom.endTime)

					// 午休时间(秒)
					let restStartTime = getTimestamp(this.dataFrom.restStartTime)

					let restEndTime = getTimestamp(this.dataFrom.restEndTime)

					// 每天上班总时长(秒)
					let workTime = endTime - startTime

					// 每天休息时长(秒)
					let restTime = restEndTime - restStartTime

					// 每秒所得工资
					this.increase = this.dataFrom.monthlyPay / this.dataFrom.monthlyWork / (workTime - restTime)

					let settledWages = 0;
					
					
					if(timestamp<startTime){


						this.text = '上班'
						this.updateCountdown(this.dataFrom.startTime)

						return
					}else if(timestamp>endTime){

						this.text = '下班'
						this.offDutyTime = 0
							return
					}else{
						if(timestamp>restStartTime && timestamp<restEndTime){

							this.text = '午休结束'
							this.updateCountdown(this.dataFrom.restEndTime)
							
						}else if(timestamp<restStartTime){
							settledWages = this.increase * seconds
							this.text = '午休'
							this.updateCountdown(this.dataFrom.restStartTime)
							this.salary = settledWages
							this.salary += this.increase;
						}else{
							settledWages = this.increase * seconds - restTime * this.increase
								this.updateCountdown(this.dataFrom.endTime)
								this.salary = settledWages
								this.salary += this.increase;
						}
					}
				}
			},
		},
		destroyed() {
			clearInterval(this.timer)
		}
	}
</script>

<style lang="less">
	.pageHome {
		text-align: center;

		.todayPay {
			position: relative;
			margin: 0 auto;
			width: 90vw;
			height: 26vh;
			background-color: #ff0000;
			text-align: center;
			border-radius: 1rem;
			font-size: 32rpx;
			color: orange;

			.pay {
				color: white;
				font-size: 60rpx
			}

			.edit {
				position: absolute;
				left: 1rem;
				bottom: 1rem;
				width: 20vw;
			}
		}

		.offDuty {
			width: 100vw;
			height: 10vh;
			background-color: red;
			border-radius: 0 0 5rem 5rem;
			color: white;
			font-size: 24rpx;

			.offDutyTime {
				font-size: 48rpx
			}
		}


	}
</style>

抽取出来封装的方法  getTimestamp是传入一个时间,然后将其转换成秒。

formatTime是传入秒,返回的是一个时间格式的字符串

export function getTimestamp(timeStr) {
	const today = new Date()
	const timestamp = Date.now(); // 当前时间戳
	const time = timeStr.split(':')
	const targetTime = new Date(today.getFullYear(), today.getMonth(), today.getDate(), time[0], time[1])
	return Math.floor(targetTime.getTime() / 1000)
}
export function formatTime(seconds) {
  const hours = Math.floor(seconds / 3600); // 计算小时数
  const minutes = Math.floor((seconds % 3600) / 60); // 计算分钟数
  const secondsLeft = seconds % 60; // 计算剩余秒数
  
  const paddedHours = String(hours).padStart(2, '0'); // 将小时数补0为两位数
  const paddedMinutes = String(minutes).padStart(2, '0'); // 将分钟数补0为两位数
  const paddedSeconds = String(secondsLeft).padStart(2, '0'); // 将剩余秒数补0为两位数
  
  return `${paddedHours}:${paddedMinutes}:${paddedSeconds}`; // 返回时间格式字符串
}

 设置页面内容

<template>
	<view class="luckyDraw">
		<view class="edit">
			<form @submit="formSubmit">
				<text class="title">设置薪资</text>
				<view class="editContent">
					<view class="uni-list-cell">
						<view class="uni-list-cell-left">
							上下班时间
						</view>
						<view class="uni-list-cell-db">
							<picker mode="time" :value="dataFrom.startTime" @change="bindStartTimeChange"
								name="startTime">
								<view class="uni-input">{{dataFrom.startTime}}</view>
							</picker>
							<p class="timeStyle">~</p>
							<picker mode="time" :value="dataFrom.endTime" @change="bindEndTimeChange" name="endTime">
								<view class="uni-input">{{dataFrom.endTime}}</view>
							</picker>
						</view>
					</view>
				</view>
				<view class="editContent">
					<view class="uni-list-cell">
						<view class="uni-list-cell-left">
							午休时间
						</view>
						<view class="uni-list-cell-db">
							<picker mode="time" :value="dataFrom.restStartTime" @change="restStartTimeChange"
								name="restStartTime">
								<view class="uni-input">{{dataFrom.restStartTime}}</view>
							</picker>
							<p class="timeStyle">~</p>
							<picker mode="time" :value="dataFrom.restEndTime" @change="restEndTimeChange"
								name="restEndTime">
								<view class="uni-input">{{dataFrom.restEndTime}}</view>
							</picker>
						</view>
					</view>
				</view>
				<view class="editContent">
					<p>平均月薪</p> <input type="default" :value="dataFrom.monthlyPay" name="monthlyPay">
				</view>
				<view class="editContent">
					<p>月工作天数</p><input type="default" :value="dataFrom.monthlyWork" name="monthlyWork">
				</view>
				<p class="attention">注:秒薪=平均月薪/月工作天数/(上班时长-午休时长)</p>
				<view class="editContent">
					<button @click="cancel">取消</button>
					<button form-type="submit">确定</button>
				</view>
			</form>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				dataFrom: {
					monthlyPay: 3000,
					monthlyWork: 22,
					startTime: '08:30',
					endTime: '18:30',
					restStartTime: '12:00',
					restEndTime: '13:30'
				},
			};
		},
		onLoad() {
			if (uni.getStorageSync('pay')) {
				this.dataFrom = uni.getStorageSync('pay')
			}
		},
		methods: {

			bindStartTimeChange: function(e) {
				this.dataFrom.startTime = e.detail.value
			},
			bindEndTimeChange: function(e) {
				this.dataFrom.endTime = e.detail.value
			},
			restStartTimeChange: function(e) {
				this.dataFrom.restStartTime = e.detail.value
			},
			restEndTimeChange: function(e) {
				this.dataFrom.restEndTime = e.detail.value
			},
			cancel(){
					uni.navigateBack()
			},
			formSubmit(e) {
				this.dataFrom = e.detail.value
				uni.setStorageSync('pay', this.dataFrom)
				uni.navigateBack()
			},

		},
	};
</script>

<style lang="less">
	.edit {
		margin: 1rem auto;
		width: 90vw;
		height: 44vh;
		background-color: rgb(250, 213, 86);
		border-radius: 1rem;
		color: black;
		text-align: center;

		.title {
			font-weight: bold;
			font-size: 48rpx;

		}

		.uni-list-cell {
			width: 100%;
			display: flex;
			justify-content: space-between;

			.uni-list-cell-db {
				display: flex;

				.timeStyle {
					padding: 0 .2rem;
				}

				.uni-input {
					width: 20vw;
					height: 5vh;
					line-height: 5vh;
					background-color: white;
					border-radius: .5rem;
				}
			}
		}

		.editContent {
			display: flex;
			justify-content: space-between;
			margin: 1rem;

			input {
				width: 30vw;
				height: 5vh;
				background-color: white;
				border-radius: .5rem;
			}
		}
	}

	.attention {
		font-size: 24rpx
	}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值