Эх сурвалжийг харах

Merge branch 'dev' of licailing/uwip into master

licailing 4 жил өмнө
parent
commit
f7730d7ca7
33 өөрчлөгдсөн 854 нэмэгдсэн , 102 устгасан
  1. 18 2
      src/main/java/com/izouma/uwip/domain/Fee.java
  2. 9 3
      src/main/java/com/izouma/uwip/domain/Message.java
  3. 8 2
      src/main/java/com/izouma/uwip/domain/Patent.java
  4. 2 0
      src/main/java/com/izouma/uwip/dto/CountryPatentDTO.java
  5. 58 5
      src/main/java/com/izouma/uwip/dto/DomesticPatentDTO.java
  6. 2 0
      src/main/java/com/izouma/uwip/dto/InternationalPatentDTO.java
  7. 2 0
      src/main/java/com/izouma/uwip/dto/PatentDTO.java
  8. 23 0
      src/main/java/com/izouma/uwip/dto/TrendDTO.java
  9. 8 0
      src/main/java/com/izouma/uwip/enums/Category.java
  10. 1 1
      src/main/java/com/izouma/uwip/enums/CountryWorkflow.java
  11. 26 0
      src/main/java/com/izouma/uwip/repo/MessageRepo.java
  12. 9 5
      src/main/java/com/izouma/uwip/service/CountryPatentService.java
  13. 46 2
      src/main/java/com/izouma/uwip/service/DomesticPatentService.java
  14. 7 0
      src/main/java/com/izouma/uwip/service/InternationalPatentService.java
  15. 31 0
      src/main/java/com/izouma/uwip/service/MessageService.java
  16. 112 76
      src/main/java/com/izouma/uwip/service/PatentService.java
  17. 34 0
      src/main/java/com/izouma/uwip/utils/excel/BooleanConverter.java
  18. 4 3
      src/main/java/com/izouma/uwip/utils/excel/ExcelUtils.java
  19. 3 1
      src/main/java/com/izouma/uwip/web/DomesticPatentController.java
  20. 73 0
      src/main/java/com/izouma/uwip/web/MessageController.java
  21. 34 1
      src/main/java/com/izouma/uwip/web/PatentController.java
  22. 1 0
      src/main/resources/genjson/Message.json
  23. 3 0
      src/main/vue/src/components/countryPatent/Reply.vue
  24. 2 0
      src/main/vue/src/components/domesticPatent/AddSupplierNo.vue
  25. 2 0
      src/main/vue/src/components/domesticPatent/Register.vue
  26. 2 0
      src/main/vue/src/components/domesticPatent/Reply.vue
  27. 9 0
      src/main/vue/src/components/fee/FeeAdd.vue
  28. 2 0
      src/main/vue/src/components/internationalPatent/AddSupplierNo.vue
  29. 3 0
      src/main/vue/src/components/internationalPatent/Reply.vue
  30. 16 0
      src/main/vue/src/router.js
  31. 112 0
      src/main/vue/src/views/MessageEdit.vue
  32. 164 0
      src/main/vue/src/views/MessageList.vue
  33. 28 1
      src/test/java/com/izouma/uwip/service/PatentServiceTest.java

+ 18 - 2
src/main/java/com/izouma/uwip/domain/Fee.java

@@ -1,5 +1,6 @@
 package com.izouma.uwip.domain;
 
+import com.izouma.uwip.enums.Category;
 import com.izouma.uwip.enums.PayStatus;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -7,9 +8,10 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.hibernate.annotations.NotFound;
+import org.hibernate.annotations.NotFoundAction;
 
