开源测试工具 [普兰能效平台] 研发协作一站式管理平台 (http://www.seqcer.com) 开源

槽神 · December 11, 2019 · Last by 槽神 replied at January 08, 2020 · 4834 hits

说明

  • 社区开源地址
  • SEPP(Software Engineering Productivity Platform),研发能效平台。平台结合了成熟了项目管理体系和过程模型,贯穿敏捷产品研发生命周期的一站式服务。
  • 现如今类似的协作工作非常多,比如JIRA、福报厂的teambition、鹅厂的TAPD、度娘的iCafe、平安系的神兵,以及古老的禅道等等,各有各的特色!最初我们在用一些只关注项目或者敏捷协作的工具,后来发现一些过程的细节管理需要集成类似Testlink、Jenkins等很多工具来弥补。再后来看到那么多的过程数据躺在那里毫无价值,我们就想用一些数据挖掘的技巧来分析研发过程的效率。
  • 由于一些不可说的原因,我们没能第一时间采购到JIRA这种牛X的工具,我就索性自己用最简单、时兴的技术栈撸了一个,一边用一边跟研发、测试、项目团队的兄弟们撕;一边规划一边改……同时还要一边努力地拒绝一些来自高管的奇怪需求(或许接纳了更多,嘿嘿)。
  • 经过一年的使用和打磨,我们觉得差不多基本框架成型了,还有很多基础工具链的集成虽然没有全部完成,也就是时间的问题了,所以就申请把这个东西开源了。其实并不是做成一个什么样的产品,只是想给一些初学者一点参考的东西和学习的信心,因为我们也是野路子测开出身。
  • 几大缺陷:
    • 整个管理风格看起来很CMM,如果觉得不能接受,希望给点建设性建议;
    • 开源的功能肯定不完整,毕竟是企业内部应用;
    • 后端代码勉强能看,但是基本跟设计模式无关,妥妥的CRUD大合集;前端代码模块化没做,写得比较乱;
    • 没怎么写文档,但是流程上的控制逻辑比较复杂,而且自定义支持得比较少

演示地址

http://www.seqcer.com

  • 推荐注册,并创建自己的项目,便于隔离数据胡搞而不影响其他试用者
  • 仅对chrome浏览器做了完全适配,其他chromium核心浏览器或者firefox、safari也能使用,但是不推荐

仓库地址:

本地化部署问题解决步骤:

  • 先赏个STAR
  • 再加QQ群:362260709
  • 再问问题,当然,建议提问之前仔细看完下面的说明

技术栈

  • 前端:vue2、axios、element等等等等
  • 后端:springboot、guava、lombok等等等等
  • 基础组件:mariadb(10.3)、nginx(1.15.3)、nodejs(8.12.0)、fastdfs、npm(6.7.0)、webpack4等等
  • 插件:swagger2、quartz、aviator、h2等等

后端

启动方式:
  • Main Class:com.pr.sepp.SeppApplication(线上可注释掉@EnableSwagger2
  • 本地VM options:-Denv=local
  • 注意:本地开发请务必安装好IDE的lombok插件
  • 线上部署:
    • rm -rf src/main/resources/spring.properties
    • mvn clean package -Dmaven.test.skip=true
    • mv target/sepp*.jar ${your_path}/sepp.jar
    • java -Dpath=${your_conf_path}/spring.properties -jar ${your_path}/sepp.jar &
  • 集群:已测试HAProxy、keepalived,其余未测试
组件使用说明
  • mariadb(>= 10.3),必须设置lower_case_table_names=1,参考conf/database/my.conf
  • FastDfs,与nginx绑定使用,二者配置参考conf/fastdfs/*.properties、conf/nginx/*.properties
  • octopus监控需要配置octopus.admin.address和context.env两个参数
  • Quartz请注意spring-boot-starter-quartz和boot版本的兼容性问题,最好自己指定版本(参考pom.xml)
  • 邮件服务、Jenkins服务、git仓库服务、sonarQube服务、LDAP认证服务,皆可使用超级管理员进入系统设置进行配置,持久化到数据库,同时Jenkins服务和邮件服务也可以通过配置文件实现,其中Jenkins使用持久化的配置需要配置jenkins.enable-programmatic=false
  • 基础设施>>监控中心,请参考:https://github.com/fudax/octopus 工程说明,并且更新spring.properties和前端src/components/monitor/MonitorAdmin.vue文件配置

前端

安装步骤

git clone https://github.com/purang-fintech/seppf.git
cd seppf
npm install

本地开发,默认服务端口8080

npm run dev

构建生产

npm run build

License

MIT

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 24 条回复 时间 点赞

@0x88 你要的东西来了

槽神 回复

感谢大佬的分享

顶!有东西可以来分享啦~

果断start 支持。 我也在做,很多东西可以参考学习。


dev.dev.js 文件缺失
直接test.js 好像可以用

米阳MeYoung 回复

提交的时候不知道怎么漏掉了,已经好了

槽神 回复

谢谢大佬

虽然没看代码,但是技术栈就很不错,赞。

未提交代码的组件权限控制设计:

权限系统-1.资源配置

目前权限系统的权限控制粒度能控制到按钮级别,按钮和接口权限同步,同时保证前端实现权限控制的同时,保证后端服务的安全(接口权限)

一:菜单入口

权限配置->资源配置

二:权限配置

1.通过菜单入口进入权限资源配置页面

2.添加对应的资源权限

a.组件名:该值是按钮所属页面组件的名称()

b.组件id:该值是开发自己赋予的值(该值要确保在当前页面是唯一的)

c.接口:该按钮功能下对应的接口权限(按钮可能存在一对多的情况,目前支持单一接口的权限)

d.接口类型:略

e.角色:按钮和接口对应的角色

f.是否生效:略

三:前端组件使用

目前前端提供了两个权限组件用于权限控制(auth.js、has.js)

1.指令v-auth
使用该指令后,就可以通过页面配置权限的方式动态的给使用该指令的按钮分配权限
对于需要权限控制的按钮

例如资源配置里的删除按钮

<el-button v-auth="{id:'deleteResource',component:'ResourceConfig'}" icon="el-icon-delete" @click="deleteResourceConfig(scope.row)" type="text"
class="oper-button"
style="
color:#EE6F6F"></el-button>
v-auth指令中两个必须参数;id该页面中该按钮的唯一标识;component为当前组件的name

注意:在确认使用v-has的时候必须在该组件测created方法中加入this.$auth();

如图:

所以前端使用v-auth指令分两三步:
  • 1.在需要的按钮上加上v-auth(并添加唯一的标识id,同时加上当前组件name)
  • 2.在当前组件的created方法调用this.$auth()
  • 3.请到配置页面配置相应的按钮权限
2.v-has指令
v-has指令属于前端控制指令、仅对前端的按钮做权限控制,适合资源配置页面,虽然资源配置页面也使用v-auth指令,但是对于资源配置页面的按钮权限来说,使用v-has更加合适
<el-button v-has="['admin']" style="float: right; padding: 3px 0" type="text" @click="addResource">添加</el-button>

v-has指令的参数为数组形式,可以加入多个角色,在这里个人不推荐使用id作为参数,而是采用code

前端指令代码

1.auth.js

function install(Vue, options = {}) {
Vue.directive(options.name || "auth", {
inserted(el, binding) {
if (!check(binding.value)) {
el.parentNode && el.parentNode.removeChild(el);
}
}
});
}

function getCurrentAuthority() {
return JSON.parse(localStorage.getItem("roleIds"));
}

function check(authInfo) {
const currentAuthority = getCurrentAuthority();
alert(this.$options.name);
let auth = localStorage.getItem(authInfo.component);
let authJson = JSON.parse(auth);
for (let authData of authJson) {
if (authData.authId == authInfo.id) {
return currentAuthority.some(item => authData.roleIds.includes(item));
}
}
return false;
}

export default {install};

2.has.js

function install(Vue, options = {}) {
Vue.directive(options.name || "has", {
inserted(el, binding) {
if (!check(binding.value)) {
el.parentNode && el.parentNode.removeChild(el);
}
}
});
}


function getCurrentAuthority() {
return JSON.parse(localStorage.getItem("roleCodes"));
}

function check(roles) {
return getCurrentAuthority().some(item => roles.includes(item));;
}

export default {install};

四:后端接口控制

对于在资源配置页面配置过的接口需要在后端接口加上相应的权限标识,以让配置生效

例如在上面配置的删除资源配置的权限接口可以加上@ApiPermission注解以让该接口的权限生效

注解@ApiPermission的使用
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiPermission {

Role[] roles() default ALL;

boolean dynamic() default true;

RoleGroup[] groups() default RoleGroup.ALL;

enum RoleGroup {
ALL
}

}

目前该注解有三个参数:roles、dynamic、groups

groups可以忽略

rolesdynamic是成对出现的,如果我们不想动态配置接口的权限,可以将dynamic设置为false,然后设置roles,否则单独设置roles并不会生效,因为默认情况dynamictrue会从数据库读取相关角色信息
槽神 #10 · December 18, 2019 作者

@米阳MeYoung 看声明

槽神 回复

嗯嗯 我用了8.X的还是 dev 可以 build 报错。

槽神 回复

大佬 加群麻烦通过下。

部署后端的时候 最后一步报错了 java -Dpath=/opt/seppb/conf/spring.properties -jar /opt/seppb/sepp.jar &
提示:Unable to access jarfile /opt/seppb/sepp.jar

槽神 #14 · December 19, 2019 作者
妞妞 回复

……
那你自己不会写一句么:

mv target/sepp*.jar /opt/seppb/sepp.jar
槽神 #15 · December 19, 2019 作者

添加了几张基本的逻辑控制说明思维导图

槽神 #17 · December 26, 2019 作者
阿三 回复

No space left on device……百度一下啥意思吧,google就算了,看不懂

18Floor has been deleted
19Floor has been deleted
槽神 回复

这个编译失败?

阿三 回复

我也是同样的报错,楼主可否提供一下jdk版本和maven版本,github说明太粗略。谢谢

魔幻云 回复

1、你是IDE报错还是命令行mvn package报错?
2、你确定你的代码版本是最新的吗?
3、你确定你按照readme一步一步操作了没有?
4、我这pom.xml写的清清楚楚,您还需要什么信息,我一个个给您找?

槽神 回复

环境如下:
1.java:1.8.0_181
2.maven版本:apache-maven-3.6.0

构建命令:使用官方
1.mvn clean package -Dmaven.test.skip=true
2.官方图

3.git代码分支:master,日志版本信息如下:

备注:我们这边仅先尝试部署起来进行功能查看,所以要是能直接提供jar包,我就不必本地构建啦。

报错信息:

[INFO] /geelyapp/seppb/src/main/java/com/pr/sepp/utils/fasfdfs/conn/FdfsConnectionPool.java: Recompile with -Xlint:unchecked for details.
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /geelyapp/seppb/src/main/java/com/pr/sepp/utils/jenkins/JenkinsClientManager.java:[34,89] cannot find symbol
symbol: method getBuildJenkinsClientProviderMap()
location: variable jenkinsClientProvider of type com.pr.sepp.utils.jenkins.JenkinsClientProvider
[ERROR] /geelyapp/seppb/src/main/java/com/pr/sepp/utils/jenkins/JenkinsClientManager.java:[37,84] cannot find symbol
symbol: method getJenkinsClientProviderMap()
location: variable jenkinsClientProvider of type com.pr.sepp.utils.jenkins.JenkinsClientProvider
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23.076 s
[INFO] Finished at: 2020-01-08T09:12:05+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project sepp: Compilation failure: Compilation failure:
[ERROR] /geelyapp/seppb/src/main/java/com/pr/sepp/utils/jenkins/JenkinsClientManager.java:[34,89] cannot find symbol
[ERROR] symbol: method getBuildJenkinsClientProviderMap()
[ERROR] location: variable jenkinsClientProvider of type com.pr.sepp.utils.jenkins.JenkinsClientProvider
[ERROR] /geelyapp/seppb/src/main/java/com/pr/sepp/utils/jenkins/JenkinsClientManager.java:[37,84] cannot find symbol
[ERROR] symbol: method getJenkinsClientProviderMap()
[ERROR] location: variable jenkinsClientProvider of type com.pr.sepp.utils.jenkins.JenkinsClientProvider
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project sepp: Compilation failure
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1161)
at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:168)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

槽神 #24 · January 08, 2020 作者
魔幻云 回复

不好意思,代码内外版本同步有误,已解决,请重新拉代码,应该能解决问题

槽神 回复

谢谢大佬,构建可以了,不过还有一个问题配置文件里面的AES加密(密钥采用里面默认自定义)提示解密失败
配置如下:

dbc.username=这个地方换成自己加密后的user
jdbc.password=换成加密后的pwd
signing.secret=1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ

槽神 #26 · January 08, 2020 作者
魔幻云 回复

看代码,加解密的key要一致,源码里默认是写死的,没有给你配置的机会😂

private static final String ERROR_EN_MSG = "用户名密码解密失败";
private static final String ERROR_DE_MSG = "用户名密码解密失败";
private static final String CIPHER_INSTANCE = "AES/CBC/PKCS5Padding";
private static final String SERIAL_KEY = "0102030405060708";
private static final String ENCRYPT_STYLE = "AES";
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up