JavaRush /Блоги Java /Random-TG /Мо қобилияти обуна шудан ба як гурӯҳи мақолаҳоро илова ме...
Roman Beekeeper
Сатҳи

Мо қобилияти обуна шудан ба як гурӯҳи мақолаҳоро илова мекунем. (Қисми 2) - "Лоиҳаи Java аз А то Я"

Дар гурӯҳ нашр шудааст
Салом ба ҳама! Мо корро дар болои вазифае, ки ҳафтаи гузашта оғоз карда будем, идома медиҳем ."Лоиҳаи Java аз A то Я": Илова кардани қобorяти обуна ба гурӯҳи мақолаҳо.  Қисми 2 - 1

Мо JRTB-5-ро ба амал меорем

Ҳоло мо бояд фармонеро илова кунем, то мо метавонем ба баъзе гурӯҳи мақолаҳо аз JavaRush обуна шавем. Чӣ тавр бояд кард? Мо аз рӯи соддатарин сенарияе, ки ман таҳия кардаам, пайравӣ хоҳем кард. Азбаски мо тавассути ID гурӯҳ дастрасӣ дорем, ба мо корбар лозим аст, ки онро интиқол диҳад. Барои ин корбар фармони /addGroupSub GROUP_ID-ро ворид мекунад, ки он бо яке аз ду роҳ кор мекунад: агар танҳо худи фармон ояд: /addGroupSub , дар ҷавоб рӯйхати ҳамаи гурӯҳҳо ва ID-ҳои онҳо фиристода мешавад. Он гоҳ корбар метавонад идентификатсияи гурӯҳи ба ӯ лозимиро интихоб кунад ва versionи дуюми дархостро дар ин фармон эҷод кунад: /addGroupSub GROUP_ID - ва пас аз он сабти ин гурӯҳ бо ин корбар хоҳад буд. Ман фикр мекунам, ки мо дар оянда беҳтар кор карда метавонем. Ҳадафи мо нишон додани рушд аст, на таҷрибаи корбарони олӣ (ман аз гуфтан шарм медорам, аммо ман истилоҳро ба забони русӣ намедонам, ки ин маънои онро дорад). Барои дуруст илова кардани функсияе, ки тавассути тамоми замима мегузарад (дар ҳолати мо, аз муштарии боти телеграмма то базаи маълумот), шумо бояд аз охири он оғоз кунед. Мо инро аз ҷониби базаи маълумот иҷро хоҳем кард.

Илова кардани муҳоҷирати нав ба пойгоҳи додаҳо

Аввалин коре, ки бояд анҷом дод, ин илова кардани муҳоҷирати нави пойгоҳи додаҳо ва қобorяти захира кардани маълумоти обунаи гурӯҳи корбарон дар JR мебошад. Барои ба ёд оред, ки ин чӣ гуна бояд бошад, ба мақолаи " Банақшагирии лоиҳа: ҳафт маротиба чен кунед " баргардед. Дар акси дуюм диаграммаи тахминии базаи маълумот мавҷуд аст. Мо бояд ҷадвалро барои нигоҳ доштани маълумоти гурӯҳ илова кунем:
  • ID-и гурӯҳ дар JavaRush инчунин ID-и мо хоҳад буд. Мо ба онҳо боварӣ дорем ва боварӣ дорем, ки ин ID-ҳо беназиранд;
  • унвон - дар расмҳои мо он ном буд - номи ғайрирасмии гурӯҳ; яъне он чизе ки мо дар вебсайти JavaRush мебинем;
  • last_article_id - ва ин як соҳаи ҷолиб аст. Он ID охирини мақоларо дар ин гурӯҳ нигоҳ медорад, ки бот онро аллакай ба муштариёнаш фиристодааст. Бо истифода аз ин майдон, механизми ҷустуҷӯи мақолаҳои нав кор мекунад. Муштариёни нав мақолаҳоеро, ки пеш аз обуна шудан ба корбар нашр шудаанд, қабул намекунанд: танҳо онҳое, ки пас аз обуна ба гурӯҳ нашр шудаанд.
Мо инчунин байни гурӯҳҳо ва ҷадвали корбарон муносибати бисёр ба бисёр хоҳем дошт, зеро ҳар як корбар метавонад шумораи зиёди обунаҳои гурӯҳӣ дошта бошад (як ба бисёр) ва ҳар як обунаи гурӯҳ метавонад корбарони зиёд дошта бошад (як ба бисёр, танҳо дар тарафи дигар). Маълум мешавад, ки ин бисёр-ба-сари мо мешавад. Барои онҳое, ки савол доранд, мақолаҳоро дар пойгоҳи додаҳо дида бароед. Бале, ман ба наздикӣ нақша дорам, ки дар канали Telegram як пост эҷод кунам, ки дар он ҳама мақолаҳоро дар базаи маълумот ҷамъоварӣ мекунам. Муҳоҷирати базаи дуюми мо чунин хоҳад буд.
V00002__created_groupsub_many_to_many.sql:

-- add PRIMARY KEY FOR tg_user
ALTER TABLE tg_user ADD PRIMARY KEY (chat_id);

-- ensure that the tables with these names are removed before creating a new one.
DROP TABLE IF EXISTS group_sub;
DROP TABLE IF EXISTS group_x_user;

CREATE TABLE group_sub (
   id INT,
   title VARCHAR(100),
   last_article_id INT,
   PRIMARY KEY (id)
);

CREATE TABLE group_x_user (
   group_sub_id INT NOT NULL,
   user_id VARCHAR(100) NOT NULL,
   FOREIGN KEY (user_id) REFERENCES tg_user(chat_id),
   FOREIGN KEY (group_sub_id) REFERENCES group_sub(id),
   UNIQUE(user_id, group_sub_id)
);
Бояд қайд кард, ки аввал ман ҷадвали кӯҳнаро иваз мекунам - ба он калиди ибтидоӣ илова мекунам. Ман он вақт инро ба гунае аз даст додам, аммо ҳоло MySQL ба ман имкони илова кардани КАЛИДИ ХОРИҶИ барои ҷадвали gorup_x_user надодааст ва дар доираи ин муҳоҷират ман пойгоҳи додаҳоро нав кардам. Лутфан як ҷанбаи муҳимро қайд кунед. Тағйир додани базаи маълумот бояд маҳз ҳамин тавр анҷом дода шавад - ҳама чизе, ки лозим аст, дар муҳоҷирати нав аст, аммо на бо навсозии муҳоҷирати аллакай баровардашуда. Бале, дар ҳолати мо ҳеҷ чиз рӯй намедиҳад, зеро ин лоиҳаи санҷишӣ аст ва мо медонем, ки он танҳо дар як ҷо ҷойгир карда шудааст, аммо ин муносибати нодуруст хоҳад буд. Аммо мо мехоҳем, ки ҳама чиз дуруст бошад. Баъдан нест кардани ҷадвалҳо пеш аз сохтани онҳо меояд. Чаро ин аст? Барои он ки агар тасодуфан дар базаи маълумот ҷадвалҳо бо чунин номҳо вуҷуд дошта бошанд, муҳоҷират ноком намешуд ва айнан ҳамон тавре ки интизор мерафт, кор мекард. Ва он гоҳ мо ду ҷадвалро илова мекунем. Ҳама чиз тавре буд, ки мо мехостем. Ҳоло мо бояд барномаи худро оғоз кунем. Агар ҳама чиз оғоз шавад ва вайрон нашавад, пас муҳоҷират сабт карда мешавад. Ва барои бори дигар тафтиш кардани ин, мо ба базаи маълумот меравем, то боварӣ ҳосил кунем, ки: а) чунин ҷадвалҳо пайдо шудаанд; б) дар ҷадвали техникии парвоз сабти нав мавҷуд аст. Ин кори муҳоҷиратро анҷом медиҳад, биёед ба анборҳо гузарем.

Илова кардани қабати репозиторий

Бо шарофати Spring Boot Data, дар ин ҷо ҳама чиз хеле содда аст: ба мо лозим аст, ки ҷузъи GroupSub-ро илова кунем, TelegramUser-ро каме навсозӣ кунем ва GroupSubRepository қариб холӣ илова кунем: Мо гурӯҳи GroupSub-ро ба ҳамон бастаи TelegramUser илова мекунем:
package com.github.javarushcommunity.jrtb.repository.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

import static java.util.Objects.isNull;

@Data
@Entity
@Table(name = "group_sub")
@EqualsAndHashCode
public class GroupSub {

   @Id
   private Integer id;

   @Column(name = "title")
   private String title;

   @Column(name = "last_article_id")
   private Integer lastArticleId;

   @ManyToMany(fetch = FetchType.EAGER)
   @JoinTable(
           name = "group_x_user",
           joinColumns = @JoinColumn(name = "group_sub_id"),
           inverseJoinColumns = @JoinColumn(name = "user_id")
   )
   private List<TelegramUser> users;

   public void addUser(TelegramUser telegramUser) {
       if (isNull(users)) {
           users = new ArrayList<>();
       }
       users.add(telegramUser);
   }
}
Як чизи қобor зикр аст, ки мо як майдони корбарони иловагӣ дорем, ки маҷмӯи ҳамаи корбарони ба гурӯҳ обунашударо дар бар мегирад. Ва ду тавзеҳот - ManyToMany ва JoinTable - маҳз ҳамон чизест, ки барои ин ба мо лозим аст. Барои TelegramUser ҳамон майдон бояд илова карда шавад:
@ManyToMany(mappedBy = "users", fetch = FetchType.EAGER)
private List<GroupSub> groupSubs;
Ин майдон пайвастагиҳоеро, ки дар an objectи GroupSub навишта шудаанд, истифода мебарад. Ва, дар асл, синфи анбори мо барои GroupSub GroupSubRepository аст :
package com.github.javarushcommunity.jrtb.repository;

import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
* {@link Repository} for {@link GroupSub} entity.
*/
@Repository
public interface GroupSubRepository extends JpaRepository<GroupSub, Integer> {
}
Дар ин марҳила ба мо усулҳои иловагӣ лозим нест: онҳое, ки дар аҷдоди JpaRepository амалӣ карда шудаанд, барои мо кифояанд. Биёед дар TelegramUserRepositoryIT озмоиш нависем, ки тафтиш мекунад, ки бисёр-ба-бисёр кор мекунад. Идеяи санҷиш аз он иборат аст, ки мо тавассути скрипти sql ба пойгоҳи додаҳо 5 гурӯҳи обунаҳоро дар як корбар илова мекунем, ин корбарро бо ID-и худ мегирем ва тафтиш мекунем, ки мо маҳз ҳамон гурӯҳҳоро ва бо ҳамон арзишҳо қабул кардаем. Чӣ тавр бояд кард? Шумо метавонед ҳисобкунакро дар маълумот ҷойгир кунед, ки мо онро пас аз гузаштан ва тафтиш карда метавонем. Ин аст скрипти fiveGroupSubsForUser.sql:
INSERT INTO tg_user VALUES (1, 1);

INSERT INTO group_sub VALUES
(1, 'g1', 1),
(2, 'g2', 2),
(3, 'g3', 3),
(4, 'g4', 4),
(5, 'g5', 5);

INSERT INTO group_x_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);
Ва худи имтиҳон:
@Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveGroupSubsForUser.sql"})
@Test
public void shouldProperlyGetAllGroupSubsForUser() {
   //when
   Optional<TelegramUser> userFromDB = telegramUserRepository.findById("1");

   //then
   Assertions.assertTrue(userFromDB.isPresent());
   List<GroupSub> groupSubs = userFromDB.get().getGroupSubs();
   for (int i = 0; i < groupSubs.size(); i++) {
       Assertions.assertEquals(String.format("g%s", (i + 1)), groupSubs.get(i).getTitle());
       Assertions.assertEquals(i + 1, groupSubs.get(i).getId());
       Assertions.assertEquals(i + 1, groupSubs.get(i).getLastArticleId());
   }
}
Акнун биёед санҷиши ҳамон маъноро барои an objectи GroupSub илова кунем. Барои ин, биёед синфи санҷишии groupSubRepositoryIT-ро дар ҳамон бастае бо groupSubRepositoryIT эҷод кунем :
package com.github.javarushcommunity.jrtb.repository;

import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;

import java.util.List;
import java.util.Optional;

import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE;

/**
* Integration-level testing for {@link GroupSubRepository}.
*/
@ActiveProfiles("test")
@DataJpaTest
@AutoConfigureTestDatabase(replace = NONE)
public class GroupSubRepositoryIT {

   @Autowired
   private GroupSubRepository groupSubRepository;

   @Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveUsersForGroupSub.sql"})
   @Test
   public void shouldProperlyGetAllUsersForGroupSub() {
       //when
       Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(1);

       //then
       Assertions.assertTrue(groupSubFromDB.isPresent());
       Assertions.assertEquals(1, groupSubFromDB.get().getId());
       List<TelegramUser> users = groupSubFromDB.get().getUsers();
       for(int i=0; i<users.size(); i++) {
           Assertions.assertEquals(String.valueOf(i + 1), users.get(i).getChatId());
           Assertions.assertTrue(users.get(i).isActive());
       }
   }
}
Ва панҷ скрипти гумшудаиUsersForGroupSub.sql:
INSERT INTO tg_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);

INSERT INTO group_sub VALUES (1, 'g1', 1);

INSERT INTO group_x_user VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5);
Дар ин лаҳза, як қисми кор бо анборро анҷом додан мумкин аст. Акнун биёед як қабати хидматрасониро нависед.

Мо GroupSubService менависем

Дар ин марҳила, барои кор бо гурӯҳҳои обунаҳо, мо бояд танҳо онҳоро захира карда тавонем, бинобар ин ҳеҷ мушкиле нест: мо хидмати GroupSubService ва татбиқи он GroupSubServiceImpl-ро дар бастае эҷод мекунем, ки хидматҳои дигарро дар бар мегирад - хидмат:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;

/**
* Service for manipulating with {@link GroupSub}.
*/
public interface GroupSubService {

   GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo);
}
Ва татбиқи он:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.ws.rs.NotFoundException;
import java.util.Optional;

@Service
public class GroupSubServiceImpl implements GroupSubService {

   private final GroupSubRepository groupSubRepository;
   private final TelegramUserService telegramUserService;

   @Autowired
   public GroupSubServiceImpl(GroupSubRepository groupSubRepository, TelegramUserService telegramUserService) {
       this.groupSubRepository = groupSubRepository;
       this.telegramUserService = telegramUserService;
   }

   @Override
   public GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo) {
       TelegramUser telegramUser = telegramUserService.findByChatId(chatId).orElseThrow(NotFoundException::new);
       //TODO add exception handling
       GroupSub groupSub;
       Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(groupDiscussionInfo.getId());
       if(groupSubFromDB.isPresent()) {
           groupSub = groupSubFromDB.get();
           Optional<TelegramUser> first = groupSub.getUsers().stream()
                   .filter(it -> it.getChatId().equalsIgnoreCase(chatId))
                   .findFirst();
           if(first.isEmpty()) {
               groupSub.addUser(telegramUser);
           }
       } else {
           groupSub = new GroupSub();
           groupSub.addUser(telegramUser);
           groupSub.setId(groupDiscussionInfo.getId());
           groupSub.setTitle(groupDiscussionInfo.getTitle());
       }
       return groupSubRepository.save(groupSub);
   }
}
Барои он ки Spring Data дуруст кор кунад ва сабти бисёр ба бисёр эҷод шавад, мо бояд корбарро аз пойгоҳи додаи гурӯҳи обунаие, ки мо эҷод карда истодаем, гирем ва онро ба an objectи GroupSub илова кунем. Ҳамин тариқ, вақте ки мо ин обунаро барои захира интиқол медиҳем, пайвастшавӣ инчунин тавассути ҷадвали group_x_user эҷод карда мешавад. Шояд вазъияте вуҷуд дошта бошад, ки чунин гурӯҳи обуна аллакай таъсис дода шудааст ва шумо танҳо бояд ба он корбари дигар илова кунед. Барои ин мо аввал идентификатсияи гурӯҳро аз база мегирем ва агар сабт мавҷуд бошад, бо он кор мекунем, агар набошад, наваш эҷод мекунем. Қайд кардан муҳим аст, ки барои кор бо TelegramUser мо TelegramUserService-ро барои риояи охирин принсипҳои SOLID истифода мебарем. Дар айни замон, агар мо сабтро аз рӯи ID наёбем, ман танҳо як истисно мегузорам. Ҳоло он ба ҳеҷ ваҷҳ коркард карда намешавад: мо инро дар ниҳоят, пеш аз MVP иҷро хоҳем кард. Биёед ду санҷиши воҳидиро барои синфи GroupSubServiceTest нависед . Кадомашон ба мо лозиманд? Ман мехоҳам итминон дошта бошам, ки усули нигоҳдорӣ дар GroupSubRepository даъват карда мешавад ва an objectи дорои як корбари ягона ба GroupSub интиқол дода мешавад - он шахсе, ки TelegramUserService -ро бо истифода аз ID-и пешниҳодшуда ба мо бармегардонад. Ва варианти дуюм, вақте ки гурӯҳе бо ҳамон ID аллакай дар пойгоҳи додаҳо қарор дорад ва ин гурӯҳ аллакай як корбар дорад ва шумо бояд тафтиш кунед, ки корбари дигар ба ин гурӯҳ илова карда мешавад ва ин an object захира карда мешавад. Ин аст татбиқи:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.Optional;

@DisplayName("Unit-level testing for GroupSubService")
public class GroupSubServiceTest {

   private GroupSubService groupSubService;
   private GroupSubRepository groupSubRepository;
   private TelegramUser newUser;

   private final static String CHAT_ID = "1";

   @BeforeEach
   public void init() {
       TelegramUserService telegramUserService = Mockito.mock(TelegramUserService.class);
       groupSubRepository = Mockito.mock(GroupSubRepository.class);
       groupSubService = new GroupSubServiceImpl(groupSubRepository, telegramUserService);

       newUser = new TelegramUser();
       newUser.setActive(true);
       newUser.setChatId(CHAT_ID);

       Mockito.when(telegramUserService.findByChatId(CHAT_ID)).thenReturn(Optional.of(newUser));
   }

   @Test
   public void shouldProperlySaveGroup() {
       //given

       GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
       groupDiscussionInfo.setId(1);
       groupDiscussionInfo.setTitle("g1");

       GroupSub expectedGroupSub = new GroupSub();
       expectedGroupSub.setId(groupDiscussionInfo.getId());
       expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
       expectedGroupSub.addUser(newUser);

       //when
       groupSubService.save(CHAT_ID, groupDiscussionInfo);

       //then
       Mockito.verify(groupSubRepository).save(expectedGroupSub);
   }

   @Test
   public void shouldProperlyAddUserToExistingGroup() {
       //given
       TelegramUser oldTelegramUser = new TelegramUser();
       oldTelegramUser.setChatId("2");
       oldTelegramUser.setActive(true);

       GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
       groupDiscussionInfo.setId(1);
       groupDiscussionInfo.setTitle("g1");

       GroupSub groupFromDB = new GroupSub();
       groupFromDB.setId(groupDiscussionInfo.getId());
       groupFromDB.setTitle(groupDiscussionInfo.getTitle());
       groupFromDB.addUser(oldTelegramUser);

       Mockito.when(groupSubRepository.findById(groupDiscussionInfo.getId())).thenReturn(Optional.of(groupFromDB));

       GroupSub expectedGroupSub = new GroupSub();
       expectedGroupSub.setId(groupDiscussionInfo.getId());
       expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
       expectedGroupSub.addUser(oldTelegramUser);
       expectedGroupSub.addUser(newUser);

       //when
       groupSubService.save(CHAT_ID, groupDiscussionInfo);

       //then
       Mockito.verify(groupSubRepository).findById(groupDiscussionInfo.getId());
       Mockito.verify(groupSubRepository).save(expectedGroupSub);
   }

}
Ман инчунин усули init() -ро бо эзоҳоти BeforeEach илова кардам. Бо ин роҳ, онҳо одатан усулеро эҷод мекунанд, ки пеш аз ҳар як санҷиш иҷро карда мешавад ва барои ҳама санҷишҳо мантиқи умумиро ба он гузоштан мумкин аст. Дар ҳолати мо, мо бояд TelegramUserService-ро барои ҳама санҷишҳои ин синф ҳамин тавр қулф кунем, аз ин рӯ интиқол додани ин мантиқ ба усули умумӣ маъно дорад. Дар ин ҷо ду тарҳи mokito истифода мешаванд:
  • Mockito.when(o1.m1(a1)).thenReturn(o2) - дар он мо мегӯем, ки вақте усули m1 дар an objectи o1 бо аргументи a1 даъват мешавад , метод an objectи o2 -ро бармегардонад . Ин қариб муҳимтарин функсияи mockito аст - маҷбур кардани an objectи масхара барои баргардонидани маҳз он чизе, ки ба мо лозим аст;

  • Mockito.verify(o1).m1(a1) - ки тасдиқ мекунад, ки усули m1 дар an objectи o1 бо аргументи a1 даъват шудааст . Албатта, истифода бурдани an objectи баргардонидашудаи усули нигоҳдорӣ имконпазир буд, аммо ман қарор додам, ки бо нишон додани усули дигари имконпазир онро каме мураккабтар кунам. Кай он метавонад муфид бошад? Дар ҳолатҳое, ки усулҳои дарсҳои тақаллубӣ беэътибор бармегарданд. Пас бе Mockito.verify кор намешавад)))

Мо ба ақидае пайравӣ мекунем, ки санҷишҳо бояд навишта шаванд ва бисёре аз онҳо бояд навишта шаванд. Марҳилаи навбатӣ кор бо дастаи телеграмма мебошад.

Фармони /addGroupSub -ро эҷод кунед

Дар ин ҷо мо бояд мантиқи зеринро иҷро кунем: агар мо танҳо як фармонро бидуни ягон контекст қабул кунем, мо ба корбар кӯмак мекунем ва ба ӯ рӯйхати ҳамаи гурӯҳҳоро бо ID-ҳояшон медиҳем, то ӯ маълумоти заруриро ба бот интиқол диҳад. Ва агар корбар фармонеро ба бот бо ягон калима(ҳо)-и дигар фиристад, гурӯҳеро бо он ID пайдо кунед ё бинависед, ки чунин гурӯҳ вуҷуд надорад. Биёед ба номи худ арзиши нав илова кунем - CommandName:
ADD_GROUP_SUB("/addgroupsub")
Биёед минбаъд аз пойгоҳи додаҳо ба боти телеграмма гузарем - синфи AddGroupSubCommandро дар бастаи фармонҳо эҷод кунед:
package com.github.javarushcommunity.jrtb.command;

import com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.service.GroupSubService;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import org.telegram.telegrambots.meta.api.objects.Update;

import java.util.stream.Collectors;

import static com.github.javarushcommunity.jrtb.command.CommandName.ADD_GROUP_SUB;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getChatId;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getMessage;
import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.SPACE;
import static org.apache.commons.lang3.StringUtils.isNumeric;

/**
* Add Group subscription {@link Command}.
*/
public class AddGroupSubCommand implements Command {

   private final SendBotMessageService sendBotMessageService;
   private final JavaRushGroupClient javaRushGroupClient;
   private final GroupSubService groupSubService;

   public AddGroupSubCommand(SendBotMessageService sendBotMessageService, JavaRushGroupClient javaRushGroupClient,
                             GroupSubService groupSubService) {
       this.sendBotMessageService = sendBotMessageService;
       this.javaRushGroupClient = javaRushGroupClient;
       this.groupSubService = groupSubService;
   }

   @Override
   public void execute(Update update) {
       if (getMessage(update).equalsIgnoreCase(ADD_GROUP_SUB.getCommandName())) {
           sendGroupIdList(getChatId(update));
           return;
       }
       String groupId = getMessage(update).split(SPACE)[1];
       String chatId = getChatId(update);
       if (isNumeric(groupId)) {
           GroupDiscussionInfo groupById = javaRushGroupClient.getGroupById(Integer.parseInt(groupId));
           if (isNull(groupById.getId())) {
               sendGroupNotFound(chatId, groupId);
           }
           GroupSub savedGroupSub = groupSubService.save(chatId, groupById);
           sendBotMessageService.sendMessage(chatId, "Подписал на группу " + savedGroupSub.getTitle());
       } else {
           sendGroupNotFound(chatId, groupId);
       }
   }