-import javax.persistence.Entity;
-import javax.persistence.Transient;
+import javax.persistence.*;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 
@@ -86,6 +88,10 @@ public class Fee extends BaseEntity {
 
     private Long userId;
 
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private Category category;
+
     @Transient
     private String patentPartner;
 
@@ -94,4 +100,14 @@ public class Fee extends BaseEntity {
 
     @Transient
     private String currency;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "patentId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
+    @NotFound(action = NotFoundAction.IGNORE)
+    private Patent patent;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "patentId", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
+    @NotFound(action = NotFoundAction.IGNORE)
+    private LogoPatent lPatent;
 }

+ 9 - 3
src/main/java/com/izouma/uwip/domain/Message.java

@@ -10,21 +10,27 @@ import lombok.NoArgsConstructor;
 import org.hibernate.annotations.Where;
 
 import javax.persistence.Convert;
+import javax.persistence.Entity;
 import java.util.List;
 
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 @Builder
+@Entity
 @ApiModel(value = "系统消息")
 @Where(clause = "del = 0")
 public class Message extends BaseEntity {
     @ApiModelProperty(value = "接收人")
-    @Convert(converter = LongArrayConverter.class)
-    private List<Long> receiveUserId;
+//    @Convert(converter = LongArrayConverter.class)
+//    private List<Long> receiveUserId;
+    private Long receiveUserId;
 
     @ApiModelProperty(value = "是否已读")
-    private boolean read;
+    private boolean isRead;
+
+    @ApiModelProperty(value = "标题")
+    private String title;
 
     @ApiModelProperty(value = "内容")
     private String content;

+ 8 - 2
src/main/java/com/izouma/uwip/domain/Patent.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.izouma.uwip.annotations.Searchable;
 import com.izouma.uwip.converter.HandleListConverter;
 import com.izouma.uwip.enums.ApplyStatus;
+import com.izouma.uwip.enums.Category;
 import com.izouma.uwip.enums.PatentType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -26,7 +27,6 @@ import java.util.List;
 @Where(clause = "del = 0")
 @JsonIgnoreProperties(value = {"hibernateLazyInitializer"}, ignoreUnknown = true)
 public class Patent extends BaseEntity {
-//    private String workflow;
 
     @Searchable
     @ApiModelProperty(value = "专利名称")
@@ -106,5 +106,11 @@ public class Patent extends BaseEntity {
     @Convert(converter = HandleListConverter.class)
     private List<Handle> handle;
 
-//    private CascadeType
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private Category category;
+
+    private String flow;
+
+    private LocalDate period;
 }

+ 2 - 0
src/main/java/com/izouma/uwip/dto/CountryPatentDTO.java

@@ -161,6 +161,8 @@ public class CountryPatentDTO {
     @ApiModelProperty(value = "申请日")
     private LocalDate applyDate;
 
+    public LocalDate period;
+
     private List<Handle> handle = new ArrayList<>();
 
     public List<AttachmentDTO> attachments;

+ 58 - 5
src/main/java/com/izouma/uwip/dto/DomesticPatentDTO.java

@@ -1,6 +1,8 @@
 package com.izouma.uwip.dto;
 
 import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.izouma.uwip.domain.DomesticPatent;
 import com.izouma.uwip.domain.Handle;
 import com.izouma.uwip.domain.Patent;
@@ -23,36 +25,47 @@ import java.util.List;
 @Data
 @Builder
 @NoArgsConstructor
-@ApiModel(value = "国内申请")
+@ApiModel(value = "DomesticPatent", description = "国内申请")
 public class DomesticPatentDTO {
+    @ExcelIgnore
     private Long did;
 
+    @ExcelIgnore
     private Long patentId;
 
+    @ExcelIgnore
     @ApiModelProperty(value = "流程")
     private DomesticWorkflow workflow;
 
+    @ExcelProperty(value = "申请人统一社会信用代码")
     @ApiModelProperty(value = "申请人统一社会信用代码")
     private String applicantUscc;
 
+    @ExcelProperty(value = "第一发明人身份证")
     @ApiModelProperty(value = "第一发明人身份证")
     private String inventorIdno;
 
+    @ExcelProperty(value = "是否请求费减")
     @ApiModelProperty(value = "是否请求费减")
     private boolean deduction;
 
+    @ExcelProperty(value = "是否请求实质审查")
     @ApiModelProperty(value = "是否请求实质审查")
     private boolean essentialReview;
 
+    @ExcelProperty(value = "是否申请提前公开")
     @ApiModelProperty(value = "是否申请提前公开")
     private boolean publicInAdvance;
 
+    @ExcelProperty(value = "是否申请红章受理通知书")
     @ApiModelProperty(value = "是否申请红章受理通知书")
     private boolean chapterAcceptanceNotice;
 
+    @ExcelProperty(value = "是否申请红章缴费通知书")
     @ApiModelProperty(value = "是否申请红章缴费通知书")
     private boolean chapterPaymentNotice;
 
+    @ExcelProperty(value = "是否决定答复")
     @ApiModelProperty(value = "是否决定答复")
     private Boolean decideReply;
 
@@ -60,109 +73,149 @@ public class DomesticPatentDTO {
     true 客户准备
     false 律师准备
      */
+    @ExcelProperty(value = "准备答复意见")
     @ApiModelProperty(value = "准备答复意见")
     private Boolean isClientReady;
 
+    @ExcelProperty(value = "是否通过答复")
     @ApiModelProperty(value = "是否通过答复")
     private Boolean replyPassed;
 
+    @ExcelProperty(value = "办登通知日")
     @ApiModelProperty(value = "办登通知日")
     private LocalDate registerNotice;
 
+    @ExcelProperty(value = "办登截止日")
     @ApiModelProperty(value = "办登截止日")
     private LocalDate registerEndDate;
 
+    @ExcelProperty(value = "费用备注")
     @ApiModelProperty(value = "费用备注")
     private String feeRemark;
 
+    @ExcelProperty(value = "是否已缴费")
     @ApiModelProperty(value = "是否已缴费")
     private Boolean payment;
 
+    @ExcelProperty(value = "年费")
     @ApiModelProperty(value = "年费")
     private BigDecimal annualFee;
 
+    @ExcelProperty(value = "年费支付期限")
     @ApiModelProperty(value = "年费支付期限")
     private LocalDate feePaymentPeriod;
 
+    @ExcelProperty(value = "账单")
     @ApiModelProperty(value = "账单")
     private String bill;
 
+    @ExcelProperty(value = "专利名称")
     @ApiModelProperty(value = "专利名称")
     private String name;
 
+    @ExcelIgnore
     private ApplyStatus applyStatus;
 
+    @ExcelIgnore
     @ApiModelProperty(value = "专利类型")
     private PatentType type;
 
     /*
     客户编码(由客户经理填写)+年份+案件类型+连接符+案件阶段[+国家]+序列号
      */
+    @ExcelProperty(value = "寰球案号")
     @ApiModelProperty(value = "寰球案号")
     private String uwNo;
 
+    @ExcelIgnore
     @ApiModelProperty(value = "客户id")
     private Long clientPartnerId;
 
+    @ExcelIgnore
     @ApiModelProperty(value = "供应商")
     private Long supplierPartnerId;
 
+    @ExcelProperty(value = "供应商案号")
     @ApiModelProperty(value = "供应商案号")
     private String supplierNo;
 
+    @ExcelProperty(value = "供应商提交期限")
     @ApiModelProperty(value = "供应商提交期限")
     private LocalDate supplierSubmitPeriod;
 
+    @ExcelProperty(value = "申请人名称")
     @ApiModelProperty(value = "申请人名称")
     private String applicantName;
 
+    @ExcelProperty(value = "申请人英文名称")
     @ApiModelProperty(value = "申请人英文名称")
     private String applicantEnName;
 
+    @ExcelProperty(value = "申请人地址")
     @ApiModelProperty(value = "申请人地址")
     private String applicantAddress;
 
+    @ExcelProperty(value = "申请人英文地址")
     @ApiModelProperty(value = "申请人英文地址")
     private String applicantEnAddress;
 
+    @ExcelProperty(value = "发明人名称")
     @ApiModelProperty(value = "发明人名称")
     private String inventorName;
 
+    @ExcelProperty(value = "发明人英文名称")
     @ApiModelProperty(value = "发明人英文名称")
     private String inventorEnName;
 
+    @ExcelProperty(value = "优先权号")
     @ApiModelProperty(value = "优先权号")
     private String priorityNo;
 
+    @ExcelProperty(value = "优先权日")
     @ApiModelProperty(value = "优先权日")
     private LocalDate priorityDate;
 
+    @ExcelProperty(value = "优先权国别")
     @ApiModelProperty(value = "优先权国别")
     private String priorityCountry;
 
+    @ExcelProperty(value = "内部期限")
     @ApiModelProperty(value = "提交期限/内部期限")
     private LocalDate submitPeriod;
 
     /*
     =优先权日+30个月
      */
+    @ExcelProperty(value = "官方期限")
     @ApiModelProperty(value = "官方期限")
     private LocalDate officialPeriod;
 
+    @ExcelProperty(value = "申请号")
     @ApiModelProperty(value = "申请号")
     private String applyNo;
 
+    @ExcelProperty(value = "申请日")
     @ApiModelProperty(value = "申请日")
     private LocalDate applyDate;
-
+    @ExcelIgnore
     public List<AttachmentDTO> attachments;
 
+    @ExcelIgnore
+    public LocalDate period;
+
+    @ExcelIgnore
     private List<Handle> handle = new ArrayList<>();
 
-    public DomesticPatentDTO(DomesticPatent dPatent, Patent patent){
-        BeanUtil.copyProperties(dPatent,this);
-        BeanUtil.copyProperties(patent,this);
+    public DomesticPatentDTO(DomesticPatent dPatent, Patent patent) {
+        BeanUtil.copyProperties(dPatent, this);
+        BeanUtil.copyProperties(patent, this);
         this.did = dPatent.getId();
         this.patentId = patent.getId();
     }
+
+    public DomesticPatentDTO(DomesticPatent dPatent) {
+        BeanUtil.copyProperties(dPatent, this);
+        BeanUtil.copyProperties(dPatent.getPatent(), this);
+        this.did = dPatent.getId();
+    }
 }

+ 2 - 0
src/main/java/com/izouma/uwip/dto/InternationalPatentDTO.java

@@ -124,6 +124,8 @@ public class InternationalPatentDTO {
     @ApiModelProperty(value = "申请日")
     private LocalDate applyDate;
 
+    public LocalDate period;
+
     public List<AttachmentDTO> attachments;
 
     private List<Handle> handle = new ArrayList<>();

+ 2 - 0
src/main/java/com/izouma/uwip/dto/PatentDTO.java

@@ -28,6 +28,8 @@ public class PatentDTO {
         this.name = patent.getName();
         this.uwNo = patent.getUwNo();
         this.applyStatus = patent.getApplyStatus();
+        this.workflow = patent.getFlow();
+        this.date = patent.getPeriod();
     }
 
     public PatentDTO(LogoPatent patent) {

+ 23 - 0
src/main/java/com/izouma/uwip/dto/TrendDTO.java

@@ -0,0 +1,23 @@
+package com.izouma.uwip.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@ApiModel("趋势")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TrendDTO {
+    private int dp;
+
+    private int ip;
+
+    private int cp;
+
+    private int lp;
+
+    private int day;
+
+}

+ 8 - 0
src/main/java/com/izouma/uwip/enums/Category.java

@@ -0,0 +1,8 @@
+package com.izouma.uwip.enums;
+
+public enum Category {
+    DOMESTIC,
+    INTERNATIONAL,
+    COUNTRY,
+    LOGO
+}

+ 1 - 1
src/main/java/com/izouma/uwip/enums/CountryWorkflow.java

@@ -16,7 +16,7 @@ public enum CountryWorkflow {
     REPLY_NOTIFICATION("待上传答复通知", 2),
     DETERMINED_REPLY("待确定答复意向", 1),
     NO_REPLY("不答复终止", 1),
-    REPLY_SUBMISSIONS("待上传答复意见书", 1),
+    REPLY_SUBMISSION("待上传答复意见书", 1),
     RESPONSE_RESULT("待确定答复结果", 2),
     /*
     授权办登通知日

+ 26 - 0
src/main/java/com/izouma/uwip/repo/MessageRepo.java

@@ -0,0 +1,26 @@
+package com.izouma.uwip.repo;
+
+import com.izouma.uwip.domain.Message;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+public interface MessageRepo extends JpaRepository<Message, Long>, JpaSpecificationExecutor<Message> {
+    @Query("update Message t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+
+    @Query("update Message t set t.isRead = true where t.receiveUserId = ?1")
+    @Modifying
+    @Transactional
+    void batchRead(Long userId);
+
+    List<Message> findAllByReceiveUserId(Long receiveUserId);
+//    @Query(nativeQuery = true, value = "select * from message where find_in_set(?1, receive_user_id)")
+//    List<Message> findMy(Long userId);
+}

+ 9 - 5
src/main/java/com/izouma/uwip/service/CountryPatentService.java

@@ -8,10 +8,7 @@ import com.izouma.uwip.domain.InternationalPatent;
 import com.izouma.uwip.domain.Patent;
 import com.izouma.uwip.dto.CountryPatentDTO;
 import com.izouma.uwip.dto.PageQuery;
-import com.izouma.uwip.enums.ApplyStatus;
-import com.izouma.uwip.enums.CaseStage;
-import com.izouma.uwip.enums.CaseType;
-import com.izouma.uwip.enums.CountryWorkflow;
+import com.izouma.uwip.enums.*;
 import com.izouma.uwip.exception.BusinessException;
 import com.izouma.uwip.repo.CountryPatentRepo;
 import com.izouma.uwip.repo.PatentRepo;
@@ -64,6 +61,12 @@ public class CountryPatentService {
             if (ObjectUtil.isNull(record.getApplyStatus()) || !ApplyStatus.COMPLETED.equals(record.getApplyStatus())) {
                 orig1.setApplyStatus(this.getApplyStatus(record.getWorkflow()));
             }
+
+            // 流程--首页统计用
+            patent.setFlow(orig.getWorkflow().getDescription());
+            if (ObjectUtil.isNull(record.getPeriod())) {
+                patent.setPeriod(null);
+            }
             patentRepo.save(orig1);
 
             // 保存附件
@@ -76,6 +79,7 @@ public class CountryPatentService {
         Patent patent = new Patent();
         BeanUtil.copyProperties(record, patent);
         patent.setSort(patentRepo.findMax());
+        patent.setCategory(Category.COUNTRY);
 
         // 寰球案号
         String type = patent.getType().name();
@@ -109,7 +113,7 @@ public class CountryPatentService {
                 return ApplyStatus.APPLY_STAGE;//申请阶段
             case REPLY_NOTIFICATION://答复通知
             case DETERMINED_REPLY://答复意向
-            case REPLY_SUBMISSIONS://答复意见书
+            case REPLY_SUBMISSION://答复意见书
             case RESPONSE_RESULT://答复结果
                 return ApplyStatus.SUBSTANTIVE_STAGE;//审查
             case PENDING_REGISTER://办登通知日

+ 46 - 2
src/main/java/com/izouma/uwip/service/DomesticPatentService.java

@@ -5,12 +5,15 @@ import cn.hutool.core.util.ObjectUtil;
 import com.izouma.uwip.domain.DomesticPatent;
 import com.izouma.uwip.domain.Handle;
 import com.izouma.uwip.domain.Patent;
+import com.izouma.uwip.domain.User;
 import com.izouma.uwip.dto.DomesticPatentDTO;
 import com.izouma.uwip.dto.PageQuery;
 import com.izouma.uwip.enums.*;
 import com.izouma.uwip.exception.BusinessException;
 import com.izouma.uwip.repo.DomesticPatentRepo;
 import com.izouma.uwip.repo.PatentRepo;
+import com.izouma.uwip.repo.UserRepo;
+import com.izouma.uwip.security.Authority;
 import com.izouma.uwip.utils.JpaUtils;
 import com.izouma.uwip.utils.ObjUtils;
 import lombok.AllArgsConstructor;
@@ -21,6 +24,7 @@ import org.springframework.stereotype.Service;
 import javax.persistence.criteria.Predicate;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
@@ -31,6 +35,8 @@ public class DomesticPatentService {
     private final PatentRepo         patentRepo;
     private final PartnerService     partnerService;
     private final PatentService      patentService;
+    private final UserRepo           userRepo;
+    private final MessageService     messageService;
 
     public Page<DomesticPatent> all(PageQuery pageQuery) {
         return domesticPatentRepo.findAll(JpaUtils.toSpecification(pageQuery, DomesticPatent.class), JpaUtils.toPageRequest(pageQuery));
@@ -57,7 +63,12 @@ public class DomesticPatentService {
             patentService.saveHandle(record.getWorkflow().toString(), userId, handleList);
 
             if (ObjectUtil.isNull(record.getApplyStatus()) || !ApplyStatus.COMPLETED.equals(record.getApplyStatus())) {
-                orig1.setApplyStatus(this.getApplyStatus(record.getWorkflow()));
+                orig1.setApplyStatus(this.getApplyStatus(record.getWorkflow(), record.getName()));
+            }
+            // 流程--首页统计用
+            patent.setFlow(orig.getWorkflow().getDescription());
+            if (ObjectUtil.isNull(record.getPeriod())) {
+                patent.setPeriod(null);
             }
             patentRepo.save(orig1);
 
@@ -72,6 +83,7 @@ public class DomesticPatentService {
         Patent patent = new Patent();
         BeanUtil.copyProperties(record, patent);
         patent.setSort(patentRepo.findMax());
+        patent.setCategory(Category.DOMESTIC);
 
         //寰球案号
         PatentType type = patent.getType();
@@ -91,21 +103,53 @@ public class DomesticPatentService {
         return dPatent;
     }
 
-    public ApplyStatus getApplyStatus(DomesticWorkflow workflow) {
+    public ApplyStatus getApplyStatus(DomesticWorkflow workflow, String name) {
+        List<Long> accountIds = userRepo.findAllByAuthoritiesContainsAndDelFalse(Authority.get(AuthorityName.ROLE_ACCOUNT))
+                .stream()
+                .map(User::getId)
+                .collect(Collectors.toList());
+
+        List<Long> projectIds = userRepo.findAllByAuthoritiesContainsAndDelFalse(Authority.get(AuthorityName.ROLE_PROJECT))
+                .stream()
+                .map(User::getId)
+                .collect(Collectors.toList());
+
         switch (workflow) {
             case ADD_SUPPLIERS://待添加供应商
             case SUPPLIER_MATERIALS://供应商反馈文件
+                return ApplyStatus.APPLY_STAGE;
             case MAINTAIN_CASE://申请号/申请日
+                //发送消息-客户经理
+                messageService.batchSave(accountIds,"国内专利:"+name,"收到一条待维护案件专利");
+                return ApplyStatus.APPLY_STAGE;
             case REPLY_TO_NOTICE://官方期限/内部期限
+                //发送消息-项目经理
+                messageService.batchSave(projectIds,"国内专利:"+name,"收到一条上传答复通知专利");
+                return ApplyStatus.APPLY_STAGE;
+
             case PENDING_REVIEW://是否答复 待审查
+                //发送消息-客户经理
+                messageService.batchSave(accountIds,"国内专利:"+name,"收到一条待审查专利");
+
                 return ApplyStatus.APPLY_STAGE;//申请阶段
             case REPLY_SUBMISSIONS://答复意见书
                 return ApplyStatus.SUBSTANTIVE_STAGE;// 实审阶段
             case REPLY_RESULT://答复结果
+                //发送消息-项目经理
+                messageService.batchSave(projectIds,"国内专利:"+name,"收到一条待上传答复通知专利");
+
                 return ApplyStatus.REVIEW_STAGE;//复查阶段
             case PENDING_REGISTER://办登通知日
+                //发送消息-客户经理
+                messageService.batchSave(accountIds,"国内专利:"+name,"收到一条待待办登专利");
+                return ApplyStatus.GRANT_STAGE;
+
             case PAYMENT_REGISTER://是否缴费
+                return ApplyStatus.GRANT_STAGE;
             case REGISTER://办登登记
+                //发送消息-项目经理
+                messageService.batchSave(projectIds,"国内专利:"+name,"收到一条待办理登记专利");
+
             case ANNUAL_FEE://维护费用
                 return ApplyStatus.GRANT_STAGE;//授权阶段
             default://不答复终止

+ 7 - 0
src/main/java/com/izouma/uwip/service/InternationalPatentService.java

@@ -57,6 +57,12 @@ public class InternationalPatentService {
             if (ObjectUtil.isNull(record.getApplyStatus()) || !ApplyStatus.COMPLETED.equals(record.getApplyStatus())) {
                 orig1.setApplyStatus(this.getApplyStatus(record.getWorkflow()));
             }
+
+            // 流程--首页统计用
+            patent.setFlow(orig.getWorkflow().getDescription());
+            if (ObjectUtil.isNull(record.getPeriod())) {
+                patent.setPeriod(null);
+            }
             patentRepo.save(orig1);
 
             // 保存附件
@@ -69,6 +75,7 @@ public class InternationalPatentService {
         Patent patent = new Patent();
         BeanUtil.copyProperties(record, patent);
         patent.setSort(patentRepo.findMax());
+        patent.setCategory(Category.INTERNATIONAL);
 
         //寰球案号
         PatentType type = patent.getType();

+ 31 - 0
src/main/java/com/izouma/uwip/service/MessageService.java

@@ -0,0 +1,31 @@
+package com.izouma.uwip.service;
+
+import com.izouma.uwip.domain.Message;
+import com.izouma.uwip.dto.PageQuery;
+import com.izouma.uwip.repo.MessageRepo;
+import com.izouma.uwip.utils.JpaUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class MessageService {
+
+    private final MessageRepo messageRepo;
+
+    public Page<Message> all(PageQuery pageQuery) {
+        return messageRepo.findAll(JpaUtils.toSpecification(pageQuery, Message.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public void batchSave(List<Long> userIds, String name, String content) {
+        userIds.forEach(id -> messageRepo.save(Message.builder()
+                .title(name)
+                .content(content)
+                .receiveUserId(id)
+                .build()));
+
+    }
+}

+ 112 - 76
src/main/java/com/izouma/uwip/service/PatentService.java

@@ -1,6 +1,5 @@
 package com.izouma.uwip.service;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.izouma.uwip.domain.Handle;
@@ -8,8 +7,11 @@ import com.izouma.uwip.domain.LogoPatent;
 import com.izouma.uwip.domain.Patent;
 import com.izouma.uwip.dto.PageQuery;
 import com.izouma.uwip.dto.PatentDTO;
+import com.izouma.uwip.dto.TrendDTO;
 import com.izouma.uwip.enums.ApplyStatus;
-import com.izouma.uwip.repo.*;
+import com.izouma.uwip.enums.Category;
+import com.izouma.uwip.repo.LogoPatentRepo;
+import com.izouma.uwip.repo.PatentRepo;
 import com.izouma.uwip.utils.JpaUtils;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
@@ -28,11 +30,8 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class PatentService {
 
-    private final PatentRepo              patentRepo;
-    private final LogoPatentRepo          logoPatentRepo;
-    private final DomesticPatentRepo      domesticPatentRepo;
-    private final InternationalPatentRepo internationalPatentRepo;
-    private final CountryPatentRepo       countryPatentRepo;
+    private final PatentRepo     patentRepo;
+    private final LogoPatentRepo logoPatentRepo;
 
     public Page<Patent> all(PageQuery pageQuery) {
         return patentRepo.findAll(JpaUtils.toSpecification(pageQuery, Patent.class), JpaUtils.toPageRequest(pageQuery));
@@ -84,17 +83,16 @@ public class PatentService {
         List<Patent> patents = patentRepo.findAll();
         List<LogoPatent> logoPatents = logoPatentRepo.findAll();
 
+        Map<String, Integer> card = new HashMap<>();
         //总数
         int total = patents.size() + logoPatents.size();
-        map.put("total", total);
-
+        card.put("total", total);
         //今天
         LocalDate now = LocalDate.now();
         long pToday = patents.stream().filter(patent -> patent.getCreatedAt().toLocalDate().equals(now)).count();
         long lToday = logoPatents.stream().filter(patent -> patent.getCreatedAt().toLocalDate().equals(now)).count();
         int today = (int) (pToday + lToday);
-        map.put("today", today);
-
+        card.put("today", today);
         //进行中
         List<Patent> pInProgress = patents.stream()
                 .filter(patent -> !ApplyStatus.COMPLETED.equals(patent.getApplyStatus()))
@@ -103,80 +101,52 @@ public class PatentService {
                 .filter(patent -> !ApplyStatus.COMPLETED.equals(patent.getApplyStatus()))
                 .collect(Collectors.toList());
         int inProgress = pInProgress.size() + lInProgress.size();
-        map.put("inProgress", inProgress);
-
+        card.put("inProgress", inProgress);
         //已结束
         int end = total - inProgress;
-        map.put("end", end);
-
-        //代办案件列表
-        List<PatentDTO> lAgent = lInProgress.stream().map(PatentDTO::new).collect(Collectors.toList());
-//        List<PatentDTO> pAgent = pInProgress.stream().map(PatentDTO::new).collect(Collectors.toList());
-
-        pInProgress.forEach(patent -> {
-            PatentDTO dto = new PatentDTO(patent);
-            List<Handle> handle = patent.getHandle();
-            int size = handle.size();
-            if (size > 0) {
-                String workflow = handle.get(size - 1).getWorkflow();
-
-                if ("TRANSLATION_DOCUMENTS".equals(workflow)) {
-                    //TRANSLATION_DOCUMENTS 待申请翻译文稿
-                } else if ("SUPPLIER_MATERIALS".equals(workflow)) {
-                    //SUPPLIER_MATERIALS 待添加供应商
-                    dto.setDate(patent.getSupplierSubmitPeriod());
-                } else if ("DETERMINED_REPLY".equals(workflow)) {
-                    //DETERMINED_REPLY 待上传答复通知
-                    dto.setDate(patent.getSubmitPeriod());
-                } else if("AUTHORIZE_REGISTER".equals(workflow)){
-                   //授权办登通知日
-                } else if("PENDING_REVIEW".equals(workflow)){
-
-                }
+        card.put("end", end);
 
+        map.put("card", card);
 
-            }
 
-        });
-        //数据统计
-        Map<ApplyStatus, List<Patent>> byPStatus = patents.stream()
-                .collect(Collectors.groupingBy(Patent::getApplyStatus));
+        //代办案件列表
+        List<PatentDTO> lAgent = lInProgress.stream()
+                .map(PatentDTO::new)
+                .filter(agent -> ObjectUtil.isNotNull(agent.getDate()))
+                .collect(Collectors.toList());
+        List<PatentDTO> pAgent = pInProgress.stream()
+                .map(PatentDTO::new)
+                .filter(agent -> ObjectUtil.isNotNull(agent.getDate()))
+                .collect(Collectors.toList());
 
-        Map<ApplyStatus, List<LogoPatent>> byLStatus = logoPatents.stream()
-                .collect(Collectors.groupingBy(LogoPatent::getApplyStatus));
-        List<LogoPatent> applyLPatent = byLStatus.get(ApplyStatus.APPLY_STAGE);
-        List<Patent> applyPatent = byPStatus.get(ApplyStatus.APPLY_STAGE);
-        int apply = CollUtil.isEmpty(applyLPatent) ? 0 : applyLPatent.size() +
-                ((CollUtil.isEmpty(applyPatent)) ? 0 : applyPatent.size());
+        lAgent.addAll(pAgent);
+        List<PatentDTO> agents = lAgent.stream()
+                .sorted(Comparator.comparing(PatentDTO::getDate))
+                .limit(5)
+                .collect(Collectors.toList());
+        map.put("agent", agents);
 
-        List<LogoPatent> grantLPatent = byLStatus.get(ApplyStatus.GRANT_STAGE);
-        List<Patent> grantPatent = byPStatus.get(ApplyStatus.GRANT_STAGE);
-        int grant = CollUtil.isEmpty(grantLPatent) ? 0 : grantLPatent.size() +
-                ((CollUtil.isEmpty(grantPatent)) ? 0 : grantPatent.size());
 
-        List<LogoPatent> reviewLPatent = byLStatus.get(ApplyStatus.REVIEW_STAGE);
-        List<Patent> reviewPatent = byPStatus.get(ApplyStatus.REVIEW_STAGE);
-        int review = CollUtil.isEmpty(reviewLPatent) ? 0 : reviewLPatent.size() +
-                ((CollUtil.isEmpty(reviewPatent)) ? 0 : reviewPatent.size());
+        //数据统计
+        Map<ApplyStatus, Long> byPStatus = patents.stream()
+                .collect(Collectors.groupingBy(Patent::getApplyStatus, Collectors.counting()));
 
-        List<LogoPatent> substantiveLPatent = byLStatus.get(ApplyStatus.SUBSTANTIVE_STAGE);
-        List<Patent> substantivePatent = byPStatus.get(ApplyStatus.SUBSTANTIVE_STAGE);
-        int substantive = CollUtil.isEmpty(substantiveLPatent) ? 0 : substantiveLPatent.size() +
-                ((CollUtil.isEmpty(substantivePatent)) ? 0 : substantivePatent.size());
+        Map<ApplyStatus, Long> byLStatus = logoPatents.stream()
+                .collect(Collectors.groupingBy(LogoPatent::getApplyStatus, Collectors.counting()));
 
-        map.put("apply", apply);
-        map.put("grant", grant);
-        map.put("review", review);
-        map.put("substantive", substantive);
+        Map<ApplyStatus, Long> pie = new HashMap<>(byPStatus);
+        byLStatus.forEach((key, value) -> pie.merge(key, value, Long::sum));
 
+        map.put("pie", pie);
 
         //本周数据对比
-        int dayOfWeek = now.getDayOfWeek().getValue() % 7;
+        int dayOfWeek = now.getDayOfWeek().getValue();
         Map<LocalDate, Integer> weekMap = getData(patents, logoPatents, now, dayOfWeek);
         map.put("weekMap", weekMap);
 
+
         //本月数据对比
-        int dayOfMonth = now.getDayOfMonth() - 1;
+        int dayOfMonth = now.getDayOfMonth();
         Map<LocalDate, Integer> monthMap = getData(patents, logoPatents, now, dayOfMonth);
         map.put("monthMap", monthMap);
 
@@ -189,23 +159,89 @@ public class PatentService {
     2 月
     3 年
      */
-    public Map<Integer, Integer> getTrend(int type) {
-        Map<Integer, Integer> map = new HashMap<>();
-        switch (type) {
+    public List<TrendDTO> getTrend(int type) {
 
+        List<TrendDTO> dtos = new ArrayList<>();
+        LocalDate now = LocalDate.now();
+        List<Patent> patents = patentRepo.findAll();
+        List<LogoPatent> logoPatents = logoPatentRepo.findAll();
+        switch (type) {
+            case 1:
+                int dayOfWeek = now.getDayOfWeek().getValue();
+                getEveryDay(patents, logoPatents, dtos, now, dayOfWeek);
+                break;
+            case 2:
+                int dayOfMonth = now.getDayOfMonth();
+                getEveryDay(patents, logoPatents, dtos, now, dayOfMonth);
+                break;
             case 3:
+                int month = now.getMonthValue();
+                while (month > 0) {
+                    int dp = 0;
+                    int ip = 0;
+                    int cp = 0;
+                    int finalMonth = month;
+                    List<Patent> monthPatents = patents.stream()
+                            .filter(patent -> patent.getCreatedAt().getMonthValue() == finalMonth)
+                            .collect(Collectors.toList());
+                    for (Patent mp : monthPatents) {
+                        if (Category.DOMESTIC.equals(mp.getCategory())) {
+                            dp++;
+                        } else if (Category.INTERNATIONAL.equals(mp.getCategory())) {
+                            ip++;
+                        } else {
+                            cp++;
+                        }
+                    }
+                    int lp = (int) logoPatents.stream()
+                            .filter(patent -> patent.getCreatedAt().getMonthValue() == finalMonth)
+                            .count();
+
+                    dtos.add(new TrendDTO(dp, ip, cp, lp, month));
+                    month--;
+                }
+                break;
+            default:
+                break;
 
         }
 
+        return dtos;
+    }
 
-        return map;
+    public void getEveryDay(List<Patent> patents, List<LogoPatent> lPatents, List<TrendDTO> dtos, LocalDate now, int day) {
+        while (day > 0) {
+            int dp = 0;
+            int ip = 0;
+            int cp = 0;
+            LocalDate weekStart = now.minusDays(day - 1);
+            List<Patent> monPatents = patents.stream()
+                    .filter(patent -> patent.getCreatedAt().toLocalDate().equals(weekStart))
+                    .collect(Collectors.toList());
+            for (Patent mp : monPatents) {
+                if (Category.DOMESTIC.equals(mp.getCategory())) {
+                    dp++;
+                } else if (Category.INTERNATIONAL.equals(mp.getCategory())) {
+                    ip++;
+                } else {
+                    cp++;
+                }
+            }
+//            System.out.println(monPatents);
+            int lp = (int) lPatents.stream()
+                    .filter(patent -> patent.getCreatedAt().toLocalDate().equals(weekStart))
+                    .count();
+
+            dtos.add(new TrendDTO(dp, ip, cp, lp, day));
+            day--;
+        }
     }
 
-    private Map<LocalDate, Integer> getData(List<Patent> patents, List<LogoPatent> logoPatents,
-                                            LocalDate now, int day) {
+    public Map<LocalDate, Integer> getData(List<Patent> patents, List<LogoPatent> logoPatents,
+                                           LocalDate now, int day) {
         Map<LocalDate, Integer> map = new HashMap<>();
-        while (day >= 0) {
-            LocalDate weekStart = now.minusDays(day);
+        while (day > 0) {
+            LocalDate weekStart = now.minusDays(day - 1);
 
             long pWeek = patents.stream()
                     .filter(patent -> patent.getCreatedAt().toLocalDate().equals(weekStart))

+ 34 - 0
src/main/java/com/izouma/uwip/utils/excel/BooleanConverter.java

@@ -0,0 +1,34 @@
+package com.izouma.uwip.utils.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+
+public class BooleanConverter implements Converter<Boolean> {
+    @Override
+    public Class supportJavaTypeKey() {
+        return Boolean.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public Boolean convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return Boolean.valueOf(cellData.getStringValue());
+    }
+
+    @Override
+    public CellData convertToExcelData(Boolean booleanValue, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        String str = "";
+        if (booleanValue != null) {
+            str = booleanValue ? "是" : "否";
+        }
+        return new CellData(str);
+    }
+}

+ 4 - 3
src/main/java/com/izouma/uwip/utils/excel/ExcelUtils.java

@@ -16,8 +16,9 @@ public class ExcelUtils<T> {
         response.setCharacterEncoding("utf-8");
         response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
         EasyExcel.write(response.getOutputStream(), data.get(0).getClass()).sheet("sheet")
-                 .registerConverter(new LocalDateConverter())
-                 .registerConverter(new LocalDateTimeConverter())
-                 .doWrite(data);
+                .registerConverter(new LocalDateConverter())
+                .registerConverter(new LocalDateTimeConverter())
+                .registerConverter(new BooleanConverter())
+                .doWrite(data);
     }
 }

+ 3 - 1
src/main/java/com/izouma/uwip/web/DomesticPatentController.java

@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/domesticPatent")
@@ -75,7 +76,8 @@ public class DomesticPatentController extends BaseController {
     @ResponseBody
     public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
         List<DomesticPatent> data = all(pageQuery).getContent();
-        ExcelUtils.export(response, data);
+        List<DomesticPatentDTO> dtos = data.stream().map(DomesticPatentDTO::new).collect(Collectors.toList());
+        ExcelUtils.export(response, dtos);
     }
 }
 

+ 73 - 0
src/main/java/com/izouma/uwip/web/MessageController.java

@@ -0,0 +1,73 @@
+package com.izouma.uwip.web;
+
+import com.izouma.uwip.domain.Message;
+import com.izouma.uwip.dto.PageQuery;
+import com.izouma.uwip.exception.BusinessException;
+import com.izouma.uwip.repo.MessageRepo;
+import com.izouma.uwip.service.MessageService;
+import com.izouma.uwip.utils.ObjUtils;
+import com.izouma.uwip.utils.SecurityUtils;
+import com.izouma.uwip.utils.excel.ExcelUtils;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/message")
+@AllArgsConstructor
+public class MessageController extends BaseController {
+    private final MessageService messageService;
+    private final MessageRepo    messageRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public Message save(@RequestBody Message record) {
+        if (record.getId() != null) {
+            Message orig = messageRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return messageRepo.save(orig);
+        }
+        return messageRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<Message> all(@RequestBody PageQuery pageQuery) {
+        return messageService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public Message get(@PathVariable Long id) {
+        return messageRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        messageRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<Message> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+
+    @GetMapping("/my")
+    public List<Message> my() {
+        return messageRepo.findAllByReceiveUserId(SecurityUtils.getAuthenticatedUser().getId());
+    }
+
+    @GetMapping("/batchRead")
+    @ApiOperation("批量已读")
+    public void batchRead() {
+        messageRepo.batchRead(SecurityUtils.getAuthenticatedUser().getId());
+    }
+}
+

+ 34 - 1
src/main/java/com/izouma/uwip/web/PatentController.java

@@ -1,11 +1,14 @@
 package com.izouma.uwip.web;
+
 import com.izouma.uwip.domain.Patent;
+import com.izouma.uwip.dto.TrendDTO;
 import com.izouma.uwip.service.PatentService;
 import com.izouma.uwip.dto.PageQuery;
 import com.izouma.uwip.exception.BusinessException;
 import com.izouma.uwip.repo.PatentRepo;
 import com.izouma.uwip.utils.ObjUtils;
 import com.izouma.uwip.utils.excel.ExcelUtils;
+import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -14,13 +17,14 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/patent")
 @AllArgsConstructor
 public class PatentController extends BaseController {
     private final PatentService patentService;
-    private final PatentRepo patentRepo;
+    private final PatentRepo    patentRepo;
 
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
@@ -56,5 +60,34 @@ public class PatentController extends BaseController {
         List<Patent> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
     }
+
+    /**
+     * @return map
+     * card:卡片上
+     * ---->total:案件数量 today:今日新增 inProgress:进行中 end:已结束
+     * agent: 待办案件列表
+     * weekMap:本周新增数据对比(周一为一周的开始)
+     * monthMap:本月数据增长趋势
+     * pie:饼状图
+     * ---->apply:申请阶段 grant:授权阶段 review:复审阶段 substantive:实审阶段
+     */
+    @GetMapping("/statistic")
+    @ApiOperation("统计")
+    public Map<String, Object> statistic() {
+        return patentService.total();
+    }
+
+    /**
+     * 趋势列表
+     *
+     * @param type 1-周 2-月 3-年
+     * @return 趋势列表 为周时,周一为一周的开始
+     * dp-国内专利  ip-国际专利 cp-国家专利 lp-商标专利 day-(年)几月,(月)几号,(周)周几
+     */
+    @GetMapping("/trend")
+    @ApiOperation("增长趋势")
+    public List<TrendDTO> tread(int type) {
+        return patentService.getTrend(type);
+    }
 }
 

+ 1 - 0
src/main/resources/genjson/Message.json

@@ -0,0 +1 @@
+{"tableName":"Message","className":"Message","remark":"消息列表","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/qiufangchao/Desktop/project/uwip/src/main/java/com/izouma/uwip","viewPath":"/Users/qiufangchao/Desktop/project/uwip/src/main/vue/src/views","routerPath":"/Users/qiufangchao/Desktop/project/uwip/src/main/vue/src","resourcesPath":"/Users/qiufangchao/Desktop/project/uwip/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"isRead","modelName":"isRead","remark":"是否已读","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"title","modelName":"title","remark":"标题","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"content","modelName":"content","remark":"内容","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.uwip","tablePackage":"com.izouma.uwip.domain.Message"}

+ 3 - 0
src/main/vue/src/components/countryPatent/Reply.vue

@@ -87,6 +87,9 @@ export default {
             info.officialPeriod = this.form.officialPeriod;
             info.submitPeriod = this.form.submitPeriod;
             info.workflow = 'REPLY_SUBMISSION';
+            // 期限-用于首页统计用
+            info.period = this.form.submitPeriod;
+
             this.$emit('submit', info);
             this.show = false;
         }

+ 2 - 0
src/main/vue/src/components/domesticPatent/AddSupplierNo.vue

@@ -94,6 +94,8 @@ export default {
             info.supplierSubmitPeriod = this.form.supplierSubmitPeriod;
 
             info.workflow = 'SUPPLIER_MATERIALS';
+            // 期限-用于首页统计用
+            info.period = this.form.supplierSubmitPeriod;
 
             this.$emit('submit', info);
             this.show = false;

+ 2 - 0
src/main/vue/src/components/domesticPatent/Register.vue

@@ -92,6 +92,8 @@ export default {
             info.feeRemark = this.form.feeRemark;
             this.$emit('uploadAttement', this.form.attachment1);
             info.workflow = 'PAYMENT_REGISTER';
+            // 期限-用于首页统计用
+            info.period = this.form.registerEndDate;
             this.$emit('submit', info);
             this.show = false;
         }

+ 2 - 0
src/main/vue/src/components/domesticPatent/Reply.vue

@@ -87,6 +87,8 @@ export default {
             info.officialPeriod = this.form.officialPeriod;
             info.submitPeriod = this.form.submitPeriod;
             info.workflow = 'PENDING_REVIEW';
+            // 期限-用于首页统计用
+            info.period = this.form.submitPeriod;
             this.$emit('submit', info);
             this.show = false;
         }

+ 9 - 0
src/main/vue/src/components/fee/FeeAdd.vue

@@ -264,6 +264,15 @@ export default {
             if (this.info.patentId || this.info.id) {
                 data.patentId = this.info.patentId || this.info.id;
             }
+            if (this.info.id) {
+                data.category = 'LOGO';
+            } else if (this.info.did) {
+                data.category = 'DOMESTIC';
+            } else if (this.info.iid) {
+                data.category = 'INTERNATIONAL';
+            } else {
+                data.category = 'COUNTRY';
+            }
             this.saving = true;
             this.$http
                 .post('/fee/save', data, { body: 'json' })

+ 2 - 0
src/main/vue/src/components/internationalPatent/AddSupplierNo.vue

@@ -94,6 +94,8 @@ export default {
             info.supplierSubmitPeriod = this.form.supplierSubmitPeriod;
 
             info.workflow = 'SUPPLIER_MATERIALS';
+            // 期限-用于首页统计用
+            info.period = this.form.supplierSubmitPeriod;
 
             this.$emit('submit', info);
             this.show = false;

+ 3 - 0
src/main/vue/src/components/internationalPatent/Reply.vue

@@ -87,6 +87,9 @@ export default {
             info.officialPeriod = this.form.officialPeriod;
             info.submitPeriod = this.form.submitPeriod;
             info.workflow = 'REPLY_SUBMISSIONS';
+            // 期限-用于首页统计用
+            info.period = this.form.submitPeriod;
+
             this.$emit('submit', info);
             this.show = false;
         }

+ 16 - 0
src/main/vue/src/router.js

@@ -318,6 +318,22 @@ const router = new Router({
                     meta: {
                         title: '异常日志'
                     }
+                },
+                {
+                    path: '/messageEdit',
+                    name: 'MessageEdit',
+                    component: () => import(/* webpackChunkName: "messageEdit" */ '@/views/MessageEdit.vue'),
+                    meta: {
+                        title: '消息列表编辑'
+                    }
+                },
+                {
+                    path: '/messageList',
+                    name: 'MessageList',
+                    component: () => import(/* webpackChunkName: "messageList" */ '@/views/MessageList.vue'),
+                    meta: {
+                        title: '消息列表'
+                    }
                 }
                 /**INSERT_LOCATION**/
             ]

+ 112 - 0
src/main/vue/src/views/MessageEdit.vue

@@ -0,0 +1,112 @@
+<template>
+    <div class="edit-view">
+        <page-title>
+            <el-button @click="$router.go(-1)">取消</el-button>
+            <el-button @click="del" :loading="$store.state.fetchingData" type="danger" v-if="formData.id">
+                删除
+            </el-button>
+            <el-button @click="onSave" :loading="$store.state.fetchingData" type="primary">保存</el-button>
+        </page-title>
+        <div class="edit-view__content-wrapper">
+            <div class="edit-view__content-section">
+                <divider />
+                <el-form
+                    :model="formData"
+                    :rules="rules"
+                    ref="form"
+                    label-width="80px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px;"
+                >
+                    <el-form-item prop="isRead" label="是否已读">
+                        <el-input v-model="formData.isRead"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="title" label="标题">
+                        <el-input v-model="formData.title"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="content" label="内容">
+                        <el-input v-model="formData.content"></el-input>
+                    </el-form-item>
+                    <el-form-item class="form-submit">
+                        <el-button @click="onSave" :loading="saving" size="default" type="primary">保存 </el-button>
+                        <el-button @click="onDelete" :loading="saving" size="default" type="danger" v-if="formData.id"
+                            >删除
+                        </el-button>
+                        <el-button @click="$router.go(-1)" size="default">取消</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    name: 'MessageEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('message/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            saving: false,
+            formData: {},
+            rules: {}
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
+
+            this.saving = true;
+            this.$http
+                .post('/message/save', data, { body: 'json' })
+                .then(res => {
+                    this.saving = false;
+                    this.$message.success('成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.saving = false;
+                    this.$message.error(e.error);
+                });
+        },
+        onDelete() {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/message/del/${this.formData.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        console.log(e);
+                        this.$message.error((e || {}).error || '删除失败');
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 164 - 0
src/main/vue/src/views/MessageList.vue

@@ -0,0 +1,164 @@
+<template>
+    <div class="list-view">
+        <page-title>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" :loading="downloading" class="filter-item">
+                新增
+            </el-button>
+            <el-button @click="download" icon="el-icon-upload2" :loading="downloading" class="filter-item">
+                导出
+            </el-button>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
+            </el-input>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="isRead" label="是否已读"> </el-table-column>
+            <el-table-column prop="title" label="标题"> </el-table-column>
+            <el-table-column prop="content" label="内容"> </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" min-width="150">
+                <template slot-scope="{ row }">
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'MessageList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/message/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/messageEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/messageEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/message/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 }
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/message/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 28 - 1
src/test/java/com/izouma/uwip/service/PatentServiceTest.java

@@ -1,16 +1,43 @@
 package com.izouma.uwip.service;
 
 import com.izouma.uwip.ApplicationTests;
+import com.izouma.uwip.dto.TrendDTO;
+import com.izouma.uwip.repo.LogoPatentRepo;
+import com.izouma.uwip.repo.PatentRepo;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
 public class PatentServiceTest extends ApplicationTests {
 
     @Autowired
-    private PatentService patentService;
+    private PatentService  patentService;
+    @Autowired
+    private PatentRepo     patentRepo;
+    @Autowired
+    private LogoPatentRepo logoPatentRepo;
 
     @Test
     public void total() {
         System.out.println(patentService.total());
+//        System.out.println(LocalDate.now().minusDays(24));
+    }
+
+    @Test
+    public void test1() {
+//        System.out.println(patentService.getData(patentRepo.findAll(), logoPatentRepo.findAll(), LocalDate.now(), 7));
+        List<TrendDTO> dto = new ArrayList<>();
+        patentService.getEveryDay(patentRepo.findAll(), logoPatentRepo.findAll(), dto, LocalDate
+                .now(), 7);
+        dto.forEach(System.out::println);
+    }
+
+    @Test
+    public void test2() {
+        List<TrendDTO> trend = patentService.getTrend(3);
+        trend.forEach(System.out::println);
     }
 }