licailing 4 роки тому
батько
коміт
78df31a932

+ 6 - 1
src/main/java/com/izouma/uwip/domain/Message.java

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

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

@@ -0,0 +1,20 @@
+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(nativeQuery = true, value = "select * from message where find_in_set(?1, receive_user_id)")
+    List<Message> findMy(Long userId);
+}

+ 71 - 6
src/main/java/com/izouma/uwip/service/DomesticPatentService.java

@@ -2,16 +2,16 @@ package com.izouma.uwip.service;
 
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
-import com.izouma.uwip.domain.DomesticPatent;
-import com.izouma.uwip.domain.Fee;
-import com.izouma.uwip.domain.Handle;
-import com.izouma.uwip.domain.Patent;
+import com.izouma.uwip.domain.*;
 import com.izouma.uwip.dto.DomesticPatentDTO;
 import com.izouma.uwip.dto.DomesticPatentDTO;
 import com.izouma.uwip.dto.PageQuery;
 import com.izouma.uwip.dto.PageQuery;
 import com.izouma.uwip.enums.*;
 import com.izouma.uwip.enums.*;
 import com.izouma.uwip.exception.BusinessException;
 import com.izouma.uwip.exception.BusinessException;
 import com.izouma.uwip.repo.DomesticPatentRepo;
 import com.izouma.uwip.repo.DomesticPatentRepo;
+import com.izouma.uwip.repo.MessageRepo;
 import com.izouma.uwip.repo.PatentRepo;
 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.JpaUtils;
 import com.izouma.uwip.utils.ObjUtils;
 import com.izouma.uwip.utils.ObjUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Predicate;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.stream.Collectors;
 
 
 @Service
 @Service
 @AllArgsConstructor
 @AllArgsConstructor
@@ -32,6 +33,8 @@ public class DomesticPatentService {
     private final PatentRepo         patentRepo;
     private final PatentRepo         patentRepo;
     private final PartnerService     partnerService;
     private final PartnerService     partnerService;
     private final PatentService      patentService;
     private final PatentService      patentService;
+    private final UserRepo           userRepo;
+    private final MessageRepo        messageRepo;
 
 
     public Page<DomesticPatent> all(PageQuery pageQuery) {
     public Page<DomesticPatent> all(PageQuery pageQuery) {
         return domesticPatentRepo.findAll(JpaUtils.toSpecification(pageQuery, DomesticPatent.class), JpaUtils.toPageRequest(pageQuery));
         return domesticPatentRepo.findAll(JpaUtils.toSpecification(pageQuery, DomesticPatent.class), JpaUtils.toPageRequest(pageQuery));
@@ -58,7 +61,7 @@ public class DomesticPatentService {
             patentService.saveHandle(record.getWorkflow().toString(), userId, handleList);
             patentService.saveHandle(record.getWorkflow().toString(), userId, handleList);
 
 
             if (ObjectUtil.isNull(record.getApplyStatus()) || !ApplyStatus.COMPLETED.equals(record.getApplyStatus())) {
             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());
             patent.setFlow(orig.getWorkflow().getDescription());
@@ -98,21 +101,83 @@ public class DomesticPatentService {
         return dPatent;
         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) {
         switch (workflow) {
             case ADD_SUPPLIERS://待添加供应商
             case ADD_SUPPLIERS://待添加供应商
             case SUPPLIER_MATERIALS://供应商反馈文件
             case SUPPLIER_MATERIALS://供应商反馈文件
+                return ApplyStatus.APPLY_STAGE;
             case MAINTAIN_CASE://申请号/申请日
             case MAINTAIN_CASE://申请号/申请日
+                //发送消息-客户经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(accountIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条待维护案件专利")
+                                .build());
+                return ApplyStatus.APPLY_STAGE;
             case REPLY_TO_NOTICE://官方期限/内部期限
             case REPLY_TO_NOTICE://官方期限/内部期限
+                //发送消息-项目经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(projectIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条上传答复通知专利")
+                                .build());
+                return ApplyStatus.APPLY_STAGE;
+
             case PENDING_REVIEW://是否答复 待审查
             case PENDING_REVIEW://是否答复 待审查
+                //发送消息-客户经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(accountIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条待审查专利")
+                                .build());
+
                 return ApplyStatus.APPLY_STAGE;//申请阶段
                 return ApplyStatus.APPLY_STAGE;//申请阶段
             case REPLY_SUBMISSIONS://答复意见书
             case REPLY_SUBMISSIONS://答复意见书
                 return ApplyStatus.SUBSTANTIVE_STAGE;// 实审阶段
                 return ApplyStatus.SUBSTANTIVE_STAGE;// 实审阶段
             case REPLY_RESULT://答复结果
             case REPLY_RESULT://答复结果
+                //发送消息-项目经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(projectIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条待上传答复通知专利")
+                                .build());
+
                 return ApplyStatus.REVIEW_STAGE;//复查阶段
                 return ApplyStatus.REVIEW_STAGE;//复查阶段
             case PENDING_REGISTER://办登通知日
             case PENDING_REGISTER://办登通知日
+                //发送消息-客户经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(accountIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条待待办登专利")
+                                .build());
+                return ApplyStatus.GRANT_STAGE;
+
             case PAYMENT_REGISTER://是否缴费
             case PAYMENT_REGISTER://是否缴费
+                return ApplyStatus.GRANT_STAGE;
             case REGISTER://办登登记
             case REGISTER://办登登记
+                //发送消息-项目经理
+                messageRepo.save(
+                        Message.builder()
+                                .receiveUserId(projectIds)
+                                .title("国内专利:" + name)
+                                .content("收到一条待办理登记专利")
+                                .build());
+
             case ANNUAL_FEE://维护费用
             case ANNUAL_FEE://维护费用
                 return ApplyStatus.GRANT_STAGE;//授权阶段
                 return ApplyStatus.GRANT_STAGE;//授权阶段
             default://不答复终止
             default://不答复终止

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

@@ -0,0 +1,20 @@
+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;
+
+@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));
+    }
+}

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

@@ -0,0 +1,67 @@
+package com.izouma.uwip.web;
+
+import com.izouma.uwip.domain.Message;
+import com.izouma.uwip.service.MessageService;
+import com.izouma.uwip.dto.PageQuery;
+import com.izouma.uwip.exception.BusinessException;
+import com.izouma.uwip.repo.MessageRepo;
+import com.izouma.uwip.utils.ObjUtils;
+import com.izouma.uwip.utils.SecurityUtils;
+import com.izouma.uwip.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+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.findMy(SecurityUtils.getAuthenticatedUser().getId());
+    }
+}
+

+ 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"}

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

@@ -318,6 +318,22 @@ const router = new Router({
                     meta: {
                     meta: {
                         title: '异常日志'
                         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**/
                 /**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>