什么是礼品网

采取礼品代发的方法,可以让店铺用比较低的成本,拥有真实的发货物流,而且不需要自己去处理发货。那么靠谱的礼品代发平台有什么特点?选择礼品代发平台应该看什么?

礼品代发的意义。

当你有一个礼品需要寄给买家,你起码需要以下几个步骤:
虽说整个流程没有技术难度,大家每天也在做这个事情,但如果每天需要发10个,甚至100个礼品单,就会消耗大量的人工和时间成本,算上礼品和快递费的成本,长此以往也是笔不小的开销,为了控制成本留下更多的利润,需要以更低的成本,更高的效率,更便捷的方式去发礼品单。

如何搭建礼品网?怎么搭建一个礼品网?

礼品网分别,用户端,站点可以进行商品的上架,下架管理等操作,支持一键对接第三方云仓库,一键发货
开发工具:
前端: vue
服务端:springboot + mysql + mybaits
源码展示

验证码获取

package cn.gift.web.service.system;

import cn.gift.web.constants.BusinessException;
import cn.gift.web.constants.RedisKeyConstants;
import cn.plus.core.exception.ServiceException;
import cn.plus.core.utils.SerialNumber;
import com.google.code.kaptcha.Producer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 校准需要的内容
 * @author: RaveyXie
 * @date: 2022年11月13日 7:59 PM
 * @since
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CheckVerifyCodeService {

    private final StringRedisTemplate masterRedisTemplate;

    private final Producer producer;

    /**
     * 校准验证码
     *
     * @param key
     * @param code
     * @param isRemoveKey 判断是否删除验证码 用来做发送短信就要校验验证码
     */
    public void checkVerifyCode(String key, String code, Boolean isRemoveKey) {
        // 校准验证码
        if (StringUtils.isEmpty(code)) {
            throw new ServiceException(BusinessException.CODE_CANNOT_EMPTY);
        }
        String redisCode = RedisKeyConstants.KAPTCHA.setArg(key);
        String oldCode = masterRedisTemplate.opsForValue().get(redisCode);
        if (isRemoveKey) {
            masterRedisTemplate.delete(redisCode);
        }
        if (StringUtils.isEmpty(oldCode)) {
            throw new ServiceException(BusinessException.VERIFICATION_CODE_HAS_EXPIRED);
        }
        if (oldCode.compareToIgnoreCase(code) != 0) {
            throw new ServiceException(BusinessException.VERIFICATION_CODE_INPUT_ERROR);
        }
    }

    /**
     * 生成验证码
     *
     * @return
     */
    public Object doKaptcha() {
        // 生成验证码
        String text = producer.createText();
        BufferedImage image = producer.createImage(text);
        // 将验证码的信息存在session中进行比对
        Long serialNum7 = SerialNumber.key7();
        String key = RedisKeyConstants.KAPTCHA.setArg(serialNum7.toString());
        // 存在redis里面 设置10分钟过期
        masterRedisTemplate.opsForValue().set(key, text, 3, TimeUnit.MINUTES);
        // 这一步就要存session
        Map<String, Object> maps = new HashMap<>(16);
        maps.put("key", serialNum7);
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "jpeg", outputStream);
            String base64 = Base64.encodeBase64String(outputStream.toByteArray());
            String captchaBase64 = "data:image/jpeg;base64," + base64.replaceAll("\r\n", "");
            maps.put("value", captchaBase64);
            return maps;
        } catch (IOException e) {
            return null;
        }
    }
}

关于密码加密

package cn.gift.web.util;

import com.google.common.collect.Lists;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * 进行rsa加密 像 RSA 这样的非对称密码旨在加密短数据,通常是对称 key ,而大数据使用对称分组密码加密(对称 key 将与非对称密码交换)。
 * StackOverflow 上确实有很多类似的问题和答案。 This one是一个提供了很好的答案。
 * 即使这样确实可以解决大数据量加密的问题,但是前端输入的长度是不可控制的 所以我们这边就进行一个操作
 * 对大数据量的接口进行过滤。对文件类型接口进行过滤不进行加密
 * 1.前端加密规则,因为存在中文所以前端加密会导致后端乱码所以加密规则定下
 * - 先进行参数的base64编码
 * - 在进行rsa加密
 * - 在进行base64编码
 * 我们进行长数据的接口进行过滤
 *
 * @author raveyxie
 */
