diff --git a/.gitignore b/.gitignore
index a1c2a23..16be3b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,5 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+.idea/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c5c3627
--- /dev/null
+++ b/README.md
@@ -0,0 +1,47 @@
+## 禅道java版sdk工具包
+基于禅道开源版18.1封装的java版sdk工具包,对于高版本的是否兼容还需要测试
+
+### 功能描述
+利用禅道开放的第三方应用接口,封装的java版sdk工具包,可通过java代码的方式创建项目、执行、任务等常用接口。
+大部分接口是直接使用的禅道开放的接口,小部分接口是通过模拟浏览器的方式实现的。
+
+### 免责声明
+SDK源码编写完成后仅简单应用了项目、执行、任务的创建、开始、关闭等功能,未进行大规模测试。
+此仓库的源码是从项目上剥离出来的源码,使用时请备份数据,并进行严格测试,确保安全后再上线使用。
+
+### 开发环境
+jdk 8+
+
+### 构建工具
+Maven 3+
+
+### 编译命令
+```
+mvn package
+```
+如果编译报错,可以尝试更换maven版本或使用最新maven版本
+
+### 使用说明
+#### 引用方式
+1. 直接引入jar包
+2. 引入源码
+
+#### 创建凭证
+使用禅道管理员账号登录,依次找到左侧菜单栏【后台】-【二次开发】-【应用】-【添加应用】
+得到代号+密钥就是接入凭证
+
+#### 创建管理账号
+创建一个专门的管理账号,拥有管理员权限。例如我创建的是pms账号
+
+#### 使用方法
+参考 ClientTest.java
+
+##### 版本说明
+###### v0.0.1-SNAPSHOT
+1. 项目的创建、删除、修改、开始、激活、关闭
+2. 执行的创建、删除、开始、激活、关闭
+3. 任务的创建、删除、开始、激活、关闭、完成
+4. 用户的获取
+
+### 联系方式
+E-Mail:wangbing@wbsite.xyz
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c1ee6b1
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,71 @@
+
+
+ * 基于开源版本18.1开发
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZentaoClient {
+
+ /**
+ * 普通禅道账户
+ */
+ private static Map
+ * 要求managerAccount账户有管理员权限
+ */
+ public List
+ * 禅道查询条件是设置在session中的,所有查询之前先设置参数
+ */
+ private boolean setQuery(int projectId, String fieldName, String fieldValue) {
+ try {
+ String url = StrUtil.format("/search-buildQuery.html");
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("fieldname", "");
+ httpRequest.form("fieldid", "");
+ httpRequest.form("fieldstatus", "0");
+ httpRequest.form("fieldproject", "0");
+ httpRequest.form("fieldPM", "");
+ httpRequest.form("fieldopenedBy", "");
+ httpRequest.form("fieldopenedDate", "");
+ httpRequest.form("fieldbegin", "");
+ httpRequest.form("fieldend", "");
+ httpRequest.form("fieldrealBegan", "");
+ httpRequest.form("fieldrealEnd", "");
+ httpRequest.form("fieldclosedBy", "");
+ httpRequest.form("fieldlastEditedDate", "");
+ httpRequest.form("fieldclosedDate", "");
+ httpRequest.form("fieldteamCount", "");
+ httpRequest.form("andOr1", "AND");
+ httpRequest.form("field1", fieldName);
+ httpRequest.form("operator1", "=");
+ httpRequest.form("value1", fieldValue);
+ httpRequest.form("andOr2", "and");
+ httpRequest.form("field2", "id");
+ httpRequest.form("operator2", "=");
+ httpRequest.form("value2", "");
+ httpRequest.form("andOr3", "and");
+ httpRequest.form("field3", "status");
+ httpRequest.form("operator3", "=");
+ httpRequest.form("value3", "0");
+ httpRequest.form("groupAndOr", "and");
+ httpRequest.form("andOr4", "AND");
+ httpRequest.form("field4", "project");
+ httpRequest.form("operator4", "=");
+ httpRequest.form("value4", projectId);
+ httpRequest.form("andOr5", "and");
+ httpRequest.form("field5", "PM");
+ httpRequest.form("operator5", "=");
+ httpRequest.form("value5", "");
+ httpRequest.form("andOr6", "and");
+ httpRequest.form("field6", "openedBy");
+ httpRequest.form("operator6", "=");
+ httpRequest.form("value6", "");
+ httpRequest.form("module", "execution");
+ httpRequest.form("actionURL", "/execution-all-bySearch-order_asc-0-myQueryID.html");
+ httpRequest.form("groupItems", "3");
+ httpRequest.form("formType", "lite");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ return false;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ return execute.getStatus() == HttpStatus.HTTP_OK;
+ } catch (Exception e) {
+ StaticLog.error(e);
+ }
+ return false;
+ }
+
+ /**
+ * 通过执行名称获取执行
+ */
+ public ZtExecutionGetResponse getByName(int projectId, String name) {
+ ZtExecutionGetResponse response = new ZtExecutionGetResponse();
+ try {
+ boolean setQuery = setQuery(projectId, "name", name);
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml("/execution-all-bySearch-order_asc-0-myQueryID.html");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select(".main-table .sortable tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtExecution ztExecution = new ZtExecution();
+ ztExecution.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztExecution.setName(tr.select(".c-name").attr("title"));
+ ztExecution.setCode(tr.select(".c-code").attr("title"));
+ ztExecution.setProjectId(projectId);
+ ztExecution.setProjectName(tr.select(".c-project").attr("title"));
+ ztExecution.setPm(tr.select(".c-PM").text());
+ ztExecution.setStatus(tr.select(".c-status").text());
+ ztExecution.setProgress(tr.select(".c-progress").text());
+ ztExecution.setBegin(tr.select(".c-begin").text());
+ ztExecution.setEnd(tr.select(".c-end").text());
+ ztExecution.setEstimate(tr.select(".c-estimate").text());
+ ztExecution.setConsumed(tr.select(".c-consumed").text());
+ ztExecution.setLeft(tr.select(".c-left").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztExecution);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 通过项目编码获取项目
+ */
+ public ZtExecutionGetResponse getByCode(int projectId, String code) {
+ ZtExecutionGetResponse response = new ZtExecutionGetResponse();
+ try {
+ boolean setQuery = setQuery(projectId, "code", code);
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml("/execution-all-bySearch-order_asc-0-myQueryID.html");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select(".main-table .sortable tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtExecution ztExecution = new ZtExecution();
+ ztExecution.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztExecution.setName(tr.select(".c-name").attr("title"));
+ ztExecution.setCode(tr.select(".c-code").attr("title"));
+ ztExecution.setProjectId(projectId);
+ ztExecution.setProjectName(tr.select(".c-project").attr("title"));
+ ztExecution.setPm(tr.select(".c-PM").text());
+ ztExecution.setStatus(tr.select(".c-status").text());
+ ztExecution.setProgress(tr.select(".c-progress").text());
+ ztExecution.setBegin(tr.select(".c-begin").text());
+ ztExecution.setEnd(tr.select(".c-end").text());
+ ztExecution.setEstimate(tr.select(".c-estimate").text());
+ ztExecution.setConsumed(tr.select(".c-consumed").text());
+ ztExecution.setLeft(tr.select(".c-left").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztExecution);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/execution/ent/ZtExecution.java b/src/main/java/xyz/wbsite/zentao/sdk/execution/ent/ZtExecution.java
new file mode 100644
index 0000000..cce6cb4
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/execution/ent/ZtExecution.java
@@ -0,0 +1,168 @@
+package xyz.wbsite.zentao.sdk.execution.ent;
+
+/**
+ * 禅道执行信息
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtExecution {
+
+ /**
+ * 执行ID
+ */
+ private int id;
+ /**
+ * 执行名称
+ */
+ private String name;
+ /**
+ * 执行代号
+ */
+ private String code;
+ /**
+ * 项目ID
+ */
+ private int projectId;
+ /**
+ * 项目名称
+ */
+ private String projectName;
+ /**
+ * 执行产品经理
+ */
+ private String pm;
+ /**
+ * 执行状态
+ */
+ private String status;
+ /**
+ * 进度
+ */
+ private String progress;
+ /**
+ * 计划开始时间
+ */
+ private String begin;
+ /**
+ * 计划完成时间
+ */
+ private String end;
+ /**
+ * 预计工时
+ */
+ private String estimate;
+ /**
+ * 消耗工时
+ */
+ private String consumed;
+ /**
+ * 剩余工时
+ */
+ private String left;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public int getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(int projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+ public String getPm() {
+ return pm;
+ }
+
+ public void setPm(String pm) {
+ this.pm = pm;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getProgress() {
+ return progress;
+ }
+
+ public void setProgress(String progress) {
+ this.progress = progress;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public String getEstimate() {
+ return estimate;
+ }
+
+ public void setEstimate(String estimate) {
+ this.estimate = estimate;
+ }
+
+ public String getConsumed() {
+ return consumed;
+ }
+
+ public void setConsumed(String consumed) {
+ this.consumed = consumed;
+ }
+
+ public String getLeft() {
+ return left;
+ }
+
+ public void setLeft(String left) {
+ this.left = left;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionActivateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionActivateRequest.java
new file mode 100644
index 0000000..0593279
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionActivateRequest.java
@@ -0,0 +1,64 @@
+package xyz.wbsite.zentao.sdk.execution.req;
+
+/**
+ * 禅道执行激活请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtExecutionActivateRequest {
+
+ private int executionId;
+
+ private String begin;
+
+ private String end;
+
+ /**
+ * 是否重新调整时间 0/1
+ */
+ private String readjustTime;
+
+ private String comment;
+
+ public int getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(int executionId) {
+ this.executionId = executionId;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public String getReadjustTime() {
+ return readjustTime;
+ }
+
+ public void setReadjustTime(String readjustTime) {
+ this.readjustTime = readjustTime;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCloseRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCloseRequest.java
new file mode 100644
index 0000000..7a6ee4a
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCloseRequest.java
@@ -0,0 +1,41 @@
+package xyz.wbsite.zentao.sdk.execution.req;
+
+/**
+ * 禅道执行关闭请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtExecutionCloseRequest {
+
+ private int executionId;
+
+ private String comment;
+
+ private String realEnd;
+
+ public int getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(int executionId) {
+ this.executionId = executionId;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String getRealEnd() {
+ return realEnd;
+ }
+
+ public void setRealEnd(String realEnd) {
+ this.realEnd = realEnd;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCreateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCreateRequest.java
new file mode 100644
index 0000000..05e2c32
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/execution/req/ZtExecutionCreateRequest.java
@@ -0,0 +1,222 @@
+package xyz.wbsite.zentao.sdk.execution.req;
+
+import java.util.List;
+
+/**
+ * 禅道执行创建请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtExecutionCreateRequest {
+
+ private int project;
+ private String name;
+ private String code;
+ /**
+ * 开始日期2023-11-09
+ */
+ private String begin;
+ /**
+ * 结束日期2024-11-07
+ */
+ private String end;
+ /**
+ * 总耗时天数
+ */
+ private int delta;
+ /**
+ * 可用工作日
+ */
+ private int days;
+ /**
+ * 执行类型short/long/ops
+ */
+ private String lifetime;
+ /**
+ * 团队名称可空
+ */
+ private String team;
+ /**
+ * 需要复制得团队,和团队名称必填一个
+ * 值为zt_project的id
+ */
+ private int teams;
+ /**
+ * 需求负责人
+ */
+ private String po;
+ /**
+ * 测试负责人
+ */
+ private String qd;
+ /**
+ * 迭代负责人
+ */
+ private String pm;
+ /**
+ * 发布负责人
+ */
+ private String rd;
+ /**
+ * 团队成员
+ */
+ private List
+ * 禅道查询条件是设置在session中的,所有查询之前先设置参数
+ */
+ private boolean setQuery(String fieldName, String fieldValue) {
+ try {
+ String url = StrUtil.format("/search-buildQuery.html");
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("fieldname", "");
+ httpRequest.form("fieldcode", "");
+ httpRequest.form("fieldid", "");
+ httpRequest.form("fieldmodel", "");
+ httpRequest.form("fieldhasProduct", "");
+ httpRequest.form("fieldparent", "0");
+ httpRequest.form("fieldstatus", "");
+ httpRequest.form("fielddesc", "");
+ httpRequest.form("fieldPM", "");
+ httpRequest.form("fieldopenedDate", "");
+ httpRequest.form("fieldbegin", "");
+ httpRequest.form("fieldend", "");
+ httpRequest.form("fieldrealBegan", "");
+ httpRequest.form("fieldrealEnd", "");
+ httpRequest.form("fieldopenedBy", "");
+ httpRequest.form("fieldclosedBy", "");
+ httpRequest.form("fieldlastEditedDate", "");
+ httpRequest.form("fieldclosedDate", "");
+ httpRequest.form("andOr1", "AND");
+ httpRequest.form("field1", fieldName);
+ httpRequest.form("operator1", "=");
+ httpRequest.form("value1", fieldValue);
+ httpRequest.form("andOr2", "and");
+ httpRequest.form("field2", "code");
+ httpRequest.form("operator2", "=");
+ httpRequest.form("value2", "");
+ httpRequest.form("andOr3", "and");
+ httpRequest.form("field3", "id");
+ httpRequest.form("operator3", "=");
+ httpRequest.form("value3", "");
+ httpRequest.form("groupAndOr", "and");
+ httpRequest.form("andOr4", "AND");
+ httpRequest.form("field4", "model");
+ httpRequest.form("operator4", "=");
+ httpRequest.form("value4", "");
+ httpRequest.form("andOr5", "and");
+ httpRequest.form("field5", "hasProduct");
+ httpRequest.form("operator5", "=");
+ httpRequest.form("value5", "");
+ httpRequest.form("andOr6", "and");
+ httpRequest.form("field6", "parent");
+ httpRequest.form("operator6", "=");
+ httpRequest.form("value6", 0);
+ httpRequest.form("module", "project");
+ httpRequest.form("actionURL", "/project-browse-0-bySearch-myQueryID.html");
+ httpRequest.form("groupItems", "3");
+ httpRequest.form("formType", "lite");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ return false;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ return execute.getStatus() == HttpStatus.HTTP_OK;
+ } catch (Exception e) {
+ StaticLog.error(e);
+ }
+ return false;
+ }
+
+ /**
+ * 通过项目名称获取项目
+ */
+ public ZtProjectGetResponse getByName(String name) {
+ ZtProjectGetResponse response = new ZtProjectGetResponse();
+ try {
+ boolean setQuery = setQuery("name", name);
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml("/project-browse-0-bySearch-myQueryID.html");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select(".main-table .sortable tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtProject ztProject = new ZtProject();
+ ztProject.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztProject.setName(tr.select(".c-name").attr("title"));
+ ztProject.setStatus(tr.select(".c-status").text());
+ ztProject.setPm(tr.select(".c-PM").text());
+ ztProject.setBudget(tr.select(".c-budget").text());
+ ztProject.setBegin(tr.select(".c-begin").text());
+ ztProject.setEnd(tr.select(".c-end").text());
+ ztProject.setProgress(tr.select(".c-progress").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztProject);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 通过项目编码获取项目
+ */
+ public ZtProjectGetResponse getByCode(String code) {
+ ZtProjectGetResponse response = new ZtProjectGetResponse();
+ try {
+ boolean setQuery = setQuery("code", code);
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml("/project-browse-0-bySearch-myQueryID.html");
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select(".main-table .sortable tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtProject ztProject = new ZtProject();
+ ztProject.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztProject.setName(tr.select(".c-name").attr("title"));
+ ztProject.setStatus(tr.select(".c-status").text());
+ ztProject.setPm(tr.select(".c-PM").text());
+ ztProject.setBudget(tr.select(".c-budget").text());
+ ztProject.setBegin(tr.select(".c-begin").text());
+ ztProject.setEnd(tr.select(".c-end").text());
+ ztProject.setProgress(tr.select(".c-progress").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztProject);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/ent/ZtProject.java b/src/main/java/xyz/wbsite/zentao/sdk/project/ent/ZtProject.java
new file mode 100644
index 0000000..3d9b6c9
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/ent/ZtProject.java
@@ -0,0 +1,108 @@
+package xyz.wbsite.zentao.sdk.project.ent;
+
+/**
+ * 禅道项目信息
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProject {
+
+ /**
+ * 项目ID
+ */
+ private int id;
+ /**
+ * 项目名称
+ */
+ private String name;
+ /**
+ * 项目状态
+ */
+ private String status;
+ /**
+ * 项目产品经理
+ */
+ private String pm;
+ /**
+ * 预算
+ */
+ private String budget;
+ /**
+ * 计划开始时间
+ */
+ private String begin;
+ /**
+ * 计划完成时间
+ */
+ private String end;
+ /**
+ * 进度
+ */
+ private String progress;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getPm() {
+ return pm;
+ }
+
+ public void setPm(String pm) {
+ this.pm = pm;
+ }
+
+ public String getBudget() {
+ return budget;
+ }
+
+ public void setBudget(String budget) {
+ this.budget = budget;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public String getProgress() {
+ return progress;
+ }
+
+ public void setProgress(String progress) {
+ this.progress = progress;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectActivateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectActivateRequest.java
new file mode 100644
index 0000000..a767081
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectActivateRequest.java
@@ -0,0 +1,65 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+/**
+ * 禅道项目激活请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectActivateRequest {
+
+ private int projectId;
+
+ private String begin;
+
+ private String end;
+
+ /**
+ * 是否重新调整时间 0/1
+ */
+ private String readjustTime;
+
+ private String comment;
+
+
+ public int getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(int projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public String getReadjustTime() {
+ return readjustTime;
+ }
+
+ public void setReadjustTime(String readjustTime) {
+ this.readjustTime = readjustTime;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCloseRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCloseRequest.java
new file mode 100644
index 0000000..f20b889
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCloseRequest.java
@@ -0,0 +1,41 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+/**
+ * 禅道项目关闭请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectCloseRequest {
+
+ private int projectId;
+
+ private String comment;
+
+ private String realEnd;
+
+ public int getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(int projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String getRealEnd() {
+ return realEnd;
+ }
+
+ public void setRealEnd(String realEnd) {
+ this.realEnd = realEnd;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCreateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCreateRequest.java
new file mode 100644
index 0000000..c8806fc
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectCreateRequest.java
@@ -0,0 +1,229 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+
+/**
+ * 禅道项目创建请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectCreateRequest {
+
+ /**
+ * 父项目
+ */
+ private String parent;
+ /**
+ * 项目名称
+ */
+ private String name;
+ /**
+ * 项目代号
+ */
+ private String code;
+ /**
+ * 启用迭代(0:不启用,1:启用)
+ */
+ private String multiple;
+ /**
+ * 是否产品型项目(0:没有关联产品,1:关联产品)
+ */
+ private String hasProduct;
+ /**
+ * 产品经理账户
+ */
+ private String pm;
+ /**
+ * 预算(金额)
+ */
+ private String budget;
+ /**
+ * 预算单位CNY
+ */
+ private String budgetUnit;
+ /**
+ * 预算待定(值为空或1)
+ */
+ private String future;
+ /**
+ * 项目开始时间 yyyy-MM-dd
+ */
+ private String begin;
+ /**
+ * 项目结束时间 yyyy-MM-dd
+ */
+ private String end;
+ /**
+ * 可用工作日
+ */
+ private int days;
+ /**
+ * 关联产品
+ */
+ private String products;
+ /**
+ * 关联产品名称
+ */
+ private String productName;
+ /**
+ * 项目描述
+ */
+ private String desc;
+ /**
+ * 访问控制private/open
+ */
+ private String acl;
+ /**
+ * 权限控制extend/reset
+ */
+ private String auth;
+ /**
+ * 项目管理方式scrum/waterfall/kanban
+ */
+ private String model;
+
+ public String getParent() {
+ return parent;
+ }
+
+ public void setParent(String parent) {
+ this.parent = parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMultiple() {
+ return multiple;
+ }
+
+ public void setMultiple(String multiple) {
+ this.multiple = multiple;
+ }
+
+ public String getHasProduct() {
+ return hasProduct;
+ }
+
+ public void setHasProduct(String hasProduct) {
+ this.hasProduct = hasProduct;
+ }
+
+ public String getPm() {
+ return pm;
+ }
+
+ public void setPm(String pm) {
+ this.pm = pm;
+ }
+
+ public String getBudget() {
+ return budget;
+ }
+
+ public void setBudget(String budget) {
+ this.budget = budget;
+ }
+
+ public String getBudgetUnit() {
+ return budgetUnit;
+ }
+
+ public void setBudgetUnit(String budgetUnit) {
+ this.budgetUnit = budgetUnit;
+ }
+
+ public String getFuture() {
+ return future;
+ }
+
+ public void setFuture(String future) {
+ this.future = future;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public int getDays() {
+ return days;
+ }
+
+ public void setDays(int days) {
+ this.days = days;
+ }
+
+ public String getProducts() {
+ return products;
+ }
+
+ public void setProducts(String products) {
+ this.products = products;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public String getAcl() {
+ return acl;
+ }
+
+ public void setAcl(String acl) {
+ this.acl = acl;
+ }
+
+ public String getAuth() {
+ return auth;
+ }
+
+ public void setAuth(String auth) {
+ this.auth = auth;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectDeleteRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectDeleteRequest.java
new file mode 100644
index 0000000..2f4e6fe
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectDeleteRequest.java
@@ -0,0 +1,21 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+/**
+ * 禅道项目删除请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectDeleteRequest {
+
+ private int projectId;
+
+ public int getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(int projectId) {
+ this.projectId = projectId;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectEditRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectEditRequest.java
new file mode 100644
index 0000000..f198fee
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectEditRequest.java
@@ -0,0 +1,205 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+/**
+ * 禅道项目更新响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectEditRequest {
+
+ /**
+ * 项目ID
+ */
+ private int id;
+ /**
+ * 父项目ID
+ */
+ private String parent;
+ /**
+ * 项目名称
+ */
+ private String name;
+ /**
+ * 项目代号
+ */
+ private String code;
+ /**
+ * 产品经理账户
+ */
+ private String pm;
+ /**
+ * 是否待定(1待定)
+ */
+ private String future;
+ /**
+ * 预算
+ */
+ private String budget;
+ /**
+ * 预算单位CNY
+ */
+ private String budgetUnit;
+ /**
+ * 项目开始时间 yyyy-MM-dd
+ */
+ private String begin;
+ /**
+ * 项目结束时间 yyyy-MM-dd
+ */
+ private String end;
+ /**
+ * 可用工作日
+ */
+ private int days;
+ /**
+ * delta
+ */
+ private int delta;
+ /**
+ * 项目描述
+ */
+ private String desc;
+ /**
+ * 访问控制private/open
+ */
+ private String acl;
+ /**
+ * 权限控制extend/reset
+ */
+ private String auth;
+ /**
+ * 项目管理方式scrum/waterfall/kanban
+ */
+ private String model;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getParent() {
+ return parent;
+ }
+
+ public void setParent(String parent) {
+ this.parent = parent;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+
+ public String getPm() {
+ return pm;
+ }
+
+ public void setPm(String pm) {
+ this.pm = pm;
+ }
+
+ public String getBudget() {
+ return budget;
+ }
+
+ public void setBudget(String budget) {
+ this.budget = budget;
+ }
+
+ public String getBudgetUnit() {
+ return budgetUnit;
+ }
+
+ public void setBudgetUnit(String budgetUnit) {
+ this.budgetUnit = budgetUnit;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public int getDays() {
+ return days;
+ }
+
+ public void setDays(int days) {
+ this.days = days;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public String getAcl() {
+ return acl;
+ }
+
+ public void setAcl(String acl) {
+ this.acl = acl;
+ }
+
+ public String getAuth() {
+ return auth;
+ }
+
+ public void setAuth(String auth) {
+ this.auth = auth;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public int getDelta() {
+ return delta;
+ }
+
+ public void setDelta(int delta) {
+ this.delta = delta;
+ }
+
+ public String getFuture() {
+ return future;
+ }
+
+ public void setFuture(String future) {
+ this.future = future;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectStartRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectStartRequest.java
new file mode 100644
index 0000000..d5036b6
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/req/ZtProjectStartRequest.java
@@ -0,0 +1,41 @@
+package xyz.wbsite.zentao.sdk.project.req;
+
+/**
+ * 禅道项目启动响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectStartRequest {
+
+ private int projectId;
+
+ private String comment;
+
+ private String realBegan;
+
+ public int getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(int projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public String getRealBegan() {
+ return realBegan;
+ }
+
+ public void setRealBegan(String realBegan) {
+ this.realBegan = realBegan;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectActivateResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectActivateResponse.java
new file mode 100644
index 0000000..1289c2f
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectActivateResponse.java
@@ -0,0 +1,36 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 项目激活响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectActivateResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCloseResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCloseResponse.java
new file mode 100644
index 0000000..6196b8d
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCloseResponse.java
@@ -0,0 +1,36 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 项目关闭响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectCloseResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCreateResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCreateResponse.java
new file mode 100644
index 0000000..bc5bc38
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectCreateResponse.java
@@ -0,0 +1,50 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 项目创建结果响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectCreateResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ /**
+ *
+ * 项目id
+ */
+ private int id;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectDeleteResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectDeleteResponse.java
new file mode 100644
index 0000000..8b0b0bf
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectDeleteResponse.java
@@ -0,0 +1,36 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 禅道项目删除响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectDeleteResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectEditResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectEditResponse.java
new file mode 100644
index 0000000..d3db91b
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectEditResponse.java
@@ -0,0 +1,36 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 项目信息更新响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectEditResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectGetResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectGetResponse.java
new file mode 100644
index 0000000..82931a3
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectGetResponse.java
@@ -0,0 +1,48 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+import xyz.wbsite.zentao.sdk.project.ent.ZtProject;
+
+/**
+ * 检索项目
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectGetResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ private ZtProject result;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public ZtProject getResult() {
+ return result;
+ }
+
+ public void setResult(ZtProject result) {
+ this.result = result;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectStartResponse.java b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectStartResponse.java
new file mode 100644
index 0000000..0a4a444
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/project/rsp/ZtProjectStartResponse.java
@@ -0,0 +1,49 @@
+package xyz.wbsite.zentao.sdk.project.rsp;
+
+/**
+ * 项目启动响应
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtProjectStartResponse {
+
+ /**
+ * 成功标志
+ */
+ private boolean success;
+ /**
+ * 消息
+ */
+ private String message;
+
+ /**
+ * 项目id
+ */
+ private int id;
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/task/ZtTaskService.java b/src/main/java/xyz/wbsite/zentao/sdk/task/ZtTaskService.java
new file mode 100644
index 0000000..4787f8e
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/task/ZtTaskService.java
@@ -0,0 +1,450 @@
+package xyz.wbsite.zentao.sdk.task;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpException;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.log.StaticLog;
+import xyz.wbsite.zentao.sdk.Constant;
+import xyz.wbsite.zentao.sdk.ZentaoInstance;
+import xyz.wbsite.zentao.sdk.task.ent.ZtTask;
+import xyz.wbsite.zentao.sdk.task.req.ZtTaskCloseRequest;
+import xyz.wbsite.zentao.sdk.task.req.ZtTaskCreateRequest;
+import xyz.wbsite.zentao.sdk.task.req.ZtTaskDeleteRequest;
+import xyz.wbsite.zentao.sdk.task.req.ZtTaskFinishRequest;
+import xyz.wbsite.zentao.sdk.task.req.ZtTaskStartRequest;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskCloseResponse;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskCreateResponse;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskDeleteResponse;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskFinishResponse;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskGetResponse;
+import xyz.wbsite.zentao.sdk.task.rsp.ZtTaskStartResponse;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+/**
+ * 禅道任务服务
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtTaskService {
+
+ private ZentaoInstance zentaoInstance;
+
+ public ZtTaskService(ZentaoInstance zentaoInstance) {
+ this.zentaoInstance = zentaoInstance;
+ }
+
+ /**
+ * 创建任务
+ */
+ public ZtTaskCreateResponse create(ZtTaskCreateRequest ztTaskCreateRequest) {
+ ZtTaskCreateResponse response = new ZtTaskCreateResponse();
+ try {
+ String url = StrUtil.format("/task-create-{}-0-0.json", ztTaskCreateRequest.getExecution());
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("execution", ztTaskCreateRequest.getExecution());
+ httpRequest.form("type", ztTaskCreateRequest.getType());
+ httpRequest.form("module", ztTaskCreateRequest.getModule());
+ httpRequest.form("assignedTo[]", StrUtil.join(",", ztTaskCreateRequest.getAssignedTo()));
+ httpRequest.form("teamMember", ztTaskCreateRequest.getTeamMember());
+ httpRequest.form("multiple", ztTaskCreateRequest.getMultiple());
+ httpRequest.form("mode", ztTaskCreateRequest.getMode());
+ httpRequest.form("status", "wait");
+ httpRequest.form("story", ztTaskCreateRequest.getStory());
+ httpRequest.form("color", ztTaskCreateRequest.getColor());
+ httpRequest.form("name", ztTaskCreateRequest.getName());
+ httpRequest.form("storyEstimate", ztTaskCreateRequest.getStoryEstimate());
+ httpRequest.form("storyDesc", ztTaskCreateRequest.getStoryDesc());
+ httpRequest.form("storyPri", ztTaskCreateRequest.getStoryPri());
+ httpRequest.form("pri", ztTaskCreateRequest.getPri());
+ httpRequest.form("estimate", ztTaskCreateRequest.getEstimate());
+ httpRequest.form("desc", ztTaskCreateRequest.getDesc());
+ httpRequest.form("estStarted", ztTaskCreateRequest.getEstStarted());
+ httpRequest.form("deadline", ztTaskCreateRequest.getDeadline());
+ httpRequest.form("after", "toTaskList");
+ httpRequest.form("team[]", "");
+ httpRequest.form("teamSource[]", "");
+ httpRequest.form("teamEstimate[]", "");
+ if (CollUtil.isNotEmpty(ztTaskCreateRequest.getMailtos())) {
+ for (String mailto : ztTaskCreateRequest.getMailtos()) {
+ httpRequest.form("mailto[]", mailto);
+ }
+ }
+ httpRequest.form("uid", RandomUtil.randomString(13));
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ // {"result":"success","message":"保存成功","id":"1891"}
+ if (body.contains(Constant.SUCCESS_KEY)) {
+ JSONObject entries = JSONUtil.parseObj(body);
+ response.setId(Convert.toInt(entries.get("id")));
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ return response;
+ } else {
+ response.setSuccess(false);
+ response.setMessage(JSONUtil.parseObj(body).getStr("message"));
+ return response;
+ }
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 关闭执行
+ */
+ public ZtTaskStartResponse start(ZtTaskStartRequest projectStartRequest) {
+ ZtTaskStartResponse response = new ZtTaskStartResponse();
+ try {
+ String url = StrUtil.format("/task-start-{}.html", projectStartRequest.getTaskId());
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("assignedTo", projectStartRequest.getAssignedTo());
+ httpRequest.form("realStarted", projectStartRequest.getRealStarted());
+ httpRequest.form("consumed", projectStartRequest.getConsumed());
+ httpRequest.form("left", projectStartRequest.getLeft());
+ httpRequest.form("status", "doing");
+ httpRequest.form("comment", projectStartRequest.getComment());
+ httpRequest.form("uid", RandomUtil.randomString(13));
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ // 返回html
+ StaticLog.info(body);
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 完成任务
+ */
+ public ZtTaskFinishResponse finish(ZtTaskFinishRequest ztTaskFinishRequest) {
+ ZtTaskFinishResponse response = new ZtTaskFinishResponse();
+ try {
+ String url = StrUtil.format("/task-finish-{}.html", ztTaskFinishRequest.getTaskId());
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("currentConsumed", ztTaskFinishRequest.getCurrentConsumed());
+ httpRequest.form("consumed", ztTaskFinishRequest.getConsumed());
+ httpRequest.form("assignedTo", ztTaskFinishRequest.getAssignedTo());
+ httpRequest.form("realStarted", ztTaskFinishRequest.getRealStarted());
+ httpRequest.form("finishedDate", ztTaskFinishRequest.getFinishedDate());
+ httpRequest.form("status", "done");
+ httpRequest.form("comment", ztTaskFinishRequest.getComment());
+ httpRequest.form("uid", RandomUtil.randomString(13));
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ if (body.contains(Constant.SUCCESS_KEY)) {
+ JSONObject entries = JSONUtil.parseObj(body);
+ response.setId(Convert.toInt(entries.get("id")));
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ return response;
+ }
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 关闭任务
+ */
+ public ZtTaskCloseResponse close(ZtTaskCloseRequest projectCloseRequest) {
+ ZtTaskCloseResponse response = new ZtTaskCloseResponse();
+ try {
+ String url = StrUtil.format("/task-close-{}.html", projectCloseRequest.getTaskId());
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("status", "closed");
+ httpRequest.form("comment", projectCloseRequest.getComment());
+ httpRequest.form("uid", RandomUtil.randomString(13));
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ if (body.contains(Constant.SUCCESS_KEY)) {
+ JSONObject entries = JSONUtil.parseObj(body);
+ response.setId(Convert.toInt(entries.get("id")));
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ return response;
+ }
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 删除执行
+ */
+ public ZtTaskDeleteResponse delete(ZtTaskDeleteRequest projectDeleteRequest) {
+ ZtTaskDeleteResponse response = new ZtTaskDeleteResponse();
+ try {
+ String url = StrUtil.format("/task-delete-{}.html", projectDeleteRequest.getTaskId());
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 设置查询条件
+ *
+ * 禅道查询条件是设置在session中的,所有查询之前先设置参数
+ */
+ private boolean setQuery(int executionId, String fieldName, String fieldValue) {
+ try {
+ String url = StrUtil.format("/search-buildQuery.html");
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createPost(url);
+ httpRequest.form("fieldname", "");
+ httpRequest.form("fieldstatus", "");
+ httpRequest.form("fielddesc", "");
+ httpRequest.form("fieldassignedTo", "");
+ httpRequest.form("fieldpri", 0);
+ httpRequest.form("fieldexecution", "");
+ httpRequest.form("fieldmodule", "ZERO");
+ httpRequest.form("fieldestimate", "");
+ httpRequest.form("fieldleft", "");
+ httpRequest.form("fieldconsumed", "");
+ httpRequest.form("fieldtype", "");
+ httpRequest.form("fieldfromBug", "");
+ httpRequest.form("fieldclosedReason", "");
+ httpRequest.form("fieldopenedBy", "");
+ httpRequest.form("fieldfinishedBy", "");
+ httpRequest.form("fieldclosedBy", "");
+ httpRequest.form("fieldcanceledBy", "");
+ httpRequest.form("fieldlastEditedBy", "");
+ httpRequest.form("fieldmailto", "");
+ httpRequest.form("fieldopenedDate", "");
+ httpRequest.form("fielddeadline", "");
+ httpRequest.form("fieldestStarted", "");
+ httpRequest.form("fieldrealStarted", "");
+ httpRequest.form("fieldassignedDate", "");
+ httpRequest.form("fieldfinishedDate", "");
+ httpRequest.form("fieldclosedDate", "");
+ httpRequest.form("fieldcanceledDate", "");
+ httpRequest.form("fieldlastEditedDate", "");
+ httpRequest.form("fieldactivatedDate", "");
+ httpRequest.form("fieldid", "");
+ httpRequest.form("andOr1", "AND");
+ httpRequest.form("field1", fieldName);
+ httpRequest.form("operator1", "=");
+ httpRequest.form("value1", fieldValue);
+ httpRequest.form("andOr2", "and");
+ httpRequest.form("field2", "id");
+ httpRequest.form("operator2", "=");
+ httpRequest.form("value2", "");
+ httpRequest.form("andOr3", "and");
+ httpRequest.form("field3", "status");
+ httpRequest.form("operator3", "=");
+ httpRequest.form("value3", "");
+ httpRequest.form("groupAndOr", "and");
+ httpRequest.form("andOr4", "AND");
+ httpRequest.form("field4", "desc");
+ httpRequest.form("operator4", "include");
+ httpRequest.form("value4", "");
+ httpRequest.form("andOr5", "and");
+ httpRequest.form("field5", "assignedTo");
+ httpRequest.form("operator5", "=");
+ httpRequest.form("value5", "");
+ httpRequest.form("andOr6", "and");
+ httpRequest.form("field6", "pri");
+ httpRequest.form("operator6", "=");
+ httpRequest.form("value6", 0);
+ httpRequest.form("module", "task");
+ httpRequest.form("actionURL", StrUtil.format("/execution-task-{}-bySearch-myQueryID.html", executionId));
+ httpRequest.form("groupItems", "3");
+ httpRequest.form("formType", "lite");
+ StaticLog.info(JSONUtil.toJsonStr(httpRequest.form()));
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ return false;
+ }
+ String body = Convert.unicodeToStr(execute.body());
+ StaticLog.info(body);
+ return execute.getStatus() == HttpStatus.HTTP_OK;
+ } catch (Exception e) {
+ StaticLog.error(e);
+ }
+ return false;
+ }
+
+ /**
+ * 通过任务名称获取任务
+ *
+ * @param executionId 执行ID
+ * @param taskId 任务ID
+ * @return 任务获取响应
+ */
+ public ZtTaskGetResponse getById(int executionId, int taskId) {
+ ZtTaskGetResponse response = new ZtTaskGetResponse();
+ try {
+ boolean setQuery = setQuery(executionId, "id", String.valueOf(taskId));
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ String url = StrUtil.format("/execution-task-{}-bySearch-myQueryID.html", executionId);
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml(url);
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select("#taskList tbody tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtTask ztTask = new ZtTask();
+ ztTask.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztTask.setName(tr.select(".c-name").attr("title"));
+ ztTask.setStatus(tr.select(".c-status").text());
+ ztTask.setPri(tr.select(".c-pri").text());
+ ztTask.setAssignedTo(tr.select(".c-assignedTo").text());
+ ztTask.setStatus(tr.select(".c-status").text());
+ ztTask.setFinishedBy(tr.select(".c-finishedBy").text());
+ ztTask.setProgress(tr.select("c-deadline").text());
+ ztTask.setProgress(tr.select("c-estimate").text());
+ ztTask.setProgress(tr.select("c-consumed").text());
+ ztTask.setProgress(tr.select("c-left").text());
+ ztTask.setProgress(tr.select("c-progress").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztTask);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+
+ /**
+ * 通过任务名称获取任务
+ *
+ * @param executionId 执行ID
+ * @param name 任务名称
+ * @return 任务获取响应
+ */
+ public ZtTaskGetResponse getByName(int executionId, String name) {
+ ZtTaskGetResponse response = new ZtTaskGetResponse();
+ try {
+ boolean setQuery = setQuery(executionId, "name", name);
+ if (!setQuery) {
+ response.setSuccess(false);
+ response.setMessage("设置查询参数失败");
+ return response;
+ }
+ String url = StrUtil.format("/execution-task-{}-bySearch-myQueryID.html", executionId);
+ StaticLog.info(url);
+ HttpRequest httpRequest = zentaoInstance.createGetForHtml(url);
+ HttpResponse execute = httpRequest.execute();
+ if (HttpStatus.HTTP_OK != execute.getStatus()) {
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+ String body = execute.body();
+ Document parse = Jsoup.parse(body);
+ Elements trs = parse.select("#taskList tbody tr");
+ if (trs.size() == 1) {
+ Element tr = trs.get(0);
+ ZtTask ztTask = new ZtTask();
+ ztTask.setId(Convert.toInt(tr.select(".c-id").text()));
+ ztTask.setName(tr.select(".c-name").attr("title"));
+ ztTask.setStatus(tr.select(".c-status").text());
+ ztTask.setPri(tr.select(".c-pri").text());
+ ztTask.setAssignedTo(tr.select(".c-assignedTo").text());
+ ztTask.setStatus(tr.select(".c-status").text());
+ ztTask.setFinishedBy(tr.select(".c-finishedBy").text());
+ ztTask.setProgress(tr.select("c-deadline").text());
+ ztTask.setProgress(tr.select("c-estimate").text());
+ ztTask.setProgress(tr.select("c-consumed").text());
+ ztTask.setProgress(tr.select("c-left").text());
+ ztTask.setProgress(tr.select("c-progress").text());
+ response.setSuccess(true);
+ response.setMessage("请求成功");
+ response.setResult(ztTask);
+ return response;
+ }
+ StaticLog.info(body);
+ response.setMessage("无数据");
+ return response;
+ } catch (HttpException e) {
+ StaticLog.error(e);
+ }
+ response.setSuccess(false);
+ response.setMessage("请求失败");
+ return response;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/task/ent/ZtTask.java b/src/main/java/xyz/wbsite/zentao/sdk/task/ent/ZtTask.java
new file mode 100644
index 0000000..f1151a1
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/task/ent/ZtTask.java
@@ -0,0 +1,144 @@
+package xyz.wbsite.zentao.sdk.task.ent;
+
+/**
+ * 禅道任务信息
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtTask {
+
+ /**
+ * 任务ID
+ */
+ private int id;
+ /**
+ * 任务名称
+ */
+ private String name;
+ /**
+ * 任务等级
+ */
+ private String pri;
+ /**
+ * 指派人
+ */
+ private String assignedTo;
+ /**
+ * 任务状态
+ */
+ private String status;
+ /**
+ * 任务完成人
+ */
+ private String finishedBy;
+ /**
+ * 结束日期
+ */
+ private String deadline;
+ /**
+ * 预计工时
+ */
+ private String estimate;
+ /**
+ * 消耗工时
+ */
+ private String consumed;
+ /**
+ * 剩余工时
+ */
+ private String left;
+ /**
+ * 进度
+ */
+ private String progress;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPri() {
+ return pri;
+ }
+
+ public void setPri(String pri) {
+ this.pri = pri;
+ }
+
+ public String getAssignedTo() {
+ return assignedTo;
+ }
+
+ public void setAssignedTo(String assignedTo) {
+ this.assignedTo = assignedTo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getFinishedBy() {
+ return finishedBy;
+ }
+
+ public void setFinishedBy(String finishedBy) {
+ this.finishedBy = finishedBy;
+ }
+
+ public String getDeadline() {
+ return deadline;
+ }
+
+ public void setDeadline(String deadline) {
+ this.deadline = deadline;
+ }
+
+ public String getEstimate() {
+ return estimate;
+ }
+
+ public void setEstimate(String estimate) {
+ this.estimate = estimate;
+ }
+
+ public String getConsumed() {
+ return consumed;
+ }
+
+ public void setConsumed(String consumed) {
+ this.consumed = consumed;
+ }
+
+ public String getLeft() {
+ return left;
+ }
+
+ public void setLeft(String left) {
+ this.left = left;
+ }
+
+ public String getProgress() {
+ return progress;
+ }
+
+ public void setProgress(String progress) {
+ this.progress = progress;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskActivateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskActivateRequest.java
new file mode 100644
index 0000000..ca58ae6
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskActivateRequest.java
@@ -0,0 +1,72 @@
+package xyz.wbsite.zentao.sdk.task.req;
+
+/**
+ * 禅道任务执行请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtTaskActivateRequest {
+
+ /**
+ * 执行id
+ */
+ private int executionId;
+ /**
+ * 开始日期
+ */
+ private String begin;
+ /**
+ * 结束日期
+ */
+ private String end;
+ /**
+ * 是否重新调整时间 0/1
+ */
+ private boolean readjustTime;
+ /**
+ * 备注
+ */
+ private String comment;
+
+ public int getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(int executionId) {
+ this.executionId = executionId;
+ }
+
+ public String getBegin() {
+ return begin;
+ }
+
+ public void setBegin(String begin) {
+ this.begin = begin;
+ }
+
+ public String getEnd() {
+ return end;
+ }
+
+ public void setEnd(String end) {
+ this.end = end;
+ }
+
+ public boolean isReadjustTime() {
+ return readjustTime;
+ }
+
+ public void setReadjustTime(boolean readjustTime) {
+ this.readjustTime = readjustTime;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCloseRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCloseRequest.java
new file mode 100644
index 0000000..b21f205
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCloseRequest.java
@@ -0,0 +1,31 @@
+package xyz.wbsite.zentao.sdk.task.req;
+
+/**
+ * 禅道任务关闭请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtTaskCloseRequest {
+
+ private int taskId;
+
+ private String comment;
+
+ public int getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(int taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCreateRequest.java b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCreateRequest.java
new file mode 100644
index 0000000..d40a237
--- /dev/null
+++ b/src/main/java/xyz/wbsite/zentao/sdk/task/req/ZtTaskCreateRequest.java
@@ -0,0 +1,238 @@
+package xyz.wbsite.zentao.sdk.task.req;
+
+import java.util.List;
+
+/**
+ * 禅道任务创建请求
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class ZtTaskCreateRequest {
+
+ /**
+ * 执行ID
+ */
+ private int execution;
+
+ /**
+ * 任务类型devel/design/request/test/study/discuss/ui/affair/misc
+ */
+ private String type;
+
+ /**
+ * 所属模块ID,可默认0
+ */
+ private String module;
+
+ /**
+ * 指派
+ */
+ private List
+ * 基于开源版本18.1开发
+ *
+ * @since 1.8
+ */
+public class ClientTest {
+
+ @Test
+ public void test() {
+ // 初始化客户端
+ ZentaoClient client = new ZentaoClient("http://127.0.0.1:80", "******", "********************************", "pms");
+ ZentaoInstance instance = client.loginAsPms();
+
+ // 创建项目
+ ZtProjectCreateRequest ztProjectCreateRequest = new ZtProjectCreateRequest();
+ ztProjectCreateRequest.setParent("0");
+ ztProjectCreateRequest.setName("测试项目");
+ ztProjectCreateRequest.setCode("测试项目");
+ ztProjectCreateRequest.setMultiple("1");
+ ztProjectCreateRequest.setHasProduct("0");
+ ztProjectCreateRequest.setPm("");
+ ztProjectCreateRequest.setBudget("1000");
+ ztProjectCreateRequest.setBudgetUnit("CNY");
+ ztProjectCreateRequest.setBegin(DateUtil.date().toString("yyyy-MM-dd"));
+ ztProjectCreateRequest.setEnd(DateUtil.date().offset(DateField.DAY_OF_MONTH, 27).toString("yyyy-MM-dd"));
+ ztProjectCreateRequest.setDays(21);
+ ztProjectCreateRequest.setProducts("0");
+ ztProjectCreateRequest.setProductName("");
+ ztProjectCreateRequest.setDesc("");
+ ztProjectCreateRequest.setAcl("open");
+ ztProjectCreateRequest.setAuth("extend");
+ ztProjectCreateRequest.setModel("scrum");
+ ZtProjectCreateResponse createProjectResponse = instance.getZtProjectService().create(ztProjectCreateRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(createProjectResponse));
+
+ // 编辑项目
+ ZtProjectEditRequest ztProjectEditRequest = new ZtProjectEditRequest();
+ ztProjectEditRequest.setId(createProjectResponse.getId());
+ ztProjectEditRequest.setParent("0");
+ ztProjectEditRequest.setName("测试项目");
+ ztProjectEditRequest.setCode("测试项目");
+ ztProjectEditRequest.setPm("");
+ ztProjectEditRequest.setBudget("1000");
+ ztProjectEditRequest.setBudgetUnit("CNY");
+ ztProjectEditRequest.setBegin(DateUtil.date().toString("yyyy-MM-dd"));
+ ztProjectEditRequest.setEnd(DateUtil.date().offset(DateField.DAY_OF_MONTH, 27).toString("yyyy-MM-dd"));
+ ztProjectEditRequest.setDays(21);
+ ztProjectEditRequest.setDesc("");
+ ztProjectEditRequest.setAcl("open");
+ ztProjectEditRequest.setAuth("extend");
+ ztProjectEditRequest.setModel("scrum");
+ ZtProjectEditResponse ztProjectEditResponse = instance.getZtProjectService().edit(ztProjectEditRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztProjectEditResponse));
+
+ // 开始项目
+ ZtProjectStartRequest ztProjectStartRequest = new ZtProjectStartRequest();
+ ztProjectStartRequest.setProjectId(createProjectResponse.getId());
+ ztProjectStartRequest.setComment("");
+ ztProjectStartRequest.setRealBegan(DateUtil.today());
+ ZtProjectStartResponse startProjectResponse = instance.getZtProjectService().start(ztProjectStartRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(startProjectResponse));
+
+ // 创建执行(模块1)
+ {
+ ZtExecutionCreateRequest ztExecutionCreateRequest = new ZtExecutionCreateRequest();
+ ztExecutionCreateRequest.setProject(createProjectResponse.getId());
+ ztExecutionCreateRequest.setName("测试项目-模块1");
+ ztExecutionCreateRequest.setCode("测试项目-模块1");
+ ztExecutionCreateRequest.setBegin(DateUtil.date().toString("yyyy-MM-dd"));
+ ztExecutionCreateRequest.setEnd(DateUtil.date().offset(DateField.DAY_OF_MONTH, 6).toString("yyyy-MM-dd"));
+ ztExecutionCreateRequest.setDelta(7);
+ ztExecutionCreateRequest.setDays(5);
+ ztExecutionCreateRequest.setLifetime("short");
+ ztExecutionCreateRequest.setTeam("");
+ ztExecutionCreateRequest.setTeams(createProjectResponse.getId());
+ ztExecutionCreateRequest.setPo("");
+ ztExecutionCreateRequest.setQd("");
+ ztExecutionCreateRequest.setPm("");
+ ztExecutionCreateRequest.setRd("");
+ ztExecutionCreateRequest.setTeamMembers(CollUtil.newArrayList(""));
+ ztExecutionCreateRequest.setDesc("");
+ ztExecutionCreateRequest.setAcl("open");
+ ztExecutionCreateRequest.setAuth("extend");
+ ZtExecutionCreateResponse ztExecutionCreateResponse = instance.getZtExecutionService().create(ztExecutionCreateRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztExecutionCreateResponse));
+
+ // 开始执行(模块1)
+ ZtExecutionStartRequest ztExecutionStartRequest = new ZtExecutionStartRequest();
+ ztExecutionStartRequest.setExecutionId(ztExecutionCreateResponse.getId());
+ ztExecutionStartRequest.setComment("");
+ ztExecutionStartRequest.setRealBegan(DateUtil.today());
+ ZtExecutionStartResponse ztExecutionStartResponse = instance.getZtExecutionService().start(ztExecutionStartRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztExecutionStartResponse));
+
+ {
+ // 创建测试任务1
+ ZtTaskCreateRequest ztTaskCreateRequest = new ZtTaskCreateRequest();
+ ztTaskCreateRequest.setExecution(ztExecutionCreateResponse.getId());
+ ztTaskCreateRequest.setType("devel");
+ ztTaskCreateRequest.setModule("0");
+ ztTaskCreateRequest.setAssignedTo(Collections.emptyList());
+ ztTaskCreateRequest.setTeamMember("");
+ ztTaskCreateRequest.setMultiple("");
+ ztTaskCreateRequest.setMode("");
+ ztTaskCreateRequest.setStory("");
+ ztTaskCreateRequest.setStoryEstimate("");
+ ztTaskCreateRequest.setStoryDesc("");
+ ztTaskCreateRequest.setStoryPri("");
+ ztTaskCreateRequest.setColor("#ff0000");
+ ztTaskCreateRequest.setName("测试任务1");
+ ztTaskCreateRequest.setPri("1");
+ ztTaskCreateRequest.setEstimate("1");
+ ztTaskCreateRequest.setDesc("任务描述");
+ ztTaskCreateRequest.setEstStarted(DateUtil.date().toString("yyyy-MM-dd"));
+ ztTaskCreateRequest.setDeadline(DateUtil.date().toString("yyyy-MM-dd"));
+ ztTaskCreateRequest.setMailtos(Collections.emptyList());
+ ZtTaskCreateResponse ztTaskCreateResponse = instance.getZtTaskService().create(ztTaskCreateRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztTaskCreateResponse));
+
+ ZtTaskGetResponse ztTaskGetResponse = instance.getZtTaskService().getByName(ztExecutionCreateResponse.getId(), "测试任务1");
+ // 开始任务
+ ZtTaskStartRequest ztTaskStartRequest = new ZtTaskStartRequest();
+ ztTaskStartRequest.setTaskId(ztTaskGetResponse.getResult().getId());
+ ztTaskStartRequest.setAssignedTo("");
+ ztTaskStartRequest.setRealStarted(DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));
+ ztTaskStartRequest.setConsumed(ztTaskGetResponse.getResult().getConsumed());
+ ztTaskStartRequest.setLeft(ztTaskGetResponse.getResult().getLeft());
+ ztTaskStartRequest.setComment("备注");
+ ZtTaskStartResponse ztTaskStartResponse = instance.getZtTaskService().start(ztTaskStartRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztTaskStartResponse));
+
+ // 完成任务
+ ZtTaskFinishRequest ztTaskFinishRequest = new ZtTaskFinishRequest();
+ ztTaskFinishRequest.setTaskId(ztTaskGetResponse.getResult().getId());
+ ztTaskFinishRequest.setAssignedTo("");
+ ztTaskFinishRequest.setRealStarted(DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));
+ ztTaskFinishRequest.setConsumed(ztTaskGetResponse.getResult().getConsumed());
+ ztTaskFinishRequest.setComment("备注");
+ ZtTaskFinishResponse ztTaskFinishResponse = instance.getZtTaskService().finish(ztTaskFinishRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztTaskFinishResponse));
+
+ // 关闭任务
+ ZtTaskCloseRequest ztTaskCloseRequest = new ZtTaskCloseRequest();
+ ztTaskCloseRequest.setTaskId(ztTaskCreateResponse.getId());
+ ztTaskCloseRequest.setComment("备注");
+ ZtTaskCloseResponse ztTaskCloseResponse = instance.getZtTaskService().close(ztTaskCloseRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztTaskCloseResponse));
+
+ // 删除任务
+ ZtTaskDeleteRequest ztTaskDeleteRequest = new ZtTaskDeleteRequest();
+ ztTaskDeleteRequest.setTaskId(ztTaskCreateResponse.getId());
+ ZtTaskDeleteResponse ztTaskDeleteResponse = instance.getZtTaskService().delete(ztTaskDeleteRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztTaskDeleteResponse));
+ }
+ }
+
+ // 关闭项目
+ ZtProjectCloseRequest ztProjectCloseRequest = new ZtProjectCloseRequest();
+ ztProjectCloseRequest.setProjectId(createProjectResponse.getId());
+ ztProjectCloseRequest.setComment("");
+ ztProjectCloseRequest.setRealEnd(DateUtil.today());
+ ZtProjectCloseResponse closeProjectResponse = instance.getZtProjectService().close(ztProjectCloseRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(closeProjectResponse));
+
+ // 激活项目
+ ZtProjectActivateRequest ztProjectActivateRequest = new ZtProjectActivateRequest();
+ ztProjectActivateRequest.setProjectId(createProjectResponse.getId());
+ ztProjectActivateRequest.setComment("");
+ ztProjectActivateRequest.setBegin(DateUtil.today());
+ ZtProjectActivateResponse activateProjectResponse = instance.getZtProjectService().activate(ztProjectActivateRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(activateProjectResponse));
+
+ // 删除项目
+ ZtProjectDeleteRequest ztProjectDeleteRequest = new ZtProjectDeleteRequest();
+ ztProjectDeleteRequest.setProjectId(createProjectResponse.getId());
+ ZtProjectDeleteResponse ztProjectDeleteResponse = instance.getZtProjectService().delete(ztProjectDeleteRequest);
+ System.out.println(JSONUtil.toJsonPrettyStr(ztProjectDeleteResponse));
+ }
+}