
一、本文前言https://www.jnpfsoft.com/在开始本文前咨询了deepsick是否合适分享咨询后认为是好事本文会遵循以下原则1、只分享使用经验仅停留在使用的层面2、不透露核心代码3、不用做商业化4、本文认为可能涉及敏感信息的内容均已脱敏下面本文开始本文描述不够准确的地方欢迎交流指正二、jnpf简介jnpf 是 pnpm-workplace 单体代码库架构序号项目目录位置备注2jnpf-web-apps-mainjnpf-web-monorepo-framework/apps/jnpf-web-apps-main前端主项目源码Vue3项目名字不能修改否则不能下载依赖也不能启动项目3jnpf-bpmnjnpf-web-monorepo-framework/packages/jnpf/plugins/jnpf-bpmn前端流程设计器核心源码Vue3项目名字不能修改否则不能下载依赖也不能启动项目4jnpf-univerjnpf-web-monorepo-framework/packages/jnpf/plugins/jnpf-univer前端Univer报表设计器核心源码Vue3项目名字不能修改否则不能下载依赖也不能启动项目5jnpf-resources服务器上使用静态资源和代码下载后的文件及引用的文件路径相关1jnpf-web-monorepo-framework根目录框架项目6jnpf-web-datareport独立使用前端报表项目源码7jnpf-web-datascreen-vue3独立使用前端大屏项目源码Vue38jnpf-web-tenant-vue3租户项目9jnpf-app-vue3移动端项目1、第一次启动项目时先检查 项目名是否准确 env 相关文件配置是否准确2、检查node环境 本文使用 24.11.1 做参考3、pnpm install 下载依赖4、pnpm run dev 启动项目5、本地启动了 localhost:30006、登录账密进入项目env.development# env.development # 端口号 VITE_PORT3000 VITE_BASE/ # 本地开发代理可以解决跨域及多地址代理 # 如果接口地址匹配到则会转发到http://localhost:30000防止本地出现跨域问题 # 可以有多个注意多个不能换行否则代理将会失效 VITE_PROXY[[/dev,http://www.snow.com], [/reportDev,http://localhost:32000]] # 接口地址 VITE_GLOB_API_URL/dev # 报表接口地址 VITE_GLOB_REPORT_API_URL/reportDev # WebSocket基础地址 VITE_GLOB_WEBSOCKET_URLws://localhost:30000 # 是否打开 devtoolstrue 为打开false 为关闭 VITE_DEVTOOLSfalse # 是否注入全局loading VITE_INJECT_APP_LOADINGtrue三、创建应用地址https://www.snow.com/appCenter 访问自己部署后的项目地址这里仅作展示账号test密码testtest3.1、创建应用3.2、创建成功3.3、进入应用四、数据中心4.1、数据中心-数据源链接/链接数据库根据字段提示填写对应信息维护完成之后点击确定就会出现在列表里边4.2、数据中心-数据接口-新建接口数据接口列表-新建维护步骤1基本信息注意这里的switch组件/鉴权如果要设置“变量”这里需要打开如果不设置对象这里不需要打开维护步骤2数据配置注意这里要传参数包括token和业务参数等维护步骤3异常校验维护步骤4异常处理这里如果开启了鉴权那么没有这个步骤如果没有打开这里可以处理数据比如接口返回的数据不符合页面使用的预期那么可以在这里做处理4.3、数据中心-数据接口-变量参数传参设置变量变量可以在接口部分动态传递参数使用变量如果在body里边用变量前边加上即可4.4、数据中心-数据接口-接口参数传参1、接口数据-找到目标接口2、右侧接口参数-新建参数3、写入接口参数4、页面使用接口5、设置参数到这一步就设置了接口的使用页面的动态参数字段值的options为页面的字段如果页面里没有这个字段但是需要使用这个字段可以设置一个隐藏字段然后在这里使用值就可以了4.5、数据中心-数据接口-接口参数传参为页面增加隐藏字段作为接口参数1、为组件添加字段2、添加目标字段3、为字段添加数据 / 此处为用户信息的数据其他数据同理4、为字段设置数据4.6、数据中心-数据建模-理解数据建模JNPF平台的数据建模是其作为企业级低代码开发平台的核心功能之一。它是一种可视化的、基于模型驱动的数据库设计和管理工具旨在让开发者甚至业务人员能够通过图形化界面快速定义应用的数据结构而无需编写复杂的SQL代码从而极大地提升开发效率降低技术门槛。简单来说数据建模就是在JNPF平台上“画”出你的数据库表结构。模型驱动开发 (Model-Driven Development)数据建模是JNPF平台模型驱动思想的体现。您通过定义数据实体Entity、属性Attribute和关系Relationship等模型元素来响应业务需求变化。可视化数据库建模它提供了一个在线的、可视化的环境让您像画流程图一样创建和管理数据库表、字段、主键、外键以及表之间的关系。全生命周期管理数据建模不仅是设计阶段的工具它贯穿了数据表的整个生命周期包括创建、配置、数据查看、编辑、删除以及导入导出。在线实体建模新建表通过简单的表单填写表名、表说明并逐个添加字段。字段配置为每个字段配置名称、说明、数据类型如字符串、数字、日期等、是否为主键、是否自增长、默认值等属性。关系支持支持单表、一对一、一对多等常见的表关系配置。4.7、数据中心-数据建模-创建接口-选择SQL操作-使用数据建模1、点击数据中心选择目标数据库点击新建2、输入表名表说明字段设置点确定保存3、创建接口--选择SQL操作–使用数据建模填写信息后点下一步到数据配置4、填写完成后点下一步到数量统计5、完善后点下一步到数据回显6、完善后点下一步到数据处理完成后点确定保存7、表单设计时就可以使用接口了五、系统管理5.1、系统管理-素材管理-数据字典1、数据字典2、新建字典数据3、获取字典分类下拉框列表import { getDictionaryDataSelector } from #/api/systemData/dictionary; getDictionaryDataSelector(config.dictionaryType).then((res) { cur.options res.data.list; });5.2、系统管理-素材管理-系统字典-表单分类表单设计表单分类这个在哪里维护在这里维护5.3、系统管理-storeimport { useBaseStore } from #/store; const baseStore useBaseStore(); async function getOptions() { const sexRes await baseStore.getDictionaryData(sex); updateSchema({ field: gender, componentProps: { options: sexRes } }); }5.4、系统管理-变量 variatevariate.ts apps/jnpf-web-apps-main/src/api/systemData/variate.ts import { defHttp } from #/api/request; enum Api { Prefix /api/system/DataInterfaceVariate, } // 获取变量列表 export function getList(data) { return defHttp.get({ url: ${Api.Prefix}/${data.id}, data }); } // 新增变量 export function create(data) { return defHttp.post({ url: Api.Prefix, data }); } // 修改变量 export function update(data) { return defHttp.put({ url: ${Api.Prefix}/${data.id}, data }); } // 获取变量 export function getInfo(id) { return defHttp.get({ url: ${Api.Prefix}/${id}/Info }); } // 删除变量 export function del(id) { return defHttp.delete({ url: ${Api.Prefix}/${id} }); } // 复制变量 export function copy(id) { return defHttp.post({ url: ${Api.Prefix}/${id}/Actions/Copy }); } // 导出变量 export function exportData(id) { return defHttp.get({ url: ${Api.Prefix}/${id}/Actions/Export }); } // 获取变量 export function getVariateSelector() { return defHttp.get({ url: ${Api.Prefix}/Selector }); }5.5、系统管理-地区 areaapps/jnpf-web-apps-main/src/api/system/area.ts import { defHttp } from #/api/request; enum Api { Prefix /api/system/Area, } // 获取行政区划列表 export function getAreaList(data) { return defHttp.get({ url: ${Api.Prefix}/${data.nodeId}, data }); } // 获取行政区划下拉框列表 export function getAreaSelector(id, currId 0) { return defHttp.get({ url: ${Api.Prefix}/${id}/Selector/${currId} }); } // 获取行政区划数据详情 export function getAreaByIds(idsList) { return defHttp.post({ url: ${Api.Prefix}/GetAreaByIds, data: { idsList } }); } // 新建行政区划 export function createArea(data) { return defHttp.post({ url: Api.Prefix, data }); } // 修改行政区划 export function updateArea(data) { return defHttp.put({ url: ${Api.Prefix}/${data.id}, data }); } // 获取行政区划 export function getAreaInfo(id) { return defHttp.get({ url: ${Api.Prefix}/${id}/Info }); } // 删除行政区划 export function delArea(id) { return defHttp.delete({ url: ${Api.Prefix}/${id} }); }六、应用前台-应用后台应用前台/用户使用的页面应用后台/编辑和管理当前应用/无代码模式开发在应用后台进行操作七、应用后台-在线开发7.1、应用后台-在线开发-表单设计新建-表单步骤一基础设计核心--选择数据库表步骤二表单设计左侧组件库这里选用目标组件拖放到中间区域中间这里是组合后的页面内容右侧组件属性、组件样式、表单属性步骤三列表设计左侧上部查询字段左侧下部列表字段右侧左1设置查询字段右侧左2设置列表字段右侧左3设置列表属性勾选需要的字段点击保存点击发布到应用前台页面查看到此大致的页面就完成了。但是在配置页面的时候细节是非常多的一个细节卡住可能就需要排查很长时间所以细节部分后续会陆续随着使用补充。7.2、应用后台-在线开发-表单设计-下拉选择1、实现目标下拉框点击可以选择数据数据从接口获取同理 Element-ui 的远程搜索2、表单设计-下拉选择选择目标接口选择字段输入名称选择下拉数据所需要的接口输入存储字段、回显字段7.3.1、应用后台-在线开发-表单设计-设计子表1、目标1.1、添加子表1.2、为子表设计/表格列 添加字段2、添加子表拖动过来选择关联子表为这个表格添加接口3、为子表添加字段点击添加字段从弹窗里选择类型选择关联子表子表字段为表格添加列对于普通的字段选择对应的字段4、为子表选择控件字段子表控件弹窗选择为子表选择控件字段为弹窗控件输入字段为弹窗控件设置 隐藏根据需要来设置5、其他这个子表的弹窗字段和按钮的弹窗应该是关联的两边的字段也一样依靠记忆形成本文记录不准确的后续发现后随时修改这里是按钮弹窗的可以做个对比参考7.3.2、应用后台-在线开发-表单设计-设计子表-按钮-弹窗-选择数据1、实现目标应用前台见下图图1图2应用后台见下图2、实现添加产品的“按钮-弹窗-选择数据”点击添加按钮在对应的字段添加信息动作设置按钮动作--选择数据数据来源--数据接口数据接口--选择对应的接口动作设置参数设置–设置查询参数设置列表字段/设置关联字段根据实际情况填写填写完成后点击确定7.3.3、应用后台-在线开发-表单设计-当下选择发生变化时为其他表单字段赋值1、当选择收获仓之后通过收获仓接口返回的数据为其他字段进行赋值2、配置change({ data, rowIndex, formData, setFormData, setShowOrHide, setRequired, setDisabled, onlineUtils }) { // 在此编写代码 setFormData(contact_man, data.receiverName) setFormData(contact_man_phone, data.receiverPhone) setFormData(storage_address, data.warehouseAddress) }3、配置后当收获仓选择后对应的字段就会回显数据了7.3.4、应用后台-在线开发-表单设计-为什么新增按钮会出现弹窗或者打开新页面列表页面点击新增按钮会出现弹窗或者打开新的页面居中弹窗全屏弹窗八、二次开发 / 低代码开发8.1、二次开发-应用后台-在线开发-表单设计-代码生成/低代码开发/下载代码 自己 二次开发1、代码生成/低代码开发的起点2、下载代码这里有个代码预览可以预览完整代码模块命名3、代码预览这里前后端代码都可以查看4、下载后的文件第一个文件是用来表单回传的第二个文件是前端代码第三个文件是后端代码这里我们把前端代码复制到我们的jnpf-web-apps-main/src/views目标目录下配置对应的菜单jnpf-web-apps-main/src/router配置菜单后就可以在本地访问页面了代码修改完成后我们继续5、本地启动项目访问页面进行开发调试pnpm run dev6、表单回传6.1、点击导入6.2、上传文件上传我们当时下载的文件包下的 returnForm.vdd 文件即可上传后列表多了一条数据6.3、点编辑填写页面地址点保存到这里就形成了一个页面的模板7、配置菜单这里关键字段是类型表单回传/我们本地开发的页面代码菜单列表多了我们刚配置的菜单配置好之后在应用前台我们就能看到了注意此时还是在本地开发如果要发布到线上需要提交代码到仓库对应的分支到此我们记录了二次开发/低代码的全过程同样细节很多后续伴随着使用陆续补充注意低代码开发下载下来的代码包括前端代码也包括后端代码需要前后端都使用低代码后端上传代码后前端代码可以正常使用否则前端访问接口接口的http返回200业务代码返回400msg不能访问服务下载代码后后端需要先上传代码并发版pass接口才可以走通8.2、二次开发-获取JnpfRelationForm表单组件的数据import { useGeneratorStore } from #/store; const generatorStore useGeneratorStore(); const relationData generatorStore.getRelationData; console.log(844---, relationData); // 数据拿到了8.3、二次开发-getTableActions的使用function getTableActions(record): ActionItem[] { return [ { label: $t(common.editText), onClick: addOrUpdateHandle.bind(null, record.id), }, { label: 发布, color: error, modelConfirm: { title: 发布确认, content: 发布表单会覆盖当前线上版本, 是否继续?, onOk: handleRelease.bind(null, record.id), }, }, ]; }九、平台能力开发十、合并代码 / 发版