21 changed files with 382 additions and 114 deletions
@ -0,0 +1,68 @@ |
|||||||
|
package com.biutag.lan.controller; |
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil; |
||||||
|
import cn.hutool.crypto.digest.MD5; |
||||||
|
import cn.hutool.http.HttpUtil; |
||||||
|
import com.alibaba.fastjson2.JSON; |
||||||
|
import com.alibaba.fastjson2.JSONObject; |
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.biutag.config.Minio; |
||||||
|
import com.biutag.core.AjaxResult; |
||||||
|
import com.biutag.exception.AuthException; |
||||||
|
import com.biutag.exception.BusinessException; |
||||||
|
import com.biutag.lan.domain.MailSource; |
||||||
|
import com.biutag.lan.domain.bo.MailApiV1Req; |
||||||
|
import com.biutag.lan.service.MailSourceService; |
||||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||||
|
import jakarta.validation.Valid; |
||||||
|
import jakarta.validation.constraints.NotNull; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import org.simpleframework.xml.core.Validate; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
@RequiredArgsConstructor |
||||||
|
@Validate |
||||||
|
@RequestMapping("/v1/") |
||||||
|
@RestController |
||||||
|
public class ApiV1Controller { |
||||||
|
|
||||||
|
private final MailSourceService mailSourceService; |
||||||
|
|
||||||
|
private final Minio minio; |
||||||
|
|
||||||
|
private final String key = "mailbox"; |
||||||
|
|
||||||
|
@PostMapping("mail") |
||||||
|
public AjaxResult<Void> addMail(@RequestBody @Valid MailApiV1Req mail, HttpServletRequest request) { |
||||||
|
validAuth(request); |
||||||
|
if (mailSourceService.exists(new LambdaQueryWrapper<MailSource>().eq(MailSource::getId, mail.getId()))) { |
||||||
|
return AjaxResult.success(); |
||||||
|
} |
||||||
|
if (StrUtil.isNotBlank(mail.getAttachments())) { |
||||||
|
List<JSONObject> attachments = JSON.parseArray(mail.getAttachments()).toList(JSONObject.class); |
||||||
|
for (JSONObject attachment : attachments) { |
||||||
|
//minio.upload(IOUtil.base64ToStream(attachment.getString("base64")), attachment.getString("filepath"), true);
|
||||||
|
attachment.remove("base64"); |
||||||
|
} |
||||||
|
mail.setAttachments(JSON.toJSONString(attachments)); |
||||||
|
} |
||||||
|
mailSourceService.saveBatch(Collections.singletonList(mail.toMailOuter())); |
||||||
|
return AjaxResult.success(); |
||||||
|
} |
||||||
|
|
||||||
|
private void validAuth(HttpServletRequest request) { |
||||||
|
String authorization = request.getHeader("Authorization"); |
||||||
|
String timestamp = request.getHeader("timestamp"); |
||||||
|
if (StrUtil.isBlank(authorization) || StrUtil.isBlank(timestamp)) { |
||||||
|
throw new AuthException(); |
||||||
|
} |
||||||
|
if (!authorization.equals(MD5.create().digestHex(key + timestamp))) { |
||||||
|
throw new AuthException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -1,82 +0,0 @@ |
|||||||
package com.biutag.lan.crontab; |
|
||||||
|
|
||||||
import cn.hutool.core.date.DatePattern; |
|
||||||
import cn.hutool.http.HttpResponse; |
|
||||||
import cn.hutool.http.HttpUtil; |
|
||||||
import com.alibaba.fastjson2.JSON; |
|
||||||
import com.alibaba.fastjson2.JSONObject; |
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
||||||
import com.biutag.constants.AppConstants; |
|
||||||
import com.biutag.lan.domain.MailSourceEtl; |
|
||||||
import com.biutag.lan.domain.bo.MailOuter; |
|
||||||
import com.biutag.lan.service.MailSourceEtlService; |
|
||||||
import com.biutag.lan.service.MailSourceService; |
|
||||||
import lombok.RequiredArgsConstructor; |
|
||||||
import org.springframework.scheduling.annotation.Scheduled; |
|
||||||
import org.springframework.stereotype.Component; |
|
||||||
import org.springframework.transaction.annotation.Transactional; |
|
||||||
|
|
||||||
import java.time.LocalDateTime; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Optional; |
|
||||||
|
|
||||||
@RequiredArgsConstructor |
|
||||||
@Component |
|
||||||
public class MailSourceJob { |
|
||||||
|
|
||||||
private final MailSourceEtlService mailSourceEtlService; |
|
||||||
|
|
||||||
private final MailSourceService mailSourceService; |
|
||||||
|
|
||||||
// @Scheduled(fixedRate = 60000)
|
|
||||||
@Transactional(rollbackFor = Exception.class) |
|
||||||
public void extractMailSource() { |
|
||||||
System.out.println("extractMailSource------------"); |
|
||||||
MailSourceEtl latestEtl = mailSourceEtlService.getLatestSuccess(); |
|
||||||
LocalDateTime beginTime = Optional.ofNullable(latestEtl).map(MailSourceEtl::getEtlTime).orElse(LocalDateTime.of(1970, 1, 1, 0, 0, 0)); |
|
||||||
LocalDateTime now = LocalDateTime.now(); |
|
||||||
int current = 1; |
|
||||||
int size = 10; |
|
||||||
Page<MailOuter> mailOuterPage = pageMailOuterByCreateTime(current, size, |
|
||||||
beginTime.format(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter()), |
|
||||||
now.format(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter()), |
|
||||||
new ArrayList<>()); |
|
||||||
// 保存记录
|
|
||||||
if (mailOuterPage.getTotal() > 0) { |
|
||||||
mailSourceService.saveBatch(mailOuterPage.getRecords()); |
|
||||||
mailSourceEtlService.save(new MailSourceEtl().setEtlTime(now).setSuccess(AppConstants.YES).setTotal(mailOuterPage.getTotal())); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public Page<MailOuter> pageMailOuterByCreateTime(int current, int size, String beginTime, String endTime, List<MailOuter> records) { |
|
||||||
String url = String.format("https://mailbox.biutag.com/api/api/mail?current=%s&size=%s&beginTime=%s&endTime=%s", current, size, beginTime, endTime); |
|
||||||
HttpResponse httpResponse = HttpUtil.createGet(url) |
|
||||||
.auth("chuangke") |
|
||||||
.execute(); |
|
||||||
if (!httpResponse.isOk()) { |
|
||||||
|
|
||||||
} |
|
||||||
JSONObject data = JSON.parseObject(httpResponse.body()); |
|
||||||
Long total = data.getLong("total"); |
|
||||||
records.addAll(data.getList("records", MailOuter.class)); |
|
||||||
if (total <= records.size()) { |
|
||||||
return new Page<MailOuter>().setTotal(total).setRecords(records); |
|
||||||
} |
|
||||||
return pageMailOuterByCreateTime(++current, size, beginTime, endTime, records, total); |
|
||||||
} |
|
||||||
|
|
||||||
public Page<MailOuter> pageMailOuterByCreateTime(int current, int size, String beginTime, String endTime, List<MailOuter> records, long total) { |
|
||||||
String url = String.format("https://mailbox.biutag.com/api/api/mail?current=%s&size=%s&beginTime=%s&endTime=%s", current, size, beginTime, endTime); |
|
||||||
HttpResponse httpResponse = HttpUtil.createGet(url) |
|
||||||
.auth("chuangke") |
|
||||||
.execute(); |
|
||||||
JSONObject data = JSON.parseObject(httpResponse.body()); |
|
||||||
records.addAll(data.getList("records", MailOuter.class)); |
|
||||||
if (total <= records.size()) { |
|
||||||
return new Page<MailOuter>().setTotal(total).setRecords(records); |
|
||||||
} |
|
||||||
return pageMailOuterByCreateTime(++current, size, beginTime, endTime, records); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -0,0 +1,92 @@ |
|||||||
|
package com.biutag.lan.domain.bo; |
||||||
|
|
||||||
|
import com.biutag.lan.domain.MailSource; |
||||||
|
import com.biutag.validator.annotation.IdCard; |
||||||
|
import com.biutag.validator.annotation.Phone; |
||||||
|
import jakarta.validation.constraints.NotBlank; |
||||||
|
import jakarta.validation.constraints.NotNull; |
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import org.hibernate.validator.constraints.Length; |
||||||
|
import org.springframework.beans.BeanUtils; |
||||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
@Setter |
||||||
|
@Getter |
||||||
|
public class MailApiV1Req { |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
@NotBlank |
||||||
|
private String id; |
||||||
|
|
||||||
|
/** |
||||||
|
* 联系人姓名 |
||||||
|
*/ |
||||||
|
@NotBlank(message = "请输入联系人姓名") |
||||||
|
private String contactName; |
||||||
|
|
||||||
|
/** |
||||||
|
* 联系人性别 M / F |
||||||
|
*/ |
||||||
|
private String contactSex; |
||||||
|
|
||||||
|
/** |
||||||
|
* 联系人身份证号 |
||||||
|
*/ |
||||||
|
@IdCard |
||||||
|
private String contactIdCard; |
||||||
|
|
||||||
|
/** |
||||||
|
* 联系人手机号 |
||||||
|
*/ |
||||||
|
@Phone |
||||||
|
private String contactPhone; |
||||||
|
|
||||||
|
/** |
||||||
|
* 案件编号 |
||||||
|
*/ |
||||||
|
private String caseNumber; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内容 |
||||||
|
*/ |
||||||
|
@Length(min= 10, max = 300, message = "信件内容不符合规范(不少于10字,不多于300字)") |
||||||
|
@NotBlank(message = "请输入信件内容") |
||||||
|
private String content; |
||||||
|
|
||||||
|
/** |
||||||
|
* 附件 |
||||||
|
*/ |
||||||
|
private String attachments; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建时间 |
||||||
|
*/ |
||||||
|
@NotNull |
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||||
|
private LocalDateTime createTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 涉及单位ID |
||||||
|
*/ |
||||||
|
private Integer involvedDeptId; |
||||||
|
|
||||||
|
/** |
||||||
|
* 涉及单位名称 |
||||||
|
*/ |
||||||
|
private String involvedDeptName; |
||||||
|
|
||||||
|
|
||||||
|
private String source = MailSource.Source.MAILBOX.getValue(); |
||||||
|
|
||||||
|
public MailOuter toMailOuter() { |
||||||
|
MailOuter mailOuter = new MailOuter(); |
||||||
|
BeanUtils.copyProperties(this, mailOuter); |
||||||
|
return mailOuter; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
package com.biutag.outer.domain; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import lombok.experimental.Accessors; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
@Accessors(chain = true) |
||||||
|
@Setter |
||||||
|
@Getter |
||||||
|
public class MailEtl { |
||||||
|
|
||||||
|
@TableId(type = IdType.AUTO) |
||||||
|
private Integer id; |
||||||
|
|
||||||
|
private String mailId; |
||||||
|
|
||||||
|
private Boolean success; |
||||||
|
|
||||||
|
private LocalDateTime createTime; |
||||||
|
|
||||||
|
private String errMsg; |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,82 @@ |
|||||||
|
package com.biutag.outer.job; |
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil; |
||||||
|
import cn.hutool.crypto.digest.MD5; |
||||||
|
import cn.hutool.http.HttpResponse; |
||||||
|
import cn.hutool.http.HttpUtil; |
||||||
|
import com.alibaba.fastjson2.JSON; |
||||||
|
import com.alibaba.fastjson2.JSONObject; |
||||||
|
import com.biutag.config.Minio; |
||||||
|
import com.biutag.outer.domain.Mail; |
||||||
|
import com.biutag.outer.domain.MailEtl; |
||||||
|
import com.biutag.outer.mapper.MailEtlMapper; |
||||||
|
import com.biutag.outer.mapper.MailMapper; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
import org.springframework.transaction.annotation.Transactional; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@RequiredArgsConstructor |
||||||
|
@Component |
||||||
|
public class MailJob { |
||||||
|
|
||||||
|
private final MailEtlMapper mailEtlMapper; |
||||||
|
|
||||||
|
private final MailMapper mailMapper; |
||||||
|
|
||||||
|
private final Minio minio; |
||||||
|
|
||||||
|
@Value("${mailbox.url}") |
||||||
|
private String mailboxUrl; |
||||||
|
|
||||||
|
private final String key = "mailbox"; |
||||||
|
|
||||||
|
// 1分钟
|
||||||
|
@Scheduled(fixedRate = 60000) |
||||||
|
@Transactional(rollbackFor = Exception.class) |
||||||
|
public void pushMailData() { |
||||||
|
System.out.println(LocalDateTime.now()); |
||||||
|
List<Mail> mails = mailMapper.listByMailEtl(); |
||||||
|
for (Mail mail : mails) { |
||||||
|
try { |
||||||
|
if (StrUtil.isNotBlank(mail.getAttachments())) { |
||||||
|
List<JSONObject> attachments = JSON.parseArray(mail.getAttachments()).toList(JSONObject.class); |
||||||
|
for (JSONObject attachment : attachments) { |
||||||
|
attachment.put("base64", minio.getBase64(attachment.getString("filepath"))); |
||||||
|
} |
||||||
|
mail.setAttachments(JSON.toJSONString(attachments)); |
||||||
|
} |
||||||
|
long timestamp = new Date().getTime(); |
||||||
|
HttpResponse httpResponse = HttpUtil.createPost(mailboxUrl + "mail") |
||||||
|
.header("timestamp", String.valueOf(timestamp)) |
||||||
|
.auth(MD5.create().digestHex(key + timestamp)) |
||||||
|
.body(JSON.toJSONString(mail)) |
||||||
|
.execute(); |
||||||
|
if (!httpResponse.isOk()) { |
||||||
|
throw new RuntimeException(String.format("httpCode: %s", httpResponse.getStatus())); |
||||||
|
} |
||||||
|
log.info(httpResponse.body()); |
||||||
|
JSONObject response = JSONObject.parseObject(httpResponse.body()); |
||||||
|
if (response.getInteger("code") != 200) { |
||||||
|
throw new RuntimeException(response.getString("msg")); |
||||||
|
} |
||||||
|
MailEtl mailEtl = new MailEtl().setMailId(mail.getId()).setSuccess(true).setCreateTime(LocalDateTime.now()); |
||||||
|
mailEtlMapper.insert(mailEtl); |
||||||
|
} catch (RuntimeException e) { |
||||||
|
log.error("推送信件[{}]异常: {}", mail.getId(), e.getMessage(), e); |
||||||
|
MailEtl mailEtl = new MailEtl().setMailId(mail.getId()).setSuccess(false).setCreateTime(LocalDateTime.now()).setErrMsg(e.getMessage()); |
||||||
|
mailEtlMapper.insert(mailEtl); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
package com.biutag.outer.mapper; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import com.biutag.outer.domain.MailEtl; |
||||||
|
import org.apache.ibatis.annotations.Mapper; |
||||||
|
|
||||||
|
@Mapper |
||||||
|
public interface MailEtlMapper extends BaseMapper<MailEtl> { |
||||||
|
} |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
package com.biutag.outer; |
||||||
|
|
||||||
|
import cn.hutool.crypto.digest.MD5; |
||||||
|
import com.alibaba.fastjson2.JSON; |
||||||
|
import com.biutag.outer.domain.Mail; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class ApiTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAuth() { |
||||||
|
Mail mail = new Mail(); |
||||||
|
mail.setCreateTime(LocalDateTime.now()); |
||||||
|
System.out.println(JSON.toJSONString(mail)); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue