Przeglądaj źródła

feat(server): 水印

Go 4 lat temu
rodzic
commit
d9cc32953d

+ 1 - 1
front/project/admin/routes/subject/examination/page.js

@@ -169,7 +169,7 @@ export default class extends Page {
   deleteAction() {
     const { selectedRows } = this.state;
     asyncDelConfirm('删除确认', '是否删除选中题目?', () => {
-      return Promise.all(selectedRows.map(row => Question.del({ id: row.question_id }))).then(() => {
+      return Promise.all(selectedRows.map(row => Question.delNo({ id: row.id }))).then(() => {
         asyncSMessage('删除成功!');
         this.refresh();
       });

+ 1 - 1
front/project/admin/routes/subject/exercise/page.js

@@ -255,7 +255,7 @@ export default class extends Page {
   deleteAction() {
     const { selectedRows } = this.state;
     asyncDelConfirm('删除确认', '是否删除选中题目?', () => {
-      return Promise.all(selectedRows.map(row => Question.del({ id: row.question_id }))).then(() => {
+      return Promise.all(selectedRows.map(row => Question.delNo({ id: row.id }))).then(() => {
         asyncSMessage('删除成功!');
         this.refresh();
       });

+ 5 - 5
front/project/www/components/OtherModal/index.js

@@ -376,8 +376,8 @@ export class EditInfo extends Component {
       this.setState({ empty: { nickname: !data.nickname } });
       return;
     }
-    if (data.nickname.length < 2 || data.nickname.length > 20) {
-      this.setState({ nicknameError: '用户名长度不足2个自负或超过20个字符' });
+    if (data.nickname.length < 2 || data.nickname.length > 14) {
+      this.setState({ nicknameError: '用户名长度不足2个自负或超过14个字符' });
       return;
     }
     const { nickname, avatar } = data;
@@ -413,7 +413,7 @@ export class EditInfo extends Component {
             <div className="input-layout">
               <Input
                 className="w-10"
-                placeholder="2-20位,不可使用特殊字符。"
+                placeholder="2-14个字符。"
                 value={this.state.data.nickname || ''}
                 error={this.state.nicknameError}
                 empty={this.state.empty.nickname}
@@ -504,7 +504,7 @@ export class EditAvatar extends Component {
       };
     } else {
       const img = new Image();
-      img.onload = function() {
+      img.onload = function () {
         const canvas = document.createElement('canvas');
         canvas.height = img.height;
         canvas.width = img.width;
@@ -1456,7 +1456,7 @@ export class QuestionNoteModal extends Component {
     const { show } = this.props;
     const { data, noteField } = this.state;
     return (
-      <div hidden={!show} className="modal note">
+      <div hidden={!show} className="question-modal note">
         <div className="mask" />
         <div className="body">
           <div className="title">提问</div>

+ 5 - 3
front/project/www/routes/paper/question/detail/index.less

@@ -279,6 +279,8 @@
           .block {
             background: #fff;
             margin-bottom: 5px;
+            overflow: hidden;
+            overflow-y: auto;
           }
 
           .detail {
@@ -335,9 +337,9 @@
               }
             }
 
-            // .answer-block {
-            //   margin-bottom: 5px;
-            // }
+            .answer-block {
+              margin-bottom: 5px;
+            }
           }
 
           .other {

+ 11 - 9
front/project/www/stores/user.js

@@ -89,15 +89,17 @@ export default class UserStore extends BaseStore {
   }
 
   initAfter() {
-    this.refreshToken().then(() => {
-      if (this.adminLogin) {
-        window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
-      }
-    }).catch(() => {
-      if (this.adminLogin) {
-        window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
-      }
-    });
+    if (this.adminLogin || this.state.login) {
+      this.refreshToken().then(() => {
+        if (this.adminLogin) {
+          window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
+        }
+      }).catch(() => {
+        if (this.adminLogin) {
+          window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
+        }
+      });
+    }
   }
 
   needPay(order) {

+ 29 - 0
server/build.gradle

@@ -68,31 +68,51 @@ subprojects {
     dependencies {
         compileClasspath("org.springframework.boot:spring-boot-starter")
         compileClasspath("org.springframework.boot:spring-boot-starter-web")
+        testCompile("org.springframework.boot:spring-boot-starter-web")
         compileClasspath('org.springframework.boot:spring-boot-starter-aop')
+        testCompile('org.springframework.boot:spring-boot-starter-aop')
         compileClasspath('org.springframework.boot:spring-boot-starter-jdbc')
+        testCompile('org.springframework.boot:spring-boot-starter-jdbc')
         compileClasspath('org.springframework.boot:spring-boot-starter-data-jpa')
+        testCompile('org.springframework.boot:spring-boot-starter-data-jpa')
 //	compileClasspath("org.springframework.boot:spring-boot-starter-security")
+//        testCompile("org.springframework.boot:spring-boot-starter-security")
         compileClasspath("org.springframework.boot:spring-boot-starter-actuator")
+        testCompile("org.springframework.boot:spring-boot-starter-actuator")
         compileClasspath('org.springframework.boot:spring-boot-starter-logging')
+        testCompile('org.springframework.boot:spring-boot-starter-logging')
         compileClasspath('org.springframework.boot:spring-boot-starter-cache')
+        testCompile('org.springframework.boot:spring-boot-starter-cache')
         compileClasspath('org.springframework.boot:spring-boot-starter-data-redis')
+        testCompile('org.springframework.boot:spring-boot-starter-data-redis')
         compileClasspath("org.springframework.boot:spring-boot-devtools")
+        testCompile("org.springframework.boot:spring-boot-devtools")
 
         compileClasspath('mysql:mysql-connector-java')
+        testCompile('mysql:mysql-connector-java')
         compileClasspath(libraries."mybatis", libraries."mybatis-page")
+        testCompile(libraries."mybatis", libraries."mybatis-page")
         compileClasspath("tk.mybatis:mapper-spring-boot-starter:2.1.5"){
             exclude group: "javax.persistence"
         }
+        testCompile("tk.mybatis:mapper-spring-boot-starter:2.1.5"){
+            exclude group: "javax.persistence"
+        }
 
         testCompile("org.springframework.boot:spring-boot-starter-test")
 
 
         compileClasspath group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9'
+        testCompile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9'
         compileClasspath group: 'com.alibaba', name: 'fastjson', version: '1.2.46'
+        testCompile group: 'com.alibaba', name: 'fastjson', version: '1.2.46'
         compileClasspath 'javax.persistence:javax.persistence-api:2.2'
+        testCompile 'javax.persistence:javax.persistence-api:2.2'
         compileClasspath group: 'net.ipip', name: 'ipdb', version: '1.1.2'
+        testCompile group: 'net.ipip', name: 'ipdb', version: '1.1.2'
 
         compileClasspath fileTree(dir:'libs',include:['*.jar'])
+        testCompile fileTree(dir:'libs',include:['*.jar'])
     }
 
 //自定义环境 start
@@ -104,6 +124,11 @@ subprojects {
                 srcDirs = ["src/main/resources", "src/main/profile/$env", "src/main/java"]
             }
         }
+        test {
+            resources {
+                srcDirs = ["src/test/resources", "src/main/resources", "src/main/profile/$env", "src/main/java"]
+            }
+        }
     }
 //自定义环境 end
 
@@ -164,5 +189,9 @@ project(':gateway-api') {
         compile(project(":data"))
         compileClasspath project(path:":tools", configuration: 'parentClasspath')
         compileClasspath project(path:":data", configuration: 'parentClasspath')
+        testCompile(project(":tools"))
+        testCompile(project(":data"))
+        testCompile project(path:":tools", configuration: 'parentClasspath')
+        testCompile project(path:":data", configuration: 'parentClasspath')
     }
 }

+ 12 - 4
server/gateway-api/build.gradle

@@ -5,7 +5,6 @@ mainClassName = 'com.qxgmat.Application'
 repositories {
     mavenLocal()
     maven { url = "http://maven.aliyun.com/nexus/content/groups/public" }
-    maven { url = "http://repo.e-iceblue.com/nexus/content/groups/public" }
     mavenCentral()
 }
 
@@ -14,21 +13,30 @@ dependencies {
     // shiro
 //    compile(libraries."shiro-core", libraries."shiro-spring", libraries."shiro-cache")
     compileClasspath libraries."shiro"
+    testCompile libraries."shiro"
 
     // druid
     compileClasspath 'com.alibaba:druid-spring-boot-starter:1.1.10'
+    testCompile 'com.alibaba:druid-spring-boot-starter:1.1.10'
 
     // swagger
     compileClasspath libraries."springfox-bean-validators", libraries."springfox-swagger2", libraries."springfox-swagger-ui"
+    testCompile libraries."springfox-bean-validators", libraries."springfox-swagger2", libraries."springfox-swagger-ui"
 
     compileClasspath 'com.github.penggle:kaptcha:2.3.2'
+    testCompile 'com.github.penggle:kaptcha:2.3.2'
 
     // https://mvnrepository.com/artifact/org.apache.poi/poi
     compileClasspath group: 'org.apache.poi', name: 'poi', version: '3.17'
+    testCompile group: 'org.apache.poi', name: 'poi', version: '3.17'
     compileClasspath group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
+    testCompile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
 
-    compileClasspath group: 'e-iceblue', name: 'spire.pdf', version: '2.2.0'
-
+//    compileClasspath group: 'e-iceblue', name: 'spire.pdf', version: '2.2.0'
+    compileClasspath group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.1'
+    testCompile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.1'
+    compileClasspath group: 'com.itextpdf', name: 'itext-asian', version: '5.2.0'
+    testCompile group: 'com.itextpdf', name: 'itext-asian', version: '5.2.0'
 //    compile group: 'commons-lang', name: 'commons-lang', version:'2.6'
 //    compile group: 'commons-fileupload', name: 'commons-fileupload', version:'1.3.3'
 //    compile group: 'commons-io', name: 'commons-io', version:'2.6'
@@ -62,4 +70,4 @@ bootRun {
 //    dependsOn bootJar
 //    main="org.springframework.boot.loader.PropertiesLauncher"
 //    args("-Dloader.path=${libsDir}/lib -Dloader.debug=true")
-//}
+//}

+ 7 - 6
server/gateway-api/src/main/java/com/qxgmat/controller/admin/SentenceController.java

@@ -119,12 +119,13 @@ public class SentenceController {
         return ResponseHelp.success(true);
     }
 
-//    @RequestMapping(value = "/question/delete", method = RequestMethod.DELETE)
-//    @ApiOperation(value = "删除长难句题目", httpMethod = "DELETE")
-//    public Response<Boolean> deleteQuestion(@RequestParam int id, HttpServletRequest request) {
-//        managerLogService.log(request);
-//        return ResponseHelp.success(sentenceQuestionService.delete(id));
-//    }
+    @RequestMapping(value = "/question/delete", method = RequestMethod.DELETE)
+    @ApiOperation(value = "删除长难句题目", httpMethod = "DELETE")
+    public Response<Boolean> deleteQuestion(@RequestParam int id, HttpServletRequest request) {
+        sentenceService.deleteQuestion(id);
+        managerLogService.log(request);
+        return ResponseHelp.success(true);
+    }
 
     @RequestMapping(value = "/question/detail", method = RequestMethod.GET)
     @ApiOperation(value = "获取长难句题目", httpMethod = "GET")

+ 2 - 2
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -2214,7 +2214,7 @@ public class MyController {
         }
         try {
             String resource = courseData.getResource();
-            String fileName = pdfHelp.generatePdfImage(user.getId(), resource, false);
+            String fileName = pdfHelp.generatePdfImage(user, resource, false);
             FileInputStream fileInputStream = new FileInputStream(fileName);
             ServletOutputStream outputStream = response.getOutputStream();
             response.setHeader("content-disposition","attachment;filename="+fileName);
@@ -2256,7 +2256,7 @@ public class MyController {
                     resource = latest.getQuant();
                     break;
             }
-            String fileName = pdfHelp.generatePdfImage(user.getId(), resource, false);
+            String fileName = pdfHelp.generatePdfImage(user, resource, false);
             FileInputStream fileInputStream = new FileInputStream(fileName);
             ServletOutputStream outputStream = response.getOutputStream();
             response.setHeader("content-disposition","attachment;filename="+fileName);

+ 144 - 65
server/gateway-api/src/main/java/com/qxgmat/help/PdfHelp.java

@@ -1,21 +1,24 @@
 package com.qxgmat.help;
 
-import com.spire.pdf.PdfDocument;
-import com.spire.pdf.PdfPageBase;
-import com.spire.pdf.graphics.*;
-import com.spire.pdf.widget.PdfPageCollection;
+//import com.spire.pdf.PdfDocument;
+//import com.spire.pdf.PdfPageBase;
+//import com.spire.pdf.graphics.*;
+//import com.spire.pdf.widget.PdfPageCollection;
+import com.itextpdf.text.*;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.pdf.*;
+import com.qxgmat.data.dao.entity.User;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import javax.imageio.ImageIO;
 import java.awt.*;
-import java.awt.geom.Dimension2D;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
+import java.awt.Image;
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
 /**
@@ -33,32 +36,28 @@ public class PdfHelp {
 
     @Value("${upload.water}")
     private String water;
-    
-    public String generatePdfImage(Integer userId, String pdfUrl, boolean force) throws IOException {
-        String pdfFile = pdfUrl.replace(webUrl, localPath);
-        String dest = pdfFile.replace(".pdf", String.format("_%d.pdf", userId));
-        File file = new File(dest);
-
-        if (!force && file.exists()){
-            return dest;
-        }
 
-        PdfDocument pdf = new PdfDocument();
-        pdf.loadFromFile(pdfFile);
+    private BaseFont font;
 
-        File srcImgFile = new File(water);
-        Image srcImg = ImageIO.read(srcImgFile);
-
-        BufferedImage bi = toBufferedImage(srcImg);
-        for (Object page: pdf.getPages()) {
-            AddImageWatermark((PdfPageBase)page, bi);
+    @Autowired
+    private void getFont(@Value("${upload.font}") String path) throws IOException, DocumentException {
+        FontFactory.registerDirectories();
+        String sub = "";
+        if (path.toLowerCase().endsWith(".ttc")){
+            sub += ",1";
+        }
+        if (path.startsWith(".")){
+            // 相对路径,从resource中获取
+//            logger.debug("{}, {}", path, this.getClass().getClassLoader().getResource(path.replaceFirst(".","")));
+//            logger.debug("{}, {}", path, this.getClass().getClassLoader().getResource(path));
+            try {
+                font = BaseFont.createFont(this.getClass().getClassLoader().getResource(path.replaceFirst(".","")).toString()+sub,BaseFont.IDENTITY_H,true);
+            }catch (Exception e){
+                font = BaseFont.createFont(this.getClass().getClassLoader().getResource(path).toString()+sub,BaseFont.IDENTITY_H,true);
+            }
+        }else{
+            font = BaseFont.createFont(path+sub,BaseFont.IDENTITY_H,true);
         }
-
-        //保存
-        pdf.saveToFile(dest);
-        //关闭
-        pdf.close();
-        return dest;
     }
 
     public static BufferedImage toBufferedImage(Image img)
@@ -80,40 +79,120 @@ public class PdfHelp {
         return bimage;
     }
 
-    /**
-     * @param page
-     * 要添加水印的页面
-     * @param image
-     * 水印图片路径
-     */
-    static void AddImageWatermark(PdfPageBase page, BufferedImage image)
-    {
-        page.setBackgroundImage(image);
-        Rectangle2D rect = new Rectangle2D.Float();
-        rect.setFrame(page.getClientSize().getWidth()/2 - image.getWidth() / 2, page.getClientSize().getHeight()/2 - image.getHeight()/2, image.getWidth(), image.getHeight());
-        page.setBackgroundRegion(rect);
+    public String generatePdfImage(User user, String pdfUrl, boolean force) throws IOException, DocumentException {
+        String pdfFile = pdfUrl.replace(webUrl, localPath);
+        String dest = pdfFile.replace(".pdf", String.format("_%d.pdf", user.getId()));
+        File file = new File(dest);
+
+        if (!force && file.exists()){
+            return dest;
+        }else if(file.exists()){
+            file.delete();
+        }
+        // 2份水印文字
+        String mobile = user.getMobile().replaceAll("(\\d{3})\\d*(\\d{4})","$1****$2");
+        String name = (user.getRealStatus() > 0? user.getRealName().replaceAll("(.{1}).*(.{1})?","$1*$2 ") : "") + mobile;
+        String qx = "千行ID "+String.format("%04d", user.getId());
+
+        PdfReader reader = new PdfReader(pdfFile);
+        // 如果是web项目,直接下载应该放到response的流里面
+        // PdfStamper stamp = new PdfStamper(reader,response.getOutputStream());
+        // 添加水印之后的pdf文件
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
+        int pageSize = reader.getNumberOfPages();
+        PdfContentByte under;
+        for (int i = 1; i<=pageSize;i++){
+            under = stamper.getUnderContent(i);
+            AddTextWatermark(under, name);
+            AddTextWatermark(under, qx);
+        }
+        stamper.close();
+        reader.close();
+        return dest;
     }
- 
-    /**
-      * @param page
-      * 要添加水印的页面
-      * @param textWatermark
-      * 水印文字
-      */
-    static void AddTextWatermark(PdfPageBase page, String textWatermark)
-    {
-        Dimension2D dimension2D = new Dimension();
-        dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 2, page.getCanvas().getClientSize().getHeight() / 3);
-        PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
-        brush.getGraphics().setTransparency(0.3F);
-        brush.getGraphics().save();
-        brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 2, (float) brush.getSize().getHeight() / 2);
-        brush.getGraphics().rotateTransform(-45);
-        brush.getGraphics().drawString(textWatermark, new PdfTrueTypeFont(new Font("Arial Unicode MS",Font.PLAIN,30),true), PdfBrushes.getRed(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
-        brush.getGraphics().restore();
-        brush.getGraphics().setTransparency(1);
-        Rectangle2D loRect = new Rectangle2D.Float();
-        loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
-        page.getCanvas().drawRectangle(brush, loRect);
+    void AddTextWatermark(PdfContentByte content, String textWatermark){
+        content.saveState();
+        Font f = new Font(font, 10);
+        f.setColor(0,0,0);
+        f.setStyle(Font.NORMAL);
+        PdfGState gs = new PdfGState();
+        gs.setFillOpacity(0.2f);
+        content.setGState(gs);
+        Phrase p = new Phrase(textWatermark, f);
+
+        content.beginText();
+        content.setColorFill(new BaseColor(0,0,0));// 文字水印 颜色
+        content.setFontAndSize(font, 10);// 文字水印 字体及字号
+        content.setTextMatrix(0, 0);// 文字水印 起始位置
+        content.showTextAligned(Element.ALIGN_CENTER, textWatermark, 200, 100, 0);
+        content.endText();
+
+        // 在页面中添加多次,计算为止
+        ColumnText.showTextAligned(content,  Element.ALIGN_CENTER, p, 100f,100f, 0);
+        content.restoreState();
     }
+
+//    public String generatePdfImage(Integer userId, String pdfUrl, boolean force) throws IOException {
+//        String pdfFile = pdfUrl.replace(webUrl, localPath);
+//        String dest = pdfFile.replace(".pdf", String.format("_%d.pdf", userId));
+//        File file = new File(dest);
+//
+//        if (!force && file.exists()){
+//            return dest;
+//        }
+//
+//        PdfDocument pdf = new PdfDocument();
+//        pdf.loadFromFile(pdfFile);
+//
+//        File srcImgFile = new File(water);
+//        Image srcImg = ImageIO.read(srcImgFile);
+//
+//        BufferedImage bi = toBufferedImage(srcImg);
+//        for (Object page: pdf.getPages()) {
+//            AddImageWatermark((PdfPageBase)page, bi);
+//        }
+//
+//        //保存
+//        pdf.saveToFile(dest);
+//        //关闭
+//        pdf.close();
+//        return dest;
+//    }
+
+//    /**
+//     * @param page
+//     * 要添加水印的页面
+//     * @param image
+//     * 水印图片路径
+//     */
+//    static void AddImageWatermark(PdfPageBase page, BufferedImage image)
+//    {
+//        page.setBackgroundImage(image);
+//        Rectangle2D rect = new Rectangle2D.Float();
+//        rect.setFrame(page.getClientSize().getWidth()/2 - image.getWidth() / 2, page.getClientSize().getHeight()/2 - image.getHeight()/2, image.getWidth(), image.getHeight());
+//        page.setBackgroundRegion(rect);
+//    }
+//
+//    /**
+//      * @param page
+//      * 要添加水印的页面
+//      * @param textWatermark
+//      * 水印文字
+//      */
+//    static void AddTextWatermark(PdfPageBase page, String textWatermark)
+//    {
+//        Dimension2D dimension2D = new Dimension();
+//        dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 2, page.getCanvas().getClientSize().getHeight() / 3);
+//        PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
+//        brush.getGraphics().setTransparency(0.3F);
+//        brush.getGraphics().save();
+//        brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 2, (float) brush.getSize().getHeight() / 2);
+//        brush.getGraphics().rotateTransform(-45);
+//        brush.getGraphics().drawString(textWatermark, new PdfTrueTypeFont(new Font("Arial Unicode MS",Font.PLAIN,30),true), PdfBrushes.getRed(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
+//        brush.getGraphics().restore();
+//        brush.getGraphics().setTransparency(1);
+//        Rectangle2D loRect = new Rectangle2D.Float();
+//        loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
+//        page.getCanvas().drawRectangle(brush, loRect);
+//    }
 }

+ 18 - 18
server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java

@@ -147,21 +147,20 @@ public class UsersService extends AbstractService {
                 throw new ParameterException("该微信账户已绑定其他手机号,您可直接使用微信登录");
             }
         }
-        User mm = User.builder()
-                .id(openUser != null ? openUser.getId() : null)
-                .build();
-//        if (openUser ==null || openUser.getAvatar() == null || openUser.getAvatar().isEmpty()) {
-//            mm.setAvatar(data.getAvatar());
-//            if(openUser != null){
-//                openUser.setAvatar(data.getAvatar());
-//            }
-//        }
-//        if (openUser == null || openUser.getNickname() == null|| openUser.getNickname().isEmpty()){
-//            mm.setNickname(data.getNickName());
-//            if(openUser != null){
-//                openUser.setNickname(data.getNickName());
-//            }
-//        }
+        User mm = User.builder().build();
+
+        if (openUser ==null || openUser.getAvatar() == null || openUser.getAvatar().isEmpty()) {
+            mm.setAvatar(data.getAvatar());
+            if(openUser != null){
+                openUser.setAvatar(data.getAvatar());
+            }
+        }
+        if (openUser == null || openUser.getNickname() == null|| openUser.getNickname().isEmpty() || openUser.getNickname().equals("qx"+openUser.getMobile())){
+            mm.setNickname(data.getNickName());
+            if(openUser != null){
+                openUser.setNickname(data.getNickName());
+            }
+        }
 
         switch(platform){
             case "wechat_pc":
@@ -176,8 +175,9 @@ public class UsersService extends AbstractService {
                 mm.setWechatExpireTime(data.getExpiresTime());
                 break;
         }
-        if (mm.getId() != null){
+        if (openUser != null && openUser.getId() != null){
             // 直接更新数据
+            mm.setId(openUser.getId());
             edit(mm);
             return openUser;
         }
@@ -251,8 +251,8 @@ public class UsersService extends AbstractService {
         if(openUser.getWechatUnionid() != null) user.setWechatUnionid(openUser.getWechatUnionid());
         if(openUser.getWechatAccessToken() != null) user.setWechatAccessToken(openUser.getWechatAccessToken());
         if(openUser.getWechatRefreshToken() != null) user.setWechatRefreshToken(openUser.getWechatRefreshToken());
-//        if(openUser.getNickname() != null) user.setNickname(openUser.getNickname());
-//        if(openUser.getAvatar() != null) user.setAvatar(openUser.getAvatar());
+        if(openUser.getNickname() != null && (user.getNickname() == null || user.getNickname().isEmpty() || user.getNickname().equals("qx" + user.getMobile()))) user.setNickname(openUser.getNickname());
+        if(openUser.getAvatar() != null && (user.getAvatar() == null || user.getAvatar().isEmpty())) user.setAvatar(openUser.getAvatar());
         return user;
     }
 

+ 4 - 4
server/gateway-api/src/main/java/com/qxgmat/service/extend/MessageExtendService.java

@@ -307,9 +307,9 @@ public class MessageExtendService {
         map.put("rcDescription", String.valueOf(textbookLibrary.getRcDescription()));
         if (subscribe){
             try {
-                String quant = pdfHelp.generatePdfImage(user.getId(), textbookLibrary.getQuant(), true);
-                String ir = pdfHelp.generatePdfImage(user.getId(), textbookLibrary.getIr(), true);
-                String rc = pdfHelp.generatePdfImage(user.getId(), textbookLibrary.getRc(), true);
+                String quant = pdfHelp.generatePdfImage(user, textbookLibrary.getQuant(), true);
+                String ir = pdfHelp.generatePdfImage(user, textbookLibrary.getIr(), true);
+                String rc = pdfHelp.generatePdfImage(user, textbookLibrary.getRc(), true);
                 map.put("attachments", String.format("%s;%s;%s", quant, ir, rc));
                 send(user, MessageCategory.TEXTBOOK_UPDATE_SUBSCRIBE, map, 0);
             }catch (Exception e){
@@ -602,7 +602,7 @@ public class MessageExtendService {
                 if (subscribe){
                     try{
                         // todo 获取水印文件
-                        String file = pdfHelp.generatePdfImage(user.getId(), data.getResource(), true);
+                        String file = pdfHelp.generatePdfImage(user, data.getResource(), true);
 
                         map.put("attachment", file);
                         send(user, MessageCategory.DATA_UPDATE_SUBSCRIBE, map, data.getId());

+ 9 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/SentenceService.java

@@ -134,6 +134,15 @@ public class SentenceService {
         return sentenceQuestion;
     }
 
+    @Transactional
+    public void deleteQuestion(Integer id){
+        SentenceQuestion in = sentenceQuestionService.get(id);
+        QuestionNo questionNo = questionNoService.get(in.getQuestionNoId());
+        questionNoService.delete(in.getQuestionNoId());
+        questionService.delete(questionNo.getQuestionId());
+        sentenceQuestionService.delete(id);
+    }
+
 
     /**
      * 根据题目创建组卷序列

+ 2 - 1
server/gateway-api/src/main/profile/dev/application-runtime.yml

@@ -84,9 +84,10 @@ spring:
     timeout: 5000
 
 upload:
-  local_path: ../upload/
+  local_path: ../../upload/
   web_url: /upload/
   water: /upload
+  font: ./NotoSansCJK-Bold.ttc
 
 third:
   wechat:

+ 1 - 0
server/gateway-api/src/main/profile/prod/application-runtime.yml

@@ -87,6 +87,7 @@ upload:
   local_path: ../upload/
   web_url: /upload/
   water: /upload
+  font: ./NotoSansCJK-Bold.ttc
 
 third:
   wechat:

+ 1 - 0
server/gateway-api/src/main/profile/test/application-runtime.yml

@@ -87,6 +87,7 @@ upload:
   local_path: ../upload/
   web_url: /upload/
   water: /upload
+  font: ./NotoSansCJK-Bold.ttc
 
 third:
   wechat:

BIN
server/gateway-api/src/main/resources/NotoSansCJK-Bold.ttc


BIN
server/gateway-api/src/main/resources/NotoSerifCJKsc-Bold.otf


+ 24 - 0
server/gateway-api/src/test/java/com/qxgmat/help/pdf.java

@@ -0,0 +1,24 @@
+package com.qxgmat.help;
+
+import com.itextpdf.text.DocumentException;
+import com.qxgmat.data.dao.entity.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class pdf {
+    @Autowired
+    private PdfHelp pdfHelp;
+
+    @Test
+    public void contextLoads() throws IOException, DocumentException {
+        User user = User.builder().id(10).realName("高杰").mobile("15221504895").realStatus(1).build();
+        pdfHelp.generatePdfImage(user, "/upload/123.pdf", true);
+    }
+}