From 5044753d7726f7b1aaac9101eeb0d9825c129b06 Mon Sep 17 00:00:00 2001 From: 21819 Date: Mon, 5 Feb 2024 19:38:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=96=E7=BD=91=E7=AE=A1=E7=90=86=E7=AB=AF?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E4=BB=A3=E7=A0=81=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/biutag/lan/service/WorkService.java | 2 + mailbox-outer-admin/pom.xml | 11 ++ .../biutag/outeradmin/config/LoginConfig.java | 24 +++ .../outeradmin/config/MyBatisPlusConfig.java | 19 +++ .../controller/HolidayController.java | 78 +++++++++ .../outeradmin/controller/JwtController.java | 49 ++++++ .../controller/LoginController.java | 74 ++++++++ .../outeradmin/controller/MailController.java | 149 ++++++++++++++++ .../outeradmin/controller/UserController.java | 90 ++++++++++ .../com/biutag/outeradmin/dto/HolidayDTO.java | 10 ++ .../biutag/outeradmin/dto/HolidayRefresh.java | 10 ++ .../biutag/outeradmin/dto/HolidayYear.java | 8 + .../biutag/outeradmin/dto/LoginFormData.java | 9 + .../biutag/outeradmin/dto/MailFormData.java | 16 ++ .../biutag/outeradmin/dto/MailFormPage.java | 10 ++ .../com/biutag/outeradmin/dto/MailID.java | 8 + .../biutag/outeradmin/dto/MailPageInfo.java | 12 ++ .../com/biutag/outeradmin/dto/PageSet.java | 10 ++ .../com/biutag/outeradmin/dto/TokenDTO.java | 14 ++ .../biutag/outeradmin/dto/UserFormData.java | 13 ++ .../biutag/outeradmin/dto/UserFormPage.java | 9 + .../biutag/outeradmin/dto/UserPageInfo.java | 13 ++ .../com/biutag/outeradmin/entity/Holiday.java | 11 ++ .../com/biutag/outeradmin/entity/Mail.java | 72 ++++++++ .../com/biutag/outeradmin/entity/User.java | 22 +++ .../exception/GlobalExceptionHandler.java | 14 ++ .../outeradmin/exception/TokenException.java | 14 ++ .../interceptor/UserLoginInterceptor.java | 68 ++++++++ .../outeradmin/mapper/HolidayMapper.java | 10 ++ .../biutag/outeradmin/mapper/MailMapper.java | 9 + .../biutag/outeradmin/mapper/UserMapper.java | 9 + .../outeradmin/service/HolidayService.java | 10 ++ .../outeradmin/service/MailService.java | 10 ++ .../outeradmin/service/UserService.java | 10 ++ .../outeradmin/util/DesensitizedUtil.java | 27 +++ .../com/biutag/outeradmin/util/ExcelUtil.java | 76 +++++++++ .../biutag/outeradmin/util/HolidayUtil.java | 161 ++++++++++++++++++ .../com/biutag/outeradmin/util/JwtUtil.java | 107 ++++++++++++ .../outeradmin/util/PhoneEncryptUtil.java | 22 +++ .../src/main/resources/excelmodel.xlsx | Bin 0 -> 9725 bytes 40 files changed, 1290 insertions(+) create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/LoginConfig.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/MyBatisPlusConfig.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/HolidayController.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/JwtController.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/LoginController.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/MailController.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/UserController.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayDTO.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayRefresh.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayYear.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/LoginFormData.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormData.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormPage.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailID.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailPageInfo.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/PageSet.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/TokenDTO.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormData.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormPage.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserPageInfo.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Holiday.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Mail.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/User.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/GlobalExceptionHandler.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/TokenException.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/interceptor/UserLoginInterceptor.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/HolidayMapper.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/MailMapper.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/UserMapper.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/HolidayService.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/MailService.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/UserService.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/DesensitizedUtil.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/ExcelUtil.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/HolidayUtil.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/JwtUtil.java create mode 100644 mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/PhoneEncryptUtil.java create mode 100644 mailbox-outer-admin/src/main/resources/excelmodel.xlsx diff --git a/mailbox-lan/src/main/java/com/biutag/lan/service/WorkService.java b/mailbox-lan/src/main/java/com/biutag/lan/service/WorkService.java index 170d9d2..467c975 100644 --- a/mailbox-lan/src/main/java/com/biutag/lan/service/WorkService.java +++ b/mailbox-lan/src/main/java/com/biutag/lan/service/WorkService.java @@ -51,6 +51,7 @@ public class WorkService extends ServiceImpl { .eq("w.sign_role_id", roleId) // 如果不是市局专班,则需要查询签收部门ID .eq(!RoleEnum.MUNICIPAL_DEPT_CLASSES.getRoleId().equals(roleId), "w.sign_dept_id", deptId)); +// .eq("w.sign_dept_id", deptId)); }) .ge(StrUtil.isNotBlank(todoQuery.getMailTimeStart()), "TO_CHAR(m.mail_time, 'YYYY-MM-DD')", todoQuery.getMailTimeStart()) .le(StrUtil.isNotBlank(todoQuery.getMailTimeStartEnd()), "TO_CHAR(m.mail_time, 'YYYY-MM-DD')", todoQuery.getMailTimeStartEnd()) @@ -87,6 +88,7 @@ public class WorkService extends ServiceImpl { /** * 查询未签收的信件 + * * @param mailId * @return */ diff --git a/mailbox-outer-admin/pom.xml b/mailbox-outer-admin/pom.xml index e460f29..36fdfd3 100644 --- a/mailbox-outer-admin/pom.xml +++ b/mailbox-outer-admin/pom.xml @@ -64,6 +64,17 @@ mailbox-common + + com.alibaba + easyexcel + 3.3.2 + + + io.jsonwebtoken + jjwt + 0.12.3 + + diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/LoginConfig.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/LoginConfig.java new file mode 100644 index 0000000..1ad0832 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/LoginConfig.java @@ -0,0 +1,24 @@ +package com.biutag.outeradmin.config; + +import com.biutag.outeradmin.interceptor.UserLoginInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class LoginConfig implements WebMvcConfigurer { + @Autowired + private UserLoginInterceptor userLoginInterceptor; + @Override + public void addInterceptors(InterceptorRegistry registry) { + InterceptorRegistration interceptorRegistration = registry.addInterceptor(userLoginInterceptor); + interceptorRegistration.addPathPatterns("/**"); + interceptorRegistration.excludePathPatterns( + "/login", + "/captcha", + "/refresh-token" + ); + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/MyBatisPlusConfig.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..d5f2f48 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/config/MyBatisPlusConfig.java @@ -0,0 +1,19 @@ +package com.biutag.outeradmin.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@MapperScan("com.biutag.outeradmin.mapper") +public class MyBatisPlusConfig { + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL)); + return interceptor; + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/HolidayController.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/HolidayController.java new file mode 100644 index 0000000..47dd443 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/HolidayController.java @@ -0,0 +1,78 @@ +package com.biutag.outeradmin.controller; + +import com.alibaba.fastjson2.JSON; +import com.biutag.outeradmin.dto.HolidayDTO; +import com.biutag.outeradmin.dto.HolidayRefresh; +import com.biutag.outeradmin.dto.HolidayYear; +import com.biutag.outeradmin.entity.Holiday; +import com.biutag.outeradmin.mapper.HolidayMapper; +import com.biutag.outeradmin.service.HolidayService; +import com.biutag.outeradmin.util.HolidayUtil; +import com.biutag.util.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@RequiredArgsConstructor +@RestController +@Api(tags = "节假日接口") +@RequestMapping("/outer/holiday") +public class HolidayController { + private final HolidayService holidayService; + private final HolidayMapper holidayMapper; + + @PostMapping("/refresh-holiday") + @ApiOperation("同步节假日信息") + public HolidayRefresh setlist(@RequestBody String year) throws Exception { + HolidayYear getYear = JSON.parseObject(year, HolidayYear.class); + HolidayRefresh holidayRefresh = new HolidayRefresh(); + LocalDateTime currentDate = LocalDateTime.now(); + + String currentYear = Integer.toString(currentDate.getYear()); +// String currentYear = "2025"; + if (getYear.getYear().equals(currentYear)) { + holidayRefresh.setMessage("success"); + } else { + holidayMapper.delete(null); + List holidays = HolidayUtil.getAllHolidayByYear(getYear.getYear()); + holidayService.saveBatch(holidays); + holidayRefresh.setMessage("success"); + } + holidayRefresh.setHolidayList(getlist()); + return holidayRefresh; + } + + + @RequestMapping("/show-holiday") + @ApiOperation("进入页面显示节假日") + public List getlist() { + List holidayList = holidayService.list(); + List result = new ArrayList<>(); + for (Holiday holiday : holidayList) { + if (holiday.getHolidayFlag().equals("Y")) { + HolidayDTO holidayDTO = new HolidayDTO(); + holidayDTO.setHolidayFlag(holiday.getHolidayFlag()); + holidayDTO.setDetail(holiday.getDetail()); + holidayDTO.setDate(holiday.getDate()); + result.add(holidayDTO); + } else if (holiday.getHolidayFlag().equals("N") && StringUtils.isNotEmpty(holiday.getDetail())) { + HolidayDTO holidayDTO = new HolidayDTO(); + holidayDTO.setHolidayFlag(holiday.getHolidayFlag()); + holidayDTO.setDetail(holiday.getDetail()); + holidayDTO.setDate(holiday.getDate()); + result.add(holidayDTO); + } + } + return result; + } + + +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/JwtController.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/JwtController.java new file mode 100644 index 0000000..0c42ff1 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/JwtController.java @@ -0,0 +1,49 @@ +package com.biutag.outeradmin.controller; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.biutag.outeradmin.dto.TokenDTO; +import com.biutag.outeradmin.entity.User; +import com.biutag.outeradmin.service.UserService; +import com.biutag.outeradmin.util.JwtUtil; +import io.jsonwebtoken.Claims; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class JwtController { + private final UserService userService; + + + @RequestMapping("/refresh-token") + public TokenDTO refreshToken(@RequestBody String reToken) { + TokenDTO tokenDTOReceived = JSON.parseObject(reToken, TokenDTO.class); + String token = tokenDTOReceived.getRefreshToken(); + log.info("refresh_token:{}", token); + try { + Claims claims = JwtUtil.parseJwtToken(token).getPayload(); + log.info("refresh token:{}", token); + log.info("claims:{}", claims); + String phone = claims.get("username", String.class); + TokenDTO tokenDTO = new TokenDTO(); + + User user = userService.getOne(new QueryWrapper().eq("phone", phone)); + // 如果用户存在,就生成一个新的令牌 + if (user != null) { + String refreshToken = JwtUtil.getNewRefreshToken(token); + String accessToken = JwtUtil.getNewAccessToken(token); + tokenDTO.setRefreshToken(refreshToken); + tokenDTO.setAccessToken(accessToken); + } + log.info("refresh token success:{}", tokenDTO.toString()); + return tokenDTO; + } catch (Exception e) { + throw new RuntimeException(); + } + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/LoginController.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/LoginController.java new file mode 100644 index 0000000..699ce1b --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/LoginController.java @@ -0,0 +1,74 @@ +package com.biutag.outeradmin.controller; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.biutag.enums.ErrorEnum; +import com.biutag.outeradmin.dto.LoginFormData; +import com.biutag.outeradmin.dto.TokenDTO; +import com.biutag.outeradmin.entity.User; +import com.biutag.outeradmin.mapper.UserMapper; +import com.biutag.outeradmin.service.UserService; +import com.biutag.outeradmin.util.JwtUtil; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@Slf4j +public class LoginController { + private final UserService userService; + private final UserMapper userMapper; + + private static String randomCaptcha = ""; + + + @RequestMapping("/login") + public TokenDTO login(@RequestBody String formData, HttpServletRequest request) { + LoginFormData data = JSON.parseObject(formData, LoginFormData.class); + TokenDTO tokens = new TokenDTO(); + if (!data.getCaptcha().equals(randomCaptcha)) { + tokens.setStateCode(ErrorEnum.CAPTCHA_ERROR.getCode()); + return tokens; + } else { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("phone", data.getAccount()); + User user = userService.getOne(queryWrapper, false); + if (user == null) { + tokens.setStateCode(ErrorEnum.LOGIN_ACCOUNT_ERROR.getCode()); + return tokens; + } else { + tokens.setAccessToken(JwtUtil.buildJwtToken(data.getAccount(), data.getCaptcha(), false)); + tokens.setRefreshToken(JwtUtil.buildJwtToken(data.getAccount(), data.getCaptcha(), true)); + log.info("refresh_token:{}", tokens.getRefreshToken()); + tokens.setStateCode(ErrorEnum.SUCCESS.getCode()); + return tokens; + } + } + } + + @RequestMapping("/captcha") + public String captcha(@RequestBody String formData) { + LoginFormData data = JSON.parseObject(formData, LoginFormData.class); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("phone", data.getAccount()); + User user = userService.getOne(queryWrapper, false); + if (user == null) { + return Integer.toString(ErrorEnum.LOGIN_ACCOUNT_ERROR.getCode()); + } else { + randomCaptcha = Integer.toString((int) ((Math.random() * 9 + 1) * 100000)); + System.out.println(randomCaptcha); + return randomCaptcha; + } + + } + + @RequestMapping("/logout") + public int logout() { + log.info("用户已登出"); + return ErrorEnum.SUCCESS.getCode(); + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/MailController.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/MailController.java new file mode 100644 index 0000000..25df790 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/MailController.java @@ -0,0 +1,149 @@ +package com.biutag.outeradmin.controller; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.biutag.outeradmin.dto.*; +import com.biutag.outeradmin.entity.*; +import com.biutag.outeradmin.mapper.MailMapper; +import com.biutag.outeradmin.service.MailService; +import com.biutag.outeradmin.util.DesensitizedUtil; +import com.biutag.outeradmin.util.ExcelUtil; +import com.biutag.util.StringUtils; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.List; + +@RequiredArgsConstructor +@RequestMapping("/mailbox") +@RestController +public class MailController { + private final MailService mailService; + private final MailMapper mailMapper; + + /** + * 查询所有信件 + * + * @return 信件列表json + */ + @RequestMapping("/list") + public MailPageInfo list(@RequestBody String req) { + PageSet pageSet = JSON.parseObject(req, PageSet.class); + Page page = new Page<>(pageSet.getCurrentPage(), pageSet.getPageSize()); + List mailPage = mailMapper.selectPage(page, null).getRecords(); + pageSet.setTotalSize((int) page.getTotal()); + MailPageInfo result = new MailPageInfo(); + result.setMails(mailPage); + result.setPageSet(pageSet); + return result; + } + + /** + * 根据前端表格数据查询指定信件 + * + * @param form 前端信件表单数据 + * @return 指定信件json + */ + @RequestMapping("/list-submit") + public MailPageInfo siftList(@RequestBody String form) { + MailFormPage mailFormPage = JSON.parseObject(form, MailFormPage.class); + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (mailFormPage != null && mailFormPage.getFormData() != null && mailFormPage.getPageData() != null) { + MailFormData mailFormData = mailFormPage.getFormData(); + if (StringUtils.isNotEmpty(mailFormData.getEvaluate())) { + switch (mailFormData.getEvaluate()) { + case "不满意": + mailFormData.setEvaluate("NOT_SATISFIED"); + break; + case "基本满意": + mailFormData.setEvaluate("BASICALLY_SATISFIED"); + break; + case "满意": + mailFormData.setEvaluate("SATISFIED"); + break; + } + } + + queryWrapper.lambda().like(StringUtils.isNotEmpty(mailFormData.getContactName()), Mail::getContactName, mailFormData.getContactName()) + .like(StringUtils.isNotEmpty(mailFormData.getContactPhone()), Mail::getContactPhone, mailFormData.getContactPhone()) + .like(StringUtils.isNotEmpty(mailFormData.getContactIdCard()), Mail::getContactIdCard, mailFormData.getContactIdCard()) + .like(StringUtils.isNotEmpty(mailFormData.getId()), Mail::getId, mailFormData.getId()) + .like(StringUtils.isNotEmpty(mailFormData.getContent()), Mail::getContent, mailFormData.getContent()) + .eq(StringUtils.isNotEmpty(mailFormData.getEvaluate()), Mail::getSatisfaction, mailFormData.getEvaluate()); + if (CollectionUtils.isNotEmpty(mailFormData.getDate()) && mailFormData.getDate().size() == 2) { + queryWrapper.lambda().between(Mail::getCreateTime, mailFormData.getDate().get(0), mailFormData.getDate().get(1)); + } + } + PageSet pageSet = mailFormPage.getPageData(); + + Page page = new Page<>(pageSet.getCurrentPage(), pageSet.getPageSize()); + List mailPage = mailMapper.selectPage(page, queryWrapper).getRecords(); + for (Mail mail : mailPage) { + mail.setContactIdCard(DesensitizedUtil.encryptIDCard(mail.getContactIdCard())); + mail.setContactPhone(DesensitizedUtil.encryptPhone(mail.getContactPhone())); + if (StringUtils.isNotEmpty(mail.getSatisfaction())) { + switch (mail.getSatisfaction()) { + case "SATISFIED": + mail.setSatisfaction("满意"); + break; + case "NOT_SATISFIED": + mail.setSatisfaction("不满意"); + break; + case "BASICALLY_SATISFIED": + mail.setSatisfaction("基本满意"); + break; + } + } + } + pageSet.setTotalSize((int) page.getTotal()); + MailPageInfo result = new MailPageInfo(); + result.setMails(mailPage); + result.setPageSet(pageSet); + + return result; + } + + /** + * 查询指定信件详情 + * + * @param id 信件ID + * @return 指定信件详情json + */ + @RequestMapping("/detail") + public String detail(@RequestBody String id) { + MailID mailID = JSON.parseObject(id, MailID.class); + //TODO 这里根据ID查询数据库,记得删掉 + Mail mail = mailService.getById(mailID.getID()); + mail.setContactIdCard(DesensitizedUtil.encryptIDCard(mail.getContactIdCard())); + mail.setContactPhone(DesensitizedUtil.encryptPhone(mail.getContactPhone())); + return JSON.toJSONString(mail); + } + + @RequestMapping("/exportexcel") + public void exportexcel(HttpServletResponse response, @RequestBody String form) throws IOException { + MailFormPage formPage = JSON.parseObject(form, MailFormPage.class); + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (formPage != null && formPage.getFormData() != null && formPage.getPageData() != null) { + MailFormData formData = formPage.getFormData(); + queryWrapper.lambda().like(StringUtils.isNotEmpty(formData.getContactName()), Mail::getContactName, formData.getContactName()) + .like(StringUtils.isNotEmpty(formData.getContactPhone()), Mail::getContactPhone, formData.getContactPhone()) + .like(StringUtils.isNotEmpty(formData.getContactIdCard()), Mail::getContactIdCard, formData.getContactIdCard()) + .like(StringUtils.isNotEmpty(formData.getId()), Mail::getId, formData.getId()) + .like(StringUtils.isNotEmpty(formData.getContent()), Mail::getContent, formData.getContent()); + if (CollectionUtils.isNotEmpty(formData.getDate()) && formData.getDate().size() == 2) { + queryWrapper.lambda().between(Mail::getCreateTime, formData.getDate().get(0), formData.getDate().get(1)); + } + } + + List mailPage = mailMapper.selectList(queryWrapper); + for (Mail mail : mailPage) { + mail.setContactIdCard(DesensitizedUtil.encryptIDCard(mail.getContactIdCard())); + mail.setContactPhone(DesensitizedUtil.encryptPhone(mail.getContactPhone())); + } + ExcelUtil.exportExcel(response, mailPage); + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/UserController.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/UserController.java new file mode 100644 index 0000000..a84b904 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/controller/UserController.java @@ -0,0 +1,90 @@ +package com.biutag.outeradmin.controller; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.biutag.outeradmin.dto.PageSet; +import com.biutag.outeradmin.dto.UserFormData; +import com.biutag.outeradmin.dto.UserFormPage; +import com.biutag.outeradmin.dto.UserPageInfo; +import com.biutag.outeradmin.entity.*; +import com.biutag.outeradmin.mapper.UserMapper; +import com.biutag.outeradmin.service.UserService; +import com.biutag.outeradmin.util.DesensitizedUtil; +import com.biutag.util.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@RequestMapping("/user") +@RestController +@RequiredArgsConstructor +public class UserController { + private final UserMapper userMapper; + private final UserService userService; + + @RequestMapping("/list-submit") + public UserPageInfo siftList(@RequestBody String form) { + UserFormPage userFormPage = JSON.parseObject(form, UserFormPage.class); + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (userFormPage != null && userFormPage.getFormData() != null && userFormPage.getPageData() != null) { + UserFormData formData = userFormPage.getFormData(); + + queryWrapper.lambda().like(StringUtils.isNotEmpty(formData.getRealName()), User::getRealName, formData.getRealName()) + .like(StringUtils.isNotEmpty(formData.getPhone()), User::getPhone, formData.getPhone()) + .like(StringUtils.isNotEmpty(formData.getIdCard()), User::getIdCard, formData.getIdCard()); + if (CollectionUtils.isNotEmpty(formData.getDate()) && formData.getDate().size() == 2) { + queryWrapper.lambda().between(User::getCreateTime, formData.getDate().get(0), formData.getDate().get(1)); + } + } + PageSet pageSet = userFormPage.getPageData(); + + Page page = new Page<>(pageSet.getCurrentPage(), pageSet.getPageSize()); + List userPage = userMapper.selectPage(page, queryWrapper).getRecords(); + for (User user : userPage) { + user.setIdCard(DesensitizedUtil.encryptIDCard(user.getIdCard())); + user.setPhone(DesensitizedUtil.encryptPhone(user.getPhone())); + } + pageSet.setTotalSize((int) page.getTotal()); + UserPageInfo result = new UserPageInfo(); + result.setUsers(userPage); + result.setPageSet(pageSet); + + return result; + } + + @RequestMapping("/add-user") + public String addUser(@RequestBody String form) { + UserFormData userForm = JSON.parseObject(form, UserFormData.class); + User user = new User(); + user.setRealName(userForm.getRealName()); + user.setPhone(userForm.getPhone()); + user.setIdCard(userForm.getIdCard()); + LocalDateTime createTime = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + user.setCreateTime(simpleDateFormat.parse(createTime.format(formatter))); + userMapper.insert(user); + return "success"; + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + @RequestMapping("/delete-user") + public String deleteUser(@RequestBody String id) { + User user = JSON.parseObject(id, User.class); + userMapper.deleteById(user.getId()); + return "success"; + } +} + diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayDTO.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayDTO.java new file mode 100644 index 0000000..e8d5973 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayDTO.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class HolidayDTO { + private String date; + private String holidayFlag; + private String detail; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayRefresh.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayRefresh.java new file mode 100644 index 0000000..0674b1d --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayRefresh.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +import java.util.List; +@Data +public class HolidayRefresh { + private List holidayList; + private String message; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayYear.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayYear.java new file mode 100644 index 0000000..501d721 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/HolidayYear.java @@ -0,0 +1,8 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class HolidayYear { + private String year; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/LoginFormData.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/LoginFormData.java new file mode 100644 index 0000000..0452a16 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/LoginFormData.java @@ -0,0 +1,9 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class LoginFormData { + private String account; + private String captcha; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormData.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormData.java new file mode 100644 index 0000000..3fdabc0 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormData.java @@ -0,0 +1,16 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class MailFormData { + private List date; + private String contactName; + private String contactPhone; + private String contactIdCard; + private String id; + private String content; + private String evaluate; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormPage.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormPage.java new file mode 100644 index 0000000..4cf9db8 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailFormPage.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class MailFormPage { + private MailFormData formData; + private PageSet pageData; + +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailID.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailID.java new file mode 100644 index 0000000..287365c --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailID.java @@ -0,0 +1,8 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class MailID { + private String ID; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailPageInfo.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailPageInfo.java new file mode 100644 index 0000000..db725dc --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/MailPageInfo.java @@ -0,0 +1,12 @@ +package com.biutag.outeradmin.dto; + +import com.biutag.outeradmin.entity.Mail; +import lombok.Data; + +import java.util.List; + +@Data +public class MailPageInfo { + private List mails; + private PageSet pageSet; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/PageSet.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/PageSet.java new file mode 100644 index 0000000..3bbca4e --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/PageSet.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class PageSet { + private int currentPage; + private int pageSize; + private int totalSize; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/TokenDTO.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/TokenDTO.java new file mode 100644 index 0000000..dddd225 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/TokenDTO.java @@ -0,0 +1,14 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; +import org.apache.poi.ss.formula.functions.T; + +import java.util.List; + +@Data +public class TokenDTO { + private String accessToken; + private String refreshToken; + private int stateCode; + private List list; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormData.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormData.java new file mode 100644 index 0000000..317a994 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormData.java @@ -0,0 +1,13 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class UserFormData { + private List date; + private String realName; + private String phone; + private String idCard; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormPage.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormPage.java new file mode 100644 index 0000000..3b5358a --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserFormPage.java @@ -0,0 +1,9 @@ +package com.biutag.outeradmin.dto; + +import lombok.Data; + +@Data +public class UserFormPage { + private UserFormData formData; + private PageSet pageData; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserPageInfo.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserPageInfo.java new file mode 100644 index 0000000..fcea549 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/dto/UserPageInfo.java @@ -0,0 +1,13 @@ +package com.biutag.outeradmin.dto; + +import com.biutag.outeradmin.dto.PageSet; +import com.biutag.outeradmin.entity.User; +import lombok.Data; + +import java.util.List; + +@Data +public class UserPageInfo { + private List users; + private PageSet pageSet; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Holiday.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Holiday.java new file mode 100644 index 0000000..9ab7eaa --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Holiday.java @@ -0,0 +1,11 @@ +package com.biutag.outeradmin.entity; + +import lombok.Data; + +@Data +public class Holiday { + private Integer id; + private String date; + private String holidayFlag; + private String detail; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Mail.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Mail.java new file mode 100644 index 0000000..a5697e3 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/Mail.java @@ -0,0 +1,72 @@ +package com.biutag.outeradmin.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.util.Date; + +@Data +public class Mail { + @TableId + private String id; + + /** + * 联系人姓名 + */ + private String contactName; + + /** + * 联系人性别 + */ + private String contactSex; + + /** + * 联系人身份证号码 + */ + private String contactIdCard; + + /** + * 联系人手机号码 + */ + private String contactPhone; + + /** + * 案件编号 + */ + private String caseNumber; + + /** + * 内容 + */ + private String content; + + /** + * 附件 + */ + private String attachments; + + /** + * 用户ID + */ + private Integer userId; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + +// /** +// * 评价 +// */ +// private String evaluate; + + /** + * 是否满意 + */ + private String satisfaction; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/User.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/User.java new file mode 100644 index 0000000..ed1fe55 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/entity/User.java @@ -0,0 +1,22 @@ +package com.biutag.outeradmin.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("\"user\"") +public class User { + @TableId + private Integer id; + private String openid; + private String nickName; + private Date createTime; + private String idCard; + private String realName; + private String phone; + private Date updateTime; + private Date faceAuthTime; +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/GlobalExceptionHandler.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..bf05848 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/GlobalExceptionHandler.java @@ -0,0 +1,14 @@ +package com.biutag.outeradmin.exception; + +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalExceptionHandler { + @ExceptionHandler(TokenException.class) + public String handleTokenException(TokenException e, HttpServletResponse response) { + response.setStatus(e.getCode()); + return e.getMessage(); + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/TokenException.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/TokenException.java new file mode 100644 index 0000000..d86f036 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/exception/TokenException.java @@ -0,0 +1,14 @@ +package com.biutag.outeradmin.exception; + +public class TokenException extends RuntimeException{ + private int code; + + public TokenException(int code, String message) { + super(message); + this.code = code; + } + + public int getCode() { + return code; + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/interceptor/UserLoginInterceptor.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/interceptor/UserLoginInterceptor.java new file mode 100644 index 0000000..371f557 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/interceptor/UserLoginInterceptor.java @@ -0,0 +1,68 @@ +package com.biutag.outeradmin.interceptor; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.biutag.outeradmin.entity.User; +import com.biutag.outeradmin.service.UserService; +import com.biutag.outeradmin.util.JwtUtil; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import java.util.Date; + +@Slf4j +@Component +public class UserLoginInterceptor implements HandlerInterceptor { + + @Autowired + private UserService userService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String token = request.getHeader("Authorization"); + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + try { + Claims claims = JwtUtil.parseJwtToken(token).getPayload(); + String name = claims.get("username", String.class); + Date date = claims.getExpiration(); + if (name != null && date != null && date.after(new Date())) { + log.info("用户{}已登录", name); + return true; + } + } catch (Exception e) { + if (e instanceof ExpiredJwtException) { + response.setStatus(401); + log.info("用户未登录或长时间未操作导致登陆失效"); + return false; + } + throw new RuntimeException("Token无效或过期"); + } + } + return false; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + if (ex == null) { + String token = request.getHeader("Authorization"); + token = token.substring(7); + Claims claims = JwtUtil.parseJwtToken(token).getPayload(); + String phone = claims.get("username", String.class); + + User user = userService.getOne(new QueryWrapper().eq("phone", phone)); + // 如果用户存在,就生成一个新的令牌 + if (user != null) { + String newToken = JwtUtil.getNewAccessToken(token); + // 将新的令牌添加到响应头中 + response.setHeader("Authorization", "Bearer " + newToken); + log.info("用户{}的令牌已更新", phone); + } + } + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/HolidayMapper.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/HolidayMapper.java new file mode 100644 index 0000000..99eb796 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/HolidayMapper.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.biutag.outeradmin.entity.Holiday; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface HolidayMapper extends BaseMapper { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/MailMapper.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/MailMapper.java new file mode 100644 index 0000000..66b4ba3 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/MailMapper.java @@ -0,0 +1,9 @@ +package com.biutag.outeradmin.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.biutag.outeradmin.entity.Mail; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface MailMapper extends BaseMapper { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/UserMapper.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/UserMapper.java new file mode 100644 index 0000000..de443cc --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/mapper/UserMapper.java @@ -0,0 +1,9 @@ +package com.biutag.outeradmin.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.biutag.outeradmin.entity.User; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface UserMapper extends BaseMapper { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/HolidayService.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/HolidayService.java new file mode 100644 index 0000000..f7de197 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/HolidayService.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.biutag.outeradmin.entity.Holiday; +import com.biutag.outeradmin.mapper.HolidayMapper; +import org.springframework.stereotype.Service; + +@Service +public class HolidayService extends ServiceImpl { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/MailService.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/MailService.java new file mode 100644 index 0000000..1ec9275 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/MailService.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.biutag.outeradmin.entity.Mail; +import com.biutag.outeradmin.mapper.MailMapper; +import org.springframework.stereotype.Service; + +@Service +public class MailService extends ServiceImpl { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/UserService.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/UserService.java new file mode 100644 index 0000000..d6835fe --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/service/UserService.java @@ -0,0 +1,10 @@ +package com.biutag.outeradmin.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.biutag.outeradmin.entity.User; +import com.biutag.outeradmin.mapper.UserMapper; +import org.springframework.stereotype.Service; + +@Service +public class UserService extends ServiceImpl { +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/DesensitizedUtil.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/DesensitizedUtil.java new file mode 100644 index 0000000..9d2fb4e --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/DesensitizedUtil.java @@ -0,0 +1,27 @@ +package com.biutag.outeradmin.util; + +import com.biutag.util.StringUtils; + +/** + * 身份证以及手机号脱敏处理工具类 + */ +public class DesensitizedUtil { + public static String encryptIDCard(String idCard) { + if (StringUtils.isNotBlank(idCard)) { + if (idCard.length() == 15) { + idCard = idCard.replaceAll("(\\w{6})\\w*(\\w{4})", "$1******$2"); + } + if (idCard.length() == 18) { + idCard = idCard.replaceAll("(\\w{6})\\w*(\\w{4})", "$1*********$2"); + } + } + return idCard; + } + + public static String encryptPhone(String phone) { + if (StringUtils.isNotBlank(phone)) { + phone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); + } + return phone; + } +} \ No newline at end of file diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/ExcelUtil.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/ExcelUtil.java new file mode 100644 index 0000000..d03b99d --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/ExcelUtil.java @@ -0,0 +1,76 @@ +package com.biutag.outeradmin.util; + + + + +import com.alibaba.excel.EasyExcel; + +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.fill.FillConfig; +import com.alibaba.excel.write.metadata.fill.FillWrapper; +import com.biutag.outeradmin.entity.Mail; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + + +import java.io.IOException; +import java.io.InputStream; + +import java.text.SimpleDateFormat; +import java.util.*; + + +public class ExcelUtil { + public static void exportExcel(HttpServletResponse response,List mailPage) throws IOException { + // 模板文件 +// String templateFile = "/excelmodel.xlsx"; + Resource resource = new ClassPathResource("excelmodel.xlsx"); + InputStream is = resource.getInputStream(); +// long date = new Date().getTime(); + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + System.out.println(formatter.format(calendar.getTime())); + String name = formatter.format(calendar.getTime())+".xlsx"; + String fileName = new String(name.getBytes()); + response.setContentType("application/octet-stream"); + response.setCharacterEncoding("utf8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName); + // 根据模板文件生成目标文件 + ExcelWriter excelWriter = EasyExcel + .write(response.getOutputStream(), Mail.class) + .withTemplate(is) + // 单独设置单元格格式 +// .registerWriteHandler(new CellStyleHandler()) + .build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + // 每次都会重新生成新的一行,而不是使用下面的空行 + FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); + // 第一种占位符替换 +// Map map = new HashMap(); +// map.put("reportDate", reportDate); +// excelWriter.fill(map, writeSheet); + // 第二种占位符替换,这里定义了 hisData + System.out.println(mailPage); + excelWriter.fill(new FillWrapper("mailPage",mailPage),fillConfig, writeSheet); + excelWriter.finish(); + } + +// +// private static List mailData(){ +// List resList = new ArrayList<>(); +// MailDto mailData = MailDto.builder() +// .contactName("today") +// .contactIdCard("34.211") +// .contactPhone("1.222") +// .caseNumber("34.211") +// .createTime(new Date()) +// .build(); +// resList.add(mailData); +// return resList; +// } + + + +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/HolidayUtil.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/HolidayUtil.java new file mode 100644 index 0000000..397b6e6 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/HolidayUtil.java @@ -0,0 +1,161 @@ +package com.biutag.outeradmin.util; + +import com.biutag.outeradmin.entity.Holiday; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; + +public class HolidayUtil { + + /** + * 发送get请求 + */ + private static String get(String url){ + StringBuilder inputLine = new StringBuilder(); + String read; + try { + HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); + urlConnection.setReadTimeout(30 * 1000); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setRequestProperty("Charset", "UTF-8"); + urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36)"); + BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8)); + while ((read = in.readLine()) != null) { + inputLine.append(read); + } + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return inputLine.toString(); + } + + + public static List getAllHolidayByYear(String year) throws IOException { + List allDateDayList = new ArrayList<>(); + +// SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); +// ArrayList holidayVoList = new ArrayList<>(); +// HashMap hashMap = new HashMap<>(); + + //查询全年日历包含周末 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + List allDateList = new ArrayList<>(); + LocalDate startDate = LocalDate.of(Integer.parseInt(year.trim()), 1, 1); + LocalDate endDate = startDate; + + while (Integer.parseInt(year) == endDate.getYear()) { + Holiday holiday = new Holiday(); + DayOfWeek week = endDate.getDayOfWeek(); + if(week == DayOfWeek.SATURDAY ) { + holiday.setHolidayFlag("Y"); + holiday.setDate(endDate.format(formatter)); + holiday.setDetail("周六"); + allDateDayList.add(holiday); + }else if(week == DayOfWeek.SUNDAY){ + holiday.setHolidayFlag("Y"); + holiday.setDate(endDate.format(formatter)); + holiday.setDetail("周日"); + allDateDayList.add(holiday); + }else{ + holiday.setHolidayFlag("N"); + holiday.setDate(endDate.format(formatter)); + allDateDayList.add(holiday); + } + + endDate = endDate.plusDays(1L); + } + + + //查询全年节假日、调休 + String holidayJson = HolidayUtil.get("https://timor.tech/api/holiday/year/"+year + "/"); + ObjectMapper mapper = new ObjectMapper(); + Map holidayMap = mapper.readValue(holidayJson,Map.class); + LinkedHashMap holidayList = (LinkedHashMap)holidayMap.get("holiday"); +// if(holidayList == null){ +// +// } + holidayList.forEach((key,value) -> { + Holiday holiday = new Holiday(); + Map value1 = (Map) value; + String dateTime = value1.get("date").toString(); + holiday.setDate(dateTime); + if(value1.get("name").toString().contains("补班")){ + holiday.setDetail("正常上班"); + holiday.setHolidayFlag("N"); + }else { + holiday.setDetail(value1.get("name").toString()); + holiday.setHolidayFlag("Y"); + } + + for(int i = 0;i { + Integer i = o1.getDate().compareTo(o2.getDate()); + return i; + }); + for(Holiday holiday : allDateDayList){ + System.out.println(holiday); + } + + return allDateDayList; + } + +// public static Map> HolidayHandle(List list){ +// Map> map = new HashMap>(); +// for(Holiday holiday : list){ +// HolidayVo holidayVo = new HolidayVo(); +// +// if (holiday.getDetail()==null){ +// continue; +// }else if(holiday.getDetail().contains("初")||holiday.getDetail().contains("元旦")||holiday.getDetail().contains("节")||holiday.getDetail().contains("周")){ +// holidayVo.setContent(holiday.getDetail()); +// }else if(holiday.getDetail().contains("正常上班")){ +// holidayVo.setContent(holiday.getDetail()); +// } +// String mouth = holiday.getDate().substring(5,7); +// holidayVo.setWorkingday(holiday.getDate().substring(8,10)); +// +// if (map.containsKey("mouth"+mouth)){ +// List listofmap = map.get("mouth"+mouth); +// listofmap.add(holidayVo); +// }else { +// List listHolidayVo = new ArrayList<>(); +// listHolidayVo.add(holidayVo); +// map.put("mouth"+mouth,listHolidayVo); +// } +// System.out.println(holidayVo); +// } +// return map; +// } + + + +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/JwtUtil.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/JwtUtil.java new file mode 100644 index 0000000..06ca814 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/JwtUtil.java @@ -0,0 +1,107 @@ +package com.biutag.outeradmin.util; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwsHeader; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SecureDigestAlgorithm; +import lombok.extern.slf4j.Slf4j; + +import javax.crypto.SecretKey; +import java.time.Instant; +import java.util.Date; + +@Slf4j +public class JwtUtil { + // TODO 正式上线以后需要修改accessToken持续时间 + public static final long EXPIRATION_TIME = 5; // 1h + public static final long REFRESH_TIME = 60 * 60 * 24 * 7; + public static final String APP_SECRET = "5FtX1OpGWKBVyaIh3dwRl04gkAzLro6U"; + public static final SecretKey KEY = Keys.hmacShaKeyFor(APP_SECRET.getBytes()); + public static final SecureDigestAlgorithm ALGORITHM = Jwts.SIG.HS256; + private final static String JWT_ISS = "admin"; + + private final static String SUBJECT = "Peripherals"; + + /** + * 构建双Token + * + * @param phone 用户手机号 + * @param captcha 验证码 + * @param ifRefresh 是否refreshToken控制参数 + * @return + */ + + public static String buildJwtToken(String phone, String captcha, boolean ifRefresh) { + Date exprireDate = Date.from(Instant.now().plusSeconds(EXPIRATION_TIME)); + if (ifRefresh) + exprireDate = Date.from(Instant.now().plusSeconds(REFRESH_TIME)); + return Jwts.builder() + .header().add("typ", "JWT").add("alg", "HS256") + .and() + .claim("username", phone).id(captcha) + .expiration(exprireDate) + .issuedAt(new Date()) + .subject(SUBJECT) + .issuer(JWT_ISS) + .signWith(KEY, ALGORITHM) + .compact(); + } + + /** + * 在accessToken发送过来时刷新refreshToken + * + * @param Token + * @return + */ + public static String getNewRefreshToken(String Token) { + Jws data = parseJwtToken(Token); + String name = data.getPayload().get("username", String.class); + String captcha = data.getPayload().getId(); + return buildJwtToken(name, captcha, true); + } + + /** + * accessToken过期时依据未过期的refreshToken刷新accessToken + * + * @param refreshToken + * @return + */ + public static String getNewAccessToken(String refreshToken) { + Jws data = parseJwtToken(refreshToken); + String name = data.getPayload().get("username", String.class); + String captcha = data.getPayload().getId(); + return buildJwtToken(name, captcha, true); + } + + /** + * 解析Token + * + * @param token + * @return + */ + public static Jws parseJwtToken(String token) { + return Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token); + } + + /** + * 解析Token中的header + * + * @param token + * @return + */ + public static JwsHeader parseTokenHeader(String token) { + return parseJwtToken(token).getHeader(); + } + + /** + * 解析Token中的payload + * + * @param token + * @return + */ + public static Claims parsePayload(String token) { + return parseJwtToken(token).getPayload(); + } +} diff --git a/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/PhoneEncryptUtil.java b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/PhoneEncryptUtil.java new file mode 100644 index 0000000..fae2d89 --- /dev/null +++ b/mailbox-outer-admin/src/main/java/com/biutag/outeradmin/util/PhoneEncryptUtil.java @@ -0,0 +1,22 @@ +package com.biutag.outeradmin.util; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; + +public class PhoneEncryptUtil { + private static final String KEY = "D9ioYl2WCeVRfLXvg4FrqZ51UtT8Ewcz"; + + private static AES init() { + String result = ""; + byte[] key = SecureUtil.generateKey(KEY).getEncoded(); + return new AES(key); + } + + public static String encrypt(String phone) { + return init().encryptHex(phone); + } + + public static String decrypt(String phone) { + return init().decryptStr(phone); + } +} \ No newline at end of file diff --git a/mailbox-outer-admin/src/main/resources/excelmodel.xlsx b/mailbox-outer-admin/src/main/resources/excelmodel.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9e4f9fa16162107f4f2d619f54075d91a1e087a1 GIT binary patch literal 9725 zcma)Cbyyrt(kHlkfZ*=7xNDZ+4#C}B7Kh;O?h+C_xCe(|!QBZ?2<{sAAh~;md+(mF z|LECgwxs7*Q`J3HB`*a52@m!(f@Rl)p058MaF0KXYz^fdZ0#JG)vLUM5OYh~;`{z948t1oX8dqB96ADd8ye8xaUJI+%kw&B7rVztcjuwb)_z_e z@1HX=uF~J^lqPq5m*0f|>_8~&K{xq*L5tMx%*m=u&du?+J^>=iAso!8|J)&#*h%VY+(KWPnFn)qJGOkj#iy0H>LVizjlEo!~ z08S@CA(UAd@ER>-s7hB!bnSH=$vzV?rI^V(u+Sp(Y>1yo86S~^nVD~vZleyo9N08A zQXNqw!$o?ik32VgjG(YtBFDNxdxXSq@MyV*;NbuoeqtYtT&N5v^aK4^RT6R{!1mSR zCIb=yX?RNL5$x%rvbClJ<6+ezo0GEzlJ*jF3^Ff*Tic=?nG=*m?U6tOQ6U`S!#qZA z1y#`PuYwRAV#LG%BSelnZgtX2Etq4}k8FK<$$KdhKCGsa_!cP*hr`>a zoU&kBM&)hajVhu%y1iHmxCMNok@9!$7BuC2w1c5tJQL;gQ2tA4FhLEE`ii21@xQM(Q^n+!~$V)k?cLF87DuYTc=6q z7+Z(CbS@n9hl)3g;Bl0fBZsk`FaB-{)Ohbm+DB8MJ(>dJZ>Df^1ld|Y86z)N+tQyI zGw2ZJ7KP*zK%`m%WDwKDX;RbIwhcD3f{G6bUHUrftt&Ybsl8{?#FvpAyv=axTIh^}~L^3*`6G@F>&B z2oW+~s8uXknsoK%=hSq&J@(N~3(mFFPW%$@=}iIx8nPm$(2;bxTvr*QF3S7FW=wgj z7qXxW(kZf!FwFAy(=b~Tg%y%sz@ch(L*)iIVBQ|%$A+Nxs8>dvPVqu^aSsy9CxWI9 z!!ivC_H&7JA_!QAx5wz=%~7xKBZhF8X!=k2jJ}{uC%hR+puFPES}Exf47@8D{kiVH zJ11ScsWijM3%EZrB-aaJ8R4J$Kw`YXiRalmy_q}*^91cbhZ=}SXkD#-1(|;)K>khO zV(Vb(Xl85-dLEEuW~FWl9&I!Y4F-nuAGE(%0KYs(Wx-~h7}ZPH{Gns5rS)SYo$M5) zj7y$&(flrJ$2#OoJf@h2pSMvY&i2(|Uqun|w+1s(ed%qo5YX_2%^3$0$n~YcsZ$4C z8>RXWb<;~|;A-9*iv`k?P%!2651pJA02!v@mmyNXUP)%gwE(90!q^r>g`KGBsL}fK zXbU^?=7FCTg;*_>L(EWn*9&u+$)ohk1UgAhGg#H6oT+ozqF(#vK(Ehu=?XAS#hqWz>&hfZ08O1QMBX5RpEV$j6O$KH6s^ zH|;b$Av`Ge&F6KMGN*-phz{vt@Sun`;f{1(AwNF>UfHYm zF(#1_fj8o6#M?B4RQraU{I#%FOoP3UP@d|V;(b~mDYfDQRMvj~7g_vVtbiN~S=Ov? z9`A_SF7IOL-V%|sadm5Of=zq{D!j~bL=f@DQpfTa# zh;a2kdan-OClb^oBPcWqPsi>4&}B?Uh{!kQr^-eQlb}nq$a9weJ_ANOW1s0>FkSTW zh7AlUcqPBGd#q8jye5r%8a(w)^ue%A0_ex7q!E<8HP3G*~c8&>eJt1oL44jqml&7c9@~ zp#pEubA_YZiE>?m`^9K%j{D?8!Talikvk#k+&myttLw>bH5F6q-A27Fk;e)QK9ZGd zHn|!k=aITyIK@gja)c!};n7U|_uddLbZY1&!YP7RyzO|7ue};5o&8;cMIVk{ln)*7 z)?F9~#D8HuJ?FCb>5UkpTwey$dh4i;b}%v?>g^yPyu#e6>g>jDcn=eq*$PYEAdas zuxUWxQUBt`N_pbh?x?_>xnTb37odYgzCh-i5CGns$%JY|++gs2EL&YAQ3#DZCKQ$Q z%}VcJDe5`0o6t@V=o`tb#N~yU9Uf1C^>`fdkAVme2R9_v;IizLhVUe8F@>?idH&v$+dqNm+V@VdoS-w1eNxyzi=S6}2ti^loKh(gc9a zYhSS~Shrlu-gz7X-q%oVV-mr&{KTrbiTKQ17;q+xfelkhAM{40CugZchKtsSl5~a* zO}GaVAEhg@coK$3$|kCJ%T>Mj?FTb}uRvU9fcxiAfg(obq`^?f4?2dqaWAA0{PoCC z+b`auCGCn4%EE-K#j*gBD}GjF>rNE71|eiKCY0D=K14UyMQ{ zlwns{rd_|69pi#5F?+|rr8T+NCeKMBx74g)aiusv7n)y!VG@%y8XBf_eJI;g4SCVI=6GCP<%VeL-bdd1_>RBT}e@aW>{pR z+9?L2#@LiQY--bfB|2|w$}O|(`SMX=8@L1LIw3Yg(ohdj-W)m5c=IV(t9sNP)ql#+ zI)6Kew;I^&w57u5<2YMyViMZ%vgM`SSt?PaWK-+p?Y~Sl^F)cRUl$)3ht+n z;N!d7hrMMr;GdqHq2?c|0dI}Vv#X8oW~iYD*YV8wTOx*~?1l$Qgm27skb=Ye8ii2iwfDN6?Ae7kFe7}upRyWKhj{jn4g z=~QX6K!auTSaBkwGq`iYTkyJ!L4b^UGwes>d51}M>s4aA4y1C+`MUjHNpcH>S~~mN zUF#RK@*j(58!=lfPlus4RMing*Sjy|s(}xsdJjD+;K>qzu z3zfTk%8UpG7Of2ihV*-*a0Izo89P3mke0M8qw(Ipx{vzejl=DS0&7~{ zvSZZtplj8!@!}`U=-%xX!EOG_YOhV#71(nkHT0i!^&-@;)v&Ej5L60_r z6l4zOpRf;BEpafoPNd`2{rR4EqQ*-GH;RC^=4Jn62Ow;uO%uQTdj1j8>NqEpcAO1-`TK1m)g4=1Z^J$4 za+NL=tu;-~z%ZQf+-uruPtn{5uVZS@obHeBa`W=vA?ji(ie##g#<{DfRYo`KHRv|R z*?#005X_^$&>7@Ew=^={I^_Nuq5yKKyFG}3RF5V8`h94)?jgx;0F;x~M=hc~W6w_l zRwJ5loc^A>q7yxSLYLqB0xX$_g`bF4LcGx8J3$$#LccGP50I%_UhL`tCvi>u6q&a) zOkezHgc)^8D|TE2l0#Szqgo@O9e-Ek7Ry{a*x3}r-o&o}D~DrxqeQY z2q^+|G@!iB>J-O()@cAlNfzl~qI`&j{~2GoILLzSM_*%jF}Qj@kV_bRYI8N<#F%_^ z)_PA0p>)HMp6#d&_?eCBT}kypURr>k3STetcd`C(B+V%179@ra5li8+3U}-4B;cwB z^^uzx0~S_8(~9WG7w3$RqQ%99<>0o?b?+VV)s{znm_*Jz*Nq_g6G_h26%sMJ92_Ny z+_yqMt#IVw_#W~&qnO*z_Wb<7RWGDsTOYe9d*;u-r{0SNO4)6YBUgmSR$)|9Z7SWR zi_60~s>fAtVn2JF_iud11k@twg~SYeG4e8ZqmA>`*o#$-F7tWx7JBu!?i^IMUcNyPBG|;ZgyS!%4B3_oe)9Q(A9pp-1I8nupEv6iA+I;y{0DT6J?5H^weXUQFwpyu9XM?LM6h8D}6r zEZgLoQAqpwPOyIkS8}!2%R(5h4mYP;w#FoiP(PQ&9dW|x%Gh)PwAZ!Tj@yY|yb0xu z&Cu?=TJo|ijquWR*1|Q^olv&}KQaRYV#9D}l~dl=bD@g?^|}>rS6D~;bg}&hwCgUU z2E{vbm1B!bu|jx;yF0zat|HfmZZR&EE=?W|5tZU9(uWf|OPmMWXc&S4)}vM;#kUbE zZy6;GH@1exQzS!j_#{GBJTi(|JO@8kQ;^etEubE-Ns?2jTB48C|LWMq7Bt6O)&sW2 zx5(0{-`EfsS`cRm>qx1E^u8zYORzewh&%PCRrt?umFq;7k_!*~@gxKSGh#j*JH%2e zNf4e9OA6QOW-BW14pY~v$|)dmaRs}=j}P7OB~F2h1obO?Rnsr?f4KsA0miY$S=er@ z5Nokcoc6l=POGZ^uH#iAzfrNe|Mw(iiDF~_tEbD3PllEvMbR`k#SYRadX=+8?MHA% zR?$>N6*~>7e1Cab26HWzNJsNpBaK}}bBQ<2%}6Mv#%`K~xXC&860B&Y6nx3bQnYJ! zCuSHm^tKD4KrNcb*;0MEF1W|oZGli@;G~Wp^krb-VpJoke*Zlg@(5ncR7W|*R9skt z#v|2qRkJlppp?_Tb+mYSU-0hf_ud%{mR{$(X@ zI>(#xw#QE*POK1g0ErJbrfliQUEr38W5>wmtwUgMy4$S4S;GL+n z@3tv5dfDv=p*Q4L8CyYW!M zZR;lWKoO8KQ`e$i6bg)y8(R~`3{CDVotW@mPG7#a zrAHpr$M5W(+!(9=$d}HJ$w*F_ok6*&&PJ`pmhtU=?zBJ-9UTh+9vdNkM1cRcm!SP> zqrdAE<(uH`W-nx&T|j(gsAlNP9ZM0FKI1L}D0jFFYKzmkiYtZ2tD+IpE(7>^^(YQ} z$2j+*igv&CYJBKa9f{eMVe}3)SGg}%c>`zg`dw?Xn`?{{bOA_w3g_yZU4Y0$@?#%7 z9B3_16ZgOheL#r=Absa$XArRLE6^tYEi4{ZBQAC${wMNO6=MLx%w030>f^oY3aE%K z$|o`5TC-<;`tdu70Z0wL$hAE~QTXLT(w!I3OU|!-W!4QiFrJ9iBg5yU%TYP#9oQKi zSX)G9eZ0*+H1ut{LJ?!RL8*-)Hlz$at73lfq)}(LBi(8Ov>m`e)$QP8FJ!ms)g^uPa z|KzfIPp8vyH=Eoo^fL_ge*B8OnrE!Nqmiz9BaJkrNKW!pq>-l%{D-XoZ2X=&WM!cp zBeRq`l{re1PRAM&-8{%W_QHZa(Tnj2o!zy+&8|9rfC9T%7wZjnQ9brCdNKRxA@XQo z{Z+d*O9AqFQPvb^udE%}b)^c)$P6EX4TXyBf%BL;56%~0Uin=8B3QMBN}r>ehJ@q< z=?Awn{Asc;7}=0vvW{J@kTx4jxC?e?hg9rd-sQ{6^HXX0mMZ&t4>_MTlhafrEOueo zMOi>VFT5V~FMSX&WmVoQ!#rDr$4Rv zB50F;W+NmuO*~l0BC63g<@3>uB(pvmbTyJaeyJ`ZSGX*j8LSd(6c?m5Uy8P>yE$4#q}GAO~|B(_dd0fpJ5UT|%fn zhkl2s7dG`_A>wg_@P5hTqFz4iuhIjJ>P@I}LxTOnNOR>Yl4&o92_ZdVvGBT+CB|>C z%BV?&$Jd81hei&f)aMX94Y5VK^D6obilh-yqd<*j8b;NXtre1pfzl0w$>8)=C}GNb z*W5}pY@jlEtYcJ7%LLk9f1jc_E8kHg&7c>eUWn<+wIX_DCt%D+JBp3XA`m@L0Q^^Q zlU~W8XmG60t|$^K(O9C(9$ByP^-OCB`^*-rfbD%f-8LxwXhLy>Uwt0F9S~ zd$RHJj<~OTpY2=$Lcitv*O|mOISa@|=kVrH_3lhaWy!$2k>E@FlDSuxYzlLe^)8eB z{l<4HA+sYeWCZg394shJR4fTaV#kV}FexuhC%K1(Jp(+O#J~eY6i6(bFp{?m?#wNc z-fYF3-S^Kv>AVRy=>{HgUw+J_qx{DGDOYY_Yis!{?X9G3o6d~sm0k0ocb$nN-UkL% zEbpgUR8-6+Q(w>zf$<3!Z*I7cZNF_q$c)!1&GmC@?>6B#rt-33b_l@`W#uDS9#%Z? zPDcg#cM&V=0@a?d2|dm2(st+_*{?fFuGWK9=r&GWNV0sl*#*T1yHO+|n~=JoXVZk*%>-PQS_e%L zQkzfFEjQ-mHKXohFo2ACzBjd+&-r*!o~fCWnKJFmBDchTzt#Kbj^LWTAv%NC%hp`Y zNr~c^M8Xc^ro`3KiIZfQ^i66sH4BHU4iALrFkLTsiIqVfxl;b+6vKnCVVcyD#c~z0 zE|Gj7a5Hai@pj|m3?9=hzwGKFP12#5!h{w)g(Uv~Ffxdy8Lx2tgFu>|SDcC5+Efmf zvzfE7Zo2~*W8TBLP=i#HBIDQtnLrA^u@NaZuQa*NH|xuV(8YzJ`voPA#O7tn9d{n@ zmW9%`15Vu@s!>6_u))D0hsgLh>oXA#VE;We{8;(`({(VmdR`mx;Bsz$c>M3%qfa9I zLBse&SsFJY`Gpy^=gAefT4h{bqRoMrNcUunynIrmA4VxL;?(zBTZ9$pCqKhPr(SQR zfAchI!doKN0pv$D`#CB23EB2Jw<;WYx~eVtiGOODf^bu|>x69jabj>A;J?L}FwaOH ztL>>c$`Z^=6K_7Yqbx6!&C3of;1)C_^XF)>k+=DJBG!{lC@;g;y-XY8(FASJ71(@j zYg@cKyuzRQL3D(bZbLaX)5$94WrV-yhuJpNb09P{_lSd&z`&u4Wbmg_69y!pR$z)! z*y5&En>~GMua+!P7)8#|wa~=Gc4tTIm}bp@I8OjY?(PFQOYfJBBsT$eU2%sKh7yMORBsEzBL1PbRl%r3mQ%gCcXG;?f0llLPI8OrRYoJUM zSVy|YZ;$Z&Joj-}ExK41n!lxz54MllcxW+HsYU*ldwT#lN`#e(l=&{m-S0}?!!gwd zjkPHqBCH$iru8zYS60U{Kjp0SYAEfPp0|_RE6$xKTobW74Y434YLfV5(4HpNN{R;? zr{&6i^I0vT@L0pq^f4YGJ=PCTQx2sUxS#uXlFZ1%JMt9$fD5$7xs-vm*CmIZhN?EK@_9245N5Gxjgkr z_gw9Ttb5+lCljLhsv zlJ=@09b+DLMRi~_X}9%g;bm-*T2V~ZK;ppX>rkebrp31RUI%Yur0wr$%S!PK`Pj|O_L z3ocKGE4pfE&cDL%53g)9h|GHx?<}9U#@4mbH=lN#8gkr0%S*ig$NaSy|8CuQZkb2p zfV}`Cew@W0r+={1Zvp>YmVF92zsFM-NCm;40qE~apNF6)p5IC*|KR!MGXG22lTZF0 zPs*OgU%FHNuJ3t&$`kQ#eN=yC`&YNhbBLbzU;N1(`1nfyq4eL~7|+?C_YC~Wj{3Me z|H=MG2f_b(=%>o~@A34|mXN>V&HrNfJ4$zie+f{}7y3MsJ?Z(45*g87*#0A~J(u(R z(D$btp~nFEPe;J#5}s$I|CF%#n4o@=@JD|7|NrcXFuz#;T`K+i8}htZ`lrU`zq0*V zI(@$6=O?Z|1vKFO()(A~{@0?PS{r_kCksdXw(t}4AB_%wU-|P^hbP|OR%`eV-ai{3 W