   private void sendGroupNotFound(String chatId, String groupId) {
       String groupNotFoundMessage = "Нет группы с ID = \"%s\"";
       sendBotMessageService.sendMessage(chatId, String.format(groupNotFoundMessage, groupId));
   }

   private void sendGroupIdList(String chatId) {
       String groupIds = javaRushGroupClient.getGroupList(GroupRequestArgs.builder().build()).stream()
               .map(group -> String.format("%s - %s \n", group.getTitle(), group.getId()))
               .collect(Collectors.joining());

       String message = "Whatбы подписаться на группу - передай комадну вместе с ID группы. \n" +
               "Например: /addGroupSub 16. \n\n" +
               "я подготовил список всех групп - выберай Howую хочешь :) \n\n" +
               "Name группы - ID группы \n\n" +
               "%s";

       sendBotMessageService.sendMessage(chatId, String.format(message, groupIds));
   }
}
Ин синф усули isNumeric аз китобхонаи apache-commons-ро истифода мебарад, аз ин рӯ биёед онро ба хотираи худ илова кунем:
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>${apache.commons.version}</version>
</dependency>
Ва дар блоки хосиятҳо:
<apache.commons.version>3.11</apache.commons.version>
Ҳамаи ин мантиқ дар синф аст. Онро бодиққат хонед. Агар шумо ягон савол / пешниҳод дошта бошед, онҳоро дар шарҳҳо нависед. Пас аз ин, мо бояд фармонро ба CommandContainer дар харитаи фармони худ илова кунем:
.put(ADD_GROUP_SUB.getCommandName(), new AddGroupSubCommand(sendBotMessageService, javaRushGroupClient, groupSubService))
Ва ҳама чиз барои ин даста. Ман мехостам бо ягон роҳ ин функсияро санҷам, аммо то ҳол ман метавонам онро танҳо дар базаи маълумот дидам. Дар қисми сеюм, ман тағиротро аз JRTB-6 илова мекунам, то мо метавонем рӯйхати гурӯҳҳоеро, ки корбар ба он обуна шудааст, бубинем. Акнун хамаи инро тафтиш кардан хуб мебуд. Барои ин, мо тамоми амалҳоро дар Telegram иҷро мекунем ва дар базаи маълумот тафтиш мекунем. Азбаски мо санҷишҳоро навиштаем, ҳама чиз бояд хуб бошад. Мақола аллакай хеле дароз аст, бинобар ин мо дертар барои AddGroupSubCommand санҷиш менависем ва TODO-ро дар code илова мекунем, то фаромӯш накунем.

хулосахо

Дар ин мақола, мо ба кори илова кардани функсияҳо тавассути тамоми барнома, аз пойгоҳи додаҳо сар карда, то кор бо муштарие, ки ботро истифода мебарад, дида баромадем. Одатан, чунин вазифаҳо барои фаҳмидани лоиҳа ва фаҳмидани моҳияти он кӯмак мекунанд. Бифаҳмед, ки он чӣ гуна кор мекунад. Дар ин рӯзҳо мавзӯъҳо осон нестанд, аз ин рӯ шарм надоред: саволҳои худро дар шарҳҳо нависед ва ман кӯшиш мекунам ба онҳо ҷавоб диҳам. Лоиҳа ба шумо маъқул аст? Ба он дар Github ситора диҳед : бо ин роҳ маълум хоҳад шуд, ки онҳо ба лоиҳа таваҷҷӯҳ доранд ва ман хурсанд хоҳам шуд. Чи хеле ки мегуянд, усто хамеша аз кадри мехнаташ шод мешавад. Рамз ҳар се қисми STEP_6-ро дар бар мегирад ва то ин мақола дастрас хоҳад буд. Чӣ тавр дар бораи он фаҳмидан мумкин аст? Ин осон аст - ба канали телеграм ҳамроҳ шавед , ки дар он ман ҳама маълумотро дар бораи мақолаҳои худ дар бораи боти телеграм нашр мекунам. Ташаккур барои хондан! Қисми 3 аллакай дар ин ҷост .

Рӯйхати ҳамаи маводҳои силсила дар аввали ин мақола аст.

Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION