您的位置 首页 java

Java,商品单位转换,计量单位换算,存储单位转换,单位换算功能

商品单位转换及计量单位换算

进销存系统开发时,商品货物流转会遇到商品计量单位及计量单位的换算,如:输入货物700吨,7000千克。一个厂商的产品一般不大可能既有重量单位又有体积单位,一个电子商务平台,货物来自多个厂商,种类就繁多了。如果平台国际化了,甚至是国家的都会出自己的标准。如何在一个系统中可以方便地兼容各种计量单位呢?这也是在设计之初必须考虑到的事情,会对后面的开发、维护产生重大的影响,不容忽视。

系统开发单位换算的实现的几种方案:

1、个人维护换算标准,缺点:不利于团队开发,如出现修改,维护量就大了。

2、公共类或公共枚举维护换算标准,统一维护换算标准管理,将多人的工作量变成了一个人。缺点:后期系统做大国际化了,需要加入其他的换算标准,就需要修改,不够灵活。

3、数据库中约定规则,这种方案,增加灵活性、可扩展性,甚至添加计量单位和计量单位的换算都不用修改代码,直接在后台添加即可,单位表用于记录全部可能使用的计量单位。

数据库中约定规则,设计表:

随时可以添加计量单位和计量单位之间的换算因子,可以满足大部分需求。

Java单位换算功能

商品的库存单位需求

同一个商品一般情况下有4个级别的单位:一级单位、二级单位、三级单位、四级单位,由小到大为:一级单位 < 二级单位 < 三级单位 < 四级单位。根据上表,单位转换值:上级转下级,下级 = 数量*上级的单位转换值,单位兑换值:下级转上级,从最高级自上而下进行折算。

匹配的模型类建立

 package com.what21.app.service.unit;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class Unit {

    // ID
    private Long id;

    // 商品的ID
    private Long goodsId;

    // 单位名称
    private String unitName;

    // 单位类型:1、一级单位,2、二级单位,3、三级单位 4、四级单位
    private Integer unitType;

    // 是否基础,同级单位可以有多个, 是否基础 0 否 1是
    private Integer unitBasics;

    // 单位转换值
    private Integer unitValue;

    // 单位兑换值
    private BigDecimal unitExchangeRate;

    // 单位规格
    private String unitSpecs;


}  

准备商品的单位

 package com.what21.app.service.unit;

import java.math.BigDecimal;
import java.util.*;

public class UnitConvertService {

    /**
     * @param goodsId
     * @return
     */
    public static List<Unit> getUnitList(Long goodsId) {
        List<Unit> unitList = new ArrayList<>();
        // 一级单位
        Unit unit1 = new Unit();
        unit1.setId(1L);
        unit1.setGoodsId(goodsId);
        unit1.setUnitType(1);
        unit1.setUnitName("克");
        unit1.setUnitBasics(1);
        unit1.setUnitValue(1);
        unit1.setUnitExchangeRate(new BigDecimal(1));
        unit1.setUnitSpecs("1g/克");
        unitList.add(unit1);
        // 二级单位
        Unit unit2 = new Unit();
        unit2.setId(2L);
        unit2.setGoodsId(goodsId);
        unit2.setUnitType(2);
        unit2.setUnitName("包");
        unit2.setUnitBasics(1);
        unit2.setUnitValue(40);
        unit2.setUnitExchangeRate(new BigDecimal(40));
        unit2.setUnitSpecs("40克/包");
        unitList.add(unit2);
        // 三级单位
        Unit unit3 = new Unit();
        unit3.setId(3L);
        unit3.setGoodsId(goodsId);
        unit3.setUnitType(3);
        unit3.setUnitName("盒");
        unit3.setUnitBasics(1);
        unit3.setUnitValue(10);
        unit3.setUnitExchangeRate(new BigDecimal(400));
        unit3.setUnitSpecs("(40g×10包)/盒");
        unitList.add(unit3);
        // 四级单位
        Unit unit4 = new Unit();
        unit4.setId(4L);
        unit4.setGoodsId(goodsId);
        unit4.setUnitType(4);
        unit4.setUnitName("箱");
        unit4.setUnitBasics(1);
        unit4.setUnitValue(20);
        unit4.setUnitExchangeRate(new BigDecimal(8000));
        unit4.setUnitSpecs("(40g×10包)/盒");
        unitList.add(unit4);
        return unitList;
    }

}  

