123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // 商品价格计算相关
- import { times, plus, minus, divide } from 'number-precision'
- // 价格格式化
- export function formatPrice(value, needSymbol = true) {
- // 不能在最后一步显示之前格式化999 111, 否则可能出现单价1买999个得到999价格被格式化成poa的情况
- if (value === 0) {
- return needSymbol ? '£0.00' : '0.00'
- } else {
- return needSymbol ? `£${value}` : `${value}`
- }
- }
- // 简单的乘法换算
- function multiply(value, ratio = 100) {
- return parseFloat((value * ratio).toPrecision(12))
- }
- // 小数处理, 四舍五入, 为toFixed做准备
- export function round(number, ratio = 100) {
- return Math.round(multiply(number, ratio)) / ratio
- }
- /**
- * 将字符串简单转换成数字, 并可数倍转换. 注意, 这个适用于整数倍(商品件数), 非整数的不能用这个处理小数.
- * @param {*} value 目标值
- * @param {*} ratio 倍数, 默认1
- * @returns number | origin, 转换后的数字, 无法转成数字的返回原值
- */
- export function transformNumber(value, ratio = 1) {
- const v = Number(value)
- if (Number.isNaN(v)) {
- return value
- } else {
- // 保留两位小数
- return divide(Math.trunc(times(times(v, ratio), 100)), 100)
- }
- }
- // unit 单个商品的, 没有乘数量. 因为含有111 999 这些极端值, 没有格式化输出之前直接乘回出问题的.
- export const getUnit = function (buyNum, index, attributeList, basePriceList) {
- // 算出购买数量位于 价格阶梯的 哪个区间
- const candidate = Object.entries(attributeList).filter(
- item => buyNum >= item[1]
- )
- let key = 'website_qty1'
- if (candidate.length) {
- key = candidate.pop()[0]
- }
- return transformNumber(basePriceList[index][key], buyNum)
- }
- // 打印和附加价格 的steup之和. 商品基础价格现在没有setup了.
- export const getSetup = function (buyNum, form, additionList) {
- const sum = Object.entries(form).reduce((total, current) => {
- let s = 0
- // 打印服务表单的数据跟附加服务表单的数据结构不一致, 以数字id字符串键名的是打印服务的数据
- if (/\d+/.test(current[0]) && current[1].enable) {
- const temp = current[1].colorForm.filter(
- i => i.id === current[1].printService
- )
- let colorNumber = 1
- if (temp.length) {
- colorNumber = temp[0].colorNumber
- }
- const decoration = current[1].decorationList.filter(
- i => i.id === current[1].printService
- )
- let setup = 0
- if (decoration.length) {
- setup = plus(
- Number(decoration[0].website_setup),
- times(Number(decoration[0].supplier_setup), colorNumber - 1)
- )
- }
- s = plus(s, setup)
- } else if (current[1].length) {
- // 附加服务的表单数据, 有值说明该项有选中了附加服务
- const addition = additionList[current[0]].filter(addition =>
- current[1].includes(addition.id)
- )
- if (addition.length) {
- const temp = addition.reduce((t, c) => {
- let value = Number(c.website_setup)
- if ([5, 6].includes(c.website_setup_id)) {
- // 5是poa, 6是waived. 这种情况一般setup是留空的, 不留空大概是异常数据, 重置0保险一点.
- value = 0
- }
- return plus(t, Number.isNaN(value) ? 0 : value)
- }, 0)
- s = plus(s, temp)
- }
- }
- total = plus(total, s)
- return total
- }, 0)
- return transformNumber(sum)
- }
- // 打印价格的 阶梯基础价*购买数量.
- export const getPrint = function (buyNum, form, attributeList) {
- // 算出购买数量位于 价格阶梯的 哪个区间
- const candidate = Object.entries(attributeList).filter(
- item => buyNum >= item[1]
- )
- const key = `website_qty${candidate.length}`
- const key2 = `supplier_qty${candidate.length}`
- // 如果其中一项为POA, 则‘和’都是POA
- const result = Object.entries(form).reduce((total, current) => {
- if (total === 'POA') {
- return total
- }
- let sum = 0
- if (/\d+/.test(current[0]) && current[1].enable) {
- const temp = current[1].colorForm.filter(
- i => i.id === current[1].printService
- )
- let colorNumber = 1
- if (temp.length) {
- colorNumber = temp[0].colorNumber
- }
- const decoration = current[1].decorationList.filter(
- i => i.id === current[1].printService
- )
- // 打印价格的基础价. 其中数字111(代表'-') 和999(代表'POA')
- const p1 = transformNumber(decoration[0][key])
- if (p1 === 999 || p1 === 111 || typeof p1 !== 'number') {
- return 'POA'
- }
- // 打印价格的附加价
- const p2 = transformNumber(decoration[0][key2])
- if (p2 === 999 || p2 === 111 || typeof p2 !== 'number') {
- return 'POA'
- }
- let price = 0
- if (decoration.length) {
- price = plus(p1, times(p2, colorNumber - 1))
- }
- sum = plus(sum, price)
- }
- total = plus(total, sum)
- return total
- }, 0)
- return transformNumber(result, buyNum)
- }
- // 附加服务除了packing之外的总价
- export const getAddon = function (buyNum, form, attributeList, additionList) {
- // 算出购买数量位于 价格阶梯的 哪个区间
- const candidate = Object.entries(attributeList).filter(
- item => buyNum >= item[1]
- )
- const key = `website_qty${candidate.length}`
- const result = Object.entries(form).reduce((total, current) => {
- if (total === 'POA') {
- return total
- }
- let sum = 0
- if (!/\d+/.test(current[0]) && current[0] !== 'packaging') {
- sum = additionList[current[0]]
- .filter(item => current[1].includes(item.id))
- .reduce((t, c) => {
- if (t === 'POA') {
- return t
- }
- let temp = transformNumber(c[key])
- if (temp === 999 || temp === 111 || typeof temp !== 'number') {
- temp = 0
- return 'POA'
- }
- t = plus(t, temp)
- return t
- }, 0)
- }
- return plus(total, sum)
- }, 0)
- return transformNumber(result, buyNum)
- }
- // 附加服务中 packing 的价格
- export const getPackaging = function (
- buyNum,
- form,
- attributeList,
- additionList
- ) {
- // 算出购买数量位于 价格阶梯的 哪个区间
- const candidate = Object.entries(attributeList).filter(
- item => buyNum >= item[1]
- )
- const key = `website_qty${candidate.length}`
- const result = Object.entries(form).reduce((total, current) => {
- if (total === 'POA') {
- return total
- }
- let sum = 0
- if (!/\d+/.test(current[0]) && current[0] === 'packaging') {
- sum = additionList[current[0]]
- .filter(item => current[1].includes(item.id))
- .reduce((t, c) => {
- if (t === 'POA') {
- return t
- }
- let temp = transformNumber(c[key])
- if (temp === 999 || temp === 111 || typeof temp !== 'number') {
- temp = 0
- return 'POA'
- }
- t = plus(t, temp)
- return t
- }, 0)
- }
- return plus(total, sum)
- }, 0)
- return transformNumber(result, buyNum)
- }
- // 运费计算. 从product页面抄过来的逻辑. +号是隐式类型转换
- export const getFright = function (buyNum, config, freight, weight, ratio = 1) {
- // 单独批次数量的总重
- const totalWeight = Math.ceil(times(+weight.unit_w_local, buyNum))
- const expressFactor = plus(
- 1,
- divide(plus(+config.express_freight, +config.fuel), 100)
- )
- const AAEFactor = plus(
- 1,
- divide(plus(+config.bag_freight, +config.fuel), 100)
- )
- let frightCost = 0
- if (freight.type === 1) {
- if (totalWeight > 20) {
- const a1 = minus(totalWeight, 20)
- const a2 = times(a1, +freight.basic)
- const a3 = plus(+freight.pickup, a2)
- frightCost = times(a3, expressFactor)
- } else {
- frightCost = times(+freight.pickup, expressFactor)
- }
- } else if (freight.type === 2) {
- const a1 = times(totalWeight, +freight.basic)
- const a2 = plus(+freight.pickup, a1)
- frightCost = times(a2, AAEFactor)
- } else {
- frightCost = 0
- }
- return transformNumber(frightCost, ratio)
- }
|