Browse Source

前端核心发布: 8.2.80

基础框架发布: 8.2.18
  1) 规则引擎中,增加模型和子模型的导入导出功能
main
wangshaoping 3 months ago
parent
commit
754e1e8b17
  1. 1
      io.sc.engine.rule.frontend/src/i18n/messages.json
  2. 1
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  3. 1
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  4. 74
      io.sc.engine.rule.frontend/src/views/resources/designer/ImportModelDialog.vue
  5. 30
      io.sc.engine.rule.frontend/src/views/resources/designer/Model.vue
  6. 56
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ModelWebController.java
  7. 19
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ModelService.java
  8. 28
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ModelServiceImpl.java
  9. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java
  10. 5
      io.sc.platform.ai/src/main/java/io/sc/platform/ai/provider/ollama/service/support/chat/ChatCallback.java

1
io.sc.engine.rule.frontend/src/i18n/messages.json

@ -53,6 +53,7 @@
"re.model.grid.toolbar.generateGroovySourceCode": "Generate Script Code",
"re.model.grid.entity.resource": "Resource",
"re.model.grid.entity.executeMode": "Execute Mode",
"re.model.dialog.import.title": "Import Sub Model",
"re.parameter.grid.title": "Parameter List",
"re.parameter.grid.toolbar.move": "Move",

1
io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json

@ -53,6 +53,7 @@
"re.model.grid.toolbar.generateGroovySourceCode": "生成腳本代碼",
"re.model.grid.entity.resource": "資源",
"re.model.grid.entity.executeMode": "執行模式",
"re.model.dialog.import.title": "導入子模型",
"re.parameter.grid.title": "參數列表",
"re.parameter.grid.toolbar.move": "移動",

1
io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json

@ -53,6 +53,7 @@
"re.model.grid.toolbar.generateGroovySourceCode": "生成脚本代码",
"re.model.grid.entity.resource": "资源",
"re.model.grid.entity.executeMode": "执行模式",
"re.model.dialog.import.title": "导入子模型",
"re.parameter.grid.title": "参数列表",
"re.parameter.grid.toolbar.move": "移动",

74
io.sc.engine.rule.frontend/src/views/resources/designer/ImportModelDialog.vue

@ -0,0 +1,74 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.model.dialog.import.title')" width="600px" :can-maximize="false">
<q-form action="post">
<div class="row py-1">
<div class="col-1"></div>
<div class="col-10">
<q-file ref="fileRef" v-model="modelValue.file" :label="$t('file.single.tip')" dense outlined clearable counter accept=".json">
<template #prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
</div>
<div class="col-1"></div>
</div>
<div class="row py-1">
<div class="col-1"></div>
<div class="col-10 row justify-center q-gutter-md py-2">
<q-btn icon="bi-database-up" :label="$t('import')" color="primary" @click="importData"></q-btn>
</div>
<div class="col-1"></div>
</div>
</q-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { axios, Environment } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const dialogRef = ref();
const modelValue = reactive({
file: undefined,
});
const fileRef = ref();
let currentSelectedModelId: string;
const importData = () => {
axios
.post(
Environment.apiContextPath('/api/re/model/import/' + currentSelectedModelId),
{
file: fileRef.value.nativeEl.files[0],
},
{
loading: true,
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
.then(() => {
close();
emit('afterImported');
});
};
const open = (modelId: string) => {
currentSelectedModelId = modelId;
modelValue.file = undefined;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

30
io.sc.engine.rule.frontend/src/views/resources/designer/Model.vue

@ -82,7 +82,26 @@
'separator',
'view',
'separator',
'export',
{
name: 'import',
label: $t('import'),
icon: 'file_upload',
enableIf: (args: any) => {
return args.selected;
},
click: (args: any) => {
importDialogRef.open(args.selected.id);
},
},
{
extend: 'export',
enableIf: (args: any) => {
return args.selected;
},
click: (args: any) => {
Downloader.get(Environment.apiContextPath('/api/re/model/export/' + args.selected.id), { loading: true });
},
},
]"
:columns="[
{ width: 220, name: 'name', label: $t('name'), sortable: false },
@ -163,14 +182,16 @@
:source-code-url="Environment.apiContextPath('/api/re/executable/generateGroovySourceCode/' + resource.id)"
:validate-url="Environment.apiContextPath('/api/re/executable/validateGroovySourceCode')"
></SourceCodeDialog>
<ImportDialog ref="importDialogRef" @after-imported="afterImported"></ImportDialog>
</div>
</template>
<script setup lang="ts">
import 'tailwindcss/utilities.css';
import { ref, useAttrs } from 'vue';
import { axios, Environment, Formater, DialogManager, CorporationAuditorEntityManager } from 'platform-core';
import { axios, Environment, Formater, DialogManager, CorporationAuditorEntityManager, Downloader } from 'platform-core';
import SourceCodeDialog from '@/views/shared/SourceCodeDialog.vue';
import { EngineEnums } from '@/views/shared/enums/EngineEnums';
import ImportDialog from './ImportModelDialog.vue';
const attrs = useAttrs();
@ -180,7 +201,12 @@ const props = defineProps({
});
const treeGridRef = ref();
const importDialogRef = ref();
const sourceCodeDialogRef = ref();
const afterImported = () => {
treeGridRef.value.refresh();
};
await EngineEnums.init();
</script>

56
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ModelWebController.java

@ -1,17 +1,33 @@
package io.sc.engine.rule.server.model.controller;
import io.sc.engine.rule.core.ModelAbstract;
import io.sc.engine.rule.core.po.model.Model;
import io.sc.engine.rule.core.po.resource.Resource;
import io.sc.engine.rule.server.model.converter.ModelEntityConverter;
import io.sc.engine.rule.server.model.entity.ModelEntity;
import io.sc.engine.rule.server.model.repository.ModelRepository;
import io.sc.engine.rule.server.model.service.ModelService;
import io.sc.engine.rule.server.model.vo.ModelVo;
import io.sc.engine.rule.server.resource.controller.ResourceWebController;
import io.sc.engine.rule.server.resource.converter.ResourceEntityConverter;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.mvc.support.FileDownloader;
import io.sc.platform.util.ObjectMapperUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* 模型 Controller
@ -19,6 +35,7 @@ import java.util.List;
@RestController("io.sc.engine.rule.server.model.controller.ModelWebController")
@RequestMapping("/api/re/model")
public class ModelWebController extends RestCrudController<ModelVo, ModelEntity,String,ModelRepository,ModelService> {
private static final Logger log = LoggerFactory.getLogger(ModelWebController.class);
@GetMapping("findModelWithSubModelsByResourceId")
protected List<ModelVo> findModelWithSubModelsByResourceId(@RequestParam(name="resourceId") String resourceId) throws Exception {
@ -43,4 +60,43 @@ public class ModelWebController extends RestCrudController<ModelVo, ModelEntity,
}
return list;
}
/**
* 导入模型或子模型
* @param multipartFile 模型或子模型文件
* @param locale 区域
* @return 返回给客户端的操作 js 脚本
* @throws Exception 违例
*/
@PostMapping(value="import/{targetModelId}")
public void importModel(@PathVariable(name="targetModelId",required=true)String targetModelId, @RequestParam(name="file",required=false) MultipartFile multipartFile, Locale locale) throws Exception{
if(multipartFile!=null && !multipartFile.isEmpty()) {
Model model =null;
//解析文件
try {
model = ObjectMapperUtil.json().readValue(multipartFile.getInputStream(), Model.class);
} catch (Exception e) {
log.error("",e);
throw e;
}
//导入
try {
service.imports(targetModelId,model);
}catch (Exception e) {
log.error("",e);
throw e;
}
}
}
@GetMapping(value="export/{id}")
@IgnoreResponseBodyAdvice
public void exportModel(@PathVariable(name="id",required=true)String id, HttpServletRequest request, HttpServletResponse response) throws Exception{
Model po =service.exports(id);
if(po!=null) {
String json = ObjectMapperUtil.json().writeValueAsString(po);
InputStream in =new ByteArrayInputStream(json.getBytes("UTF-8"));
FileDownloader.download(request, response, po.getName() + "_model.json", in);
}
}
}

19
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ModelService.java

@ -3,10 +3,13 @@ package io.sc.engine.rule.server.model.service;
import java.util.List;
import io.sc.engine.rule.core.ModelAbstract;
import io.sc.engine.rule.core.po.model.Model;
import io.sc.engine.rule.core.po.resource.Resource;
import io.sc.engine.rule.server.model.entity.ModelEntity;
import io.sc.engine.rule.server.model.entity.ParameterEntity;
import io.sc.engine.rule.server.model.repository.ModelRepository;
import io.sc.engine.rule.server.model.vo.ModelVo;
import io.sc.engine.rule.server.resource.entity.ResourceEntity;
import io.sc.platform.orm.service.DaoService;
/**
@ -108,4 +111,20 @@ public interface ModelService extends DaoService<ModelEntity, String, ModelRepos
* @return 当前模型所在的根模型及其其下的所有子模型列表
*/
public List<ModelEntity> findModelByParentIdAndCodeOrName(String parentId,String code,String name);
/**
* 导入模型或子模型
* @param targetModelId 目标模型ID
* @param model 模型或子模型对象
* @throws Exception 违例
*/
public void imports(String targetModelId, Model model) throws Exception;
/**
* 导出指定的模型或子模型
* @param id 模型或子模型ID
* @return 模型或子模型 PO 对象
* @throws Exception 违例
*/
public Model exports(String id) throws Exception;
}

