const BigNumber = require('bignumber.js'); exports.getPackageData = function (data, rest = {}) { return { ...rest, name: data.name.trim(), cateId: typeof data.cateId === 'string' ? data.cateId : '', desc: typeof data.desc === 'string' ? data.desc.trim() : '', hasValidDays: typeof data.hasValidDays === 'boolean' ? data.hasValidDays : false, validDays: typeof data.validDays === 'number' ? data.validDays : 0, enableDiscount: typeof data.enableDiscount === 'boolean' ? data.enableDiscount : false, minDiscount: typeof data.minDiscount === 'number' ? data.minDiscount : 10, packageType: data.packageType, packagePrice: data.packagePrice, projectNumber: data.projectNumber, projects: data.projects.map(i => ({ _id: i._id, projectName: i.projectName, projectCateId: i.projectCateId, price: i.price, number: i.number, discount: i.discount, required: i.required })) } } exports.verifyPakcage = function (data) { if (typeof data.name !== 'string' || data.name.trim() === '') { return '套餐名称不能为空' } if (data.name.trim().length > 50) { return '套餐名称不能超过50个字符' } if (data.desc && typeof data.desc !== 'string') { return '套餐描述必须是字符串' } if (typeof data.desc === 'string' && data.desc.trim().length > 500) { return '套餐描述不能超过500个字符' } if (typeof data.hasValidDays !== 'boolean') { return '是否有有效期设置不正确' } if (data.hasValidDays && (typeof data.validDays !== 'number' || !(data.validDays > 0)) || data.validDays % 1 !== 0) { return '有效天数无效' } if (typeof data.enableDiscount !== 'boolean') { return '启用折扣设置不正确' } if (data.enableDiscount && (typeof data.minDiscount !== 'number' || !(data.minDiscount > 0 && data.minDiscount <= 10))) { return '最小折扣无效' } if (typeof data.cateId !== 'string' || data.cateId.trim() === '') { return '套餐分类不能为空' } if (data.enableDiscount && !checkDecimal(data.minDiscount, 2)) { return '最小折扣最多支持2为小数' } if (!['fixed', 'free'].includes(data.packageType)) { return '套餐类型不正确' } if (data.packagePrice === 'free' && (typeof data.packagePrice !== 'number' || !(data.packagePrice > 0))) { return '套餐价格无效' } if (data.packagePrice === 'free' && !checkDecimal(data.packagePrice, 2)) { return '套餐价格最多支持2位小数' } const msg = verifyPackageItems(data.projects, data.packageType); if (msg) return msg; if (typeof data.projectNumber !== 'number' || !(data.projectNumber > 0) || !checkDecimal(data.projectNumber, 0)) { return '套餐项目数量设置不正确' } } function verifyPackageItems(projects, packageType) { if (!Array.isArray(projects) || projects.length === 0) { return '套餐项目不能为空' } if (packageType === 'fixed' && projects.some(i => !(i._id && typeof i.projectName === 'string' && i.projectName.trim() !== '' && i.price && i.number && i.discount))) return '套餐项目信息不完整' for (let project of projects) { const name = project.projectName.trim(); if (typeof project._id !== 'string' || project._id.trim() === '') { return `${name}数据设置不正确` } if (typeof project.price !== 'number' || !(project.price > 0)) { return `${name}价格设置不正确` } // if (checkDecimal(project.price, 2)) { // return `${name}价格最多支持2位小数` // } if (typeof project.number !== 'number' || !(project.number > 0) || !checkDecimal(project.number, 0)) { return `${name} 项目数量设置不正确` } if (packageType === 'fixed') { if (typeof project.discount !== 'number' || !(project.discount > 0 && project.discount <= 10 && checkDecimal(project.discount, 2))) { return `${name} 折扣设置不正确` } } if (typeof project.required !== 'boolean') { return `${name} 是否必选设置不正确` } } } /** * 计算项目套餐价格 */ exports.getPackageListWithPrice = function (packageList) { if (!Array.isArray(packageList)) return []; return packageList.map(p => { const projectData = Array.isArray(p.packageProjects) ? p.packageProjects : []; const _projects = Array.isArray(p.projects) ? p.projects : []; let allProjectPrice = new BigNumber(0); let count = 0; const projects = _projects.map(i => { const project = projectData.find(j => j._id === i._id); let projectFee = 0 if (p.packageType === 'fixed') { count += 1 const price = project && project.price >= 0 ? Number(project.price) : 0; const discount = i.discount >= 0 ? Number(i.discount) : 10; const number = i.number >= 0 ? Number(i.number) : 1; projectFee = new BigNumber(price).multipliedBy(discount).dividedBy(10).multipliedBy(number).toNumber(); allProjectPrice = allProjectPrice.plus(projectFee); } return { ...i, projectName: project ? project.projectName : i.projectName, price: project ? project.price : i.price, number: i.number, discount: i.discount, projectFee, lowestDiscount: project ? project.lowestDiscount : '', } }) const { packageProjects, ...rest } = p; return { ...rest, projects, count, packagePrice: p.packageType === 'fixed' ? allProjectPrice.toNumber() : p.packagePrice, } }) } function checkDecimal(num, len) { if (typeof num !== 'number' || typeof len !== 'number' || !(len >= 0) || len % 1 !== 0) return false; if (len === 0) return Number.isInteger(num); return parseFloat(num.toFixed(len)) === num }