门户短信发送验证码及验证功能

我们在开发中会遇到短信或者邮箱发送短信验证码校验登场景,下面记录一下开发的心得

首先我们要获取验证码生成的时候放到redis中,然后在后面根据账号或者其他去关联查询放在redis中的验证码。

1.获取验证码

java 复制代码
    /**
     * 图形验证码
     * @param response
     */
    @GET
    @Path("/imgCaptcha")
    public WebResult captchaImg(@QueryParam("phone") String phone, @Context HttpServletResponse response) {
        try {
            LineCaptcha lineCaptcha = lcjtWebSiteSupplierRegisterService.imgCaptcha(phone);
            //将验证码输出
            lineCaptcha.write(response.getOutputStream());
            return WebResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取图形验证码异常:" + e.getLocalizedMessage());
            return WebResult.error(e.getMessage());
        }
    }
java 复制代码
    /**
     * 图形验证码
     * @param phone
     * @return
     * @throws Exception
     */
    LineCaptcha imgCaptcha(String phone) throws Exception;
java 复制代码
package cn.hutool.captcha;

/**
 * 图形验证码工具
 * 
 * @author looly
 * @since 3.1.2
 */
public class CaptchaUtil {

	/**
	 * 创建线干扰的验证码,默认5位验证码,150条干扰线
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @return {@link LineCaptcha}
	 */
	public static LineCaptcha createLineCaptcha(int width, int height) {
		return new LineCaptcha(width, height);
	}

	/**
	 * 创建线干扰的验证码
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @param codeCount 字符个数
	 * @param lineCount 干扰线条数
	 * @return {@link LineCaptcha}
	 */
	public static LineCaptcha createLineCaptcha(int width, int height, int codeCount, int lineCount) {
		return new LineCaptcha(width, height, codeCount, lineCount);
	}

	/**
	 * 创建圆圈干扰的验证码,默认5位验证码,15个干扰圈
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @return {@link CircleCaptcha}
	 * @since 3.2.3
	 */
	public static CircleCaptcha createCircleCaptcha(int width, int height) {
		return new CircleCaptcha(width, height);
	}

	/**
	 * 创建圆圈干扰的验证码
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @param codeCount 字符个数
	 * @param circleCount 干扰圆圈条数
	 * @return {@link CircleCaptcha}
	 * @since 3.2.3
	 */
	public static CircleCaptcha createCircleCaptcha(int width, int height, int codeCount, int circleCount) {
		return new CircleCaptcha(width, height, codeCount, circleCount);
	}
	
	/**
	 * 创建扭曲干扰的验证码,默认5位验证码
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @return {@link ShearCaptcha}
	 * @since 3.2.3
	 */
	public static ShearCaptcha createShearCaptcha(int width, int height) {
		return new ShearCaptcha(width, height);
	}
	
	/**
	 * 创建扭曲干扰的验证码,默认5位验证码
	 * 
	 * @param width 图片宽
	 * @param height 图片高
	 * @param codeCount 字符个数
	 * @param thickness 干扰线宽度
	 * @return {@link ShearCaptcha}
	 * @since 3.3.0
	 */
	public static ShearCaptcha createShearCaptcha(int width, int height, int codeCount, int thickness) {
		return new ShearCaptcha(width, height, codeCount, thickness);
	}
}
java 复制代码
    Cache getCache(String var1, LayeringCacheSetting var2);
java 复制代码
  public Cache getCache(String name, LayeringCacheSetting layeringCacheSetting) {
        ConcurrentMap<String, Cache> cacheMap = (ConcurrentMap)this.cacheContainer.get(name);
        if (!CollectionUtils.isEmpty(cacheMap)) {
            if (cacheMap.size() > 1) {
                this.logger.warn("缓存名称为 {} 的缓存,存在两个不同的过期时间配置,请一定注意保证缓存的key唯一性,否则会出现缓存过期时间错乱的情况", name);
            }

            Cache cache = (Cache)cacheMap.get(layeringCacheSetting.getInternalKey());
            if (cache != null) {
                return cache;
            }
        }

        synchronized(this.cacheContainer) {
            ConcurrentMap<String, Cache> cacheMap = (ConcurrentMap)this.cacheContainer.get(name);
            Cache cache;
            if (!CollectionUtils.isEmpty((Map)cacheMap)) {
                cache = (Cache)((ConcurrentMap)cacheMap).get(layeringCacheSetting.getInternalKey());
                if (cache != null) {
                    return cache;
                }
            } else {
                cacheMap = new ConcurrentHashMap(16);
                this.cacheContainer.put(name, cacheMap);
                this.updateCacheNames(name);
            }

            cache = this.getMissingCache(name, layeringCacheSetting);
            if (cache != null) {
                cache = this.decorateCache(cache);
                ((ConcurrentMap)cacheMap).put(layeringCacheSetting.getInternalKey(), cache);
                if (((ConcurrentMap)cacheMap).size() > 1) {
                    this.logger.warn("缓存名称为 {} 的缓存,存在两个不同的过期时间配置,请一定注意保证缓存的key唯一性,否则会出现缓存过期时间错乱的情况", name);
                }

                if (this.useFirstAndSecond(layeringCacheSetting)) {
                    this.addMessageListener(name);
                }
            }

            return cache;
        }
    }
java 复制代码
package cn.hutool.captcha;

import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 抽象验证码<br>
 * 抽象验证码实现了验证码字符串的生成、验证,验证码图片的写出<br>
 * 实现类通过实现{@link #createImage(String)} 方法生成图片对象
 *
 * @author looly
 */
public abstract class AbstractCaptcha implements ICaptcha {
	private static final long serialVersionUID = 3180820918087507254L;

	/**
	 * 图片的宽度
	 */
	protected int width;
	/**
	 * 图片的高度
	 */
	protected int height;
	/**
	 * 验证码干扰元素个数
	 */
	protected int interfereCount;
	/**
	 * 字体
	 */
	protected Font font;
	/**
	 * 验证码
	 */
	protected String code;
	/**
	 * 验证码图片
	 */
	protected byte[] imageBytes;
	/**
	 * 验证码生成器
	 */
	protected CodeGenerator generator;
	/**
	 * 背景色
	 */
	protected Color background;
	/**
	 * 文字透明度
	 */
	protected AlphaComposite textAlpha;

	/**
	 * 构造,使用随机验证码生成器生成验证码
	 *
	 * @param width          图片宽
	 * @param height         图片高
	 * @param codeCount      字符个数
	 * @param interfereCount 验证码干扰元素个数
	 */
	public AbstractCaptcha(int width, int height, int codeCount, int interfereCount) {
		this(width, height, new RandomGenerator(codeCount), interfereCount);
	}

	/**
	 * 构造
	 *
	 * @param width          图片宽
	 * @param height         图片高
	 * @param generator      验证码生成器
	 * @param interfereCount 验证码干扰元素个数
	 */
	public AbstractCaptcha(int width, int height, CodeGenerator generator, int interfereCount) {
		this.width = width;
		this.height = height;
		this.generator = generator;
		this.interfereCount = interfereCount;
		// 字体高度设为验证码高度-2,留边距
		this.font = new Font(Font.SANS_SERIF, Font.PLAIN, (int) (this.height * 0.75));
	}

	@Override
	public void createCode() {
		generateCode();

		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		ImgUtil.writePng(createImage(this.code), out);
		this.imageBytes = out.toByteArray();
	}

	/**
	 * 生成验证码字符串
	 *
	 * @since 3.3.0
	 */
	protected void generateCode() {
		this.code = generator.generate();
	}

	/**
	 * 根据生成的code创建验证码图片
	 *
	 * @param code 验证码
	 * @return Image
	 */
	protected abstract Image createImage(String code);

	@Override
	public String getCode() {
		if (null == this.code) {
			createCode();
		}
		return this.code;
	}

	@Override
	public boolean verify(String userInputCode) {
		return this.generator.verify(getCode(), userInputCode);
	}

	/**
	 * 验证码写出到文件
	 *
	 * @param path 文件路径
	 * @throws IORuntimeException IO异常
	 */
	public void write(String path) throws IORuntimeException {
		this.write(FileUtil.touch(path));
	}

	/**
	 * 验证码写出到文件
	 *
	 * @param file 文件
	 * @throws IORuntimeException IO异常
	 */
	public void write(File file) throws IORuntimeException {
		try (OutputStream out = FileUtil.getOutputStream(file)) {
			this.write(out);
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
	}

	@Override
	public void write(OutputStream out) {
		IoUtil.write(out, false, getImageBytes());
	}

	/**
	 * 获取图形验证码图片bytes
	 *
	 * @return 图形验证码图片bytes
	 * @since 4.5.17
	 */
	public byte[] getImageBytes() {
		if (null == this.imageBytes) {
			createCode();
		}
		return this.imageBytes;
	}

	/**
	 * 获取验证码图
	 *
	 * @return 验证码图
	 */
	public BufferedImage getImage() {
		return ImgUtil.read(IoUtil.toStream(getImageBytes()));
	}

	/**
	 * 获得图片的Base64形式
	 *
	 * @return 图片的Base64
	 * @since 3.3.0
	 */
	public String getImageBase64() {
		return Base64.encode(getImageBytes());
	}

	/**
	 * 自定义字体
	 *
	 * @param font 字体
	 */
	public void setFont(Font font) {
		this.font = font;
	}

	/**
	 * 获取验证码生成器
	 *
	 * @return 验证码生成器
	 */
	public CodeGenerator getGenerator() {
		return generator;
	}

	/**
	 * 设置验证码生成器
	 *
	 * @param generator 验证码生成器
	 */
	public void setGenerator(CodeGenerator generator) {
		this.generator = generator;
	}

	/**
	 * 设置背景色
	 *
	 * @param background 背景色
	 * @since 4.1.22
	 */
	public void setBackground(Color background) {
		this.background = background;
	}

	/**
	 * 设置文字透明度
	 *
	 * @param textAlpha 文字透明度,取值0~1,1表示不透明
	 * @since 4.5.17
	 */
	public void setTextAlpha(float textAlpha) {
		this.textAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, textAlpha);
	}

}

2.验证

java 复制代码
    /**
     * 门户统一登录
     * @param loginParam
     * @return
     */
    @POST
    @Path("/uLogin")
    @Produces(MediaType.APPLICATION_JSON)
    public WebResult login(Map<String, String> loginParam) {
        try {
            Map<String, String> loginRet = lcjtLoginService.login(loginParam);
            return WebResult.ok(loginRet);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);
            return WebResult.error(e.getMessage());
        }
    }
java 复制代码
    Map<String, String> login(Map<String, String> loginParam);
java 复制代码
    @Override
    public Map<String, String> login(Map<String, String> loginParam) {
        //新增验证码校验
        String imgCode = loginParam.get("imgCode");

        String userCode = loginParam.get("userCode");

        String codeKey = loginParam.get("codeKey");

        if (StrUtil.isBlank(codeKey)) {
            throw new EsRuntimeException("验证码已过期,请重新获取!");
        }


        if (StrUtil.isBlank(userCode)) throw new EsRuntimeException("手机号或登录账户不能为空!");
        if (StrUtil.isBlank(imgCode)) throw new EsRuntimeException("图形验证码为空!");

        String phoneCaptchaTimeLimit = TrdInfConfigUtil.getConfigItemValue("lcjt_portalSite", "portalSite_phoneCaptchaTimeLimit");
        Integer time = StrUtil.isBlank(phoneCaptchaTimeLimit) ? 5 : Integer.valueOf(phoneCaptchaTimeLimit);

        //声明当前要使用的缓存配置,建议此配置通过静态变量持有
        LayeringCacheSetting setting = new LayeringCacheSetting.Builder()
                //关闭一级缓存
                .disableFirstCache()
                //开启二级缓存
                .enableSecondCache()
                //一级缓存过期时间
                .secondCacheExpireTime(time)  // 5分钟
                //一级缓存过期时间单位
                .secondCacheTimeUnit(TimeUnit.MINUTES)
                //缓存配置说明
                .depict("手机号" + codeKey + "验证号").build();
        //获取缓存实例,通过cache操作缓存
        Cache cache = cacheManager.getCache(cacheName, setting);

        String imgCaptchaExist = cache.get(codeKey + "img", String.class);

        if (StrUtil.isBlank(imgCaptchaExist)) {
            throw new EsRuntimeException("验证码已失效,请重新获取!");

        }
        cache.evict(codeKey + "img");
        if (!imgCode.equals(imgCaptchaExist)) {
            throw new EsRuntimeException("验证码不正确,请重新输入!");
        }


        String logid = LcjtLogUtil.startLog("login", "用户登录 loginParam:" + JSON.toJSONString(loginParam));
        if (StrUtil.isBlank(loginParam.get("userCode")) || StrUtil.isBlank(loginParam.get("password"))) {
            LcjtLogUtil.info(logid, "登录名或密码错误!");
            throw new EsRuntimeException("登录名或密码错误!");
        }

        LcjtSupplierRegisterEntity registerCode = lcjtSupplierRegisterRepository.findByAppcodeAndIsnew(loginParam.get("userCode"), "1");
        LcjtSupplierRegisterEntity registerPhone = lcjtSupplierRegisterRepository.findByPhoneAndIsnewAndOriginIsNull(loginParam.get("userCode"), "1");

        List<SuppliercontactsEntity> suppliercontactsCodeList = suppliercontactsRepository.findByContactcode(loginParam.get("userCode"));
        List<SuppliercontactsEntity> suppliercontactsPhoneList = suppliercontactsRepository.findAllByContactphone(loginParam.get("userCode"));

        List<LcjtIgoUserEntity> igoUserCodeList = lcjtIgoUserRepository.findByUsercode(loginParam.get("userCode"));
        List<LcjtIgoUserEntity> igoUserPhoneList = lcjtIgoUserRepository.findByPhone(loginParam.get("userCode"));

        if (null == registerCode && null == registerPhone && CollUtil.isEmpty(suppliercontactsCodeList) && CollUtil.isEmpty(suppliercontactsPhoneList)
                && CollUtil.isEmpty(igoUserCodeList) && CollUtil.isEmpty(igoUserPhoneList)) {
            LcjtLogUtil.info(logid, "登录名或密码错误!");
            throw new EsRuntimeException("登录名或密码错误!");
        }

        RestTemplate restTemplate = new RestTemplate();

        String loginUrl = TrdInfConfigUtil.getConfigItemValue("lcjt_portalSite", "portalSite_gsCloudAddress");
        if (StrUtil.isBlank(loginUrl)) {
            log.error("虚拟登录参数未配置,请检查二开参数配置,【lcjt_portalSite】【portalSite_gsCloudAddress】!");
            LcjtLogUtil.info(logid, "虚拟登录参数未配置,请检查二开参数配置,【lcjt_portalSite】【portalSite_gsCloudAddress】!");
            throw new EsRuntimeException("请联系运维人员!");
        }

        loginUrl += "/sign-in";

        HttpHeaders loginheaders = new HttpHeaders();
        loginheaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap loginmap = new LinkedMultiValueMap();
        loginmap.add("userCode", loginParam.get("userCode"));
        loginmap.add("password", loginParam.get("password"));
        loginmap.add("Tenant", 10000);
        loginmap.add("seType", "true");
        loginmap.add("Authenstrategy", "Inspur_Supplier_FT");
        loginmap.add("language", "zh-CHS");
        loginmap.add("vc", "");
        loginmap.add("RTF-CheckAuthStrategy", true);
        HttpEntity<MultiValueMap> loginentity = new HttpEntity<>(loginmap, loginheaders);
        log.info("loginentity " + loginentity);

        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

        try {
            ResponseEntity<String> loginresponse = restTemplate.postForEntity(loginUrl, loginentity, String.class);
            int statusCode = loginresponse.getStatusCodeValue();
            if (statusCode != 200) {
                log.error("登录失败,statusCode = " + statusCode);
                LcjtLogUtil.info(logid, "登录失败,statusCode = " + statusCode);
                throw new RuntimeException("登录异常,请联系运维人员!");
            }
            JSONObject body = JSON.parseObject(loginresponse.getBody());
            String authentication = (String) body.get("authentication");
            if (!authentication.equals("success")) {
                LcjtLogUtil.info(logid, "登录失败2,authentication = " + authentication);
                log.error("登录失败,authentication = " + authentication);
                throw new RuntimeException("登录异常,请联系运维人员!");
            }
        } catch (Exception e) {
            String str = e.getLocalizedMessage();
            if (str.contains("Incorrect username or password")) {
                LcjtLogUtil.info(logid, "登录失败3,登录名或密码错误 ");
                throw new RuntimeException("登录名或密码错误!");
            } else {
                LcjtLogUtil.info(logid, "登录失败4 ");
                throw new RuntimeException("登录异常,请联系运维人员!");
            }
        }
        LcjtLogUtil.info(logid, "根据编号获得用户信息!");
        User user = userManager.getUserByCode(loginParam.get("userCode"), null, null, null, null);
        if (null == user) {
            LcjtLogUtil.info(logid, "根据编号未获得用户信息,根据手机号获得用户信息!");
            UserExtendManager userExtendManager = SpringUtil.getBean(UserExtendManager.class);
            UserExtend userExtend = userExtendManager.getExtendByMobilePhone(loginParam.get("userCode"));
            if (null != userExtend) {
                user = userManager.getUserBasicInfo(userExtend.getUserId());
            }
        }

        if (null == user) {
            log.error("GspUser信息为空!");
            LcjtLogUtil.info(logid, "GspUser信息为空!");
            throw new EsRuntimeException("登录异常,请联系运维人员!");
        }
        LcjtLogUtil.info(logid, "已获得gsc用户信息!");
        String supAuthFlag = "0";
        if (null == registerCode && null == registerPhone) {
            supAuthFlag = "1";
        } else {
            String appState = (null == registerCode) ? registerPhone.getAppstate() : registerCode.getAppstate();
            if (StrUtil.isBlank(appState) || "0".equals(appState)) {//
                supAuthFlag = "0";
            } else if ("3".equals(appState)) {
                supAuthFlag = "3";//用来区分这个供应商认证被驳回了
            } else if ("1".equals(appState)) {
                supAuthFlag = "4";//用来区别审批中状态
            } else {
                supAuthFlag = "1";
            }
        }
        LcjtLogUtil.info(logid, "supAuthFlag:" + supAuthFlag);
        String token = lcjtJwtTokenUtil.generateToken(user.getCode());
        if (StringUtils.isBlank(token)) {
            LcjtLogUtil.info(logid, "根据用户信息生成token异常:token信息为空!");
            log.error("根据用户信息生成token异常:token信息为空!");
            throw new EsRuntimeException("登录异常,请联系运维人员!");
        }
        Map<String, String> tokenMap = new HashMap<>();
        String tokenHead = TrdInfConfigUtil.getConfigItemValue("lcjt_Jwt", "lcjt_jwt_tokenHead");
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        tokenMap.put("userName", user.getName());
        tokenMap.put("userCode", user.getCode());
        tokenMap.put("isAuth", supAuthFlag);

        return tokenMap;
    }

3.前端生成验证码

java 复制代码
<template>
  <div class="login">
    <div>
      <div class="main">
        <el-tabs v-model="tabPaneName" @tab-click="handleTabClick">
          <el-tab-pane :label="$t('login.qydl')" name="tab1">
            <el-form ref="ruleForm" :model="ruleForm" :rules="rules" class="">
              <el-row :gutter="24">
                <el-col :span="24">
                  <el-form-item label="" prop="name">
                    <el-input style="" v-model.trim="ruleForm.name" :placeholder="$t('login.dlplaceholder')" prefix-icon="el-icon-user"></el-input>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="24">
                <el-col :span="24">
                  <el-form-item label="" prop="pwd">
                    <el-input style="" type="password" show-password v-model.trim="ruleForm.pwd" :placeholder="$t('login.mimaplaceholder')" prefix-icon="el-icon-lock"></el-input>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="24">
                <el-col :span="14">
                  <el-form-item label="" prop="imgCode">
                    <el-input style="" type="imgCode" v-model.trim="ruleForm.imgCode" :placeholder="'请输入验证码'" prefix-icon="el-icon-key"></el-input>
                  </el-form-item>
                </el-col>
                <el-col :span="10">
                  <div @click="onRefreshClick">
                    <el-tooltip effect="dark" content="点击切换验证码(区分大小写)" placement="bottom">
                      <!-- <verify-code class="c-verifyCode" ref="verifyCode" v-if="isShowCode"></verify-code> -->
                      <img :src="verifyCodeUrl" @click="captchaClick" />
                    </el-tooltip>
                  </div>
                </el-col>

              </el-row>
              <div style="
                  font-family: Noto Sans S Chinese;
                  color: #141313;
                  font-size: 14px;
                  margin-bottom: 10px;
                  text-align:center
                ">
                <div>
                  <el-checkbox v-model="agreeChecked"></el-checkbox><span style="margin-left:6px">{{ $t("login.wyydbty") }}</span>
                </div>
                <div>
                  <a target="_blank" class="downbtn" :href="'/pdf/' + $t('yhzcxy')+ '.pdf'"><span style="color: #409eff; cursor: pointer">{{
                      $t("login.zcxy")
                    }}</span></a>{{ $t("login.he")
                  }}<a target="_blank" class="downbtn" :href="'/pdf/' + $t('ptyszc')+ '.pdf'"><span style="color: #409eff; cursor: pointer">{{
                      $t("login.yszc")
                    }}</span></a>
                </div>
              </div>
              <div @click="zhmm" class="link-box">
                <span style="
                    margin-right: 15px;
                    font-family: Noto Sans S Chinese;
                    color: #409eff;
                    font-size: 14px;
                    cursor: pointer;
                  ">{{ $t("login.zhmm") }}</span>
                <!-- <span @click="goHome"
                      style="
                    font-family: Noto Sans S Chinese;
                    color: #409eff;
                    font-size: 14px;
                    cursor: pointer;
                  ">{{ $t("login.fhsy") }}</span> -->
              </div>
              <el-form-item>
                <div class="btns" @click="submitForm">{{ $t("login.dl") }}</div>
              </el-form-item>
            </el-form>
          </el-tab-pane>

          <el-tab-pane :label="$t('login.ljzc')" name="tab2">
            <!-- <h2>跳转注册页面</h2> -->
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <!-- <Agreement ref="agree" :html="xieyicontent" @getAgree="getAgree" />
    <Policy ref="policy" :html="xieyicontent" @getAgree="getAgree" /> -->
  </div>
</template>

<script>
import aes128 from "@/utils/aes128";
import { generateUUID } from "@/utils";
// import { rsaEncrypt } from '@/utils/rsa'
// import { mapActions } from 'vuex'

export default {
  data () {
    // let validatePass = (rule, value, callback) => {
    //   if (!value) {
    //     callback(new Error("密码不能为空"));
    //   } else {
    //     if (this.ruleForm.name === value) {
    //       callback(new Error("密码不能与用户名相同"));
    //     }
    //     let reg =
    //       /^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@$#^?~/])[\u4E00-\u9FA5A-Za-z0-9!@$#^?~/]{8,16}$/;
    //     if (value.length < 6) {
    //       callback(new Error("密码不少于8位"));
    //     }
    //     if (value.length > 16) {
    //       callback(new Error("密码不大于16位"));
    //     }
    //     if (!reg.test(value)) {
    //       callback(
    //         new Error("密码需包含大小写字母,数字及特殊字符【!@$#^?~/】")
    //       );
    //     } else {
    //       callback();
    //     }
    //   }
    // };
    let validateImgCode = (rule, value, callback) => {
      // if (
      //   value.toUpperCase() !==
      //   this.$refs.verifyCode.$refs.verifyCode.result.toUpperCase()
      // ) {
      //   this.isImgCode = true;
      //   callback(new Error("请输入正确的验证码"));
      // } else {
      //   this.isImgCode = false;
      //   callback();
      // }
      if (!value) {
        callback(new Error("请输入验证码"));
      } else {
        callback();
      }
    };
    return {
      agreeChecked: false,
      tabPaneName: "tab1",
      query: '',
      verifyCodeUrl:'',
      ruleForm: {
        name: "",
        pwd: "",
        imgCode: "",
      },
      xieyicontent: "",
      dialogVisible: false,
      isShowCode: true, //刷新验证码
      rules: {
        name: [
          { required: true, message: "请输入登录名/手机号", trigger: "blur" },
        ],
        pwd: [{ required: true, message: "请输入密码", trigger: "blur" }],
        imgCode: [
          { required: true, validator: validateImgCode, trigger: "none" },
        ],
      },
    };
  },
  created() {
    this.query = this.generateUUID()
    this.verifyCodeUrl = "/cloudapis/api/ep/hy/v1.0/portal/lcjt/website/supCheck/imgCaptcha?phone=" +
        this.query +
        "&time=" +
        new Date()
  },
  mounted() {
    // getXieyi().then(res=>{
    //   this.xieyicontent = res?.result?.content??''
    // })
  },
  methods: {
    generateUUID, //获取build的方法
    onRefreshClick() {
      this.isShowCode = false;
      this.$nextTick(() => (this.isShowCode = true));
    },
    goHome() {
      this.$router.push({ path: "/homepage" });
    },
    fwxy() {
      this.$refs.agree.toggle();
    },
    getAgree(val) {
      this.agreeChecked = val;
    },
    handleClose() {
      this.agreeChecked = true;
      this.dialogVisible = false;
    },
    ysxx() {
      this.$refs.policy.toggle();
    },
    zhmm() {
      this.$router.push({ path: "/forgotpassword" });
    },
    captchaClick() {
      this.verifyCodeUrl =
        "/cloudapis/api/ep/hy/v1.0/portal/lcjt/website/supCheck/imgCaptcha?phone=" +
        this.query +
        "&time=" +
        new Date();
      this.ruleForm.imgCode = "";
    },
    handleTabClick(tab) {
      if (tab.index == 1) {
        this.$router.push({ path: "/countryRegister" });
      }
    },

    async submitForm () {
      if (!this.agreeChecked) {
        this.$message.warning(this.$t("login.xy"));
        return
      }
      try {
        const validateResult = await this.$refs.ruleForm
          .validate()
          .catch(() => {
            this.onRefreshClick()
          });
        if (!validateResult) return;
        let data = {
          userCode: this.ruleForm.name,
          password: aes128.encrypt(this.ruleForm.pwd), //密码加密
          imgCode:this.ruleForm.imgCode,
          codeKey:this.query
        };   
        this.$store.commit("setUserCode", this.ruleForm.name);

        //调登录接口
        await this.$store.dispatch("login", data);
        // //登陆成功后的逻辑
        // this.$router.push({ path: "/homepage" });
      } catch (err) {
        this.onRefreshClick()
        console.log(err);
      }
    },
  },
};
</script>

<style scoped lang="scss">
::v-deep .el-tabs__item {
  font-family: Noto Sans S Chinese;
  font-weight: 700;
  // color:#021133;
  font-size: 24px;
}
::v-deep .el-tabs__header {
  margin-bottom: 30px;
}
.login {
  .main {
    background: url(~@/assets/images/login/dzbg.png);
    background-size: 100% 100%;
    width: 380px;
    height: 450px;
    padding: 30px 50px 20px;
    .link-box {
      display: flex;
      justify-content: space-between;
    }
    .btns {
      margin-top: 10px;
      text-align: center;
      background: linear-gradient(90deg, #0b5bfb 0%, #3e6cd7 100%);
      border-radius: 8px;
      height: 48px;
      line-height: 48px;
      font-family: Noto Sans S Chinese;
      color: #ffffff;
      font-size: 16px;
      cursor: pointer;
    }
    .go-home {
      text-align: right;
    }
    /deep/#tab-tab2 {
      font-size: 20px;
    }
    /deep/.login-btn {
      margin-bottom: 10px;
    }
  }
}
</style>
相关推荐
elangyipi1232 小时前
pnpm :下一代包管理工具的原理与实践
前端·npm
代码的奴隶(艾伦·耶格尔)2 小时前
Sentinel限流熔断
java·前端·sentinel
talenteddriver2 小时前
mysql: MySQL中between子句和limit子句的区别
前端·javascript·数据库
A24207349303 小时前
深入浅出理解AJAX:核心原理与POST/GET区别详解
前端·ajax·okhttp
LYFlied3 小时前
【每日算法】LeetCode 300. 最长递增子序列
前端·数据结构·算法·leetcode·职场和发展
张较瘦_3 小时前
前端 | 代码可读性 + SEO 双提升!HTML 语义化标签实战教程
前端·html
似水流年QC3 小时前
前端国际化实战指南:i18n 工程化最佳实践总结
前端
GISer_Jing3 小时前
企业级前端脚手架:原理与实战指南
前端·前端框架
非凡ghost3 小时前
Floorp Browser(基于Firefox火狐浏览器)
前端·windows·学习·firefox·软件需求