首页 > 编程语言 >java里面使用groovy案例+详解

java里面使用groovy案例+详解

时间:2024-11-11 13:20:08浏览次数:3  
标签:groovy Groovy 运费 Java 编程 rule 详解 java def

场景: 最近有一个计算商品运费的,如果商品的数量大于快递公司设置的数量 10
那么超出部分也需要计算额外运费,那么这些计算过程代码我能不能不在java里面写呢,用一种可配置化的方式来根据不同的传参计算出运费?

页面传参

[{“key”:“起订量(大单位)”,“isRequired”:true,“isNumber”:true},{“key”:“运费(元)”,“isRequired”:true,“isNumber”:true},{“key”:“续件(大单位)”,“isRequired”:false,“isFixed”:true,“value”:“1”},{“key”:“续件费(元)”,“isRequired”:true},{“key”:“订单金额满
¥ 免运费”,“isRequired”:false,“isFixed”:true,“value”:“800”}]

我需要拿到json里面的value值,然后计算运费

groovy介绍

Groovy是一种动态语言,它运行在Java虚拟机(JVM)上,并且与Java语言兼容。以下是Groovy的一些关键特点和优势:

  1. JVM兼容性:Groovy可以无缝地与Java代码集成,允许开发者在同一个项目中混合使用Groovy和Java代码。这意味着任何Java库都可以在Groovy中使用,反之亦然。

  2. 动态类型:Groovy是一种动态类型语言,这意味着变量的类型在运行时确定,而不是在编译时。这使得Groovy代码更加灵活和简洁。

  3. 简洁的语法:Groovy的语法设计得更加简洁和易于阅读,它提供了许多快捷方式来减少代码量,比如省略类型声明、使用GString(Groovy字符串)等。

  4. 元编程:Groovy支持强大的元编程特性,包括Groovy的闭包(类似于Java 8的Lambda表达式)和动态代理,这使得函数式编程和AOP(面向切面编程)更加容易实现。

  5. 构建工具:Groovy被广泛用于构建工具,特别是Apache Maven和Gradle,后者甚至使用Groovy作为其构建脚本的默认语言。

  6. 测试框架:Groovy与Spock框架(一种基于Groovy的测试框架)紧密集成,使得编写测试用例更加简洁和表达力强。

  7. 并发编程:Groovy提供了对并发编程的支持,包括对Java并发API的封装,以及GPars库,后者提供了对并发和并行编程的高级抽象。

  8. Web开发:Groovy支持多种Web开发框架,如Grails(一个基于Groovy的全栈Web应用框架)和Ratpack(一个用于构建现代HTTP应用的工具包)。

  9. 脚本编写:Groovy的简洁性和强大的标准库使其成为编写脚本的理想选择,尤其是在需要与Java系统集成时。

  10. 社区和生态系统:Groovy有一个活跃的社区和不断增长的生态系统,提供了大量的插件和库来扩展其功能。

Groovy的设计哲学是“让事情更简单”,它旨在提供一种更加简洁和愉快的编程体验,同时保持与Java生态系统的兼容性。这使得Groovy在许多领域,尤其是在企业级应用开发中,成为一种受欢迎的选择。

依赖

<!--    groovy    -->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.5.11</version>
            <type>pom</type>
        </dependency>

计算结果数据解析

/**
 * @author sunpeiyang
 * @date 2024/11/6 13:35
 */
@Slf4j
@Component
public class CspGroovyCodeVerification {

    public Map<String, Object> getFreightAmount(Object value) {
        Map<String, Object> resultMap = new HashMap<>();
        // 检查传入的 value 是否为数组
        if (value != null) {
            List<Object> resultList = (List<Object>) value;
            resultMap.put("isFreeFreightAmount", resultList.get(0));
            resultMap.put("freightAmount", resultList.get(1));
        }
        return resultMap;
    }

}

计算结果工具类

@Slf4j
public class CspGroovyUtil {
    private ScriptEngineManager factory = null;

    private ScriptEngine engine = null;

    public CspGroovyUtil() {
        factory = new ScriptEngineManager();
        engine = factory.getEngineByName("groovy");
        engine.getContext().setAttribute("out", new PrintStreamWrapper(), ScriptContext.ENGINE_SCOPE);
    }