public class RSAUtils {
    protected static final Log log = LogFactory.getLog(RSAUtils.class);
    private static String KEY_RSA_TYPE = "RSA";
    private static String KEY_RSA_TYPE_ALL = "RSA/ECB/PKCS1Padding";
    private static int KEY_SIZE = 1024;
    private static int ENCODE_PART_SIZE = KEY_SIZE / 8;
    public static final String PUBLIC_KEY_NAME = "public";
    public static final String PRIVATE_KEY_NAME = "private";

    /**
     * 创建公钥秘钥
     *
     * @return
     */
    public static Map<String, String> createRSAKeys() {
        //里面存放公私秘钥的Base64位加密
        Map<String, String> keyPairMap = new HashMap<>();
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA_TYPE);
            keyPairGenerator.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();

            //获取公钥秘钥
            String publicKeyValue = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
            String privateKeyValue = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());

            //存入公钥秘钥,以便以后获取
            keyPairMap.put(PUBLIC_KEY_NAME, publicKeyValue);
            keyPairMap.put(PRIVATE_KEY_NAME, privateKeyValue);
        } catch (NoSuchAlgorithmException e) {
            log.error("当前JDK版本没找到RSA加密算法!");
            e.printStackTrace();
        }
        return keyPairMap;
    }

    /**
     * 公钥加密
     * 描述:
     * 1字节 = 8位;
     * 最大加密长度如 1024位私钥时,最大加密长度为 128-11 = 117字节,不管多长数据,加密出来都是 128 字节长度。
     *
     * @param sourceStr
     * @param publicKeyBase64Str
     * @return
     */
    public static String encode(String sourceStr, String publicKeyBase64Str) {
        byte[] publicBytes = Base64.decodeBase64(publicKeyBase64Str);
        //公钥加密
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicBytes);
        List<byte[]> alreadyEncodeListData = new LinkedList<>();

        int maxEncodeSize = ENCODE_PART_SIZE - 11;
        String encodeBase64Result = null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE_ALL);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] sourceBytes = sourceStr.getBytes(StandardCharsets.UTF_8);
            int sourceLen = sourceBytes.length;
            for (int i = 0; i < sourceLen; i += maxEncodeSize) {
                int curPosition = sourceLen - i;
                int tempLen = curPosition;
                if (curPosition > maxEncodeSize) {
                    tempLen = maxEncodeSize;
                }
                //待加密分段数据
                byte[] tempBytes = new byte[tempLen];
                System.arraycopy(sourceBytes, i, tempBytes, 0, tempLen);
                byte[] tempAlreadyEncodeData = cipher.doFinal(tempBytes);
                alreadyEncodeListData.add(tempAlreadyEncodeData);
            }
            //加密次数
            int partLen = alreadyEncodeListData.size();

            int allEncodeLen = partLen * ENCODE_PART_SIZE;
            //存放所有RSA分段加密数据
            byte[] encodeData = new byte[allEncodeLen];
            for (int i = 0; i < partLen; i++) {
                byte[] tempByteList = alreadyEncodeListData.get(i);
                System.arraycopy(tempByteList, 0, encodeData, i * ENCODE_PART_SIZE, ENCODE_PART_SIZE);
            }
            encodeBase64Result = Base64.encodeBase64String(encodeData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encodeBase64Result;
    }

    /**
     * 私钥解密
     * 1.前端加密规则,因为存在中文所以前端加密会导致后端乱码所以加密规则定下
     * - 先进行参数的base64编码
     * - 在进行rsa加密
     * - 在进行base64编码
     *
     * @param sourceBase64RSA
     * @param privateKeyBase64Str
     */
    public static String decode(String sourceBase64RSA, String privateKeyBase64Str) {
        byte[] privateBytes = Base64.decodeBase64(privateKeyBase64Str);
        byte[] encodeSource = Base64.decodeBase64(sourceBase64RSA);
        int encodePartLen = encodeSource.length / ENCODE_PART_SIZE;
        //所有解密数据
        List<byte[]> decodeListData = new LinkedList<>();
        String decodeStrResult = null;
        //私钥解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateBytes);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE_ALL);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //初始化所有被解密数据长度
            int allDecodeByteLen = 0;
            for (int i = 0; i < encodePartLen; i++) {
                byte[] tempEncodedData = new byte[ENCODE_PART_SIZE];
                System.arraycopy(encodeSource, i * ENCODE_PART_SIZE, tempEncodedData, 0, ENCODE_PART_SIZE);
                byte[] decodePartData = cipher.doFinal(tempEncodedData);
                decodeListData.add(decodePartData);
                allDecodeByteLen += decodePartData.length;
            }
            byte[] decodeResultBytes = new byte[allDecodeByteLen];
            for (int i = 0, curPosition = 0; i < encodePartLen; i++) {
                byte[] tempSorceBytes = decodeListData.get(i);
                int tempSourceBytesLen = tempSorceBytes.length;
                System.arraycopy(tempSorceBytes, 0, decodeResultBytes, curPosition, tempSourceBytesLen);
                curPosition += tempSourceBytesLen;
            }
            decodeStrResult = new String(decodeResultBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(Base64.decodeBase64(decodeStrResult));
    }

  

    /**
     * 过滤链接
     */
    public static final List<String> NO_RSA_URI = Lists.newArrayList(
            "/business/basic/cutAddress",
            "/business/order/saveOrder",
            "/business/basic/templateImport");

    /**
     * 获取过滤链接
     *
     * @param webFirst
     * @return
     */
    public static List<String> getFilterUrlInfo(String webFirst) {
        List<String> webFilter = new ArrayList<>();
        RSAUtils.NO_RSA_URI.forEach(item -> webFilter.add(webFirst + item));
        return webFilter;
    }
}

加密算法

package cn.gift.web.util;
/*
 * Copyright 2002-2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import lombok.extern.slf4j.Slf4j;

import java.security.SecureRandom;
import java.util.regex.Pattern;

/**
 * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients
 * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom
 * instance. The larger the strength parameter the more work will have to be done
 * (exponentially) to hash the passwords. The default value is 10.
 * 进行密码的加密
 * @author Dave Syer
 */
@Slf4j
public class BCryptPasswordEncoder {
    private final int strength;
    private final SecureRandom random;
    private Pattern BCRYPT_PATTERN = Pattern
            .compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}");

    public BCryptPasswordEncoder() {
        this(-1);
    }

    /**
     * @param strength the log rounds to use, between 4 and 31
     */
    public BCryptPasswordEncoder(int strength) {
        this(strength, null);
    }

    /**
     * @param strength the log rounds to use, between 4 and 31
     * @param random   the secure random instance to use
     */
    public BCryptPasswordEncoder(int strength, SecureRandom random) {
        if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
            throw new IllegalArgumentException("Bad strength");
        }
        this.strength = strength;
        this.random = random;
    }

    public String encode(CharSequence rawPassword) {
        String salt;
        if (strength > 0) {
            if (random != null) {
                salt = BCrypt.gensalt(strength, random);
            } else {
                salt = BCrypt.gensalt(strength);
            }
        } else {
            salt = BCrypt.gensalt();
        }
        return BCrypt.hashpw(rawPassword.toString(), salt);
    }

    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        if (encodedPassword == null || encodedPassword.length() == 0) {
            log.warn("Empty encoded password");
            return false;
        }

        if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
            log.warn("Encoded password does not look like BCrypt");
            return false;
        }

        return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
    }
}

前端代码

<template>
  <div id="wxLogin">
    <div v-if="type == -1" class="form">
      <img :src="$store.state.tenantInfo.logo | fullPath" />
      <p style="font-size: 18px">商家端</p>
      <input type="tel" placeholder="用户名" v-model="formData.username" />
      <input type="password" placeholder="密码" v-model="formData.password" />
      <div class="verification">
        <input type="text" placeholder="验证码" v-model="formData.verifyCode" />
        <div @click="reflashCode" id="imgcode">
          <img :src="imgUrl" />
        </div>
      </div>
      <input @click="login" type="button" value="登录" />
    </div>
    <div v-else-if="type == 1" class="form">
      <img :src="$store.state.tenantInfo.logo | fullPath" />
      <h3>请点击下方按钮授权</h3>
      <p>授权后,你将开通微信提现功能,提现时金额将到此微信</p>
      <input
        id="authorization"
        @click="updateOpenid"
        type="button"
        value="一键授权"
      />
    </div>
    <div v-else-if="type == 2" class="form">
      <img :src="$store.state.tenantInfo.logo | fullPath" />
      <p>授权成功,你已开通微信提现功能</p>
    </div>
    <div v-else-if="type == 3" class="form">
      <img :src="$store.state.tenantInfo.logo | fullPath" />
      <p>
        分站已开通微信提现功能,授权的微信账号与当前账号不一致,是否重新授权
      </p>
      <input
        id="authorization"
        @click="updateOpenid"
        type="button"
        value="重新授权"
      />
    </div>
  </div>
</template>

<script>
import rsa from "@/utils/rsa";
export default {
  name: "",
  data() {
    return {
      type: -1, //1未授权,2已授权(授权openid与当前openid一致),3已售罄(授权openid与当前openid不一致)
      formData: {
        username: "",
        password: "",
        verifyCode: "",
        verifySign: "",
      },
      imgUrl: "", //图片验证码路径
      code: "",
      openid: "", //当前openid
    };
  },
  created() {
    this.reflashCode();
    var openid = this.$route.query.openid;
    if (openid) {
      this.openid = openid;
    }
    var token = localStorage.getItem(`dftToken`);
    if (openid && token) {
      this.decideOpenid();
    }
  },
  mounted() {},
  watch: {},
  methods: {
    //-----------获取图片验证码------------
    reflashCode: function () {
      var _this = this;
      _this.$axios
        .get("/ReportApi/basic/system/getVerifyCode", { responseType: "blob" })
        .then(function (res) {
          _this.imgUrl = window.URL.createObjectURL(res.data);
          _this.formData.verifySign = res.headers.sign;
        })
        .catch(function (error) {
          //consloe.log(error);
        });
    },
    //-------登录--------
    login: function () {
      var _this = this;
      if (_this.formData.username == "") {
        _this.$message.warning("账户名不能为空");
        return;
      }
      if (_this.formData.password == "") {
        _this.$message.warning("密码不能为空");
        return;
      }
      if (_this.formData.verifyCode == "") {
        _this.$message.warning("验证码不能为空");
        return;
      }
      // let postData = _this.$qs.stringify(_this.formData);
      _this.$request.post({
        url: "bus/info/public/authority",
        params: {
          account: rsa.encryptByPublicKey(_this.formData.username),
          password: rsa.encryptByPublicKey(_this.formData.password),
          verifyCode: _this.formData.verifyCode,
          verifySign: _this.formData.verifySign,
        },
        success: (res) => {
          _this.type = 1;
          localStorage.setItem("dftToken", res.token);
          localStorage.setItem("phone", res.info.phone);
          this.$store.commit("getUserInfo", res);
          this.$store.commit("setIsLogin", true);
          this.toWechat();
        },
      });
    },
    updateOpenid() {
      this.$request.post({
        url: "bus/info/updateOpenid",
        params: {
          openid: this.openid,
        },
        success: (result) => {
          this.$message.success("授权成功");
          this.type = 2;
        },
        finally: () => {},
      });
    },
    decideOpenid() {
      this.$request.post({
        url: "bus/info/decideOpenid",
        params: {
          openid: this.openid,
        },
        success: (result) => {
          this.type = result;
        },
        finally: () => {},
      });
    },
    toWechat() {
      window.location =
        window.location.protocol +
        "//" +
        window.location.host +
        "/newApi/wechat/autho/public/send?type=2";
    },
  },
};
</script>

<style>
html,
body {
  width: 100%;
  height: 100%;
  min-width: auto;
}
input[type="button"] {
  -webkit-appearance: none;
  appearance: none;
}
</style>

