Bladeren bron

短信平台

licailing 4 jaren geleden
bovenliggende
commit
b6fb75da33

+ 7 - 4
src/main/java/com/izouma/wenlvju/domain/Announcement.java

@@ -1,5 +1,6 @@
 package com.izouma.wenlvju.domain;
 package com.izouma.wenlvju.domain;
 
 
+import com.izouma.wenlvju.converter.FileObjectListConverter;
 import com.izouma.wenlvju.enums.AnnouncementType;
 import com.izouma.wenlvju.enums.AnnouncementType;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Builder;
@@ -7,10 +8,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.NoArgsConstructor;
 import org.hibernate.annotations.Where;
 import org.hibernate.annotations.Where;
 
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
+import javax.persistence.*;
+import java.util.List;
 
 
 
 
 @Data
 @Data
@@ -27,4 +26,8 @@ public class Announcement extends BaseEntity {
 
 
     @Column(columnDefinition = "TEXT")
     @Column(columnDefinition = "TEXT")
     private String content;
     private String content;
+
+    @Convert(converter = FileObjectListConverter.class)
+    @Column(columnDefinition = "TEXT")
+    private List<FileObject> annexes;
 }
 }

+ 53 - 0
src/main/java/com/izouma/wenlvju/domain/Message.java

@@ -0,0 +1,53 @@
+package com.izouma.wenlvju.domain;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.izouma.wenlvju.converter.StringArrayConverter;
+import com.izouma.wenlvju.enums.MessageType;
+import com.izouma.wenlvju.security.Authority;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.BatchSize;
+import org.hibernate.annotations.Where;
+
+import javax.persistence.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Entity
+@Where(clause = "del = 0")
+public class Message extends BaseEntity {
+
+    @Enumerated(EnumType.STRING)
+    private MessageType type;
+
+    @Column(columnDefinition = "TEXT")
+    private String content;
+
+    @Convert(converter = StringArrayConverter.class)
+    @Column(columnDefinition = "TEXT")
+    @ApiModelProperty(value = "发送的手机号")
+    private List<String> phone;
+
+    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH})
+    @JoinTable(
+            name = "message_authority",
+            joinColumns = {@JoinColumn(name = "message_id", referencedColumnName = "id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))},
+            inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))})
+    @BatchSize(size = 20)
+    @ExcelIgnore
+    private Set<Authority> authorities = new HashSet<>();
+
+    @ApiModelProperty(value = "返回内容")
+    private String responseBody;
+
+    @ApiModelProperty(value = "是否已发送")
+    private boolean send;
+}

+ 14 - 0
src/main/java/com/izouma/wenlvju/dto/MessageUpload.java

@@ -0,0 +1,14 @@
+package com.izouma.wenlvju.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MessageUpload {
+    @ExcelProperty(value = "手机号")
+    private String phone;
+}

+ 20 - 0
src/main/java/com/izouma/wenlvju/enums/MessageType.java

@@ -0,0 +1,20 @@
+package com.izouma.wenlvju.enums;
+
+public enum MessageType {
+    /*
+    权限
+     */
+    PERMISSION,
+    /*
+    模块
+     */
+    MODULE,
+    /*
+    手动
+     */
+    MANUAL,
+    /*
+    上传
+     */
+    UPLOAD
+}

+ 16 - 0
src/main/java/com/izouma/wenlvju/repo/MessageRepo.java

@@ -0,0 +1,16 @@
+package com.izouma.wenlvju.repo;
+
+import com.izouma.wenlvju.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;
+
+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);
+}

+ 76 - 0
src/main/java/com/izouma/wenlvju/service/MessageService.java

