最近做了一个项目中有一个需求:在选择的开始时间和结束时间段内,获取该时间段内的可用面积,并在添加面积的时候判断面积是否够用。这个需求是使用后端接口进行验证的,但过程中出现了很多问题,但当时考虑到需求的复杂性,所以我也没有去做前端验证,项目做完之后现在来思考这个需求应该怎么写。
1. 首先封装一个判断月份返回每月天数的方法
function calculationDays(year, month) {
if (month > 12 || month < 1) {
throw new Error("月份不符合规范")
}
if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
return 31
} else if (month === 4 || month === 6 || month === 9 || month === 11) {
return 30
} else if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
return 29
} else {
return 28
}
}
2. 在封装一个创建对象的方法,将年月日作为对象的键进行保存
// 如2021-01-01到2021-01-03使用面积为20, 对象格式为:
{
2021: {
1: {
1: 20,
2: 20,
3: 20
}
}
}
//时间格式如下:
let starTime1 = '2019-11-25'
let endTime1 = '2021-02-05'
let starTime2 = '2020-01-25'
let endTime2 = '2021-03-05'
function areaAndDateObj(starTime, endTime, area) {
let obj = {}
// 取出需要的年月日
let year1 = Number(starTime.slice(0, 4))
let year2 = Number(endTime.slice(0, 4))
let month1 = Number(starTime.slice(5, 7))
let month2 = Number(endTime.slice(5, 7))
let day1 = Number(starTime.slice(8))
let day2 = Number(endTime.slice(8))
// 判断年份是否相等,执行不同操作
if (year1 === year2) {
obj[year1] = {}
for (let i = month1; i <= month2; i++) {
obj[year2][i] = {}
var monthType = null
monthType = calculationDays(year2, i)
if (i === month2) {
for (let j = 1; j <= day2; j++) {
obj[year2][i][j] = area
}
} else if (i === month1) {
for (let j = day1; j <= monthType; j++) {
obj[year2][i][j] = area
}
} else {
for (let j = 1; j <= monthType; j++) {
obj[year2][i][j] = area
}
}
}
} else {
for (let y = year1; y <= year2; y++) {
obj[y] = {}
let startM, endM, startDay, endDay
if (y === year1) {
startM = month1
endM = 12
} else if (y === year2) {
startM = 1
endM = month2;
} else {
startM = 1
endM = 12;
}
for (let m = startM; m <= endM; m++) {
obj[y][m] = {}
if (y === year1 && m === month1) {
startDay = day1
endDay = calculationDays(y, m)
} else if (y === year2 && m === month2) {
startDay = 1
endDay = day2
} else {
startDay = 1
endDay = calculationDays(y, m)
}
for (let d = startDay; d <= endDay; d++) {
obj[y][m][d] = area
}
}
}
}
return obj
}
将两个这种格式的对象进行合并计算,求出每天的总面积(参数只能传两个对象,所以进行计算的时候只能多次调用,日后在改进)
function merge(obj1, obj2) {
let yKey1 = Object.keys(obj1)
let yKey2 = Object.keys(obj2)
yKey1.forEach(yItem => {
if (yKey2.includes(yItem)) {
let mKey1 = Object.keys(obj1[yItem])
let mKey2 = Object.keys(obj2[yItem])
mKey1.forEach(mItem => {
if (mKey2.includes(mItem)) {
let dKey1 = Object.keys(obj1[yItem][mItem])
let dKey2 = Object.keys(obj2[yItem][mItem])
dKey1.forEach(dItem => {
if (dKey2.includes(dItem)) {
obj2[yItem][mItem][dItem] = obj2[yItem][mItem][dItem] + obj1[yItem][mItem][dItem]
} else {
obj2[yItem][mItem][dItem] = obj1[yItem][mItem][dItem]
}
})
} else {
obj2[yItem][mItem] = obj1[yItem][mItem]
}
})
} else {
obj2[yItem] = obj1[yItem]
}
})
return obj2
}
最后进行比较,面积是否够用
function judgeArea(usedObj, useObj, allArea) {
let flag = true
let yKey1 = Object.keys(usedObj)
let yKey2 = Object.keys(useObj)
try {
yKey2.forEach(yItem => {
if (yKey1.includes(yItem)) {
let mKey1 = Object.keys(usedObj[yItem])
let mKey2 = Object.keys(useObj[yItem])
mKey2.forEach(mItem => {
if (mKey1.includes(mItem)) {
let dKey1 = Object.keys(usedObj[yItem][mItem])
let dKey2 = Object.keys(useObj[yItem][mItem])
dKey1.forEach(dItem => {
if (dKey1.includes(dItem)) {
if (useObj[yItem][mItem][dItem] + usedObj[yItem][mItem][dItem] > allArea) {
console.log(useObj[yItem][mItem][dItem], usedObj[yItem][mItem][dItem])
throw new Error("面积超出总面积!")
}
} else {
if (useObj[yItem][mItem][dItem] > allArea) {
throw new Error("面积超出总面积!")
}
}
})
} else {
let dKey2 = Object.keys(useObj[yItem][mItem])
dKey2.forEach(dItem => {
if (useObj[yItem][mItem][dItem] > allArea) {
throw new Error("面积超出总面积!")
}
})
}
})
} else {
let mKey2 = Object.keys(useObj[yItem])
mKey2.forEach(mItem => {
let dKey2 = Object.keys(useObj[yItem][mItem])
dKey2.forEach(dItem => {
if (useObj[yItem][mItem][dItem] > allArea) {
throw new Error("面积超出总面积!")
}
})
})
}
})
} catch (e) {
console.log(e)
flag = false
}
return flag
}
网友评论