This commit is contained in:
BronnikovAlex 2023-07-06 17:37:23 +03:00
parent b1792423c1
commit 24b69c6024
27 changed files with 1010 additions and 0 deletions

View File

@ -0,0 +1,13 @@
package callcenter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Callcenter2Application {
public static void main(String[] args) {
SpringApplication.run(Callcenter2Application.class, args);
}
}

View File

@ -0,0 +1,14 @@
package callcenter.Repository;
import callcenter.models.CallLogTypeResult;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CallLogTypeResultRepository extends JpaRepository<CallLogTypeResult,Integer> {
CallLogTypeResult findByNametyperesult(String nametyperesult);
}

View File

@ -0,0 +1,14 @@
package callcenter.Repository;
import callcenter.models.CallResults;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CallResultsRepository extends JpaRepository<CallResults,Integer> {
CallResults findByName(String callResultsName);
}

View File

@ -0,0 +1,16 @@
package callcenter.Repository;
import callcenter.models.CallTypes;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface CallTypesRepository extends JpaRepository<CallTypes,Integer> {
CallTypes findByName(String callTypeName);
}

View File

@ -0,0 +1,13 @@
package callcenter.Repository;
import callcenter.models.CallLog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CalllogRepository extends JpaRepository<CallLog,Integer> {
}

View File

@ -0,0 +1,12 @@
package callcenter.Repository;
import callcenter.models.Clients;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface ClientsRepository extends JpaRepository<Clients , Integer> {
}

View File

@ -0,0 +1,14 @@
package callcenter.Repository;
import callcenter.models.ContactPost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ContactsPostRepository extends JpaRepository<ContactPost, Integer>{
ContactPost findByPostname(String postname);
}

View File

@ -0,0 +1,12 @@
package callcenter.Repository;
import callcenter.models.Contacts;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ContactsRepository extends JpaRepository<Contacts,Integer> {
}

View File

@ -0,0 +1,10 @@
package callcenter.Repository;
import callcenter.models.Employees;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmpoyeesRepository extends JpaRepository<Employees, Integer> {
Employees findByFamily(String family);
}

View File

@ -0,0 +1,13 @@
package callcenter.Repository;
import callcenter.models.Organizations;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrganizationRepository extends JpaRepository<Organizations,Integer> {
}

View File

@ -0,0 +1,18 @@
package callcenter.Repository;
import callcenter.models.Scenario;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ScenarioRepository extends JpaRepository<Scenario, Integer> {
Scenario findByName(String scenarioName);
List<Scenario> findByNameIn(List<String> scenarioNames);
}

View File

@ -0,0 +1,15 @@
package callcenter.Repository;
import callcenter.models.Tags;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface TagsRepository extends JpaRepository<Tags,Integer> {
Tags findByNameTag(String nameTag);
}

View File

@ -0,0 +1,412 @@
package callcenter.Service;
import callcenter.Repository.*;
import callcenter.models.*;
import callcenter.models.CallLogTypeResult;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
@Service
public class ReportService {
private final CalllogRepository callLogRepository;
private final EmpoyeesRepository empoyeesRepository;
private final CallTypesRepository callTypeRepository;
private final ClientsRepository clientRepository;
private final CallResultsRepository callResultRepository;
private final ContactsRepository contactRepository;
private final TagsRepository tagRepository;
private final OrganizationRepository organizationRepository;
private final ScenarioRepository scenarioRepository;
private final CallLogTypeResultRepository callLogTypeResultRepository;
private final ContactsPostRepository contactsPostRepository;
@Autowired
public ReportService(CalllogRepository callLogRepository, EmpoyeesRepository empoyeesRepository, CallTypesRepository callTypeRepository, ClientsRepository clientRepository, CallResultsRepository callResultRepository, ContactsRepository contactRepository, TagsRepository tagRepository, OrganizationRepository organizationRepository, ScenarioRepository scenarioRepository, CallLogTypeResultRepository callLogTypeResultRepository, ContactsPostRepository contactsPostRepository) {
this.callLogRepository = callLogRepository;
this.empoyeesRepository = empoyeesRepository;
this.callTypeRepository = callTypeRepository;
this.clientRepository = clientRepository;
this.callResultRepository = callResultRepository;
this.contactRepository = contactRepository;
this.tagRepository = tagRepository;
this.organizationRepository = organizationRepository;
this.scenarioRepository = scenarioRepository;
this.callLogTypeResultRepository = callLogTypeResultRepository;
this.contactsPostRepository = contactsPostRepository;
}
public void processReport(File reportFile) {
try {
FileInputStream fis = new FileInputStream(reportFile);
// Создание экземпляр книги
XSSFWorkbook workbook = new XSSFWorkbook(fis);
// Получение первый лист в книге
XSSFSheet sheet = workbook.getSheetAt(0);
// Реализация проверки первой строки , что там действительно содержатся нужные нам записи
Row initialLine = sheet.getRow(0);
String expectedLine = "Дата\tВремя" +
"\tСотрудник\tТип вызова" +
"\tДлит-ть (мм:сс)\tКлиент, которому звонили" +
"\tТелефон, на который звонили\tСценарий" +
"\tРезультат\tТип результата\tКомментарий" +
"\tКонтакт\tТелефон контакта №1\tE-mail контакта №1" +
"\олжность\tОрганизация\tТелефон организации №1" +
"\tE-mail организации №1\tСфера деятельности\tТеги\tID записи";
String actualLine = getRowAsString(initialLine);
if (!expectedLine.equals(actualLine)) {
throw new IllegalArgumentException("Неверный формат файла");
}
// Перебор строки, начиная со второй строки (индекс 1), чтобы пропустить заголовки
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
// Извлечение данных из каждой ячейки и создайте объекты моделей
// CallLog
CallLog callLog = new CallLog();
Cell callComment = row.getCell(10);
if (callComment != null){
if (callComment.getCellType() == CellType.STRING) {
callLog.setComment(callComment.getStringCellValue());
} else {
callLog.setComment(null);
}
} else {
callLog.setComment(null);
}
callLog.setCall_date(row.getCell(0).getStringCellValue());
callLog.setCall_time(row.getCell(1).getStringCellValue());
callLog.setDuration(row.getCell(4).getStringCellValue());
Cell callId = row.getCell(20);
if (callId != null) {
if (callId.getCellType() == CellType.NUMERIC) {
callLog.setIdzapisi((int) callId.getNumericCellValue());
} else {
callLog.setIdzapisi(null);
}
} else {
callLog.setIdzapisi(null);
}
callLogRepository.save(callLog);
// CallResults
String callResultsName = "";
Cell result = row.getCell(8);
if (result != null) {
String callValueResult = result.getStringCellValue();
if(callValueResult != null) {
callResultsName = callValueResult.trim();
}
}
CallResults callResults = callResultRepository.findByName(callResultsName);
if(!callResultsName.isEmpty()){
if(callResults == null){
callResults = new CallResults();
callResults.setName(callResultsName);
}
callResultRepository.save(callResults);
}
// CallLogTypeResult
String nametyperesult = "";
Cell LogResultName = row.getCell(9);
if (LogResultName != null) {
String cellLogResut = LogResultName.getStringCellValue();
if (cellLogResut != null) {
nametyperesult = cellLogResut.trim();
}
}
CallLogTypeResult callLogTypeResult = callLogTypeResultRepository.findByNametyperesult(nametyperesult);
if (!nametyperesult.isEmpty()) {
if (callLogTypeResult == null) {
callLogTypeResult = new CallLogTypeResult();
callLogTypeResult.setNametyperesult(nametyperesult);
}
callLogTypeResultRepository.save(callLogTypeResult);
}
// CallTypes
// изменил исключаем повторяющиеся значения
String callTypeName = row.getCell(3).getStringCellValue().trim();
CallTypes callTypes = callTypeRepository.findByName(callTypeName);
if (callTypes == null) {
callTypes = new CallTypes();
callTypes.setName(callTypeName);
callTypeRepository.save(callTypes);
}
callTypeRepository.save(callTypes);
// Tags
//String tagsName = row.getCell(19).getStringCellValue();
// изменил добавил проверки
String tagsName = "";
Cell tag = row.getCell(19);
if (tag != null) {
String cellValue = tag.getStringCellValue();
if (cellValue != null) {
tagsName = cellValue.trim();
}
}
Tags tags = tagRepository.findByNameTag(tagsName);
if (!tagsName.isEmpty()) {
if (tags == null) {
tags = new Tags();
tags.setNameTag(tagsName);
}
tagRepository.save(tags);
}
// Contacts
Contacts contacts = new Contacts();
Cell callContact = row.getCell(11);
Cell callPhone = row.getCell(12);
Cell callEmail= row.getCell(13);
if (callContact != null){
if (callContact.getCellType() == CellType.STRING) {
contacts.setName(callContact.getStringCellValue());
} else {
contacts.setName(null);
}
} else {
contacts.setName(null);
}
if (callPhone != null){
if (callPhone.getCellType() == CellType.STRING) {
contacts.setPhone(callPhone.getStringCellValue());
} else {
contacts.setPhone(null);
}
} else {
contacts.setPhone(null);
}
if (callEmail != null){
if (callEmail.getCellType() == CellType.STRING) {
contacts.setEmail(callEmail.getStringCellValue());
} else {
contacts.setEmail(null);
}
} else {
contacts.setEmail(null);
}
contactRepository.save(contacts);
// Employees
String family = row.getCell(2).getStringCellValue().trim();
Employees employees = empoyeesRepository.findByFamily(family);
if (employees == null) {
employees = new Employees();
employees.setFamily(family);
empoyeesRepository.save(employees);
}
// Organizations
Organizations organizations = new Organizations();
Cell callNameOrgan = row.getCell(15);
if (callNameOrgan != null) {
if (callNameOrgan.getCellType() == CellType.STRING) {
organizations.setName(callNameOrgan.getStringCellValue());
} else if (callNameOrgan.getCellType() == CellType.NUMERIC) {
organizations.setName(String.valueOf(callNameOrgan.getNumericCellValue()));
} else {
organizations.setName(null);
}
} else {
organizations.setName(null);
}
Cell callEmailOrgan = row.getCell(17);
if (callEmailOrgan != null){
if (callEmailOrgan.getCellType() == CellType.STRING) {
organizations.setEmail(callEmailOrgan.getStringCellValue());
} else {
organizations.setEmail(null);
}
} else {
organizations.setEmail(null);
}
Cell callIndusryOrgan = row.getCell(18);
if (callIndusryOrgan != null){
if (callIndusryOrgan.getCellType() == CellType.STRING) {
organizations.setIndustry(callIndusryOrgan.getStringCellValue());
} else {
organizations.setIndustry(null);
}
} else {
organizations.setIndustry(null);
}
Cell callPhoneOrgan = row.getCell(18);
if (callPhoneOrgan != null){
if (callPhoneOrgan.getCellType() == CellType.STRING) {
organizations.setPhone(callPhoneOrgan.getStringCellValue());
} else {
organizations.setPhone(null);
}
} else {
organizations.setPhone(null);
}
organizationRepository.save(organizations);
// ContactPost
String postname = "";
Cell post = row.getCell(14);
if(post != null){
String cellPostValue = post.getStringCellValue();
if(cellPostValue != null){
postname = cellPostValue.trim();
}
}
ContactPost contactPost = contactsPostRepository.findByPostname(postname);
if(!postname.isEmpty()){
if(contactPost == null){
contactPost = new ContactPost();
contactPost.setPostname(postname);
}
contactsPostRepository.save(contactPost);
}
// Scenario
String scenarioName = row.getCell(7).getStringCellValue().trim();
Scenario scenario = scenarioRepository.findByName(scenarioName);
if (scenario == null) {
scenario = new Scenario();
scenario.setName(scenarioName);
scenarioRepository.save(scenario);
}
// Clients
Clients clients = new Clients();
clients.setName_and_family(row.getCell(5).getStringCellValue());
clients.setPhone(row.getCell(6).getStringCellValue());
clientRepository.save(clients);
List<String> scenarioNames = Arrays.asList(scenarioName);
List<Scenario> scenarios = scenarioRepository.findByNameIn(scenarioNames);
Set<Scenario> scenarioSet = new HashSet<>(scenarios);
clients.setScenarios(scenarioSet);
callLog.setCallType(callTypes);
callLog.setCallResult(callResults);
callLog.setClient(clients);
callLog.setContact(contacts);
callLog.setTag(tags);
callLog.setEmployee(employees);
callLog.setScenario(scenario);
callLog.setCallLogTypeResult(callLogTypeResult);
contacts.setOrganization(organizations);
contacts.setContactPost(contactPost);
}
// Закрытие книги и поток ввода
workbook.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String getRowAsString(Row row) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < row.getLastCellNum(); i++) {
Cell cell = row.getCell(i);
String value = (cell != null) ? cell.getStringCellValue() : "";
sb.append(value);
if (i < row.getLastCellNum() - 1) {
sb.append("\t");
}
}
return sb.toString();
}
public List<CallLog> getReportData(){
return callLogRepository.findAll();
}
}