<style scoped>
#wxLogin {
  width: 100%;
  height: 100vh;
  background-color: #f5f5f5;
}
.form {
  padding-top: 100px;
}
.form > img {
  width: 40%;
  display: block;
  margin: 0 auto;
  margin-bottom: 20px;
}
.form > input[type="tel"],
.form > input[type="password"] {
  width: 80%;
  height: 40px;
  display: block;
  margin: 0 auto;
  margin-top: 20px;
  border: none;
  border-radius: 50px;
  background-color: #ffffff;
  padding: 0 20px;
  box-sizing: border-box;
  font-size: 16px;
}
.form .verification {
  width: 80%;
  height: 40px;
  margin: 0 auto;
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
}
.form .verification input {
  background: #ffffff;
  border: none;
  border-radius: 50px;
  width: 60%;
  height: 100%;
  padding: 0 20px;
  box-sizing: border-box;
  font-size: 16px;
}
.form .verification #imgcode {
  width: 38%;
  height: 100%;
  padding-right: 10px;
  cursor: pointer;
  margin-left: 10px;
}
.form .verification #imgcode img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 5px;
}
.form input[type="button"] {
  width: 80%;
  height: 40px;
  display: block;
  margin: 0 auto;
  margin-top: 20px;
  background-color: #ff8800;
  border: none;
  border-radius: 50px;
  color: #ffffff;
  font-size: 18px;
  letter-spacing: 20px;
  padding-left: 20px;
  box-sizing: border-box;
}
.form input[type="button"]#authorization {
  letter-spacing: 2px;
  padding-left: 2px;
  box-sizing: border-box;
  width: 60%;
}
.form h3 {
  font-size: 16px;
  color: #4d4d4d;
  margin-top: 10px;
  text-align: center;
}
.form p {
  text-align: center;
  color: #808080;
  font-size: 14px;
  margin-top: 10px;
  margin-bottom: 10px;
}
</style>
export default {

	// 验证手机号
	isPhone(phone){
		var reg=/^1[3-9]\d{9}$/;
		if(reg.test(phone)){
			return true;
		}else{
			return false;
		}
    },
    /**
     *  验证手机号中国(严谨), 根据工信部2019年最新公布的手机号段
     * @param { string } value
     */
    isPhoneStrict(phone){
		var reg=/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-7|9])|(?:5[0-3|5-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1|8|9]))\d{8}$/g;
		if(reg.test(phone)){
			return true;
		}else{
			return false;
		}
    },

	// 数字和字母
	numandenglish(str){
		var reg=/^[A-Za-z0-9]+$/;
		if(reg.test(str)){
			return str;
		}else{
			return str.replace(/[^\w\.\/]/ig,'')
		}
	},
	// 验证邮箱
	isEmail(email){
		var reg=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
		if(reg.test(email)){
			return true;
		}else{
			return false;
		}
	},

	// 验证非中文
	noChinese(text){
		var reg=/^[\u4e00-\u9fa5]{0,}$/;
		if(reg.test(text)){
			return '';
		}else{
			return text;
		}
	},

	//验证正整数(不含零)
	isInteger(num){
		var reg=/^[1-9]\d*$/;
		if(reg.test(num)){
			return num;
		}else{
			return num.replace(/[^\d]/g,'');
		}
	},

	// 验证正数(不含零)
	// 可在keyup方法中使用
	// num 需要验证的数字
	// min 需要限制的最小值
	// max 需要限制的最大值
	isPositive(num,min,max){
		var reg=/^\d+(\.\d+)?$/;
		// 小数点出现次数
		var n = (num.split('.')).length-1;
		// 小数点不止出现一次
		if (n > 1) {
			
			return num.substr(0, num.length - 1);

		}
		// 判断最后一位为小数点
		if (num.indexOf(".") != -1 && num.indexOf(".") == (num.length - 1)) {
			
			if (num.length > 1) {
				return num;
			} else {
				return ''
			}

		} 
		// 最后一位不是小数点,判断是否为数字,判断小数位数
		else if(reg.test(num)){

			if(min && Number(num)< min) return min;
			if(max && Number(num)> max) return max;
			// 小数点后位数大于2,返回两位小数
			if (num.indexOf(".") != -1 && num.split('.')[1].length > 2) {
				return Number(num).toFixed(2);
			}
			if(Number(num)>= 0) return num;
			return '';

		}
		// 不纯为数字,清空并返回空
		else{

			return num.replace(/[^\d(\.\d)?$]/g,'');

		}
	},

	// 验证链接
	isLink(link){
		if(link.indexOf('https://') == -1 && link.indexOf('http://') == -1){
			return false;
		}else{
			return true;
		}
    },

    /**
     *  验证银行卡号(10到30位, 覆盖对公/私账户, 参考微信支付)
     * @param { string } value
     */
    isBanktNumber(value){
        if (/^[1-9]\d{9,29}$/g.test(value)) {
            return value;
        } else {
            return '';
        }
    },

    /**
     *  验证座机电话(国内),如: 0341-86091234
     * @param { string } value
     */
    isLandlineTelephone(value){
        if (/\d{3}-\d{8}|\d{4}-\d{7}/g.test(value)) {
            return value;
        } else {
            return '';
        }
    },

    /**
     *  身份证号, 支持1/2代(15位/18位数字)
     * @param { string } value
     */
    isIDCard(value){
        if (/(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0\d|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/g.test(value)) {
            return value;
        } else {
            return '';
        }
    },

    /**
     *  验证护照(包含香港、澳门)
     * @param { string } value
     */
    isPassport(value){
        if (/(^[EeKkGgDdSsPpHh]\d{8}$)|(^(([Ee][a-fA-F])|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\d{7}$)/g.test(value)) {
            return value;
        } else {
            return '';
        }
    },

}

搭建效果如下

网站: http://giftweb.pingq.cn/#/index礼品代发网