IDEA 接入通义灵码-DeepSeek-R1

一、通义灵码介绍

通义灵码,是基于通义大模型的 AI 研发辅助工具,提供代码智能生成、研发智能问答、多文件代码修改、自主执行等能力,为开发者带来智能化研发体验,引领 AI 原生研发新范式。

核心能力

  1. 代码智能生成
    经过海量优秀开源代码数据训练,可根据当前代码文件及跨文件的上下文,为你生成行级/函数级代码、单元测试、代码优化建议等。沉浸式编码心流,秒级生成速度,让你更专注在技术设计,高效完成编码工作。

  2. 研发智能问答
    基于海量研发文档、产品文档、通用研发知识、阿里云的云服务文档和 SDK/OpenAPI 文档等进行问答训练,为你答疑解惑,助你轻松解决研发问题。

  3. AI 程序员
    具备多文件代码修改和工具使用的能力,可以与开发者协同完成编码任务,如需求实现、问题解决、单元测试用例生成、批量代码修改等。

二、安装指南

方法 1:从插件市场安装

  1. 打开 IntelliJ IDEA 设置窗口,在插件市场中搜索 TONGYI Lingma,找到通义灵码后单击安装。
  2. 安装完成后,重启 IntelliJ IDEA。


    安装1.png

方法 2:下载安装包安装

  1. 单击下方链接,下载 JetBrains IDEs 的 zip 安装包;

    TONGYI Lingma - JetBrains

  2. 下载完安装包后,打开 IntelliJ IDEA 后,打开设置,在插件管理的设置下拉菜单中单击从本地安装插件,选择下载的 zip 文件后安装。

  3. 安装完成后,重启 IntelliJ IDEA。

安装2.png

登录
单击侧边导航的通义灵码,在通义灵码助手的窗口单击登录按钮,使用支付宝或钉钉扫码登录。

登录1.png

二、使用实践

1.智能补全
当你在 IDE 编辑器区进行代码编写时,在开启自动云端生成的模式下,通义灵码会根据当前代码文件及相关代码文件的上下文,自动为你生成行级/函数级的代码建议,此时你可以使用快捷键采纳、废弃,或查看不同的代码建议,快捷键 Alt + P 。

智能补全.png

2. 基于问题提问
问题1:验证DTO中state是BooleanEnum枚举中的key值;

问题1.png

推理过程:
嗯,用户的问题是关于如何验证state字段是BooleanEnum枚举中的key。首先,我需要看一下用户提供的代码片段。他们有一个TctBuyerDTO类,其中的state字段使用了@NotNull注解,并且类型是BooleanEnum。用户希望确保传入的state值确实是该枚举的有效键。 首先,考虑现有的验证注解。@NotNull只能检查是否为null,但无法验证枚举的有效性。所以,我需要找一个能够检查枚举值的注解。常见的做法是使用@Pattern来匹配正则表达式,但枚举的键可能更适合用特定的验证方式。 然后,想到JSR 380规范中的@ValidEnum注解,但发现这可能属于Hibernate Validator的扩展,不是标准的一部分。或者,用户可能需要自定义一个验证器。比如,创建一个@EnumValue注解,并实现对应的ConstraintValidator,检查值是否存在于枚举的键中。 接下来,查看用户当前的导入,发现他们使用了javax.validation.constraints中的注解,所以可能需要引入额外的依赖,比如Hibernate Validator的扩展库,或者自己实现。假设用户的项目中没有现成的@ValidEnum,那么自定义验证器是可行的方案。 然后,考虑如何实现自定义验证器。需要定义一个注解,比如@ValidEnum,指定目标枚举类型。然后编写验证逻辑,遍历枚举的keys,检查传入的值是否匹配。这里需要注意,枚举的键通常通过name()方法获取,而用户传入的可能是字符串,需要转换比较。 另外,用户可能希望错误信息能够明确,所以message属性需要设置合适的提示信息。同时,groups属性需要包含Add和Edit,以保持与其他验证注解的一致性。 最后,在state字段上添加这个新的@ValidEnum注解,并确保所有依赖和配置正确。这样,当有请求传入时,如果state的值不是BooleanEnum的有效键,验证就会失败,并返回指定的错误信息。 还需要检查BooleanEnum的枚举项是否正确,确保键的名称与传入的值匹配。例如,BooleanEnum可能有TRUE和FALSE两个枚举常量,那么传入的字符串应该是"TRUE"或"FALSE"才能通过验证。 总结,解决方案是自定义一个枚举验证注解,或者使用现有的库提供的注解,来确保state的值符合枚举的键。

方案一:自定义校验注解(推荐)

// 1. 创建校验注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumKeyValidator.class)
public @interface ValidEnumKey {
    String message() default "必须为指定枚举值";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<? extends Enum<?>> enumClass();
}

// 2. 实现校验逻辑
public class EnumKeyValidator implements ConstraintValidator<ValidEnumKey, String> {
    private Class<? extends Enum<?>> enumClass;

    @Override
    public void initialize(ValidEnumKey constraintAnnotation) {
        this.enumClass = constraintAnnotation.enumClass();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) return true;
        return Arrays.stream(enumClass.getEnumConstants())
                .anyMatch(e -> e.name().equals(value));
    }
}

// 3. 在字段上添加注解
@ValidEnumKey(enumClass = BooleanEnum.class, groups = {Add.class, Edit.class}, 
             message = "必须是BooleanEnum的有效枚举值")
@NotNull(message = "启用状态不能为空!", groups = {Add.class, Edit.class})
private BooleanEnum state;

方案二:使用Hibernate Validator(需确保依赖存在)

// 直接使用已有注解
@NotNull(message = "启用状态不能为空!", groups = {Add.class, Edit.class})
@Pattern(regexp = "TRUE|FALSE", message = "必须为TRUE或FALSE")
private String state; // 注意类型需要改为String

注意事项:
1.如果使用方案一,需要确保BooleanEnum中确实包含TRUE和FALSE的枚举常量。
2.对于枚举类型字段,建议直接使用BooleanEnum类型而非String,配合自定义校验器更符合类型安全原则。
3.当前字段已经是BooleanEnum类型,理论上框架会自动进行类型转换,若出现非法值会抛出类型转换异常,可通过全局异常处理器捕获处理。

建议采用方案一,既保持类型安全又实现精准校验。

总结:基于问题推理描述清晰,给出的结论和现有编码完全一致

@ApiModelProperty(value = "启用状态-TRUE:启用,FALSE:禁用", required = true)
@NotNull(message = "启用状态不能为空!", groups = {Add.class, Edit.class})
@EnumValidation(message = "启用状态格式错误!", enums = BooleanEnum.class, groups = {Add.class, Edit.class})
private BooleanEnum state;

2.基于需求提问写出sql语句

推理过程:
好的,我现在需要帮用户写一个SQL查询,统计商家各个商品的已分拣和未分拣数据。首先,用户的需求是查询sellerId为12345的商家,配送日期dlrDate是2025-03-02,分拣状态有四个值:WAITPICK和STOCKOUT属于未分拣,PICKED和NOSTOCK属于已分拣。需要按商品ID分组,统计每个商品的未分拣和已分拣数量。 首先,我需要确定用户的数据表结构。虽然用户没有提供表结构,但根据常见的数据库设计,可能有一个订单或分拣表,包含sellerId、pdtId、pickStatus、dlrDate等字段。假设表名为order_pick,接下来需要考虑如何将pickStatus分类,并用条件聚合来统计数量。 然后,分拣状态的分类:WAITPICK和STOCKOUT为未分拣,PICKED和NOSTOCK为已分拣。需要使用CASE WHEN语句将这两种状态分别标记为1和0,然后使用SUM函数统计数量。比如,SUM(CASE WHEN pickStatus IN ('WAITPICK', 'STOCKOUT') THEN 1 ELSE 0 END) AS unpicked_count。 接下来,筛选条件:sellerId=12345,dlrDate='2025-03-02'。这需要在WHERE子句中设置。同时,按pdtId分组,使用GROUP BY pdtId。 还需要考虑可能的异常情况,比如pickStatus是否有其他值,是否需要排除。用户提供的状态已经覆盖了所有可能的情况,所以暂时不需要处理其他值。 另外,是否需要处理NULL值?比如,如果pickStatus为NULL,是否会计入统计。根据用户的需求,可能不需要,但可以在CASE WHEN中添加处理,或者假设数据库中没有NULL值。 最后,组织SQL语句,确保语法正确,字段名和表名正确。可能需要用户根据实际表名进行调整,比如将order_pick替换为实际表名。同时,是否需要去重计数,比如使用COUNT(DISTINCT ...),但用户需求是统计数量,可能每条记录代表一个分拣项,所以直接COUNT即可。 总结,SQL结构应该是SELECT pdtId,SUM未分拣和已分拣的数量,WHERE条件,GROUP BY pdtId。测试一下是否有语法错误,比如别名是否正确,逗号是否正确分隔字段等。

方案:

SELECT 
    pdtId,
    SUM(CASE WHEN pickStatus IN ('WAITPICK', 'STOCKOUT') THEN 1 ELSE 0 END) AS unpicked_count,
    SUM(CASE WHEN pickStatus IN ('PICKED', 'NOSTOCK') THEN 1 ELSE 0 END) AS picked_count
FROM 
    order_pick  -- 请替换为实际表名
WHERE 
    sellerId = 12345 
    AND dlrDate = '2025-03-02'
GROUP BY 
    pdtId

说明:
1.CASE WHEN 条件判断分拣状态;
2.SUM(...) 统计符合条件的数据条数;
3.WHERE 过滤指定商家和配送日期;
4.GROUP BY 按商品ID分组统计;
5.结果包含三列:商品ID、未分拣数量、已分拣数量;
6.注意需要根据实际表结构调整;
7.如果分拣状态存储为枚举值,可能需要处理大小写;
8.若需要去重计数可改用 COUNT(DISTINCT order_id);
9.表名 order_pick 需替换为实际分拣记录表名;

总结:基于问题推理描述清晰,给出的结论和现有编码完全一致

    <select id="statPickPdtCnt" resultType="com.yuanbenx.scsp.sorting.pojo.vo.StatPickCntVO">
        select t1.pdtId, count(1) pickCnt,
        sum(case when t1.pickStatus in ( 'PICKED', 'NOSTOCK' ) then 1 else 0 end) doneCnt,
        sum(case when t1.pickStatus in ( 'WAITPICK', 'STOCKOUT' ) then 1 else 0 end) unDoneCnt
        from tst_queue t1
        where t1.sellerId = #{sellerId}
        and t1.dlrDate = #{grantDate}
        and t1.isTakeBack = 'FALSE'
        group by t1.pdtId
    </select>

3.代码解释

解释代码1.png

推理过程:
好的,我需要解释这段Java代码的功能,并画出对应的控制流图。首先,代码是一个定时任务,用来更新采集基地的经纬度信息。类名是UpdateColNullGpsScheduler,使用了Spring的@Scheduled注解,每两小时执行一次,并且是异步的。 看看方法updCollectNullGps。方法开始获取分布式锁,防止并发执行。使用CustomRedisLock获取锁,锁的key是StaticValue.UPDATE_GPS_LOCK,尝试获取30秒。如果获取不到锁就直接返回,避免重复处理。 接下来,构造查询条件,查找那些经纬度为空或者为0的TcoCollectFarmPO记录。如果查询结果为空,日志记录后返回。否则,将查询到的数据转换为TdeDeclareGpsDTO列表,然后调用declareGPSService的updateCollectGps方法进行更新。过程中如果有异常会被捕获并记录,最后释放锁。 控制流图应该包括主要的步骤:尝试获取锁、判断是否成功、查询数据库、处理数据、更新GPS、异常处理和释放锁。需要注意条件判断的分支,比如获取锁失败和查询结果为空的情况。 流程图的结构应该是从上到下,先尝试获取锁,失败则结束。成功的话继续查询数据库,如果结果为空则结束,否则处理数据并更新,最后释放锁。异常处理部分在finally块中,无论是否成功都检查锁状态并释放。 现在需要把这些步骤用Mermaid的活动图表示出来,节点使用中文描述,条件判断用菱形节点,流程简洁。确保不直接放代码,而是用简短的文字描述每个步骤。

