|
@@ -0,0 +1,323 @@
|
|
|
|
|
+package com.malk.service.aliwork.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.malk.server.aliwork.YDAuth;
|
|
|
|
|
+import com.malk.server.aliwork.YDConf;
|
|
|
|
|
+import com.malk.server.common.McException;
|
|
|
|
|
+import com.malk.server.dingtalk.DDR_New;
|
|
|
|
|
+import com.malk.service.aliwork.YDClient_Form;
|
|
|
|
|
+import com.malk.service.dingtalk.DDClient;
|
|
|
|
|
+import com.malk.utils.UtilHttp;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Collections;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 宜搭表单原子接口实现
|
|
|
|
|
+ *
|
|
|
|
|
+ * <p>严格对齐 {@code mjava-baseline §3.4.2}:所有 body_ext 字段透传到 HTTP body,不过滤。
|
|
|
|
|
+ * accessToken 为 null 时回退到 {@code DDClient.initTokenHeader()} 全局 token。</p>
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Service
|
|
|
|
|
+public class YDClient_FormImpl implements YDClient_Form {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private DDClient ddClient;
|
|
|
|
|
+
|
|
|
|
|
+ // ---------------- 共用工具 ----------------
|
|
|
|
|
+
|
|
|
|
|
+ private static final String BASE_V1 = "https://api.dingtalk.com/v1.0/yida";
|
|
|
|
|
+ private static final String BASE_V2 = "https://api.dingtalk.com/v2.0/yida";
|
|
|
|
|
+
|
|
|
|
|
+ private String url(String uri) {
|
|
|
|
|
+ return BASE_V1 + uri;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String urlV2(String uri) {
|
|
|
|
|
+ return BASE_V2 + uri;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构造请求头:accessToken 为 null 时回退到全局 DDClient。
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, String> header(YDAuth auth) {
|
|
|
|
|
+ if (auth.getAccessToken() != null && !auth.getAccessToken().isEmpty()) {
|
|
|
|
|
+ Map<String, String> h = new HashMap<>();
|
|
|
|
|
+ h.put("x-acs-dingtalk-access-token", auth.getAccessToken());
|
|
|
|
|
+ return h;
|
|
|
|
|
+ }
|
|
|
|
|
+ return ddClient.initTokenHeader();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构造基础 body:auth 三字段 + body_ext 透传。
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, Object> body(YDAuth auth) {
|
|
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
|
|
+ body.put("appType", auth.getAppType());
|
|
|
|
|
+ body.put("systemToken", auth.getSystemToken());
|
|
|
|
|
+ body.put("userId", auth.resolvedUserId());
|
|
|
|
|
+ return body;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 合并 body_ext 透传(不过滤任何字段;优先级:显式参数 > body_ext > auth)
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, Object> mergeExt(Map<String, Object> body, Map<String, Object> body_ext) {
|
|
|
|
|
+ if (body_ext == null || body_ext.isEmpty()) {
|
|
|
|
|
+ return body;
|
|
|
|
|
+ }
|
|
|
|
|
+ // body_ext 先进(优先级低),然后显式参数覆盖
|
|
|
|
|
+ Map<String, Object> merged = new HashMap<>(body_ext);
|
|
|
|
|
+ merged.putAll(body);
|
|
|
|
|
+ return merged;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private DDR_New assertResult(DDR_New ddr, String action) {
|
|
|
|
|
+ if (ddr == null) {
|
|
|
|
|
+ throw new McException("宜搭接口 [" + action + "] 返回空");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!ddr.isSuccess()) {
|
|
|
|
|
+ throw new McException("宜搭接口 [" + action + "] 失败: " + ddr.getErrorCode() + " - " + ddr.getErrorMsg());
|
|
|
|
|
+ }
|
|
|
|
|
+ return ddr;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+ // 表单实例 CRUD
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String saveForm(YDAuth auth, String formUuid, String formDataJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("formDataJson", formDataJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/instances"), header(auth), null, body), "saveForm");
|
|
|
|
|
+ return String.valueOf(r.getResult());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> updateForm(YDAuth auth, String formInstanceId, String updateFormDataJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formInstanceId", formInstanceId);
|
|
|
|
|
+ body.put("updateFormDataJson", updateFormDataJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult((DDR_New) UtilHttp.doPut(url("/forms/instances"), header(auth), body, DDR_New.class), "updateForm");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> upsertForm(YDAuth auth, String formUuid, String searchFieldJson, String formDataJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("searchFieldJson", searchFieldJson);
|
|
|
|
|
+ body.put("formDataJson", formDataJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(urlV2("/forms/instances/insertOrUpdate"), header(auth), null, body), "upsertForm");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Boolean deleteForm(YDAuth auth, String formInstanceId, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formInstanceId", formInstanceId);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult((DDR_New) UtilHttp.doDelete(url("/forms/instances"), header(auth), body, DDR_New.class), "deleteForm");
|
|
|
|
|
+ return Boolean.TRUE.equals(r.getResult()) || "true".equalsIgnoreCase(String.valueOf(r.getResult()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Integer deleteFormByCondition(YDAuth auth, String formUuid, String searchFieldJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("searchFieldJson", searchFieldJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/instances/batchRemove"), header(auth), null, body), "deleteFormByCondition");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof Number) {
|
|
|
|
|
+ return ((Number) result).intValue();
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> updateFormComponents(YDAuth auth, List<String> formInstanceIdList, String updateFormDataJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formInstanceIdList", formInstanceIdList);
|
|
|
|
|
+ body.put("updateFormDataJson", updateFormDataJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult((DDR_New) UtilHttp.doPut(url("/forms/instances/components"), header(auth), body, DDR_New.class), "updateFormComponents");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<String> batchSaveForm(YDAuth auth, String formUuid, String formDataListJson, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("formDataListJson", formDataListJson);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/instances/batchSave"), header(auth), null, body), "batchSaveForm");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof List) {
|
|
|
|
|
+ return JSON.parseArray(JSON.toJSONString(result), String.class);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+ // 表单实例查询
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> getForm(YDAuth auth, String formInstanceId, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> param = body(auth);
|
|
|
|
|
+ if (body_ext != null) {
|
|
|
|
|
+ param.putAll(body_ext);
|
|
|
|
|
+ // body_ext 优先级低,auth 字段覆盖
|
|
|
|
|
+ param.putAll(body(auth));
|
|
|
|
|
+ }
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doGet(url("/forms/instances/" + formInstanceId), header(auth), param), "getForm");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> searchForm(YDAuth auth, String formUuid, String searchFieldJson,
|
|
|
|
|
+ Integer currentPage, Integer pageSize, Map<String, Object> body_ext) {
|
|
|
|
|
+ if (pageSize != null && pageSize > YDConf.PAGE_SIZE_LIMIT) {
|
|
|
|
|
+ throw new McException("pageSize 不能超过 " + YDConf.PAGE_SIZE_LIMIT);
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("searchFieldJson", StringUtils.isBlank(searchFieldJson) ? "{}" : searchFieldJson);
|
|
|
|
|
+ body.put("currentPage", currentPage == null ? 1 : currentPage);
|
|
|
|
|
+ body.put("pageSize", pageSize == null ? YDConf.PAGE_SIZE_LIMIT : pageSize);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/instances/search"), header(auth), null, body), "searchForm");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<String> listFormIds(YDAuth auth, String formUuid, String searchFieldJson,
|
|
|
|
|
+ Integer currentPage, Integer pageSize, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("searchFieldJson", StringUtils.isBlank(searchFieldJson) ? "{}" : searchFieldJson);
|
|
|
|
|
+ body.put("currentPage", currentPage == null ? 1 : currentPage);
|
|
|
|
|
+ body.put("pageSize", pageSize == null ? YDConf.PAGE_SIZE_LIMIT : pageSize);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(
|
|
|
|
|
+ DDR_New.doPost(url("/forms/instances/ids/" + auth.getAppType() + "/" + formUuid), header(auth), body, body),
|
|
|
|
|
+ "listFormIds"
|
|
|
|
|
+ );
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof List) {
|
|
|
|
|
+ return JSON.parseArray(JSON.toJSONString(result), String.class);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, Object> listFormsAll(YDAuth auth, String formUuid, String searchFieldJson,
|
|
|
|
|
+ Integer currentPage, Integer pageSize, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formUuid", formUuid);
|
|
|
|
|
+ body.put("searchFieldJson", StringUtils.isBlank(searchFieldJson) ? "{}" : searchFieldJson);
|
|
|
|
|
+ body.put("currentPage", currentPage == null ? 1 : currentPage);
|
|
|
|
|
+ body.put("pageSize", pageSize == null ? YDConf.PAGE_SIZE_LIMIT : pageSize);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/instances/advances/queryAll"), header(auth), null, body), "listFormsAll");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ return result instanceof Map ? (Map<String, Object>) result : Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<Map<String, Object>> listInnerTable(YDAuth auth, String formInstanceId, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> param = body(auth);
|
|
|
|
|
+ if (body_ext != null) {
|
|
|
|
|
+ param.putAll(body_ext);
|
|
|
|
|
+ param.putAll(body(auth));
|
|
|
|
|
+ }
|
|
|
|
|
+ DDR_New r = assertResult(
|
|
|
|
|
+ DDR_New.doGet(url("/forms/innerTables/" + formInstanceId), header(auth), param),
|
|
|
|
|
+ "listInnerTable"
|
|
|
|
|
+ );
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof List) {
|
|
|
|
|
+ return JSON.parseArray(JSON.toJSONString(result), Map.class).stream()
|
|
|
|
|
+ .map(m -> (Map<String, Object>) m)
|
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<Map<String, Object>> listFormOperations(YDAuth auth, String formInstanceId, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formInstanceId", formInstanceId);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doPost(url("/forms/operationsLogs/query"), header(auth), null, body), "listFormOperations");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof List) {
|
|
|
|
|
+ return JSON.parseArray(JSON.toJSONString(result), Map.class).stream()
|
|
|
|
|
+ .map(m -> (Map<String, Object>) m)
|
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<Map<String, Object>> listForms(YDAuth auth, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> param = body(auth);
|
|
|
|
|
+ if (body_ext != null) {
|
|
|
|
|
+ param.putAll(body_ext);
|
|
|
|
|
+ param.putAll(body(auth));
|
|
|
|
|
+ }
|
|
|
|
|
+ DDR_New r = assertResult(DDR_New.doGet(url("/forms"), header(auth), param), "listForms");
|
|
|
|
|
+ Object result = r.getResult();
|
|
|
|
|
+ if (result instanceof List) {
|
|
|
|
|
+ return JSON.parseArray(JSON.toJSONString(result), Map.class).stream()
|
|
|
|
|
+ .map(m -> (Map<String, Object>) m)
|
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void remarkForm(YDAuth auth, String formInstanceId, String remark, Map<String, Object> body_ext) {
|
|
|
|
|
+ Map<String, Object> body = body(auth);
|
|
|
|
|
+ body.put("formInstanceId", formInstanceId);
|
|
|
|
|
+ body.put("remark", remark);
|
|
|
|
|
+ body = mergeExt(body, body_ext);
|
|
|
|
|
+ assertResult(DDR_New.doPost(url("/forms/remarks"), header(auth), null, body), "remarkForm");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+ // 附件临时免登
|
|
|
|
|
+ // ================================================================
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String convertTempUrl(YDAuth auth, String fileUrl, Integer timeoutMs) {
|
|
|
|
|
+ Map<String, Object> param = new HashMap<>();
|
|
|
|
|
+ param.put("systemToken", auth.getSystemToken());
|
|
|
|
|
+ param.put("userId", auth.resolvedUserId());
|
|
|
|
|
+ param.put("fileUrl", fileUrl);
|
|
|
|
|
+ param.put("timeout", timeoutMs == null ? 60_000 : timeoutMs);
|
|
|
|
|
+ DDR_New r = assertResult(
|
|
|
|
|
+ DDR_New.doGet(url("/apps/temporaryUrls/" + auth.getAppType()), header(auth), param),
|
|
|
|
|
+ "convertTempUrl"
|
|
|
|
|
+ );
|
|
|
|
|
+ return String.valueOf(r.getResult());
|
|
|
|
|
+ }
|
|
|
|
|
+}
|