Commit 75109fcd authored by 姬鋆屾's avatar 姬鋆屾
parents dad70983 7dd5af8b
...@@ -91,9 +91,16 @@ export default { ...@@ -91,9 +91,16 @@ export default {
// { label: "创建用户", prop: "createUserId", formatter: this.formatter }, // { label: "创建用户", prop: "createUserId", formatter: this.formatter },
{ {
label: "状态", prop: "processStatus", formatter: (row) => { label: "状态", prop: "processStatus", formatter: (row) => {
let str="未开始"
if(row.processStatus==1){
str="进行中"
}else if (row.processStatus==2){
str="已结束"
}
return ( return (
<el-tag type={row.processStatus ? row.processStatus = 1 ? 'success' : 'info' : 'danger'} size="small"> <el-tag type={row.processStatus ? row.processStatus == 2 ? 'success' : 'info' : 'danger'} size="small">
{row.processStatus ? row.processStatus = 1 ? '进行中' : '已结束' : '未开始'} {str}
</el-tag> </el-tag>
) )
} }
......
...@@ -71,6 +71,8 @@ ...@@ -71,6 +71,8 @@
<profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId> <profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId>
<profiles.dingtalk.appKey>dingpqzradgfr4efdi2j</profiles.dingtalk.appKey> <profiles.dingtalk.appKey>dingpqzradgfr4efdi2j</profiles.dingtalk.appKey>
<profiles.dingtalk.appSecret>bF2WALmo5_Wuj3hg5gXeWqezrYnZChUJ88HjzNWpkA9ivdOxfBDGOGYcfVRfB3vd</profiles.dingtalk.appSecret> <profiles.dingtalk.appSecret>bF2WALmo5_Wuj3hg5gXeWqezrYnZChUJ88HjzNWpkA9ivdOxfBDGOGYcfVRfB3vd</profiles.dingtalk.appSecret>
<profiles.dingtalk.aesKey>1QcPYuSpAc98OS3qQwwx5HPH85CZDidxF95yBGad2fJ</profiles.dingtalk.aesKey>
<profiles.dingtalk.token>m3WeuVx5kcTY76kh22uWZOTSu0XjvcwNhd</profiles.dingtalk.token>
<profiles.webUrl>http://8.136.255.30:11039/attendance</profiles.webUrl> <profiles.webUrl>http://8.136.255.30:11039/attendance</profiles.webUrl>
<package.environment>test</package.environment> <package.environment>test</package.environment>
<skipUi>false</skipUi> <skipUi>false</skipUi>
...@@ -99,6 +101,8 @@ ...@@ -99,6 +101,8 @@
<profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId> <profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId>
<profiles.dingtalk.appKey>dingpqzradgfr4efdi2j</profiles.dingtalk.appKey> <profiles.dingtalk.appKey>dingpqzradgfr4efdi2j</profiles.dingtalk.appKey>
<profiles.dingtalk.appSecret>bF2WALmo5_Wuj3hg5gXeWqezrYnZChUJ88HjzNWpkA9ivdOxfBDGOGYcfVRfB3vd</profiles.dingtalk.appSecret> <profiles.dingtalk.appSecret>bF2WALmo5_Wuj3hg5gXeWqezrYnZChUJ88HjzNWpkA9ivdOxfBDGOGYcfVRfB3vd</profiles.dingtalk.appSecret>
<profiles.dingtalk.aesKey>1QcPYuSpAc98OS3qQwwx5HPH85CZDidxF95yBGad2fJ</profiles.dingtalk.aesKey>
<profiles.dingtalk.token>m3WeuVx5kcTY76kh22uWZOTSu0XjvcwNhd</profiles.dingtalk.token>
<profiles.webUrl>https://ybswxxcx.zwfwhfgjjfzj.yibin.gov.cn/performance-h5</profiles.webUrl> <profiles.webUrl>https://ybswxxcx.zwfwhfgjjfzj.yibin.gov.cn/performance-h5</profiles.webUrl>
<package.environment>build</package.environment> <package.environment>build</package.environment>
<skipUi>false</skipUi> <skipUi>false</skipUi>
......
package com.mortals.xhx.busiz;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.utils.ServletUtils;
import com.mortals.xhx.base.system.idgenerator.service.IdgeneratorService;
import com.mortals.xhx.base.system.upload.service.UploadService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.module.dept.model.DeptEntity;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.hik.face.model.req.img.ImgReq;
import com.mortals.xhx.module.hik.face.service.IHikFaceService;
import com.mortals.xhx.module.perform.model.PerformPerposeDeptStatEntity;
import com.mortals.xhx.module.perform.model.PerformPerposeStaffEntity;
import com.mortals.xhx.module.perform.model.PerformPerposeStaffStatEntity;
import com.mortals.xhx.module.perform.service.PerformPerposeDeptStatService;
import com.mortals.xhx.module.perform.service.PerformPerposeStaffService;
import com.mortals.xhx.module.perform.service.PerformPerposeStaffStatService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffPerformSummaryEntity;
import com.mortals.xhx.module.staff.model.StaffPerformSummaryQuery;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffPerformSummaryService;
import com.mortals.xhx.module.staff.service.StaffService;
import com.mortals.xhx.module.workman.model.WorkmanEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* 设备
*
* @author: zxfei
* @date: 2021/8/24 20:28
*/
@RestController
@Slf4j
@RequestMapping("/mock")
public class MockDataController {
@Autowired
private IdgeneratorService idgeneratorService;
@Autowired
private ICacheService cacheService;
@Autowired
private StaffService staffService;
@Autowired
private UserService userService;
@Autowired
private IHikFaceService faceService;
@Autowired
private UploadService uploadService;
@Autowired
private DeptService deptService;
@Autowired
private PerformPerposeStaffStatService perposeStaffStatService;
@Autowired
private PerformPerposeDeptStatService perposeDeptStatService;
@Autowired
private StaffPerformSummaryService summaryService;
/**
* 生成模拟数据
* mortals_xhx_perform_perpose_staff_stat
*
* @return
*/
@GetMapping("randomStatPerposeStaffData")
@UnAuth
public Rest<Void> randomStatPerposeStaffData() {
List<StaffEntity> cacheList = staffService.getCacheList();
//最近两月模拟数据
DateTime beforeStartDate = DateUtil.offsetDay(new Date(), -60);
for (int i = 1; i <= 60; i++) {
DateTime curDate = DateUtil.offsetDay(beforeStartDate, i);
List<PerformPerposeStaffStatEntity> collect = cacheList.stream().map(item -> {
PerformPerposeStaffStatEntity statEntity = new PerformPerposeStaffStatEntity();
statEntity.initAttrValue();
statEntity.setStaffId(item.getId());
statEntity.setStaffName(item.getName());
statEntity.setNumber(item.getWorkNum());
statEntity.setAbsentRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setAbsenceRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setLateRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setEarlyRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setLeaveRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setTurnoverRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setSleepRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setPlayPhoneRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setExpireWorkRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setNegaReviewRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setYear(DateUtil.year(curDate));
statEntity.setMonth(DateUtil.month(curDate) + 1);
statEntity.setDay(DateUtil.dayOfMonth(curDate));
return statEntity;
}).collect(Collectors.toList());
perposeStaffStatService.save(collect);
}
return Rest.ok();
}
/**
* 生成模拟数据
* mortals_xhx_perform_perpose_dept_stat
*
* @return
*/
@GetMapping("randomStatPerposeDeptData")
@UnAuth
public Rest<Void> randomStatPerposeDeptData() {
List<DeptEntity> deptEntityList = deptService.find(new DeptQuery());
//最近两月模拟数据
DateTime beforeStartDate = DateUtil.offsetDay(new Date(), -60);
for (int i = 1; i <= 60; i++) {
DateTime curDate = DateUtil.offsetDay(beforeStartDate, i);
List<PerformPerposeDeptStatEntity> collect = deptEntityList.stream().map(item -> {
PerformPerposeDeptStatEntity statEntity = new PerformPerposeDeptStatEntity();
statEntity.initAttrValue();
statEntity.setDeptId(item.getId());
statEntity.setDeptName(item.getDeptName());
statEntity.setAbsentRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setAbsenceRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setLateRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setEarlyRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setLeaveRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setTurnoverRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setSleepRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setPlayPhoneRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setExpireWorkRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setNegaReviewRate(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
statEntity.setYear(DateUtil.year(curDate));
statEntity.setMonth(DateUtil.month(curDate) + 1);
statEntity.setDay(DateUtil.dayOfMonth(curDate));
return statEntity;
}).collect(Collectors.toList());
perposeDeptStatService.save(collect);
}
return Rest.ok();
}
/**
* 生成模拟数据
* mortals_xhx_staff_perform_summary
*
* @return
*/
@GetMapping("randomStatStaffSummaryData")
@UnAuth
public Rest<Void> randomStatStaffSummaryData() {
List<StaffEntity> cacheList = staffService.getCacheList();
//最近两月模拟数据
DateTime beforeStartDate = DateUtil.offsetMonth(new Date(), -3);
for (int i = 1; i <= 3; i++) {
DateTime curDate = DateUtil.offsetMonth(beforeStartDate, i);
List<StaffPerformSummaryEntity> collect = cacheList.stream().map(item -> {
StaffPerformSummaryEntity statEntity = new StaffPerformSummaryEntity();
statEntity.initAttrValue();
statEntity.setStaffId(item.getId());
statEntity.setStaffName(item.getName());
statEntity.setWorkNum(item.getWorkNum());
statEntity.setDeptId(item.getDeptId());
statEntity.setDeptName(item.getDeptName());
BigDecimal attendScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal reviewScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal complainScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal goworkScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal effectScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal otherScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal errorScore = RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal totalScore =attendScore.add(reviewScore).add(complainScore).add(goworkScore).add(effectScore).add(otherScore).add(errorScore);
statEntity.setAttendScore(attendScore);
statEntity.setReviewScore(reviewScore);
statEntity.setComplainScore(complainScore);
statEntity.setGoworkScore(goworkScore);
statEntity.setEffectScore(effectScore);
statEntity.setOtherScore(otherScore);
statEntity.setErrorScore(errorScore);
statEntity.setTotalScore(totalScore);
statEntity.setYear(DateUtil.year(curDate));
statEntity.setMonth(DateUtil.month(curDate) + 1);
return statEntity;
}).collect(Collectors.toList());
summaryService.save(collect);
}
return Rest.ok();
}
public static void main(String[] args) {
System.out.println(RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal("1")).setScale(2, BigDecimal.ROUND_CEILING));
}
}
...@@ -17,6 +17,7 @@ import com.mortals.xhx.base.system.user.service.UserService; ...@@ -17,6 +17,7 @@ import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.YesNoEnum; import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.hik.face.model.req.img.ImgReq; import com.mortals.xhx.module.hik.face.model.req.img.ImgReq;
import com.mortals.xhx.module.hik.face.service.IHikFaceService; import com.mortals.xhx.module.hik.face.service.IHikFaceService;
import com.mortals.xhx.module.perform.service.PerformPerposeStaffService;
import com.mortals.xhx.module.staff.model.StaffEntity; import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery; import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffService; import com.mortals.xhx.module.staff.service.StaffService;
...@@ -62,6 +63,9 @@ public class TestController { ...@@ -62,6 +63,9 @@ public class TestController {
@Autowired @Autowired
private UploadService uploadService; private UploadService uploadService;
@Autowired
private PerformPerposeStaffService performPerposeStaffService;
// @GetMapping("webservice")@GetMapping("idGens") // @GetMapping("webservice")@GetMapping("idGens")
// public String idGens() { // public String idGens() {
...@@ -207,11 +211,12 @@ public class TestController { ...@@ -207,11 +211,12 @@ public class TestController {
/** /**
* 生成模拟数据 * 生成模拟数据
* mortals_xhx_perform_perpose_staff_stat
* @return * @return
*/ */
@GetMapping("randomStatData") @GetMapping("randomStatPerposeStaffData")
@UnAuth @UnAuth
public Rest<Void> randomMockStatData() { public Rest<Void> randomStatPerposeStaffData() {
return Rest.ok(); return Rest.ok();
......
...@@ -10,7 +10,7 @@ import com.mortals.framework.model.PageInfo; ...@@ -10,7 +10,7 @@ import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result; import com.mortals.framework.model.Result;
import com.mortals.xhx.busiz.h5.req.FeedbackReq; import com.mortals.xhx.busiz.h5.req.FeedbackReq;
import com.mortals.xhx.busiz.h5.req.FeedbackSaveReq; import com.mortals.xhx.busiz.h5.req.FeedbackSaveReq;
import com.mortals.xhx.common.code.YesNoEnum; import com.mortals.xhx.common.code.*;
import com.mortals.xhx.module.feedback.model.*; import com.mortals.xhx.module.feedback.model.*;
import com.mortals.xhx.module.feedback.service.FeedbackAnswerService; import com.mortals.xhx.module.feedback.service.FeedbackAnswerService;
import com.mortals.xhx.module.feedback.service.FeedbackService; import com.mortals.xhx.module.feedback.service.FeedbackService;
...@@ -48,6 +48,12 @@ public class FeedbackApiController extends AbstractBaseController<FeedbackReq> { ...@@ -48,6 +48,12 @@ public class FeedbackApiController extends AbstractBaseController<FeedbackReq> {
@Autowired @Autowired
private FeedbackAnswerService answerService; private FeedbackAnswerService answerService;
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "processStatus", FeedProcessStatusEnum.getEnumMap());
}
/** /**
* 反馈列表 * 反馈列表
*/ */
...@@ -137,6 +143,7 @@ public class FeedbackApiController extends AbstractBaseController<FeedbackReq> { ...@@ -137,6 +143,7 @@ public class FeedbackApiController extends AbstractBaseController<FeedbackReq> {
} }
} }
} }
this.init(model, context);
rest.setData(model); rest.setData(model);
recordSysLog(request, busiDesc + " 【成功】"); recordSysLog(request, busiDesc + " 【成功】");
} catch (Exception e) { } catch (Exception e) {
......
...@@ -174,7 +174,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> { ...@@ -174,7 +174,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> {
BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item)); BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) { if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) {
performInfo.setResult(CheckStatusEnum.未处理.getDesc()); performInfo.setResult("待处理");
} else { } else {
performInfo.setResult(item.getCheckResult()); performInfo.setResult(item.getCheckResult());
} }
...@@ -194,7 +194,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> { ...@@ -194,7 +194,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> {
BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item)); BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) { if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) {
performInfo.setResult(CheckStatusEnum.未处理.getDesc()); performInfo.setResult("待处理");
} else { } else {
performInfo.setResult(item.getCheckResult()); performInfo.setResult(item.getCheckResult());
} }
...@@ -213,7 +213,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> { ...@@ -213,7 +213,7 @@ public class InspectApiController extends AbstractBaseController<PerformReq> {
BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item)); BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) { if (CheckStatusEnum.未处理.getValue() == item.getCheckStatus()) {
performInfo.setResult(CheckStatusEnum.未处理.getDesc()); performInfo.setResult("待处理");
} else { } else {
performInfo.setResult(item.getCheckResult()); performInfo.setResult(item.getCheckResult());
} }
......
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 处理状态(1.未处理,2.已处理)枚举类
*
* @author zxfei
*/
public enum FeedProcessStatusEnum {
未开始(0, "未开始"),
进行中(1, "进行中"),
已完成(2, "已完成");
private Integer value;
private String desc;
FeedProcessStatusEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static FeedProcessStatusEnum getByValue(Integer value) {
for (FeedProcessStatusEnum checkStatusEnum : FeedProcessStatusEnum.values()) {
if (checkStatusEnum.getValue() == value) {
return checkStatusEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (FeedProcessStatusEnum item : FeedProcessStatusEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.module.attendance.dingmsg;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 钉钉开放平台加解密方法
*
* @author ZYW
* @date 2023-07-18 10:42
*/
public class DingCallbackCrypto {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final Base64 base64 = new Base64();
private byte[] aesKey;
private String token;
private String corpId;
/**
* ask getPaddingBytes key固定长度
**/
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
/**
* 加密随机字符串字节长度
**/
private static final Integer RANDOM_LENGTH = 16;
/**
* 构造函数
*
* @param token 钉钉开放平台上,开发者设置的token
* @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey
* @param corpId 企业自建应用-事件订阅, 使用appKey
* 企业自建应用-注册回调地址, 使用corpId
* 第三方企业应用, 使用suiteKey
*
* @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);
}
this.token = token;
this.corpId = corpId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}
public Map<String, String> getEncryptedMap(String plaintext) throws DingTalkEncryptException {
return getEncryptedMap(plaintext, System.currentTimeMillis(), Utils.getRandomStr(16));
}
/**
* 将和钉钉开放平台同步的消息体加密,返回加密Map
*
* @param plaintext 传递的消息体明文
* @param timeStamp 时间戳
* @param nonce 随机字符串
* @return
* @throws DingTalkEncryptException
*/
public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce)
throws DingTalkEncryptException {
if (null == plaintext) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);
}
if (null == timeStamp) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL);
}
if (null == nonce) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);
}
// 加密
String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH), plaintext);
String signature = getSignature(token, String.valueOf(timeStamp), nonce, encrypt);
Map<String, String> resultMap = new HashMap<String, String>();
resultMap.put("msg_signature", signature);
resultMap.put("encrypt", encrypt);
resultMap.put("timeStamp", String.valueOf(timeStamp));
resultMap.put("nonce", nonce);
return resultMap;
}
/**
* 密文解密
*
* @param msgSignature 签名串
* @param timeStamp 时间戳
* @param nonce 随机串
* @param encryptMsg 密文
* @return 解密后的原文
* @throws DingTalkEncryptException
*/
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg)
throws DingTalkEncryptException {
//校验签名
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
if (!signature.equals(msgSignature)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
// 解密
String result = decrypt(encryptMsg);
return result;
}
/*
* 对明文加密.
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
*/
private String encrypt(String random, String plaintext) throws DingTalkEncryptException {
try {
byte[] randomBytes = random.getBytes(CHARSET);
byte[] plainTextBytes = plaintext.getBytes(CHARSET);
byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length);
byte[] corpidBytes = corpId.getBytes(CHARSET);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byteStream.write(randomBytes);
byteStream.write(lengthByte);
byteStream.write(plainTextBytes);
byteStream.write(corpidBytes);
byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size());
byteStream.write(padBytes);
byte[] unencrypted = byteStream.toByteArray();
byteStream.close();
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] encrypted = cipher.doFinal(unencrypted);
String result = base64.encodeToString(encrypted);
return result;
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);
}
}
/*
* 对密文进行解密.
* @param text 需要解密的密文
* @return 解密得到的明文
*/
private String decrypt(String text) throws DingTalkEncryptException {
byte[] originalArr;
try {
// 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.decodeBase64(text);
// 解密
originalArr = cipher.doFinal(encrypted);
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
}
String plainText;
String fromCorpid;
try {
// 去除补位字符
byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
// 分离16位随机字符串,网络字节序和corpId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLegth = Utils.bytes2int(networkOrder);
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
}
// corpid不相同的情况
if (!fromCorpid.equals(corpId)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
}
return plainText;
}
/**
* 数字签名
*
* @param token isv token
* @param timestamp 时间戳
* @param nonce 随机串
* @param encrypt 加密文本
* @return
* @throws DingTalkEncryptException
*/
public String getSignature(String token, String timestamp, String nonce, String encrypt)
throws DingTalkEncryptException {
try {
String[] array = new String[] {token, timestamp, nonce, encrypt};
Arrays.sort(array);
System.out.println(JSON.toJSONString(array));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
sb.append(array[i]);
}
String str = sb.toString();
System.out.println(str);
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
}
public static class Utils {
public Utils() {
}
public static String getRandomStr(int count) {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; ++i) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static byte[] int2Bytes(int count) {
byte[] byteArr = new byte[] {(byte)(count >> 24 & 255), (byte)(count >> 16 & 255), (byte)(count >> 8 & 255),
(byte)(count & 255)};
return byteArr;
}
public static int bytes2int(byte[] byteArr) {
int count = 0;
for (int i = 0; i < 4; ++i) {
count <<= 8;
count |= byteArr[i] & 255;
}
return count;
}
}
public static class PKCS7Padding {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
public PKCS7Padding() {
}
public static byte[] getPaddingBytes(int count) {
int amountToPad = 32 - count % 32;
if (amountToPad == 0) {
amountToPad = 32;
}
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; ++index) {
tmp = tmp + padChr;
}
return tmp.getBytes(CHARSET);
}
public static byte[] removePaddingBytes(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
private static char chr(int a) {
byte target = (byte)(a & 255);
return (char)target;
}
}
public static class DingTalkEncryptException extends Exception {
public static final int SUCCESS = 0;
public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;
public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;
public static final int ENCRYPTION_NONCE_ILLEGAL = 900003;
public static final int AES_KEY_ILLEGAL = 900004;
public static final int SIGNATURE_NOT_MATCH = 900005;
public static final int COMPUTE_SIGNATURE_ERROR = 900006;
public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;
public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008;
public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;
public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;
private static Map<Integer, String> msgMap = new HashMap();
private Integer code;
static {
msgMap.put(0, "成功");
msgMap.put(900001, "加密明文文本非法");
msgMap.put(900002, "加密时间戳参数非法");
msgMap.put(900003, "加密随机字符串参数非法");
msgMap.put(900005, "签名不匹配");
msgMap.put(900006, "签名计算失败");
msgMap.put(900004, "不合法的aes key");
msgMap.put(900007, "计算加密文字错误");
msgMap.put(900008, "计算解密文字错误");
msgMap.put(900009, "计算解密文字长度不匹配");
msgMap.put(900010, "计算解密文字corpid不匹配");
}
public Integer getCode() {
return this.code;
}
public DingTalkEncryptException(Integer exceptionCode) {
super((String)msgMap.get(exceptionCode));
this.code = exceptionCode;
}
}
static {
try {
Security.setProperty("crypto.policy", "limited");
RemoveCryptographyRestrictions();
} catch (Exception var1) {
}
}
private static void RemoveCryptographyRestrictions() throws Exception {
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
if (jceSecurity != null) {
setFinalStaticValue(jceSecurity, "isRestricted", false);
PermissionCollection defaultPolicy = (PermissionCollection)getFieldValue(jceSecurity, "defaultPolicy", (Object)null, PermissionCollection.class);
if (cryptoPermissions != null) {
Map<?, ?> map = (Map)getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
map.clear();
}
if (cryptoAllPermission != null) {
Permission permission = (Permission)getFieldValue(cryptoAllPermission, "INSTANCE", (Object)null, Permission.class);
defaultPolicy.add(permission);
}
}
}
private static Class<?> getClazz(String className) {
Class clazz = null;
try {
clazz = Class.forName(className);
} catch (Exception var3) {
}
return clazz;
}
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & -17);
field.set((Object)null, newValue);
}
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
return dstClazz.cast(field.get(owner));
}
}
package com.mortals.xhx.module.attendance.dingmsg.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.common.pdu.ApiRespPdu;
import com.mortals.xhx.module.attendance.dingmsg.DingCallbackCrypto;
import com.mortals.xhx.module.attendance.dingmsg.dingmsgreq.DingResponsMeassageReq;
import com.mortals.xhx.module.attendance.dingmsg.dingmsgreq.EncryptReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
*
* 接收钉钉的审批消息推送
*
* @author ZYW
* @date 2023-07-18 9:52
*/
@RestController
@Slf4j
public class DingMessageController {
/**
* appKey
*/
@Value("${dingtalk.AppKey:''}")
protected String appKey;
/**
* aesKey
*/
@Value("${dingtalk.AesKey:''}")
protected String aesKey;
/**
* 订阅消息token
*/
@Value("${dingtalk.token:''}")
protected String token;
/**
* 接收钉钉消息
*
* @return
*/
@PostMapping("/dingtalk/getOaMeassge")
@UnAuth
public Map<String, String> getOaMessage(@RequestParam(value = "msg_signature", required = false) String msg_signature,
@RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestBody(required = false) JSONObject json) throws DingCallbackCrypto.DingTalkEncryptException {
try {
// 1. 从http请求中获取加解密参数
// 2. 使用加解密类型
// Constant.OWNER_KEY 说明:
// 1、开发者后台配置的订阅事件为应用级事件推送,此时OWNER_KEY为应用的APP_KEY。
// 2、调用订阅事件接口订阅的事件为企业级事件推送,
// 此时OWNER_KEY为:企业的appkey(企业内部应用)或SUITE_KEY(三方应用)
DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aesKey, appKey);
String encryptMsg = json.getString("encrypt");
String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);
// 3. 反序列化回调事件json数据
JSONObject eventJson = JSON.parseObject(decryptMsg);
String eventType = eventJson.getString("EventType");
// 4. 根据EventType分类处理
if ("check_url".equals(eventType)) {
// 测试回调url的正确性
log.info("测试回调url的正确性");
} else if ("user_add_org".equals(eventType)) {
// 处理通讯录用户增加事件
log.info("发生了:" + eventType + "事件");
} else {
// 添加其他已注册的
log.info("发生了:" + eventType + "事件");
}
// 5. 返回success的加密数据
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
return successMap;
} catch (DingCallbackCrypto.DingTalkEncryptException e) {
e.printStackTrace();
}
return null;
}
}
package com.mortals.xhx.module.attendance.dingmsg.dingmsgreq;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author ZYW
* @date 2023-07-18 10:20
*/
@NoArgsConstructor
@Data
public class DingResponsMeassageReq {
@JsonProperty("msg_signature")
private String msgSignature;
@JsonProperty("timeStamp")
private String timeStamp;
@JsonProperty("nonce")
private String nonce;
@JsonProperty("encrypt")
private String encrypt;
}
package com.mortals.xhx.module.attendance.dingmsg.dingmsgreq;
/**
* @author ZYW
* @date 2023-07-18 10:14
*/
public class EncryptReq {
String encrypt;
public String getEncrypt() {
return encrypt;
}
public void setEncrypt(String encrypt) {
this.encrypt = encrypt;
}
}
...@@ -40,8 +40,17 @@ public class FeedbackServiceImpl extends AbstractCRUDServiceImpl<FeedbackDao, Fe ...@@ -40,8 +40,17 @@ public class FeedbackServiceImpl extends AbstractCRUDServiceImpl<FeedbackDao, Fe
private FeedbackStaffService feedbackStaffService; private FeedbackStaffService feedbackStaffService;
@Override
protected void findAfter(FeedbackEntity params, PageInfo pageInfo, Context context, List<FeedbackEntity> list) throws AppException {
updateProcessStatus(list);
}
@Override @Override
protected void findAfter(FeedbackEntity entity, Context context, List<FeedbackEntity> list) throws AppException { protected void findAfter(FeedbackEntity entity, Context context, List<FeedbackEntity> list) throws AppException {
updateProcessStatus(list);
}
private static void updateProcessStatus(List<FeedbackEntity> list) {
list.stream().forEach(item->{ list.stream().forEach(item->{
Date feedbackTimeStart = item.getFeedbackTimeStart(); Date feedbackTimeStart = item.getFeedbackTimeStart();
Date feedbackTimeEnd = item.getFeedbackTimeEnd(); Date feedbackTimeEnd = item.getFeedbackTimeEnd();
......
...@@ -72,5 +72,7 @@ dingtalk: ...@@ -72,5 +72,7 @@ dingtalk:
agentId: @profiles.dingtalk.agentId@ agentId: @profiles.dingtalk.agentId@
AppKey: @profiles.dingtalk.appKey@ AppKey: @profiles.dingtalk.appKey@
AppSecret: @profiles.dingtalk.appSecret@ AppSecret: @profiles.dingtalk.appSecret@
webUrl: @profiles.webUrl@ webUrl: @profiles.webUrl@
AesKey: @profiles.dingtalk.aesKey@
token: @profiles.dingtalk.token@
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment