添加请求校验
This commit is contained in:
parent
124c3acfaa
commit
761a2f08d4
@ -0,0 +1,133 @@
|
||||
package com.cpop.core.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cpop.core.base.entity.CpopSignBase;
|
||||
import okhttp3.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author DB
|
||||
* @version 1.0.0
|
||||
* @since 2024-02-28 14:50
|
||||
*/
|
||||
@Component
|
||||
public class CpopSignatureUtils {
|
||||
|
||||
@Autowired
|
||||
private RsaUtils rsaUtils;
|
||||
|
||||
private static final Map<String, String[]> APP_IDS = new HashMap<String, String[]>() {{
|
||||
//数币
|
||||
put("1688842965582499840", new String[]{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmsFHkB4iIdVSgaz8u8QG66wiZupgSbu2T/ml/kdPm2vemsKgvEqUqp1gR6ulfHcPF8otjVbjiE8q8oR70XfxFIREbomTUmpsOzurLFrAmVhyvu6/tY23/txjQoeeH/tlCy7Lq/TL1AqPKyBcGzsQ4yInpIgRWpXz7fmJCTRw07tyE+4lpXBqiaLdWrkkGG00LnHQAOfcUoXf0TdxFPSfRHiBikfbkmgeVoU66RGlUEXU2esTY2nYGvFn+FqWsNkGEnn2YxIqgbQQ1zNX33+FWBlba1WdQtc8mTJAleaPGXmFnQiEMb55b7xVPjyyCWt6aRwl97KQgtCmfsoPZUWwQQIDAQAB"});
|
||||
//系统
|
||||
put("100", new String[]{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDdtx3eLzoUbm0qr8xv4XXew0raUsv98eOmdxS4jDgFkajzK3H02fnWg99y2CRcZNnEFA6MlE/0RrAuWnuIehazQBR5dpnzoOht4WweRO0DEciRTdQ5Uf5T4YOlwmNKhE2S9jsmBP8X5Gi2r65G4miBG8r4AJJ9Pxtq8fjZUkCpKrk3y167mSunDUtZZOAimQ7W235Oh7fIqOSNQN+KxvhFSkiSqFIaXjDY50eONdSBaPYV1NsbW5A6VHrsvcG/2uzcEAfINFoRsmF9SxsckvnVsVfKgN+ONvnQdFmAJaiwtXJ9eJ4TfMt+HPTZk8pMfAUEj8vfz/98g39kKY42b2QIDAQAB"});
|
||||
}};
|
||||
|
||||
/**
|
||||
* 发送签名http请求
|
||||
* @author DB
|
||||
* @since 2024/2/28
|
||||
* @param url 路径
|
||||
* @param data 数据
|
||||
* @param appid appid
|
||||
* @return Response
|
||||
*/
|
||||
public JSONObject sendSignaturePost(String url, Object data, String appid) throws IOException, IllegalAccessException {
|
||||
OkHttpClient client = new OkHttpClient().newBuilder().build();
|
||||
MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8");
|
||||
RequestBody body = RequestBody.Companion.create(JSONObject.toJSONString(data), mediaType);
|
||||
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
|
||||
String signType = "RSA";
|
||||
CpopSignBase cpopSignBase = new CpopSignBase();
|
||||
cpopSignBase.setSignType(signType);
|
||||
cpopSignBase.setDateTime(now);
|
||||
cpopSignBase.setAppId(appid);
|
||||
cpopSignBase.setSignature(md5(data, appid));
|
||||
Request request = new Request
|
||||
.Builder()
|
||||
.url(url)
|
||||
.post(body)
|
||||
.addHeader("Content-Type", "application/json")
|
||||
.addHeader("appId", appid)
|
||||
.addHeader("signature", signature(cpopSignBase,APP_IDS.get(appid)[0]))
|
||||
.addHeader("dateTime", now)
|
||||
.addHeader("signType", signType)
|
||||
.build();
|
||||
Response response = null;
|
||||
try {
|
||||
response = client.newCall(request).execute();
|
||||
return JSONObject.parseObject(response.body().string());
|
||||
} finally {
|
||||
assert response != null;
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String md5(Object object, String appId) throws IllegalAccessException {
|
||||
//验签拼接字段
|
||||
List<String> signString = new ArrayList<String>();
|
||||
//获取父类(公共类必传属性)
|
||||
Field[] fatherFields = object.getClass().getSuperclass().getDeclaredFields();
|
||||
for (Field field : fatherFields) {
|
||||
field.setAccessible(true);
|
||||
signString.add(field.getName() + "=" + field.get(object));
|
||||
}
|
||||
//可能为空参
|
||||
Field[] fields = object.getClass().getDeclaredFields();
|
||||
if (fields.length > 0) {
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
if (null == field.get(object)) {
|
||||
signString.add(field.getName() + "=");
|
||||
} else {
|
||||
signString.add(field.getName() + "=" + field.get(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
//按照字母排序
|
||||
String sign = signString.stream().sorted().collect(Collectors.joining("&")) + appId;
|
||||
return DigestUtils.md5DigestAsHex(sign.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名
|
||||
*
|
||||
* @param data 数据
|
||||
* @return String
|
||||
* @author DB
|
||||
* @since 2024/2/28
|
||||
*/
|
||||
private String signature(CpopSignBase data, String publicKey) {
|
||||
return rsaUtils.encrypt(JSONObject.toJSONString(data), stringToPublicKey(publicKey));
|
||||
}
|
||||
|
||||
private PublicKey stringToPublicKey(String publicKey) {
|
||||
byte[] decode = Base64.getDecoder().decode(publicKey);
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
|
||||
//返回转换指定算法的KeyFactory对象
|
||||
KeyFactory keyFactory = null;
|
||||
try {
|
||||
keyFactory = KeyFactory.getInstance("RSA");
|
||||
//根据PKCS8编码密钥规范产生私钥对象
|
||||
return keyFactory.generatePublic(x509EncodedKeySpec);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,8 +169,7 @@ public class RsaUtils {
|
||||
* @param source 源数据
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public String encrypt(String source) {
|
||||
Key publicKey = getKeyFromFile(keyPairConfig.getPublicKeyFile());
|
||||
public String encrypt(String source, Key publicKey) {
|
||||
Base64.Encoder encoder = Base64.getEncoder();
|
||||
String encryptSource = null;
|
||||
try {
|
||||
@ -187,6 +186,15 @@ public class RsaUtils {
|
||||
return encryptSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
* @param source 源数据
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public String encrypt(String source) {
|
||||
return encrypt(source, getKeyFromFile(keyPairConfig.getPublicKeyFile()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
* @param source 密文
|
||||
|
||||
@ -64,7 +64,7 @@ public class EasyLearnUnionPayBo {
|
||||
/**
|
||||
* 订单类型
|
||||
*/
|
||||
@NotNull(message = "联合支付类型不能为空")
|
||||
@NotBlank(message = "联合支付类型不能为空")
|
||||
@ApiModelProperty(value = "联合支付类型(WX_PAY:微信支付;PREPAYMENT:预付;REPAYMENT:还款;MEMBER:会员)",required = true)
|
||||
private String easyLearnUnionPay;
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ public enum EasyLearnPayPayEnum {
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账比例
|
||||
* 订单类型
|
||||
*/
|
||||
private Integer orderType;
|
||||
|
||||
|
||||
@ -3,14 +3,22 @@ package com.cpop.oam.web;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.tencent.location.handler.TencentLocationHandler;
|
||||
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
|
||||
import com.cpop.core.annontation.StringArrayConvert;
|
||||
import com.cpop.core.utils.CpopSignatureUtils;
|
||||
import com.cpop.core.utils.RsaUtils;
|
||||
import com.cpop.core.utils.SpringUtils;
|
||||
import com.cpop.oam.business.bo.ApiTenantRequest;
|
||||
import com.cpop.pay.framewok.handler.ecpp.EcppHandler;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import okhttp3.Response;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -60,4 +68,18 @@ public class CpopApiTests {
|
||||
JSONObject geocoder = SpringUtils.getBean(TencentLocationHandler.class).geocoder("114.4246835", "23.12707132", "UGLBZ-LBF3I-ETCGO-UUH5X-QDV45-3LFKA");
|
||||
System.out.println(geocoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增租户
|
||||
* @author DB
|
||||
* @since 2024/2/28
|
||||
*/
|
||||
@Test
|
||||
public void insertTenant() throws IOException, IllegalAccessException {
|
||||
com.alibaba.fastjson2.JSONObject jsonObject = SpringUtils.getBean(CpopSignatureUtils.class).sendSignaturePost("http://localhost:9440/Jambox-System/api/tenant/insertTenant",
|
||||
new ApiTenantRequest().setName("测试租户").setIsSuper(false), "100");
|
||||
System.out.println(jsonObject);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
package com.cpop.oam.business.bo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author DB
|
||||
* @version 1.0.0
|
||||
* @since 2024-02-28 16:50
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ApiTenantRequest {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 租户名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 是否是超管
|
||||
*/
|
||||
private Boolean isSuper;
|
||||
|
||||
/**
|
||||
* 外部id
|
||||
*/
|
||||
private String outId;
|
||||
|
||||
/**
|
||||
* logo
|
||||
*/
|
||||
private String logo;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer orderNo;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 状态(0:停用;1:启用)
|
||||
*/
|
||||
private Boolean status;
|
||||
|
||||
/**
|
||||
* 到期日期
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private LocalDate maturityDate;
|
||||
|
||||
/**
|
||||
* 加密签名
|
||||
*/
|
||||
private String signature;
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
package com.cpop.oam.framework.tasks;
|
||||
|
||||
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.common.utils.bean.BeanUtils;
|
||||
import com.cpop.core.base.exception.ServiceException;
|
||||
import com.cpop.core.base.table.SysConfig;
|
||||
import com.cpop.core.service.CoreService;
|
||||
import com.cpop.core.service.RedisService;
|
||||
@ -14,7 +16,9 @@ import com.cpop.oam.business.entity.table.DataImportTableDef;
|
||||
import com.cpop.oam.business.mapper.ClueMapper;
|
||||
import com.cpop.oam.business.service.*;
|
||||
import com.cpop.oam.business.vo.SignGoalConfigInfoVo;
|
||||
import com.cpop.oam.business.vo.StaffInfoVo;
|
||||
import com.cpop.oam.framework.constant.OamConfigKey;
|
||||
import com.cpop.oam.framework.constant.WebHookKeyConstant;
|
||||
import com.cpop.oam.framework.enums.OamConfigEnum;
|
||||
import com.mybatisflex.core.row.Db;
|
||||
import com.mybatisflex.core.update.UpdateChain;
|
||||
@ -25,6 +29,7 @@ import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
@ -212,4 +217,46 @@ public class OamScheduledTasks {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务逾期提醒
|
||||
* @author DB
|
||||
* @since 2023/12/11
|
||||
*/
|
||||
@Scheduled(cron = "0 30 9 * * *")
|
||||
public void taskOverdueRemind() {
|
||||
log.info("==============开始检查即将逾期任务===========");
|
||||
TaskService taskService = SpringUtils.getBean(TaskService.class);
|
||||
//进行中的任务提醒任务负责人
|
||||
List<Task> dealTasks = taskService.queryChain().where(TASK.TASK_STATUS.eq(2)).and(TASK.TASK_TYPE.in(0, 1)).and(TASK.EXPECTED_COMPLETION_DATE.eq(LocalDate.now())).list();
|
||||
if (!dealTasks.isEmpty()) {
|
||||
dealTasks.forEach(item->{
|
||||
ArrayList<String> phoneList = new ArrayList<>();
|
||||
StaffInfoVo staffInfo = SpringUtils.getBean(StaffService.class).getStaffInfo(item.getResponsibleStaffId());
|
||||
phoneList.add(staffInfo.getPhoneNumber());
|
||||
try {
|
||||
SpringUtils.getBean(WebHookSendHandler.class).webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT, phoneList,
|
||||
"==========您有一个任务今天即将到期,请及时处理==========\n" + item.getTaskContent(),
|
||||
false);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("发送消息通知失败!");
|
||||
}
|
||||
});
|
||||
}
|
||||
List<Task> testTasks = taskService.queryChain().where(TASK.TASK_STATUS.eq(3)).and(TASK.TASK_TYPE.in(0, 1)).and(TASK.EXPECTED_COMPLETION_DATE.eq(LocalDate.now().minusDays(1))).list();
|
||||
if (!testTasks.isEmpty()) {
|
||||
String testStaffPhones = SpringUtils.getBean(RedisService.class).getCacheObject(OamConfigKey.OAM_CONFIG_KEY + OamConfigEnum.TEST_STAFF_PHONE.getKey());
|
||||
testTasks.forEach(item->{
|
||||
ArrayList<String> phoneList = new ArrayList<>();
|
||||
phoneList.add(testStaffPhones);
|
||||
try {
|
||||
SpringUtils.getBean(WebHookSendHandler.class).webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT, phoneList,
|
||||
"==========您有一个测试任务今天即将到期,请及时处理==========\n" + item.getTaskContent(),
|
||||
false);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("发送消息通知失败!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
package com.cpop.oam.framework.tasks;
|
||||
|
||||
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
|
||||
import com.cpop.core.base.exception.ServiceException;
|
||||
import com.cpop.core.utils.SpringUtils;
|
||||
import com.cpop.oam.business.entity.Task;
|
||||
import com.cpop.oam.business.entity.TaskWorkOrder;
|
||||
import com.cpop.oam.business.service.StaffService;
|
||||
import com.cpop.oam.business.service.TaskService;
|
||||
import com.cpop.oam.business.service.TaskWorkOrderService;
|
||||
import com.cpop.oam.business.vo.StaffInfoVo;
|
||||
import com.cpop.oam.framework.constant.WebHookKeyConstant;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cpop.oam.business.entity.table.TaskTableDef.TASK;
|
||||
|
||||
/**
|
||||
@ -32,6 +41,21 @@ public class WorkOrderPauseRecoverTask implements Job {
|
||||
Task task = taskService.getById(taskWorkOrder.getTaskId());
|
||||
if (task.getTaskStatus() == 5) {
|
||||
taskService.updateChain().set(TASK.TASK_STATUS, 2).where(TASK.ID.eq(taskWorkOrder.getTaskId())).update();
|
||||
// 发送消息通知
|
||||
List<String> phoneList = new ArrayList<String>();
|
||||
StaffInfoVo responsibleStaff = SpringUtils.getBean(StaffService.class).getStaffInfo(task.getResponsibleStaffId());
|
||||
StaffInfoVo recordStaff = SpringUtils.getBean(StaffService.class).getStaffInfo(task.getRecordStaffId());
|
||||
phoneList.add(responsibleStaff.getPhoneNumber());
|
||||
phoneList.add(recordStaff.getPhoneNumber());
|
||||
try {
|
||||
SpringUtils.getBean(WebHookSendHandler.class)
|
||||
.webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT,
|
||||
phoneList,
|
||||
"==========您有一条工单已经到期,请及时处理==========\n" + task.getTaskContent(),
|
||||
false);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("发送消息通知失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ public class BackstageBrandController {
|
||||
Row row = Db.selectOneByQuery("cp_j_brand_extend", QueryWrapper.create().where("brand_id = ?", bo.getId()));
|
||||
if (row != null){
|
||||
CloudBrandDto cloudBrandDto = new CloudBrandDto();
|
||||
cloudBrandDto.setBrandCloudId(row.getString("brand_cloud_id"));
|
||||
cloudBrandDto.setBrandCloudId(row.getString("brandCloudId"));
|
||||
cloudBrandDto.setBrandName(bo.getBrandName());
|
||||
SpringUtils.getBean(CloudBrandHandler.class).updateBrand(cloudBrandDto);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user