    public synchronized Object invoke(String script, String name, Object... args) throws ScriptException, NoSuchMethodException {
        engine.eval(script);
        return ((Invocable) engine).invokeFunction(name, args);
    }

    private static class PrintStreamWrapper {
        public void println(String x) {
            log.info("scriptInfoOut={}", x);
        }
    }

    public Object invokeExtra(String script, String name, Object... args) throws ScriptException, NoSuchMethodException {
        engine.eval(script);
        return ((Invocable) engine).invokeFunction(name, args);
    }
}

运费计算

Map<String, Object> resultMap = resultMap = groovyCodeVerification.getFreightAmount(groovyUtil.invoke("def calculationFormula(rule,orderAmount,goodsNumberTotal){  " + cspQuoteRule.getTemplateCalculationFormulaCode() + "  }", "calculationFormula", unitList, freightQuotationSetDetail.getOrderAmount(), freightQuotationSetDetail.getGoodsNumberTotal()));

计算公式

// 满件数(大单位)
    def fullNum = 0
// 运费(元)
    def freight = 0
// 续件(大单位)
    def continueNum = 0
// 续运费单价(元)
    def continueFreight = 0
// 免运费的条件金额
    def freeFreightAmount = 0
// 获取数组的大小
    def ruleSize = rule.size()
// 运费的结果
    def resultFreightAmount = 0

    if(ruleSize > 0){
        fullNum = rule[0].toInteger()
    }
    if(ruleSize > 1){
        freight = rule[1].toBigDecimal()
    }
    if(ruleSize > 2){
        continueNum = rule[2].toInteger()
    }
    if(ruleSize > 3){
        continueFreight = rule[3].toBigDecimal()
    }
    if(ruleSize > 4){
        freeFreightAmount = rule[4] ? rule[4].toBigDecimal() : BigDecimal.ZERO
    }
    if(goodsNumberTotal <= fullNum){
        resultFreightAmount = freight
    }else if(goodsNumberTotal > fullNum){
        // 商品数量大于满件数(大单位),那么 运费 = freight + continueNumBer*continueFreight;
        def resultGoodsNumberTotal = goodsNumberTotal - fullNum
        if(resultGoodsNumberTotal > 0){
            // 续件(大单位)数量计算,不足一进一
            def continueNumBer = Math.ceil(resultGoodsNumberTotal / continueNum)
            resultFreightAmount = freight + (continueNumBer * continueFreight)
        }
    }
// 如果订单的金额大于门店设置的免运费条件,则免运费
    def orderAmountResult = orderAmount - freeFreightAmount
    if(freeFreightAmount > 0 && orderAmountResult >= 0){
        return [0,resultFreightAmount]
    }else{
        return [1,resultFreightAmount]
    }

简单的案例

在这里插入图片描述

csp_order_freight_expression_debug.groovy

def matchingConditions(rule, orderAmount, goodsNumberTotal) {
    // 满件数(大单位)
    def fullNum = 0
// 运费(元)
    def freight = 0
// 续件(大单位)
    def continueNum = 0
// 续运费单价(元)
    def continueFreight = 0
// 免运费的条件金额
    def freeFreightAmount = 0
// 获取数组的大小
    def ruleSize = rule.size()
// 运费的结果
    def resultFreightAmount = 0

    if(ruleSize > 0){
        fullNum = rule[0].toInteger()
    }
    if(ruleSize > 1){
        freight = rule[1].toBigDecimal()
    }
    if(ruleSize > 2){
        continueNum = rule[2].toInteger()
    }
    if(ruleSize > 3){
        continueFreight = rule[3].toBigDecimal()
    }
    if(ruleSize > 4){
        freeFreightAmount = rule[4] ? rule[4].toBigDecimal() : BigDecimal.ZERO
    }
    if(goodsNumberTotal <= fullNum){
        resultFreightAmount = freight
    }else if(goodsNumberTotal > fullNum){
        // 商品数量大于满件数(大单位),那么 运费 = freight + continueNumBer*continueFreight;
        def resultGoodsNumberTotal = goodsNumberTotal - fullNum
        if(resultGoodsNumberTotal > 0){
            // 续件(大单位)数量计算,不足一进一
            def continueNumBer = Math.ceil(resultGoodsNumberTotal / continueNum)
            resultFreightAmount = freight + (continueNumBer * continueFreight)
        }
    }
// 如果订单的金额大于门店设置的免运费条件,则免运费
    def orderAmountResult = orderAmount - freeFreightAmount
    if(freeFreightAmount > 0 && orderAmountResult >= 0){
        return [0,resultFreightAmount]
    }else{
        return [1,resultFreightAmount]
    }
}