28
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ModelServiceImpl.java

@ -1,6 +1,9 @@
package io.sc.engine.rule.server.model.service.impl;
import io.sc.engine.rule.core.ModelAbstract;
import io.sc.engine.rule.core.po.model.Model;
import io.sc.engine.rule.core.po.resource.Resource;
import io.sc.engine.rule.server.model.converter.ModelEntityConverter;
import io.sc.engine.rule.server.model.entity.ModelEntity;
import io.sc.engine.rule.server.model.entity.ParameterEntity;
import io.sc.engine.rule.server.model.exception.ModelEntityAlreadyExistsException;
@ -9,6 +12,7 @@ import io.sc.engine.rule.server.model.repository.ModelRepository;
import io.sc.engine.rule.server.model.service.ModelService;
import io.sc.engine.rule.server.model.service.support.ModelEntityChangedEvent;
import io.sc.engine.rule.server.model.vo.ModelVo;
import io.sc.engine.rule.server.resource.converter.ResourceEntityConverter;
import io.sc.engine.rule.server.resource.entity.ResourceEntity;
import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
@ -290,7 +294,29 @@ public class ModelServiceImpl extends DaoServiceImpl<ModelEntity, String, ModelR
return null;
}
private void recursiveGetSubModels(ModelEntity model,List<ModelEntity> result) {
@Override
@Transactional
public void imports(String targetModelId, Model model) throws Exception {
if(StringUtils.hasText(targetModelId) && model!=null){
ModelEntity targetEntity =findById(targetModelId);
ModelEntity subModelEntity =ModelEntityConverter.fromPo(model);
subModelEntity.clearId();
subModelEntity.setParent(targetEntity);
repository.save(subModelEntity);
}
}
@Override
public Model exports(String id) throws Exception {
ModelEntity entity =findById(id);
if(entity!=null) {
Model po = ModelEntityConverter.toPo(entity);
return po;
}
return null;
}
private void recursiveGetSubModels(ModelEntity model, List<ModelEntity> result) {
if(model!=null) {
List<ModelEntity> models =model.getChildren();
if(models!=null && models.size()>0) {

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java

@ -236,7 +236,7 @@ public class ResourceWebController extends RestCrudController<ResourceVo, Resour
if(po!=null) {
String json =ObjectMapperUtil.json().writeValueAsString(po);
InputStream in =new ByteArrayInputStream(json.getBytes("UTF-8"));
FileDownloader.download(request, response, po.getName() + "_model.json", in);
FileDownloader.download(request, response, po.getName() + "_resource.json", in);
}
}

5
io.sc.platform.ai/src/main/java/io/sc/platform/ai/provider/ollama/service/support/chat/ChatCallback.java

@ -7,7 +7,6 @@ import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import java.io.IOException;
@ -20,12 +19,12 @@ public class ChatCallback implements Callback {
}
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
public void onFailure(Call call, IOException e) {
emitter.completeWithError(e);
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()) {
try (ResponseBody body = response.body()) {
BufferedSource bufferedSource = body.source();

Loading…
Cancel
Save