@@ -0,0 +1,76 @@
+package com.izouma.wenlvju.service;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.exception.ExcelAnalysisException;
+import com.alibaba.excel.exception.ExcelDataConvertException;
+import com.alibaba.excel.metadata.CellData;
+import com.izouma.wenlvju.domain.Message;
+import com.izouma.wenlvju.dto.MessageUpload;
+import com.izouma.wenlvju.dto.PageQuery;
+import com.izouma.wenlvju.exception.BusinessException;
+import com.izouma.wenlvju.repo.MessageRepo;
+import com.izouma.wenlvju.utils.JpaUtils;
+import com.izouma.wenlvju.utils.excel.UploadDataListener;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.transaction.Transactional;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@AllArgsConstructor
+public class MessageService {
+
+    private MessageRepo messageRepo;
+
+    public Page<Message> all(PageQuery pageQuery) {
+        return messageRepo.findAll(JpaUtils.toSpecification(pageQuery, Message.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public byte[] excelTemp(HttpServletResponse response) throws IOException {
+        // 设置response的Header
+        response.setContentType("application/pdf");
+        response.setHeader("Content-Disposition", "attachment; filename=" + "Phone.xlsx");
+
+        InputStream is = getClass().getResourceAsStream("/templates/Phone.xlsx");
+        byte[] buffer = new byte[is.available()];
+
+        is.read(buffer);
+        is.close();
+        return buffer;
+    }
+
+    @Transactional(rollbackOn = Exception.class)
+    public List<String> upload(MultipartFile file) {
+        try {
+            InputStream fis = file.getInputStream();
+            UploadDataListener<MessageUpload> listener = new UploadDataListener<>();
+            List<MessageUpload> phones = EasyExcel.read(fis, MessageUpload.class, listener)
+                    .sheet()
+                    .doReadSync();
+            return phones.stream().map(MessageUpload::getPhone).distinct().collect(Collectors.toList());
+        } catch (ExcelAnalysisException e) {
+            e.printStackTrace();
+            if (e.getCause() instanceof ExcelDataConvertException) {
+                ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) e.getCause();
+                String cellMsg = "";
+                String errorMsg = String.format("excel表格:第%s行,第%s列,数据值为:%s,该数据值不符合要求,请检验后重新导入!请检查其他的记录是否有同类型的错误!", excelDataConvertException.getRowIndex() + 1, excelDataConvertException.getColumnIndex(), cellMsg);
+                log.error(errorMsg);
+                throw new BusinessException(errorMsg);
+            }
+
+        } catch (IOException e) {
+            log.error("上传失败", e);
+            throw new BusinessException("上传失败", e.getMessage());
+        }
+        return null;
+    }
+}

+ 3 - 2
src/main/java/com/izouma/wenlvju/service/sms/NjwlSmsService.java

@@ -71,9 +71,9 @@ public class NjwlSmsService {
         return map;
         return map;
     }
     }
 
 
-    public void sendSms(String phone, String message) {
+    public String sendSms(String phone, String message) {
         if (StringUtils.isBlank(phone)) {
         if (StringUtils.isBlank(phone)) {
-            return;
+            return null;
         }
         }
         Map<String, Object> map = new HashMap<>();
         Map<String, Object> map = new HashMap<>();
         Map<String, String> token = this.getToken();
         Map<String, String> token = this.getToken();
@@ -95,6 +95,7 @@ public class NjwlSmsService {
 
 
         String responseBody = writer.toString();
         String responseBody = writer.toString();
         log.info(responseBody);
         log.info(responseBody);
+        return responseBody;
 
 
     }
     }
 
 

+ 85 - 0
src/main/java/com/izouma/wenlvju/web/MessageController.java

@@ -0,0 +1,85 @@
+package com.izouma.wenlvju.web;
+
+import com.izouma.wenlvju.domain.Message;
+import com.izouma.wenlvju.dto.MessageUpload;
+import com.izouma.wenlvju.service.MessageService;
+import com.izouma.wenlvju.dto.PageQuery;
+import com.izouma.wenlvju.exception.BusinessException;
+import com.izouma.wenlvju.repo.MessageRepo;
+import com.izouma.wenlvju.service.sms.NjwlSmsService;
+import com.izouma.wenlvju.utils.ObjUtils;
+import com.izouma.wenlvju.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Page;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+@RestController
+@RequestMapping("/message")
+@AllArgsConstructor
+public class MessageController extends BaseController {
+    private MessageService messageService;
+    private MessageRepo    messageRepo;
+    private NjwlSmsService njwlSmsService;
+
+    //@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);
+    }
+
+    @GetMapping("/send/{id}")
+    public void send(@PathVariable Long id) {
+        Message message = messageRepo.findById(id).orElseThrow(new BusinessException("无短信内容"));
+        String result = njwlSmsService.sendSms(String.join(",", message.getPhone()), message.getContent());
+        message.setResponseBody(result);
+        messageRepo.save(message);
+    }
+
+
+    //@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(value = "/excelTemp", produces = "application/vnd.ms-excel;charset=utf-8")
+    public byte[] excelTemp(HttpServletResponse response) throws IOException {
+        return messageService.excelTemp(response);
+    }
+
+    @PostMapping("/upload")
+    public List<String> uploadFile(@RequestParam("file") MultipartFile file) {
+        return messageService.upload(file);
+    }
+}
+

+ 14 - 4
src/main/java/com/izouma/wenlvju/web/UserController.java

@@ -1,5 +1,6 @@
 package com.izouma.wenlvju.web;
 package com.izouma.wenlvju.web;
 
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import com.izouma.wenlvju.domain.User;
 import com.izouma.wenlvju.domain.User;
@@ -30,6 +31,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 @AllArgsConstructor
 @AllArgsConstructor
 @RestController
 @RestController
@@ -106,13 +109,20 @@ public class UserController extends BaseController {
     @PostMapping("/all2")
     @PostMapping("/all2")
     public Page<User> all2(@RequestBody PageQuery pageQuery) {
     public Page<User> all2(@RequestBody PageQuery pageQuery) {
         List<Authority> authorities = new ArrayList<>();
         List<Authority> authorities = new ArrayList<>();
-//        authorities.add(Authority.get(AuthorityName.ROLE_DISTRICT));
         authorities.add(Authority.get(AuthorityName.ROLE_ORGANIZER));
         authorities.add(Authority.get(AuthorityName.ROLE_ORGANIZER));
-//        authorities.add(Authority.get(AuthorityName.ROLE_ADMIN));
-//        authorities.add(Authority.get(AuthorityName.ROLE_DEV));
         authorities.add(Authority.get(AuthorityName.ROLE_SUPERVISOR));
         authorities.add(Authority.get(AuthorityName.ROLE_SUPERVISOR));
         authorities.add(Authority.get(AuthorityName.ROLE_USER));
         authorities.add(Authority.get(AuthorityName.ROLE_USER));
-//        authorities.add(Authority.get(AuthorityName.ROLE_DISTRICT_STAFF));
+        return userService.byAuthority(pageQuery, authorities);
+    }
+
+    @PostMapping("/byAuthority")
+    public Page<User> byAuthority(@RequestBody PageQuery pageQuery) {
+        Map<String, Object> query = pageQuery.getQuery();
+        List<String> names = Convert.toList(String.class, query.get("authorities"));
+        List<Authority> authorities = names.stream()
+                .map(name -> Authority.get(AuthorityName.valueOf(name)))
+                .collect(Collectors.toList());
+        query.remove("authorities");
         return userService.byAuthority(pageQuery, authorities);
         return userService.byAuthority(pageQuery, authorities);
     }
     }
 
 

+ 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/wenlvju/src/main/java/com/izouma/wenlvju","viewPath":"/Users/qiufangchao/Desktop/project/wenlvju/src/main/vue/src/views","routerPath":"/Users/qiufangchao/Desktop/project/wenlvju/src/main/vue/src","resourcesPath":"/Users/qiufangchao/Desktop/project/wenlvju/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"type","modelName":"type","remark":"类型","showInList":true,"showInForm":true,"formType":"select","apiFlag":"1","optionsValue":"[{\"label\":\"人员\",\"value\":\"PERMISSION\"},{\"label\":\"模块\",\"value\":\"MANUAL\"}]"},{"name":"detail","modelName":"detail","remark":"详情","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"moduleDetail","modelName":"moduleDetail","remark":"详细","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"content","modelName":"content","remark":"内容","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"phone","modelName":"phone","remark":"发送的手机号","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"responseBody","modelName":"responseBody","remark":"返回内容","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.wenlvju","tablePackage":"com.izouma.wenlvju.domain.Message"}

BIN
src/main/resources/templates/Phone.xlsx


File diff suppressed because it is too large
+ 0 - 0
src/main/resources/templates/RateTemplate.ftl


+ 285 - 0
src/main/vue/src/components/FileUpload3.vue

@@ -0,0 +1,285 @@
+<template>
+    <el-upload
+        class="file-upload"
+        :action="uploadUrl"
+        :on-success="onSuccess"
+        :headers="headers"
+        :file-list="fileList"
+        :limit="filesLimit"
+        :on-exceed="onExceed"
+        :on-preview="onPreview"
+        ref="upload"
+        :disabled="readonly"
+    >
+        <el-button type="primary" size="mini" slot="trigger" :disabled="readonly" plain>
+            点击上传
+        </el-button>
+        <div class="file-list-item" slot="file" slot-scope="{ file }">
+            <div class="file-name">
+                <i class="status-icon el-icon-warning-outline danger" v-if="file.status === 'fail'"></i>
+                <i class="status-icon el-icon-circle-check success" v-else-if="file.status === 'success'"></i>
+                <i class="status-icon el-icon-loading" v-else></i>
+                {{ file.name }}
+                <i class="opt">
+                    <i
+                        class="opt-icon el-icon-search"
+                        v-if="file.status === 'success' && isImage(file)"
+                        @click="preview(file)"
+                    ></i>
+                    <i
+                        class="opt-icon el-icon-search"
+                        v-if="file.status === 'success' && isPdf(file)"
+                        @click="previewPdf(file)"
+                    ></i>
+                    <i
+                        class="opt-icon el-icon-search"
+                        v-if="file.status === 'success' && isDoc(file)"
+                        @click="previewDoc(file)"
+                    ></i>
+                    <i class="opt-icon el-icon-download" v-if="file.status === 'success'" @click="download(file)"></i>
+                    <i class="opt-icon el-icon-delete" @click="removeFile(file)" v-if="!readonly"></i>
+                </i>
+            </div>
+            <el-progress
+                v-if="file.status === 'uploading'"
+                :percentage="file.percentage"
+                :show-text="false"
+                :stroke-width="2"
+                class="upload-progress"
+            ></el-progress>
+        </div>
+        <el-image style="width:0;height:0;" :src="previewUrl" :preview-src-list="previewList" ref="preview"> </el-image>
+    </el-upload>
+</template>
+
+<script>
+import resolveUrl from 'resolve-url';
+import axios from 'axios';
+export default {
+    name: 'FileUpload',
+    props: {
+        single: {
+            type: Boolean,
+            default() {
+                return false;
+            }
+        },
+        readonly: {
+            type: Boolean,
+            default() {
+                return false;
+            }
+        },
+        limit: {
+            type: Number,
+            default() {
+                return 50000;
+            }
+        },
+        value: {},
+        format: {
+            type: String,
+            default: 'string'
+        }
+    },
+    data() {
+        return {
+            fileList: [],
+            emitting: false,
+            uploadUrl: '',
+            previewUrl: null
+        };
+    },
+    computed: {
+        headers() {
+            return {
+                Authorization: 'Bearer ' + sessionStorage.getItem('token')
+            };
+        },
+        filesLimit() {
+            if (this.single) {
+                return 1;
+            }
+            return this.limit;
+        },
+        disabled() {
+            return this.fileList.length >= this.limit;
+        },
+        previewList() {
+            return [...this.fileList]
+                .filter(item => {
+                    return this.isImage(item);
+                })
+                .map(item => {
+                    return item.url;
+                });
+        }
+    },
+    created() {
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
+        this.update(this.value);
+    },
+    methods: {
+        onSuccess(res, file, fileList) {
+            file.url = res;
+            this.fileList = fileList;
+            this.emit();
+        },
+        update(value) {
+            if (this.filesLimit === 1) {
+                if (this.format === 'json') {
+                    this.fileList = value ? [{ name: value.name, url: value.url }] : [];
+                } else {
+                    this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
+                }
+            } else {
+                if (!value) {
+                    this.fileList = [];
+                } else {
+                    this.fileList = value.map(i => {
+                        if (this.format === 'json') {
+                            return { name: i.name, url: i.url };
+                        } else {
+                            return { name: i.split('/').pop(), url: i };
+                        }
+                        // return { name: i.name, url: i.url };
+                    });
+                }
+            }
+        },
+        onExceed(files, fileList) {
+            console.log(files, fileList);
+            this.$message.error(`最多上传${this.filesLimit}个文件`);
+        },
+        onPreview(file) {
+            console.log(file);
+        },
+        removeFile(file) {
+            if (file.status === 'uploading') {
+                this.$refs.upload.abort(file);
+            } else if (file.status === 'success') {
+                let index = this.fileList.findIndex(i => i.url === file.url);
+                if (index > -1) {
+                    this.fileList.splice(index, 1);
+                }
+            }
+            this.emit();
+        },
+        download(file) {
+            window.open(file.url, '_blank');
+        },
+        preview(file) {
+            this.previewUrl = file.url;
+            this.$nextTick(() => {
+                this.$refs.preview.clickHandler();
+            });
+        },
+        previewDoc(file) {
+            window.open('https://view.officeapps.live.com/op/view.aspx?src=' + file.url, '_blank');
+        },
+        previewPdf(file) {
+            window.open(this.$baseUrl + '/pdf/web/viewer.html?file=' + file.url, '_blank');
+        },
+        isImage(file) {
+            return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
+        },
+        isPdf(file) {
+            return /\.(pdf)$/i.test(file.url);
+        },
+        isDoc(file) {
+            return /\.(docx|doc)$/i.test(file.url);
+        },
+        emit() {
+            this.emitting = true;
+            if (this.filesLimit === 1) {
+                if (this.format === 'json') {
+                    this.$emit(
+                        'input',
+                        this.fileList[0]
+                            ? {
+                                  name: this.fileList[0].name,
+                                  url: this.fileList[0].url
+                              }
+                            : null
+                    );
+                } else {
+                    this.$emit('input', this.fileList[0] ? this.fileList[0].url : null);
+                }
+            } else {
+                if (this.format === 'json') {
+                    this.$emit(
+                        'input',
+                        this.fileList.map(i => {
+                            return {
+                                name: i.name,
+                                url: i.url
+                            };
+                        })
+                    );
+                } else {
+                    this.$emit(
+                        'input',
+                        this.fileList.map(i => i.url)
+                    );
+                }
+            }
+            this.$nextTick(() => {
+                this.emitting = false;
+            });
+        }
+    },
+    watch: {
+        value(value) {
+            if (this.emitting) return;
+            this.update(value);
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.file-list-item {
+    line-height: 1.8;
+    margin-top: 5px;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    overflow: hidden;
+    cursor: pointer;
+    .file-name {
+        padding: 0 90px 0 20px;
+    }
+    .upload-progress {
+        margin-top: 2px;
+        position: absolute;
+        bottom: 0;
+        left: 20px;
+        right: 0;
+        width: auto;
+    }
+    .danger {
+        color: #f56c6c;
+    }
+    .success {
+        color: #67c23a;
+    }
+    .status-icon {
+        position: absolute;
+        left: 0;
+        top: 0;
+        line-height: inherit;
+    }
+    .opt {
+        position: absolute;
+        right: 0;
+        top: 0;
+        line-height: inherit;
+        .opt-icon {
+            margin-left: 15px;
+            transition: color 0.3s;
+            &:hover {
+                color: #409eff;
+            }
+        }
+    }
+}
+</style>

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

@@ -824,6 +824,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**/
             ]
             ]

+ 97 - 1
src/main/vue/src/views/AnnouncementDetail.vue

@@ -2,7 +2,31 @@
     <div class="edit-view">
     <div class="edit-view">
         <div class="title">{{ formData.title }}</div>
         <div class="title">{{ formData.title }}</div>
         <div class="time">发布时间:{{ formData.createdAt }}</div>
         <div class="time">发布时间:{{ formData.createdAt }}</div>
-        <div class="content" v-html="formData.content"></div>
+        <div style="min-height: 400px">
+            <div class="content" v-html="formData.content"></div>
+            <div v-if="formData.annexes" style="padding: 20px 50px">
+                <div class="file-list-item" v-for="(file, index) in formData.annexes" :key="index">
+                    <div class="file-name">
+                        <i class="status-icon el-icon-circle-check success"></i>
+
+                        {{ file.name }}
+                        <i class="opt">
+                            <i class="opt-icon el-icon-search" v-if="isImage(file)" @click="preview(file)"></i>
+                            <i class="opt-icon el-icon-search" v-if="isPdf(file)" @click="previewPdf(file)"></i>
+                            <i class="opt-icon el-icon-search" v-if="isDoc(file)" @click="previewDoc(file)"></i>
+                            <i class="opt-icon el-icon-download" @click="download(file)"></i>
+                        </i>
+                    </div>
+                    <el-progress
+                        v-if="file.status === 'uploading'"
+                        :percentage="file.percentage"
+                        :show-text="false"
+                        :stroke-width="2"
+                        class="upload-progress"
+                    ></el-progress>
+                </div>
+            </div>
+        </div>
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
@@ -70,6 +94,30 @@ export default {
                         this.$message.error((e || {}).error || '删除失败');
                         this.$message.error((e || {}).error || '删除失败');
                     }
                     }
                 });
                 });