View File

@ -0,0 +1,68 @@
package callcenter.controllers;
import callcenter.Service.ReportService;
import callcenter.models.CallLog;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/reports")
public class ReportController {
private final ReportService reportService;
@Autowired
public ReportController(ReportService reportService){
this.reportService = reportService;
}
@PostMapping("/upload")
public ResponseEntity<String> uploadReport(@RequestParam("file") MultipartFile file) {
try {
File reportFile = new File(file.getOriginalFilename());
file.transferTo(reportFile);
reportService.processReport(reportFile);
reportFile.delete();
return ResponseEntity.ok("{\"message\": \"Отчет успешно загружен и обработан\"}");
} catch (IOException e){
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("{\"error\": \"Произошла ошибка при загрузке и обработке отчета.\"}");
}
}
@GetMapping("/summary")
public ResponseEntity<?> getReportSummary() {
try {
// Выполнение запроса к базе данных для получения данных отчета
List<CallLog> reportData = reportService.getReportData();
ObjectMapper objectMapper = new ObjectMapper();
String jsonData = objectMapper.writeValueAsString(reportData);
// Возвращаем успешный ответ с данными отчета в виде json- файла
return ResponseEntity.ok()
.header("Content-Type", "application/json")
.body(jsonData);
} catch (Exception e) {
e.printStackTrace();
// Возвращаем ответ с ошибкой
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("{\"error\": \"Произошла ошибка при получении данных отчета.\"}");
}
}
}

