Цель данного проекта — реализация системы онлайн-офиса для малых и средних предприятий. Онлайн-система управления офисом CloudOffice предназначена для управления повседневной работой, включая различные процессы одобрения, новостей, объявлений, информации о файлах, финансов, кадров, расходов, активов, административных вопросов, проектов и мобильной работы. Основная цель системы — обеспечить удобство управления через программное обеспечение, сделать процесс более простым, эффективным и стандартизованным, что позволит повысить уровень управления и операционной деятельности.
Архитектурное описание программы
Новый созданный Spring Boot проект будет использоваться как родительский проект. Этот родительский проект будет служить для управления зависимостями pom всех наших проектов, поэтому большинство файлов и папок можно удалить.
Измените файл pom.xml
, удалите тег зависимости <dependencies>
и тег сборки <build>
, а также его содержимое. Добавьте тег <packaging>
со значением pom
.
Создайте модульный проект Module. Используйте Maven для создания быстрого запуска модульного подпроекта yeb-server
, который будет отвечать за всю бизнес-логику.
Внесите изменения в новый модульный проект yeb-server
. Удалите сгенерированный класс App и тестовый класс AppTest, затем добавьте пакет server
.
В файле pom.xml
подпроекта yeb-server
добавьте координаты родительского проекта, связывая его с основным проектом.6) Удалите тег сборки <build>
и зависимости (так как мы будем копировать необходимые зависимости).
Дополните структуру директорий нового модульного проекта, такие как resources
, директории уровней и так далее, и добавьте конфигурационный файл application.yml
. Обратите внимание, что при копировании содержимого конфигурационного файла легко возникнуть ошибки.
Добавьте запуск класс YebApplication
и аннотацию сканирования мапперов.
Разместите конфигурационный файл application.yml
в директории config
.
yeb-generator
после создания классов для каждого модуля скопируйте их в субпроект yeb-server
.yeb-server
, удалите их из субпроекта yeb-generator
, так как они будут отмечены ошибками.swagger2
.CodeGenerator
генератора кода вам потребуется указать пакеты, для которых требуется создание классов. В этом файле есть подробные комментарии.6. Создание класса-инструмента Jwt Token
Настройка фильтров авторизации безопасности
Персонализация результатов возврата безопасности
@Configuration
.Напишите интерфейс CaptchaController
.
В SecurityConfig
разрешите доступ к графическому CAPTCHA, указав адреса, которые должны быть разрешены.
Измените документацию API так, чтобы она также отображала графический CAPTCHA, используя аннотацию @GetMapping(value = "/captcha", produces = "image/jpeg")
.
При истечении срока действия токена будет выдано сообщение об ошибке: io.jsonwebtoken.ExpiredJwtException: JWT expired at 202-7-23723:18.2 Current time:2001-47-2412208.34, a difference of 82207652 milliseconds. Allowed clock skew:0 milliseconds.
15. Проверка кода подтверждения
AdminLoginParam
добавьте параметр кода подтверждения, а также добавьте параметр code
в соответствующие методы слоёв.login()
класса AdminServiceImpl
проверьте, совпадает ли введённый пользователем код подтверждения с тем, что хранится в сессии.16. Получение списка меню по id пользователя
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
.17. Составление SQL-запроса для получения списка меню по id пользователя
MenuController
, поэтому здесь была проведена корректировка.18. [18. Интеграция Redis для управления меню]
application.yml
.@Configuration
, иначе конфигурация не будет применена.component
и измените пути хранения некоторых .java
файлов.t_menu
, иначе возникнет ошибка недостаточных прав доступа.@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
в классах сущностей, где pattern
— это формат времени, а timezone
— временная зона.LocalDateTime.now()
, чтобы получить текущее время системы.Arrays.asList(ids)
@RestControllerAdvice
указывает на класс, расширяющий возможности контроллеров, и позволяет перехватывать соответствующие исключения.@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
к соответствующим полям в сущностях для форматирования времени.List
выполняется через Arrays.asList(ids)
.titleLevel
таблицы t_joblevel
имеет фиксированное значение, что следует учитывать.Enum
.RequestMapping
MenuController
на "system/config"
.list()
MyBatisPlus
roleService.list()
.save()
MyBatisPlus
roleService.save()
.Id
с использованием метода removeById()
MyBatisPlus
roleService.removeById()
.resultMap
в MenuMapper.xml
.id
по роли id
): menuRoleService.list(new QueryWrapper<MenuRole>().eq("rid", rid)).stream().map(MenuRole::getMid).collect(Collectors.toList())
.26. Реализация функционала обновления меню группы прав доступа
Создание и вызов хранимых процедур
Обзор хранимых процедур проекта
Получение всех отделов
<insert>
тега в xxxMapper.xml
файле используется <select>
тегAdminUtils
для получения информации о входящем пользователе, такой как ID, который берется из Spring Security@Param
concat()
, предоставляемую базой данных, для соединения строк<resultMap>
в файле AdminMapper.xml
Обновляем данные с помощью метода updateById()
, предоставленного MyBatisPlus
Здесь следует обратить внимание на @Data
. Добавьте аннотацию @Getter(AccessLevel.NONE)
, чтобы не генерировать getter метод для этого поля
Интерфейсы для обновления и удаления данных не были протестированы35. [Реализация функционала роли оператора]
Обратите внимание на цикл SQL-запросов в AdminRoleMapper.xml при массовой обработке данных
Эти интерфейсы также не были протестированы
[Тестирование получения всех сотрудников с пагинацией]1) После завершения каждого интерфейса его обязательно следует протестировать, исправлять ошибки и улучшать качество.
[Подготовка к добавлению сотрудника]
EmployeeServiceImpl
используйте String.format
для форматирования строки, чтобы избежать проблем с кодировкой.max(workID)
вместо max(workId)
.LocalDate
.MyBatisPlus
, чтобы быстро выполнить задачи.В файле pom.xml добавьте зависимости EasyPoi; одной из его основных особенностей является возможность использования аннотаций для определения полей, которые вы хотите экспортировать.
В полях соответствующих POJO-классов добавьте аннотацию @Excel от EasyPoi. Обратите внимание на использование аннотации @ExcelEntity.
Классы следует пометить аннотацией @ExcelEntity, а затем использовать аннотацию @Excel для полей внутри объекта.44. 【44. Экспорт данных сотрудников】
Обратите внимание на использование свойства produces
в аннотации @GetMapping(value = "/export", produces = "application/octet-stream")
, чтобы избежать проблем с кодировкой, как это было сделано для CAPTCHA.
Экспортируемые данные отправляются потоковым образом.
Для запроса информации о сотрудниках используется SQL-запрос из раздела [37. Получение всех сотрудников с пагинацией].
Я протестировал экспорт и считаю это очень мощным решением.
Дата увольнения и стаж работы не содержатся в базе данных, поэтому они не экспортируются.
@EqualsAndHashCode
.Успешный импорт, но отсутствие данных в базе данных могут указывать на то, что все данные не были проверены или находятся на следующей странице. Этот опыт показывает.
Аргумент ExcelType.HSSF указывает на использование версии Excel 2003, так как она обеспечивает лучшую совместимость.47. 【47. Создание проекта для отправки электронных сообщений】
Отправка электронных сообщений требует активации SMTP-сервера для почты.
Создайте новый подпроект yeb-mail
, обновите файл pom.xml
для добавления необходимых зависимостей, создайте запускающий класс.
Подготовьте шаблоны электронных сообщений, используя Thymeleaf. Шаблоны должны быть расположены в директории templates
в каталоге resources
, такие как файл mail.html
.
Для использования Thymeleaf необходимо добавить заголовок <html lang="en" xmlns:th="http://www.thymeleaf.org">
в html-файле.
Для безопасности авторизация для отправки электронных сообщений не была загружена. При использовании необходимо добавить ваш ключ авторизации в файл application.yml
службы почты.
В подпроекте yeb-server
в файле pom.xml
необходимо добавить зависимость rabbitmq
, так как требуется её использование.
Кроме зависимости, также потребуется конфигурация rabbitmq
в файле application.yml
подпроекта yeb-server
.
Конфигурацию rabbitmq
следует настроить с использованием вашего имени пользователя, пароля и адреса сервера.
Здесь реализовано только отправка письма при добавлении сотрудника; импорт данных через Excel пока не реализован.
Отправка сообщений осуществляется в подпроекте yeb-server
, а получение сообщений и отправка электронной почты — в подпроекте yeb-mail
.6) В запускающем классе проекта yeb-mail
необходимо настроить привязку к rabbitmq
, такие как очереди и обменники.
В проекте yeb-mail
была добавлена зависимость от yeb-server
, что требует подключения к базе данных. Поэтому необходимо указать источник данных, убрав аннотацию @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
в запускающем классе MailApplication
.
Обратите внимание, что вам необходимо настроить ваш авторизационный код почтового сервиса.
[Описание надёжной доставки сообщений на стороне производителя]
[Включение обратного вызова сообщений]
Основная цель — обеспечить правильную отправку электронной почты.
Необходим класс конфигурации RabbitMQConfig
, использующий режим маршрутизации DirectExchange
.
Также следует настроить обратный вызов успешной доставки и обратный вызов ошибочной доставки в файле application.yml
.
Успешный и неудачный обратные вызовы должны быть правильно обработаны.
Создание задачи отправки электронной почты с расписанием.
В запускающем классе добавьте аннотацию @EnableScheduling
для включения задач с расписанием.3) Теперь сообщения будут записываться в базу данных.
Включите ручное подтверждение RabbitMQ.
В файле application.yml проекта yeb-mail добавьте конфигурацию Redis.
Измените местоположение отправки электронной почты; изменения довольно существенные.
Сохраните данные в Redis при отправке электронной почты.
Здесь важно понять этот процесс.
В полях класса POJO добавьте аннотацию @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai"), чтобы форматировать время.
Поскольку все пути запросов уже определены в базе данных, каждый раз при создании контроллеров необходимо указывать соответствующие пути @RequestMapping().
Получение текущего времени выполняется с помощью LocalDateTime.now().
Процесс добавления, удаления, изменения и выборки можно использовать методы, предоставляемые MyBatisPlus.
employeeService.update(new UpdateWrapper<Employee>().set("salaryId", sid).eq("id", eid))
На уровне контроллера используйте аннотации @RestController
и @RequestMapping("/salary/sobcfg")
57. [Модуль онлайн-чат — конфигурация webSocket]
Добавьте зависимости для работы с webSocket
Создайте конфигурационный класс WebSocketConfig
и примените к нему аннотации @Configuration
и @EnableWebSocketMessageBroker
, где @Configuration
обязательна для конфигурационного класса
Класс WebSocketConfig
также должен реализовать интерфейс WebSocketMessageBrokerConfigurer
В фронтенд части обычно используют sockJS
для соединения с webSocket, а использование нативной реализации сейчас мало распространено
@Value("${jwt.tokenHead}")
для получения значения из файла application.yml
и привязки его к полюChatMsg
для хранения содержимого сообщений@MessageMapping
в методах контроллераДобавьте комментарии для лучшего понимания процесса работы webSocket
Конфигурируйте конечную точку /ws/ep
Установите токен Auth-Token
Установите глобальный объект пользователя безопасности и вызов accessor.setUser()
, чтобы обеспечить подключение
Установите пространство имен registry.enableSimpleBroker("/queue")
, которое может быть расширено по необходимости бизнеса
Наконец, не забудьте открыть пути для отправки сообщений в классе SecurityConfig
с помощью аннотации @MessageMapping("/ws/chat")
60. [Модуль личного центра — реализация функционала личного центра]
Реализованы основные операции личного центра, такие как обновление информации пользователя и замена аватара (используя FastDFS).
Основные операции личного центра: обновление информации пользователя, обновление пароля.
После изменения пароля пользователю требуется выйти из системы и войти снова; этот процесс обрабатывается на стороне клиента.
Пользовательская десериализация
При обновлении информации о залогиненном пользователе возникает проблема с JSON-преобразованием, связанная с некорректной передачей полей authorities
. По умолчанию GrantedAuthority
не может быть десериализован.
Для решения этой проблемы необходимо создать пользовательский класс десериализации CustomAuthorityDeserializer
.
В местах, где требуется десериализация, следует использовать аннотацию @JsonDeserialize(using = CustomAuthorityDeserializer.class)
.
Тестирование обновления информации о текущем пользователе и изменения пароля пользователя завершено.
[Написание вспомогательных классов для FastDFS]1) Основной задачей является реализация функционала изменения аватара, поэтому важно убедиться, что сервис FastDFS запущен, то есть сначала следует установить FastDFS.
FastDFS — это открытый легковесный распределённый файловый системный проект.
В первую очередь требуется конфигурационный файл fdfs_client.conf для FastDFS, обратите внимание на суффикс .conf.
Конфигурационный файл fdfs_client.conf включает в себя настройку IP-адреса вашего трекера и порта.
Далее следует написать вспомогательные классы для FastDFS, содержащие различные методы операций, такие как загрузка и скачивание файлов.63. [63. Реализация функционала изменения аватара]
Интерфейсы тестирования функционала изменения аватара завершены
При выполнении следующих команд запуска необходимо сначала настроить ip адреса сервисов в конфигурационном файле application.yml и авторизационный код для отправки электронной почты новым сотрудникам, например для почтового сервера 163.1) Команда запуска Redis: ./redis-server redis.conf
Проверка состояния запуска Redis: ps -ef | grep redis
Команда запуска RabbitMQ: systemctl start rabbitmq-server.service
Проверка состояния запуска RabbitMQ: systemctl status rabbitmq-server.service
Команда запуска трекера FastDFS: /etc/init.d/fdfs_trackerd start
(Если трекер настроен на автоматический запуск при старте системы, то данная команда не требуется)
Команда запуска ноды хранения FastDFS: /etc/init.d/fdfs_storaged start
(При условии, что трекер уже запущен, рекомендуется не использовать автоматический запуск данной службы)
Проверка состояния запуска трекера и ноды хранения: ps aux | grep fdfs
Команда запуска Nginx: /usr/local/nginx/sbin/nginx
Если Redis не настроен и не запущен, то вход будет невозможен, так как после входа система пытается получить данные меню, но из-за отсутствия запуска Redis, вход успешен, но страница открывается пустой
В местах, требующих изменений, были указаны IP-адреса с примечаниями 67. [Добавление процесса входа в систему в документацию Swagger]
Вызовите метод /captcha
контроллера CaptchaController
, чтобы получить капчу
Вызовите метод /login
контроллера LoginController
, передайте полученную капчу, имя пользователя admin
и пароль 123
. Получите возвращенный токен
Найдите Authorize
, добавьте полученный токен в значение параметра, добавьте слово Bearer
перед токеном, разделите их пробелом и нажмите Сохранить68. [Пояснение запуска проекта]
Клонируйте проект на локальную машину, откройте его в IDEA, создайте базу данных с именем yeb
, выполните скрипт файла yeb.sql
из папки database
, настройте источник данных в файле pom.xml
.
Запустите основной класс YebApplication.java
, откройте браузер и перейдите по адресу http://localhost:8081/doc.html
, чтобы открыть API управления.
Вызовите метод /captcha
контроллера CaptchaController
, чтобы получить капчу.
Вызовите метод /login
контроллера LoginController
, передайте полученную капчу, имя пользователя admin
и пароль 123
. Получите возвращенный токен.
Найдите Authorize
, добавьте полученный токен в значение параметра, добавьте слово Bearer
перед токеном, разделите их пробелом и нажмите Сохранить.
Теперь вы можете нормально использовать остальные интерфейсы, иначе будет сообщено "Вы ещё не вошли в систему, пожалуйста, войдите!".
pom.xml
родительского проекта.Module -> Maven -> maven-archetype-quickstart
.@MapperScan("com.xxxx.server.mapper")
.must-revalidate
в must-revalidate
.#### Как сделать вкладFeat_xxx
Feat_xxx
.Особая благодарность следующим участникам:
Благодарю следующих участников:
Используйте Readme_XXX.md для поддержки различных языков, например Readme_en.md, Readme_zh.md
Официальный блог Gitee blog.gitee.com
Вы можете https://gitee.com/explore посетить этот адрес, чтобы узнать о лучших открытых проектах на Gitee
GVP расшифровывается как "Gitee Most Valuable Open Source Project", что означает лучшие открытые проекты, выбранные по совокупности критериев
Официальное руководство по использованию от Gitee https://gitee.com/help
Проект "Обложка Gitee" представляет собой рубрику, которая демонстрирует достижения членов сообщества Gitee https://gitee.com/gitee-stars/
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )