Skip to content

Commit 15fadb0

Browse files
authored
Merge pull request #85 from codingapi/dev
Dev
2 parents 1e35cf3 + d8b711f commit 15fadb0

9 files changed

Lines changed: 123 additions & 6 deletions

File tree

flow-engine-framework/src/main/java/com/codingapi/flow/service/WorkflowService.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.codingapi.flow.repository.WorkflowRepository;
55
import com.codingapi.flow.repository.WorkflowRuntimeRepository;
66
import com.codingapi.flow.repository.WorkflowVersionRepository;
7+
import com.codingapi.flow.utils.Base64Utils;
78
import com.codingapi.flow.workflow.Workflow;
89
import com.codingapi.flow.workflow.WorkflowVersion;
910
import com.codingapi.flow.workflow.runtime.WorkflowRuntime;
@@ -164,4 +165,17 @@ public void saveWorkflowRuntime(WorkflowRuntime workflowRuntime) {
164165
public WorkflowRuntime getWorkflowRuntime(String workId, long workVersion) {
165166
return this.workflowRuntimeRepository.getByWorkId(workId, workVersion);
166167
}
168+
169+
/**
170+
* 导入流程
171+
* @param body base64
172+
* @return 流程id
173+
*/
174+
public String importWorkflow(String body) {
175+
String json = Base64Utils.toJson(body);
176+
Workflow workflow = Workflow.formJson(json);
177+
workflow.resetWorkflow();
178+
this.saveWorkflow(workflow);
179+
return workflow.getId();
180+
}
167181
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.codingapi.flow.utils;
2+
3+
import java.nio.charset.StandardCharsets;
4+
import java.util.Base64;
5+
6+
public class Base64Utils {
7+
8+
public static String toJson(String base64) {
9+
if (base64 == null) {
10+
return null;
11+
}
12+
// 去掉前缀
13+
if (base64.contains(",")) {
14+
base64 = base64.substring(base64.indexOf(",") + 1);
15+
}
16+
try {
17+
byte[] decoded;
18+
try {
19+
decoded = Base64.getDecoder().decode(base64);
20+
} catch (IllegalArgumentException e) {
21+
decoded = Base64.getUrlDecoder().decode(base64);
22+
}
23+
return new String(decoded, StandardCharsets.UTF_8);
24+
} catch (Exception e) {
25+
throw new IllegalArgumentException("Invalid Base64 string: " + base64.substring(0, 30), e);
26+
}
27+
}
28+
29+
30+
}

flow-engine-framework/src/main/java/com/codingapi/flow/workflow/Workflow.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,11 @@ public boolean isNextNode(IFlowNode currentNode, IFlowNode nextNode) {
373373
public void updateTime() {
374374
this.updatedTime = System.currentTimeMillis();
375375
}
376+
377+
public void resetWorkflow() {
378+
this.id = RandomUtils.generateStringId();
379+
this.code = RandomUtils.generateWorkflowCode();
380+
this.createdTime = System.currentTimeMillis();
381+
this.updateTime();
382+
}
376383
}

flow-engine-framework/src/test/java/com/codingapi/flow/factory/MyFlowServiceFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.codingapi.flow.factory;
22

3+
import com.codingapi.flow.context.GatewayContext;
34
import com.codingapi.flow.context.RepositoryHolderContext;
45
import com.codingapi.flow.gateway.impl.UserGateway;
56
import com.codingapi.flow.repository.*;
@@ -42,6 +43,8 @@ public MyFlowServiceFactory() {
4243
RepositoryHolderContext.getInstance().register(workflowService, flowRecordService, userGateway, parallelBranchRepository, delayTaskRepository, urgeIntervalRepository);
4344
repositoryHolder = RepositoryHolderContext.getInstance();
4445
this.flowService = new FlowService(this.repositoryHolder);
46+
47+
GatewayContext.getInstance().setFlowOperatorGateway(userGateway);
4548
}
4649

4750
}

flow-engine-framework/src/test/java/com/codingapi/flow/service/FlowSampleServiceTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ void create() {
111111
}
112112

113113

114+
@Test
115+
void importWorkflow() {
116+
String data = "data:application/json;base64,eyJ1cGRhdGVkVGltZSI6IjE3NzMyMjI0MzkzMTIiLCJjb2RlIjoicmRZbUt2UzMxOSIsIm5vZGVzIjpbeyJ2aWV3IjoiZGVmYXVsdCIsInN0cmF0ZWdpZXMiOlt7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5L2g5pyJ5LiA5p2h5b6F5YqeXG5kZWYgcnVuKHJlcXVlc3Qpe1xuICAgIHJldHVybiAn5L2g5pyJ5LiA5p2h5b6F5YqeJ1xufVxuIiwic3RyYXRlZ3lUeXBlIjoiTm9kZVRpdGxlU3RyYXRlZ3kifSx7InN0cmF0ZWd5VHlwZSI6IkZvcm1GaWVsZFBlcm1pc3Npb25TdHJhdGVneSIsImZpZWxkUGVybWlzc2lvbnMiOltdfSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlvIDlp4voioLngrkiLCJpZCI6IldSOGNnOTN1c3hqTmxQMXNFVSIsInR5cGUiOiJTVEFSVCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6IkJ6UGtWQ3BISUp6WXNaRVJSYiIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuS/neWtmCJ9LCJpZCI6ImgzYmhoQTBGZHlRTUpNUnlBQSIsInR5cGUiOiJTQVZFIiwidGl0bGUiOiLkv53lrZgifV0sIm9yZGVyIjoiMCJ9LHsidmlldyI6ImRlZmF1bHQiLCJzdHJhdGVnaWVzIjpbeyJ0aW1lb3V0VGltZSI6Ijg2NDAwMDAwIiwidHlwZSI6IlJFTUlORCIsInN0cmF0ZWd5VHlwZSI6IlRpbWVvdXRTdHJhdGVneSJ9LHsidHlwZSI6IlNFUVVFTkNFIiwicGVyY2VudCI6IjAuMCIsInN0cmF0ZWd5VHlwZSI6Ik11bHRpT3BlcmF0b3JBdWRpdFN0cmF0ZWd5In0seyJ0eXBlIjoiQVVUT19QQVNTIiwic3RyYXRlZ3lUeXBlIjoiU2FtZU9wZXJhdG9yQXVkaXRTdHJhdGVneSJ9LHsiZW5hYmxlIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiUmVjb3JkTWVyZ2VTdHJhdGVneSJ9LHsidHlwZSI6IlJFU1VNRSIsInN0cmF0ZWd5VHlwZSI6IlJlc3VibWl0U3RyYXRlZ3kifSx7InNpZ25SZXF1aXJlZCI6ZmFsc2UsImFkdmljZVJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiQWR2aWNlU3RyYXRlZ3kifSx7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5Zue6YCA6Iez5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwibm9kZVwiLFwibm9kZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICRiaW5kLmNyZWF0ZUVycm9yVGhyb3cocmVxdWVzdC5nZXRTdGFydE5vZGUoKSk7XG59XG4iLCJzdHJhdGVneVR5cGUiOiJFcnJvclRyaWdnZXJTdHJhdGVneSJ9LHsic2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDkvaDmnInkuIDmnaHlvoXlip5cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICfkvaDmnInkuIDmnaHlvoXlip4nXG59XG4iLCJzdHJhdGVneVR5cGUiOiJOb2RlVGl0bGVTdHJhdGVneSJ9LHsic3RyYXRlZ3lUeXBlIjoiRm9ybUZpZWxkUGVybWlzc2lvblN0cmF0ZWd5IiwiZmllbGRQZXJtaXNzaW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifX0seyJzY3JpcHQiOiIvLyBAU0NSSVBUX1RJVExFIOa1geeoi+WIm+W7uuiAhVxuLy8gQFNDUklQVF9NRVRBIHtcInR5cGVcIjpcImNyZWF0b3JcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIFtyZXF1ZXN0LmdldENyZWF0ZWRPcGVyYXRvcigpXVxufVxuIiwic3RyYXRlZ3lUeXBlIjoiT3BlcmF0b3JMb2FkU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlrqHmibnoioLngrkiLCJpZCI6IjFNQWNxRkpBbEtCeGNVb2J4MyIsInR5cGUiOiJBUFBST1ZBTCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6ImpjWk9IYWlKcnl6SmIyZkZNciIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuaLkue7nSJ9LCJpZCI6ImJ5VVpub2trNnRYVzRrOHlPVyIsInR5cGUiOiJSRUpFQ1QiLCJ0aXRsZSI6IuaLkue7nSIsInNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg6L+U5Zue5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0U3RhcnROb2RlKCkuZ2V0SWQoKTtcbn1cbiJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5L+d5a2YIn0sImlkIjoiUWplQXp3bU1qSFNOWHBiOVBvIiwidHlwZSI6IlNBVkUiLCJ0aXRsZSI6IuS/neWtmCJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5Yqg562+In0sImlkIjoiUzd4Q09kNHF0ZHRHZDJFbFF3IiwidHlwZSI6IkFERF9BVURJVCIsInRpdGxlIjoi5Yqg562+In0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLovazlip4ifSwiaWQiOiJXNmJiM1dWd1JKSlpWNDVzUjMiLCJ0eXBlIjoiVFJBTlNGRVIiLCJ0aXRsZSI6Iui9rOWKniJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi6YCA5ZueIn0sImlkIjoicVphb0djc3ZXNmVtSlZnTU03IiwidHlwZSI6IlJFVFVSTiIsInRpdGxlIjoi6YCA5ZueIn0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLlp5TmtL4ifSwiaWQiOiJHTTBtaU1IRWdyV25naU1QRnAiLCJ0eXBlIjoiREVMRUdBVEUiLCJ0aXRsZSI6IuWnlOa0viJ9XSwib3JkZXIiOiIwIn0seyJzdHJhdGVnaWVzIjp7IiRyZWYiOiIkLm5vZGVzWzBdLnN0cmF0ZWdpZXNbMV0uZmllbGRQZXJtaXNzaW9ucyJ9LCJkaXNwbGF5Ijp0cnVlLCJuYW1lIjoi57uT5p2f6IqC54K5IiwiaWQiOiJ4cUttRFBpV3BZbXpFQWlONkoiLCJ0eXBlIjoiRU5EIiwiYWN0aW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifSwib3JkZXIiOiIwIn1dLCJmb3JtIjp7ImNvZGUiOiJsZWF2ZSIsIm5hbWUiOiLor7flgYfljZUiLCJmaWVsZHMiOlt7ImNvZGUiOiJkYXlzIiwiaGlkZGVuIjpmYWxzZSwibmFtZSI6IuWkqeaVsCIsImlkIjoiNjhmNjdiODAtODk2YS00MGI5LTk4OGMtYTI2NTI3NjAyNGMyIiwicGxhY2Vob2xkZXIiOiLor7fovpPlhaXlpKnmlbAiLCJ0eXBlIjoiTlVNQkVSIiwicmVxdWlyZWQiOnRydWV9LHsiY29kZSI6ImRlc2MiLCJoaWRkZW4iOmZhbHNlLCJuYW1lIjoi55CG55SxIiwiaWQiOiJmYmJiZGYwNS03NGMwLTQyNDktYmVhYS1hNzdiZDJmN2RlYTQiLCJwbGFjZWhvbGRlciI6Iuivt+i+k+WFpeeQhueUsSIsInR5cGUiOiJTVFJJTkciLCJyZXF1aXJlZCI6dHJ1ZX1dfSwiY3JlYXRlZE9wZXJhdG9yIjoiMSIsInN0cmF0ZWdpZXMiOlt7ImVuYWJsZSI6dHJ1ZSwic3RyYXRlZ3lUeXBlIjoiSW50ZXJmZXJlU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwiaW50ZXJ2YWwiOiI2MCIsInN0cmF0ZWd5VHlwZSI6IlVyZ2VTdHJhdGVneSJ9XSwiY3JlYXRlZFRpbWUiOiIxNzczMjIyNDAxMzU0IiwiaWQiOiJySUVtbVFFUFR4MWx6MmlSSFoiLCJ0aXRsZSI6Iuivt+WBh+a1geeoiyIsIm9wZXJhdG9yQ3JlYXRlU2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDku7vmhI/nlKjmiLdcbi8vIEBTQ1JJUFRfTUVUQSB7XCJ0eXBlXCI6XCJhbnlcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHRydWVcbn1cbiJ9";
117+
String workId = factory.workflowService.importWorkflow(data);
118+
Workflow workflow = factory.workflowService.getWorkflow(workId);
119+
assertEquals("leave", workflow.getForm().getCode());
120+
assertEquals("请假流程", workflow.getTitle());
121+
}
122+
123+
114124
/**
115125
* 全部通过测试
116126
*/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.codingapi.flow.utils;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
class Base64UtilsTest {
8+
9+
@Test
10+
void toJson() {
11+
String data = "data:application/json;base64,eyJ1cGRhdGVkVGltZSI6IjE3NzMyMjI0MzkzMTIiLCJjb2RlIjoicmRZbUt2UzMxOSIsIm5vZGVzIjpbeyJ2aWV3IjoiZGVmYXVsdCIsInN0cmF0ZWdpZXMiOlt7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5L2g5pyJ5LiA5p2h5b6F5YqeXG5kZWYgcnVuKHJlcXVlc3Qpe1xuICAgIHJldHVybiAn5L2g5pyJ5LiA5p2h5b6F5YqeJ1xufVxuIiwic3RyYXRlZ3lUeXBlIjoiTm9kZVRpdGxlU3RyYXRlZ3kifSx7InN0cmF0ZWd5VHlwZSI6IkZvcm1GaWVsZFBlcm1pc3Npb25TdHJhdGVneSIsImZpZWxkUGVybWlzc2lvbnMiOltdfSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlvIDlp4voioLngrkiLCJpZCI6IldSOGNnOTN1c3hqTmxQMXNFVSIsInR5cGUiOiJTVEFSVCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6IkJ6UGtWQ3BISUp6WXNaRVJSYiIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuS/neWtmCJ9LCJpZCI6ImgzYmhoQTBGZHlRTUpNUnlBQSIsInR5cGUiOiJTQVZFIiwidGl0bGUiOiLkv53lrZgifV0sIm9yZGVyIjoiMCJ9LHsidmlldyI6ImRlZmF1bHQiLCJzdHJhdGVnaWVzIjpbeyJ0aW1lb3V0VGltZSI6Ijg2NDAwMDAwIiwidHlwZSI6IlJFTUlORCIsInN0cmF0ZWd5VHlwZSI6IlRpbWVvdXRTdHJhdGVneSJ9LHsidHlwZSI6IlNFUVVFTkNFIiwicGVyY2VudCI6IjAuMCIsInN0cmF0ZWd5VHlwZSI6Ik11bHRpT3BlcmF0b3JBdWRpdFN0cmF0ZWd5In0seyJ0eXBlIjoiQVVUT19QQVNTIiwic3RyYXRlZ3lUeXBlIjoiU2FtZU9wZXJhdG9yQXVkaXRTdHJhdGVneSJ9LHsiZW5hYmxlIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiUmVjb3JkTWVyZ2VTdHJhdGVneSJ9LHsidHlwZSI6IlJFU1VNRSIsInN0cmF0ZWd5VHlwZSI6IlJlc3VibWl0U3RyYXRlZ3kifSx7InNpZ25SZXF1aXJlZCI6ZmFsc2UsImFkdmljZVJlcXVpcmVkIjpmYWxzZSwic3RyYXRlZ3lUeXBlIjoiQWR2aWNlU3RyYXRlZ3kifSx7InNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg5Zue6YCA6Iez5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwibm9kZVwiLFwibm9kZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICRiaW5kLmNyZWF0ZUVycm9yVGhyb3cocmVxdWVzdC5nZXRTdGFydE5vZGUoKSk7XG59XG4iLCJzdHJhdGVneVR5cGUiOiJFcnJvclRyaWdnZXJTdHJhdGVneSJ9LHsic2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDkvaDmnInkuIDmnaHlvoXlip5cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuICfkvaDmnInkuIDmnaHlvoXlip4nXG59XG4iLCJzdHJhdGVneVR5cGUiOiJOb2RlVGl0bGVTdHJhdGVneSJ9LHsic3RyYXRlZ3lUeXBlIjoiRm9ybUZpZWxkUGVybWlzc2lvblN0cmF0ZWd5IiwiZmllbGRQZXJtaXNzaW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifX0seyJzY3JpcHQiOiIvLyBAU0NSSVBUX1RJVExFIOa1geeoi+WIm+W7uuiAhVxuLy8gQFNDUklQVF9NRVRBIHtcInR5cGVcIjpcImNyZWF0b3JcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIFtyZXF1ZXN0LmdldENyZWF0ZWRPcGVyYXRvcigpXVxufVxuIiwic3RyYXRlZ3lUeXBlIjoiT3BlcmF0b3JMb2FkU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwidHlwZSI6IlJFVk9LRV9DVVJSRU5UIiwic3RyYXRlZ3lUeXBlIjoiUmV2b2tlU3RyYXRlZ3kifV0sImRpc3BsYXkiOnRydWUsIm5hbWUiOiLlrqHmibnoioLngrkiLCJpZCI6IjFNQWNxRkpBbEtCeGNVb2J4MyIsInR5cGUiOiJBUFBST1ZBTCIsImFjdGlvbnMiOlt7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IumAmui/hyJ9LCJpZCI6ImpjWk9IYWlKcnl6SmIyZkZNciIsInR5cGUiOiJQQVNTIiwidGl0bGUiOiLpgJrov4cifSx7ImVuYWJsZSI6dHJ1ZSwiZGlzcGxheSI6eyJ0aXRsZSI6IuaLkue7nSJ9LCJpZCI6ImJ5VVpub2trNnRYVzRrOHlPVyIsInR5cGUiOiJSRUpFQ1QiLCJ0aXRsZSI6IuaLkue7nSIsInNjcmlwdCI6Ii8vIEBTQ1JJUFRfVElUTEUg6L+U5Zue5byA5aeL6IqC54K5XG4vLyBAU0NSSVBUX01FVEEge1widHlwZVwiOlwiU1RBUlRcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0U3RhcnROb2RlKCkuZ2V0SWQoKTtcbn1cbiJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5L+d5a2YIn0sImlkIjoiUWplQXp3bU1qSFNOWHBiOVBvIiwidHlwZSI6IlNBVkUiLCJ0aXRsZSI6IuS/neWtmCJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi5Yqg562+In0sImlkIjoiUzd4Q09kNHF0ZHRHZDJFbFF3IiwidHlwZSI6IkFERF9BVURJVCIsInRpdGxlIjoi5Yqg562+In0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLovazlip4ifSwiaWQiOiJXNmJiM1dWd1JKSlpWNDVzUjMiLCJ0eXBlIjoiVFJBTlNGRVIiLCJ0aXRsZSI6Iui9rOWKniJ9LHsiZW5hYmxlIjp0cnVlLCJkaXNwbGF5Ijp7InRpdGxlIjoi6YCA5ZueIn0sImlkIjoicVphb0djc3ZXNmVtSlZnTU03IiwidHlwZSI6IlJFVFVSTiIsInRpdGxlIjoi6YCA5ZueIn0seyJlbmFibGUiOnRydWUsImRpc3BsYXkiOnsidGl0bGUiOiLlp5TmtL4ifSwiaWQiOiJHTTBtaU1IRWdyV25naU1QRnAiLCJ0eXBlIjoiREVMRUdBVEUiLCJ0aXRsZSI6IuWnlOa0viJ9XSwib3JkZXIiOiIwIn0seyJzdHJhdGVnaWVzIjp7IiRyZWYiOiIkLm5vZGVzWzBdLnN0cmF0ZWdpZXNbMV0uZmllbGRQZXJtaXNzaW9ucyJ9LCJkaXNwbGF5Ijp0cnVlLCJuYW1lIjoi57uT5p2f6IqC54K5IiwiaWQiOiJ4cUttRFBpV3BZbXpFQWlONkoiLCJ0eXBlIjoiRU5EIiwiYWN0aW9ucyI6eyIkcmVmIjoiJC5ub2Rlc1swXS5zdHJhdGVnaWVzWzFdLmZpZWxkUGVybWlzc2lvbnMifSwib3JkZXIiOiIwIn1dLCJmb3JtIjp7ImNvZGUiOiJsZWF2ZSIsIm5hbWUiOiLor7flgYfljZUiLCJmaWVsZHMiOlt7ImNvZGUiOiJkYXlzIiwiaGlkZGVuIjpmYWxzZSwibmFtZSI6IuWkqeaVsCIsImlkIjoiNjhmNjdiODAtODk2YS00MGI5LTk4OGMtYTI2NTI3NjAyNGMyIiwicGxhY2Vob2xkZXIiOiLor7fovpPlhaXlpKnmlbAiLCJ0eXBlIjoiTlVNQkVSIiwicmVxdWlyZWQiOnRydWV9LHsiY29kZSI6ImRlc2MiLCJoaWRkZW4iOmZhbHNlLCJuYW1lIjoi55CG55SxIiwiaWQiOiJmYmJiZGYwNS03NGMwLTQyNDktYmVhYS1hNzdiZDJmN2RlYTQiLCJwbGFjZWhvbGRlciI6Iuivt+i+k+WFpeeQhueUsSIsInR5cGUiOiJTVFJJTkciLCJyZXF1aXJlZCI6dHJ1ZX1dfSwiY3JlYXRlZE9wZXJhdG9yIjoiMSIsInN0cmF0ZWdpZXMiOlt7ImVuYWJsZSI6dHJ1ZSwic3RyYXRlZ3lUeXBlIjoiSW50ZXJmZXJlU3RyYXRlZ3kifSx7ImVuYWJsZSI6dHJ1ZSwiaW50ZXJ2YWwiOiI2MCIsInN0cmF0ZWd5VHlwZSI6IlVyZ2VTdHJhdGVneSJ9XSwiY3JlYXRlZFRpbWUiOiIxNzczMjIyNDAxMzU0IiwiaWQiOiJySUVtbVFFUFR4MWx6MmlSSFoiLCJ0aXRsZSI6Iuivt+WBh+a1geeoiyIsIm9wZXJhdG9yQ3JlYXRlU2NyaXB0IjoiLy8gQFNDUklQVF9USVRMRSDku7vmhI/nlKjmiLdcbi8vIEBTQ1JJUFRfTUVUQSB7XCJ0eXBlXCI6XCJhbnlcIn1cbmRlZiBydW4ocmVxdWVzdCl7XG4gICAgcmV0dXJuIHRydWVcbn1cbiJ9";
12+
13+
// Debug output
14+
System.out.println("Input length: " + data.length());
15+
System.out.println("Input starts with prefix: " + data.startsWith("data:application/json;base64,"));
16+
17+
String result = Base64Utils.toJson(data);
18+
System.out.println("Result length: " + result.length());
19+
System.out.println("First 100 chars: " + result.substring(0, Math.min(100, result.length())));
20+
}
21+
}