代码解释:
该代码是定时更新缺失经纬度的采集基地数据的任务。每2小时异步执行,通过分布式锁防止并发冲突。主要流程:获取Redis锁→查询缺少经纬度的基地列表→转换为DTO→批量更新GPS数据→异常捕获→释放锁。

除了代码解释,也有生成单元测试,生成注释,优化代码的便捷小工具(controller、service代码上会有小图标)。

解释代码2.png

4.代码优化

代码优化1.png

以下是对代码的审查建议:
潜在问题提醒:
1.字符串构建器复用风险:循环内重复使用同一个StrBuilder对象并调用clear(),可能残留未清除数据(虽然当前逻辑已正确清除,但存在维护风险)
2.空值处理不足:未对rcvPersonTel、rcvAreaName等字段进行空值处理,当这些字段为null时会导致字符串拼接出现"null"字样
优化建议:
1.优化字符串构建方式:每次循环创建新的字符串构建器,避免可能的残留风险
2.增强空值防御:使用StrUtil的blankToDefault方法处理可能为空的字段
3.提取常量提升可维护性:将固定格式字符串提取为常量;

原代码:

@Override
    @Transactional(readOnly = true)
    public IPage<TctBuyerVO> pageList(TctBuyerQuery query) {
        IPage<TctBuyerVO> page = buyerMapper.pageList(Page.of(query.getCurrent(), query.getSize()), query);
        List<TctBuyerVO> records = page.getRecords();
        if (CollectionUtil.isEmpty(records)) return page;

        StrBuilder builder = new StrBuilder();
        for (TctBuyerVO vo : records) {
            if (StrUtil.isBlank(vo.getRcvPerson())) continue;
            builder.append("联系人:").append(vo.getRcvPerson()).append(";");
            builder.append("联系电话:").append(vo.getRcvPersonTel()).append(";");
            builder.append("收货地址:").append(vo.getRcvAreaName()).append(vo.getRcvAddress()).append(";");
            vo.setRcvStr(builder.toString());
            builder.clear();
        }
        return page;
    }

优化后的代码:


// 常量定义(类级别)
private static final String CONTACT_FORMAT = "联系人:%s;联系电话:%s;收货地址:%s%s;";

@Override
@Transactional(readOnly = true)
public IPage<TctBuyerVO> pageList(TctBuyerQuery query) {
    IPage<TctBuyerVO> page = buyerMapper.pageList(Page.of(query.getCurrent(), query.getSize()), query);
    List<TctBuyerVO> records = page.getRecords();
    if (CollectionUtil.isEmpty(records)) return page;

    for (TctBuyerVO vo : records) {
        if (StrUtil.isBlank(vo.getRcvPerson())) continue;
        
        String tel = StrUtil.blankToDefault(vo.getRcvPersonTel(), "");
        String area = StrUtil.blankToDefault(vo.getRcvAreaName(), "");
        String address = StrUtil.blankToDefault(vo.getRcvAddress(), "");
        
        vo.setRcvStr(String.format(CONTACT_FORMAT, 
            vo.getRcvPerson(),
            tel,
            area,
            address));
    }
    return page;
}

修改说明:
1.使用String.format替代StrBuilder,提升代码简洁性
2.通过StrUtil.blankToDefault处理可能为空的字段
3.将格式字符串提取为常量CONTACT_FORMAT
4.移除不必要的临时变量和循环内对象复用
5.保持原有方法输入输出不变,仅修改内部实现

总结下,通义灵码真的好用,香,真的香!

提示:
1.使用个人基础版(免费);
2.插件可选择 Qwen-2.5、DeepSeek-R1 和 DeepSeek-V3 模型;
通义灵码官方文档链接

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,226评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,509评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,523评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,181评论 1 302
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,189评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,642评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,993评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,977评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,527评论 1 326
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,547评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,661评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,250评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,991评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,422评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,571评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,241评论 3 382
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,737评论 2 366

推荐阅读更多精彩内容