29 changed files with 3724 additions and 1 deletions
@ -0,0 +1,131 @@ |
|||||
|
package io.sc.engine.rule.core.function; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Random; |
||||
|
|
||||
|
/** |
||||
|
* 算数函数 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public class ArithmeticFunction { |
||||
|
/** |
||||
|
* 获取一个 range 范围内的随机整数 |
||||
|
* @param range 随机数范围 |
||||
|
* @return 随机数 |
||||
|
*/ |
||||
|
public static int randomInt(int range) { |
||||
|
Random random =new Random(); |
||||
|
return random.nextInt(range); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 求最大可比较值 |
||||
|
* @param <T> 参数类型 |
||||
|
* @param numbers 参数列表 |
||||
|
* @return 最大可比较值 |
||||
|
*/ |
||||
|
@SafeVarargs |
||||
|
public static <T extends Comparable<T>> T max(T... numbers) { |
||||
|
T max =null; |
||||
|
if(numbers!=null) { |
||||
|
for(T number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(max!=null) {if(number.compareTo(max)>0) {max =number;} }else {max =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return max; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 求最小可比较值 |
||||
|
* @param <T> 参数类型 |
||||
|
* @param numbers 参数列表 |
||||
|
* @return 最小可比较值 |
||||
|
*/ |
||||
|
@SafeVarargs |
||||
|
public static <T extends Comparable<T>> T min(T... numbers) { |
||||
|
T min =null; |
||||
|
if(numbers!=null) { |
||||
|
for(T number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(min!=null) {if(number.compareTo(min)<0) {min =number;} }else {min =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return min; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 整数求和 |
||||
|
* @param numbers 其他参数列表 |
||||
|
* @return 和 |
||||
|
*/ |
||||
|
public static Integer sum(Integer... numbers) { |
||||
|
Integer sum =null; |
||||
|
if(numbers!=null) { |
||||
|
for(Integer number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(sum!=null) { sum +=number;}else {sum =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return sum; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 小数求和 |
||||
|
* @param numbers 其他参数列表 |
||||
|
* @return 和 |
||||
|
*/ |
||||
|
public static Long sum(Long... numbers) { |
||||
|
Long sum =null; |
||||
|
if(numbers!=null) { |
||||
|
for(Long number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(sum!=null) { sum +=number;}else {sum =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return sum; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 小数求和 |
||||
|
* @param numbers 其他参数列表 |
||||
|
* @return 和 |
||||
|
*/ |
||||
|
public static Double sum(Double... numbers) { |
||||
|
Double sum =null; |
||||
|
if(numbers!=null) { |
||||
|
for(Double number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(sum!=null) { sum +=number;}else {sum =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return sum; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 小数求和 |
||||
|
* @param numbers 其他参数列表 |
||||
|
* @return 和 |
||||
|
*/ |
||||
|
public static BigDecimal sum(BigDecimal... numbers) { |
||||
|
BigDecimal sum =null; |
||||
|
if(numbers!=null) { |
||||
|
for(BigDecimal number : numbers) { |
||||
|
if(number!=null) { |
||||
|
if(sum!=null) { sum=sum.add(number);}else {sum =number;} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return sum; |
||||
|
} |
||||
|
|
||||
|
public static Double transformSequencing(Double value,Double sourceMin,Double sourceMax,Double targetMin,Double targetMax) { |
||||
|
return targetMin + ((value-sourceMin)/(sourceMax-sourceMin))*(targetMax-targetMin); |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package io.sc.engine.rule.core.po.lib.processor; |
||||
|
|
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.core.po.lib.IndicatorProcessor; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
|
import com.fasterxml.jackson.annotation.JsonTypeName; |
||||
|
|
||||
|
/** |
||||
|
* 指标处理器(算数运算操作) |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@JsonTypeName("ARITHMETIC") |
||||
|
@JsonIgnoreProperties(ignoreUnknown=true) |
||||
|
public class ArithmeticIndicatorProcessor extends IndicatorProcessor { |
||||
|
private String arithmetic;//算数表达式
|
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package io.sc.engine.rule.core.po.model.processor; |
||||
|
|
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.core.po.model.ParameterProcessor; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
|
import com.fasterxml.jackson.annotation.JsonTypeName; |
||||
|
|
||||
|
/** |
||||
|
* 模型参数处理器(算数运算操作) |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@JsonTypeName("ARITHMETIC") |
||||
|
@JsonIgnoreProperties(ignoreUnknown=true) |
||||
|
public class ArithmeticParameterProcessor extends ParameterProcessor { |
||||
|
private String arithmetic;//算数表达式
|
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
chrome >=89 |
||||
|
edge >=88 |
||||
|
firefox >=89 |
||||
|
safari >=15 |
||||
|
ios_saf >=15 |
@ -0,0 +1,14 @@ |
|||||
|
################################################################# |
||||
|
# 强制对使用该基本代码的所有人实施一致的编码样式 |
||||
|
################################################################# |
||||
|
|
||||
|
# 顶级配置(即不集成父配置) |
||||
|
root = true |
||||
|
|
||||
|
# 针对所有文件 |
||||
|
[*] |
||||
|
charset = utf-8 # 字符集: utf-8 |
||||
|
indent_size = 2 # 缩进大小: 2 |
||||
|
indent_style = space # 缩进风格: 空格 |
||||
|
insert_final_newline = true # 是否在文件的最后插入一个空行 |
||||
|
trim_trailing_whitespace = true # 是否删除行尾的空格 |
@ -0,0 +1,36 @@ |
|||||
|
module.exports = { |
||||
|
root: true, |
||||
|
|
||||
|
env: { |
||||
|
browser: true, |
||||
|
es2022: true, |
||||
|
"vue/setup-compiler-macros": true, |
||||
|
}, |
||||
|
|
||||
|
parserOptions:{ |
||||
|
ecmaVersion: 2022, |
||||
|
sourceType:"module", |
||||
|
}, |
||||
|
|
||||
|
extends:[ |
||||
|
"eslint:recommended", |
||||
|
"plugin:vue/vue3-recommended", |
||||
|
"plugin:@typescript-eslint/recommended", |
||||
|
"plugin:prettier/recommended", |
||||
|
], |
||||
|
|
||||
|
parser: "vue-eslint-parser", |
||||
|
parserOptions: { |
||||
|
ecmaVersion: 2022, |
||||
|
parser: "@typescript-eslint/parser", |
||||
|
sourceType: "module", |
||||
|
}, |
||||
|
|
||||
|
rules:{ |
||||
|
'semi':[1], |
||||
|
'@typescript-eslint/no-var-requires': 'off', |
||||
|
'@typescript-eslint/no-explicit-any': 'off', |
||||
|
"@typescript-eslint/no-unused-vars": 'off', |
||||
|
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */ |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,31 @@ |
|||||
|
# Logs |
||||
|
logs |
||||
|
*.log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
pnpm-debug.log* |
||||
|
lerna-debug.log* |
||||
|
|
||||
|
node_modules |
||||
|
.DS_Store |
||||
|
dist |
||||
|
dist-ssr |
||||
|
coverage |
||||
|
*.local |
||||
|
|
||||
|
/cypress/videos/ |
||||
|
/cypress/screenshots/ |
||||
|
|
||||
|
# Editor directories and files |
||||
|
.vscode/* |
||||
|
!.vscode/extensions.json |
||||
|
.idea |
||||
|
*.suo |
||||
|
*.ntvs* |
||||
|
*.njsproj |
||||
|
*.sln |
||||
|
*.sw? |
||||
|
|
||||
|
test-results/ |
||||
|
playwright-report/ |
@ -0,0 +1,11 @@ |
|||||
|
# npm 仓库地址, 在 npm install 时使用 |
||||
|
registry=http://nexus.sc.io:8000/repository/npm-public/ |
||||
|
|
||||
|
# 用户邮箱 |
||||
|
email= |
||||
|
|
||||
|
# 注意: 以下 // 不是注释,不能去掉哦 |
||||
|
# 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置 |
||||
|
# _authToken 可通过以下命令获取 |
||||
|
# curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin |
||||
|
//nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.193db44c-7ca5-3cb6-a990-d24b93fb0d10 |
@ -0,0 +1,3 @@ |
|||||
|
build |
||||
|
dist |
||||
|
node_modules |
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"$schema": "https://json.schemastore.org/prettierrc", |
||||
|
"semi": true, |
||||
|
"tabWidth": 2, |
||||
|
"singleQuote": true, |
||||
|
"printWidth": 160, |
||||
|
"trailingComma": "all" |
||||
|
} |
Binary file not shown.
File diff suppressed because it is too large
After Width: | Height: | Size: 85 B |
@ -0,0 +1,5 @@ |
|||||
|
<template> |
||||
|
<w-platform-page></w-platform-page> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"></script> |
@ -0,0 +1,4 @@ |
|||||
|
<template> |
||||
|
<div>authorization</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"></script> |
@ -0,0 +1,83 @@ |
|||||
|
<template> |
||||
|
<w-dialog ref="dialogRef" :title="$t('re.resources.dialog.attachment.title')" width="900px" height="500px" :can-maximize="false"> |
||||
|
<div class="px-2"> |
||||
|
<w-grid |
||||
|
ref="gridRef" |
||||
|
:title="$t('re.resources.dialog.attachment.grid.title')" |
||||
|
selection="multiple" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'add', |
||||
|
'remove', |
||||
|
{ |
||||
|
name: 'download', |
||||
|
label: $t('download'), |
||||
|
}, |
||||
|
]" |
||||
|
:query-form-fields="[]" |
||||
|
:auto-fetch-data="false" |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
:data-url="dataUrl" |
||||
|
:columns="[ |
||||
|
{ width: 120, name: 'id', label: $t('id'), hidden: true }, |
||||
|
{ width: 200, name: 'name', label: $t('name') }, |
||||
|
{ width: '100%', name: 'description', label: $t('description') }, |
||||
|
{ width: 100, name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '300px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'bussinessKey', label: $t('bussinessKey'), type: 'text', defaultValue: foreignValue, hidden: true }, |
||||
|
{ name: 'name', label: $t('re.resources.grid.entity.name'), type: 'text', required: true }, |
||||
|
{ name: 'description', label: $t('re.resources.grid.entity.description'), type: 'text' }, |
||||
|
{ name: 'file', label: $t('re.resources.dialog.attachment.grid.entity.file'), type: 'file' }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</div> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, nextTick } from 'vue'; |
||||
|
import { useI18n } from 'vue-i18n'; |
||||
|
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
opener: { type: Object, default: undefined }, |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
dataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const gridRef = ref(); |
||||
|
const foreignKeyRef = ref(); |
||||
|
|
||||
|
const open = (foreignKey: string) => { |
||||
|
foreignKeyRef.value = foreignKey; |
||||
|
dialogRef.value.show(); |
||||
|
|
||||
|
nextTick(() => { |
||||
|
gridRef.value.refresh(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,58 @@ |
|||||
|
package io.sc.engine.rule.server.lib.entity.processor; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonTypeName; |
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.core.util.ExpressionReplacer; |
||||
|
import io.sc.engine.rule.server.lib.entity.IndicatorProcessorEntity; |
||||
|
import io.sc.engine.rule.server.lib.vo.processor.ArithmeticIndicatorProcessorVo; |
||||
|
|
||||
|
import javax.persistence.Column; |
||||
|
import javax.persistence.DiscriminatorValue; |
||||
|
import javax.persistence.Entity; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 指标处理器(算数运算操作)实体类 |
||||
|
*/ |
||||
|
@Entity |
||||
|
@DiscriminatorValue("ARITHMETIC") |
||||
|
@JsonTypeName("ARITHMETIC") |
||||
|
public class ArithmeticIndicatorProcessorEntity extends IndicatorProcessorEntity { |
||||
|
//算数表达式
|
||||
|
@Column(name="ARITHMETIC_") |
||||
|
private String arithmetic; |
||||
|
|
||||
|
@Override |
||||
|
public ArithmeticIndicatorProcessorVo toVo() { |
||||
|
ArithmeticIndicatorProcessorVo vo =new ArithmeticIndicatorProcessorVo(); |
||||
|
super.toVo(vo); |
||||
|
vo.setType(this.getType()); |
||||
|
vo.setArithmetic(this.getArithmetic()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean replace(Map<String, String> mapping) { |
||||
|
String replaced =ExpressionReplacer.replace(this.arithmetic, mapping); |
||||
|
replaced =(replaced==null?"":replaced); |
||||
|
boolean result =false; |
||||
|
if(!replaced.equals(this.arithmetic)) { |
||||
|
result =true; |
||||
|
} |
||||
|
this.arithmetic =replaced; |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package io.sc.engine.rule.server.lib.vo.processor; |
||||
|
|
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.server.lib.vo.IndicatorProcessorVo; |
||||
|
|
||||
|
/** |
||||
|
* 指标处理器(算数运算操作)Vo 类 |
||||
|
*/ |
||||
|
public class ArithmeticIndicatorProcessorVo extends IndicatorProcessorVo { |
||||
|
//算数表达式
|
||||
|
private String arithmetic; |
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package io.sc.engine.rule.server.migration.support; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
import io.sc.engine.rule.core.po.dictionary.Dictionary; |
||||
|
import io.sc.engine.rule.core.po.lib.Lib; |
||||
|
import io.sc.engine.rule.core.po.resource.Resource; |
||||
|
|
||||
|
public class AllInOne { |
||||
|
private List<Resource> resources =new ArrayList<Resource>(); |
||||
|
private List<Lib> libs =new ArrayList<Lib>(); |
||||
|
private List<Dictionary> dictionaries =new ArrayList<Dictionary>(); |
||||
|
|
||||
|
public List<Resource> getResources() { |
||||
|
return resources; |
||||
|
} |
||||
|
public void setResources(List<Resource> resources) { |
||||
|
this.resources = resources; |
||||
|
} |
||||
|
public List<Lib> getLibs() { |
||||
|
return libs; |
||||
|
} |
||||
|
public void setLibs(List<Lib> libs) { |
||||
|
this.libs = libs; |
||||
|
} |
||||
|
public List<Dictionary> getDictionaries() { |
||||
|
return dictionaries; |
||||
|
} |
||||
|
public void setDictionaries(List<Dictionary> dictionaries) { |
||||
|
this.dictionaries = dictionaries; |
||||
|
} |
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
package io.sc.engine.rule.server.model.entity.processor; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonTypeName; |
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.core.util.ExpressionReplacer; |
||||
|
import io.sc.engine.rule.server.model.entity.ParameterProcessorEntity; |
||||
|
import io.sc.engine.rule.server.model.vo.processor.ArithmeticParameterProcessorVo; |
||||
|
|
||||
|
import javax.persistence.Column; |
||||
|
import javax.persistence.DiscriminatorValue; |
||||
|
import javax.persistence.Entity; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 模型参数处理器(算数运算操作)实体类 |
||||
|
*/ |
||||
|
@Entity |
||||
|
@DiscriminatorValue("ARITHMETIC") |
||||
|
@JsonTypeName("ARITHMETIC") |
||||
|
public class ArithmeticParameterProcessorEntity extends ParameterProcessorEntity { |
||||
|
//算数表达式
|
||||
|
@Column(name="ARITHMETIC_") |
||||
|
private String arithmetic; |
||||
|
|
||||
|
@Override |
||||
|
public ArithmeticParameterProcessorVo toVo() { |
||||
|
ArithmeticParameterProcessorVo vo =new ArithmeticParameterProcessorVo(); |
||||
|
super.toVo(vo); |
||||
|
vo.setArithmetic(this.getArithmetic()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean replace(Map<String, String> mapping) { |
||||
|
String replaced =ExpressionReplacer.replace(this.arithmetic, mapping); |
||||
|
replaced =(replaced==null?"":replaced); |
||||
|
boolean result =false; |
||||
|
if(!replaced.equals(this.arithmetic)) { |
||||
|
result =true; |
||||
|
} |
||||
|
this.arithmetic =replaced; |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package io.sc.engine.rule.server.model.vo.processor; |
||||
|
|
||||
|
import io.sc.engine.rule.core.enums.ProcessorType; |
||||
|
import io.sc.engine.rule.server.model.vo.ParameterProcessorVo; |
||||
|
|
||||
|
/** |
||||
|
* 模型参数处理器(算数运算操作)Vo 类 |
||||
|
*/ |
||||
|
public class ArithmeticParameterProcessorVo extends ParameterProcessorVo { |
||||
|
|
||||
|
//算数表达式
|
||||
|
private String arithmetic; |
||||
|
|
||||
|
@Override |
||||
|
public ProcessorType getType() { |
||||
|
return ProcessorType.ARITHMETIC; |
||||
|
} |
||||
|
|
||||
|
public String getArithmetic() { |
||||
|
return arithmetic; |
||||
|
} |
||||
|
|
||||
|
public void setArithmetic(String arithmetic) { |
||||
|
this.arithmetic = arithmetic; |
||||
|
} |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
package io.sc.platform.attachment.api; |
||||
|
|
||||
|
import io.sc.platform.attachment.api.enums.PersistenceType; |
||||
|
import io.sc.platform.orm.api.vo.AuditorVo; |
||||
|
|
||||
|
public abstract class AttachmentVo extends AuditorVo { |
||||
|
protected String id; |
||||
|
//业务Key
|
||||
|
protected String bussinessKey; |
||||
|
//附件持久化类型
|
||||
|
protected PersistenceType type; |
||||
|
//名称
|
||||
|
protected String name; |
||||
|
//扩展名
|
||||
|
protected String extName; |
||||
|
//描述
|
||||
|
protected String description; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getBussinessKey() { |
||||
|
return bussinessKey; |
||||
|
} |
||||
|
|
||||
|
public void setBussinessKey(String bussinessKey) { |
||||
|
this.bussinessKey = bussinessKey; |
||||
|
} |
||||
|
|
||||
|
public PersistenceType getType() { |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
public void setType(PersistenceType type) { |
||||
|
this.type = type; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getExtName() { |
||||
|
return extName; |
||||
|
} |
||||
|
|
||||
|
public void setExtName(String extName) { |
||||
|
this.extName = extName; |
||||
|
} |
||||
|
|
||||
|
public String getDescription() { |
||||
|
return description; |
||||
|
} |
||||
|
|
||||
|
public void setDescription(String description) { |
||||
|
this.description = description; |
||||
|
} |
||||
|
} |
@ -0,0 +1,60 @@ |
|||||
|
package io.sc.platform.attachment.controller; |
||||
|
|
||||
|
import java.io.ByteArrayInputStream; |
||||
|
import java.io.FileInputStream; |
||||
|
import java.io.InputStream; |
||||
|
import java.util.List; |
||||
|
import java.util.Locale; |
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletResponse; |
||||
|
|
||||
|
import io.sc.platform.attachment.api.AttachmentVo; |
||||
|
import io.sc.platform.attachment.api.enums.PersistenceType; |
||||
|
import io.sc.platform.attachment.jpa.entity.AttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.entity.DatabaseAttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.entity.DiskAttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.repository.AttachmentRepository; |
||||
|
import io.sc.platform.attachment.service.AttachmentService; |
||||
|
import io.sc.platform.mvc.controller.support.RestCrudController; |
||||
|
import io.sc.platform.mvc.support.FileDownloader; |
||||
|
import org.springframework.stereotype.Controller; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
import org.springframework.web.multipart.MultipartFile; |
||||
|
|
||||
|
@Controller |
||||
|
@RequestMapping("/api/system/attachment") |
||||
|
public class AttachmentWebController extends RestCrudController<AttachmentVo,AttachmentEntity,String, AttachmentRepository, AttachmentService> { |
||||
|
|
||||
|
@GetMapping("findByBussinessKey") |
||||
|
@ResponseBody |
||||
|
public List<AttachmentVo> findByBussinessKey(@RequestParam("bussinessKey")String bussinessKey) throws Exception{ |
||||
|
return service.findByBussinessKey(bussinessKey); |
||||
|
} |
||||
|
|
||||
|
@RequestMapping(value="upload/{bussinessKey}",method = RequestMethod.POST) |
||||
|
@ResponseBody |
||||
|
public void add(HttpServletRequest request,@PathVariable("bussinessKey")String bussinessKey,@RequestParam("file") MultipartFile multipartFile,Locale locale) throws Exception{ |
||||
|
service.upload(bussinessKey, request.getParameter("name"), request.getParameter("description"), multipartFile, locale); |
||||
|
} |
||||
|
|
||||
|
@RequestMapping(value="download/{id}",method=RequestMethod.GET) |
||||
|
public void download(HttpServletRequest request,HttpServletResponse response, @PathVariable("id")String id) throws Exception { |
||||
|
AttachmentEntity entity =service.findById(id); |
||||
|
if(entity!=null) { |
||||
|
if(PersistenceType.DISK.equals(entity.getType())) { |
||||
|
DiskAttachmentEntity _entity =(DiskAttachmentEntity)entity; |
||||
|
String file =service.getDiskAttachmentFilePath(_entity); |
||||
|
if(StringUtils.hasText(file)) { |
||||
|
InputStream in =new FileInputStream(file); |
||||
|
FileDownloader.download(request, response, _entity.getName(), in); |
||||
|
} |
||||
|
}else { |
||||
|
DatabaseAttachmentEntity _entity =(DatabaseAttachmentEntity)entity; |
||||
|
InputStream in =new ByteArrayInputStream(_entity.getBytes()); |
||||
|
FileDownloader.download(request, response, _entity.getName(), in); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,118 @@ |
|||||
|
package io.sc.platform.attachment.jpa.entity; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes; |
||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
||||
|
import io.sc.platform.attachment.api.AttachmentVo; |
||||
|
import io.sc.platform.attachment.api.enums.PersistenceType; |
||||
|
import io.sc.platform.orm.entity.AuditorEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import javax.validation.constraints.Size; |
||||
|
|
||||
|
/** |
||||
|
* 附件实体类 |
||||
|
*/ |
||||
|
@Entity |
||||
|
@Table(name="SYS_ATTACHMENT") |
||||
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) |
||||
|
@DiscriminatorColumn(name="PERSISTENCE_TYPE_",discriminatorType=DiscriminatorType.STRING,length=10) |
||||
|
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl= DatabaseAttachmentEntity.class) |
||||
|
@JsonSubTypes({ |
||||
|
@JsonSubTypes.Type(value= DiskAttachmentEntity.class), //磁盘文件
|
||||
|
@JsonSubTypes.Type(value= DatabaseAttachmentEntity.class) //数据库
|
||||
|
}) |
||||
|
public abstract class AttachmentEntity extends AuditorEntity<AttachmentVo> { |
||||
|
//ID,主键
|
||||
|
@Id |
||||
|
@GeneratedValue(generator = "system-uuid") |
||||
|
@GenericGenerator(name = "system-uuid", strategy = "uuid2") |
||||
|
@Column(name="ID_", length=36) |
||||
|
@Size(max=36) |
||||
|
protected String id; |
||||
|
|
||||
|
//业务Key
|
||||
|
@Column(name="BUSSINESS_KEY_", length=256) |
||||
|
@Size(max=256) |
||||
|
protected String bussinessKey; |
||||
|
|
||||
|
//附件持久化类型
|
||||
|
@Column(name="PERSISTENCE_TYPE_", insertable=false,updatable=false) |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
protected PersistenceType type; |
||||
|
|
||||
|
//名称
|
||||
|
@Column(name="NAME_", length=256) |
||||
|
@Size(max=256) |
||||
|
protected String name; |
||||
|
|
||||
|
//扩展名
|
||||
|
@Column(name="EXT_NAME_", length=10) |
||||
|
@Size(max=10) |
||||
|
protected String extName; |
||||
|
|
||||
|
//描述
|
||||
|
@Column(name="DESCRIPTION_", length=1024) |
||||
|
@Size(max=1024) |
||||
|
protected String description; |
||||
|
|
||||
|
public void toVo(AttachmentVo vo){ |
||||
|
if(vo!=null){ |
||||
|
super.toVo(vo); |
||||
|
vo.setId(this.getId()); |
||||
|
vo.setBussinessKey(this.getBussinessKey()); |
||||
|
vo.setType(this.getType()); |
||||
|
vo.setName(this.getName()); |
||||
|
vo.setExtName(this.getExtName()); |
||||
|
vo.setDescription(this.getDescription()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getBussinessKey() { |
||||
|
return bussinessKey; |
||||
|
} |
||||
|
|
||||
|
public void setBussinessKey(String bussinessKey) { |
||||
|
this.bussinessKey = bussinessKey; |
||||
|
} |
||||
|
|
||||
|
public PersistenceType getType() { |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
public void setType(PersistenceType type) { |
||||
|
this.type = type; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getExtName() { |
||||
|
return extName; |
||||
|
} |
||||
|
|
||||
|
public void setExtName(String extName) { |
||||
|
this.extName = extName; |
||||
|
} |
||||
|
|
||||
|
public String getDescription() { |
||||
|
return description; |
||||
|
} |
||||
|
|
||||
|
public void setDescription(String description) { |
||||
|
this.description = description; |
||||
|
} |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package io.sc.platform.attachment.jpa.repository; |
||||
|
|
||||
|
import io.sc.platform.attachment.jpa.entity.AttachmentEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.jpa.repository.Query; |
||||
|
import org.springframework.data.repository.query.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Set; |
||||
|
|
||||
|
public interface AttachmentRepository extends DaoRepository<AttachmentEntity,String> { |
||||
|
|
||||
|
public List<AttachmentEntity> findByBussinessKeyOrderByName(String bussinessKey); |
||||
|
|
||||
|
|
||||
|
@Query("select e from AttachmentEntity e where e.bussinessKey in (:bussinessKeys)") |
||||
|
public List<AttachmentEntity> findByBussinessKeys(@Param("bussinessKeys")Set<String> bussinessKeys); |
||||
|
} |
@ -0,0 +1,52 @@ |
|||||
|
package io.sc.platform.attachment.service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Locale; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
|
||||
|
import io.sc.platform.attachment.api.AttachmentVo; |
||||
|
import io.sc.platform.attachment.api.DiskAttachmentVo; |
||||
|
import io.sc.platform.attachment.jpa.entity.AttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.entity.DiskAttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.repository.AttachmentRepository; |
||||
|
import io.sc.platform.orm.service.DaoService; |
||||
|
import org.springframework.web.multipart.MultipartFile; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 附件服务接口 |
||||
|
*/ |
||||
|
public interface AttachmentService extends DaoService<AttachmentEntity, String, AttachmentRepository> { |
||||
|
/** |
||||
|
* 通过业务Key查找附件列表 |
||||
|
* @param bussinessKey 业务Key |
||||
|
* @return 附件列表 |
||||
|
*/ |
||||
|
public List<AttachmentVo> findByBussinessKey(String bussinessKey); |
||||
|
|
||||
|
/** |
||||
|
* 通过业务Key集合查找附件列表 |
||||
|
* @param bussinessKeys 业务Key集合 |
||||
|
* @return 附件列表Map(Key:bussinessKey,value:附件列表) |
||||
|
*/ |
||||
|
public Map<String,List<AttachmentVo>> findByBussinessKeys(Set<String> bussinessKeys); |
||||
|
|
||||
|
/** |
||||
|
* 获取磁盘附件的文件路径 |
||||
|
* @param entity 附件对象 |
||||
|
* @return 磁盘附件的文件路径 |
||||
|
*/ |
||||
|
public String getDiskAttachmentFilePath(DiskAttachmentEntity entity); |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* 上传附件 |
||||
|
* @param bussinessKey 业务 Key |
||||
|
* @param name 附件名称 |
||||
|
* @param description 附件描述 |
||||
|
* @param multipartFile 附件 |
||||
|
* @param locale 区域 |
||||
|
*/ |
||||
|
public void upload(String bussinessKey,String name,String description,MultipartFile multipartFile,Locale locale) throws Exception; |
||||
|
} |
@ -0,0 +1,116 @@ |
|||||
|
package io.sc.platform.attachment.service.impl; |
||||
|
|
||||
|
import io.sc.platform.attachment.api.AttachmentVo; |
||||
|
import io.sc.platform.attachment.api.enums.PersistenceType; |
||||
|
import io.sc.platform.attachment.jpa.entity.AttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.entity.DatabaseAttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.entity.DiskAttachmentEntity; |
||||
|
import io.sc.platform.attachment.jpa.repository.AttachmentRepository; |
||||
|
import io.sc.platform.attachment.service.AttachmentService; |
||||
|
import io.sc.platform.core.DirectoryManager; |
||||
|
import io.sc.platform.core.util.FileUtil; |
||||
|
import io.sc.platform.mvc.service.SystemParameterService; |
||||
|
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
|
import io.sc.platform.orm.util.EntityVoUtil; |
||||
|
import org.apache.commons.io.IOUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
import org.springframework.web.multipart.MultipartFile; |
||||
|
|
||||
|
import java.io.*; |
||||
|
import java.util.*; |
||||
|
|
||||
|
@Service("frAttachmentService") |
||||
|
public class AttachmentServiceImpl extends DaoServiceImpl<AttachmentEntity, String, AttachmentRepository> implements AttachmentService { |
||||
|
@Autowired private SystemParameterService systemParameterService; |
||||
|
|
||||
|
@Override |
||||
|
public List<AttachmentVo> findByBussinessKey(String bussinessKey) { |
||||
|
return EntityVoUtil.toVo(repository.findByBussinessKeyOrderByName(bussinessKey)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public Map<String, List<AttachmentVo>> findByBussinessKeys(Set<String> bussinessKeys) { |
||||
|
if(bussinessKeys!=null && bussinessKeys.size()>0) { |
||||
|
List<AttachmentEntity> entities =repository.findByBussinessKeys(bussinessKeys); |
||||
|
if(entities!=null && entities.size()>0) { |
||||
|
Map<String, List<AttachmentVo>> result =new HashMap<>(); |
||||
|
for(AttachmentEntity entity : entities) { |
||||
|
List<AttachmentVo> list =result.get(entity.getBussinessKey()); |
||||
|
if(list==null) { |
||||
|
list =new ArrayList<AttachmentVo>(); |
||||
|
list.add(entity.toVo()); |
||||
|
result.put(entity.getBussinessKey(), list); |
||||
|
}else { |
||||
|
list.add(entity.toVo()); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public String getDiskAttachmentFilePath(DiskAttachmentEntity entity) { |
||||
|
if(entity!=null) { |
||||
|
String path = DirectoryManager.getInstance().getByName("dir.work.web.upload"); |
||||
|
String attachmentPath =entity.getPath(); |
||||
|
if(StringUtils.hasText(attachmentPath)) { |
||||
|
if(attachmentPath.startsWith("/") || attachmentPath.startsWith("\\")) { |
||||
|
path =path + attachmentPath; |
||||
|
}else { |
||||
|
path =path + File.separator + attachmentPath; |
||||
|
} |
||||
|
} |
||||
|
if(path.endsWith("/") || path.endsWith("\\")) { |
||||
|
path =path + entity.getId() + entity.getExtName(); |
||||
|
}else { |
||||
|
path =path + File.separator + entity.getId() + entity.getExtName(); |
||||
|
} |
||||
|
return path; |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void upload(String bussinessKey, String name, String description, MultipartFile multipartFile,Locale locale) throws Exception{ |
||||
|
if(multipartFile!=null) { |
||||
|
InputStream ins = multipartFile.getInputStream(); |
||||
|
byte[] bytes = new byte[ins.available()]; |
||||
|
ins.read(bytes); |
||||
|
ins.close(); |
||||
|
|
||||
|
String attachmentPersistenceType = systemParameterService.getParameter("attachmentPersistenceType"); |
||||
|
if (PersistenceType.DISK.equals(PersistenceType.valueOf(attachmentPersistenceType))) { |
||||
|
DiskAttachmentEntity _entity = new DiskAttachmentEntity(); |
||||
|
_entity.setPath("/"); |
||||
|
_entity.setBussinessKey(bussinessKey); |
||||
|
_entity.setName(name); |
||||
|
_entity.setExtName(FileUtil.getFileExtName(multipartFile.getOriginalFilename())); |
||||
|
_entity.setDescription(description); |
||||
|
AttachmentEntity entity = add(_entity); |
||||
|
persistence2Disk((DiskAttachmentEntity) entity, bytes); |
||||
|
} else { |
||||
|
DatabaseAttachmentEntity _entity = new DatabaseAttachmentEntity(); |
||||
|
_entity.setBussinessKey(bussinessKey); |
||||
|
_entity.setName(name); |
||||
|
_entity.setExtName(FileUtil.getFileExtName(multipartFile.getName())); |
||||
|
_entity.setDescription(description); |
||||
|
_entity.setBytes(bytes); |
||||
|
add(_entity); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void persistence2Disk(DiskAttachmentEntity entity,byte[] bytes) throws FileNotFoundException, IOException { |
||||
|
String file =getDiskAttachmentFilePath(entity); |
||||
|
if(StringUtils.hasText(file)) { |
||||
|
IOUtils.copy(new ByteArrayInputStream(bytes), new FileOutputStream(file)); |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue