From 83fdf8582cd37b0603dba3f4d0a869453722e292 Mon Sep 17 00:00:00 2001
From: wayne <wayne8692wayne8692@gmail.com>
Date: 星期一, 29 十一月 2021 12:03:38 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 PAMapp/pages/login/index.vue                                                      |   47 +++++++----
 pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java             |    1 
 pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java |   62 +++++++++++++++
 pamapi/src/doc/登入API/顧問登入驗證碼流程.txt                                                |   29 +++++++
 pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java              |   68 +++++++++++++++++
 5 files changed, 191 insertions(+), 16 deletions(-)

diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue
index 865dc7f..f1cb6f7 100644
--- a/PAMapp/pages/login/index.vue
+++ b/PAMapp/pages/login/index.vue
@@ -119,8 +119,9 @@
       <el-row type="flex" justify="center" class="pam-login-page__action-bar mt-30">
         <el-button
           type="primary"
-          v-if="connectDevice === 'MOBILE' && onPhoneVerifyStep === 'INPUT_OTP'"
-          :disabled="!otpCode || !phoneNumber || !phoneValid"
+          v-if="connectDevice === 'MOBILE'
+              && onPhoneVerifyStep === 'INPUT_OTP'"
+          :disabled="isSubmitBtnDisabled"
           @click="phoneLogin">
           �
         </el-button>
@@ -129,7 +130,7 @@
       <el-dialog
         title="甇∟�雿輻��"
         :custom-class="'pam-register-dialog'"
-        :visible.sync="registerDialogVisable"
+        :visible.sync="registerDialogVisible"
         :fullscreen="true"
         :close-on-click-modal="false"
         :show-close="false"
@@ -153,7 +154,8 @@
           <el-row class="pt-10">
             <div
               class="mdTxt pam-register-dialog__contract"
-              @scroll="detectContructReadStatus">
+              ref="contract"
+              @scroll="detectContractReadStatus">
               <h3>����犖鞈��鈭��</h3>
               <p class="mt-10">
               �摰�犖鞈��風瘜��������犖鞈����������
@@ -216,15 +218,15 @@
           </el-row>
           <el-row class="pt-30">
             <div class="pam-agree-radio">
-              <label for="agreeControct" class="pam-radio"
+              <label for="agreeContract" class="pam-radio"
                 :class="{disabled: !isReadContract}">
                 <input
                   type="radio"
-                  id="agreeControct"
-                  @click="agreeControct = !agreeControct"
+                  id="agreeContract"
+                  @click="agreeContract = !agreeContract"
                   :disabled="!isReadContract"
-                  value="agreeControct">
-                  <i :class="agreeControct ?'icon-checkbox-1': 'icon-checkbox'"></i>����蒂蝜潛��
+                  value="agreeContract">
+                  <i :class="agreeContract ?'icon-checkbox-1': 'icon-checkbox'"></i>����蒂蝜潛��
               </label>
             </div>
           </el-row>
@@ -232,7 +234,7 @@
         <span slot="footer" class="dialog-footer">
           <el-button
             type="primary"
-            :disabled="!name || !agreeControct || !isReadContract"
+            :disabled="!name || !agreeContract || !isReadContract"
             @click="applyAccount"
             >撱箇�撣唾��
           </el-button>
@@ -288,7 +290,7 @@
 
 <script lang="ts">
 import { namespace } from 'nuxt-property-decorator';
-import { Vue, Component } from 'vue-property-decorator';
+import { Vue, Component, Ref } from 'vue-property-decorator';
 import { LoginRequest, loginVerify, OtpInfo, register, RegisterInfo, sendOtp } from '~/assets/ts/api/consultant';
 import { Role } from '~/assets/ts/models/enum/Role';
 
@@ -298,6 +300,7 @@
 export default class Login extends Vue {
   @roleStorage.Mutation storageIdToken!: (token:string) => void;
   @roleStorage.Mutation storageRole!: (role:string) => void;
+  @Ref('contract') readonly contract!: any;
 
   connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE';
 
@@ -309,6 +312,10 @@
   otpInterval: any;
   phoneOtpInfo!: OtpInfo;
 
+  get isSubmitBtnDisabled(): boolean {
+    return !this.otpCode || !this.phoneNumber || !this.phoneValid;
+  }
+
   email = '';
   onEmailVerifyResendStatus: 'APPLY_OTP' | 'CAN_RESEND' = 'APPLY_OTP';
   emailResendCounter = 30;
@@ -316,18 +323,18 @@
   emailOtpInfo!: OtpInfo;
 
   name = '';
-  agreeControct = false;
+  agreeContract = false;
   isReadContract = false;
 
   phoneSuccessConfirmVisable = false;
   emailOtpConfirmVisable = false;
 
-  registerDialogVisable = false;
+  registerDialogVisible = false;
   registerSuccessConfirmVisable = false;
 
   applyAccount_onAction = false;
 
-  detectContructReadStatus(event: any): void {
+  detectContractReadStatus(event?: any): void {
     const scrollTop = Math.round(event.target.scrollTop);
     const height = event.target.scrollHeight - event.target.clientHeight;
     if (Math.floor(scrollTop/10) === (Math.floor(height/10))) {
@@ -472,15 +479,22 @@
       indexKey: this.phoneOtpInfo.indexKey,
       otpCode: this.otpCode
     }
+
     loginVerify(login).then(res => {
       this.storageIdToken(res.data.id_token);
       this.storageRole(Role.USER);
       this.phoneSuccessConfirmVisable = true;
     }).catch(error => {
       if (error.response.status === 401) {
-        this.registerDialogVisable = true;
+        this.registerDialogVisible = true;
+        setTimeout(() => {
+          const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight;
+          if (isScrollBarNeedless) {
+            this.isReadContract = true;
+          }
+        }, 1000);
       }
-    })
+    });
   }
 
   destroyed() {
@@ -530,6 +544,7 @@
   border-radius: 6px;
   border: 1px solid #707070;
   padding: 20px;
+  max-height: 335px;
 }
 
 .pam-radio {
diff --git "a/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt" "b/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt"
new file mode 100644
index 0000000..c132146
--- /dev/null
+++ "b/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt"
@@ -0,0 +1,29 @@
+* �������Ⅳ����
+http get :
+
+http://localhost:8080/api/login/validate/get_img_code
+
+
+response content type: 
+image/jpeg
+
+
+
+* 撠��Ⅳ�敺垢�脰����
+
+http get :
+
+http://localhost:8080/api/login/validate/verify_img_code/{imgCode}
+
+ex:
+http://localhost:8080/api/login/validate/verify_img_code/4Rrcp
+
+
+
+
+response :
+
+true (撽����), false(撽�仃���)
+
+
+
diff --git a/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java b/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
index 4349448..6fca6d3 100644
--- a/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
+++ b/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
@@ -83,6 +83,7 @@
             .antMatchers("/api/activate").permitAll()
             .antMatchers("/api/testLogin/**").permitAll()
             .antMatchers("/api/otp/**").permitAll()
+            .antMatchers("/api/login/validate/**").permitAll()
             .antMatchers("/api/eService/authenticate").permitAll()
             .antMatchers("/api/account/reset-password/init").permitAll()
             .antMatchers("/api/account/reset-password/finish").permitAll()
diff --git a/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java b/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java
new file mode 100644
index 0000000..e42af0b
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java
@@ -0,0 +1,68 @@
+package com.pollex.pam.service.util;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.Random;
+
+public final class VerifyCodeUtil {
+
+	
+	public static String createcode() {
+		String code = "";
+		code = "";
+		String randomRange = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";// Randomly generated character
+																					// range (0-9, a-z, A-Z)
+
+		// The number of digits for generating the verification code (here 4 digits)
+		for (int i = 0; i < 4; i++) {
+			int index = (int) (Math.random() * 62);// Will produce a [0,62) number, excluding decimals
+			char randomCode = randomRange.charAt(index);
+			code = code + randomCode;
+		}
+		return code;
+	}
+
+	// 3. Generate pictures
+	public static BufferedImage createimage(String code) {
+		// The first 2 parameters are: width, height. The back is the image type
+		// Create a BufferedImage object without transparent color, TYPE_INT_ARGB is
+		// with transparent color
+		BufferedImage bi = new BufferedImage(130, 50, BufferedImage.TYPE_INT_RGB);
+
+		// 1. Get a canvas
+		Graphics g = bi.getGraphics();
+		// 2. Add background color
+		g.setColor(Color.WHITE);
+		g.fillRect(0, 0, 130, 50);
+
+		// 3. Add interference lines
+		for (int i = 0; i < 10; i++) {
+			Random r = new Random();
+			int red = r.nextInt(256);
+			int green = r.nextInt(256);
+			int blue = r.nextInt(256);
+			Color c = new Color(red, green, blue);
+			g.setColor(c);
+			int x1 = r.nextInt(131);
+			int y1 = r.nextInt(51);
+			int x2 = r.nextInt(131);
+			int y2 = r.nextInt(51);
+			g.drawLine(x1, y1, x2, y2);// Draw a line
+			// g.drawOval(x1, y1, x2, y2);//Draw a curve
+		}
+
+		// 3. Add text
+		g.setColor(Color.BLACK);
+		g.setFont(new Font(" ", Font.BOLD, 40));
+
+		// 4. Fill the text into the artboard
+		g.drawString(code, 15, 40);
+
+		// 5. Close the canvas
+		g.dispose();
+		return bi;
+	}
+
+}
\ No newline at end of file
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java
new file mode 100644
index 0000000..47b4ffc
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java
@@ -0,0 +1,62 @@
+package com.pollex.pam.web.rest;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.pollex.pam.service.util.VerifyCodeUtil;
+
+@RestController
+@RequestMapping("/api/login/validate")
+public class ConsultantLoginValidateResource {
+	
+	@GetMapping("/get_img_code")
+	public void getVerifyCodeImg(HttpServletResponse response, HttpServletRequest request) {
+		try {
+			String code = VerifyCodeUtil.createcode();
+			BufferedImage image = VerifyCodeUtil.createimage(code);
+			// Return to the client in a stream
+			response.setContentType("image/jpeg");
+			// response.setContentType("image/bmp");
+			ByteArrayOutputStream bt = new ByteArrayOutputStream();
+			// Convert pictures to byte stream
+			ImageIO.write(image, "jpeg", bt);
+			ServletOutputStream outputStream = response.getOutputStream();
+			outputStream.write(bt.toByteArray());
+			HttpSession session = request.getSession();
+			session.setAttribute("img_code", code);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	@GetMapping("/verify_img_code/{imgCode}")
+	public boolean verifyImgCode(HttpServletResponse response, HttpServletRequest request,
+			@PathVariable String imgCode) {
+		HttpSession session = request.getSession();
+		String sessionImpCode = (String) session.getAttribute("img_code");
+		if (!StringUtils.hasText(sessionImpCode)
+				|| !StringUtils.hasText(imgCode)) {
+			return false;
+		}
+		
+		if (imgCode.equals(sessionImpCode)) {
+			return true;
+		}
+		
+		return false;
+	}
+}

--
Gitblit v1.8.0