Skip to content
Merged

Dev #85

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.codingapi.flow.repository.WorkflowRepository;
import com.codingapi.flow.repository.WorkflowRuntimeRepository;
import com.codingapi.flow.repository.WorkflowVersionRepository;
import com.codingapi.flow.utils.Base64Utils;
import com.codingapi.flow.workflow.Workflow;
import com.codingapi.flow.workflow.WorkflowVersion;
import com.codingapi.flow.workflow.runtime.WorkflowRuntime;
Expand Down Expand Up @@ -164,4 +165,17 @@ public void saveWorkflowRuntime(WorkflowRuntime workflowRuntime) {
public WorkflowRuntime getWorkflowRuntime(String workId, long workVersion) {
return this.workflowRuntimeRepository.getByWorkId(workId, workVersion);
}

/**
* 导入流程
* @param body base64
* @return 流程id
*/
public String importWorkflow(String body) {
String json = Base64Utils.toJson(body);
Workflow workflow = Workflow.formJson(json);
workflow.resetWorkflow();
this.saveWorkflow(workflow);
return workflow.getId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.codingapi.flow.utils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Base64Utils {

public static String toJson(String base64) {
if (base64 == null) {
return null;
}
// 去掉前缀
if (base64.contains(",")) {
base64 = base64.substring(base64.indexOf(",") + 1);
}
try {
byte[] decoded;
try {
decoded = Base64.getDecoder().decode(base64);
} catch (IllegalArgumentException e) {
decoded = Base64.getUrlDecoder().decode(base64);
}
return new String(decoded, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid Base64 string: " + base64.substring(0, 30), e);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,11 @@ public boolean isNextNode(IFlowNode currentNode, IFlowNode nextNode) {
public void updateTime() {
this.updatedTime = System.currentTimeMillis();
}

public void resetWorkflow() {
this.id = RandomUtils.generateStringId();
this.code = RandomUtils.generateWorkflowCode();
this.createdTime = System.currentTimeMillis();
this.updateTime();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.codingapi.flow.factory;

import com.codingapi.flow.context.GatewayContext;
import com.codingapi.flow.context.RepositoryHolderContext;
import com.codingapi.flow.gateway.impl.UserGateway;
import com.codingapi.flow.repository.*;
Expand Down Expand Up @@ -42,6 +43,8 @@ public MyFlowServiceFactory() {
RepositoryHolderContext.getInstance().register(workflowService, flowRecordService, userGateway, parallelBranchRepository, delayTaskRepository, urgeIntervalRepository);
repositoryHolder = RepositoryHolderContext.getInstance();
this.flowService = new FlowService(this.repositoryHolder);

GatewayContext.getInstance().setFlowOperatorGateway(userGateway);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ void create() {
}


@Test
void importWorkflow() {
String data = "data:application/json;base64,eyJ1cGRhdGVkVGltZSI6IjE3NzMyMjI0MzkzMTIiLCJjb2RlIjoicmRZbUt2UzMxOSIsIm5vZGVzIjpbeyJ2aWV3IjoiZGVmYXVsdCIsInN0cmF0ZWdpZXMiOlt7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5L2g5pyJ5LiA5p2h5b6F5YqeXG5kZWYgcnVuKHJlcXVlc3Qpe1xuICAgIHJldHVybiAn5L2g5pyJ5LiA5p2h5b6F5YqeJ1xufVxuIiwic3RyYXRlZ3lUeXBlIjoiTm9kZVRpdGxlU3RyYXRlZ3kifSx7InN0cmF0ZWd5VHlwZSI6IkZvcm1GaWVsZFBlcm1pc3Npb25TdHJhdGVneSIsImZpZWxkUGVybWlzc2lvbnMiOltdfSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlvIDlp4voioLngrkiLCJpZCI6IldSOGNnOTN1c3hqTmxQMXNFVSIsInR5cGUiOiJTVEFSVCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6IkJ6UGtWQ3BISUp6WXNaRVJSYiIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuS/neWtmCJ9LCJpZCI6ImgzYmhoQTBGZHlRTUpNUnlBQSIsInR5cGUiOiJTQVZFIiwidGl0bGUiOiLkv53lrZgifV0sIm9yZGVyIjoiMCJ9LHsidmlldyI6ImRlZmF1bHQiLCJzdHJhdGVnaWVzIjpbeyJ0aW1lb3V0VGltZSI6Ijg2NDAwMDAwIiwidHlwZSI6IlJFTUlORCIsInN0cmF0ZWd5VHlwZSI6IlRpbWVvdXRTdHJhdGVneSJ9LHsidHlwZSI6IlNFUVVFTkNFIiwicGVyY2VudCI6IjAuMCIsInN0cmF0ZWd5VHlwZSI6Ik11bHRpT3BlcmF0b3JBdWRpdFN0cmF0ZWd5In0seyJ0eXBlIjoiQVVUT19QQVNTIiwic3RyYXRlZ3lUeXBlIjoiU2FtZU9wZXJhdG9yQXVkaXRTdHJhdGVneSJ9LHsiZW5hYmxlIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiUmVjb3JkTWVyZ2VTdHJhdGVneSJ9LHsidHlwZSI6IlJFU1VNRSIsInN0cmF0ZWd5VHlwZSI6IlJlc3VibWl0U3RyYXRlZ3kifSx7InNpZ25SZXF1aXJlZCI6ZmFsc2UsImFkdmljZVJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiQWR2aWNlU3RyYXRlZ3kifSx7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5Zue6YCA6Iez5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwibm9kZVwiLFwibm9kZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICRiaW5kLmNyZWF0ZUVycm9yVGhyb3cocmVxdWVzdC5nZXRTdGFydE5vZGUoKSk7XG59XG4iLCJzdHJhdGVneVR5cGUiOiJFcnJvclRyaWdnZXJTdHJhdGVneSJ9LHsic2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDkvaDmnInkuIDmnaHlvoXlip5cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICfkvaDmnInkuIDmnaHlvoXlip4nXG59XG4iLCJzdHJhdGVneVR5cGUiOiJOb2RlVGl0bGVTdHJhdGVneSJ9LHsic3RyYXRlZ3lUeXBlIjoiRm9ybUZpZWxkUGVybWlzc2lvblN0cmF0ZWd5IiwiZmllbGRQZXJtaXNzaW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifX0seyJzY3JpcHQiOiIvLyBAU0NSSVBUX1RJVExFIOa1geeoi+WIm+W7uuiAhVxuLy8gQFNDUklQVF9NRVRBIHtcInR5cGVcIjpcImNyZWF0b3JcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIFtyZXF1ZXN0LmdldENyZWF0ZWRPcGVyYXRvcigpXVxufVxuIiwic3RyYXRlZ3lUeXBlIjoiT3BlcmF0b3JMb2FkU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlrqHmibnoioLngrkiLCJpZCI6IjFNQWNxRkpBbEtCeGNVb2J4MyIsInR5cGUiOiJBUFBST1ZBTCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6ImpjWk9IYWlKcnl6SmIyZkZNciIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuaLkue7nSJ9LCJpZCI6ImJ5VVpub2trNnRYVzRrOHlPVyIsInR5cGUiOiJSRUpFQ1QiLCJ0aXRsZSI6IuaLkue7nSIsInNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg6L+U5Zue5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0U3RhcnROb2RlKCkuZ2V0SWQoKTtcbn1cbiJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5L+d5a2YIn0sImlkIjoiUWplQXp3bU1qSFNOWHBiOVBvIiwidHlwZSI6IlNBVkUiLCJ0aXRsZSI6IuS/neWtmCJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5Yqg562+In0sImlkIjoiUzd4Q09kNHF0ZHRHZDJFbFF3IiwidHlwZSI6IkFERF9BVURJVCIsInRpdGxlIjoi5Yqg562+In0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLovazlip4ifSwiaWQiOiJXNmJiM1dWd1JKSlpWNDVzUjMiLCJ0eXBlIjoiVFJBTlNGRVIiLCJ0aXRsZSI6Iui9rOWKniJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi6YCA5ZueIn0sImlkIjoicVphb0djc3ZXNmVtSlZnTU03IiwidHlwZSI6IlJFVFVSTiIsInRpdGxlIjoi6YCA5ZueIn0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLlp5TmtL4ifSwiaWQiOiJHTTBtaU1IRWdyV25naU1QRnAiLCJ0eXBlIjoiREVMRUdBVEUiLCJ0aXRsZSI6IuWnlOa0viJ9XSwib3JkZXIiOiIwIn0seyJzdHJhdGVnaWVzIjp7IiRyZWYiOiIkLm5vZGVzWzBdLnN0cmF0ZWdpZXNbMV0uZmllbGRQZXJtaXNzaW9ucyJ9LCJkaXNwbGF5Ijp0cnVlLCJuYW1lIjoi57uT5p2f6IqC54K5IiwiaWQiOiJ4cUttRFBpV3BZbXpFQWlONkoiLCJ0eXBlIjoiRU5EIiwiYWN0aW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifSwib3JkZXIiOiIwIn1dLCJmb3JtIjp7ImNvZGUiOiJsZWF2ZSIsIm5hbWUiOiLor7flgYfljZUiLCJmaWVsZHMiOlt7ImNvZGUiOiJkYXlzIiwiaGlkZGVuIjpmYWxzZSwibmFtZSI6IuWkqeaVsCIsImlkIjoiNjhmNjdiODAtODk2YS00MGI5LTk4OGMtYTI2NTI3NjAyNGMyIiwicGxhY2Vob2xkZXIiOiLor7fovpPlhaXlpKnmlbAiLCJ0eXBlIjoiTlVNQkVSIiwicmVxdWlyZWQiOnRydWV9LHsiY29kZSI6ImRlc2MiLCJoaWRkZW4iOmZhbHNlLCJuYW1lIjoi55CG55SxIiwiaWQiOiJmYmJiZGYwNS03NGMwLTQyNDktYmVhYS1hNzdiZDJmN2RlYTQiLCJwbGFjZWhvbGRlciI6Iuivt+i+k+WFpeeQhueUsSIsInR5cGUiOiJTVFJJTkciLCJyZXF1aXJlZCI6dHJ1ZX1dfSwiY3JlYXRlZE9wZXJhdG9yIjoiMSIsInN0cmF0ZWdpZXMiOlt7ImVuYWJsZSI6dHJ1ZSwic3RyYXRlZ3lUeXBlIjoiSW50ZXJmZXJlU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwiaW50ZXJ2YWwiOiI2MCIsInN0cmF0ZWd5VHlwZSI6IlVyZ2VTdHJhdGVneSJ9XSwiY3JlYXRlZFRpbWUiOiIxNzczMjIyNDAxMzU0IiwiaWQiOiJySUVtbVFFUFR4MWx6MmlSSFoiLCJ0aXRsZSI6Iuivt+WBh+a1geeoiyIsIm9wZXJhdG9yQ3JlYXRlU2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDku7vmhI/nlKjmiLdcbi8vIEBTQ1JJUFRfTUVUQSB7XCJ0eXBlXCI6XCJhbnlcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHRydWVcbn1cbiJ9";
String workId = factory.workflowService.importWorkflow(data);
Workflow workflow = factory.workflowService.getWorkflow(workId);
assertEquals("leave", workflow.getForm().getCode());
assertEquals("请假流程", workflow.getTitle());
}


/**
* 全部通过测试
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.codingapi.flow.utils;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class Base64UtilsTest {

@Test
void toJson() {
String data = "data:application/json;base64,eyJ1cGRhdGVkVGltZSI6IjE3NzMyMjI0MzkzMTIiLCJjb2RlIjoicmRZbUt2UzMxOSIsIm5vZGVzIjpbeyJ2aWV3IjoiZGVmYXVsdCIsInN0cmF0ZWdpZXMiOlt7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5L2g5pyJ5LiA5p2h5b6F5YqeXG5kZWYgcnVuKHJlcXVlc3Qpe1xuICAgIHJldHVybiAn5L2g5pyJ5LiA5p2h5b6F5YqeJ1xufVxuIiwic3RyYXRlZ3lUeXBlIjoiTm9kZVRpdGxlU3RyYXRlZ3kifSx7InN0cmF0ZWd5VHlwZSI6IkZvcm1GaWVsZFBlcm1pc3Npb25TdHJhdGVneSIsImZpZWxkUGVybWlzc2lvbnMiOltdfSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlvIDlp4voioLngrkiLCJpZCI6IldSOGNnOTN1c3hqTmxQMXNFVSIsInR5cGUiOiJTVEFSVCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6IkJ6UGtWQ3BISUp6WXNaRVJSYiIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuS/neWtmCJ9LCJpZCI6ImgzYmhoQTBGZHlRTUpNUnlBQSIsInR5cGUiOiJTQVZFIiwidGl0bGUiOiLkv53lrZgifV0sIm9yZGVyIjoiMCJ9LHsidmlldyI6ImRlZmF1bHQiLCJzdHJhdGVnaWVzIjpbeyJ0aW1lb3V0VGltZSI6Ijg2NDAwMDAwIiwidHlwZSI6IlJFTUlORCIsInN0cmF0ZWd5VHlwZSI6IlRpbWVvdXRTdHJhdGVneSJ9LHsidHlwZSI6IlNFUVVFTkNFIiwicGVyY2VudCI6IjAuMCIsInN0cmF0ZWd5VHlwZSI6Ik11bHRpT3BlcmF0b3JBdWRpdFN0cmF0ZWd5In0seyJ0eXBlIjoiQVVUT19QQVNTIiwic3RyYXRlZ3lUeXBlIjoiU2FtZU9wZXJhdG9yQXVkaXRTdHJhdGVneSJ9LHsiZW5hYmxlIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiUmVjb3JkTWVyZ2VTdHJhdGVneSJ9LHsidHlwZSI6IlJFU1VNRSIsInN0cmF0ZWd5VHlwZSI6IlJlc3VibWl0U3RyYXRlZ3kifSx7InNpZ25SZXF1aXJlZCI6ZmFsc2UsImFkdmljZVJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiQWR2aWNlU3RyYXRlZ3kifSx7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5Zue6YCA6Iez5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwibm9kZVwiLFwibm9kZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICRiaW5kLmNyZWF0ZUVycm9yVGhyb3cocmVxdWVzdC5nZXRTdGFydE5vZGUoKSk7XG59XG4iLCJzdHJhdGVneVR5cGUiOiJFcnJvclRyaWdnZXJTdHJhdGVneSJ9LHsic2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDkvaDmnInkuIDmnaHlvoXlip5cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICfkvaDmnInkuIDmnaHlvoXlip4nXG59XG4iLCJzdHJhdGVneVR5cGUiOiJOb2RlVGl0bGVTdHJhdGVneSJ9LHsic3RyYXRlZ3lUeXBlIjoiRm9ybUZpZWxkUGVybWlzc2lvblN0cmF0ZWd5IiwiZmllbGRQZXJtaXNzaW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifX0seyJzY3JpcHQiOiIvLyBAU0NSSVBUX1RJVExFIOa1geeoi+WIm+W7uuiAhVxuLy8gQFNDUklQVF9NRVRBIHtcInR5cGVcIjpcImNyZWF0b3JcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIFtyZXF1ZXN0LmdldENyZWF0ZWRPcGVyYXRvcigpXVxufVxuIiwic3RyYXRlZ3lUeXBlIjoiT3BlcmF0b3JMb2FkU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlrqHmibnoioLngrkiLCJpZCI6IjFNQWNxRkpBbEtCeGNVb2J4MyIsInR5cGUiOiJBUFBST1ZBTCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6ImpjWk9IYWlKcnl6SmIyZkZNciIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuaLkue7nSJ9LCJpZCI6ImJ5VVpub2trNnRYVzRrOHlPVyIsInR5cGUiOiJSRUpFQ1QiLCJ0aXRsZSI6IuaLkue7nSIsInNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg6L+U5Zue5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0U3RhcnROb2RlKCkuZ2V0SWQoKTtcbn1cbiJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5L+d5a2YIn0sImlkIjoiUWplQXp3bU1qSFNOWHBiOVBvIiwidHlwZSI6IlNBVkUiLCJ0aXRsZSI6IuS/neWtmCJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5Yqg562+In0sImlkIjoiUzd4Q09kNHF0ZHRHZDJFbFF3IiwidHlwZSI6IkFERF9BVURJVCIsInRpdGxlIjoi5Yqg562+In0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLovazlip4ifSwiaWQiOiJXNmJiM1dWd1JKSlpWNDVzUjMiLCJ0eXBlIjoiVFJBTlNGRVIiLCJ0aXRsZSI6Iui9rOWKniJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi6YCA5ZueIn0sImlkIjoicVphb0djc3ZXNmVtSlZnTU03IiwidHlwZSI6IlJFVFVSTiIsInRpdGxlIjoi6YCA5ZueIn0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLlp5TmtL4ifSwiaWQiOiJHTTBtaU1IRWdyV25naU1QRnAiLCJ0eXBlIjoiREVMRUdBVEUiLCJ0aXRsZSI6IuWnlOa0viJ9XSwib3JkZXIiOiIwIn0seyJzdHJhdGVnaWVzIjp7IiRyZWYiOiIkLm5vZGVzWzBdLnN0cmF0ZWdpZXNbMV0uZmllbGRQZXJtaXNzaW9ucyJ9LCJkaXNwbGF5Ijp0cnVlLCJuYW1lIjoi57uT5p2f6IqC54K5IiwiaWQiOiJ4cUttRFBpV3BZbXpFQWlONkoiLCJ0eXBlIjoiRU5EIiwiYWN0aW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifSwib3JkZXIiOiIwIn1dLCJmb3JtIjp7ImNvZGUiOiJsZWF2ZSIsIm5hbWUiOiLor7flgYfljZUiLCJmaWVsZHMiOlt7ImNvZGUiOiJkYXlzIiwiaGlkZGVuIjpmYWxzZSwibmFtZSI6IuWkqeaVsCIsImlkIjoiNjhmNjdiODAtODk2YS00MGI5LTk4OGMtYTI2NTI3NjAyNGMyIiwicGxhY2Vob2xkZXIiOiLor7fovpPlhaXlpKnmlbAiLCJ0eXBlIjoiTlVNQkVSIiwicmVxdWlyZWQiOnRydWV9LHsiY29kZSI6ImRlc2MiLCJoaWRkZW4iOmZhbHNlLCJuYW1lIjoi55CG55SxIiwiaWQiOiJmYmJiZGYwNS03NGMwLTQyNDktYmVhYS1hNzdiZDJmN2RlYTQiLCJwbGFjZWhvbGRlciI6Iuivt+i+k+WFpeeQhueUsSIsInR5cGUiOiJTVFJJTkciLCJyZXF1aXJlZCI6dHJ1ZX1dfSwiY3JlYXRlZE9wZXJhdG9yIjoiMSIsInN0cmF0ZWdpZXMiOlt7ImVuYWJsZSI6dHJ1ZSwic3RyYXRlZ3lUeXBlIjoiSW50ZXJmZXJlU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwiaW50ZXJ2YWwiOiI2MCIsInN0cmF0ZWd5VHlwZSI6IlVyZ2VTdHJhdGVneSJ9XSwiY3JlYXRlZFRpbWUiOiIxNzczMjIyNDAxMzU0IiwiaWQiOiJySUVtbVFFUFR4MWx6MmlSSFoiLCJ0aXRsZSI6Iuivt+WBh+a1geeoiyIsIm9wZXJhdG9yQ3JlYXRlU2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDku7vmhI/nlKjmiLdcbi8vIEBTQ1JJUFRfTUVUQSB7XCJ0eXBlXCI6XCJhbnlcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHRydWVcbn1cbiJ9";

// Debug output
System.out.println("Input length: " + data.length());
System.out.println("Input starts with prefix: " + data.startsWith("data:application/json;base64,"));

String result = Base64Utils.toJson(data);
System.out.println("Result length: " + result.length());
System.out.println("First 100 chars: " + result.substring(0, Math.min(100, result.length())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import com.alibaba.fastjson.JSONObject;
import com.codingapi.flow.api.pojo.NodeCreateRequest;
import com.codingapi.flow.api.pojo.WorkflowUpdateVersionNameRequest;
import com.codingapi.flow.context.GatewayContext;
import com.codingapi.flow.context.RepositoryHolderContext;
import com.codingapi.flow.exception.FlowPermissionException;
import com.codingapi.flow.gateway.FlowOperatorGateway;
import com.codingapi.flow.mock.MockInstance;
import com.codingapi.flow.mock.MockInstanceFactory;
Expand All @@ -21,11 +20,15 @@
import com.codingapi.springboot.framework.dto.request.IdRequest;
import com.codingapi.springboot.framework.dto.response.Response;
import com.codingapi.springboot.framework.dto.response.SingleResponse;
import com.codingapi.springboot.framework.exception.LocaleMessageException;
import com.codingapi.springboot.framework.user.UserContext;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;


Expand Down Expand Up @@ -79,7 +82,13 @@ public Response changeState(@RequestBody IdRequest request) {

@PostMapping("/mock")
public SingleResponse<String> mock() {
MockInstance mockInstance = MockInstanceFactory.getInstance().create(flowOperatorGateway,workflowRepository);
IFlowOperator current = (IFlowOperator) UserContext.getInstance().current();
if (current != null) {
if (!current.isFlowManager()) {
throw FlowPermissionException.accessDenied(current.getName());
}
}
MockInstance mockInstance = MockInstanceFactory.getInstance().create(flowOperatorGateway, workflowRepository);
return SingleResponse.of(mockInstance.getMockKey());
}

Expand All @@ -89,7 +98,6 @@ public Response mock(@RequestBody IdRequest request) {
return Response.buildSuccess();
}


@PostMapping("/create")
public SingleResponse<JSONObject> create() {
Workflow workflow = WorkflowBuilder.builder()
Expand All @@ -99,6 +107,28 @@ public SingleResponse<JSONObject> create() {
return SingleResponse.of(jsonObject);
}

@PostMapping("/import")
public SingleResponse<String> importWorkflow(@RequestBody JSONObject body) {
String workId = workflowService.importWorkflow(body.getString("file"));
return SingleResponse.of(workId);
}

@GetMapping("/export")
public void export(IdRequest request, HttpServletResponse response) {
Workflow workflow = workflowService.getWorkflow(request.getStringId());
JSONObject jsonObject = JSONObject.parseObject(workflow.toJson());
try {
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
String fileName = URLEncoder.encode("workflow_" + request.getStringId() + ".json", StandardCharsets.UTF_8);
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.getWriter().write(jsonObject.toJSONString());
response.getWriter().flush();
} catch (Exception e) {
throw new LocaleMessageException("export.error", e);
}
}

@PostMapping("/create-node")
public SingleResponse<Map<String, Object>> createNode(@RequestBody NodeCreateRequest request) {
NodeType type = NodeType.valueOf(request.getType());
Expand All @@ -121,7 +151,7 @@ public Response save(@RequestBody JSONObject request) {
if (StringUtils.hasText(versionName)) {
WorkflowVersion workflowVersion = new WorkflowVersion(workflow);
workflowVersion.setVersionName(versionName);
workflowService.saveWorkflowVersion(workflowVersion,true);
workflowService.saveWorkflowVersion(workflowVersion, true);
} else {
workflowService.saveWorkflow(workflow);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import com.codingapi.flow.infra.jpa.WorkflowVersionEntityRepository;
import com.codingapi.flow.repository.WorkflowVersionRepository;
import com.codingapi.flow.workflow.WorkflowVersion;
import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;

import java.util.List;

@Transactional
@AllArgsConstructor
public class WorkflowVersionRepositoryImpl implements WorkflowVersionRepository {

Expand Down