+        },
+        download(file) {
+            window.open(file.url, '_blank');
+        },
+        preview(file) {
+            this.previewUrl = file.url;
+            this.$nextTick(() => {
+                this.$refs.preview.clickHandler();
+            });
+        },
+        previewDoc(file) {
+            window.open('https://view.officeapps.live.com/op/view.aspx?src=' + file.url, '_blank');
+        },
+        previewPdf(file) {
+            window.open(this.$baseUrl + '/pdf/web/viewer.html?file=' + file.url, '_blank');
+        },
+        isImage(file) {
+            return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
+        },
+        isPdf(file) {
+            return /\.(pdf)$/i.test(file.url);
+        },
+        isDoc(file) {
+            return /\.(docx|doc)$/i.test(file.url);
         }
         }
     }
     }
 };
 };
@@ -90,5 +138,53 @@ export default {
 
 
 .content {
 .content {
     padding: 20px 50px;
     padding: 20px 50px;
+    // min-height: 500px;
+}
+.file-list-item {
+    font-size: 14px;
+    color: #2f2f31;
+    line-height: 1.8;
+    margin-top: 5px;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    overflow: hidden;
+    cursor: pointer;
+    position: relative;
+    .file-name {
+        padding: 0 20px 0 20px;
+    }
+    .upload-progress {
+        margin-top: 2px;
+        position: absolute;
+        bottom: 0;
+        left: 20px;
+        right: 0;
+        width: auto;
+    }
+    .danger {
+        color: #f56c6c;
+    }
+    .success {
+        color: #67c23a;
+    }
+    .status-icon {
+        position: absolute;
+        left: 0;
+        top: 0;
+        line-height: inherit;
+    }
+    .opt {
+        // position: absolute;
+        right: 0;
+        top: 0;
+        line-height: inherit;
+        .opt-icon {
+            margin-left: 15px;
+            transition: color 0.3s;
+            &:hover {
+                color: #409eff;
+            }
+        }
+    }
 }
 }
 </style>
 </style>

+ 5 - 0
src/main/vue/src/views/AnnouncementEdit.vue

@@ -22,6 +22,9 @@
             <el-form-item prop="content" label="内容">
             <el-form-item prop="content" label="内容">
                 <rich-text v-model="formData.content"></rich-text>
                 <rich-text v-model="formData.content"></rich-text>
             </el-form-item>
             </el-form-item>
+            <el-form-item prop="annexes" label="附件">
+                <file-upload format="json" v-model="formData.annexes"></file-upload>
+            </el-form-item>
             <el-form-item>
             <el-form-item>
                 <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
                 <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
                 <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id">删除 </el-button>
                 <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id">删除 </el-button>
@@ -31,7 +34,9 @@
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
+import FileUpload from '../components/FileUpload.vue';
 export default {
 export default {
+    components: { FileUpload },
     name: 'AnnouncementEdit',
     name: 'AnnouncementEdit',
     created() {
     created() {
         if (this.$route.query.id) {
         if (this.$route.query.id) {

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

@@ -0,0 +1,322 @@
+<template>
+    <div class="edit-view">
+        <el-form
+            :model="formData"
+            :rules="rules"
+            ref="form"
+            label-width="108px"
+            label-position="right"
+            size="small"
+            style="max-width: 700px;"
+        >
+            <el-form-item prop="type" label="发送类型">
+                <el-select v-model="formData.type" clearable filterable placeholder="请选择" :disabled="formData.send">
+                    <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item prop="authorities" label="角色权限" v-if="formData.type == 'PERMISSION'">
+                <el-select
+                    v-model="formData.authorities"
+                    multiple
+                    placeholder="请选择"
+                    value-key="name"
+                    style="width:70%"
+                    @change="changeAuth"
+                    :disabled="formData.send"
+                >
+                    <el-option v-for="item in authorities" :key="item.name" :label="item.description" :value="item">
+                    </el-option>
+                </el-select>
+                <el-button style="margin-left: 20px" @click="showUser">查看人员</el-button>
+            </el-form-item>
+            <el-form-item label="模版" v-if="formData.type == 'UPLOAD'">
+                <el-button @click="downloadTemp">手机号模版下载</el-button>
+                <el-upload
+                    :action="uploadUrl"
+                    :before-upload="beforeUpload"
+                    :headers="headers"
+                    :show-file-list="false"
+                    ref="upload"
+                    :on-success="onSuccess"
+                    class="uploader"
+                    :on-error="onfail"
+                    :loading="loading"
+                    :disabled="loading || formData.send"
+                >
+                    <el-button slot="trigger" :loading="loading" :disabled="loading || formData.send"
+                        >导入手机号</el-button
+                    >
+                </el-upload>
+            </el-form-item>
+            <el-form-item prop="phone" label="手机号">
+                <!-- <el-input v-model="formData.phone"></el-input> -->
+                <el-select
+                    v-model="formData.phone"
+                    class="suffix"
+                    multiple
+                    style="width: 100%"
+                    filterable
+                    allow-create
+                    default-first-option
+                    placeholder="请输入手机号,按回车分割"
+                    clearable
+                    popper-class="hideSelect"
+                    :disabled="formData.send"
+                >
+                </el-select>
+            </el-form-item>
+            <el-form-item prop="content" label="短信内容">
+                <el-input type="textarea" :rows="6" v-model="formData.content" :readonly="formData.send"></el-input>
+            </el-form-item>
+            <el-form-item prop="responseBody" label="返回内容" v-if="formData.responseBody">
+                <el-input v-model="formData.responseBody" :readonly="formData.send"></el-input>
+            </el-form-item>
+            <el-form-item>
+                <el-button @click="submit(false)" :loading="saving" type="primary" v-if="!formData.send"
+                    >保存</el-button
+                >
+                <el-button @click="onSave" :loading="saving" type="success" v-if="!formData.send">发送</el-button>
+                <el-button @click="sendToo" :loading="saving" type="success" v-if="formData.send">再次发送</el-button>
+                <el-button @click="onDelete" :loading="saving" type="danger" v-if="formData.id">删除 </el-button>
+                <el-button @click="$router.go(-1)">取消</el-button>
+            </el-form-item>
+        </el-form>
+        <el-dialog title="待发送人员" :visible.sync="dialogShow" style="min-height:400px">
+            <el-table
+                :data="users"
+                row-key="id"
+                ref="table"
+                height="tableHeight"
+                header-row-class-name="table-header-row"
+                header-cell-class-name="table-header-cell"
+                row-class-name="table-row"
+                cell-class-name="table-cell"
+            >
+                <el-table-column prop="nickname" label="昵称" min-width="100"> </el-table-column>
+                <el-table-column prop="phone" label="手机号" min-width="100"> </el-table-column>
+                <el-table-column prop="work" label="工作单位" min-width="100"> </el-table-column>
+            </el-table>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import resolveUrl from 'resolve-url';
+export default {
+    name: 'MessageEdit',
+    created() {
+        this.uploadUrl = resolveUrl(this.$baseUrl, 'message/upload');
+        if (this.$route.query.id) {
+            this.get(this.$route.query.id);
+        }
+        this.$http
+            .get('/authority/all')
+            .then(res => {
+                this.authorities = res;
+            })
+            .catch(e => {
+                console.log(e);
+            });
+    },
+    data() {
+        return {
+            saving: false,
+            formData: {},
+            rules: {
+                type: [{ required: true, message: '请选择发送类型', trigger: 'blur' }],
+                phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
+                content: [{ required: true, message: '请输入短信内容', trigger: 'blur' }]
+            },
+            typeOptions: [
+                { label: '按角色权限选择', value: 'PERMISSION' },
+                { label: '手动输入手机号', value: 'MANUAL' },
+                { label: '批量上传手机号', value: 'UPLOAD' }
+            ],
+            authorities: [],
+            loading: false,
+            users: [],
+            dialogShow: false
+        };
+    },
+    computed: {
+        headers() {
+            return {
+                Authorization: 'Bearer ' + sessionStorage.getItem('token')
+            };
+        }
+    },
+    methods: {
+        sendToo() {
+            this.formData.id = '';
+            this.formData.responseBody = '';
+            this.onSave();
+        },
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    return this.$confirm('确认要发送短信吗?', '提示', {
+                        confirmButtonText: '确定',
+                        cancelButtonText: '取消'
+                    }).then(() => {
+                        this.submit(true);
+                    });
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit(send) {
+            let data = { ...this.formData, send: send };
+
+            this.saving = true;
+            this.$http
+                .post('/message/save', data, { body: 'json' })
+                .then(res => {
+                    this.saving = false;
+                    if (send) {
+                        this.$http.get(`/message/send/${res.id}`);
+                    }
+                    this.$message.success('成功');
+                    // this.$router.go(-1);
+                    this.$router.replace({
+                        query: {
+                            id: res.id
+                        }
+                    });
+                    this.formData.send = res.send;
+                    this.formData.responseBody = res.responseBody;
+                })
+                .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 || '删除失败');
+                    }
+                });
+        },
+        downloadTemp() {
+            this.downloading = true;
+            this.$axios
+                .get('/message/excelTemp', {
+                    responseType: 'blob'
+                })
+                .then(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);
+                });
+        },
+        beforeUpload() {
+            return this.$confirm('确认要导入表格吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.loading = true;
+            });
+        },
+        upload() {},
+        onfail(e) {
+            console.log(e);
+            this.$message.error('失败:' + e);
+            this.loading = false;
+        },
+        onSuccess(res) {
+            console.log(res);
+            this.formData.phone = res;
+            this.$message.success('上传成功');
+            this.loading = false;
+        },
+        showUser() {
+            this.dialogShow = true;
+            if (this.formData.send) {
+                let data = this.formData.authorities.map(item => {
+                    return item.name;
+                });
+                if (this.formData.authorities.length > 0) {
+                    this.$http
+                        .post(
+                            '/user/byAuthority',
+                            { size: 1000, query: { del: false, authorities: data.join(',') } },
+                            { body: 'json' }
+                        )
+                        .then(res => {
+                            this.users = res.content;
+                        })
+                        .catch(e => {
+                            console.log(e);
+                        });
+                }
+            }
+        },
+        changeAuth(res) {
+            let data = res.map(item => {
+                return item.name;
+            });
+            // console.log(res);
+            if (res.length == 0) {
+                this.formData.phone = [];
+            }
+            if (res.length > 0) {
+                this.$http
+                    .post(
+                        '/user/byAuthority',
+                        { size: 1000, query: { del: false, authorities: data.join(',') } },
+                        { body: 'json' }
+                    )
+                    .then(res => {
+                        this.users = res.content;
+                        let phone = this.users.map(item => {
+                            return item.phone;
+                        });
+                        this.formData.phone = phone;
+                    })
+                    .catch(e => {
+                        console.log(e);
+                    });
+            }
+        },
+        get(id) {
+            this.$http
+                .get('message/get/' + id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.uploader {
+    display: inline-block;
+    margin: 0 10px;
+}
+</style>

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

@@ -0,0 +1,173 @@
+<template>
+    <div class="list-view">
+        <div class="filters-container">
+            <el-input placeholder="输入关键字" v-model="search" clearable class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button>
+            <el-button
+                @click="download"
+                type="primary"
+                icon="el-icon-download"
+                :loading="downloading"
+                class="filter-item"
+                >导出EXCEL
+            </el-button>
+        </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="type" label="类型" :formatter="typeFormatter"> </el-table-column>
+            <el-table-column prop="content" label="内容"> </el-table-column>
+            <el-table-column prop="phone" label="发送的手机号"> </el-table-column>
+            <el-table-column prop="responseBody" 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
+                        ><span v-if="row.send">查看</span><span v-else>编辑</span></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,
+            typeOptions: [
+                { label: '按角色权限选择', value: 'PERMISSION' },
+                { label: '手动输入手机号', value: 'MANUAL' },
+                { label: '批量上传手机号', value: 'UPLOAD' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        typeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        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>

+ 1 - 1
src/main/vue/src/views/user/StaffList.vue

@@ -73,7 +73,7 @@ export default {
             if (this.search) {
             if (this.search) {
                 data.search = this.search;
                 data.search = this.search;
             }
             }
-            console.log(this.getAdmin());
+            // console.log(this.getAdmin());
             if (!this.getAdmin()) {
             if (!this.getAdmin()) {
                 data.query.id = this.userInfo.id;
                 data.query.id = this.userInfo.id;
             }
             }

+ 1 - 1
src/main/vue/src/views/user/UserList.vue

@@ -102,7 +102,7 @@ export default {
                 data.search = this.search;
                 data.search = this.search;
                 data.page = 0;
                 data.page = 0;
             }
             }
-            console.log(this.getAdmin());
+            // console.log(this.getAdmin());
             if (!this.getAdmin()) {
             if (!this.getAdmin()) {
                 data.query.id = this.userInfo.id;
                 data.query.id = this.userInfo.id;
             }
             }

+ 7 - 6
src/test/java/com/izouma/wenlvju/service/RateServiceTest.java

@@ -36,9 +36,9 @@ public class RateServiceTest extends ApplicationTests {
     @Test
     @Test
     public void test2() {
     public void test2() {
 
 
-//        Rate rate = rateRepo.findById(11825L).orElseThrow(new BusinessException("无记录"));
-        List<Rate> rates = rateRepo.findAllByStatusAndYearOrderByScoreDesc(RateStatus.COLLECT_PAPER_MATERIALS, "2021");
-        rates.forEach(rate -> {
+        Rate rate = rateRepo.findById(10270L).orElseThrow(new BusinessException("无记录"));
+//        List<Rate> rates = rateRepo.findAllByStatusAndYearOrderByScoreDesc(RateStatus.COLLECT_PAPER_MATERIALS, "2021");
+//        rates.forEach(rate -> {
 
 
             List<InputStream> files = null;
             List<InputStream> files = null;
             try {
             try {
@@ -47,7 +47,7 @@ public class RateServiceTest extends ApplicationTests {
                 e.printStackTrace();
                 e.printStackTrace();
             }
             }
 
 
-            String targetPath = "/Users/qiufangchao/Desktop/rate/material" + rate.getId() + ".pdf";
+            String targetPath = "/Users/qiufangchao/Desktop/material" + rate.getId() + ".pdf";
 //            if (!new File(targetPath).exists()) {
 //            if (!new File(targetPath).exists()) {
             // pdf合并工具类
             // pdf合并工具类
             PDFMergerUtility mergePdf = new PDFMergerUtility();
             PDFMergerUtility mergePdf = new PDFMergerUtility();
@@ -62,6 +62,7 @@ public class RateServiceTest extends ApplicationTests {
             mergePdf.setDestinationFileName(targetPath);
             mergePdf.setDestinationFileName(targetPath);
             // 合并pdf
             // 合并pdf
             try {
             try {
+//                System.setProperty("https.protocols", "TLSv1,SSLv3");
                 mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
                 mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
                 for (InputStream is : files) {
                 for (InputStream is : files) {
                     is.close();
                     is.close();
@@ -70,7 +71,7 @@ public class RateServiceTest extends ApplicationTests {
                 e.printStackTrace();
                 e.printStackTrace();
             }
             }
 //            }
 //            }
-        });
+//        });
 
 
 //        System.out.println(writer.toString());
 //        System.out.println(writer.toString());
 //        new File(targetPath);
 //        new File(targetPath);
@@ -118,7 +119,7 @@ public class RateServiceTest extends ApplicationTests {
 
 
     @Test
     @Test
     public void test7() throws IOException {
     public void test7() throws IOException {
-        Rate rate = rateRepo.findById(625L).orElse(null);
+        Rate rate = rateRepo.findById(10270L).orElse(null);
         String export = rateService.export(rate);
         String export = rateService.export(rate);
         InputStream is = new ByteArrayInputStream(export.getBytes());
         InputStream is = new ByteArrayInputStream(export.getBytes());
 
 

Some files were not shown because too many files changed in this diff