# 前端扩展参考
# 1、项目独立
统一提供源代码,直接修改。
# 2、前后端分离
1)devops-web项目:基于VUE(ElementUI)的前端项目
# 3、前后端接口同步
1) 修改 scripts/buildApi.js 中 swagger.json 的在线地址
2) 运行 npm run build:api
... ... (function () { // 读取 在线 swagger var url = "http://10.15.15.109:8080/swagger/swagger.json"; execute(url).then((data) => { console.log(`read ${url} ...`) mapAction(data) }).then(() => { console.log('create controller') createController() }) })()
# 4、静态资源
(图片文件, 非npm管理的第三方js库) 统一放在 /static 目录下
# 5、动态表单自定义事件扩展
1) 所有自定义事件统一写在 该文件里 /src/views/project/deploy/release/env-deploy/dynamic-form-events.js
2) 提供三种事件 init (控件初始化时执行), onvaluechanged (控件值变化时执行) , all (以上两者都执行).
3) 事件接受两个参数 (attrValue, $this) 分别为控件当前值 attrValue 和 表单上下文&this, 其中$this提供以下 api
1. $this.getCtrl(refName) ------------ 获得控件对象
2. $this.getSelectObject(refName) ------------ 获得选中的控件对象
3. $this.setAttrValue(refName, attrValue) ------------ 设置控件值
4. $this.getAttrValue(refName) ------------ 获得控件值
5. $this.hiddenComponents.add(refName) ------------ 隐藏控件
6. $this.hiddenComponents.delete(refName) ------------ 显示控件
7. $this.getCtrl(refName).setUrl(url) ------------ 设置下拉列表数据源
示例如下:
"10000000": { //defId "defName": 'scriptType', "events": { "onvaluechanged": (attrValue, $this) => { $this.hiddenComponents.add("resources") $this.getAttrValue("resources") $this.setAttrValue("resources","demo") $this.hiddenComponents.delete("resources") $this.getCtrl("resources").setUrl("/api/demo?name=demo") }, "init": (attrValue, $this) => { ... }, "all": (attrValue, $this) => { ... }, } },
# 6、权限扩展
1) 在 /src/permission/FuncCode.txt 里增加权限代码 名称 类型, 注意中间用 空格 隔开
2) 运行 npm run build:permission (需提前安装 babel-node: npm i -g babel-node )
# 7、路由扩展
1) 修改 /src/router/index.js
# 后端扩展参考
# 1、实现:
统一使用springbean实现业务逻辑,所有的接口,均存放于devops-specs项目的com.primeton.devops.specs.api构件包中
注意: 包名需要是com.primeton.devops.为前缀的,否则需要在spring.xml中配置包扫描。
1)单实现业务:
使用@Order注解实现(值越小,优先级越高,系统提供的实现为int最大值),使用@Autowired注解注入引用。示例如下:
//业务实现 @Service @Order(100) public class UserServiceExtend extends UserService { @Override public LoginResult login(String userName, String password) throws Exception { ... } ... } @Controller public class UserController implements IUserController { //引用注入 @Autowired private IUserService userService; ... }
2)多实现业务:
使用EnforcedServiceLoader方式引用加载,配置文件在构件包的META-INF/services目录下,文件名为接口名。示例如下:
配置文件com.primeton.devops.specs.api.pcm.IWorklistApprovalActionService:
#com.primeton.devops.specs.api.pcm.IWorklistApprovalActionService接口实现 com.primeton.devops.pcm.helper.ReleaseWorklistApprovalActionService,WorklistType=RELEASE_APPROVAL com.primeton.devops.pcm.helper.ReleaseConfirmWorklistApprovalActionService,WorklistType=RELEASE_CONFIRM com.primeton.devops.pcm.helper.ReleaseTaskConfirmWorklistApprovalActionService,WorklistType=RELEASE_TASK_CONFIRM com.primeton.devops.pcm.helper.CodeMergeWorklistApprovalActionService,WorklistType=CODE_MERGE_APPROVAL com.primeton.devops.pcm.helper.ProjectCreateApprovalActionService,WorklistType=PROJECT_CREATE_APPROVAL
实现使用加载示例代码:
EnforcedServiceLoader<IWorklistApprovalActionService> serviceLoader = EnforcedServiceLoader.load(IWorklistApprovalActionService.class); Map<String, String> property = new HashMap<String, String>(); property.put("WorklistType", worklistApproval.getWorklistType()); IWorklistApprovalActionService worklistApprovalActionService = serviceLoader.getService(property, false, false);
# 2、事务控制
如果是自己写的独立线程发起,需要调用TransitionUtil的方法进行业务处理;否则不用关心事务问题。TransitionUtil方法如下:
/** * 生成包含事务控制的固定的线程执行器 * * @param nThreads 线程数 * @param isDaemon 是否是daemon线程 * @param threadName 线程名称 * @return 线程执行器 */ public static ThreadPoolExecutorWithTx newFixedThreadPoolExecutorWithTx(int nThreads, boolean isDaemon, String threadName); /** * 生成包含事务控制的线程 * * @param isDaemon 是否是daemon线程 * @param threadName 线程名称 * @return 线程 */ public static ThreadWithTx newThreadWithTx(boolean isDaemon, String threadName); /** * 在事务中执行,没有线程的情况下 */ public static <T> T executeWithTx(Callable<T> call) throws Exception;
# 3、错误信息统一前后端处理,处理规范如下:
1) 定义一个实现com.primeton.devops.specs.exception.DevOps.ErrorCode接口的枚举类,错误信息由错误码、错误信息和格式化参数构成,使用异常抛出。
注意:错误信息可以有国际化,如果有国际化,前端会显示国际化后的错误信息,否则会统一显示“系统错误,请联系管理员.”。
定义示例:
//有国际化信息 PROJECT_ALREADY_EXISTED("en=>Project[{0}] already existed.", "zh_CN=>项目[{0}]已存在。"), //无国际化 LOCK_ACQUIRED_TIMEOUT("Lock acquired tomeout: [lockType={0}][lockId={1}][timeout={2}]."),
使用示例:
throw new DevOpsException(DevOps.PM.PROJECT_ALREADY_EXISTED, >project.getProjectCode());
扩展示例:
public enum XXX implements ErrorCode { XXXXX_ALREADY_EXISTED("en=>XXXXX[{0}] already existed.", "zh_CN=>XXXXX[{0}]已存在。"), ... ; private XXX(String... localeMessages) { setMessages(localeMessages); } }
2) 前端请求是设置head中的“Locale”信息,得到的错误信息对象格式(Json串):
{ "errorCode": "DEVOPS_PM_PROJECT_ALREADY_EXISTED", "errorLocalizedMessage": "项目[DEMOA]已存在。", "errorMessage": "Project[DEMOA] already existed." }
# 4、devops的后端jar包(包含所有的接口和实现类)
如果是Maven工程,可以把jar包上传到maven仓库中。GAV信息设置如下:
<groupId>com.primeton.devops</groupId> <artifactId>devops</artifactId> <version>6.2.0.0</version>