parent
6c1848e645
commit
309f6910d5
@ -1,2 +1,2 @@ |
||||
fileUrl=/home/project/hsg/filesystem |
||||
cmsPath=/home/project/hsg/filesystem/cmsPath |
||||
fileUrl=/home/project/phg/filesystem |
||||
cmsPath=/home/project/phg/filesystem/cmsPath |
||||
|
@ -0,0 +1,166 @@ |
||||
package com.cweb.controller; |
||||
|
||||
import com.cweb.config.SysConfig; |
||||
import com.hfkj.common.obs.HuaWeiYunObs; |
||||
import com.hfkj.common.utils.DateUtil; |
||||
import com.hfkj.common.utils.ResponseMsgUtil; |
||||
import com.hfkj.config.CommonSysConst; |
||||
import com.hfkj.model.ResponseData; |
||||
import com.hfkj.service.FileUploadService; |
||||
import com.obs.services.model.PutObjectResult; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import net.coobird.thumbnailator.Thumbnails; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.web.bind.annotation.*; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
import org.springframework.web.multipart.MultipartHttpServletRequest; |
||||
import org.springframework.web.multipart.commons.CommonsMultipartResolver; |
||||
|
||||
import javax.annotation.Resource; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.InputStream; |
||||
import java.util.ArrayList; |
||||
import java.util.Date; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
|
||||
@RestController |
||||
@RequestMapping(value="/fileUpload") |
||||
@Api(value="文件上传") |
||||
public class FileUploadController { |
||||
|
||||
private static Logger log = LoggerFactory.getLogger(FileUploadController.class); |
||||
|
||||
@Resource |
||||
private SysConfig sysConfig; |
||||
|
||||
@Resource |
||||
private FileUploadService fileUploadService; |
||||
|
||||
@RequestMapping(value="/uploadfile",method = RequestMethod.POST) |
||||
@ResponseBody |
||||
@ApiOperation(value = "文件上传") |
||||
public ResponseData uploadFile(@RequestParam(value = "files" , required = false) MultipartFile files, |
||||
HttpServletRequest request, |
||||
HttpServletResponse response) throws Exception { |
||||
try { |
||||
response.setHeader("Access-Control-Allow-Origin", "*"); |
||||
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( |
||||
request.getSession().getServletContext()); |
||||
// 判断 request 是否有文件上传,即多部分请求
|
||||
List<String> fileNames = new ArrayList<String>(); |
||||
if (multipartResolver.isMultipart(request)) { |
||||
// 转换成多部分request
|
||||
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; |
||||
Iterator<String> iterator = multiRequest.getFileNames(); |
||||
|
||||
while (iterator.hasNext()) { |
||||
MultipartFile file = multiRequest.getFile(iterator.next()); |
||||
if (file != null) { |
||||
FileOutputStream out = null; |
||||
try { |
||||
String fileType = file.getOriginalFilename() |
||||
.substring(file.getOriginalFilename().lastIndexOf(".") + 1); |
||||
String fileName = System.currentTimeMillis() + "." + fileType; |
||||
String childPath = DateUtil.date2String(new Date(), "yyyyMM"); |
||||
String destDirName = sysConfig.getFileUrl() + File.separator + childPath; |
||||
File dir = new File(destDirName); |
||||
if (!dir.exists()) { |
||||
dir.mkdirs(); |
||||
} |
||||
out = new FileOutputStream(destDirName + File.separator + fileName); |
||||
out.write(file.getBytes()); |
||||
out.flush(); |
||||
fileNames.add(childPath + "/" + fileName); |
||||
|
||||
PutObjectResult putObjectResult = HuaWeiYunObs.putObject(CommonSysConst.getSysConfig().getObsBucketName(), |
||||
childPath + "/" + fileName, new File(destDirName + "/" + fileName)); |
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
} finally { |
||||
if (out != null) { |
||||
out.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return ResponseMsgUtil.success(fileNames); |
||||
|
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
return ResponseMsgUtil.exception(e); |
||||
} |
||||
|
||||
} |
||||
|
||||
@RequestMapping(value = "/fileUpload", method = RequestMethod.POST) |
||||
@ApiOperation(value = "上传文件(超过500KB压缩)") |
||||
@ResponseBody |
||||
public ResponseData fileUpload(@RequestParam(value = "files" , required = false) MultipartFile files, |
||||
HttpServletRequest request, |
||||
HttpServletResponse response |
||||
) { |
||||
try { |
||||
response.setHeader("Access-Control-Allow-Origin", "*"); |
||||
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( |
||||
request.getSession().getServletContext()); |
||||
// 判断 request 是否有文件上传,即多部分请求
|
||||
List<String> fileNames = new ArrayList<String>(); |
||||
if (multipartResolver.isMultipart(request)) { |
||||
// 转换成多部分request
|
||||
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; |
||||
Iterator<String> iterator = multiRequest.getFileNames(); |
||||
|
||||
while (iterator.hasNext()) { |
||||
MultipartFile file = multiRequest.getFile(iterator.next()); |
||||
if (file != null) { |
||||
FileOutputStream out = null; |
||||
try { |
||||
String fileType = file.getOriginalFilename() |
||||
.substring(file.getOriginalFilename().lastIndexOf(".") + 1); |
||||
String fileName = System.currentTimeMillis() + "." + fileType; |
||||
String childPath = DateUtil.date2String(new Date(), "yyyyMM"); |
||||
String destDirName = sysConfig.getFileUrl() + File.separator + childPath; |
||||
File dir = new File(destDirName); |
||||
if (!dir.exists()) { |
||||
dir.mkdirs(); |
||||
} |
||||
out = new FileOutputStream(destDirName + File.separator + fileName); |
||||
out.write(file.getBytes()); |
||||
out.flush(); |
||||
fileNames.add(childPath + "/" + fileName); |
||||
// 图片压缩
|
||||
InputStream fis = new FileInputStream(destDirName + File.separator + fileName); |
||||
if (fis.available() > 500000) { |
||||
Thumbnails.of(new FileInputStream(destDirName + File.separator + fileName)).scale(0.5).toFile(new File(destDirName + File.separator + fileName)); |
||||
} |
||||
PutObjectResult putObjectResult = HuaWeiYunObs.putObject(CommonSysConst.getSysConfig().getObsBucketName(), |
||||
childPath + "/" + fileName, new File(destDirName + "/" + fileName)); |
||||
|
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
} finally { |
||||
if (out != null) { |
||||
out.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return ResponseMsgUtil.success(fileNames); |
||||
|
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
return ResponseMsgUtil.exception(e); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -1,2 +1,2 @@ |
||||
fileUrl=/home/project/hsg/filesystem |
||||
cmsPath=/home/project/hsg/filesystem/cmsPath |
||||
fileUrl=/home/project/phg/filesystem |
||||
cmsPath=/home/project/phg/filesystem/cmsPath |
||||
|
@ -0,0 +1,189 @@ |
||||
package com.hfkj.common.utils; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.security.MessageDigest; |
||||
import java.util.Map; |
||||
import java.util.TreeMap; |
||||
|
||||
public class PetroEncryptUtil { |
||||
|
||||
|
||||
/** |
||||
* 生成签名 |
||||
* |
||||
* @param signMaps |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
public static String generateSign(Map<String, Object> signMaps) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
TreeMap<String, Object> sortedMap = new TreeMap<>(signMaps); |
||||
// 字典序
|
||||
for (Map.Entry<String, Object> entry : sortedMap.entrySet()) { |
||||
String key = entry.getKey(); |
||||
String value = (String) entry.getValue(); |
||||
|
||||
// 为空不参与签名、参数名区分大小写
|
||||
if (!"sign".equals(key)) { |
||||
sb.append(key).append("=").append(value).append("&"); |
||||
} |
||||
|
||||
} |
||||
sb = new StringBuilder(sb.substring(0, sb.length() - 1)); |
||||
// MD5加密
|
||||
return md532(sb.toString()); |
||||
} |
||||
|
||||
/*** |
||||
* MD5加码 生成32位md5码 |
||||
*/ |
||||
public static String md532(String inStr) { |
||||
MessageDigest md5; |
||||
try { |
||||
md5 = MessageDigest.getInstance("MD5"); |
||||
|
||||
} catch (Exception e) { |
||||
System.out.println(e); |
||||
e.printStackTrace(); |
||||
return ""; |
||||
} |
||||
char[] charArray = inStr.toCharArray(); |
||||
byte[] byteArray = new byte[charArray.length]; |
||||
|
||||
for (int i = 0; i < charArray.length; i++) |
||||
byteArray[i] = (byte) charArray[i]; |
||||
byte[] md5Bytes = md5.digest(byteArray); |
||||
StringBuilder hexValue = new StringBuilder(); |
||||
for (byte md5Byte : md5Bytes) { |
||||
int val = ((int) md5Byte) & 0xff; |
||||
if (val < 16) |
||||
hexValue.append("0"); |
||||
hexValue.append(Integer.toHexString(val)); |
||||
} |
||||
return hexValue.toString(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 加密解密算法 |
||||
* |
||||
* @param inStr 加密字符串 |
||||
* @param secretKey 秘钥 |
||||
* 算法: |
||||
* 1:加密字符串和秘钥转换成字符数组; |
||||
* 2:秘钥去重复 |
||||
* 3:循环一(秘钥字符串数组){ 循环二(加密字符串数组){ |
||||
* 秘钥字符的ASC码 与 加密字符的ASC码 进行二进制异或运算 |
||||
* } |
||||
* } |
||||
* 4:把字符串转为16进制 |
||||
*/ |
||||
private static String convert(String inStr, String secretKey) { |
||||
char[] a = inStr.toCharArray(); |
||||
char[] s = rmRepeated(secretKey).toCharArray(); |
||||
for (int i = 0; i < s.length; i++) { |
||||
for (int j = 0; j < a.length; j++) { |
||||
a[j] = (char) (a[j] ^ s[i]); |
||||
} |
||||
} |
||||
return new String(a); |
||||
} |
||||
|
||||
/** |
||||
* 清除字符串中重复字母算法 |
||||
* |
||||
* @param s |
||||
* @return |
||||
*/ |
||||
private static String rmRepeated(String s) { |
||||
int len = s.length(); |
||||
int k = 0; |
||||
int count = 0; |
||||
String str = ""; |
||||
char[] c = new char[len]; |
||||
for (int i = 0; i < len; i++) { |
||||
c[i] = s.charAt(i); |
||||
} |
||||
for (int i = 0; i < len; i++) { |
||||
k = i + 1; |
||||
while (k < len - count) { |
||||
if (c[i] == c[k]) { |
||||
for (int j = k; j < len - 1; j++) { |
||||
c[j] = c[j + 1];// 出现重复字母,从k位置开始将数组往前挪位
|
||||
} |
||||
count++;// 重复字母出现的次数
|
||||
k--; |
||||
} |
||||
k++; |
||||
} |
||||
} |
||||
for (int i = 0; i < len - count; i++) { |
||||
str += String.valueOf(c[i]); |
||||
} |
||||
return str; |
||||
} |
||||
|
||||
/* |
||||
* 将字符串编码成16进制数字,适用于所有字符(包括中文) |
||||
*/ |
||||
private static String hexString = "0123456789ABCDEF"; |
||||
|
||||
public static String encode(String str) { |
||||
// 根据默认编码获取字节数组
|
||||
String r; |
||||
byte[] bytes = str.getBytes(StandardCharsets.UTF_8); |
||||
StringBuilder sb = new StringBuilder(bytes.length * 2); |
||||
// 将字节数组中每个字节拆解成2位16进制整数
|
||||
for (byte aByte : bytes) { |
||||
sb.append(hexString.charAt((aByte & 0xf0) >> 4)); |
||||
sb.append(hexString.charAt((aByte & 0x0f))); |
||||
} |
||||
r = sb.toString(); |
||||
return r; |
||||
} |
||||
|
||||
/* |
||||
* 将16进制数字解码成字符串,适用于所有字符(包括中文) |
||||
*/ |
||||
public static String decode(String bytes) { |
||||
String r = ""; |
||||
try { |
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(bytes.length() / 2); |
||||
// 将每2位16进制整数组装成一个字节
|
||||
for (int i = 0; i < bytes.length(); i += 2) { |
||||
byteArrayOutputStream.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1)))); |
||||
} |
||||
r = byteArrayOutputStream.toString("UTF-8"); |
||||
} catch (UnsupportedEncodingException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return r; |
||||
} |
||||
|
||||
/** |
||||
* 加密 |
||||
* |
||||
* @param inStr 原字符串 |
||||
* @param secretKey 秘钥 |
||||
* @return |
||||
*/ |
||||
public static String encrypt(String inStr, String secretKey) { |
||||
String hexStr = convert(inStr, secretKey); |
||||
return encode(hexStr); |
||||
} |
||||
|
||||
/** |
||||
* 解密 |
||||
* |
||||
* @param inStr 原字符串 |
||||
* @param secretKey 秘钥 |
||||
* @return |
||||
*/ |
||||
public static String decrypt(String inStr, String secretKey) { |
||||
String hexStr = decode(inStr); |
||||
return convert(hexStr, secretKey); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,380 @@ |
||||
package com.hfkj.service.coupon.channel; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.hfkj.common.utils.HttpsUtils; |
||||
import com.hfkj.common.utils.PetroEncryptUtil; |
||||
import com.hfkj.config.CommonSysConst; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.util.Date; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* @serviceName .java |
||||
* @author Sum1Dream |
||||
* @version 1.0.0 |
||||
* @Description // 四川中石油
|
||||
* @createTime 18:33 2023/11/13 |
||||
**/ |
||||
public class PetroConfig { |
||||
|
||||
private static String reqUrl; |
||||
private static String petroAppKey; |
||||
private static String petroAppid; |
||||
private static String petroAesKey; |
||||
|
||||
private static final String version = "1.0"; |
||||
|
||||
private final static String charset = "UTF-8"; |
||||
|
||||
private static Logger log = LoggerFactory.getLogger(PetroConfig.class); |
||||
|
||||
|
||||
public static void init(Integer type) { |
||||
if (type == 1) { |
||||
reqUrl = CommonSysConst.getSysConfig().getScPetroUrl(); |
||||
petroAppKey = CommonSysConst.getSysConfig().getScPetroAppKey(); |
||||
petroAppid = CommonSysConst.getSysConfig().getScPetroAppid(); |
||||
petroAesKey = CommonSysConst.getSysConfig().getScPetroAesKey(); |
||||
} else { |
||||
reqUrl = CommonSysConst.getSysConfig().getGzPetroUrl(); |
||||
petroAppKey = CommonSysConst.getSysConfig().getGzPetroAppKey(); |
||||
petroAppid = CommonSysConst.getSysConfig().getGzPetroAppid(); |
||||
petroAesKey = CommonSysConst.getSysConfig().getGzPetroAesKey(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name synCouponRule |
||||
* @Description // 获取券列表
|
||||
* @Date 11:17 2023/11/17 |
||||
|
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public static JSONObject synCouponRule() { |
||||
log.info("========================请求任务Start========================="); |
||||
Map<String, Object> req = new HashMap<>(); |
||||
req.put("appId", petroAppid); |
||||
req.put("appKey", petroAppKey); |
||||
req.put("jsonData" , ""); |
||||
req.put("timestamp", System.currentTimeMillis() + ""); |
||||
req.put("nonce" , generateRandomString(16)); |
||||
|
||||
//生成签名
|
||||
String sign = PetroEncryptUtil.generateSign(req); |
||||
|
||||
Map<String , Object> postData = new HashMap<>(); |
||||
postData.put("sign" , sign); |
||||
postData.put("timestamp" , req.get("timestamp")); |
||||
postData.put("jsonData" , ""); |
||||
postData.put("nonce" , req.get("nonce")); |
||||
postData.put("appId", petroAppid); |
||||
//签名放到参数中
|
||||
|
||||
log.info("获取券列表-请求参数: " + JSON.toJSONString(req)); |
||||
JSONObject object = HttpsUtils.doPost(reqUrl + "/outapi/getCouTypesYt", postData); |
||||
log.info("购买加油券充值订单-回调参数: " + JSON.toJSONString(object)); |
||||
log.info("========================请求任务End========================="); |
||||
// 请求接口
|
||||
return object; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name getCoupon |
||||
* @Description // 获取券code
|
||||
* @Date 11:19 2023/11/17 |
||||
* @Param code |
||||
* @Param phone |
||||
* @Param orderNo |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public static JSONObject getCoupon(String code , String phone) { |
||||
log.info("========================请求任务Start========================="); |
||||
Map<String, Object> req = new HashMap<>(); |
||||
req.put("appId", petroAppid); |
||||
req.put("appKey", petroAppKey); |
||||
req.put("timestamp", System.currentTimeMillis()+ ""); |
||||
req.put("nonce" , generateRandomString(16)); |
||||
|
||||
// 业务数据
|
||||
JSONObject jsonData = new JSONObject(); |
||||
jsonData.put("alias" , code); |
||||
jsonData.put("businessId" , phone); |
||||
|
||||
//业务内容加密
|
||||
String bizContent = JSONObject.toJSONString(jsonData); |
||||
bizContent = encrypt(bizContent); |
||||
|
||||
//加密的内容放到参数中
|
||||
req.put("jsonData", bizContent); |
||||
//生成签名
|
||||
String sign = PetroEncryptUtil.generateSign(req); |
||||
|
||||
|
||||
Map<String , Object> postData = new HashMap<>(); |
||||
postData.put("sign" , sign); |
||||
postData.put("timestamp" , req.get("timestamp")); |
||||
postData.put("jsonData" , bizContent); |
||||
postData.put("nonce" , req.get("nonce")); |
||||
postData.put("appId", petroAppid); |
||||
log.info("获取电子券-请求参数: " + JSON.toJSONString(req)); |
||||
JSONObject object = HttpsUtils.doPost(reqUrl + "/outapi/getCouponYt", postData); |
||||
log.info("获取电子券-回调参数: " + JSON.toJSONString(object)); |
||||
log.info("========================请求任务End========================="); |
||||
// 请求接口
|
||||
return object; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name couponDetail |
||||
* @Description // 查询电子券状态
|
||||
* @Date 11:20 2023/11/17 |
||||
* @Param ticketNum |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public static JSONObject couponDetail(String ticketNum , String phone) throws Exception{ |
||||
log.info("========================请求任务Start========================="); |
||||
Map<String, Object> req = new HashMap<>(); |
||||
req.put("appId", petroAppid); |
||||
req.put("appKey", petroAppKey); |
||||
req.put("timestamp", System.currentTimeMillis() + ""); |
||||
req.put("nonce" , generateRandomString(16)); |
||||
|
||||
// 业务数据
|
||||
JSONObject jsonData = new JSONObject(); |
||||
jsonData.put("voucher" , ticketNum); |
||||
jsonData.put("businessId" , phone); |
||||
|
||||
|
||||
//业务内容加密
|
||||
String bizContent = JSONObject.toJSONString(jsonData); |
||||
bizContent = encrypt(bizContent); |
||||
|
||||
//加密的内容放到参数中
|
||||
req.put("jsonData", bizContent); |
||||
//生成签名
|
||||
String sign = PetroEncryptUtil.generateSign(req); |
||||
//签名放到参数中
|
||||
req.put("sign", sign); |
||||
Map<String , Object> postData = new HashMap<>(); |
||||
postData.put("sign" , sign); |
||||
postData.put("timestamp" , req.get("timestamp")); |
||||
postData.put("jsonData" , bizContent); |
||||
postData.put("nonce" , req.get("nonce")); |
||||
postData.put("appId", petroAppid); |
||||
log.info("查询电子券状态-请求参数: " + JSON.toJSONString(req)); |
||||
// 请求接口
|
||||
JSONObject object = HttpsUtils.doPost(reqUrl + "/outapi/getStateYt", postData); |
||||
|
||||
log.info("查询电子券状态-回调参数: " + JSON.toJSONString(object)); |
||||
return object; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name unusedCoupons |
||||
* @Description // 获取核销码
|
||||
* @Date 14:32 2024/1/31 |
||||
* @Param ticketNum |
||||
* @Param phone |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject getCheckCode(String ticketNum , String phone) throws Exception{ |
||||
log.info("========================请求任务Start========================="); |
||||
Map<String, Object> req = new HashMap<>(); |
||||
req.put("appId", petroAppid); |
||||
req.put("appKey", petroAppKey); |
||||
req.put("timestamp", System.currentTimeMillis() + ""); |
||||
req.put("nonce" , generateRandomString(16)); |
||||
|
||||
// 业务数据
|
||||
JSONObject jsonData = new JSONObject(); |
||||
jsonData.put("voucher" , ticketNum); |
||||
jsonData.put("businessId" , phone); |
||||
|
||||
|
||||
//业务内容加密
|
||||
String bizContent = JSONObject.toJSONString(jsonData); |
||||
bizContent = encrypt(bizContent); |
||||
|
||||
//加密的内容放到参数中
|
||||
req.put("jsonData", bizContent); |
||||
//生成签名
|
||||
String sign = PetroEncryptUtil.generateSign(req); |
||||
//签名放到参数中
|
||||
req.put("sign", sign); |
||||
Map<String , Object> postData = new HashMap<>(); |
||||
postData.put("sign" , sign); |
||||
postData.put("timestamp" , req.get("timestamp")); |
||||
postData.put("jsonData" , bizContent); |
||||
postData.put("nonce" , req.get("nonce")); |
||||
postData.put("appId", petroAppid); |
||||
log.info("查询电子券状态-请求参数: " + JSON.toJSONString(req)); |
||||
// 请求接口
|
||||
JSONObject object = HttpsUtils.doPost(reqUrl + "/outapi/getCheckCode", postData); |
||||
|
||||
log.info("查询电子券状态-回调参数: " + JSON.toJSONString(object)); |
||||
return object; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name cancelCouponsYt |
||||
* @Description // 注销电子券
|
||||
* @Date 15:19 2024/1/31 |
||||
* @Param ticketNum |
||||
* @Param phone |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject cancelCouponsYt(String ticketNum , String phone) throws Exception{ |
||||
log.info("========================请求任务Start========================="); |
||||
Map<String, Object> req = new HashMap<>(); |
||||
req.put("appId", petroAppid); |
||||
req.put("appKey", petroAppKey); |
||||
req.put("timestamp", System.currentTimeMillis() + ""); |
||||
req.put("nonce" , generateRandomString(16)); |
||||
|
||||
String [] vouchers = {ticketNum}; |
||||
|
||||
// 业务数据
|
||||
JSONObject jsonData = new JSONObject(); |
||||
jsonData.put("vouchers" , vouchers); |
||||
jsonData.put("businessId" , phone); |
||||
|
||||
//业务内容加密
|
||||
String bizContent = JSONObject.toJSONString(jsonData); |
||||
bizContent = encrypt(bizContent); |
||||
|
||||
//加密的内容放到参数中
|
||||
req.put("jsonData", bizContent); |
||||
//生成签名
|
||||
String sign = PetroEncryptUtil.generateSign(req); |
||||
//签名放到参数中
|
||||
req.put("sign", sign); |
||||
Map<String , Object> postData = new HashMap<>(); |
||||
postData.put("sign" , sign); |
||||
postData.put("timestamp" , req.get("timestamp")); |
||||
postData.put("jsonData" , bizContent); |
||||
postData.put("nonce" , req.get("nonce")); |
||||
postData.put("appId", petroAppid); |
||||
log.info("查询电子券状态-请求参数: " + JSON.toJSONString(req)); |
||||
// 请求接口
|
||||
JSONObject object = HttpsUtils.doPost(reqUrl + "/outapi/cancelCouponsYt", postData); |
||||
|
||||
log.info("查询电子券状态-回调参数: " + JSON.toJSONString(object)); |
||||
return object; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name memberCards |
||||
* @Description // ETC卡券下发接口
|
||||
* @Date 14:17 2024/2/28 |
||||
* @Param object |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject etcOrder(Map<String , Object> object) { |
||||
log.info("========================请求任务Start========================="); |
||||
log.info("卡券下发接口-请求参数: " + JSON.toJSONString(object)); |
||||
// 请求接口
|
||||
JSONObject jsonObject = HttpsUtils.doPost(CommonSysConst.getSysConfig().getEtcPostUrl() + "channel/order" , object); |
||||
log.info("卡券下发接口-回调参数: " + JSON.toJSONString(jsonObject)); |
||||
return jsonObject; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name etcCardStatus |
||||
* @Description // etc卡券状态查询接口
|
||||
* @Date 14:22 2024/2/28 |
||||
* @Param object |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject etcCardStatus(Map<String , Object> object) { |
||||
log.info("========================请求任务Start========================="); |
||||
log.info("卡券状态查询接口-请求参数: " + JSON.toJSONString(object)); |
||||
// 请求接口
|
||||
JSONObject jsonObject = HttpsUtils.doPost(CommonSysConst.getSysConfig().getEtcPostUrl() + "/channel/cardStatus" , object); |
||||
log.info("卡券状态查询接口-回调参数: " + JSON.toJSONString(jsonObject)); |
||||
return jsonObject; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name etcDestroy |
||||
* @Description // 卡券退款接口
|
||||
* @Date 14:23 2024/2/28 |
||||
* @Param object |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject etcDestroy(Map<String , Object> object) { |
||||
log.info("========================请求任务Start========================="); |
||||
log.info(" 卡券退款接口-请求参数: " + JSON.toJSONString(object)); |
||||
// 请求接口
|
||||
JSONObject jsonObject = HttpsUtils.doPost(CommonSysConst.getSysConfig().getEtcPostUrl() + "/channel/order/destroy" , object); |
||||
log.info(" 卡券退款接口-回调参数: " + JSON.toJSONString(jsonObject)); |
||||
return jsonObject; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name etcQueryStock |
||||
* @Description // 查询卡券库存接口
|
||||
* @Date 14:23 2024/2/28 |
||||
* @Param object |
||||
* @return com.alibaba.fastjson.JSONObject |
||||
*/ |
||||
public JSONObject etcQueryStock(Map<String , Object> object) { |
||||
log.info("========================请求任务Start========================="); |
||||
log.info(" 查询卡券库存接口-请求参数: " + JSON.toJSONString(object)); |
||||
// 请求接口
|
||||
JSONObject jsonObject = HttpsUtils.doPost(CommonSysConst.getSysConfig().getEtcPostUrl() + "/channel/queryStock" , object); |
||||
log.info(" 查询卡券库存接口-回调参数: " + JSON.toJSONString(jsonObject)); |
||||
return jsonObject; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name generateRandomString |
||||
* @Description // 生成16位随机字符串
|
||||
* @Date 16:24 2024/1/15 |
||||
* @Param length 长度 |
||||
* @return java.lang.String |
||||
*/ |
||||
private static String generateRandomString(Integer length) { |
||||
UUID uuid = UUID.randomUUID(); |
||||
return uuid.toString().replaceAll("-", "").substring(0, length); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @param content AES加密前的明文 |
||||
* @return AES加密后的内容 |
||||
*/ |
||||
public static String encrypt(final String content) { |
||||
return PetroEncryptUtil.encrypt(content , petroAesKey); |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name decrypt |
||||
* @Description // 解密
|
||||
* @Date 16:19 2023/11/15 |
||||
* @Param content |
||||
* @Param key |
||||
* @return java.lang.String |
||||
*/ |
||||
public static String decrypt(final String content) { |
||||
return PetroEncryptUtil.decrypt(content , petroAesKey); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.hfkj.service.user; |
||||
|
||||
import com.hfkj.entity.BsUserIntegralRecord; |
||||
|
||||
/** |
||||
* @className: BsUserIntegralRecordService |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
public interface BsUserIntegralRecordService { |
||||
|
||||
/** |
||||
* 编辑数据 |
||||
* @param record |
||||
*/ |
||||
void create(BsUserIntegralRecord record); |
||||
} |
@ -0,0 +1,40 @@ |
||||
package com.hfkj.service.user; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 用户积分业务 |
||||
* @className: UserIntegral |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
public interface UserIntegralService { |
||||
|
||||
/** |
||||
* 获取积分数量 |
||||
* @param userId |
||||
* @return |
||||
*/ |
||||
Long getIntegral(Long userId); |
||||
|
||||
/** |
||||
* 进账 |
||||
* @param userId 用户id |
||||
* @param integralNum |
||||
* @param opUser |
||||
* @param source |
||||
* @return |
||||
*/ |
||||
void entry(Long userId, Long integralNum, Map<String,Object> opUser, Map<String,Object> source); |
||||
|
||||
/** |
||||
* 消费 |
||||
* @param userId 用户id |
||||
* @param integralNum |
||||
* @param opUser |
||||
* @param source |
||||
* @return |
||||
*/ |
||||
void consume(Long userId, Long integralNum,Map<String,Object> opUser, Map<String,Object> source); |
||||
|
||||
} |
@ -0,0 +1,26 @@ |
||||
package com.hfkj.service.user.impl; |
||||
|
||||
import com.hfkj.dao.BsUserIntegralRecordMapper; |
||||
import com.hfkj.entity.BsUserIntegralRecord; |
||||
import com.hfkj.service.user.BsUserIntegralRecordService; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* @className: BsUserIntegralRecordServiceImpl |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
@Service("userIntegralRecordService") |
||||
public class BsUserIntegralRecordServiceImpl implements BsUserIntegralRecordService { |
||||
@Resource |
||||
private BsUserIntegralRecordMapper userIntegralRecordMapper; |
||||
@Override |
||||
public void create(BsUserIntegralRecord record) { |
||||
record.setStatus(1); |
||||
record.setCreateTime(new Date()); |
||||
userIntegralRecordMapper.insert(record); |
||||
} |
||||
} |
@ -0,0 +1,157 @@ |
||||
package com.hfkj.service.user.impl; |
||||
|
||||
import com.hfkj.common.exception.ErrorCode; |
||||
import com.hfkj.common.exception.ErrorHelp; |
||||
import com.hfkj.common.exception.SysCode; |
||||
import com.hfkj.entity.BsUser; |
||||
import com.hfkj.entity.BsUserIntegralRecord; |
||||
import com.hfkj.service.user.BsUserIntegralRecordService; |
||||
import com.hfkj.service.user.BsUserService; |
||||
import com.hfkj.service.user.UserIntegralService; |
||||
import com.hfkj.sysenum.UserIntegralRecordStatusEnum; |
||||
import org.apache.commons.collections4.MapUtils; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Propagation; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.math.BigDecimal; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @className: UserIntegralServiceImpl |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
@Service("userIntegralService") |
||||
public class UserIntegralServiceImpl implements UserIntegralService { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
@Resource |
||||
private BsUserService userService; |
||||
@Resource |
||||
private BsUserIntegralRecordService userIntegralRecordService; |
||||
@Override |
||||
public Long getIntegral(Long userId) { |
||||
BsUser user = userService.getUser(userId); |
||||
if (user != null) { |
||||
return user.getIntegral(); |
||||
} |
||||
return 0L; |
||||
} |
||||
|
||||
@Override |
||||
@Transactional(propagation = Propagation.REQUIRED) |
||||
public void entry(Long userId, Long integralNum, Map<String,Object> opUser, Map<String,Object> source) { |
||||
String key = "USER_INTEGRAL_" + userId; |
||||
// 获取锁
|
||||
Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, integralNum); |
||||
if (Boolean.FALSE.equals(lock)) { |
||||
try { |
||||
Thread.sleep(100); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
entry(userId,integralNum, opUser, source); |
||||
} |
||||
|
||||
try { |
||||
// 获取锁成功
|
||||
// 查询用户
|
||||
BsUser user = userService.getUser(userId); |
||||
if (user == null) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的账户"); |
||||
} |
||||
// 变更前积分数
|
||||
Long beforeAmount = user.getIntegral(); |
||||
|
||||
// 计算金额
|
||||
user.setIntegral(user.getIntegral() + integralNum); |
||||
userService.editData(user); |
||||
|
||||
// 变更后积分数
|
||||
Long afterAmount = user.getIntegral(); |
||||
|
||||
BsUserIntegralRecord record = new BsUserIntegralRecord(); |
||||
record.setUserId(userId); |
||||
record.setType(UserIntegralRecordStatusEnum.type1.getCode()); |
||||
record.setTransactionAmount(integralNum); |
||||
record.setBeforeAmount(beforeAmount); |
||||
record.setAfterAmount(afterAmount); |
||||
record.setSourceType(MapUtils.getInteger(source, "sourceType")); |
||||
record.setSourceId(MapUtils.getLong(source, "sourceId")); |
||||
record.setSourceOrderNo(MapUtils.getString(source, "sourceOrderNo")); |
||||
record.setSourceContent(MapUtils.getString(source, "sourceContent")); |
||||
record.setOpUserType(MapUtils.getInteger(source, "opUserType")); |
||||
record.setOpUserId(MapUtils.getLong(source, "opUserId")); |
||||
record.setOpUserName(MapUtils.getString(source, "opUserName")); |
||||
record.setOpUserPhone(MapUtils.getString(source, "opUserPhone")); |
||||
userIntegralRecordService.create(record); |
||||
|
||||
} catch (Exception e) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "积分交易异常"); |
||||
} finally { |
||||
redisTemplate.delete(key); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void consume(Long userId, Long integralNum, Map<String,Object> opUser, Map<String,Object> source) { |
||||
String key = "USER_INTEGRAL_" + userId; |
||||
// 获取锁
|
||||
Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, integralNum); |
||||
if (Boolean.FALSE.equals(lock)) { |
||||
try { |
||||
Thread.sleep(100); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
entry(userId,integralNum, opUser, source); |
||||
} |
||||
|
||||
try { |
||||
// 获取锁成功
|
||||
// 查询用户
|
||||
BsUser user = userService.getUser(userId); |
||||
if (user == null) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的账户"); |
||||
} |
||||
if (user.getIntegral() > integralNum) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "积分数量不足"); |
||||
} |
||||
// 变更前积分数
|
||||
Long beforeAmount = user.getIntegral(); |
||||
|
||||
// 计算金额
|
||||
user.setIntegral(user.getIntegral() - integralNum); |
||||
userService.editData(user); |
||||
|
||||
// 变更后积分数
|
||||
Long afterAmount = user.getIntegral(); |
||||
|
||||
BsUserIntegralRecord record = new BsUserIntegralRecord(); |
||||
record.setUserId(userId); |
||||
record.setType(UserIntegralRecordStatusEnum.type2.getCode()); |
||||
record.setTransactionAmount(integralNum); |
||||
record.setBeforeAmount(beforeAmount); |
||||
record.setAfterAmount(afterAmount); |
||||
record.setSourceType(MapUtils.getInteger(source, "sourceType")); |
||||
record.setSourceId(MapUtils.getLong(source, "sourceId")); |
||||
record.setSourceOrderNo(MapUtils.getString(source, "sourceOrderNo")); |
||||
record.setSourceContent(MapUtils.getString(source, "sourceContent")); |
||||
record.setOpUserType(MapUtils.getInteger(source, "opUserType")); |
||||
record.setOpUserId(MapUtils.getLong(source, "opUserId")); |
||||
record.setOpUserName(MapUtils.getString(source, "opUserName")); |
||||
record.setOpUserPhone(MapUtils.getString(source, "opUserPhone")); |
||||
userIntegralRecordService.create(record); |
||||
|
||||
} catch (Exception e) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "积分交易异常"); |
||||
} finally { |
||||
redisTemplate.delete(key); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,37 @@ |
||||
package com.hfkj.sysenum; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
/** |
||||
* @className: UserIntegralRecordOpUserTypeEnum |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
@Getter |
||||
public enum UserIntegralRecordOpUserTypeEnum { |
||||
|
||||
/** |
||||
* 系统 |
||||
*/ |
||||
type1(1, "系统"), |
||||
|
||||
/** |
||||
* 支出 |
||||
*/ |
||||
type2(2, "管理员"), |
||||
/** |
||||
* 用户 |
||||
*/ |
||||
type3(3, "用户"), |
||||
; |
||||
|
||||
private int code; |
||||
|
||||
private String name; |
||||
|
||||
|
||||
UserIntegralRecordOpUserTypeEnum(int code, String name) { |
||||
this.code = code; |
||||
this.name = name; |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package com.hfkj.sysenum; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
/** |
||||
* @className: UserIntegralRecordSourceTypeEnum |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
@Getter |
||||
public enum UserIntegralRecordSourceTypeEnum { |
||||
|
||||
/** |
||||
* 交易订单 |
||||
*/ |
||||
type1(1, "交易订单"), |
||||
; |
||||
|
||||
private int code; |
||||
|
||||
private String name; |
||||
|
||||
|
||||
UserIntegralRecordSourceTypeEnum(int code, String name) { |
||||
this.code = code; |
||||
this.name = name; |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
package com.hfkj.sysenum; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
/** |
||||
* @className: UserIntegralRecordStatusEnum |
||||
* @author: HuRui |
||||
* @date: 2024/5/20 |
||||
**/ |
||||
@Getter |
||||
public enum UserIntegralRecordStatusEnum { |
||||
|
||||
/** |
||||
* 收入 |
||||
*/ |
||||
type1(1, "收入"), |
||||
|
||||
/** |
||||
* 支出 |
||||
*/ |
||||
type2(2, "支出"), |
||||
; |
||||
|
||||
private int code; |
||||
|
||||
private String name; |
||||
|
||||
|
||||
UserIntegralRecordStatusEnum(int code, String name) { |
||||
this.code = code; |
||||
this.name = name; |
||||
} |
||||
} |
Loading…
Reference in new issue