neo-cmp-cli 1.13.13 → 1.13.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/neo/neoEnvManager.js +1 -1
- package/dist/neo/neoLogin.js +1 -1
- package/dist/neo/neoRequire.js +1 -1
- package/dist/package.json.js +1 -1
- package/docs//351/200/232/347/224/250/344/273/243/347/220/206/346/216/245/345/217/243/forward.zip +0 -0
- package/docs//351/200/232/347/224/250/344/273/243/347/220/206/346/216/245/345/217/243//350/207/252/345/256/232/344/271/211API:/351/200/232/347/224/250/344/273/243/347/220/206/346/216/245/345/217/243/344/275/277/347/224/250/350/257/264/346/230/216.md +13 -0
- package/package.json +1 -1
- package/template/antd-custom-cmp-template/package.json +1 -1
- package/template/asset-manage-template/package.json +1 -1
- package/template/echarts-custom-cmp-template/package.json +1 -1
- package/template/empty-custom-cmp-template/package.json +1 -1
- package/template/map-custom-cmp-template/package.json +1 -1
- package/template/neo-bi-cmps/package.json +1 -1
- package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/index.tsx +17 -10
- package/template/neo-bi-cmps/src/components/aiCommitDrawer__c/model.ts +47 -6
- package/template/neo-bi-cmps/src/components/filterBar__c/index.tsx +21 -7
- package/template/neo-bi-cmps/src/components/forecastChart__c/index.tsx +6 -9
- package/template/neo-bi-cmps/src/components/forecastChart__c/model.ts +2 -1
- package/template/neo-bi-cmps/src/components/forecastGrid__c/model.ts +32 -4
- package/template/neo-bi-cmps/src/components/gapCloser__c/index.tsx +7 -2
- package/template/neo-bi-cmps/src/components/gapCloser__c/model.ts +6 -3
- package/template/neo-bi-cmps/src/components/kpiCards__c/model.ts +18 -3
- package/template/neo-bi-cmps/src/components/oppList__c/index.tsx +70 -13
- package/template/neo-bi-cmps/src/components/oppList__c/model.ts +50 -4
- package/template/neo-bi-cmps/src/components/pipelineFunnel__c/index.tsx +3 -1
- package/template/neo-bi-cmps/src/components/pipelineFunnel__c/model.ts +28 -4
- package/template/neo-bi-cmps/src/components/stageSwitch__c/index.tsx +21 -6
- package/template/neo-bi-cmps/src/components/stageSwitch__c/model.ts +60 -5
- package/template/neo-bi-cmps/src/components/stageTimeChart__c/model.ts +26 -4
- package/template/neo-custom-cmp-template/package.json +1 -1
- package/template/neo-h5-cmps/package.json +1 -1
- package/template/neo-order-cmps/package.json +1 -1
- package/template/neo-web-entity-grid/package.json +1 -1
- package/template/neo-web-form/package.json +1 -1
- package/template/neo-web-form/src/components/batchAddTable__c/index.tsx +17 -17
- package/template/react-custom-cmp-template/package.json +1 -1
- package/template/react-ts-custom-cmp-template/package.json +1 -1
- package/template/vue2-custom-cmp-template/package.json +1 -1
- package/template/neo-bi-cmps/docs/gartner-pipeline-apis.md +0 -279
- package/template/neo-bi-cmps/docs/gartner-pipeline-prd.md +0 -389
- package/template/neo-bi-cmps/docs/neo-backend-dev/SKILL.md +0 -188
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/01-Trigger/345/274/200/345/217/221.md +0 -183
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/02-/350/207/252/345/256/232/344/271/211API/345/274/200/345/217/221.md +0 -196
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/03-SDK/345/267/245/345/205/267/347/261/273/346/216/245/345/217/243.md +0 -346
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/04-/350/256/241/345/210/222/344/275/234/344/270/232/345/274/200/345/217/221.md +0 -188
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/05-/351/241/265/351/235/242/345/274/200/345/217/221.md +0 -293
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/06-/346/265/201/347/250/213/346/211/251/345/261/225/345/274/200/345/217/221.md +0 -175
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/PaaS/345/271/263/345/217/260/345/274/200/345/217/221/346/211/213/345/206/214/350/247/243/350/257/273.md +0 -313
- package/template/neo-bi-cmps/docs/neo-backend-dev/references/auth-config.md +0 -77
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/deploy_server_script.py +0 -118
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/download_server_script.py +0 -74
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/gen_entity_desc.py +0 -69
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/gen_entitylist.py +0 -87
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/query_crm.py +0 -65
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/uninstall_server_script.py +0 -48
- package/template/neo-bi-cmps/docs/neo-backend-dev/scripts/update_model_jar.py +0 -49
- package/template/neo-bi-cmps/docs/neo-frontend-dev/SKILL.md +0 -138
- package/template/neo-bi-cmps/docs/neo-frontend-dev/references/auth-config.md +0 -77
- package/template/neo-bi-cmps/docs/neo-frontend-dev/references/component-dev.md +0 -205
- package/template/neo-bi-cmps/docs/neo-frontend-dev/references/entityTable-example.md +0 -167
- package/template/neo-bi-cmps/docs/neo-frontend-dev/references/templates.md +0 -38
- package/template/neo-bi-cmps/docs/neo-frontend-dev/scripts/gen_entity_desc.py +0 -69
- package/template/neo-bi-cmps/docs/neo-frontend-dev/scripts/gen_entitylist.py +0 -87
- package/template/neo-bi-cmps/docs/neo-frontend-dev/scripts/query_crm.py +0 -65
- package/template/neo-bi-cmps/docs/prototype-pipeline-forecasting.html +0 -2453
- package/template/neo-bi-cmps/docs//350/264/246/345/217/267/347/233/270/345/205/263/344/277/241/346/201/257.md +0 -10
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: neo-backend-dev
|
|
3
|
-
description: Neo 后端 PaaS 开发技能,辅助在 NeoCRM 平台上进行 Java 后端开发。当用户需要:(1) 创建项目并配置后端开发环境,(2) 开发 Trigger 触发器,(3) 开发自定义 REST API,(4) 开发计划作业(定时任务),(5) 开发流程扩展(审批流/工作流),(6) 使用 SDK 工具类(数据操作、HTTP请求、缓存、异步),(7) 打包上传/下载/卸载后端代码包,(8) 获取和查询实体模型,(9) 更新 model.jar 时,使用此技能。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Neo 后端 PaaS 开发
|
|
7
|
-
|
|
8
|
-
辅助完成 NeoCRM PaaS 平台 Java 后端开发全流程。
|
|
9
|
-
|
|
10
|
-
## 前置条件
|
|
11
|
-
|
|
12
|
-
- 已全局安装 neo-cmp-cli:`npm i -g neo-cmp-cli`(用于项目创建和登录认证)
|
|
13
|
-
- Node.js 环境
|
|
14
|
-
- JDK 1.8(后端代码编译)
|
|
15
|
-
|
|
16
|
-
## 重要约定
|
|
17
|
-
|
|
18
|
-
- `neo login -e production` 默认登录生产环境。执行登录前必须询问用户要登录到哪个环境。环境参数:`production`、`gray`、`sandbox`、`cd`、`tencentuat`、`custom`
|
|
19
|
-
- `neo login` 执行后自动打开浏览器授权,轮询 `.neo-cli/token.json` 确认登录成功
|
|
20
|
-
- 执行平台操作时直接执行,未登录失败后再询问环境并登录重试
|
|
21
|
-
- Java 包路径必须三级且以 `other` 开头(如 `other.xsy.account`),不能生成 4 级或以上
|
|
22
|
-
- 仅支持第三方包:fastJson + commons-lang
|
|
23
|
-
|
|
24
|
-
## 核心工作流
|
|
25
|
-
|
|
26
|
-
### 1. 创建项目
|
|
27
|
-
|
|
28
|
-
如果用户未指定项目名称,先询问。未指定路径则告知默认位置并询问是否修改。
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
neo create project -n <项目名称>
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
项目创建后将 `neo.config.js` 中 `neoConfig` 改为正式环境:
|
|
35
|
-
```javascript
|
|
36
|
-
neoConfig: {
|
|
37
|
-
neoBaseURL: 'https://crm.xiaoshouyi.com',
|
|
38
|
-
loginURL: 'https://login.xiaoshouyi.com/auc/oauth2/auth',
|
|
39
|
-
tokenURL: 'https://login.xiaoshouyi.com/auc/oauth2/token',
|
|
40
|
-
},
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 2. 登录租户
|
|
44
|
-
|
|
45
|
-
项目创建后,先询问用户要登录到哪个环境(默认 production),执行登录:
|
|
46
|
-
```bash
|
|
47
|
-
neo login -e <env>
|
|
48
|
-
```
|
|
49
|
-
轮询 `.neo-cli/token.json` 确认登录成功。
|
|
50
|
-
|
|
51
|
-
### 3. 安装前端依赖(仅开发前端组件时需要)
|
|
52
|
-
|
|
53
|
-
后端代码开发和部署不需要执行 `npm install`,仅在需要开发前端组件时才执行:
|
|
54
|
-
```bash
|
|
55
|
-
cd <项目目录>
|
|
56
|
-
npm install
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 4. 后端代码开发
|
|
60
|
-
|
|
61
|
-
后端代码统一放在 `src/server-scripts/` 下,按代码包组织:
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
<项目>/src/server-scripts/
|
|
65
|
-
<代码包简称>/
|
|
66
|
-
other/
|
|
67
|
-
<company>/
|
|
68
|
-
<module>/ # 三级包名,如 other/xsy/account
|
|
69
|
-
XxxTrigger.java
|
|
70
|
-
XxxApi.java
|
|
71
|
-
scriptTrigger.xml # Trigger 配置
|
|
72
|
-
apiUrl.xml # 自定义 API 路由配置
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### 后端开发参考文档
|
|
76
|
-
|
|
77
|
-
根据需求选择对应参考:
|
|
78
|
-
|
|
79
|
-
- Trigger 触发器 → [references/01-Trigger开发.md](references/01-Trigger开发.md)
|
|
80
|
-
- 自定义 REST API → [references/02-自定义API开发.md](references/02-自定义API开发.md)
|
|
81
|
-
- SDK 工具类 → [references/03-SDK工具类接口.md](references/03-SDK工具类接口.md)
|
|
82
|
-
- 计划作业 → [references/04-计划作业开发.md](references/04-计划作业开发.md)
|
|
83
|
-
- 页面开发 → [references/05-页面开发.md](references/05-页面开发.md)
|
|
84
|
-
- 流程扩展 → [references/06-流程扩展开发.md](references/06-流程扩展开发.md)
|
|
85
|
-
- 平台能力概览 → [references/PaaS平台开发手册解读.md](references/PaaS平台开发手册解读.md)
|
|
86
|
-
|
|
87
|
-
### 关键限制
|
|
88
|
-
|
|
89
|
-
| 限制项 | 值 |
|
|
90
|
-
|--------|-----|
|
|
91
|
-
| 同步脚本最大运行时长 | 15 秒 |
|
|
92
|
-
| 异步脚本最大运行时长 | 90 秒 |
|
|
93
|
-
| 脚本最大内存 | 512 MB |
|
|
94
|
-
| 单次 DML 最大数据量 | 10,000 条 |
|
|
95
|
-
| commonHttpClient 最大调用次数 | 50 次/脚本 |
|
|
96
|
-
| 缓存最大大小 | 200 KB |
|
|
97
|
-
|
|
98
|
-
## 部署后端代码包
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
python3 scripts/deploy_server_script.py <项目目录> <代码包简称> <Java包名>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
示例:`python3 scripts/deploy_server_script.py NEOTrail 客户管理 other.xsy.account`
|
|
105
|
-
|
|
106
|
-
脚本自动:打包 ZIP → 检查/创建代码包 → 上传 → 安装 → 清理临时文件。
|
|
107
|
-
|
|
108
|
-
## 下载服务端代码包
|
|
109
|
-
|
|
110
|
-
如果用户未指定代码包名称(Java 包名),必须先询问。
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
python3 scripts/download_server_script.py <项目目录> <Java包名> [代码包简称]
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
本地已存在同名目录时会覆盖更新。
|
|
117
|
-
|
|
118
|
-
## 创建计划作业
|
|
119
|
-
|
|
120
|
-
代码包部署后,需要在 NeoCRM 系统后台手动创建计划作业任务(此接口需要浏览器 session 认证,无法通过 OAuth API 自动化):
|
|
121
|
-
|
|
122
|
-
1. 登录 NeoCRM 平台
|
|
123
|
-
2. 进入系统后台 → 开发 → 计划作业
|
|
124
|
-
3. 新建计划作业,填写以下信息:
|
|
125
|
-
- 任务名称
|
|
126
|
-
- 选择代码包和对应的 ScheduleJob 类
|
|
127
|
-
- 执行类型:自定义循环周期(executeType=3)
|
|
128
|
-
- 执行间隔:小时数(0-24)+ 分钟数(仅支持 5 的倍数:0,5,10,15...55)
|
|
129
|
-
- 生效时间范围
|
|
130
|
-
4. 启用计划作业
|
|
131
|
-
|
|
132
|
-
提示用户完成上述手动操作后继续。
|
|
133
|
-
|
|
134
|
-
## 更新 model.jar
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
python3 scripts/update_model_jar.py <项目目录>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## 卸载代码包
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
python3 scripts/uninstall_server_script.py <项目目录> <Java包名> [--force]
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## 获取实体模型
|
|
147
|
-
|
|
148
|
-
### 生成实体字典
|
|
149
|
-
```bash
|
|
150
|
-
python3 scripts/gen_entitylist.py <项目目录>
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### 查询实体字段
|
|
154
|
-
1. 在 `src/entity-model/entitylist.md` 中查找匹配实体
|
|
155
|
-
2. 检查 `src/entity-model/<apiKey>.md` 是否存在
|
|
156
|
-
3. 不存在则运行:`python3 scripts/gen_entity_desc.py <项目目录> <apiKey>`
|
|
157
|
-
|
|
158
|
-
## 平台 API 参考
|
|
159
|
-
|
|
160
|
-
所有 API 携带 `Authorization: Bearer <access_token>`(上传文件接口),其他接口直接传 `access_token`。
|
|
161
|
-
|
|
162
|
-
- 获取 model.jar:`GET /rest/metadata/v2.0/scripts/packages/model/jar/url`
|
|
163
|
-
- 更新 model.jar:`POST /rest/metadata/v2.0/scripts/packages/model/jar`
|
|
164
|
-
- 获取实体列表:`GET /rest/metadata/v2.0/xobjects/filter?custom=<true|false>&active=true`
|
|
165
|
-
- 获取实体字段:`GET /rest/metadata/v2.0/xobjects/<apiKey>/items`
|
|
166
|
-
- 获取业务类型列表:`GET /rest/data/v2.0/xobjects/<xObjectApiKey>/busiType`
|
|
167
|
-
- 下载代码包:`GET /rest/metadata/v2.0/scripts/packages?packageName=<包名>`
|
|
168
|
-
- 创建代码包:`POST /rest/metadata/v2.0/scripts/packages`
|
|
169
|
-
- 上传代码包:`POST /rest/metadata/v2.0/scripts/packages/files?packageName=<包名>`
|
|
170
|
-
- 安装代码包:`POST /rest/metadata/v2.0/scripts/packages/installations`
|
|
171
|
-
- 卸载代码包:`DELETE /rest/metadata/v2.0/scripts/packages/installations/<包名>?force=<bool>`
|
|
172
|
-
- 创建计划作业:`POST /rest/metadata/v2.0/dx/logic/jobDetail`
|
|
173
|
-
- 更新计划作业:`PATCH /rest/metadata/v2.0/dx/logic/jobDetail/<jobId>`
|
|
174
|
-
|
|
175
|
-
## 注意事项
|
|
176
|
-
|
|
177
|
-
- Java 类名不能以 "test" 结尾
|
|
178
|
-
- Java 文件必须 UTF-8 无 BOM 编码
|
|
179
|
-
- Trigger 的 DataResult 数量必须与 TriggerRequest 数据量一致
|
|
180
|
-
- Package 名称必须三级且以 other 开始
|
|
181
|
-
- API 调用默认不触发 Trigger
|
|
182
|
-
- `getAttribute()` 返回 Object 类型,不能直接强转 String,必须用 `obj != null ? obj.toString() : ""`
|
|
183
|
-
- CRM 查询 SQL 不支持 `WHERE 1=1`,应使用 `WHERE id > 0` 作为基础条件
|
|
184
|
-
- `RkhdHttpClient.execute()` 需要 `ResponseBodyHandler` 第二参数,且沙箱禁止 `System.getProperty()`
|
|
185
|
-
- 内部平台 API(如获取商机阶段)建议由前端直接调用,后端 SDK 调用内部 API 存在限制
|
|
186
|
-
- 自定义 API 的实际调用路径是 `/rest/data/v2.0/scripts/api/{baseUrl}/{path}`,不是 `/rest/custom/v2.0/`
|
|
187
|
-
- 开发涉及业务对象的功能前,必须先通过 `gen_entity_desc.py` 获取实体的真实字段模型,避免字段名错误
|
|
188
|
-
- 授权配置详见 [references/auth-config.md](references/auth-config.md)
|
package/template/neo-bi-cmps/docs/neo-backend-dev/references/01-Trigger/345/274/200/345/217/221.md
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
# 技能包:Trigger 开发
|
|
2
|
-
|
|
3
|
-
## 概述
|
|
4
|
-
|
|
5
|
-
Trigger(触发器)用于在业务数据操作保存至数据库之前(before)或之后(after)增加自定义业务逻辑。
|
|
6
|
-
|
|
7
|
-
## 适用场景
|
|
8
|
-
|
|
9
|
-
- 创建数据时根据业务规则校验数据
|
|
10
|
-
- 编辑数据后自动同步至第三方系统
|
|
11
|
-
- 数据保存前自动填充/修改字段值
|
|
12
|
-
- 批量数据的查重校验
|
|
13
|
-
|
|
14
|
-
## 支持的操作
|
|
15
|
-
|
|
16
|
-
| 操作 | 说明 |
|
|
17
|
-
|------|------|
|
|
18
|
-
| add | 创建 |
|
|
19
|
-
| update | 更新 |
|
|
20
|
-
| delete | 删除 |
|
|
21
|
-
| transfer | 转移 |
|
|
22
|
-
| lock | 锁定 |
|
|
23
|
-
| unlock | 解锁 |
|
|
24
|
-
| recover | 从回收站恢复 |
|
|
25
|
-
|
|
26
|
-
## 代码模板
|
|
27
|
-
|
|
28
|
-
### 前置 Trigger(before)
|
|
29
|
-
|
|
30
|
-
```java
|
|
31
|
-
package other.{company}.{project};
|
|
32
|
-
|
|
33
|
-
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
|
|
34
|
-
import com.rkhd.platform.sdk.log.Logger;
|
|
35
|
-
import com.rkhd.platform.sdk.log.LoggerFactory;
|
|
36
|
-
import com.rkhd.platform.sdk.model.XObject;
|
|
37
|
-
import com.rkhd.platform.sdk.trigger.*;
|
|
38
|
-
|
|
39
|
-
import java.util.ArrayList;
|
|
40
|
-
import java.util.List;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* 前置 Trigger 模板
|
|
44
|
-
* 在数据保存到数据库之前执行,可修改数据或阻止保存
|
|
45
|
-
*/
|
|
46
|
-
public class BeforeTriggerTemplate implements Trigger {
|
|
47
|
-
|
|
48
|
-
private static final Logger LOG = LoggerFactory.getLogger();
|
|
49
|
-
|
|
50
|
-
@Override
|
|
51
|
-
public TriggerResponse execute(TriggerRequest request) throws ScriptBusinessException {
|
|
52
|
-
LOG.info("BeforeTrigger 开始执行, 操作: " + request.getOperate());
|
|
53
|
-
|
|
54
|
-
List<DataResult> results = new ArrayList<>();
|
|
55
|
-
|
|
56
|
-
for (XObject xObject : request.getDataList()) {
|
|
57
|
-
try {
|
|
58
|
-
// === 在此编写业务逻辑 ===
|
|
59
|
-
|
|
60
|
-
// 示例:修改字段值
|
|
61
|
-
// xObject.setAttribute("fieldApiName__c", "newValue");
|
|
62
|
-
|
|
63
|
-
// 示例:校验数据,不通过则阻止保存
|
|
64
|
-
// String name = xObject.getAttribute("name");
|
|
65
|
-
// if (name == null || name.isEmpty()) {
|
|
66
|
-
// results.add(new DataResult(false, "名称不能为空", xObject));
|
|
67
|
-
// if (!request.getPartialSuccess()) {
|
|
68
|
-
// return new TriggerResponse(false, "数据校验失败", results);
|
|
69
|
-
// }
|
|
70
|
-
// continue;
|
|
71
|
-
// }
|
|
72
|
-
|
|
73
|
-
results.add(new DataResult(true, "", xObject));
|
|
74
|
-
} catch (Exception e) {
|
|
75
|
-
LOG.error("处理数据异常: " + e.getMessage());
|
|
76
|
-
results.add(new DataResult(false, e.getMessage(), xObject));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return new TriggerResponse(true, "", results);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### 后置 Trigger(after)
|
|
86
|
-
|
|
87
|
-
```java
|
|
88
|
-
package other.{company}.{project};
|
|
89
|
-
|
|
90
|
-
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
|
|
91
|
-
import com.rkhd.platform.sdk.log.Logger;
|
|
92
|
-
import com.rkhd.platform.sdk.log.LoggerFactory;
|
|
93
|
-
import com.rkhd.platform.sdk.model.XObject;
|
|
94
|
-
import com.rkhd.platform.sdk.trigger.*;
|
|
95
|
-
|
|
96
|
-
import java.util.ArrayList;
|
|
97
|
-
import java.util.List;
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* 后置 Trigger 模板
|
|
101
|
-
* 在数据保存到数据库之后执行,可用于数据同步、通知等
|
|
102
|
-
*/
|
|
103
|
-
public class AfterTriggerTemplate implements Trigger {
|
|
104
|
-
|
|
105
|
-
private static final Logger LOG = LoggerFactory.getLogger();
|
|
106
|
-
|
|
107
|
-
@Override
|
|
108
|
-
public TriggerResponse execute(TriggerRequest request) throws ScriptBusinessException {
|
|
109
|
-
LOG.info("AfterTrigger 开始执行, 操作: " + request.getOperate());
|
|
110
|
-
|
|
111
|
-
List<DataResult> results = new ArrayList<>();
|
|
112
|
-
|
|
113
|
-
for (XObject xObject : request.getDataList()) {
|
|
114
|
-
try {
|
|
115
|
-
LOG.info("处理数据 ID: " + xObject.getId());
|
|
116
|
-
|
|
117
|
-
// === 在此编写业务逻辑 ===
|
|
118
|
-
|
|
119
|
-
// 示例:同步数据到外部系统
|
|
120
|
-
// syncToExternalSystem(xObject);
|
|
121
|
-
|
|
122
|
-
results.add(new DataResult(true, "成功", xObject));
|
|
123
|
-
} catch (Exception e) {
|
|
124
|
-
LOG.error("处理数据异常: " + e.getMessage());
|
|
125
|
-
results.add(new DataResult(false, e.getMessage(), xObject));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return new TriggerResponse(true, "成功", results);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 使用 TriggerContext 在 before/after 间传参
|
|
135
|
-
|
|
136
|
-
```java
|
|
137
|
-
// Before Trigger 中设置上下文
|
|
138
|
-
TriggerContext triggerContext = new TriggerContext();
|
|
139
|
-
triggerContext.set("key", "value");
|
|
140
|
-
return new TriggerResponse(true, "", results, triggerContext);
|
|
141
|
-
|
|
142
|
-
// After Trigger 中获取上下文
|
|
143
|
-
TriggerContext triggerContext = request.getTriggerContext();
|
|
144
|
-
String value = triggerContext.get("key");
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## 配置文件模板
|
|
148
|
-
|
|
149
|
-
scriptTrigger.xml:
|
|
150
|
-
|
|
151
|
-
```xml
|
|
152
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
153
|
-
<configs>
|
|
154
|
-
<config>
|
|
155
|
-
<!-- 前置 Trigger -->
|
|
156
|
-
<trigger>
|
|
157
|
-
<object>{objectApiKey}__c</object>
|
|
158
|
-
<operate>add</operate>
|
|
159
|
-
<position>before</position>
|
|
160
|
-
<order>1</order>
|
|
161
|
-
<class>other.{company}.{project}.trigger.BeforeTriggerTemplate</class>
|
|
162
|
-
</trigger>
|
|
163
|
-
<!-- 后置 Trigger -->
|
|
164
|
-
<trigger>
|
|
165
|
-
<object>{objectApiKey}__c</object>
|
|
166
|
-
<operate>add</operate>
|
|
167
|
-
<position>after</position>
|
|
168
|
-
<order>1</order>
|
|
169
|
-
<class>other.{company}.{project}.trigger.AfterTriggerTemplate</class>
|
|
170
|
-
</trigger>
|
|
171
|
-
</config>
|
|
172
|
-
</configs>
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## 开发注意事项
|
|
176
|
-
|
|
177
|
-
1. **类名不能以 "test" 结尾**
|
|
178
|
-
2. **Java 文件必须 UTF-8 无 BOM 编码**
|
|
179
|
-
3. **DataResult 数量必须与 TriggerRequest 数据量一致**
|
|
180
|
-
4. **return 必须返回 TriggerResponse 对象**
|
|
181
|
-
5. **Package 名称必须三级且以 other 开始**(如 `other.xsy.demo`),不能生成4级或以上的包名
|
|
182
|
-
6. **同步脚本最大运行时长 15 秒**,超时会被自动终止
|
|
183
|
-
7. **API 调用默认不触发 Trigger**
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# 技能包:自定义 API 开发
|
|
2
|
-
|
|
3
|
-
## 概述
|
|
4
|
-
|
|
5
|
-
自定义 API 允许开发者根据业务需求封装自定义的 REST API 接口,供外部系统或页面代码调用。
|
|
6
|
-
|
|
7
|
-
## 适用场景
|
|
8
|
-
|
|
9
|
-
- 封装复杂的业务查询逻辑为 API
|
|
10
|
-
- 为外部系统提供数据集成接口
|
|
11
|
-
- 为自定义页面提供后端数据服务
|
|
12
|
-
- 实现跨对象的复杂数据操作
|
|
13
|
-
|
|
14
|
-
## 代码模板
|
|
15
|
-
|
|
16
|
-
### GET 请求 API
|
|
17
|
-
|
|
18
|
-
```java
|
|
19
|
-
package other.{company}.{project};
|
|
20
|
-
|
|
21
|
-
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
|
|
22
|
-
import com.rkhd.platform.sdk.api.annotations.RestApi;
|
|
23
|
-
import com.rkhd.platform.sdk.api.annotations.RestMapping;
|
|
24
|
-
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
|
|
25
|
-
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
|
|
26
|
-
import com.rkhd.platform.sdk.log.Logger;
|
|
27
|
-
import com.rkhd.platform.sdk.log.LoggerFactory;
|
|
28
|
-
import com.rkhd.platform.sdk.model.QueryResult;
|
|
29
|
-
import com.rkhd.platform.sdk.model.XObject;
|
|
30
|
-
import com.rkhd.platform.sdk.service.XObjectService;
|
|
31
|
-
|
|
32
|
-
import com.alibaba.fastjson.JSONArray;
|
|
33
|
-
import com.alibaba.fastjson.JSONObject;
|
|
34
|
-
|
|
35
|
-
import java.util.List;
|
|
36
|
-
|
|
37
|
-
@RestApi(baseUrl = "/custom")
|
|
38
|
-
public class CustomGetApi {
|
|
39
|
-
|
|
40
|
-
private Logger log = LoggerFactory.getLogger();
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* GET 请求示例
|
|
44
|
-
* 访问路径: /rest/data/v2.0/scripts/api/getData?keyword=xxx
|
|
45
|
-
*/
|
|
46
|
-
@RestMapping(value = "/getData", method = RequestMethod.GET)
|
|
47
|
-
public String handleGet(@RestQueryParam("keyword") String keyword)
|
|
48
|
-
throws ApiEntityServiceException {
|
|
49
|
-
try {
|
|
50
|
-
log.info("收到查询请求, keyword: " + keyword);
|
|
51
|
-
|
|
52
|
-
// 查询数据
|
|
53
|
-
String sql = "SELECT id, name FROM account WHERE name LIKE '%" + keyword + "%' LIMIT 10";
|
|
54
|
-
QueryResult queryResult = XObjectService.instance().query(sql);
|
|
55
|
-
List<XObject> records = queryResult.getRecords();
|
|
56
|
-
|
|
57
|
-
// 构建返回结果
|
|
58
|
-
JSONObject result = new JSONObject();
|
|
59
|
-
JSONArray dataArray = new JSONArray();
|
|
60
|
-
|
|
61
|
-
if (records != null) {
|
|
62
|
-
for (XObject record : records) {
|
|
63
|
-
JSONObject item = new JSONObject();
|
|
64
|
-
item.put("id", record.getId());
|
|
65
|
-
item.put("name", record.getAttribute("name"));
|
|
66
|
-
dataArray.add(item);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
result.put("code", "200");
|
|
71
|
-
result.put("data", dataArray);
|
|
72
|
-
result.put("total", dataArray.size());
|
|
73
|
-
return result.toJSONString();
|
|
74
|
-
|
|
75
|
-
} catch (Exception e) {
|
|
76
|
-
log.error("查询异常: " + e.getMessage());
|
|
77
|
-
JSONObject error = new JSONObject();
|
|
78
|
-
error.put("code", "500");
|
|
79
|
-
error.put("message", e.getMessage());
|
|
80
|
-
return error.toJSONString();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### POST 请求 API
|
|
87
|
-
|
|
88
|
-
```java
|
|
89
|
-
package other.{company}.{project};
|
|
90
|
-
|
|
91
|
-
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
|
|
92
|
-
import com.rkhd.platform.sdk.api.annotations.RestApi;
|
|
93
|
-
import com.rkhd.platform.sdk.api.annotations.RestMapping;
|
|
94
|
-
import com.rkhd.platform.sdk.api.annotations.RestBeanParam;
|
|
95
|
-
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
|
|
96
|
-
import com.rkhd.platform.sdk.log.Logger;
|
|
97
|
-
import com.rkhd.platform.sdk.log.LoggerFactory;
|
|
98
|
-
import com.rkhd.platform.sdk.model.XObject;
|
|
99
|
-
import com.rkhd.platform.sdk.service.XObjectService;
|
|
100
|
-
|
|
101
|
-
import com.alibaba.fastjson.JSON;
|
|
102
|
-
import com.alibaba.fastjson.JSONObject;
|
|
103
|
-
|
|
104
|
-
@RestApi(baseUrl = "/custom")
|
|
105
|
-
public class CustomPostApi {
|
|
106
|
-
|
|
107
|
-
private Logger log = LoggerFactory.getLogger();
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* POST 请求示例
|
|
111
|
-
* 访问路径: /rest/data/v2.0/scripts/api/createData
|
|
112
|
-
* Content-Type: application/json
|
|
113
|
-
* 注意:POST方法参数必须使用 @RestBeanParam(name="xxx") 注解
|
|
114
|
-
*/
|
|
115
|
-
@RestMapping(value = "/createData", method = RequestMethod.POST)
|
|
116
|
-
public String handlePost(@RestBeanParam(name = "requestBody") String requestBody)
|
|
117
|
-
throws ApiEntityServiceException {
|
|
118
|
-
try {
|
|
119
|
-
log.info("收到创建请求, body: " + requestBody);
|
|
120
|
-
|
|
121
|
-
JSONObject body = JSON.parseObject(requestBody);
|
|
122
|
-
|
|
123
|
-
// 创建数据
|
|
124
|
-
// XObject xObject = new CustomEntity1__c();
|
|
125
|
-
// xObject.setAttribute("name", requestBody.getString("name"));
|
|
126
|
-
// xObject.setAttribute("entityType", MetadataService.instance()
|
|
127
|
-
// .getBusiType(xObject.getApiKey(), "defaultBusiType").getId());
|
|
128
|
-
// XObjectService.instance().insert(xObject);
|
|
129
|
-
|
|
130
|
-
JSONObject result = new JSONObject();
|
|
131
|
-
result.put("code", "200");
|
|
132
|
-
result.put("message", "创建成功");
|
|
133
|
-
return result.toJSONString();
|
|
134
|
-
|
|
135
|
-
} catch (Exception e) {
|
|
136
|
-
log.error("创建异常: " + e.getMessage());
|
|
137
|
-
JSONObject error = new JSONObject();
|
|
138
|
-
error.put("code", "500");
|
|
139
|
-
error.put("message", e.getMessage());
|
|
140
|
-
return error.toJSONString();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## 配置文件模板
|
|
147
|
-
|
|
148
|
-
scriptTrigger.xml:
|
|
149
|
-
|
|
150
|
-
```xml
|
|
151
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
152
|
-
<configs>
|
|
153
|
-
<config>
|
|
154
|
-
<customApi>
|
|
155
|
-
<class>other.{company}.{project}.api.CustomGetApi</class>
|
|
156
|
-
</customApi>
|
|
157
|
-
<customApi>
|
|
158
|
-
<class>other.{company}.{project}.api.CustomPostApi</class>
|
|
159
|
-
</customApi>
|
|
160
|
-
</config>
|
|
161
|
-
</configs>
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## 调用方式
|
|
165
|
-
|
|
166
|
-
### 外部调用
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
GET https://api.xiaoshouyi.com/rest/data/v2.0/scripts/api/getData?keyword=xxx
|
|
170
|
-
POST https://api.xiaoshouyi.com/rest/data/v2.0/scripts/api/createData
|
|
171
|
-
|
|
172
|
-
Header:
|
|
173
|
-
Authorization: Bearer {access_token}
|
|
174
|
-
Content-Type: application/json
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### 页面代码中调用(NeoLappSdk.js)
|
|
178
|
-
|
|
179
|
-
```javascript
|
|
180
|
-
lapp.connection.invoke({
|
|
181
|
-
url: '/rest/data/v2.0/scripts/api/getData?keyword=test',
|
|
182
|
-
method: 'GET'
|
|
183
|
-
}).then(
|
|
184
|
-
res => { console.log(res); },
|
|
185
|
-
err => { console.log(err); }
|
|
186
|
-
)
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## 注意事项
|
|
190
|
-
|
|
191
|
-
1. 自定义 API 入参最大值 **15 MB**
|
|
192
|
-
2. 外部并发调用限制:用户级 **15 次/秒**,租户级 **50 次/秒**
|
|
193
|
-
3. 第三方包仅支持 **fastJson** 和 **commons-lang**
|
|
194
|
-
4. POST 方法参数必须使用 `@RestBeanParam(name="xxx")` 注解,不能直接用裸参数
|
|
195
|
-
5. `QueryResult.getRecords()` 返回 `List<XObject>`,没有 `getTotalSize()` 方法,需通过 `records.size()` 或单独 count 查询获取总数
|
|
196
|
-
6. Package 名称必须三级且以 other 开始(如 `other.xsy.pipeline`),不能生成四级包名
|