flow-engine-starter-api/src/main/java/com/codingapi/flow/api/controller/WorkflowController.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import com.alibaba.fastjson.JSONObject;
44
import com.codingapi.flow.api.pojo.NodeCreateRequest;
55
import com.codingapi.flow.api.pojo.WorkflowUpdateVersionNameRequest;
6-
import com.codingapi.flow.context.GatewayContext;
7-
import com.codingapi.flow.context.RepositoryHolderContext;
6+
import com.codingapi.flow.exception.FlowPermissionException;
87
import com.codingapi.flow.gateway.FlowOperatorGateway;
98
import com.codingapi.flow.mock.MockInstance;
109
import com.codingapi.flow.mock.MockInstanceFactory;
@@ -21,11 +20,15 @@
2120
import com.codingapi.springboot.framework.dto.request.IdRequest;
2221
import com.codingapi.springboot.framework.dto.response.Response;
2322
import com.codingapi.springboot.framework.dto.response.SingleResponse;
23+
import com.codingapi.springboot.framework.exception.LocaleMessageException;
2424
import com.codingapi.springboot.framework.user.UserContext;
25+
import jakarta.servlet.http.HttpServletResponse;
2526
import lombok.AllArgsConstructor;
2627
import org.springframework.util.StringUtils;
2728
import org.springframework.web.bind.annotation.*;
2829

30+
import java.net.URLEncoder;
31+
import java.nio.charset.StandardCharsets;
2932
import java.util.Map;
3033

3134

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

8083
@PostMapping("/mock")
8184
public SingleResponse<String> mock() {
82-
MockInstance mockInstance = MockInstanceFactory.getInstance().create(flowOperatorGateway,workflowRepository);
85+
IFlowOperator current = (IFlowOperator) UserContext.getInstance().current();
86+
if (current != null) {
87+
if (!current.isFlowManager()) {
88+
throw FlowPermissionException.accessDenied(current.getName());
89+
}
90+
}
91+
MockInstance mockInstance = MockInstanceFactory.getInstance().create(flowOperatorGateway, workflowRepository);
8392
return SingleResponse.of(mockInstance.getMockKey());
8493
}
8594

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

92-
93101
@PostMapping("/create")
94102
public SingleResponse<JSONObject> create() {
95103
Workflow workflow = WorkflowBuilder.builder()
@@ -99,6 +107,28 @@ public SingleResponse<JSONObject> create() {
99107
return SingleResponse.of(jsonObject);
100108
}
101109

110+
@PostMapping("/import")
111+
public SingleResponse<String> importWorkflow(@RequestBody JSONObject body) {
112+
String workId = workflowService.importWorkflow(body.getString("file"));
113+
return SingleResponse.of(workId);
114+
}
115+
116+
@GetMapping("/export")
117+
public void export(IdRequest request, HttpServletResponse response) {
118+
Workflow workflow = workflowService.getWorkflow(request.getStringId());
119+
JSONObject jsonObject = JSONObject.parseObject(workflow.toJson());
120+
try {
121+
response.setContentType("application/json;charset=UTF-8");
122+
response.setCharacterEncoding("UTF-8");
123+
String fileName = URLEncoder.encode("workflow_" + request.getStringId() + ".json", StandardCharsets.UTF_8);
124+
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
125+
response.getWriter().write(jsonObject.toJSONString());
126+
response.getWriter().flush();
127+
} catch (Exception e) {
128+
throw new LocaleMessageException("export.error", e);
129+
}
130+
}
131+
102132
@PostMapping("/create-node")
103133
public SingleResponse<Map<String, Object>> createNode(@RequestBody NodeCreateRequest request) {
104134
NodeType type = NodeType.valueOf(request.getType());
@@ -121,7 +151,7 @@ public Response save(@RequestBody JSONObject request) {
121151
if (StringUtils.hasText(versionName)) {
122152
WorkflowVersion workflowVersion = new WorkflowVersion(workflow);
123153
workflowVersion.setVersionName(versionName);
124-
workflowService.saveWorkflowVersion(workflowVersion,true);
154+
workflowService.saveWorkflowVersion(workflowVersion, true);
125155
} else {
126156
workflowService.saveWorkflow(workflow);
127157
}

flow-engine-starter-infra/src/main/java/com/codingapi/flow/infra/repository/impl/WorkflowVersionRepositoryImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import com.codingapi.flow.infra.jpa.WorkflowVersionEntityRepository;
66
import com.codingapi.flow.repository.WorkflowVersionRepository;
77
import com.codingapi.flow.workflow.WorkflowVersion;
8+
import jakarta.transaction.Transactional;
89
import lombok.AllArgsConstructor;
910

1011
import java.util.List;
1112

13+
@Transactional
1214
@AllArgsConstructor
1315
public class WorkflowVersionRepositoryImpl implements WorkflowVersionRepository {
1416

0 commit comments

Comments
 (0)