View File

@ -0,0 +1,80 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CallLog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int call_id;
// дата
private String call_date;
// время
private String call_time;
// связь между сотрудником
@ManyToOne
@JoinColumn(name = "employee_id")
private Employees employee;
// связь между типом вызова
@ManyToOne
@JoinColumn(name = "call_type_id")
private CallTypes callType;
// интервал
private String duration;
// связь между клиентом
@ManyToOne
@JoinColumn(name = "client_id")
private Clients client;
//private String scenario; // добавить новую таблицу
// связь между сценарием
@ManyToOne
@JoinColumn (name = "scenarioid")
private Scenario scenario;
// связь между результатом вызова
@ManyToOne
@JoinColumn(name = "call_result_id")
private CallResults callResult;
// комментарий
private String comment;
// связь между контактом
@ManyToOne
@JoinColumn(name = "contact_id")
private Contacts contact;
// связь между тегами
@ManyToOne
@JoinColumn(name = "tag_id")
private Tags tag;
// связь между типом результата вызова
@ManyToOne
@JoinColumn(name = "callLoggTypeResultId")
private CallLogTypeResult callLogTypeResult;
// индивид номер записи
private Integer call_record_id;
}

View File

@ -0,0 +1,25 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CallLogTypeResult {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int callLoggTypeResultId ;
//@Column(unique = true)
private String nametyperesult;
}

View File

@ -0,0 +1,24 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CallResults {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int call_result_id;
// @Column(unique = true)
private String name;
}

View File

@ -0,0 +1,22 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CallTypes {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int call_type_id;
//@Column(unique = true)
private String name;
}

View File

@ -0,0 +1,36 @@
package callcenter.models;
import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;
import lombok.*;
import java.util.Set;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Clients {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int client_id;
private String name_and_family;
private String phone;
// устанавливаем связь многие ко многим между сценарием и клиентом
@JsonBackReference
@ManyToMany
@JoinTable(
name = "client_scenario",
joinColumns = @JoinColumn(name = "client_id"),
inverseJoinColumns = @JoinColumn(name = "scenarioid")
)
private Set<Scenario> scenarios;
}

View File

@ -0,0 +1,24 @@
package callcenter.models;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class ContactPost {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int contact_post_id;
private String postname;
}

View File

@ -0,0 +1,32 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Contacts {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int contact_id;
private String name;
private String phone;
private String email;
@ManyToOne
@JoinColumn(name = "contact_post_id")
private ContactPost contactPost;
@ManyToOne
@JoinColumn(name = "organization_id")
private Organizations organization;
}

View File

@ -0,0 +1,20 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "employees")
public class Employees {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int employee_id;
private String family;
}

View File

@ -0,0 +1,30 @@
package callcenter.models;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Organizations {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int organization_id;
private String name;
private String phone;
private String email;
private String industry;
}

View File

@ -0,0 +1,30 @@
package callcenter.models;
import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;
import lombok.*;
import java.util.Set;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Scenario {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int scenarioid;
// @Column(unique = true)
private String name;
@JsonBackReference
@ManyToMany(mappedBy = "scenarios")
private Set<Clients> clients;;
}

View File

@ -0,0 +1,23 @@
package callcenter.models;
import jakarta.persistence.*;
import lombok.*;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Tags {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int tag_id;
// @Column(unique = true)
private String nameTag;
}

View File

@ -0,0 +1,7 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/callcenter
spring.datasource.username= bronnikovalexandr
spring.datasource.password= 84937
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
server.port=8081

View File

@ -0,0 +1,13 @@
package callcenter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Callcenter2ApplicationTests {
@Test
void contextLoads() {
}
}