// 销售单商品运费的计算公式
List<String> unitList = ['2', '200', '1', '7', '30']

BigDecimal orderAmount = 30

BigDecimal goodsNumberTotal = 3

matchingConditions(unitList, orderAmount, goodsNumberTotal);

标签:groovy,Groovy,运费,Java,编程,rule,详解,java,def
From: https://blog.csdn.net/weixin_44372802/article/details/143680530

相关文章

  • 20万字208道Java经典面试题总结(附答案)
    1、JDK和JRE有什么区别?JDK(JavaDevelopmentKit),Java开发工具包JRE(JavaRuntime Environment),Java运行环境JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。2、==和 equals 的区别是什么?对于基本类型,==比较的......
  • 2024年最全java面试题(八股文)
    1.Java基础1.1为什么Java代码可以实现一次编写、到处运行?在程序运行前,Java源代码(.java)需要经过编译器编译成字节码(.class)。在程序运行时,JVM负责将字节码翻译成特定平台下的机器码并运行,也就是说,只要在不同的平台上安装对应的JVM,就可以运行字节码文件。1.2一个Java文件里......
  • C++ 数据结构详解
    目录C++数据结构详解引言1.数组(Array)示例代码2.向量(Vector)示例代码3.链表(List)示例代码4.栈(Stack)示例代码5.队列(Queue)示例代码6.集合(Set)示例代码7.映射(Map)示例代码C++数据结构详解引言数据结构是计算机科学中的一个重要概念......
  • Java——接口
    一、接口是什么在Java中,接口(Interface)是一种引用数据类型,类似于类,然而它只能包含常量、方法签名和嵌套类型。接口不能包含实例变量或方法的实现(在Java8及之后的版本,可以在接口中定义默认方法和静态方法)。接口主要用于定义类的外部行为,并允许类实现这些行为。二、接口详细介......
  • JavaScript基础总结
             JavaScript(简称JS)是一个广泛使用的客户端脚本语言,常用于网页开发中。它可以在浏览器中运行,执行交互操作和动态效果。以下是JavaScript基础的所有核心知识点,按主题分类列出。1.基本语法声明变量使用var、let和const来声明变量:varname='Alice';/......
  • JavaScript题目一 根据成绩给出学生考评
            根据学生的成绩给出考评,可以通过if或switch语句来实现。下面是一个简单的JavaScript代码示例,根据学生的成绩返回不同的评语。示例代码:functionevaluateStudent(score){letevaluation;if(score>=90){evaluation='优秀';}else......
  • JavaScript题目二 实现猜数字游戏
    实现一个猜数字游戏的过程,通常包括以下几个步骤:生成一个随机数:计算机随机生成一个目标数字。用户输入猜测:玩家猜测数字并提交。比较用户输入与目标数字:计算机检查玩家的猜测,给出提示(比如“猜小了”或“猜大了”)。循环进行:直到玩家猜对为止,或者达到预设的次数。1.HTML文件(......
  • JavaScript题目三 制作简易计算器
    目标:提供四个基本的运算功能:加、减、乘、除。支持数字输入和运算符输入。显示结果。1.HTML文件(index.html)<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,i......
  • java浅拷贝BeanUtils.copyProperties引发的RPC异常
    作者:京东物流吴义背景近期参与了一个攻坚项目,前期因为其他流程原因,测试时间已经耽搁了好几天了,本以为已经解决了卡点,后续流程应该顺顺利利的,没想到人在地铁上,bug从咚咚来~没有任何修改的服务接口,抛出异常:java.lang.ClassCastException:java.util.HashMapcannotbecastto......
  • IPD项目管理流程详解:大厂实战经验分享
    IPD(IntegratedProductDevelopment)项目管理流程是由跨职能团队协作推动的产品开发模式,广泛应用于高科技行业、制造业以及大企业的产品开发过程中。IPD强调团队成员之间的紧密合作、系统思维和产品开发全生命周期的管理。其核心目标是通过整合各个职能领域的专家,实现高效的产品设......