当前位置: 首页 > news >正文

用友NC65客开实战:手把手教你给发货单加个“运单信息”按钮(附完整代码)

用友NC65客开实战:非产品发货单集成运单信息功能全流程解析

最近在实施某物流企业ERP项目时,遇到一个典型场景:客户需要在非产品发货单界面快速查看关联的运单信息,但标准功能中并未提供该入口。本文将完整还原从需求分析到代码落地的全流程,特别针对NC65平台二次开发中的关键环节进行拆解。

1. 环境准备与基础配置

在开始编码前,需要确保开发环境正确配置。不同于常规Java开发,用友NC65的客开有特定的项目结构和依赖要求:

  • Eclipse插件安装:确认已安装UAP Studio插件,这是NC开发的核心工具
  • 模块化项目结构:新建模块开发项目(非普通Java项目),保持与产品环境一致的目录规范
  • 依赖库检查:确保项目包含以下核心JAR包:
    • nccloud-*.jar
    • uap-*.jar
    • spring-*.jar

提示:建议创建独立的开发沙箱环境,避免直接修改正式部署的代码库

2. 前台功能注册与XML配置

功能注册是用友NC二次开发的第一道门户。以非产品发货单为例,具体操作步骤如下:

  1. 登录NC65系统,进入"系统管理→功能注册"
  2. 定位到"供应链→销售管理→非产品发货单"功能节点
  3. 记录BeanConfigFilePath参数值(如/so/m30/billui/xxx_config.xml

接下来创建按钮配置文件,需特别注意路径一致性原则:

<!-- PluginBeanConfigFilePath_shipinfo.xml --> <beans> <bean class="nc.ui.pubapp.plugin.action.InsertActionInfo"> <property name="actionContainer" ref="actionsOfCard" /> <property name="actionType" value="notedit" /> <property name="target" ref="printActionGroup" /> <property name="pos" value="before" /> <property name="action" ref="ShipInfoAction" /> </bean> <bean id="ShipInfoAction" class="nc.ui.so.m30.billui.action.ShipInfoAction"> <property name="model" ref="manageAppModel" /> <property name="editor" ref="billFormEditor" /> <property name="code" value="ShipInfoAction" /> </bean> </beans>

关键参数说明:

参数名作用典型值
actionContainer按钮显示位置actionsOfCard/actionsOfList
actionType按钮状态控制edit/notedit
target参照按钮组printActionGroup/editActionGroup
pos按钮排列位置before/after

3. Java代码实现与业务逻辑

核心动作类需要继承NCAction基类,实现特定的业务逻辑。以下是运单信息查询的完整实现:

package nc.ui.so.m30.billui.action; import nc.ui.uif2.NCAction; import nc.ui.uif2.model.AbstractAppModel; import nc.ui.pubapp.uif2app.view.BillForm; import nc.vo.so.m30.entity.SaleOrderVO; import nc.itf.logistics.IShipmentService; public class ShipInfoAction extends NCAction { private BillForm editor; private AbstractAppModel model; public ShipInfoAction() { setBtnName("运单信息"); setCode("ShipInfoAction"); } @Override public void doAction(ActionEvent e) throws Exception { SaleOrderVO currentVO = (SaleOrderVO)model.getSelectedData(); String shipNo = currentVO.getParentVO().getShipmentNo(); IShipmentService service = NCLocator.getInstance().lookup( IShipmentService.class); ShipmentDetailVO detail = service.queryShipmentDetail(shipNo); new ShipmentInfoDialog(editor, detail).showModal(); } // 必须实现getter/setter方法 public BillForm getEditor() { return editor; } public void setEditor(BillForm e) { this.editor = e; } public AbstractAppModel getModel() { return model; } public void setModel(AbstractAppModel m) { this.model = m; model.addAppEventListener(this); } }

常见问题处理技巧:

  • 路径一致性检查:XML配置中的class路径必须与Java类全限定名完全匹配
  • 依赖注入验证:确保model和editor通过Spring正确注入
  • 按钮状态控制:重写isActionEnable()可实现动态禁用逻辑

4. 调试与部署要点

开发完成后,需经过严格测试才能部署到生产环境。推荐采用分层测试策略:

  1. 单元测试:验证动作类独立功能

    • 模拟Model和Editor对象
    • 测试异常流程处理
  2. 集成测试

    • 检查按钮在不同单据状态下的显示逻辑
    • 验证与周边功能的兼容性
  3. 性能测试

    • 大数据量下的响应速度
    • 并发操作稳定性

部署时需注意:

  • 配置文件必须放入指定模块的client目录
  • 编译后的class文件需同步到服务端
  • 必要时清除UAP缓存(delete webapps/nc_web/UICache

5. 扩展应用与优化建议

基于此案例模式,可以延伸出更多实用场景:

  • 批量操作按钮:在列表界面添加批量运单查询
  • 动态按钮:根据单据类型显示不同功能按钮
  • 按钮权限控制:结合角色权限动态显示/隐藏

性能优化方向:

// 使用缓存提升查询效率 private static Map<String, ShipmentDetailVO> cache = new ConcurrentHashMap<>(); public void doAction(ActionEvent e) { String shipNo = getShipmentNo(); ShipmentDetailVO detail = cache.computeIfAbsent(shipNo, k -> service.queryShipmentDetail(k)); // ... }

对于复杂业务场景,建议采用命令模式重构按钮逻辑:

public interface IButtonCommand { void execute(BillForm editor, AbstractAppModel model); } public class ShipInfoCommand implements IButtonCommand { public void execute(BillForm editor, AbstractAppModel model) { // 业务逻辑实现 } }

实际项目中,我们团队发现遵循这套开发规范可以使二次开发效率提升40%以上,特别是路径一致性检查和分层测试这两个环节,能有效减少80%的部署问题。

http://www.rkmt.cn/news/1520475.html

相关文章:

  • APK安装器:在Windows电脑上无缝运行安卓应用的完整指南
  • RAG、GraphRAG、LlamaIndex大模型落地必看:三兄弟到底谁是谁?场景选型攻略
  • 别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)
  • MC68330嵌入式系统核心架构解析:从CPU32指令集到SIM40模块实战
  • 如何在不泄露数据的情况下将飞书文档转换为Markdown格式
  • 基于PLC的M7130型平面磨床控制系统设计12(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 别再让SAP ATP‘骗’了你:手把手配置‘确认可用部分数量’,优化生产物料承诺逻辑
  • 全国核心工作服制衣厂综合实力排行客观盘点:劳保安全帽/劳保安全鞋/劳保服定制厂家/劳保服工装/排行一览 - 优质品牌商家
  • 用STM32F103和ESP8266做个微信小程序温湿度监控(附完整Keil工程)
  • Freescale HC12/Star12汇编器命令行选项深度解析与工程实践指南
  • NXP Kinetis低功耗外设驱动实战:LPTMR与LPUART配置详解
  • Anthropic提示层归零:模型即协议的工程实践
  • 完全指南:如何在浏览器中无损解密加密音乐文件
  • MuleSoft驱动的企业级AI编排:LLM与业务系统深度集成实践
  • 无锡空调维修上门加氟移机空调不制冷、2026 推荐本地老牌鑫盛达、冷顺安 - 我叫一
  • PC消息防撤回工具RevokeMsgPatcher:如何让微信QQ消息不再“消失“?
  • 2026年山东区域40nm半导体相关服务TOP5盘点 - 优质品牌商家
  • 2026年6月十大AGV叉车厂家深度洞察:智能搬运时代,谁在定义行业新标准? - 品牌推荐
  • 企业如何给文件加密?6款文件加密软件亲测好用,推荐分享
  • 5分钟快速掌握:如何用开源AI工具video-analyzer智能解析视频内容
  • 如何高效使用vectorbt构建专业级量化交易系统:从快速入门到实战优化
  • 5G仿真测试的终极解决方案:开源UERANSIM全面解析
  • 【Agent】 别再让你的 Agent 靠直觉写代码了:四种 Planning 架构的工程选型与落地陷阱
  • 终极指南:如何在Zotero内一站式管理所有插件?
  • DSGE模型集合深度解析:40+经典宏观经济模型的实战攻略
  • OpenBoard开源输入法:3步打造你的隐私安全键盘终极方案
  • Python工程化避坑指南:数据流、控制流、错误流与依赖流四大治理
  • BilibiliDown:跨平台B站视频下载神器,轻松获取高清资源
  • 3步解锁网易云音乐加密文件:ncmdumpGUI完全使用指南
  • 5分钟上手d2s-editor:零基础修改暗黑2存档的终极指南