Compare commits
1 Commits
3-parse-ru
...
master
Author | SHA1 | Date | |
---|---|---|---|
68da6681f5 |
78
client example.py
Normal file
78
client example.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
url = 'http://plans.athene.tech/rest/get-inference'
|
||||||
|
headers = {
|
||||||
|
'Content-type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
|
||||||
|
age = 65
|
||||||
|
income = 20000
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"inputVariables": [
|
||||||
|
{
|
||||||
|
"name": "возраст",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "молодой",
|
||||||
|
"value": 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "средний",
|
||||||
|
"value": 45
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "старый",
|
||||||
|
"value": 65
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "доход",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "низкий",
|
||||||
|
"value": 50000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "средний",
|
||||||
|
"value": 100000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "высокий",
|
||||||
|
"value": 500000
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"outputVariable":
|
||||||
|
{
|
||||||
|
"name": "кредит",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "небольшой",
|
||||||
|
"value": 50000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "средний",
|
||||||
|
"value": 100000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fuzzyTerm": "большой",
|
||||||
|
"value": 200000
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"rules": [
|
||||||
|
"if доход is высокий and возраст is молодой then кредит is большой",
|
||||||
|
"if доход is высокий and возраст is средний then кредит is средний",
|
||||||
|
"if доход is высокий and возраст is старый then кредит is средний",
|
||||||
|
"if доход is низкий and возраст is молодой then кредит is небольшой"
|
||||||
|
],
|
||||||
|
"values":
|
||||||
|
{
|
||||||
|
"доход": income,
|
||||||
|
"возраст": age
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(url, data=json.dumps(data), headers=headers)
|
||||||
|
print(response.json())
|
@ -1,16 +0,0 @@
|
|||||||
package ru.ulstu.fc.config;
|
|
||||||
|
|
||||||
import com.fuzzylite.Engine;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class FuzzyEngine {
|
|
||||||
@Bean
|
|
||||||
public Engine getFuzzyEngine() {
|
|
||||||
Engine engine = new Engine();
|
|
||||||
engine.setName("Fuzzy rules");
|
|
||||||
engine.setDescription("");
|
|
||||||
return engine;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
package ru.ulstu.fc.core;
|
|
||||||
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.MappedSuperclass;
|
|
||||||
import javax.persistence.Version;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@MappedSuperclass
|
|
||||||
public abstract class BaseEntity implements Serializable, Comparable<BaseEntity> {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.TABLE)
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private Integer version;
|
|
||||||
|
|
||||||
public BaseEntity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseEntity(Integer id, Integer version) {
|
|
||||||
this.id = id;
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!getClass().isAssignableFrom(obj.getClass())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BaseEntity other = (BaseEntity) obj;
|
|
||||||
if (id == null) {
|
|
||||||
if (other.getId() != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!id.equals(other.getId())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + (id == null ? 0 : id.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getClass().getSimpleName() + "{" +
|
|
||||||
"id=" + id +
|
|
||||||
", version=" + version +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(BaseEntity o) {
|
|
||||||
return id != null ? id.compareTo(o.getId()) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
this.id = null;
|
|
||||||
this.version = null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import ru.ulstu.fc.rule.model.AddRuleForm;
|
|
||||||
import ru.ulstu.fc.rule.model.AddTermForm;
|
|
||||||
import ru.ulstu.fc.rule.model.AddVariableForm;
|
|
||||||
import ru.ulstu.fc.rule.service.RuleParseService;
|
|
||||||
import ru.ulstu.fc.rule.service.RuleService;
|
|
||||||
import ru.ulstu.fc.rule.service.TermsService;
|
|
||||||
import ru.ulstu.fc.rule.service.VariableService;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class RuleController {
|
|
||||||
private final RuleParseService ruleParseService;
|
|
||||||
private final RuleService ruleService;
|
|
||||||
private final TermsService termService;
|
|
||||||
private final VariableService variableService;
|
|
||||||
|
|
||||||
public RuleController(RuleParseService ruleParseService,
|
|
||||||
RuleService ruleService,
|
|
||||||
TermsService termService,
|
|
||||||
VariableService variableService) {
|
|
||||||
this.ruleParseService = ruleParseService;
|
|
||||||
this.ruleService = ruleService;
|
|
||||||
this.termService = termService;
|
|
||||||
this.variableService = variableService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("listRules")
|
|
||||||
public String listRules(Model model) {
|
|
||||||
model.addAttribute("rules", ruleService.getRules());
|
|
||||||
return "listRules";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("listTerms")
|
|
||||||
public String listTerms(Model model) {
|
|
||||||
model.addAttribute("terms", termService.getTerms());
|
|
||||||
return "listTerms";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("listVars")
|
|
||||||
public String listVariables(Model model) {
|
|
||||||
model.addAttribute("vars", variableService.getVars());
|
|
||||||
return "listVars";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("addRule")
|
|
||||||
public String addRule(Model model) {
|
|
||||||
model.addAttribute("addRuleForm", new AddRuleForm());
|
|
||||||
return "addRule";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("addRule")
|
|
||||||
public String parse(@ModelAttribute AddRuleForm addRuleForm, Model model) {
|
|
||||||
try {
|
|
||||||
System.out.println(ruleParseService.parseRules(List.of(addRuleForm.getRule())));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
return "addRule";
|
|
||||||
}
|
|
||||||
model.addAttribute("addRuleForm", addRuleForm);
|
|
||||||
return "listRules";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("addVariable")
|
|
||||||
public String addVariable(Model model, @RequestParam(required = false) Integer id) {
|
|
||||||
model.addAttribute("addVariableForm", variableService.getAddVariableFormOrDefault(id));
|
|
||||||
return "addVariable";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("addVariable")
|
|
||||||
public String addVariable(@ModelAttribute AddVariableForm addVariableForm, Model model) {
|
|
||||||
model.addAttribute("addVariableForm", addVariableForm);
|
|
||||||
variableService.save(addVariableForm);
|
|
||||||
model.addAttribute("vars", variableService.getVars());
|
|
||||||
return "listVars";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("addTerm")
|
|
||||||
public String addTerm(Model model) {
|
|
||||||
model.addAttribute("addTermForm", new AddTermForm());
|
|
||||||
return "addTerm";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("addTerm")
|
|
||||||
public String addTerm(@ModelAttribute AddTermForm addTermForm, Model model) {
|
|
||||||
model.addAttribute("addTermForm", addTermForm);
|
|
||||||
return "listTerms";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
|
||||||
|
|
||||||
public class AddRuleForm {
|
|
||||||
private String rule;
|
|
||||||
|
|
||||||
public String getRule() {
|
|
||||||
return rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRule(String rule) {
|
|
||||||
this.rule = rule;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
|
||||||
|
|
||||||
public class AddTermForm {
|
|
||||||
private String variable;
|
|
||||||
private String term;
|
|
||||||
private String min;
|
|
||||||
private String max;
|
|
||||||
|
|
||||||
public String getVariable() {
|
|
||||||
return variable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVariable(String variable) {
|
|
||||||
this.variable = variable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTerm() {
|
|
||||||
return term;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTerm(String term) {
|
|
||||||
this.term = term;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMin() {
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMin(String min) {
|
|
||||||
this.min = min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMax() {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMax(String max) {
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
|
||||||
|
|
||||||
public class AddVariableForm {
|
|
||||||
private Integer id;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public AddVariableForm(Variable variable) {
|
|
||||||
this.id = variable.getId();
|
|
||||||
this.name = variable.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AddVariableForm() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
|
||||||
|
|
||||||
import ru.ulstu.fc.core.BaseEntity;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Rule extends BaseEntity {
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
|
||||||
|
|
||||||
import ru.ulstu.fc.core.BaseEntity;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Term extends BaseEntity {
|
|
||||||
private String name;
|
|
||||||
private double min;
|
|
||||||
private double max;
|
|
||||||
|
|
||||||
public Term() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Term(String name, double min, double max) {
|
|
||||||
this.name = name;
|
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getMin() {
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMin(double min) {
|
|
||||||
this.min = min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getMax() {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMax(double max) {
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +1,24 @@
|
|||||||
package ru.ulstu.fc.rule.model;
|
package ru.ulstu.fc.rule.model;
|
||||||
|
|
||||||
import ru.ulstu.fc.core.BaseEntity;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Entity
|
public class Variable {
|
||||||
public class Variable extends BaseEntity {
|
|
||||||
private String name;
|
private String name;
|
||||||
@OneToMany
|
private List<VariableValue> values;
|
||||||
private List<Term> terms;
|
|
||||||
|
|
||||||
public Variable() {
|
public Variable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Variable(String name) {
|
public Variable(String name, List<VariableValue> values) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
this.values = values;
|
||||||
|
|
||||||
public Variable(String name, List<Term> terms) {
|
|
||||||
this.name = name;
|
|
||||||
this.terms = terms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public List<VariableValue> getValues() {
|
||||||
this.name = name;
|
return values;
|
||||||
}
|
|
||||||
|
|
||||||
public List<Term> getTerms() {
|
|
||||||
return terms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTerms(List<Term> terms) {
|
|
||||||
this.terms = terms;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.repository;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import ru.ulstu.fc.rule.model.Rule;
|
|
||||||
|
|
||||||
public interface RuleRepository extends JpaRepository<Rule, Integer> {
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.repository;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import ru.ulstu.fc.rule.model.Term;
|
|
||||||
|
|
||||||
public interface TermRepository extends JpaRepository<Term, Integer> {
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.repository;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import ru.ulstu.fc.rule.model.Variable;
|
|
||||||
|
|
||||||
public interface VariableRepository extends JpaRepository<Variable, Integer> {
|
|
||||||
}
|
|
@ -15,8 +15,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.ulstu.fc.rule.model.OutputValue;
|
import ru.ulstu.fc.rule.model.OutputValue;
|
||||||
import ru.ulstu.fc.rule.model.Term;
|
|
||||||
import ru.ulstu.fc.rule.model.Variable;
|
import ru.ulstu.fc.rule.model.Variable;
|
||||||
|
import ru.ulstu.fc.rule.model.VariableValue;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -30,17 +30,14 @@ public class FuzzyInferenceService {
|
|||||||
+ OUTPUT_VARIABLE_NAME
|
+ OUTPUT_VARIABLE_NAME
|
||||||
+ " is %s";
|
+ " is %s";
|
||||||
private final static String NO_RESULT = "Нет результата";
|
private final static String NO_RESULT = "Нет результата";
|
||||||
private final Engine fuzzyEngine;
|
|
||||||
|
|
||||||
public FuzzyInferenceService(Engine fuzzyEngine) {
|
|
||||||
this.fuzzyEngine = fuzzyEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getDemoRules() {
|
private List<String> getDemoRules() {
|
||||||
return List.of(
|
return List.of(
|
||||||
String.format(RULE_TEMPLATE, "возраст", "молодой", "доход", "высокий", "средний"),
|
String.format(RULE_TEMPLATE, "возраст", "молодой", "доход", "высокий", "большой"),
|
||||||
String.format(RULE_TEMPLATE, "возраст", "средний", "доход", "высокий", "большой"),
|
String.format(RULE_TEMPLATE, "возраст", "средний", "доход", "высокий", "средний"),
|
||||||
String.format(RULE_TEMPLATE, "возраст", "старый", "доход", "средний", "средний")
|
String.format(RULE_TEMPLATE, "возраст", "старый", "доход", "высокий", "средний"),
|
||||||
|
String.format(RULE_TEMPLATE, "возраст", "старый", "доход", "небольшой", "небольшой"),
|
||||||
|
String.format(RULE_TEMPLATE, "возраст", "молодой", "доход", "небольшой", "небольшой")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,13 +45,16 @@ public class FuzzyInferenceService {
|
|||||||
final InputVariable input = new InputVariable();
|
final InputVariable input = new InputVariable();
|
||||||
input.setName(variable.getName());
|
input.setName(variable.getName());
|
||||||
input.setDescription("");
|
input.setDescription("");
|
||||||
input.setRange(0, variable.getTerms().get(variable.getTerms().size() - 1).getMax());
|
input.setRange(0, variable.getValues().get(variable.getValues().size() - 1).getValue());
|
||||||
input.setEnabled(true);
|
input.setEnabled(true);
|
||||||
input.setLockValueInRange(false);
|
input.setLockValueInRange(false);
|
||||||
for (int i = 0; i < variable.getTerms().size(); i++) {
|
double prev = 0;
|
||||||
Triangle term = new Triangle(variable.getTerms().get(i).getName(),
|
for (int i = 0; i < variable.getValues().size(); i++) {
|
||||||
variable.getTerms().get(i).getMin(),
|
Triangle term = new Triangle(variable.getValues().get(i).getFuzzyTerm(),
|
||||||
variable.getTerms().get(i).getMax());
|
prev,
|
||||||
|
variable.getValues().get(i).getValue(),
|
||||||
|
variable.getValues().get(i).getValue() + variable.getValues().get(i).getValue() - prev);
|
||||||
|
prev = term.getVertexB();
|
||||||
input.addTerm(term);
|
input.addTerm(term);
|
||||||
}
|
}
|
||||||
return input;
|
return input;
|
||||||
@ -64,16 +64,20 @@ public class FuzzyInferenceService {
|
|||||||
final OutputVariable output = new OutputVariable();
|
final OutputVariable output = new OutputVariable();
|
||||||
output.setName(variable.getName());
|
output.setName(variable.getName());
|
||||||
output.setDescription("");
|
output.setDescription("");
|
||||||
output.setRange(0, variable.getTerms().get(variable.getTerms().size() - 1).getMax());
|
output.setRange(0, variable.getValues().get(variable.getValues().size() - 1).getValue());
|
||||||
output.setEnabled(true);
|
output.setEnabled(true);
|
||||||
output.setAggregation(new Maximum());
|
output.setAggregation(new Maximum());
|
||||||
output.setDefuzzifier(new WeightedAverage());
|
output.setDefuzzifier(new WeightedAverage());
|
||||||
output.setDefaultValue(Double.NaN);
|
output.setDefaultValue(Double.NaN);
|
||||||
output.setLockValueInRange(false);
|
output.setLockValueInRange(false);
|
||||||
for (int i = 0; i < variable.getTerms().size(); i++) {
|
double prev = 0;
|
||||||
Triangle term = new Triangle(variable.getTerms().get(i).getName(),
|
for (int i = 0; i < variable.getValues().size(); i++) {
|
||||||
variable.getTerms().get(i).getMin(),
|
Triangle term = new Triangle(
|
||||||
variable.getTerms().get(i).getMax());
|
variable.getValues().get(i).getFuzzyTerm(),
|
||||||
|
prev,
|
||||||
|
variable.getValues().get(i).getValue(),
|
||||||
|
variable.getValues().get(i).getValue() + variable.getValues().get(i).getValue() - prev);
|
||||||
|
prev = term.getVertexB();
|
||||||
output.addTerm(term);
|
output.addTerm(term);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@ -97,6 +101,13 @@ public class FuzzyInferenceService {
|
|||||||
return mamdani;
|
return mamdani;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Engine getFuzzyEngine() {
|
||||||
|
Engine engine = new Engine();
|
||||||
|
engine.setName("Fuzzy rules");
|
||||||
|
engine.setDescription("");
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
private List<OutputValue> getConsequent(Engine engine, Map<String, Double> variableValues) {
|
private List<OutputValue> getConsequent(Engine engine, Map<String, Double> variableValues) {
|
||||||
OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME);
|
OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME);
|
||||||
for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) {
|
for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) {
|
||||||
@ -119,21 +130,20 @@ public class FuzzyInferenceService {
|
|||||||
public List<OutputValue> getFuzzyInference(Map<String, Double> vals) {
|
public List<OutputValue> getFuzzyInference(Map<String, Double> vals) {
|
||||||
return getFuzzyInference(getDemoRules(), vals,
|
return getFuzzyInference(getDemoRules(), vals,
|
||||||
List.of(new Variable("возраст", List.of(
|
List.of(new Variable("возраст", List.of(
|
||||||
new Term("молодой", 0.0, 40.0),
|
new VariableValue("молодой", 35.0),
|
||||||
new Term("средний", 20.0, 60.0),
|
new VariableValue("средний", 60.0),
|
||||||
new Term("старый", 50.0, 100.0))
|
new VariableValue("старый", 100.0))
|
||||||
),
|
),
|
||||||
new Variable("доход", List.of(
|
new Variable("доход", List.of(
|
||||||
new Term("небольшой", 0.0, 35000.0),
|
new VariableValue("небольшой", 35000.0),
|
||||||
new Term("средний", 20000.0, 100000.0),
|
new VariableValue("средний", 100000.0),
|
||||||
new Term("высокий", 80000.0, 500000.0))
|
new VariableValue("высокий", 500000.0))
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new Variable("кредит", List.of(
|
new Variable("кредит", List.of(
|
||||||
new Term("не_выдавать_кредит", 0.0, 1.0),
|
new VariableValue("небольшой", 20000.0),
|
||||||
new Term("небольшой", 1.0, 50000.0),
|
new VariableValue("средний", 100000.0),
|
||||||
new Term("средний", 25000.0, 100000.0),
|
new VariableValue("большой", 1000000.0)))
|
||||||
new Term("большой", 75000.0, 1000000.0)))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +151,8 @@ public class FuzzyInferenceService {
|
|||||||
Map<String, Double> values,
|
Map<String, Double> values,
|
||||||
List<Variable> inputVariables,
|
List<Variable> inputVariables,
|
||||||
Variable outputVariable) {
|
Variable outputVariable) {
|
||||||
fuzzyEngine.getRuleBlocks().clear();
|
Engine engine = getFuzzyEngine();
|
||||||
fuzzyEngine.addRuleBlock(getRuleBlock(fuzzyEngine, rules, inputVariables, outputVariable));
|
engine.addRuleBlock(getRuleBlock(engine, rules, inputVariables, outputVariable));
|
||||||
return getConsequent(fuzzyEngine, values);
|
return getConsequent(engine, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.service;
|
|
||||||
|
|
||||||
import com.fuzzylite.Engine;
|
|
||||||
import com.fuzzylite.rule.Rule;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class RuleParseService {
|
|
||||||
private final static String RU_IF_STATEMENT = "если";
|
|
||||||
private final static String ENG_IF_STATEMENT = "if";
|
|
||||||
private final static String RU_THEN_STATEMENT = "то";
|
|
||||||
private final static String ENG_THEN_STATEMENT = "then";
|
|
||||||
private final static String RU_AND_STATEMENT = "и";
|
|
||||||
private final static String ENG_AND_STATEMENT = "and";
|
|
||||||
private final static String RU_IS_STATEMENT = "является";
|
|
||||||
private final static String RU_EQ_STATEMENT = "равно";
|
|
||||||
private final static String ENG_IS_STATEMENT = "is";
|
|
||||||
|
|
||||||
private final Engine fuzzyEngine;
|
|
||||||
|
|
||||||
public RuleParseService(Engine fuzzyEngine) {
|
|
||||||
this.fuzzyEngine = fuzzyEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Rule> parseRules(List<String> stringRules) {
|
|
||||||
return stringRules
|
|
||||||
.stream()
|
|
||||||
.map(s -> Rule.parse(replaceEnglishKeywords(s), fuzzyEngine))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String replaceEnglishKeywords(String stringRule) {
|
|
||||||
stringRule = stringRule.toLowerCase();
|
|
||||||
return stringRule
|
|
||||||
.replaceFirst(RU_IF_STATEMENT, ENG_IF_STATEMENT)
|
|
||||||
.replaceFirst(RU_AND_STATEMENT, ENG_AND_STATEMENT)
|
|
||||||
.replaceFirst(RU_IS_STATEMENT, ENG_IS_STATEMENT)
|
|
||||||
.replaceFirst(RU_EQ_STATEMENT, ENG_IS_STATEMENT)
|
|
||||||
.replaceAll(RU_THEN_STATEMENT, ENG_THEN_STATEMENT);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.service;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.fc.rule.model.Rule;
|
|
||||||
import ru.ulstu.fc.rule.repository.RuleRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class RuleService {
|
|
||||||
private final RuleRepository ruleRepository;
|
|
||||||
|
|
||||||
public RuleService(RuleRepository ruleRepository) {
|
|
||||||
this.ruleRepository = ruleRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Rule> getRules() {
|
|
||||||
return ruleRepository.findAll();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.service;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.fc.rule.model.Term;
|
|
||||||
import ru.ulstu.fc.rule.repository.TermRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class TermService {
|
|
||||||
private final TermRepository termRepository;
|
|
||||||
|
|
||||||
public TermService(TermRepository termRepository) {
|
|
||||||
this.termRepository = termRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Term> getTerms() {
|
|
||||||
return termRepository.findAll();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.service;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.fc.rule.model.Term;
|
|
||||||
import ru.ulstu.fc.rule.repository.TermRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class TermsService {
|
|
||||||
private final TermRepository termRepository;
|
|
||||||
|
|
||||||
public TermsService(TermRepository termRepository) {
|
|
||||||
this.termRepository = termRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Term> getTerms() {
|
|
||||||
return termRepository.findAll();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package ru.ulstu.fc.rule.service;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.fc.rule.model.AddVariableForm;
|
|
||||||
import ru.ulstu.fc.rule.model.Variable;
|
|
||||||
import ru.ulstu.fc.rule.repository.VariableRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class VariableService {
|
|
||||||
private final VariableRepository variableRepository;
|
|
||||||
|
|
||||||
public VariableService(VariableRepository variableRepository) {
|
|
||||||
this.variableRepository = variableRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<Variable> getVars() {
|
|
||||||
return variableRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(AddVariableForm addVariableForm) {
|
|
||||||
if (addVariableForm.getId() == null) {
|
|
||||||
variableRepository.save(new Variable(addVariableForm.getName()));
|
|
||||||
} else {
|
|
||||||
Variable dbVar = variableRepository.findById(addVariableForm.getId()).orElseThrow(() -> new RuntimeException("Variable not found by id"));
|
|
||||||
dbVar.setName(addVariableForm.getName());
|
|
||||||
variableRepository.save(dbVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AddVariableForm getAddVariableFormOrDefault(Integer id) {
|
|
||||||
return id == null
|
|
||||||
? new AddVariableForm()
|
|
||||||
: new AddVariableForm(variableRepository.findById(id).orElseThrow(() -> new RuntimeException("Var not foubd by id")));
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,6 @@ extractor.custom-projects-dir=
|
|||||||
server.error.include-stacktrace=always
|
server.error.include-stacktrace=always
|
||||||
server.error.include-exception=true
|
server.error.include-exception=true
|
||||||
server.error.include-message=always
|
server.error.include-message=always
|
||||||
# go to http://localhost:8080/h2-console
|
|
||||||
spring.datasource.url=jdbc:h2:file:./data/db
|
spring.datasource.url=jdbc:h2:file:./data/db
|
||||||
spring.datasource.driverClassName=org.h2.Driver
|
spring.datasource.driverClassName=org.h2.Driver
|
||||||
spring.datasource.username=sa
|
spring.datasource.username=sa
|
||||||
|
@ -3,20 +3,79 @@
|
|||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
layout:decorate="~{default}">
|
layout:decorate="~{default}">
|
||||||
<head>
|
<head>
|
||||||
<title>Добавить правило</title>
|
<title>Простая обработка формы на Spring MVC</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
</head>
|
</head>
|
||||||
<div class="container" layout:fragment="content">
|
<div class="container" layout:fragment="content">
|
||||||
<form action="/addRule" th:object="${addRuleForm}" method="post">
|
<form action="/listRule" th:action="${@route.ADD_RULE}" th:object="${addRuleForm}" method="post">
|
||||||
|
<input type="hidden" th:field="*{ruleId}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-2 col-sm-12">
|
<div class="col-md-2 col-sm-12">
|
||||||
<input class="form-control" type="text" th:field="*{rule}">
|
Если
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<select id="select-antecedent" class="selectpicker m-2" data-live-search="true"
|
||||||
|
th:field="*{firstAntecedentId}"
|
||||||
|
data-width="90%">
|
||||||
|
<option th:each="antecedent : ${antecedents}"
|
||||||
|
th:value="${antecedent}"
|
||||||
|
th:utext="${antecedent.description}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
имеет тенденцию
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
<select id="select-measures" class="selectpicker m-2" data-live-search="true"
|
||||||
|
th:field="*{firstAntecedentValueId}"
|
||||||
|
data-width="100%">
|
||||||
|
<option th:each="antecedentValue : ${antecedentValues}"
|
||||||
|
th:value="${antecedentValue.id}"
|
||||||
|
th:utext="${antecedentValue.antecedentValue}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
и
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<select id="select-second-antecedent" class="selectpicker m-2" data-live-search="true"
|
||||||
|
th:field="*{secondAntecedentId}"
|
||||||
|
data-width="90%">
|
||||||
|
<option th:each="antecedent : ${antecedents}"
|
||||||
|
th:value="${antecedent}"
|
||||||
|
th:utext="${antecedent.description}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
имеет тенденцию
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
<select id="select-second-measures" class="selectpicker m-2" data-live-search="true"
|
||||||
|
th:field="*{secondAntecedentValueId}"
|
||||||
|
data-width="100%">
|
||||||
|
<option th:each="antecedentValue : ${antecedentValues}"
|
||||||
|
th:value="${antecedentValue.id}"
|
||||||
|
th:utext="${antecedentValue.antecedentValue}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-12">
|
||||||
|
то:
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<input type="text" class="form-control m-1" th:field="*{consequent}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="col-md-4 col-sm-12"></div>
|
||||||
<div class="col-md-4 col-sm-12">
|
<div class="col-md-4 col-sm-12">
|
||||||
<input type="submit" class="btn btn-outline-success m-2" value="Создать правило"/>
|
<input type="submit" class="btn btn-outline-success m-2" th:if="*{ruleId == null}"
|
||||||
|
value="Создать правило"/>
|
||||||
|
<input type="submit" class="btn btn-outline-success m-2" th:if="*{ruleId != null}"
|
||||||
|
value="Сохранить правило"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,41 +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" xmlns:th="http://www.w3.org/1999/xhtml"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
<title>Добавить терм</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
||||||
</head>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<form action="/addTerm" th:object="${addTermForm}" method="post">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2 col-sm-12">
|
|
||||||
<select id="select-variable" class="selectpicker m-2" data-live-search="true"
|
|
||||||
th:field="*{variable}"
|
|
||||||
data-width="90%">
|
|
||||||
<option th:each="var : ${variables}"
|
|
||||||
th:value="${var}"
|
|
||||||
th:utext="${var}">
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-sm-12">
|
|
||||||
<input class="form-control" type="text" th:field="*{term}">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-sm-12">
|
|
||||||
<input class="form-control" type="text" th:field="*{min}">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-sm-12">
|
|
||||||
<input class="form-control" type="text" th:field="*{max}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 col-sm-12">
|
|
||||||
<input type="submit" class="btn btn-outline-success m-2" value="Создать term"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</html>
|
|
@ -1,25 +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" xmlns:th="http://www.w3.org/1999/xhtml"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
<title>Добавить переменную</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
||||||
</head>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<form action="/addVariable" th:object="${addVariableForm}" method="post">
|
|
||||||
<input type="hidden" th:field="*{id}">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2 col-sm-12">
|
|
||||||
<input class="form-control" type="text" th:field="*{name}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 col-sm-12">
|
|
||||||
<input type="submit" class="btn btn-outline-success m-2" value="Создать переменную"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</html>
|
|
@ -21,18 +21,12 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/listVars">Переменные</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/listTerms">Термы</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/listRules">Правила</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/swagger-ui/index.html">API</a>
|
<a class="nav-link" href="/swagger-ui/index.html">API</a>
|
||||||
</li>
|
</li>
|
||||||
|
<!-- <li class="nav-item">-->
|
||||||
|
<!-- <a class="nav-link" href="/listRules">Правила</a>-->
|
||||||
|
<!-- </li>-->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
layout:decorate="~{default}">
|
layout:decorate="~{default}">
|
||||||
<head>
|
<head>
|
||||||
<title>Список правил</title>
|
<title>Простая обработка формы на Spring MVC</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
</head>
|
</head>
|
||||||
<div class="container" layout:fragment="content">
|
<div class="container" layout:fragment="content">
|
||||||
|
@ -1,35 +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" xmlns:th="http://www.w3.org/1999/xhtml"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
<title>Список термов</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
||||||
</head>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th scope="col" colspan="10">Термы</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr th:each="dbTerm: ${terms}">
|
|
||||||
<td><span class="badge badge-success" th:text="${dbTerm.name}"></span></td>
|
|
||||||
<td>
|
|
||||||
<a role="button" class="btn btn-info" th:href="@{'addTerm?termId=' + ${dbTerm.id}}">
|
|
||||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a role="button" class="btn btn-danger" th:href="@{'deleteTerm?id=' + ${dbTerm.id}}"
|
|
||||||
onclick="return confirm('Удалить терм?')">
|
|
||||||
<i class="fa fa-times" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<a href="/addTerm" class="btn btn-outline-success">Добавить терм</a>
|
|
||||||
</div>
|
|
||||||
</html>
|
|
@ -1,35 +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" xmlns:th="http://www.w3.org/1999/xhtml"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
<title>Список переменных</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
||||||
</head>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th scope="col" colspan="10">Переменные</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr th:each="dbVar: ${vars}">
|
|
||||||
<td><span class="badge badge-success" th:text="${dbVar.name}"></span></td>
|
|
||||||
<td>
|
|
||||||
<a role="button" class="btn btn-info" th:href="@{'addVariable?id=' + ${dbVar.id}}">
|
|
||||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a role="button" class="btn btn-danger" th:href="@{'deleteVar?id=' + ${dbVar.id}}"
|
|
||||||
onclick="return confirm('Удалить переменную?')">
|
|
||||||
<i class="fa fa-times" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<a href="/addVariable" class="btn btn-outline-success">Добавить переменную</a>
|
|
||||||
</div>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user