单位向下级/上级单位转换案例

 package com.what21.app.service.unit;

import java.util.LinkedHashMap;
import java.util.List;

public class UnitConvertDemo {

    public static void main(String[] args) {
        // 准备商品
        Long goodsId = 1000L;
        // 准备商品单位列表
        List<Unit> unitList = UnitConvertService.getUnitList(goodsId);
        // 准备商品单位分组(根据类型)
        LinkedHashMap<Integer, Unit> unitMap = UnitConvertTools.toUnitMapWithType(goodsId, unitList);
        System.out.println("unitMap = " + unitMap);
        // 向下级单位转,数量乘以自身属性UnitValue
        int fourLevelNum = 1;
        Unit unit4 = unitMap.get(4);
        int threeLevelNum = fourLevelNum * unit4.getUnitValue();
        Unit unit3 = unitMap.get(3);
        int twoLevelNum = threeLevelNum * unit3.getUnitValue();
        Unit unit2 = unitMap.get(2);
        int oneLevelNum = twoLevelNum * unit2.getUnitValue();
        Unit unit1 = unitMap.get(1);
        System.out.print(fourLevelNum + unit4.getUnitName() + "======" + threeLevelNum + unit3.getUnitName() + "======");
        System.out.print(twoLevelNum + unit2.getUnitName() + "======" + oneLevelNum + unit1.getUnitName());
        System.out.println();  // 1箱======20盒======200包======8000克
        // 向上级单位转,数量除以上级属性UnitValue
        oneLevelNum = 8000;
        twoLevelNum = oneLevelNum / unit2.getUnitValue();
        threeLevelNum = twoLevelNum / unit3.getUnitValue();
        fourLevelNum = threeLevelNum / unit4.getUnitValue();
        System.out.print(oneLevelNum + unit1.getUnitName() + "======" + twoLevelNum + unit2.getUnitName() + "======");
        System.out.print(threeLevelNum + unit3.getUnitName() + "======" + fourLevelNum + unit4.getUnitName());
        System.out.println(); // 8000克======200包======20盒======1箱
    }

}  

常用的工具类实现

实现功能:1、按单位类型分组商品单位;2、计算每个商品单位对应的单位兑换值,按商品单位类型分组返回;3、上级单位类型及上级单位数量转换为最基本的单位的数量;4、上级单位类型及上级单位数量转换为指定的单位的数量;5、商品单位最小单位数量估算/折算成大单位(上级单位),按商品单位类型分组返回Map;6、商品单位最小单位数量估算/折算成大单位(上级单位),返回显示文本。

 package com.what21.app.service.unit;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public final class UnitConvertTools {

    /**
     * 按类型分组返回保证顺序的Map(根据单位类型)
     *
     * @param goodsId
     * @param unitList
     * @return
     */
    public static LinkedHashMap<Integer, Unit> toUnitMapWithType(Long goodsId, List<Unit> unitList) {
        LinkedHashMap<Integer, Unit> unitMap = new LinkedHashMap<>();
        for (Unit unit : unitList) {
            if (goodsId == unit.getGoodsId()) {
                unitMap.put(unit.getUnitType(), unit);
            }
        }
        return unitMap;
    }

    /**
     * 计算每个单位类型对应的的兑换率(根据单位类型)
     *
     * @param unitGroupMap
     * @return
     */
    public static LinkedHashMap<Integer, BigDecimal> toExchangeRateMapWithType(LinkedHashMap<Integer, Unit> unitGroupMap) {
        LinkedHashMap<Integer, BigDecimal> exchangeRateMap = new LinkedHashMap<>();
        for (int unitType = unitGroupMap.size(); unitType >= 1; unitType--) {
            BigDecimal exchangeRate = new BigDecimal(1);
            for (int toUnitType = unitType - 1; toUnitType >= 1; toUnitType--) {
                Unit toUnit = unitGroupMap.get(toUnitType + 1);
                exchangeRate = exchangeRate.multiply(new BigDecimal(toUnit.getUnitValue()));
            }
            exchangeRateMap.put(unitType, exchangeRate);
        }
        return exchangeRateMap;
    }

    /**
     * 根据上级单位类型及单位数量转换为最基本的单位
     *
     * @param goodsId
     * @param unitList
     * @param fromType
     * @param quantity
     * @return
     */
    public static Integer toUnitStandardQuantity(Long goodsId, List<Unit> unitList, int fromType, int quantity) {
        int standardQuantity = 0;
        LinkedHashMap<Integer, Unit> unitGroupMap = toUnitMapWithType(goodsId, unitList);
        for (int unitType = unitGroupMap.size(); unitType >= 1; unitType--) {
            if (unitType == fromType) {
                if (fromType == 1) {
                    standardQuantity = quantity;
                } else {
                    Unit unit = unitGroupMap.get(unitType);
                    for (int toUnitType = unitType - 1; toUnitType >= 1; toUnitType--) {
                        if (standardQuantity == 0) {
                            standardQuantity = unit.getUnitValue() * quantity;
                        } else {
                            standardQuantity = standardQuantity * unit.getUnitValue() * quantity;
                        }
                    }
                }
                break;
            }
        }
        return standardQuantity;
    }

    /**
     * 根据上级单位类型及单位数量转换为最指定的单位
     *
     * @param goodsId
     * @param unitList
     * @param fromType
     * @param quantity
     * @param toType
     * @return
     */
    public static Integer toUnitStandardQuantity(Long goodsId, List<Unit> unitList, int fromType, int quantity, int toType) {
        int standardQuantity = 0;
        LinkedHashMap<Integer, Unit> unitGroupMap = toUnitMapWithType(goodsId, unitList);
        for (int unitType = unitGroupMap.size(); unitType >= 1; unitType--) {
            if (unitType == fromType) {
                if (fromType == 1) {
                    standardQuantity = quantity;
                } else {
                    for (int toUnitType = unitType; toUnitType >= 1; toUnitType--) {
                        Unit unit = unitGroupMap.get(toUnitType);
                        if (unit.getUnitType() == toType) {
                            break;
                        }
                        if (standardQuantity == 0) {
                            standardQuantity = unit.getUnitValue() * quantity;
                        } else {
                            standardQuantity = standardQuantity * unit.getUnitValue() * quantity;
                        }
                    }
                }
                break;
            }
        }
        return standardQuantity;
    }

    /**
     * 最小单位【估算/折算】大单位,按类型分组返回Map
     *
     * @param goodsId
     * @param unitList
     * @param quantity
     * @return
     */
    public static LinkedHashMap<Integer, Integer> toUnitEquivalentQuantityWithType(Long goodsId, List<Unit> unitList, int quantity) {
        LinkedHashMap<Integer, Integer> unitEquivalentQuantity = new LinkedHashMap<>();
        LinkedHashMap<Integer, Unit> unitGroupMap = toUnitMapWithType(goodsId, unitList);
        Map<Integer, BigDecimal> exchangeRateMap = UnitConvertTools.toExchangeRateMapWithType(unitGroupMap);
        for (int unitType = unitGroupMap.size(); unitType >= 1; unitType--) {
            unitEquivalentQuantity.put(unitType, 0);
            BigDecimal exchangeRate = exchangeRateMap.get(unitType);
            if ((quantity % exchangeRate.intValue()) == 0) {
                int number = (quantity / exchangeRate.intValue());
                if (number > 0) {
                    unitEquivalentQuantity.put(unitType, number);
                }
                break;
            } else {
                int number = (quantity / exchangeRate.intValue());
                if (number > 0) {
                    unitEquivalentQuantity.put(unitType, number);
                }
                quantity = quantity % exchangeRate.intValue();
            }
        }
        return unitEquivalentQuantity;
    }

    /**
     * 最小单位【估算/折算】大单位,返回文本
     *
     * @param goodsId====>商品的ID
     * @param unitList====>商品的单位列表
     * @param quantity====>最小单位的数量
     * @return
     */
    public static String toUnitEquivalentQuantityText(Long goodsId, List<Unit> unitList, int quantity) {
        LinkedHashMap<Integer, Unit> unitGroupMap = toUnitMapWithType(goodsId, unitList);
        Map<Integer, BigDecimal> exchangeRateMap = UnitConvertTools.toExchangeRateMapWithType(unitGroupMap);
        StringBuilder stringBuilder = new StringBuilder();
        for (int unitType = unitGroupMap.size(); unitType >= 1; unitType--) {
            Unit computeUnit = unitGroupMap.get(unitType);
            BigDecimal exchangeRate = exchangeRateMap.get(unitType);
            if ((quantity % exchangeRate.intValue()) == 0) {
                int number = (quantity / exchangeRate.intValue());
                if (number > 0) {
                    stringBuilder.append((quantity / exchangeRate.intValue())).append(computeUnit.getUnitName());
                }
                break;
            } else {
                int number = (quantity / exchangeRate.intValue());
                if (number > 0) {
                    stringBuilder.append(number).append(computeUnit.getUnitName());
                }
                quantity = quantity % exchangeRate.intValue();
            }
        }
        return stringBuilder.toString();
    }

}  

常用的工具类实现测试

 package com.what21.app.service.unit;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class UnitConvertToolsTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 准备商品
        Long goodsId = 1000L;
        // 准备商品单位列表
        List<Unit> unitList = UnitConvertService.getUnitList(goodsId);
        // =======================================================================================//
        // >>>>>>>>>>>> 按类型分组返回保证顺序的Map(根据单位类型)
        LinkedHashMap<Integer, Unit> unitGroupMap = UnitConvertTools.toUnitMapWithType(goodsId, unitList);
        System.out.println("按类型分组返回保证顺序的Map(根据单位类型) = " + unitGroupMap);
        // =======================================================================================//
        // >>>>>>>>>>>> 计算每个单位类型对应的的兑换率(根据单位类型)
        Map<Integer, BigDecimal> exchangeRateMap = UnitConvertTools.toExchangeRateMapWithType(unitGroupMap);
        System.out.println("计算每个单位类型对应的的兑换率(根据单位类型)= " + exchangeRateMap);
        //  {4=8000, 3=400, 2=40, 1=1}
        // =======================================================================================//
        // >>>>>>>>>>>> 根据上级单位类型及单位数量转换为最基本的单位
        int fourLevelQuantity = 1;
        int fourLevelTotal = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 4, fourLevelQuantity);
        System.out.println("四级单位转一级单位,1" + unitGroupMap.get(4).getUnitName() + "=" + fourLevelTotal + unitGroupMap.get(1).getUnitName());
        // 四级单位转一级单位,1箱=8000克
        int threeLevelQuantity = 1;
        int threeLevelTotal = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 3, threeLevelQuantity);
        System.out.println("三级单位转一级单位,1" + unitGroupMap.get(3).getUnitName() + "=" + threeLevelTotal + unitGroupMap.get(1).getUnitName());
        // 三级单位转一级单位,1盒=100克
        int twoLevelQuantity = 1;
        int twoLevelTotal = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 2, twoLevelQuantity);
        System.out.println("二级单位转一级单位,1" + unitGroupMap.get(2).getUnitName() + "=" + twoLevelTotal + unitGroupMap.get(1).getUnitName());
        // 二级单位转一级单位,1包=40克
        int oneLevelQuantity = 1;
        int oneLevelTotal = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 1, oneLevelQuantity);
        System.out.println("一级单位转一级单位,1" + unitGroupMap.get(1).getUnitName() + "=" + oneLevelTotal + unitGroupMap.get(1).getUnitName());
        // 一级单位转一级单位,1克=1克
        // =======================================================================================//
        // >>>>>>>>>>>> 根据上级单位类型及单位数量转换为最指定的单位
        int fourLevelQuantity21 = 1;
        int fourLevelTotal21 = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 4, fourLevelQuantity21, 2);
        System.out.println("四级单位转二级单位,1" + unitGroupMap.get(4).getUnitName() + "=" + fourLevelTotal21 + unitGroupMap.get(2).getUnitName());
        // 四级单位转二级单位,1箱=200包
        int fourLevelQuantity22 = 1;
        int fourLevelTotal22 = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 4, fourLevelQuantity22, 3);
        System.out.println("四级单位转三级单位,1" + unitGroupMap.get(4).getUnitName() + "=" + fourLevelTotal22 + unitGroupMap.get(3).getUnitName());
        // 四级单位转三级单位,1箱=20盒
        int threeLevelQuantity21 = 1;
        int threeLevelTotal21 = UnitConvertTools.toUnitStandardQuantity(goodsId, unitList, 3, threeLevelQuantity21, 2);
        System.out.println("三级单位转二级单位,1" + unitGroupMap.get(3).getUnitName() + "=" + threeLevelTotal21 + unitGroupMap.get(2).getUnitName());
        // 三级单位转二级单位,1盒=10包
        // =======================================================================================//
        // >>>>>>>>>>>> 最小单位【估算/折算】大单位,按类型分组返回Map
        int quantity = 8441;
        LinkedHashMap<Integer, Integer> unitEquivalentQuantityMap = UnitConvertTools.toUnitEquivalentQuantityWithType(goodsId, unitList, quantity);
        System.out.println("最小单位【估算/折算】大单位,按类型分组返回Map = " + unitEquivalentQuantityMap);
        // {4=1, 3=1, 2=1, 1=1}
        // =======================================================================================//
        // >>>>>>>>>>>> 最小单位【估算/折算】大单位,返回文本
        int quantity2 = 8441;
        String unitEquivalentQuantity = UnitConvertTools.toUnitEquivalentQuantityText(goodsId, unitList, quantity2);
        System.out.println("计算单位向上折算返回文本 = " + unitEquivalentQuantity);
        // 1箱1盒1包1克
    }

}  

输出内容:

 按类型分组返回保证顺序的Map(根据单位类型) = {1=Unit(id=1, goodsId=1000, unitName=克, unitType=1, unitBasics=1, unitValue=1, unitExchangeRate=1, unitSpecs=1g/克), 2=Unit(id=2, goodsId=1000, unitName=包, unitType=2, unitBasics=1, unitValue=40, unitExchangeRate=40, unitSpecs=40克/包), 3=Unit(id=3, goodsId=1000, unitName=盒, unitType=3, unitBasics=1, unitValue=10, unitExchangeRate=400, unitSpecs=(40g×10包)/盒), 4=Unit(id=4, goodsId=1000, unitName=箱, unitType=4, unitBasics=1, unitValue=20, unitExchangeRate=8000, unitSpecs=(40g×10包)/盒)}
计算每个单位类型对应的的兑换率(根据单位类型)= {4=8000, 3=400, 2=40, 1=1}
四级单位转一级单位,1箱=8000克
三级单位转一级单位,1盒=100克
二级单位转一级单位,1包=40克
一级单位转一级单位,1克=1克
四级单位转二级单位,1箱=200包
四级单位转三级单位,1箱=20盒
三级单位转二级单位,1盒=10包
最小单位【估算/折算】大单位,按类型分组返回Map = {4=1, 3=1, 2=1, 1=1}
计算单位向上折算返回文本 = 1箱1盒1包1克  

文章来源:智云一二三科技

文章标题:Java,商品单位转换,计量单位换算,存储单位转换,单位换算功能

文章地址:https://www.zhihuclub.com/176053.shtml

关于作者: 智云科技

热门文章

网站地图