#2 -- Add inference dtos #22
@ -46,8 +46,7 @@ dependencies {
|
||||
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
|
||||
implementation group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
|
||||
implementation group: 'org.webjars', name: 'bootstrap-select', version: '1.13.8'
|
||||
implementation group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
|
||||
implementation group: 'org.webjars', name: 'highcharts', version: '7.0.0'
|
||||
implementation 'org.webjars.npm:bootstrap-icons:1.11.3'
|
||||
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
|
||||
}
|
||||
|
@ -24,4 +24,18 @@ public class ProjectVariableService {
|
||||
}
|
||||
return variableRepository.findByProject(projectService.getById(projectId));
|
||||
}
|
||||
|
||||
public List<Variable> getInputByProjectId(Integer projectId) {
|
||||
if (projectId == null || projectId == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return variableRepository.getInputByProject(projectService.getById(projectId));
|
||||
}
|
||||
|
||||
public List<Variable> getOutputByProjectId(Integer projectId) {
|
||||
if (projectId == null || projectId == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return variableRepository.getOutputByProject(projectService.getById(projectId));
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import ru.ulstu.fc.rule.model.FuzzyRuleForm;
|
||||
import ru.ulstu.fc.rule.model.FuzzyTerm;
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
import ru.ulstu.fc.rule.model.dto.VariableDto;
|
||||
import ru.ulstu.fc.rule.service.FuzzyRuleService;
|
||||
import ru.ulstu.fc.rule.service.FuzzyTermService;
|
||||
import ru.ulstu.fc.rule.service.VariableService;
|
||||
@ -65,11 +65,26 @@ public class FuzzyRuleController {
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/getVariables/{projectId}")
|
||||
public List<Variable> getVariables(@PathVariable("projectId") Integer projectId,
|
||||
final HttpServletResponse response) {
|
||||
public List<VariableDto> getVariables(@PathVariable("projectId") Integer projectId,
|
||||
final HttpServletResponse response) {
|
||||
response.addHeader("Cache-Control", "max-age=60, must-revalidate, no-transform");
|
||||
//TODO: return DTO without terms
|
||||
return variableService.getAllByProject(projectId);
|
||||
return variableService.getAllDtoByProject(projectId);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/getInputVariables/{projectId}")
|
||||
public List<VariableDto> getInputVariables(@PathVariable("projectId") Integer projectId,
|
||||
final HttpServletResponse response) {
|
||||
response.addHeader("Cache-Control", "max-age=60, must-revalidate, no-transform");
|
||||
return variableService.getInputVariablesDtoByProject(projectId);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/getOutputVariables/{projectId}")
|
||||
public List<VariableDto> getOutputVariables(@PathVariable("projectId") Integer projectId,
|
||||
final HttpServletResponse response) {
|
||||
response.addHeader("Cache-Control", "max-age=60, must-revalidate, no-transform");
|
||||
return variableService.getOutputVariablesDtoByProject(projectId);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
|
@ -7,22 +7,34 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.fc.project.service.ProjectRulesService;
|
||||
import ru.ulstu.fc.rule.model.FuzzyRule;
|
||||
import ru.ulstu.fc.rule.model.FuzzyRuleForm;
|
||||
import ru.ulstu.fc.rule.service.FuzzyRuleService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("fuzzyRuleRest")
|
||||
public class FuzzyRuleRestController {
|
||||
private final FuzzyRuleService ruleService;
|
||||
private final ProjectRulesService projectRulesService;
|
||||
|
||||
public FuzzyRuleRestController(FuzzyRuleService ruleService) {
|
||||
public FuzzyRuleRestController(FuzzyRuleService ruleService,
|
||||
ProjectRulesService projectRulesService) {
|
||||
this.ruleService = ruleService;
|
||||
this.projectRulesService = projectRulesService;
|
||||
}
|
||||
|
||||
@GetMapping("/get/{projectId}/{ruleId}")
|
||||
public FuzzyRule get(@PathVariable(value = "projectId") Integer projectId,
|
||||
@PathVariable(value = "ruleId") Integer id) {
|
||||
@GetMapping("/getAll/{projectId}")
|
||||
public List<FuzzyRule> getAll(@PathVariable(value = "projectId") Integer projectId) {
|
||||
//TODO: return dto
|
||||
return projectRulesService.getByProjectId(projectId);
|
||||
}
|
||||
|
||||
@GetMapping("/get/{ruleId}")
|
||||
public FuzzyRule get(@PathVariable(value = "ruleId") Integer id) {
|
||||
//TODO: return dto
|
||||
return ruleService.getById(id);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.fc.rule.model.InferenceData;
|
||||
import ru.ulstu.fc.rule.model.OutputValue;
|
||||
import ru.ulstu.fc.rule.model.ProjectInferenceData;
|
||||
import ru.ulstu.fc.rule.service.FuzzyInferenceService;
|
||||
|
||||
import java.util.List;
|
||||
@ -24,6 +25,11 @@ public class InferenceRestController {
|
||||
return fuzzyInferenceService.getFuzzyInference(inferenceData.getRules(),
|
||||
inferenceData.getValues(),
|
||||
inferenceData.getInputVariables(),
|
||||
inferenceData.getOutputVariable());
|
||||
inferenceData.getOutputVariables());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "getProjectInference", method = RequestMethod.POST)
|
||||
public List<OutputValue> getProjectInference(@RequestBody ProjectInferenceData projectInferenceData) {
|
||||
return fuzzyInferenceService.getProjectFuzzyInference(projectInferenceData);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ public class InferenceData {
|
||||
private List<String> rules;
|
||||
private Map<String, Double> values;
|
||||
private List<Variable> inputVariables;
|
||||
private Variable outputVariable;
|
||||
private List<Variable> outputVariables;
|
||||
|
||||
public List<String> getRules() {
|
||||
return rules;
|
||||
@ -33,11 +33,11 @@ public class InferenceData {
|
||||
this.inputVariables = inputVariables;
|
||||
}
|
||||
|
||||
public Variable getOutputVariable() {
|
||||
return outputVariable;
|
||||
public List<Variable> getOutputVariables() {
|
||||
return outputVariables;
|
||||
}
|
||||
|
||||
public void setOutputVariable(Variable outputVariable) {
|
||||
this.outputVariable = outputVariable;
|
||||
public void setOutputVariable(List<Variable> outputVariables) {
|
||||
this.outputVariables = outputVariables;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package ru.ulstu.fc.rule.model;
|
||||
|
||||
public class OutputValue {
|
||||
private String variable;
|
||||
private String fuzzyTerm;
|
||||
private Double degree;
|
||||
|
||||
public OutputValue(String fuzzyTerm, Double degree) {
|
||||
public OutputValue(String variable, String fuzzyTerm, Double degree) {
|
||||
this.variable = variable;
|
||||
this.fuzzyTerm = fuzzyTerm;
|
||||
this.degree = degree;
|
||||
}
|
||||
@ -24,4 +26,12 @@ public class OutputValue {
|
||||
public void setDegree(Double degree) {
|
||||
this.degree = degree;
|
||||
}
|
||||
|
||||
public String getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public void setVariable(String variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package ru.ulstu.fc.rule.model;
|
||||
|
||||
import ru.ulstu.fc.rule.model.dto.VariableValueDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ProjectInferenceData {
|
||||
private Integer projectId;
|
||||
private List<VariableValueDto> variableValues;
|
||||
|
||||
public Integer getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(Integer projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public List<VariableValueDto> getVariableValues() {
|
||||
return variableValues;
|
||||
}
|
||||
|
||||
public void setVariableValues(List<VariableValueDto> variableValues) {
|
||||
this.variableValues = variableValues;
|
||||
}
|
||||
}
|
42
src/main/java/ru/ulstu/fc/rule/model/dto/FuzzyTermDto.java
Normal file
42
src/main/java/ru/ulstu/fc/rule/model/dto/FuzzyTermDto.java
Normal file
@ -0,0 +1,42 @@
|
||||
package ru.ulstu.fc.rule.model.dto;
|
||||
|
||||
import ru.ulstu.fc.rule.model.FuzzyTerm;
|
||||
|
||||
public class FuzzyTermDto {
|
||||
private Integer id;
|
||||
private String description;
|
||||
private Double crispValue;
|
||||
|
||||
public FuzzyTermDto() {
|
||||
}
|
||||
|
||||
public FuzzyTermDto(FuzzyTerm fuzzyTerm) {
|
||||
this.description = fuzzyTerm.getDescription();
|
||||
this.crispValue = fuzzyTerm.getCrispValue();
|
||||
this.id = fuzzyTerm.getId();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Double getCrispValue() {
|
||||
return crispValue;
|
||||
}
|
||||
|
||||
public void setCrispValue(Double crispValue) {
|
||||
this.crispValue = crispValue;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
55
src/main/java/ru/ulstu/fc/rule/model/dto/VariableDto.java
Normal file
55
src/main/java/ru/ulstu/fc/rule/model/dto/VariableDto.java
Normal file
@ -0,0 +1,55 @@
|
||||
package ru.ulstu.fc.rule.model.dto;
|
||||
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VariableDto {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private boolean input;
|
||||
private List<FuzzyTermDto> terms = new ArrayList<>();
|
||||
|
||||
public VariableDto() {
|
||||
}
|
||||
|
||||
public VariableDto(Variable variable) {
|
||||
this.id = variable.getId();
|
||||
this.name = variable.getName();
|
||||
this.terms = variable.getFuzzyTerms().stream().map(FuzzyTermDto::new).toList();
|
||||
this.input = variable.isInput();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<FuzzyTermDto> getTerms() {
|
||||
return terms;
|
||||
}
|
||||
|
||||
public void setTerms(List<FuzzyTermDto> terms) {
|
||||
this.terms = terms;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public void setInput(boolean input) {
|
||||
this.input = input;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package ru.ulstu.fc.rule.model.dto;
|
||||
|
||||
public class VariableValueDto {
|
||||
private String variableName;
|
||||
private Double value;
|
||||
|
||||
public String getVariableName() {
|
||||
return variableName;
|
||||
}
|
||||
|
||||
public void setVariableName(String variableName) {
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package ru.ulstu.fc.rule.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import ru.ulstu.fc.project.model.Project;
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
|
||||
@ -11,4 +13,10 @@ public interface VariableRepository extends JpaRepository<Variable, Integer> {
|
||||
List<Variable> findByProject(Project project);
|
||||
|
||||
List<Variable> getByProject(Project project);
|
||||
|
||||
@Query("SELECT v FROM Variable v WHERE v.project = :project AND v.input = true")
|
||||
List<Variable> getInputByProject(@Param("project") Project project);
|
||||
|
||||
@Query("SELECT v FROM Variable v WHERE v.project = :project AND v.input = false")
|
||||
List<Variable> getOutputByProject(@Param("project") Project project);
|
||||
}
|
||||
|
@ -14,10 +14,17 @@ import com.fuzzylite.variable.OutputVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.fc.project.service.ProjectRulesService;
|
||||
import ru.ulstu.fc.project.service.ProjectService;
|
||||
import ru.ulstu.fc.project.service.ProjectVariableService;
|
||||
import ru.ulstu.fc.rule.model.FuzzyRule;
|
||||
import ru.ulstu.fc.rule.model.FuzzyTerm;
|
||||
import ru.ulstu.fc.rule.model.OutputValue;
|
||||
import ru.ulstu.fc.rule.model.ProjectInferenceData;
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
import ru.ulstu.fc.rule.model.dto.VariableValueDto;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@ -31,9 +38,17 @@ public class FuzzyInferenceService {
|
||||
+ " is %s";
|
||||
private final static String NO_RESULT = "Нет результата";
|
||||
private final Engine fuzzyEngine;
|
||||
private final ProjectService projectService;
|
||||
private final FuzzyRuleService fuzzyRuleService;
|
||||
private final ProjectRulesService projectRulesService;
|
||||
private final ProjectVariableService projectVariableService;
|
||||
|
||||
public FuzzyInferenceService(Engine fuzzyEngine) {
|
||||
public FuzzyInferenceService(Engine fuzzyEngine, ProjectService projectService, FuzzyRuleService fuzzyRuleService, ProjectRulesService projectRulesService, ProjectVariableService projectVariableService) {
|
||||
this.fuzzyEngine = fuzzyEngine;
|
||||
this.projectService = projectService;
|
||||
this.fuzzyRuleService = fuzzyRuleService;
|
||||
this.projectRulesService = projectRulesService;
|
||||
this.projectVariableService = projectVariableService;
|
||||
}
|
||||
|
||||
private List<String> getDemoRules() {
|
||||
@ -48,6 +63,7 @@ public class FuzzyInferenceService {
|
||||
final InputVariable input = new InputVariable();
|
||||
input.setName(variable.getName());
|
||||
input.setDescription("");
|
||||
variable.getFuzzyTerms().sort(Comparator.comparing(FuzzyTerm::getCrispValue));
|
||||
input.setRange(0, variable.getFuzzyTerms().get(variable.getFuzzyTerms().size() - 1).getCrispValue());
|
||||
input.setEnabled(true);
|
||||
input.setLockValueInRange(false);
|
||||
@ -89,9 +105,9 @@ public class FuzzyInferenceService {
|
||||
private RuleBlock getRuleBlock(Engine engine,
|
||||
List<String> rules,
|
||||
List<Variable> inputVariables,
|
||||
Variable outputVariable) {
|
||||
List<Variable> outputVariables) {
|
||||
inputVariables.stream().map(this::getInputVariable).forEach(engine::addInputVariable);
|
||||
engine.addOutputVariable(getOutputVariable(outputVariable));
|
||||
outputVariables.stream().map(this::getOutputVariable).forEach(engine::addOutputVariable);
|
||||
|
||||
RuleBlock mamdani = new RuleBlock();
|
||||
mamdani.setName("mamdani");
|
||||
@ -106,22 +122,21 @@ public class FuzzyInferenceService {
|
||||
}
|
||||
|
||||
private List<OutputValue> getConsequent(Engine engine, Map<String, Double> variableValues) {
|
||||
OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME);
|
||||
List<OutputVariable> outputVariables = engine.getOutputVariables();
|
||||
for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) {
|
||||
InputVariable inputVariable = engine.getInputVariable(variableValue.getKey());
|
||||
inputVariable.setValue(variableValue.getValue());
|
||||
}
|
||||
engine.process();
|
||||
if (outputVariable != null) {
|
||||
LOG.info("Output: {}", outputVariable.getValue());
|
||||
}
|
||||
return Double.isNaN(outputVariable.getValue())
|
||||
? List.of(new OutputValue(NO_RESULT, 0.0))
|
||||
: outputVariable.fuzzyOutput()
|
||||
.getTerms()
|
||||
|
||||
return outputVariables
|
||||
.stream()
|
||||
.map(t -> new OutputValue(t.getTerm().getName(), t.getDegree()))
|
||||
.collect(Collectors.toList());
|
||||
.filter(v -> !Double.isNaN(v.getValue()))
|
||||
.map(OutputVariable::fuzzyOutput)
|
||||
.map(a -> new OutputValue(a.getName(),
|
||||
a.getTerms().getFirst().getTerm().getName(),
|
||||
a.getTerms().getFirst().getDegree()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public List<OutputValue> getFuzzyInference(Map<String, Double> vals) {
|
||||
@ -137,19 +152,40 @@ public class FuzzyInferenceService {
|
||||
new FuzzyTerm("высокий", 500000.0))
|
||||
)
|
||||
),
|
||||
new Variable("кредит", List.of(
|
||||
List.of(new Variable("кредит", List.of(
|
||||
new FuzzyTerm("небольшой", 20000.0),
|
||||
new FuzzyTerm("средний", 100000.0),
|
||||
new FuzzyTerm("большой", 1000000.0)))
|
||||
new FuzzyTerm("большой", 1000000.0))))
|
||||
);
|
||||
}
|
||||
|
||||
public List<OutputValue> getFuzzyInference(List<String> rules,
|
||||
Map<String, Double> values,
|
||||
List<Variable> inputVariables,
|
||||
Variable outputVariable) {
|
||||
List<Variable> outputVariables) {
|
||||
fuzzyEngine.getRuleBlocks().clear();
|
||||
fuzzyEngine.addRuleBlock(getRuleBlock(fuzzyEngine, rules, inputVariables, outputVariable));
|
||||
fuzzyEngine.getInputVariables().clear();
|
||||
fuzzyEngine.getOutputVariables().clear();
|
||||
fuzzyEngine.addRuleBlock(getRuleBlock(fuzzyEngine, rules, inputVariables, outputVariables));
|
||||
return getConsequent(fuzzyEngine, values);
|
||||
}
|
||||
|
||||
public List<OutputValue> getProjectFuzzyInference(ProjectInferenceData projectInferenceData) {
|
||||
List<String> fuzzyRules = projectRulesService.getByProjectId(projectInferenceData.getProjectId())
|
||||
.stream()
|
||||
.map(FuzzyRule::getContent)
|
||||
.toList();
|
||||
Map<String, Double> variableValues = projectInferenceData.getVariableValues()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
VariableValueDto::getVariableName,
|
||||
VariableValueDto::getValue));
|
||||
List<Variable> inputVariables = projectVariableService.getInputByProjectId(projectInferenceData.getProjectId());
|
||||
List<Variable> outputVariables = projectVariableService.getOutputByProjectId(projectInferenceData.getProjectId());
|
||||
|
||||
return getFuzzyInference(fuzzyRules,
|
||||
variableValues,
|
||||
inputVariables,
|
||||
outputVariables);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import ru.ulstu.fc.project.service.ProjectService;
|
||||
import ru.ulstu.fc.rule.model.FuzzyTerm;
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
import ru.ulstu.fc.rule.model.VariableForm;
|
||||
import ru.ulstu.fc.rule.model.dto.VariableDto;
|
||||
import ru.ulstu.fc.rule.repository.VariableRepository;
|
||||
|
||||
import java.util.List;
|
||||
@ -69,7 +70,28 @@ public class VariableService {
|
||||
return variableRepository.getByProject(projectService.getById(projectId));
|
||||
}
|
||||
|
||||
public List<VariableDto> getAllDtoByProject(Integer projectId) {
|
||||
return variableRepository.getByProject(projectService.getById(projectId))
|
||||
.stream()
|
||||
.map(VariableDto::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public void checkIsCurrentUserVariableWithThrow(Variable variable) {
|
||||
projectService.checkIsCurrentUserProjectWithThrow(variable.getProject());
|
||||
}
|
||||
|
||||
public List<VariableDto> getInputVariablesDtoByProject(Integer projectId) {
|
||||
return variableRepository.getInputByProject(projectService.getById(projectId))
|
||||
.stream()
|
||||
.map(VariableDto::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public List<VariableDto> getOutputVariablesDtoByProject(Integer projectId) {
|
||||
return variableRepository.getOutputByProject(projectService.getById(projectId))
|
||||
.stream()
|
||||
.map(VariableDto::new)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ function getAntecedent(rule) {
|
||||
return withoutIf[1].trim().split('then')[0].trim();
|
||||
}
|
||||
|
||||
// TODO: remove duplicate
|
||||
function getAntecedentComponents(antecedent) {
|
||||
function getRuleComponents(antecedent) {
|
||||
return antecedent.split('and').map((i) => i.trim());
|
||||
}
|
||||
|
||||
@ -16,11 +15,6 @@ function getConsequent(rule) {
|
||||
return withoutIf[1].trim().split('then')[1].trim();
|
||||
}
|
||||
|
||||
// TODO: remove duplicate
|
||||
function getConsequentComponents(consequent) {
|
||||
return consequent.split('and').map((i) => i.trim());
|
||||
}
|
||||
|
||||
// common
|
||||
function getVariable(variableComponents) {
|
||||
return variableComponents.split('is')[0].trim();
|
||||
@ -56,8 +50,6 @@ function showFeedbackMessage(message, type) {
|
||||
/* exported errorHandler */
|
||||
function errorHandler(response, callBack, errorCallBack) {
|
||||
if (!isEmpty(response.error)) {
|
||||
// TODO: add l10n
|
||||
// showFeedbackMessage(response.error.code + ": " + response.error.message, MessageTypesEnum.DANGER);
|
||||
if (!isEmpty(errorCallBack)) {
|
||||
errorCallBack(response.data);
|
||||
}
|
||||
@ -70,15 +62,12 @@ function errorHandler(response, callBack, errorCallBack) {
|
||||
}
|
||||
|
||||
/* exported getFromRest */
|
||||
function getFromRest(url, callBack) {
|
||||
$.ajax({
|
||||
async function getFromRest(url) {
|
||||
return await $.ajax({
|
||||
url: url,
|
||||
method: 'get',
|
||||
cache: true,
|
||||
dataType: 'json',
|
||||
success: function (response) {
|
||||
errorHandler(response, callBack);
|
||||
}
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
|
||||
@ -120,60 +109,63 @@ function fillSelect(selectElement, values, selectedVal) {
|
||||
$(selectElement).append($("<option />").val(value.id).text(value.name));
|
||||
});
|
||||
$(selectElement).children().each(function () {
|
||||
if ($(this).text() == selectedVal) {
|
||||
if ($(this).text() === selectedVal) {
|
||||
$(this).prop('selected', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fillFuzzyTerms(variablesElement, fuzzyTermsElement, termVal) {
|
||||
getFromRest("/rule/getFuzzyTerms/" + $(variablesElement).val(), function (fuzzyTerms) {
|
||||
let fuzzyTermsData = [];
|
||||
$.each(fuzzyTerms, function (key, value) {
|
||||
fuzzyTermsData.push({
|
||||
id: value.id,
|
||||
name: value.description
|
||||
});
|
||||
async function fillFuzzyTerms(variablesElement, fuzzyTermsElement, termVal) {
|
||||
let fuzzyTerms = await getFromRest("/rule/getFuzzyTerms/" + $(variablesElement).val());
|
||||
let fuzzyTermsData = [];
|
||||
$.each(fuzzyTerms, function (key, value) {
|
||||
fuzzyTermsData.push({
|
||||
id: value.id,
|
||||
name: value.description
|
||||
});
|
||||
fillSelect(fuzzyTermsElement, fuzzyTermsData, termVal);
|
||||
$(fuzzyTermsElement).selectpicker("refresh");
|
||||
$(fuzzyTermsElement).trigger("change");
|
||||
});
|
||||
fillSelect(fuzzyTermsElement, fuzzyTermsData, termVal);
|
||||
}
|
||||
|
||||
function fillVariables(projectId, variablesElement, variableVal) {
|
||||
getFromRest("/rule/getVariables/" + projectId, function (variables) {
|
||||
let variablesData = [];
|
||||
$.each(variables, function (key, value) {
|
||||
variablesData.push({
|
||||
id: value.id,
|
||||
name: value.name
|
||||
});
|
||||
async function fillVariables(projectId, variablesElement, variableVal, cls) {
|
||||
let url = '/rule/';
|
||||
if (cls === 'inputVar') {
|
||||
url += 'getInputVariables/';
|
||||
} else {
|
||||
url += 'getOutputVariables/';
|
||||
}
|
||||
let variables = await getFromRest(url + projectId);
|
||||
let variablesData = [];
|
||||
$.each(variables, function (key, value) {
|
||||
variablesData.push({
|
||||
id: value.id,
|
||||
name: value.name
|
||||
});
|
||||
fillSelect(variablesElement, variablesData, variableVal);
|
||||
$(variablesElement).selectpicker("refresh");
|
||||
$(variablesElement).trigger("change");
|
||||
});
|
||||
fillSelect(variablesElement, variablesData, variableVal);
|
||||
}
|
||||
|
||||
function variableValueChanged(variablesElement, fuzzyTermsElement) {
|
||||
fillFuzzyTerms(variablesElement, fuzzyTermsElement);
|
||||
}
|
||||
|
||||
function fuzzyTermsValueChanged() {
|
||||
async function variableValueChanged(variablesElement, fuzzyTermsElement) {
|
||||
await fillFuzzyTerms(variablesElement, fuzzyTermsElement);
|
||||
$(".selectpicker").selectpicker("refresh");
|
||||
createRule();
|
||||
}
|
||||
|
||||
function createVariableSelect(cls, projectId, variableVal) {
|
||||
function fuzzyTermsValueChanged() {
|
||||
$(".selectpicker").selectpicker("refresh");
|
||||
createRule();
|
||||
}
|
||||
|
||||
async function createVariableSelect(cls, projectId, variableVal) {
|
||||
let variablesElement = $("<select class='selectpicker " + cls + " m-2' data-live-search='true data-width='70%'></select>");
|
||||
fillVariables(projectId, variablesElement, variableVal);
|
||||
await fillVariables(projectId, variablesElement, variableVal, cls);
|
||||
return variablesElement;
|
||||
}
|
||||
|
||||
function createFuzzyTermsSelect(cls, variablesElement, termVal) {
|
||||
async function createFuzzyTermsSelect(cls, variablesElement, termVal) {
|
||||
let fuzzyTermsElement = $("<select class='selectpicker " + cls + " m-2' data-live-search='true data-width='70%'></select>");
|
||||
if ($(variablesElement).val()) {
|
||||
fillFuzzyTerms(variablesElement, fuzzyTermsElement, termVal);
|
||||
await fillFuzzyTerms(variablesElement, fuzzyTermsElement, termVal);
|
||||
}
|
||||
return fuzzyTermsElement;
|
||||
}
|
||||
@ -188,15 +180,15 @@ function removeConsequent(buttonElement) {
|
||||
fuzzyTermsValueChanged();
|
||||
}
|
||||
|
||||
function addAntecedent(parentElement, projectId, variableVal, termVal) {
|
||||
async function addAntecedent(parentElement, projectId, variableVal, termVal) {
|
||||
let rowElement = $("<div class='row'></div>");
|
||||
if ($(parentElement).find('.row').length) {
|
||||
$(rowElement).append("<label class='col col-md-1 m-2'>И</label>");
|
||||
} else {
|
||||
$(rowElement).append("<label class='col col-md-1 m-2'> </label>");
|
||||
}
|
||||
let variablesElement = createVariableSelect('inputVar', projectId, variableVal);
|
||||
let fuzzyTermsElement = createFuzzyTermsSelect('inputVal', variablesElement, termVal);
|
||||
let variablesElement = await createVariableSelect('inputVar', projectId, variableVal);
|
||||
let fuzzyTermsElement = await createFuzzyTermsSelect('inputVal', variablesElement, termVal);
|
||||
$(variablesElement).on("change", function () {
|
||||
variableValueChanged(variablesElement, fuzzyTermsElement)
|
||||
});
|
||||
@ -210,19 +202,20 @@ function addAntecedent(parentElement, projectId, variableVal, termVal) {
|
||||
$(rowElement).append("<a href='#' class='btn btn-outline-dark m-2' onclick='removeAntecedent($(this))'>-</a>");
|
||||
}
|
||||
$(parentElement).append(rowElement);
|
||||
$(".selectpicker").selectpicker("refresh");
|
||||
}
|
||||
|
||||
function addConsequent(parentElement, projectId, variableVal, termVal) {
|
||||
async function addConsequent(parentElement, projectId, variableVal, termVal) {
|
||||
let rowElement = $("<div class='row'></div>");
|
||||
if ($(parentElement).find('.row').length) {
|
||||
$(rowElement).append("<label class='col col-md-1 m-2'>И</label>");
|
||||
} else {
|
||||
$(rowElement).append("<label class='col col-md-1 m-2'> </label>");
|
||||
}
|
||||
let variablesElement = createVariableSelect('outVar', projectId, variableVal);
|
||||
let fuzzyTermsElement = createFuzzyTermsSelect('outVal', variablesElement, termVal);
|
||||
$(variablesElement).on("change", function () {
|
||||
variableValueChanged(variablesElement, fuzzyTermsElement)
|
||||
let variablesElement = await createVariableSelect('outVar', projectId, variableVal);
|
||||
let fuzzyTermsElement = await createFuzzyTermsSelect('outVal', variablesElement, termVal);
|
||||
$(variablesElement).on("change", async function () {
|
||||
await variableValueChanged(variablesElement, fuzzyTermsElement)
|
||||
});
|
||||
$(fuzzyTermsElement).on("change", function () {
|
||||
fuzzyTermsValueChanged()
|
||||
@ -234,20 +227,34 @@ function addConsequent(parentElement, projectId, variableVal, termVal) {
|
||||
$(rowElement).append("<a href='#' class='btn btn-outline-dark m-2' onclick='removeConsequent($(this))'>-</a>");
|
||||
}
|
||||
$(parentElement).append(rowElement);
|
||||
$(".selectpicker").selectpicker("refresh");
|
||||
}
|
||||
|
||||
function addAntecedentFromRule(parentElement, projectId, ruleContent) {
|
||||
let antecedentComponents = getAntecedentComponents(getAntecedent(ruleContent));
|
||||
async function addAntecedentFromRule(parentElement, projectId, ruleContent) {
|
||||
let antecedentComponents = getRuleComponents(getAntecedent(ruleContent));
|
||||
for (let i = 0; i < antecedentComponents.length; i++) {
|
||||
let a = antecedentComponents[i];
|
||||
addAntecedent(parentElement, projectId, getVariable(a), getVariableValue(a));
|
||||
await addAntecedent(parentElement, projectId, getVariable(a), getVariableValue(a));
|
||||
}
|
||||
}
|
||||
|
||||
function addConsequentFromRule(parentElement, projectId, ruleContent) {
|
||||
let consequentComponents = getConsequentComponents(getConsequent(ruleContent));
|
||||
async function addConsequentFromRule(parentElement, projectId, ruleContent) {
|
||||
let consequentComponents = getRuleComponents(getConsequent(ruleContent));
|
||||
for (let i = 0; i < consequentComponents.length; i++) {
|
||||
let c = consequentComponents[i];
|
||||
addConsequent(parentElement, projectId, getVariable(c), getVariableValue(c));
|
||||
await addConsequent(parentElement, projectId, getVariable(c), getVariableValue(c));
|
||||
}
|
||||
}
|
||||
|
||||
async function initSelects() {
|
||||
let ruleContentEl = $('#ruleContent');
|
||||
let projectIdEl = $('#projectId');
|
||||
if ($(ruleContentEl).val()) {
|
||||
await addAntecedentFromRule($('#rulesAntecedent'), $(projectIdEl).val(), $(ruleContentEl).val());
|
||||
await addConsequentFromRule($('#rulesConsequent'), $(projectIdEl).val(), $(ruleContentEl).val());
|
||||
} else {
|
||||
await addAntecedent($('#rulesAntecedent'), $(projectIdEl).val());
|
||||
await addConsequent($('#rulesConsequent'), $(projectIdEl).val());
|
||||
}
|
||||
$(".selectpicker").selectpicker("refresh");
|
||||
}
|
@ -11,7 +11,8 @@
|
||||
<script type="text/javascript" src="/webjars/bootstrap-select/1.13.8/js/bootstrap-select.min.js"></script>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/4.6.0/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap-select/1.13.8/css/bootstrap-select.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css"/>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -35,7 +35,13 @@
|
||||
<div class="row" th:each="v, iter : ${variables}">
|
||||
<div class="col col-md-12">
|
||||
<a th:href="@{'/variable/edit/' + ${projectId}+'/'+${v.id}}">
|
||||
<span class="badge badge-light" th:text="${iter.index+1} + '. ' + ${v.name}"></span>
|
||||
<h3>
|
||||
<span class="badge badge-light">
|
||||
<span th:text="${iter.index+1} + '. ' + ${v.name}"></span>
|
||||
<i th:if="${v.input}" class="bi bi-box-arrow-in-right"></i>
|
||||
<i th:if="! ${v.input}" class="bi bi-box-arrow-right"></i>
|
||||
</span>
|
||||
</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -48,7 +54,7 @@
|
||||
<div class="row" th:each="r, iter : ${rules}">
|
||||
<div class="col col-md-12">
|
||||
<a th:href="@{'/rule/edit/' + ${projectId}+'/'+${r.id}}">
|
||||
<div class="rule row" th:text="${r.content}"></div>
|
||||
<div class="rule row d-none" th:text="${r.content}"></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,8 +67,8 @@
|
||||
<script type="text/javascript">
|
||||
function addRule(index, el, rule) {
|
||||
let ruleHtml = "<div class='col col-md-12'><span class='badge badge-light'>" + (index + 1) + ". Если</span></div>"
|
||||
let antecedentComponents = getAntecedentComponents(getAntecedent(rule));
|
||||
let consequentComponents = getConsequentComponents(getConsequent(rule));
|
||||
let antecedentComponents = getRuleComponents(getAntecedent(rule));
|
||||
let consequentComponents = getRuleComponents(getConsequent(rule));
|
||||
for (let i = 0; i < antecedentComponents.length; i++) {
|
||||
let a = antecedentComponents[i];
|
||||
if (i > 0) {
|
||||
@ -70,9 +76,9 @@
|
||||
} else {
|
||||
ruleHtml += "<div class='col col-md-1'></div>";
|
||||
}
|
||||
ruleHtml += "<div class='col col-md-4'><span class='badge badge-primary'>"+getVariable(a)+"</span></div>";
|
||||
ruleHtml += "<div class='col col-md-4'><span class='badge badge-primary'>" + getVariable(a) + "</span></div>";
|
||||
ruleHtml += "<div class='col col-md-3'><span class='badge badge-light'>есть</span></div>";
|
||||
ruleHtml += "<div class='col col-md-4'><span class='badge badge-success'>"+getVariableValue(a)+"</span></div>";
|
||||
ruleHtml += "<div class='col col-md-4'><span class='badge badge-success'>" + getVariableValue(a) + "</span></div>";
|
||||
}
|
||||
ruleHtml += "<div class='col col-md-12'><span class='badge badge-light'>То</span></div>"
|
||||
for (let i = 0; i < consequentComponents.length; i++) {
|
||||
@ -87,11 +93,12 @@
|
||||
ruleHtml += "<div class='col col-md-4'><span class='badge badge-success'>" + getVariableValue(c) + "</span></div>";
|
||||
}
|
||||
$(el).html(ruleHtml);
|
||||
$(el).removeClass('d-none');
|
||||
}
|
||||
$('.rule').each(function(index) {
|
||||
|
||||
$('.rule').each(function (index) {
|
||||
addRule(index, $(this), $(this).text());
|
||||
});
|
||||
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
@ -7,16 +7,19 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<div class="container" layout:fragment="content">
|
||||
<a href="/project/edit/0" class="btn btn-outline-dark">
|
||||
<i class="fa fa-plus-square" aria-hidden="true">Добавить проект</i>
|
||||
</a>
|
||||
|
||||
<ul>
|
||||
<li th:each="p : ${projects}">
|
||||
<a th:href="@{'/project/edit/' + ${p.id}}">
|
||||
<span th:text="${p.name} + ' от ' + ${#dates.format(p.createDate, 'dd.MM.yyyy HH:mm')}"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-group">
|
||||
<a href="/project/edit/0" class="btn btn-outline-dark">
|
||||
<i class="bi bi-plus-square" aria-hidden="true"></i> Добавить проект
|
||||
</a>
|
||||
</div>
|
||||
<div th:each="p : ${projects}">
|
||||
<a th:href="@{'/project/edit/' + ${p.id}}">
|
||||
<h3>
|
||||
<span class="badge badge-light"
|
||||
th:text="${p.name} + ' от ' + ${#dates.format(p.createDate, 'dd.MM.yyyy HH:mm')}">
|
||||
</span>
|
||||
</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
||||
|
@ -1,30 +0,0 @@
|
||||
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
|
||||
<head>
|
||||
<title>Список правил</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<div class="container" layout:fragment="content">
|
||||
<h3> Список правил</h3>
|
||||
<div class="rowд">
|
||||
<div class="col col-md-12">
|
||||
<span class="badge badge-light">1. Если</span>
|
||||
</div>
|
||||
<div class="col col-md-3">
|
||||
<span class="badge badge-primary">Переменная</span>
|
||||
</div>
|
||||
<div class="col col-md-3">
|
||||
<span class="badge badge-light">есть</span>
|
||||
</div>
|
||||
<div class="col col-md-3">
|
||||
<span class="badge badge-success">значение</span>
|
||||
</div>
|
||||
<div class="col col-md-3">
|
||||
<span class="badge badge-danger">И / ИЛИ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</html>
|
@ -50,15 +50,9 @@
|
||||
</div>
|
||||
<script type="text/javascript" src="/js/fuzzyRule.js"></script>
|
||||
<script type="text/javascript">
|
||||
let ruleContentEl = $('#ruleContent');
|
||||
let projectIdEl = $('#projectId');
|
||||
if ($(ruleContentEl).val()) {
|
||||
addAntecedentFromRule($('#rulesAntecedent'), $(projectIdEl).val(), $(ruleContentEl).val());
|
||||
addConsequentFromRule($('#rulesConsequent'), $(projectIdEl).val(), $(ruleContentEl).val());
|
||||
} else {
|
||||
addAntecedent($('#rulesAntecedent'), $(projectIdEl).val());
|
||||
addConsequent($('#rulesConsequent'), $(projectIdEl).val());
|
||||
}
|
||||
(async () => {
|
||||
await initSelects();
|
||||
})();
|
||||
</script>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -39,8 +39,10 @@
|
||||
<div class="row" th:each="t, iter : ${fuzzyTerms}">
|
||||
<div class="col col-md-12">
|
||||
<a th:href="@{'/fuzzyTerm/edit/' + ${projectId} + '/' + ${variableId}+'/'+${t.id}}">
|
||||
<span class="badge badge-light"
|
||||
th:text="${iter.index+1} + '. ' + ${t.description}"></span>
|
||||
<h3>
|
||||
<span class="badge badge-light"
|
||||
th:text="${iter.index+1} + '. ' + ${t.description}"></span>
|
||||
</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user