礼品代发平台有什么特点?如何搭建礼品网礼品网?
2023-02-16
1983浏览
礼品代发平台有什么特点?如何搭建礼品网礼品网?采取礼品代发的方法,可以让店铺用比较低的成本,拥有真实的发货物流,而且不需要自己去处理发货。那么靠谱的礼品代发平台有什么特点?选择礼品代发平台应该看什么?
什么是礼品网
采用赠品派送的方式,店铺可以以相对低廉的成本实现真正的派送和运费,而无需自行处理派送。 这么靠谱的送礼平台有什么特点呢? 选择送礼平台应该看什么?
送礼的意义。
当您有礼物要送给卖家时,您至少需要经过以下步骤:
整个过程虽然技术难度不大,你每天晚上都在做,但是如果你每晚需要发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.service.business;
import cn.gift.web.dao.SensitiveWordsInfoDao;
import cn.gift.web.model.SensitiveWordsInfo;
import cn.gift.web.service.tenant.TenantService;
import cn.plus.core.jdbc.PageResult;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageRowBounds;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @Description: 敏感词信息
* @author: RaveyXie
* @date: 2022年11月26日 2:42 PM
* @since
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class SensitiveWordsService {
private final SensitiveWordsInfoDao sensitiveWordsInfoDao;
private final TenantService tenantService;
/**
* 获取敏感词信息
*
* @param sensitiveStr
* @param pageRowBounds
* @return
*/
public PageResult<SensitiveWordsInfo> getSensitiveWords(String sensitiveStr, PageRowBounds pageRowBounds) {
PageInfo<SensitiveWordsInfo> pageInfo = sensitiveWordsInfoDao.getSensitiveWords(sensitiveStr, pageRowBounds);
return new PageResult<>(pageInfo.getList(), pageInfo.getTotal(), pageRowBounds.getOffset() / pageRowBounds.getLimit() + 1, pageRowBounds.getLimit());
}
public void savaOrUpdateSensitiveWords(SensitiveWordsInfo sensitiveWordsInfo) {
tenantService.checkIsAdmin();
sensitiveWordsInfoDao.saveOrUpdate(sensitiveWordsInfo);
}
public void removeSensitiveWords(Long id) {
tenantService.checkIsAdmin();
sensitiveWordsInfoDao.removeById(id);
}
}
关于密码加密
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()
相关阅读
图文阅读