需求
已知数据
不同阶段的完成时间点(这里以三个阶段举例,依次为备货阶段,装配阶段,测试阶段)
计划的开始结束时间
要求实现功能
将当前日期处于哪个阶段用进度条展示出来
不同的阶段用不同的背景色显示
如果当前日期小于阶段计划完成时间点,需要将未完成时间点标记出来
最终效果图
核心思路
- 天数计算
- linear-gradient的应用:实现不同计划阶段不同颜色,及阶段时间点标记
代码实现
下面代码以vue为例
<template><div class="progress-div"><div class="step-total":style="{ background: getRule(record, 'style') }"></div><span>{{getRule(record,'percent')}}</span><span>{{getRule(record,'text')}}</span></div></template><script>data(){record:{//这里的时间顺序一定是 计划开始时间<=备货截止日期<=装配截止日期<=测试截止日期<=计划结束时间beginTime:'2024-04-01',endTime:'2024-05-14',//备货截止日期stockEndTime:'2024-04-08',//装配截止日期assembleEndTime:'2024-04-27',//测试截止日期testEndTime:'2024-05-14'}},methods:{//工具方法用于计算两个日期天数差getDaysBetween(date1, date2){const startDate = Date.parse(date1)const endDate = Date.parse(date2)if(startDate > endDate){return0}if(startDate == endDate){return1}const days =parseInt((endDate - startDate)/(24*60*60*1000))return days
},//通过style动态绑定更改背景色,这里还获取了百分比和当前状态文字,也可以不用switch直接返回一个对象getRule(record, label){let bg =''let text ='未开始'//总天数const days =this.getDaysBetween(record.beginTime, record.endTime)//备货天数const stockDays =this.getDaysBetween(record.beginTime, record.stockEndTime)//备货占比const stockRate =parseInt((stockDays / days)*100)//装配天数const assembleDays =this.getDaysBetween(record.beginTime, record.assembleEndTime)//装备占比const assembleRate =parseInt((assembleDays / days)*100)//测试天数const testDays =this.getDaysBetween(record.beginTime, record.testEndTime)//测试占比const testRate =parseInt((testDays / days)*100)//当前过去几天const currentDays =this.getDaysBetween(record.beginTime,newDate().toISOString().slice(0,10).replace(/-/g,'-'))//当天占比const currentRate =parseInt((currentDays / days)*100)//全部完成if(currentDays >= testDays){
text ='已完成'
bg =`linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${assembleRate}%,#528135 ${assembleRate}%, #528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`}//测试中if(currentDays < testDays && currentDays >= assembleDays){
text ='测试中'
bg =`linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${assembleRate}%,#528135 ${assembleRate}%, #528135 ${currentRate}%,#ddd ${currentRate}%,#ddd ${
testRate -0.5}%,#528135 ${testRate -0.5}%,#528135 ${testRate}%,#ddd ${currentRate}%,#ddd 100%)`}//装配中if(currentDays < assembleDays && currentDays >= stockDays){
text ='装配中'
bg =`linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${currentRate}%,#ddd ${currentRate}%,#ddd ${
assembleRate -0.5}%,#a8d08d ${assembleRate -0.5}%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${
testRate -0.5}%,#528135 ${testRate -0.5}%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`}//备货中if(currentDays < stockDays && currentDays >0){
text ='备货中'
bg =`linear-gradient(to right, #e1eed9 0%, #e1eed9 ${currentRate}%,#ddd ${currentRate}%,#ddd ${
stockRate -0.5}%,#e1eed9 ${stockRate -0.5}%,#e1eed9 ${stockRate}%,#ddd ${stockRate}%,#ddd ${assembleRate -0.5}%,#a8d08d ${
assembleRate -0.5}%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${testRate -0.5}%,#528135 ${
testRate -0.5}%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`}//未开始if(currentDays ==0){
bg =`linear-gradient(to right, #ddd 0%, #ddd ${stockRate -0.5}%,#e1eed9 ${
stockRate -0.5}%,#e1eed9 ${stockRate}%,#ddd ${stockRate}%,#ddd ${assembleRate -0.5}%,#a8d08d ${
assembleRate -0.5}%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${testRate -0.5}%,#528135 ${
testRate -0.5}%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`}switch(label){case'style':return bg
case'text':return text
case'percent':returnparseInt((currentDays / days)*100)+'%'}}<script><style lang="css">.progress-div {display: flex;
align-items: center;width:100%;
justify-content: space-between;}.step-total {width: 200px;
border-radius: 10px;height: 10px;}</style>
版权归原作者 阿莫桑 所有, 如有侵权,请联系我们删除。