2024-09-16 半流程

pull/379/head
zhp 1 year ago
parent 8612fb5c39
commit f553524baa

@ -0,0 +1,25 @@
package com.ruoyi.system.api;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.factory.RemoteChannelFallbackFactory;
import com.ruoyi.system.api.factory.RemoteCustomerApplyLogFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
*
*
* @author ruoyi
*/
@FeignClient(contextId = "remoteChannelService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteChannelFallbackFactory.class)
public interface RemoteChannelService
{
}

@ -3,12 +3,12 @@ package com.ruoyi.system.api;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.Merchant;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.factory.RemoteCustomerApplyLogFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -31,4 +31,23 @@ public interface RemoteCustomerApplyLogService
@GetMapping("/log/sum")
public R<Integer> sum(@PathVariable("merchantId") Long merchantId,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
*
* @param customerID
* @param source
* @return
*/
@GetMapping("/log/customerApply")
public R<Boolean> customerApply(@PathVariable("customerID") Long customerID,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
* @param customerApplyLog
* @return
*/
@PostMapping("/log")
public AjaxResult add(@RequestBody CustomerApplyLog customerApplyLog);
}

@ -52,4 +52,11 @@ public interface RemoteCustomerService
@PostMapping("/customer/addNewCustomer")
public R add(@RequestBody Customer customer,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* token
* @param phone
* @return
*/
@GetMapping("/customer/getCustomerToken")
public String getCustomerToken(@RequestParam("phone") String phone);
}

@ -0,0 +1,30 @@
package com.ruoyi.system.api.factory;
import com.ruoyi.system.api.RemoteChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
*
*
* @author ruoyi
*/
@Component
@Slf4j
public class RemoteChannelFallbackFactory implements FallbackFactory<RemoteChannelService>
{
@Override
public RemoteChannelService create(Throwable throwable)
{
log.error("用户服务调用失败:{}", throwable.getMessage());
return new RemoteChannelService()
{
};
}
}

@ -2,7 +2,9 @@ package com.ruoyi.system.api.factory;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.Merchant;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.RemoteCustomerApplyLogService;
import com.ruoyi.system.api.RemoteMerchantService;
import lombok.extern.slf4j.Slf4j;
@ -35,7 +37,15 @@ public class RemoteCustomerApplyLogFallbackFactory implements FallbackFactory<Re
return R.fail("获取商户已申请数失败:" + throwable.getMessage());
}
@Override
public R<Boolean> customerApply(Long customerID, String source) {
return null;
}
@Override
public AjaxResult add(CustomerApplyLog customerApplyLog) {
return null;
}
};
}
}

@ -44,6 +44,11 @@ public class RemoteCustomerFallbackFactory implements FallbackFactory<RemoteCust
log.info("新增用户失败:{}",throwable.getMessage());
return R.fail("新增用户失败");
}
@Override
public String getCustomerToken(String phone) {
return null;
}
};
}
}

@ -0,0 +1,27 @@
package com.ruoyi.common.core.constant;
public class RedisConstant {
/**
*
*/
public final static String APP_CUSTOMER_KEY = CacheConstants.PROJET + ":customer:key:";
/**
*
*/
public final static String APP_CUSTOMER_USERNAME_KEY = CacheConstants.PROJET + ":app:customer:username:key:";
/**
* ID
*/
public final static String APP_CUSTOMER_CHANNEL_KEY = CacheConstants.PROJET + ":app:customer:channel:key:";
/**
*
*/
public final static String APP_CUSTOMER_TOKEN_KEY = CacheConstants.PROJET + ":app:customer:token:key:";
/**
* app
*/
public final static String APP_DEVICE_IDENTIFICATION = CacheConstants.PROJET + ":app:app:device:identification:";
}

@ -0,0 +1,35 @@
package com.ruoyi.common.core.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
*
* @Author: daisi
* @Date: 2022/4/2 9:49
*/
@Data
@Accessors(chain = true)
public class GuestProbabilityReq implements Serializable {
private static final long serialVersionUID = -9096451963988288187L;
/**
* Id
*/
private Long planId;
/**
*
*/
private BigDecimal orderPrice;
/**
*
*/
private Double guestProbability;
/**
*
*/
private Integer resultGuestProbability;
}

@ -0,0 +1,45 @@
package com.ruoyi.common.core.domain.http;
import java.math.BigDecimal;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
/**
* customer_apply_log
*
* @author ruoyi
* @date 2024-09-15
*/
@Data
public class CustomerApplyLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Long id;
/** 用户id */
@Excel(name = "用户id")
private Long customerId;
/** 商户ID */
@Excel(name = "商户ID")
private Long merchantId;
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long channelId;
/** 订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 */
@Excel(name = "订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 ")
private Long orderStatus;
/** 成交金额 分 */
@Excel(name = "成交金额 分")
private BigDecimal price;
}

@ -0,0 +1,636 @@
package com.ruoyi.common.core.utils;
import cn.hutool.core.codec.Base64;
import org.apache.commons.codec.binary.Hex;
import org.springframework.stereotype.Component;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.regex.Pattern;
/**
* @program: JieYiHua-Cloud
* @description:
* @author: LiYu
* @create: 2021-07-23 17:02
**/
@Component
public class EncryptUtil {
public static final String MD5 = "MD5";
public static final String SHA1 = "SHA1";
public static final String HmacMD5 = "HmacMD5";
public static final String HmacSHA1 = "HmacSHA1";
public static final String DES = "DES";
public static final String AES = "AES";
public static final Charset CHARSET = StandardCharsets.UTF_8;
public static final byte keyStrSize = 16;
public static final byte ivStrSize = 16;
public static final String AES_CBC_NOPADDING = "AES/CBC/NoPadding";
public static final String DES_ECB_PKCS7PADDING = "DES/ECB/PKCS7Padding";
public static final String AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding";
/**
* 使uft-8
*/
public static String charset = "utf-8";
/**
* DES
*/
public static int keysizeDES = 0;
/**
* AES
*/
public static int keysizeAES = 128;
public static EncryptUtil me;
private EncryptUtil() {
//单例
}
//双重锁
public static EncryptUtil getInstance() {
if (me == null) {
synchronized (EncryptUtil.class) {
if (me == null) {
me = new EncryptUtil();
}
}
}
return me;
}
/**
* 使MessageDigest
*
* @param res
* @param algorithm
* @return
*/
private static String messageDigest(String res, String algorithm) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
return base64(md.digest(resBytes));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使KeyGenerator/
*
* @param res
* @param algorithm 使
* @param key 使
* @return
*/
private String keyGeneratorMac(String res, String algorithm, String key) {
try {
SecretKey sk = null;
if (key == null) {
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
sk = kg.generateKey();
} else {
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
sk = new SecretKeySpec(keyBytes, algorithm);
}
Mac mac = Mac.getInstance(algorithm);
mac.init(sk);
byte[] result = mac.doFinal(res.getBytes());
return base64(result);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使KeyGeneratorDES/AES216
*
* @param res
* @param algorithm 使
* @param key
* @param keysize
* @param isEncode
* @return
*/
private static String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
try {
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
if (keysize == 0) {
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
kg.init(new SecureRandom(keyBytes));
} else if (key == null) {
kg.init(keysize);
} else {
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
kg.init(keysize, new SecureRandom(keyBytes));
}
SecretKey sk = kg.generateKey();
SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
Cipher cipher = Cipher.getInstance(algorithm);
if (isEncode) {
cipher.init(Cipher.ENCRYPT_MODE, sks);
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
return parseByte2HexStr(cipher.doFinal(resBytes));
} else {
cipher.init(Cipher.DECRYPT_MODE, sks);
return new String(cipher.doFinal(parseHexStr2Byte(res)));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Deprecated
private static String base64(byte[] res) {
return Base64.encode(res);
}
/**
* 16
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 16
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* md5
*
* @param res
* @return
*/
@Deprecated
public String MD5(String res) {
return messageDigest(res, MD5);
}
/**
* md5
*
* @param res
* @param key
* @return
*/
@Deprecated
public String MD5(String res, String key) {
return keyGeneratorMac(res, HmacMD5, key);
}
/**
* 使SHA1
*
* @param res
* @return
*/
public static String SHA1(String res) {
return messageDigest(res, SHA1);
}
/**
* 使SHA1
*
* @param res
* @param key
* @return
*/
public String SHA1(String res, String key) {
return keyGeneratorMac(res, HmacSHA1, key);
}
/**
* 使DES
*
* @param res
* @param key
* @return
*/
public static String DESencode(String res, String key) {
return keyGeneratorES(res, DES, key, keysizeDES, true);
}
/**
* 使DES
*
* @param res
* @param key
* @return
*/
public String DESdecode(String res, String key) {
return keyGeneratorES(res, DES, key, keysizeDES, false);
}
/**
* 使
*
* @param res
* @param key
* @return
*/
public String XORencode(String res, String key) {
byte[] bs = res.getBytes();
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
}
return parseByte2HexStr(bs);
}
/**
* 使
*
* @param res
* @param key
* @return
*/
public String XORdecode(String res, String key) {
byte[] bs = parseHexStr2Byte(res);
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
}
return new String(bs);
}
/**
* 使
*
* @param res
* @param key
* @return
*/
public int XOR(int res, String key) {
return res ^ key.hashCode();
}
/**
* 使Base64
*
* @param res
* @return
*/
public String Base64Encode(String res) {
return Base64.encode(res.getBytes());
}
/**
* 使Base64
*
* @param res
* @return
*/
public String Base64Decode(String res) {
return new String(Base64.decode(res));
}
private static final int length = 128;
/**
*
*
* @param content
* @param password
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws UnsupportedEncodingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
private static byte[] encrypt(String content, String password)
throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(length, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
}
/**
*
*
* @param content
* @param password
* @return
*/
private static byte[] decrypt(byte[] content, String password)
throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(length, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
}
/**
*
*
* @param content
* @param password
* @return
*/
public static byte[] encrypt2(String content, String password) {
try {
SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} catch (NoSuchAlgorithmException | NoSuchPaddingException | UnsupportedEncodingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
@Deprecated
public static String AESencode(String content, String password) {
try {
byte[] encryptResult = encrypt(content, password);
return Base64.encode(encryptResult);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Deprecated
public static String AESdecode(String content, String password) {
try {
byte[] decryptResult = decrypt(Base64.decode(content), password);
return new String(decryptResult, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return content;
}
}
public static boolean isBase64(String str) {
String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
return Pattern.matches(base64Pattern, str);
}
public static void main(String[] args) {
// String s = AESencode("430602200007025537", "wfwbkdyrdmr");
// System.out.println(s);
// String s = AESencode("18058743226", "gsdfeygasfw");
// String s1 = AESencode("张三", "gsdfeygasfw");
// System.out.println(s);
// System.out.println(s1);
// System.out.println(Arrays.toString(Base64.decode("5vpdaf8bTigPCRakqzIZXA==")));
// String s = AESdecode("Lsz+2WDokzxEuAaoZYf0cQ==", "gsdfeygasfw");
//
// String phone = AESdecode("j6rj21kehQqc4JJS4NxTug==", "fdsasdfsdds");
// System.out.println("phone:" + phone);
// String s = AESencode("18058743226", "gsdfeygasfw");
// String s1 = AESdecode("CVr/+AgX/sHe00OQnXet9Q==", "wfwbkdyrdmr");许
// System.out.println(s1);
// String s = AESencode("13750869639", "gsdfeygasfw");
// System.out.println(s);
// System.out.println(AESdecode("O1ZWNkiAaIJLDGzwAaTfug==","gsdfeygasfw"));
// String a = AESdecode("罗娜","wfwbkdyrdmr");
// System.out.println(a);
// System.out.println(MD5Utils.encrypt(a));
// System.out.println(AESencode("17707051035","gsdfeygasfw"));
System.out.println(AESdecode("W+/dxhwi5yBWiDnqtLKY+w==", "gsdfeygasfw"));
System.out.println(AESdecode("J88FbYTTmTeKXfIBBedw1A==", "gsdfeygasfw"));
}
/***
* ApacheSHA-256
* @param str
* @return
*/
public static String getSHA256Str(String str){
MessageDigest messageDigest;
String encdeStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(str.getBytes(StandardCharsets.UTF_8));
encdeStr = Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return encdeStr;
}
/**
* AES inputStr
* 使 secretStr keyivStr iv
* sun.misc.BASE64Encoder.encode
* base64
*
*
*
* @param secretStr
* @param inputStr
* @return
*/
public static String base64StrDecode(String secretStr, String ivStr, String inputStr){
byte[] inputBytes;
inputBytes = org.apache.commons.codec.binary.Base64.decodeBase64(inputStr);
String outputStr = new String(decode(secretStr, ivStr, inputBytes), CHARSET);
System.out.println("base64Decode > base64 decrypt " + outputStr);
return outputStr.trim();
}
/**
* AES inputStr
* 使 secretStr keyivStr iv
*
* @param secretStr
* @param ivStr
* @return
*/
public static byte[] decode(String secretStr, String ivStr, byte[] inputBytes){
if (keyStrSize != secretStr.length() || ivStrSize != ivStr.length()) {
return null;
}
byte[] secretKeyBytes = secretStr.getBytes(CHARSET);
byte[] ivBytes = ivStr.getBytes(CHARSET);
byte[] outputBytes = decryptCBCNoPadding(secretKeyBytes, ivBytes, inputBytes);
return outputBytes;
}
/**
* AES/CBC/NoPadding decrypt
* 16 bytes secretKeyStr
* 16 bytes intVector
*
* @param secretKeyBytes
* @param intVectorBytes
* @param input
* @return
*/
public static byte[] decryptCBCNoPadding(byte[] secretKeyBytes, byte[] intVectorBytes, byte[] input) {
try {
IvParameterSpec iv = new IvParameterSpec(intVectorBytes);
SecretKey secretKey = new SecretKeySpec(secretKeyBytes, AES);
Cipher cipher = Cipher.getInstance(AES_CBC_NOPADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] encryptBytes = cipher.doFinal(input);
return encryptBytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* DES ECB Pkcs7 Base64 utf8
* @param data
* @param password
* @return
*/
public static String encryptECBPkcs7(String data, String password) {
if (password== null || password.length() < 8) { throw new RuntimeException("加密失败key不能小于8位"); }
if(StringUtils.isBlank(data)){ return null; }
try {
//下面这行在进行PKCS7Padding加密时必须加上否则报错
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//根据传入的秘钥内容生成符合DES加密解密格式的秘钥内容
DESKeySpec dks = new DESKeySpec(password.getBytes());
//获取DES秘钥生成器对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
// 生成秘钥key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
//获取DES/ECB/PKCS7Padding该种级别的加解密对象
Cipher cipher = Cipher.getInstance(DES_ECB_PKCS7PADDING);
//初始化加解密对象【opmode:确定是加密还是解密模式secretKey是加密解密所用秘钥】
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));
return Base64.encode(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decryptECBPkcs7(String data, String password) {
if (password== null || password.length() < 8) { throw new RuntimeException("解密失败key不能小于8位"); }
if(StringUtils.isBlank(data)){ return null; }
try {
//下面这行在进行PKCS7Padding加密时必须加上否则报错
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//根据传入的秘钥内容生成符合DES加密解密格式的秘钥内容
DESKeySpec dks = new DESKeySpec(password.getBytes());
//获取DES秘钥生成器对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
// 生成秘钥key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
//获取DES/ECB/PKCS7Padding该种级别的加解密对象
Cipher cipher = Cipher.getInstance(DES_ECB_PKCS7PADDING);
//初始化加解密对象【opmode:确定是加密还是解密模式secretKey是加密解密所用秘钥】
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.decode(data.getBytes(charset))), charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* AES
* @param content
* @param password
* @return
*/
public static byte[] encryptECBPkcs5(byte[] content, byte[] password) {
if (content == null || password == null)
return null;
try {
Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5PADDING);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password, AES));
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* AES
* @param content
* @param password
* @return
*/
public static byte[] decryptECBPkcs5(byte[] content, byte[] password) {
if (content == null || password == null)
return null;
try {
Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5PADDING);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password, AES));
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

@ -0,0 +1,155 @@
package com.ruoyi.common.core.utils;
import com.ruoyi.common.core.domain.GuestProbabilityReq;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.*;
/**
*
* @Author: daisi
* @Date: 2022/4/2 11:10
*/
@Slf4j
public class ProbitUtil {
public static GuestProbabilityReq calculatePlanTheProbability(List<GuestProbabilityReq> guestProbabilityReqs) {
//按排序价格排序
Collections.sort(guestProbabilityReqs, new Comparator<GuestProbabilityReq>() {
@Override
public int compare(GuestProbabilityReq o1, GuestProbabilityReq o2) {
return o2.getOrderPrice().compareTo(o1.getOrderPrice());
}
});
List<GuestProbabilityReq> list = new ArrayList<>(5);
for (GuestProbabilityReq guestProbabilityReq : guestProbabilityReqs) {
// if (guestProbabilityReq.getOrderPrice().compareTo(guestProbabilityReqs.get(0).getOrderPrice()) == 0) {
// list.add(guestProbabilityReq);
// }
list.add(guestProbabilityReq);
}
log.info("排序后的数据:{}",list);
//重置概率
resetTranslate(list);
int index = drawGift(list);
return guestProbabilityReqs.get(index);
}
private static List<GuestProbabilityReq> resetTranslate(List<GuestProbabilityReq> reqs) {
if (reqs.size()!=1){
//高值得一部分
int count = 0;
//获取计数
BigDecimal orderPrice = reqs.get(0).getOrderPrice();
for (int i = 0; i < reqs.size(); i++) {
if (i+1<reqs.size()&&reqs.get(i).getOrderPrice().compareTo(reqs.get(i+1).getOrderPrice())==0&&orderPrice.compareTo(reqs.get(i).getOrderPrice())==0){
count++;
}
}
///获取最高的概率
BigDecimal bigDecimal = new BigDecimal(reqs.get(0).getGuestProbability().toString());
if (count!=0){
//用最高的概率除以计数 得到最高价的平均概率
BigDecimal divide = bigDecimal.divide(new BigDecimal(count+1),3,BigDecimal.ROUND_DOWN);
for (int i = 0; i <= count; i++) {
//循环重设最高概率
reqs.get(i).setGuestProbability(divide.doubleValue());
}
}
//低值得一部分
BigDecimal remTotal = new BigDecimal(1).subtract(bigDecimal);
BigDecimal b = remTotal.divide(new BigDecimal((reqs.size()-count-1)==0?1:(reqs.size()-count-1)),3,BigDecimal.ROUND_HALF_UP);
for (int i = count+1; i < reqs.size(); i++) {
reqs.get(i).setGuestProbability(b.doubleValue());
}
}
//log.info("重置概率后的概率,{}",reqs);
return reqs;
}
public static int drawGift(List<GuestProbabilityReq> guestProbabilityReqList) {
if (null != guestProbabilityReqList && guestProbabilityReqList.size() > 0) {
List<Double> orgProbList = new ArrayList<Double>(guestProbabilityReqList.size());
for (GuestProbabilityReq guest : guestProbabilityReqList) {
//按顺序将概率添加到集合中
orgProbList.add(guest.getGuestProbability());
}
return draw(orgProbList);
}
return -1;
}
public static int draw(List<Double> giftProbList) {
List<Double> sortRateList = new ArrayList<Double>();
// 计算概率总和
Double sumRate = 0D;
for (Double prob : giftProbList) {
sumRate += prob;
}
if (sumRate != 0) {
double rate = 0D; //概率所占比例
for (Double prob : giftProbList) {
rate += prob;
// 构建一个比例区段组成的集合(避免概率和不为1)
sortRateList.add(rate / sumRate);
}
// 随机生成一个随机数,并排序
double random = Math.random();
sortRateList.add(random);
Collections.sort(sortRateList);
// 返回该随机数在比例集合中的索引
return sortRateList.indexOf(random);
}
return -1;
}
// public static void main(String[] args) {
//// System.out.println(LocalDateTimeUtils.getStringFromLocalDateTime(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.offset(LocalDateTime.now(), -7, ChronoUnit.DAYS))));
//// System.out.println(LocalDateTimeUtils.getStringFromLocalDateTime(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.offset(LocalDateTime.now(), -1, ChronoUnit.DAYS))));
// int a=0;
// List<GuestProbabilityReq> guestProbabilityReqs = new ArrayList<>();
// for (int i = 0; i < 20; i++) {
// List<GuestProbabilityReq> list = new ArrayList<>();
// GuestProbabilityReq req = new GuestProbabilityReq();
// req.setPlanId(1L).setOrderPrice(new BigDecimal(104.00)).setGuestProbability(0.8D);
//
// GuestProbabilityReq req1 = new GuestProbabilityReq();
// req1.setPlanId(2L).setOrderPrice(new BigDecimal(120)).setGuestProbability(0.8D);
//
// GuestProbabilityReq req2 = new GuestProbabilityReq();
// req2.setPlanId(3L).setOrderPrice(new BigDecimal(90)).setGuestProbability(0.8D);
//
// GuestProbabilityReq req3 = new GuestProbabilityReq();
// req3.setPlanId(4L).setOrderPrice(new BigDecimal(110)).setGuestProbability(0.4D);
//
// GuestProbabilityReq req4 = new GuestProbabilityReq();
// req4.setPlanId(5L).setOrderPrice(new BigDecimal(110)).setGuestProbability(0.6D);
////
//// GuestProbabilityReq req5 = new GuestProbabilityReq();
//// req5.setPlanId(6L).setOrderPrice(new BigDecimal(80)).setGuestProbability(0.6D);
//
// list.add(req);
// list.add(req1);
// list.add(req2);
// list.add(req3);
// list.add(req4);
//// list.add(req5);
//
// guestProbabilityReqs.add(calculatePlanTheProbability(list));
//
// }
// int b = 0;
// int c = 0;
// for (GuestProbabilityReq req:guestProbabilityReqs) {
// if (req.getPlanId()==2){
// b++;
// }else {
// c++;
// }
// }
// System.out.println("几率:"+c+" "+b);
// }
}

@ -0,0 +1,390 @@
package com.ruoyi.common.redis.service;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.constant.RedisConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Created with IntelliJ IDEA.
*
* @Author:
* @Date: 2023/08/06/15:05
* @Description: token
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class CustomerTokenService {
private final RedisService redisService;
/**
* token
*/
private static final Long EXPIRE_TIME = 30 * 24 * 60 * 60L;
/**
* 128token
*
* @param customerId id
* @param phone
* @param deviceType
* @param channelId id
* @return token
*/
public String generateToken(Long customerId, String phone, String deviceType, Long channelId) {
//获取到老的token
String oldToken = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (StringUtils.hasText(oldToken)) {
//删除老的token
this.refreshToken(oldToken);
}
String newToken = null;
boolean exit = true;
while (exit) {
newToken = RandomUtil.randomString(128);
if (!redisService.hasKey(RedisConstant.APP_CUSTOMER_USERNAME_KEY + newToken)) {
exit = false;
}
}
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + newToken, phone, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId, newToken, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + newToken, channelId, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + newToken, customerId, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.setCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + newToken, deviceType.toString(), EXPIRE_TIME, TimeUnit.SECONDS);
return newToken;
}
/**
* token
*
* @param token token
* @return truefalse
*/
public boolean isExpire(String token) {
String customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token) + StrUtil.EMPTY;
String originalToken = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
String username = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token) + StrUtil.EMPTY;
return StringUtils.isEmpty(customerId) || StringUtils.isEmpty(originalToken) || !originalToken.equals(token) || !StringUtils.hasText(username);
}
/**
* token
*
* @param token token
* @param booleans 退
*/
public void refreshToken(String token, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
if (Objects.isNull(customerId) && logOut) {
new Exception("登录已过期,请重新登录");
}
redisService.expire(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.expire(RedisConstant.APP_CUSTOMER_KEY + customerId, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.expire(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.expire(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
redisService.expire(RedisConstant.APP_DEVICE_IDENTIFICATION + token, EXPIRE_TIME, TimeUnit.SECONDS);
}
/**
* idtoken
*
* @param customerId id
* @param booleans 退
* @return token
*/
public String refreshToken(Long customerId, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (StringUtils.isEmpty(token) && logOut) {
new Exception("登录已过期,请重新登录");
}
this.refreshToken(token);
return token;
}
/**
* token
*
* @param request
*/
public void refreshToken(HttpServletRequest request) {
String token = getToken(request);
this.refreshToken(token);
}
/**
* token
*
* @param token token
* @param booleans 退
*/
public void removeToken(String token, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
if (Objects.isNull(customerId) && logOut) {
new Exception("登录已过期,请重新登录");
}
redisService.deleteObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
redisService.deleteObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
redisService.deleteObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token);
redisService.deleteObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
redisService.deleteObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
}
/**
* idtoken
*
* @param customerId id
*/
public void removeToken(Long customerId) {
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
this.removeToken(token);
}
/**
* HttpServletRequesttoken
*
* @param request HttpServletRequest
* @param booleans 退
* @return token
*/
public String getToken(HttpServletRequest request, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
String token = request.getHeader("Authorization");
if (StringUtils.isEmpty(token) && logOut) {
String requestURI = request.getRequestURI();
log.info("登录过期重新登录, requestURI:{}, logOut:{}, token:{}", requestURI, logOut, token);
new Exception("登录已过期,请重新登录");
}
return token;
}
/**
* idtoken
*
* @param customerId id
* @return token
*/
public String getToken(Long customerId) {
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (StringUtils.isEmpty(token)) {
return null;
}
return token;
}
/**
* tokenID
*
* @param token token
* @param logOut 退
* @return ID
*/
public Long getCustomerId(String token, Boolean logOut) {
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
if (Objects.isNull(customerId) && logOut) {
new Exception("登录已过期,请重新登录");
}
return customerId;
}
/**
* HttpServletRequestID
*
* @param request HttpServletRequest
* @param booleans 退
* @return ID
*/
public Long getCustomerId(HttpServletRequest request, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
String token = getToken(request, logOut);
if (StringUtils.isEmpty(token)) {
return null;
}
return getCustomerId(token, logOut);
}
/**
* token
*
* @param token token
* @param booleans 退
* @return
*/
public String getPhone(String token, Boolean... booleans) {
boolean logOut = isLogOut(booleans);
String phone = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token);
if (Objects.isNull(phone) && logOut) {
new Exception("登录已过期,请重新登录");
}
return phone;
}
/**
* ID
*
* @param customerId ID
* @param booleans 退
* @return
*/
public String getPhone(Long customerId, Boolean... booleans) {
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (Objects.isNull(token) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
String phone = getPhone(token);
// try {
// phone = EncryptUtil.AESdecode(phone, redisService.getAppEncrypted());
// }catch (Exception e) {
// return phone;
// }
return phone;
}
/**
* HttpServletRequest
*
* @param request HttpServletRequest
* @return
*/
public String getPhone(HttpServletRequest request) {
String token = getToken(request);
return getPhone(token);
}
/**
* tokenID
*
* @param token token
* @param booleans 退
* @return ID
*/
public Long getChannelId(String token, Boolean... booleans) {
Long channelId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
if (Objects.isNull(channelId) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
return channelId;
}
/**
* HttpServletRequestID
*
* @param request HttpServletRequest
* @return ID
*/
public Long getChannelId(HttpServletRequest request, Boolean... booleans) {
String token = getToken(request,booleans);
return getChannelId(token,booleans);
}
/**
* IDID
*
* @param customerId ID
* @param booleans 退
* @return ID
*/
public Long getChannelId(Long customerId, Boolean... booleans) {
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (Objects.isNull(token) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
Long channelId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
if (Objects.isNull(channelId) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
return channelId;
}
/**
*
* @param customerId ID
* @param channelId ID
*/
public void setChannelId(Long customerId,Long channelId) {
String token = getToken(customerId);
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token, channelId, EXPIRE_TIME, TimeUnit.SECONDS);
}
/**
* token
*
* @param token token
* @param booleans 退
* @return
*/
public String getDeviceType(String token, Boolean... booleans) {
String deviceType = redisService.getCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
if (Objects.isNull(deviceType) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
return deviceType;
}
/**
* HttpServletRequest
*
* @param request HttpServletRequest
* @return
*/
public String getDeviceType(HttpServletRequest request,Boolean... booleans) {
String token = getToken(request,booleans);
return getDeviceType(token,booleans);
}
/**
* HttpServletRequest
*
* @param request HttpServletRequest
* @return
*/
public String getDeviceTypeStr(HttpServletRequest request) {
String token = getToken(request);
return getDeviceType(token);
}
/**
* ID
*
* @param customerId ID
* @param booleans 退
* @return
*/
public String getDeviceType(Long customerId, Boolean... booleans) {
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
if (Objects.isNull(token) && isLogOut(booleans)) {
new Exception("登录已过期,请重新登录");
}
String deviceType = redisService.getCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
if (!StringUtils.hasText(deviceType)) {
deviceType = "ANDROID";
}
return deviceType;
}
/**
* 退
*
* @param booleans
* @return 退
*/
public Boolean isLogOut(Boolean... booleans) {
if (booleans == null || booleans.length == 0) {
return true;
}
return booleans[0];
}
}

@ -0,0 +1,43 @@
package com.ruoyi.btc.controller;
import com.ruoyi.btc.domain.ComPublicHalfDto;
import com.ruoyi.btc.service.ISysPublicAllService;
import com.ruoyi.btc.service.ISysPublicHalfService;
import com.ruoyi.common.core.web.domain.AjaxResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
* API
*
* @author z
*/
@RestController
@Slf4j
@RequestMapping("/all/api")
@RequiredArgsConstructor
public class PublicAllController {
private final ISysPublicAllService sysPublicAllService;
/**
*
*/
@PostMapping("check")
public AjaxResult upload(@RequestBody ComPublicHalfDto comPublicHalfDto)
{
sysPublicAllService.check(comPublicHalfDto);
return null;
}
/**
*
*/
@PostMapping("input")
public AjaxResult input(@RequestBody ComPublicHalfDto comPublicHalfDto)
{
sysPublicAllService.input(comPublicHalfDto);
return null;
}
}

@ -5,10 +5,7 @@ import com.ruoyi.btc.service.ISysPublicHalfService;
import com.ruoyi.common.core.web.domain.AjaxResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* API
@ -46,10 +43,10 @@ public class PublicHalfController{
/**
*
*/
@PostMapping("checkOrder")
public AjaxResult checkOrder(@RequestBody ComPublicHalfDto comPublicHalfDto)
@GetMapping("checkOrder")
public AjaxResult checkOrder(@RequestParam("phoneMD5")String phoneMd5,@RequestParam("channelSign")String channelSign)
{
sysPublicHalfService.checkOrder(comPublicHalfDto);
sysPublicHalfService.checkOrder(phoneMd5,channelSign);
return null;
}
}

@ -6,14 +6,20 @@ import lombok.Data;
public class CustomerInfoDto {
//手机号码Md5
private String phoneMd5;
//手机号
private String phone;
//性别 0 男 1 女
private Integer sex;
//手机号码Md5
private String nameMd5;
//姓名
private String name;
//年龄
private Integer age;
//手身份证md5
private String idCardMd5;
//身份证好
private String idCard;
//所在城市
private String city;
//所在城市代码

@ -0,0 +1,27 @@
package com.ruoyi.btc.service;
import com.ruoyi.btc.domain.ComPublicHalfDto;
import com.ruoyi.common.core.web.domain.AjaxResult;
/**
*
*
* @author ruoyi
*/
public interface ISysPublicAllService
{
/**
*
* @param comPublicHalfDto
*/
AjaxResult check(ComPublicHalfDto comPublicHalfDto);
/**
*
* @param comPublicHalfDto
*/
AjaxResult input(ComPublicHalfDto comPublicHalfDto);
}

@ -2,6 +2,7 @@ package com.ruoyi.btc.service;
import com.ruoyi.btc.domain.ComPublicHalfDto;
import com.ruoyi.common.core.web.domain.AjaxResult;
import org.springframework.web.bind.annotation.RequestParam;
/**
*
@ -25,8 +26,8 @@ public interface ISysPublicHalfService
/**
*
* @param comPublicHalfDto
* @param
*/
AjaxResult checkOrder(ComPublicHalfDto comPublicHalfDto);
AjaxResult checkOrder(String phoneMd5, String channelSign);
}

@ -0,0 +1,249 @@
package com.ruoyi.btc.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.btc.domain.ComPublicHalfDto;
import com.ruoyi.btc.domain.CustomerInfoDto;
import com.ruoyi.btc.service.ISysPublicAllService;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.Channel;
import com.ruoyi.common.core.domain.http.Customer;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.Merchant;
import com.ruoyi.common.core.utils.ProbitUtil;
import com.ruoyi.common.core.utils.SecureUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.api.RemoteCustomerApplyLogService;
import com.ruoyi.system.api.RemoteCustomerService;
import com.ruoyi.system.api.RemoteMerchantService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*
* @author ruoyi
*/
@Service
@RequiredArgsConstructor
public class SysPublicAllServiceImpl implements ISysPublicAllService
{
private final RemoteCustomerService remoteCustomerService;
private final RemoteMerchantService remoteMerchantService;
private final RemoteCustomerApplyLogService remoteCustomerApplyLogService;
private final RedisService redisService;
/**
*
* @param comPublicHalfDto
*/
@Override
public AjaxResult check(ComPublicHalfDto comPublicHalfDto) {
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
return AjaxResult.error("渠道标识不能未空");
}
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
if (channel==null||channel.getId()==null){
return AjaxResult.error("渠道不存在");
}
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
return AjaxResult.error("加密数据不能为空");
}
//解密为customerInfoDto
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
if (s==null){
return AjaxResult.error("解密异常");
}
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
//校验数据必传参数是否未传
String checkData = checkData(customerInfoDto);
if (checkData!=null){
return AjaxResult.error(checkData);
}
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
Customer customer = new Customer();
BeanUtil.copyProperties(customerInfoDto,customer);
customer.setChannelId(channel.getId());
customer.setActurlName(customerInfoDto.getNameMd5());
customer.setFirstLoginTime(new Date());
customer.setLastLoginTime(new Date());
customer.setIsAuth(false);
customer.setStatus(2);
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
if (customerInfoByPhoneMd5.getCode()==200){
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
}else {
remoteCustomerService.add(customer,SecurityConstants.INNER);
}
//TODO 暂时不做 目前下游暂时不需要 匹配资质 造轮子 返回多个符合的商户
List<Merchant> merchants = matchMerchant(customer);
//结束返回上游结果
Map<String,Boolean> re = new HashMap<>();
if (merchants.size()>0){
re.put("data",true);
return AjaxResult.success(re);
}
re.put("data",false);
return AjaxResult.success(re);
}
/**
*
* @param customer
*/
private List<Merchant> matchMerchant(Customer customer) {
R<List<Merchant>> listR = remoteMerchantService.merchantList(SecurityConstants.INNER);
if (listR.getCode()!=200){
return new ArrayList<>();
}
List<Merchant> merchants = new ArrayList<>();
for (Merchant merchant:listR.getData()) {
//限量判定
R<Integer> sum = remoteCustomerApplyLogService.sum(merchant.getId(), SecurityConstants.INNER);
if (merchant.getLimitType()==1&&merchant.getLimitNum()<=sum.getData()){
continue;
}
if (customer.getAge()<merchant.getAgeLimitStart()||customer.getAge()>merchant.getAgeLimitEnd()){
continue;
}
if (merchant.getChannelLimitType()==1||merchant.getChannelLimitType()==2){
List<Long> list = Arrays.asList(merchant.getChannelLimit().split(",")).stream().map(val->Long.parseLong(val)).collect(Collectors.toList());
if (merchant.getChannelLimitType()==1&& !list.contains(customer.getChannelId())){
continue;
}
if (merchant.getChannelLimitType()==2&& list.contains(customer.getChannelId())){
continue;
}
}
merchants.add(merchant);
}
return merchants;
}
/**
*
* @param customerInfoDto
*/
private String checkData(CustomerInfoDto customerInfoDto) {
if (customerInfoDto.getAge()==null){
return "年龄不能为空";
}
if (StringUtils.isEmpty(customerInfoDto.getPhoneMd5())){
return "手机号MD5不能为空";
}
if (StringUtils.isEmpty(customerInfoDto.getCity())){
return "城市不能为空";
}
if (customerInfoDto.getCityCode()==null){
return "城市编码不能为空";
}
if (customerInfoDto.getSocialSecurity()==null){
return "本地社保不能为空";
}
if (customerInfoDto.getAccumulationFund()==null){
return "本地公积金不能为空";
}
if (customerInfoDto.getCar()==null){
return "车产不能为空";
}
if (customerInfoDto.getHourse()==null){
return "房产不能为空";
}
if (customerInfoDto.getGuarantee()==null){
return "房产不能为空";
}
if (customerInfoDto.getZhiMa()==null){
return "芝麻分不能为空";
}
if (customerInfoDto.getCareer()==null){
return "职业不能为空";
}
if (customerInfoDto.getCreditCard()==null){
return "信用卡不能为空";
}
if (customerInfoDto.getEducation()==null){
return "学历不能为空";
}
if (customerInfoDto.getMonthlyIncome()==null){
return "月收入不能为空";
}
return null;
}
/**
*
* @param comPublicHalfDto
*/
@Override
public AjaxResult input(ComPublicHalfDto comPublicHalfDto) {
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
return AjaxResult.error("渠道标识不能未空");
}
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
if (channel==null||channel.getId()==null){
return AjaxResult.error("渠道不存在");
}
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
return AjaxResult.error("加密数据不能为空");
}
//解密为customerInfoDto
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
if (s==null){
return AjaxResult.error("解密异常");
}
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
//校验数据必传参数是否未传
String checkData = checkData(customerInfoDto);
//转化字段未数据库中资质字段 更新 用户实名状态 一并保存用户申请记录 已申请
if (checkData!=null){
return AjaxResult.error(checkData);
}
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
Customer customer = new Customer();
BeanUtil.copyProperties(customerInfoDto,customer);
customer.setChannelId(channel.getId());
customer.setActurlName(customerInfoDto.getName());
customer.setFirstLoginTime(new Date());
customer.setLastLoginTime(new Date());
customer.setIsAuth(true);
customer.setStatus(1);
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
if (customerInfoByPhoneMd5.getCode()==200){
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
}else {
return AjaxResult.error("今日未撞库");
}
//匹配资质 造轮子 返回多个符合的商户
List<Merchant> merchants = matchMerchant(customer);
//TODO 取排序第一的
//返回渠道绑定的注册页拼接token
Map<String,Object> result = new HashMap<>();
Map<String,Object> map = new HashMap<>();
//TODO 下游是H5承接不了上游全流程 暂时不做
CustomerApplyLog customerApplyLog = new CustomerApplyLog();
customerApplyLog.setCustomerId(customerInfoByPhoneMd5.getData().getId());
customerApplyLog.setChannelId(channel.getId());
customerApplyLog.setMerchantId(merchants.get(0).getId());
customerApplyLog.setOrderStatus(0l);
remoteCustomerApplyLogService.add(customerApplyLog);
//返回上游信息
return AjaxResult.success(result);
}
}

@ -1,6 +1,7 @@
package com.ruoyi.btc.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.btc.domain.ComPublicHalfDto;
import com.ruoyi.btc.domain.CustomerInfoDto;
@ -10,7 +11,9 @@ import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.Channel;
import com.ruoyi.common.core.domain.http.Customer;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.Merchant;
import com.ruoyi.common.core.utils.ProbitUtil;
import com.ruoyi.common.core.utils.SecureUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
@ -20,6 +23,7 @@ import com.ruoyi.system.api.RemoteCustomerService;
import com.ruoyi.system.api.RemoteMerchantService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.*;
import java.util.stream.Collectors;
@ -186,21 +190,66 @@ public class SysPublicHalfServiceImpl implements ISysPublicHalfService
@Override
public AjaxResult input(ComPublicHalfDto comPublicHalfDto) {
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
return AjaxResult.error("渠道标识不能未空");
}
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
if (channel==null||channel.getId()==null){
return AjaxResult.error("渠道不存在");
}
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
return AjaxResult.error("加密数据不能为空");
}
//解密为customerInfoDto
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
if (s==null){
return AjaxResult.error("解密异常");
}
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
//校验数据必传参数是否未传
String checkData = checkData(customerInfoDto);
//转化字段未数据库中资质字段 更新 用户实名状态 一并保存用户申请记录 已申请
if (checkData!=null){
return AjaxResult.error(checkData);
}
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
Customer customer = new Customer();
BeanUtil.copyProperties(customerInfoDto,customer);
customer.setChannelId(channel.getId());
customer.setActurlName(customerInfoDto.getName());
customer.setFirstLoginTime(new Date());
customer.setLastLoginTime(new Date());
customer.setIsAuth(true);
customer.setStatus(1);
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
if (customerInfoByPhoneMd5.getCode()==200){
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
}else {
return AjaxResult.error("今日未撞库");
}
//匹配资质 造轮子 返回多个符合的商户
//取排序第一的
List<Merchant> merchants = matchMerchant(customer);
//TODO 取排序第一的
//返回渠道绑定的注册页拼接token
Map<String,Object> result = new HashMap<>();
Map<String,Object> map = new HashMap<>();
if (CollectionUtil.isEmpty(merchants)){
map.put("url","");
map.put("regist",false);
result.put("data",map);
return AjaxResult.success(result);
}
String url = channel.getHtmlLocation() + "token="+remoteCustomerService.getCustomerToken(customer.getPhone());
map.put("url",url);
map.put("regist",true);
result.put("data",map);
CustomerApplyLog customerApplyLog = new CustomerApplyLog();
customerApplyLog.setCustomerId(customerInfoByPhoneMd5.getData().getId());
customerApplyLog.setChannelId(channel.getId());
customerApplyLog.setOrderStatus(0l);
remoteCustomerApplyLogService.add(customerApplyLog);
//返回上游信息
return null;
return AjaxResult.success(result);
}
/**
@ -208,14 +257,25 @@ public class SysPublicHalfServiceImpl implements ISysPublicHalfService
* @param comPublicHalfDto
*/
@Override
public AjaxResult checkOrder(ComPublicHalfDto comPublicHalfDto) {
public AjaxResult checkOrder(String phoneMd5, String channelSign) {
//根据手机号MD5渠道标识 查询是否成功
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(phoneMd5, SecurityConstants.INNER);
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_ID + customerInfoByPhoneMd5.getData().getChannelId());
R<Boolean> booleanR = remoteCustomerApplyLogService.customerApply(customerInfoByPhoneMd5.getData().getId(), SecurityConstants.INNER);
//失败直接失败
if (!booleanR.getData()){
return AjaxResult.success("用户未申请","false");
}
//成功抽奖 按扣量比抽
//成功数
double succ = channel.getScore()*0.01;
//扣量数
double socre = 1-(channel.getScore()*0.01);
List<Double> drow = new ArrayList<>();
drow.add(succ);
drow.add(socre);
int draw = ProbitUtil.draw(drow);
//返回是否成功
return null;
return draw==0?AjaxResult.success("用户已申请",true):AjaxResult.success("用户未申请","false");
}
}

@ -0,0 +1,23 @@
package com.ruoyi.system.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Minio
*
* @author ruoyi
*/
@Configuration
@ConfigurationProperties(prefix = "system")
@Data
public class SystemConfig
{
/**
*
*/
private String AESkey;
}

@ -1,7 +1,6 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.core.constant.SecurityConstants;
@ -11,7 +10,7 @@ import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.system.domain.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.system.service.ICustomerApplyLogService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
@ -51,10 +50,23 @@ public class CustomerApplyLogController extends BaseController
* @param source
* @return
*/
@GetMapping("/log/sum")
@GetMapping("/sum")
public R<Integer> sum(@PathVariable("merchantId") Long merchantId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source){
return R.ok(customerApplyLogService.getApplySum(merchantId));
}
/**
*
*
*
* @param customerID
* @param source
* @return
*/
@GetMapping("/customerApply")
public R<Boolean> customerApply(@PathVariable("customerID") Long customerID,@RequestHeader(SecurityConstants.FROM_SOURCE) String source){
return customerApplyLogService.getCustomerApply(customerID);
}
/**
*
*/

@ -131,4 +131,9 @@ public class CustomerController extends BaseController
{
return toAjax(customerService.deleteCustomerByIds(ids));
}
@GetMapping("/getCustomerToken")
public String getCustomerToken(@RequestParam("phone") String phone) {
return customerService.getCustomerToken(phone);
}
}

@ -1,111 +0,0 @@
package com.ruoyi.system.domain;
import java.math.BigDecimal;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
/**
* customer_apply_log
*
* @author ruoyi
* @date 2024-09-15
*/
public class CustomerApplyLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Long id;
/** 用户id */
@Excel(name = "用户id")
private Long customerId;
/** 商户ID */
@Excel(name = "商户ID")
private Long merchantId;
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long channelId;
/** 订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 */
@Excel(name = "订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 ")
private Long orderStatus;
/** 成交金额 分 */
@Excel(name = "成交金额 分")
private BigDecimal price;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setCustomerId(Long customerId)
{
this.customerId = customerId;
}
public Long getCustomerId()
{
return customerId;
}
public void setMerchantId(Long merchantId)
{
this.merchantId = merchantId;
}
public Long getMerchantId()
{
return merchantId;
}
public void setChannelId(Long channelId)
{
this.channelId = channelId;
}
public Long getChannelId()
{
return channelId;
}
public void setOrderStatus(Long orderStatus)
{
this.orderStatus = orderStatus;
}
public Long getOrderStatus()
{
return orderStatus;
}
public void setPrice(BigDecimal price)
{
this.price = price;
}
public BigDecimal getPrice()
{
return price;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("customerId", getCustomerId())
.append("merchantId", getMerchantId())
.append("channelId", getChannelId())
.append("orderStatus", getOrderStatus())
.append("price", getPrice())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

@ -4,7 +4,6 @@ import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.core.domain.http.Channel;
import com.ruoyi.system.domain.CustomerApplyLog;
/**
* Mapper

@ -3,8 +3,7 @@ package com.ruoyi.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.core.domain.http.Merchant;
import com.ruoyi.system.domain.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
/**
* Mapper

@ -3,7 +3,8 @@ package com.ruoyi.system.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.system.domain.CustomerApplyLog;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
/**
* Service
@ -67,4 +68,11 @@ public interface ICustomerApplyLogService extends IService<CustomerApplyLog>
* @return
*/
Integer getApplySum(Long merchantId);
/**
*
* @param customerID
* @return
*/
R<Boolean> getCustomerApply(Long customerID);
}

@ -75,4 +75,11 @@ public interface ICustomerService extends IService<Customer>
* @return
*/
R updateByPhoneMd5(Customer customer);
/**
* tooken
* @param phone
* @return
*/
String getCustomerToken(String phone);
}

@ -5,12 +5,13 @@ import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.LocalDateTimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CustomerApplyLogMapper;
import com.ruoyi.system.domain.CustomerApplyLog;
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
import com.ruoyi.system.service.ICustomerApplyLogService;
/**
@ -114,4 +115,20 @@ public class CustomerApplyLogServiceImpl extends ServiceImpl<CustomerApplyLogMap
.le(CustomerApplyLog::getCreateTime, LocalDateTimeUtils.getDateFromLocalDateTime(LocalDateTimeUtils.getTodayEndTime())));
return aLong.intValue();
}
/**
*
* @param customerID
* @return
*/
@Override
public R<Boolean> getCustomerApply(Long customerID) {
Long aLong = customerApplyLogMapper.selectCount(
new LambdaQueryWrapper<CustomerApplyLog>()
.isNotNull(CustomerApplyLog::getMerchantId)
.eq(CustomerApplyLog::getOrderStatus, 0)
.ge(CustomerApplyLog::getCreateTime, LocalDateTimeUtils.getDateFromLocalDateTime(LocalDateTimeUtils.getTodayStartTime()))
.le(CustomerApplyLog::getCreateTime, LocalDateTimeUtils.getDateFromLocalDateTime(LocalDateTimeUtils.getTodayEndTime())));
return R.ok(aLong>0);
}
}

@ -6,13 +6,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.constant.RedisConstant;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.EncryptUtil;
import com.ruoyi.common.redis.service.CustomerTokenService;
import com.ruoyi.system.config.SystemConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CustomerMapper;
import com.ruoyi.common.core.domain.http.Customer;
import com.ruoyi.system.service.ICustomerService;
import org.springframework.util.StringUtils;
/**
* Service
@ -22,9 +28,11 @@ import com.ruoyi.system.service.ICustomerService;
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements IService<Customer>,ICustomerService {
private final CustomerMapper customerMapper;
private final SystemConfig systemConfig;
private final CustomerTokenService customerTokenService;
/**
*
*
@ -126,4 +134,19 @@ public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> i
}
return R.fail();
}
@Override
public String getCustomerToken(String phone) {
log.info("获取用户token,手机号:{},加密结果:{}", phone, EncryptUtil.AESencode(phone, systemConfig.getAESkey()));
Customer customer = this.getOne(new LambdaQueryWrapper<Customer>().eq(Customer::getPhone, EncryptUtil.AESencode(phone, systemConfig.getAESkey())));
log.info("获取用户token,用户信息:{}", customer);
//获取到用户登陆的token
String token = customerTokenService.getToken(customer.getId());
if (StringUtils.isEmpty(token)) {
//生成一个长60的token
token = customerTokenService.generateToken(customer.getId(), customer.getPhone(), "ANDROID", customer.getChannelId());
}
return token;
}
}

@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.CustomerApplyLogMapper">
<resultMap type="com.ruoyi.system.domain.CustomerApplyLog" id="CustomerApplyLogResult">
<resultMap type="com.ruoyi.common.core.domain.http.CustomerApplyLog" id="CustomerApplyLogResult">
<result property="id" column="id" />
<result property="customerId" column="customer_id" />
<result property="merchantId" column="merchant_id" />
@ -20,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select id, customer_id, merchant_id, channel_id, order_status, price, create_time, update_time, remark from customer_apply_log
</sql>
<select id="selectCustomerApplyLogList" parameterType="com.ruoyi.system.domain.CustomerApplyLog" resultMap="CustomerApplyLogResult">
<select id="selectCustomerApplyLogList" parameterType="com.ruoyi.common.core.domain.http.CustomerApplyLog" resultMap="CustomerApplyLogResult">
<include refid="selectCustomerApplyLogVo"/>
<where>
<if test="customerId != null "> and customer_id = #{customerId}</if>
@ -36,7 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<insert id="insertCustomerApplyLog" parameterType="com.ruoyi.system.domain.CustomerApplyLog" useGeneratedKeys="true" keyProperty="id">
<insert id="insertCustomerApplyLog" parameterType="com.ruoyi.common.core.domain.http.CustomerApplyLog" useGeneratedKeys="true" keyProperty="id">
insert into customer_apply_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="customerId != null">customer_id,</if>
@ -60,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<update id="updateCustomerApplyLog" parameterType="com.ruoyi.system.domain.CustomerApplyLog">
<update id="updateCustomerApplyLog" parameterType="com.ruoyi.common.core.domain.http.CustomerApplyLog">
update customer_apply_log
<trim prefix="SET" suffixOverrides=",">
<if test="customerId != null">customer_id = #{customerId},</if>

Loading…
Cancel
Save