|
@@ -77,20 +77,44 @@ public class AWImplClient implements AWClint {
|
|
|
|
|
|
/**
|
|
|
* 交付物审批 [ppExt: 宜搭附件传递 downloadUrl 和 name 即可实现在线预览]
|
|
|
+ * -
|
|
|
+ * 6.18 变更说明
|
|
|
+ * 1. 提交发布与提交变更均通过任务按钮操作, 本质上链到宜搭的页面
|
|
|
+ * 2. 提交发布自动触发评审, 执行结束关闭tab页面. 若有报错则弹出错误信息
|
|
|
+ * 3. 提交变更链接到交付物审批页面, 去掉所有的拒绝, 开启退回操作. 并添加 PCR 填写
|
|
|
*/
|
|
|
@Override
|
|
|
- public void doApprove(Map data) {
|
|
|
-
|
|
|
- String projectId = UtilMap.getString(data, "projectId");
|
|
|
- String workFlowApprove = _getWorkFlowStatus(projectId, AWServer.WORKFLOW_APPROVE);
|
|
|
- if (!data.get("tfsId").equals(workFlowApprove)) {
|
|
|
- return;
|
|
|
+ public Map doApprove(Map data, boolean isChange) {
|
|
|
+
|
|
|
+ // 通过工作流触发: prd 618 通过任务扩展按钮触发, fixme tb任务完成态工作流工作会触发完成时间更新, 导致逾期问题
|
|
|
+ String type = isChange ? "变更" : "发布"; // 回调 发布 变更
|
|
|
+ boolean isCallback = data.containsKey("tfsId");
|
|
|
+ if (isCallback) {
|
|
|
+ String projectId = UtilMap.getString(data, "projectId");
|
|
|
+ String workFlowApprove = _getWorkFlowStatus(projectId, AWServer.WORKFLOW_APPROVE);
|
|
|
+ if (!data.get("tfsId").equals(workFlowApprove)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ type = "回调";
|
|
|
}
|
|
|
+ // todo 已变更工作流, 不允许再提交发布; 没有发布状态也不允许做变更
|
|
|
+
|
|
|
log.info("交付物审批, {}", data);
|
|
|
- String pCode = UtilMap.getString(data, "projectId");
|
|
|
- String creatorId = UtilMap.getString(data, "creatorId");
|
|
|
+ McException.assertParamException_Null(data, "taskId");
|
|
|
String taskId = UtilMap.getString(data, "taskId");
|
|
|
- Map taskData = _getTaskFieldMap(UtilMap.getString(data, "taskId"), AWServer.TASK_CODE, AWServer.TASK_APPROVE_ATTACHMENT, AWServer.TASK_APPROVE_DESC, AWServer.TASK_PRODUCT, AWServer.TASK_PRODUCT_VERSION);
|
|
|
+ Map taskData = _getTaskFieldMap(taskId, AWServer.TASK_CODE, AWServer.TASK_APPROVE_ATTACHMENT, AWServer.TASK_APPROVE_DESC, AWServer.TASK_PRODUCT, AWServer.TASK_PRODUCT_VERSION);
|
|
|
+ List<Map> docs = _getDocs(taskData);
|
|
|
+ // ppExt: TB有卡控, 校验交付物不能为空, 同时兼容非交付件任务类型
|
|
|
+ McException.assertAccessException(!isCallback && docs.size() == 0, "任务交付件不能为空, 请填写后再操作!");
|
|
|
+ // prd 618 通过任务扩展按钮触发, 接口仅需传递 taskId 即可, 相关信息直接从任务详情取值
|
|
|
+ Map rTask = UtilMap.getMap(taskData, "task");
|
|
|
+ String pCode = UtilMap.getString(rTask, "projectId");
|
|
|
+ String executorId = UtilMap.getString(rTask, "executorId");
|
|
|
+ if (!isCallback) {
|
|
|
+ McException.assertAccessException(StringUtils.isBlank(executorId), "任务执行人未分配!");
|
|
|
+ }
|
|
|
+ // 返回userId, 若非执行人权限, 页面控制弹出框
|
|
|
+ String userId = "";
|
|
|
String tCode = UtilMap.getString(taskData, AWServer.TASK_CODE);
|
|
|
// 工作流tb虽然配置了流转逻辑, 冗余稳定性
|
|
|
List<Map> formList = (List<Map>) ydClient.queryData(YDParam.builder()
|
|
@@ -99,9 +123,8 @@ public class AWImplClient implements AWClint {
|
|
|
.instanceStatus("RUNNING")
|
|
|
.build(), YDConf.FORM_QUERY.retrieve_search_process).getData();
|
|
|
if (formList.size() > 0 && formList.stream().filter(item -> tCode.equals(((Map) item.get("data")).get("selectField_lqxuswzd"))).findAny().isPresent()) {
|
|
|
- return;
|
|
|
+ McException.assertAccessException(true, "已存在审批中流程, 请勿重复提交!");
|
|
|
}
|
|
|
-
|
|
|
String result = "";
|
|
|
List<Map> tList = null;
|
|
|
Map rProject = null;
|
|
@@ -126,7 +149,8 @@ public class AWImplClient implements AWClint {
|
|
|
if (StringUtils.isBlank(result)) {
|
|
|
List<Map> roles = (List<Map>) rProject.get("tableField_lqxtykcf");
|
|
|
Map formData = UtilMap.map("selectField_lqxuswzd, textField_lrncs2fu", tCode, pCode);
|
|
|
- formData.put("attachmentField_lqxtebtq", _getDocs(taskData));
|
|
|
+ formData.put("attachmentField_lqxtebtq", docs);
|
|
|
+ formData.put("textField_lxl98hsu", UtilMap.getString(rTask, "content")); // 任务标题
|
|
|
formData.put("selectField_lqxuswze", UtilMap.getString(rProject, "textField_lrj7vnxb")); // 项目编号
|
|
|
formData.put("textField_lqxuc9m4", UtilMap.getString(rProject, "textareaField_lrj7vnxl")); // 项目描述
|
|
|
formData.put("employeeField_ltzn872j", UtilMap.getString(rProject, "employeeField_ltzn872j_id")); // 项目经理 0402 控制矩阵角色为空, 流转到PM
|
|
@@ -164,21 +188,49 @@ public class AWImplClient implements AWClint {
|
|
|
formData.put(compId.get("prEmp"), namesApprover);
|
|
|
}
|
|
|
// 组装数据
|
|
|
- Map<String, String> extra = (Map) tbClient.idMapQuery(creatorId, "dingTalk-user", ddConf.getCorpId()).get(0).get("extra");
|
|
|
- UtilMap.putAll(formData, UtilMap.map("textField_lr3dlwsa, textField_lr3er4qb", taskId, creatorId));
|
|
|
- formData.put("employeeField_lui5fu7z", Arrays.asList(extra.get("userId"))); // 0402 指定发起人, 用于结构化数据子流程发起人
|
|
|
- String instanceId = (String) ydClient.operateData(YDParam.builder()
|
|
|
- .formUuid(_matchFormUuid("REVIEW"))
|
|
|
- .processCode(_matchFormUuid("REVIEW_PROCESS"))
|
|
|
- .formDataJson(JSON.toJSONString(formData))
|
|
|
- .userId(extra.get("userId"))
|
|
|
- .build(), YDConf.FORM_OPERATION.start);
|
|
|
- result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/processDetail?procInsId=" + instanceId;
|
|
|
+ Map<String, String> extra = (Map) tbClient.idMapQuery(executorId, "dingTalk-user", ddConf.getCorpId()).get(0).get("extra");
|
|
|
+ UtilMap.putAll(formData, UtilMap.map("textField_lr3dlwsa, textField_lr3er4qb", taskId, executorId));
|
|
|
+ formData.put("employeeField_lui5fu7z", Arrays.asList(extra.get("userId"))); // 0402 指定发起人, 用于结构化数据子流程发起人
|
|
|
+ formData.put("radioField_lxkaihe5", type);
|
|
|
+ formData.put("selectField_lxl7xtwe", isChange ? "提交变更" : "提交发布"); // 评审类型标题
|
|
|
+ userId = extra.get("userId");
|
|
|
+ // prd 618 通过任务扩展按钮触发, 变更填写关联pcr后再提交, 返回数据. 并需要回调
|
|
|
+ if (!isChange) {
|
|
|
+ String instanceId = (String) ydClient.operateData(YDParam.builder()
|
|
|
+ .formUuid(_matchFormUuid("REVIEW"))
|
|
|
+ .processCode(_matchFormUuid("REVIEW_PROCESS"))
|
|
|
+ .formDataJson(JSON.toJSONString(formData))
|
|
|
+ .userId(extra.get("userId"))
|
|
|
+ .build(), YDConf.FORM_OPERATION.start);
|
|
|
+ result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/processDetail?procInsId=" + instanceId;
|
|
|
+ } else {
|
|
|
+ formData.put("result", result);
|
|
|
+ formData.put("userId", userId);
|
|
|
+ List<String> pmUserIds = (List<String>) JSON.parse(UtilMap.getString(rProject, "employeeField_ltzn872j_id"));
|
|
|
+ formData.put("PMName", ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), pmUserIds.get(0)).get("name"));
|
|
|
+ return formData;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
log.info("交付物结果, {}", result);
|
|
|
+ // prd 618 通过任务扩展按钮, 提交后再触发审批回写, 直接提交场景下直接更新审批链接
|
|
|
+ if (!isChange) {
|
|
|
+ Map body = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_LINK, result);
|
|
|
+ tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
|
|
|
+ }
|
|
|
+ return UtilMap.map("result, userId", result, userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 交付物审批变更发起
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void changeApprove(String taskId, String instanceId) {
|
|
|
+ String result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/processDetail?procInsId=" + instanceId;
|
|
|
Map body = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_LINK, result);
|
|
|
tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
|
|
|
+ Map body2 = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_STATE, "变更中");
|
|
|
+ tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body2);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -188,9 +240,17 @@ public class AWImplClient implements AWClint {
|
|
|
public void approved(Map data) {
|
|
|
|
|
|
log.info("交付物审批回调, {}", data);
|
|
|
- String result = String.valueOf(data.get("approve"));
|
|
|
+ String result = UtilMap.getString(data, "approve");
|
|
|
+ String type = UtilMap.getString(data, "type");
|
|
|
+ if ("变更".equals(type)) {
|
|
|
+ Map body = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_STATE, "已变更");
|
|
|
+ tbClient.updateTaskCustomField(UtilMap.getString(data, "taskId"), tbConf.getOperatorId(), body);
|
|
|
+ }
|
|
|
+ // todo 任务工作流更新, tb需要调整
|
|
|
+// if ("回调".equals(UtilMap.getString(data, "type"))) {
|
|
|
String workFlowId = _getWorkFlowStatus(String.valueOf(data.get("projectId")), result);
|
|
|
tbClient.updateTaskFlowStatus(String.valueOf(data.get("taskId")), tbConf.getOperatorId(), workFlowId, String.valueOf(data.get("approve")));
|
|
|
+// }
|
|
|
}
|
|
|
|
|
|
@Autowired
|
|
@@ -613,14 +673,14 @@ public class AWImplClient implements AWClint {
|
|
|
tbClient.updateProjectStatusField(projectId, tbConf.getOperatorId(), TBConf.assembleCustomFieldName("项目描述", UtilMap.getString(formData, "textareaField_lrj7vnxl")));
|
|
|
tbClient.updateProjectStatusField(projectId, tbConf.getOperatorId(), TBConf.assembleCustomFieldName("项目重要等级", UtilMap.getString(formData, "textField_lwj1r7n6")));
|
|
|
}
|
|
|
- // 项目添加到项目集
|
|
|
-// List<Map> groupList = tbClient.queryProgramList_all();
|
|
|
-// Optional optional = groupList.stream().filter(item -> groupName.equals(item.get("name"))).findAny();
|
|
|
-// if (optional.isPresent()) {
|
|
|
-// tbClient.upsertProgramProject(UtilMap.getString((Map) optional.get(), "id"), Arrays.asList(projectId), tbConf.getOperatorId());
|
|
|
-// }
|
|
|
-
|
|
|
log.info("TB项目信息, {}, {}", projectId, roleIds.size());
|
|
|
+
|
|
|
+ // 项目添加到项目集
|
|
|
+ List<Map> groupList = tbClient.queryProgramList_all();
|
|
|
+ Optional optional = groupList.stream().filter(item -> groupName.equals(item.get("name"))).findAny();
|
|
|
+ if (optional.isPresent()) {
|
|
|
+ tbClient.upsertProgramProject(UtilMap.getString((Map) optional.get(), "id"), Arrays.asList(projectId), tbConf.getOperatorId());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// fixme 提取方法, 参考 getProjectCFID 实现
|
|
@@ -700,6 +760,20 @@ public class AWImplClient implements AWClint {
|
|
|
tbClient.updateTaskExecutor(UtilMap.getString(task, "id"), tbConf.getOperatorId(), tbUserId, false, false);
|
|
|
}
|
|
|
}
|
|
|
+ // prd 6.17 任务分配:资源匹配多人时,取值第一人作为执行人,其他人员作为参与者
|
|
|
+ if (roleIds.size() > 1) {
|
|
|
+ String executorId = UtilMap.getString(task, "executorId");
|
|
|
+ List<String> tbUserIds = roleIds.stream().map(item -> _convertUserId(item, false)).collect(Collectors.toList());
|
|
|
+ // prd 多人情况避免, 手动指定后被覆盖. 判定当前任务执行人在角色范围内则不支持更新
|
|
|
+ if (StringUtils.isNotBlank(executorId) && tbUserIds.contains(executorId)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (tbUserIds.size() > 0) {
|
|
|
+ tbClient.updateTaskExecutor(UtilMap.getString(task, "id"), tbConf.getOperatorId(), tbUserIds.get(0), false, false);
|
|
|
+ }
|
|
|
+ roleIds.remove(0);
|
|
|
+ tbClient.updateTaskInvolveMembers(UtilMap.getString(task, "id"), tbConf.getOperatorId(), tbUserIds, null, false, false);
|
|
|
+ }
|
|
|
}
|
|
|
return true;
|
|
|
});
|
|
@@ -1173,6 +1247,8 @@ public class AWImplClient implements AWClint {
|
|
|
* 4. 需要通过模板自动创建知识库, TB 134版本已支持
|
|
|
* 1. 调整: fixme 知识库列表接口, 查询受到 operatorId 权限控制, 仅会返回操作者有权限知识库
|
|
|
* 2. 方案: 依赖同3, 公共账号 TBManager 默认是项目拥有者, 会默认同步到知识库成员, 查询权限后通过知识库创建者添加编辑, 用于复制文件 [ppExt: 直接添加知识库根节点 rootNodeId 编辑权限]
|
|
|
+ * -
|
|
|
+ * -5. 高密知识库访问限制: 同一个知识库内可以复制, 产品答复通过接口形态也与实际操作一致的表现, 均有控制不能往外进行复制. 写入是被允许的
|
|
|
*/
|
|
|
@Override
|
|
|
public void approveVersion(String taskId, String pCode) {
|
|
@@ -1197,7 +1273,7 @@ public class AWImplClient implements AWClint {
|
|
|
rootNodeId = UtilMap.getString(pList.get(0), "textField_lx342bvd");
|
|
|
creatorId = UtilMap.getString(pList.get(0), "textField_lx8ra1bs");
|
|
|
if (StringUtils.isBlank(workspaceId)) {
|
|
|
- // 获取知识库空间Id [ ppExt: 知识库列表接口, 查询受到 operatorId 权限控制, 仅会返回操作者有权限知识库 ]
|
|
|
+ // 获取知识库空间Id [ ppExt: 知识库列表接口, 查询受到 operatorId 权限控制, 仅会返回操作者有权限知识库 ] todo tb提供接口返回知识库相关信息
|
|
|
List<Map> workspaces = ddClient_storage.searchWorkspaces(ddClient.getAccessToken(), unionId, pCode, null);
|
|
|
if (workspaces.isEmpty()) {
|
|
|
result = "项目知识库未找到";
|
|
@@ -1228,7 +1304,9 @@ public class AWImplClient implements AWClint {
|
|
|
// 知识库文件夹 & 拷贝处理 [prd 文件目录结构 TR评审节点/资源名称]
|
|
|
Map taskData = _getTaskFieldMap(taskId, AWServer.TASK_APPROVE_ATTACHMENT, AWServer.TASK_STAGE, AWServer.TASK_ROLE);
|
|
|
Map rTask = UtilMap.getMap(taskData, "task");
|
|
|
-
|
|
|
+ // fixme: 知识库所有操作和权限都与依赖于权限, 通过 spaceId + dentryId 查询创建人需要传递操作者, 操作者需要有查看以上权限. todo 目前临时读取执行人, tb文档相关信息需要返回创建人信息
|
|
|
+ Map<String, String> extra = (Map) tbClient.idMapQuery(UtilMap.getString(rTask, "executorId"), "dingTalk-user", ddConf.getCorpId()).get(0).get("extra");
|
|
|
+ String executorIdUnionId = String.valueOf(ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), extra.get("userId")).get("unionid"));
|
|
|
// 文件/文件夹版本控制: fileType, fileName, pCode, pId, workspaceId, rootNodeId, unionId
|
|
|
String fileName = "项目交付件";
|
|
|
Map record = _upsertFileAbsolutePath("文件夹", fileName, pCode, UtilMap.getString(rTask, "projectId"), workspaceId, rootNodeId, unionId);
|
|
@@ -1259,9 +1337,8 @@ public class AWImplClient implements AWClint {
|
|
|
String title = UtilMap.getString(doc, "title");
|
|
|
fileName = fileName + "/" + title;
|
|
|
Map version = _upsertFileAbsolutePath("文件", fileName, pCode, UtilMap.getString(rTask, "projectId"), workspaceId, rootNodeId, unionId);
|
|
|
-
|
|
|
- // 通过提供通过 spaceId + dentryId 查询创建人, 再由创建人为公共账号添加编辑权限, 再通过公共账号复制 [ppExt: 知识库可为其他成员添加不高于自身的权限]
|
|
|
- DDR_New ddr_dentry = ddClient_storage.getSpaceDentryDetail(ddClient.getAccessToken(), unionId, UtilMap.getString(doc, "instanceId"), UtilMap.getString(doc, "instanceId"), false);
|
|
|
+ // 通过提供 spaceId + dentryId 查询创建人, 再由创建人为公共账号添加编辑权限, 再通过公共账号复制 [ppExt: 知识库可为其他成员添加不高于自身的权限]
|
|
|
+ DDR_New ddr_dentry = ddClient_storage.getSpaceDentryDetail(ddClient.getAccessToken(), executorIdUnionId, UtilMap.getString(doc, "instanceId"), UtilMap.getString(doc, "instanceId"), false);
|
|
|
try {
|
|
|
String creatorId_t = UtilMap.getString(ddr_dentry.getUpdater(), "unionId");
|
|
|
List<Map> members_t = Arrays.asList(UtilMap.map("type, id", "USER", ddConf.getOperator()));
|
|
@@ -1283,7 +1360,6 @@ public class AWImplClient implements AWClint {
|
|
|
log.error(e.getMessage(), e);
|
|
|
continue;
|
|
|
}
|
|
|
-
|
|
|
// 更新最新版本记录, 叠加版本号
|
|
|
Map formData = UtilMap.map("textField_lx36gdpp, numberField_lx36gdpz", fileName, order);
|
|
|
formData.put("textField_lx342bvd", ddr_new.getDentryId());
|
|
@@ -1304,11 +1380,11 @@ public class AWImplClient implements AWClint {
|
|
|
tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), UtilMap.map("customfieldName, value", AWServer.TASK_APPROVE_VERSION, attas));
|
|
|
}
|
|
|
}
|
|
|
+ // prd: 变更有单独BPM流程, TBx宜搭只是作为归档管理, 目前交付物审批只有同意和退回操作 [6.18]
|
|
|
if (StringUtils.isNotBlank(result)) {
|
|
|
Map body = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_VERSION, result);
|
|
|
tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
|
|
|
}
|
|
|
- // todo: 业务待定, 若变更有单独BPM流程, TBx宜搭只是作为归档管理, 不存在变更版本审批拒绝场景
|
|
|
log.info("知识库版本管理, {}", result);
|
|
|
}
|
|
|
|
|
@@ -1317,8 +1393,26 @@ public class AWImplClient implements AWClint {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void tmp() {
|
|
|
+// this.tmp_617();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// tmp: 6.17 处理审批通过数据 [新项目工作量配置异常, 审批通过配置为审核通过]
|
|
|
+ private void tmp_617() {
|
|
|
+
|
|
|
+ List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
|
|
|
+ .formUuid("FORM-812FD46AF391449A8F206EDB3221B38840UQ")
|
|
|
+ .createFromTimeGMT("2024-06-03")
|
|
|
+ .build());
|
|
|
+ for (Map item : dataList) {
|
|
|
+ approved(UtilMap.map("approve, taskId, creatorId, projectId", "审批通过", item.get("textField_lr3dlwsa"), item.get("textField_lr3er4qb"), item.get("textField_lrncs2fu")));
|
|
|
+ }
|
|
|
+ log.info("处理审批通过数据, {}", dataList.size());
|
|
|
+ }
|
|
|
+
|
|
|
/// tmp: 5.22 处理检查项重复数据
|
|
|
- private void _test() {
|
|
|
+ private void tmp_522() {
|
|
|
List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
|
|
|
.formUuid("FORM-6E2C0D1197264B8AA23EB3FECAE7344B00BN")
|
|
|
.searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_lqxuswze", "A2328")))
|