package com.malk.huagao.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.NumberUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.malk.huagao.entity.YdNonProdPrice; import com.malk.huagao.entity.YdProdWorkHoursPrice; import com.malk.huagao.entity.YdUserInput; import com.malk.huagao.mapper.YdNonProdPriceMapper; import com.malk.huagao.mapper.YdProdWorkHoursPriceMapper; import com.malk.huagao.mapper.YdUserInputMapper; import com.malk.huagao.service.HuaGaoService; import com.malk.server.aliwork.YDConf; import com.malk.server.aliwork.YDParam; import com.malk.server.common.McException; import com.malk.server.dingtalk.DDR; import com.malk.server.dingtalk.DDR_New; import com.malk.service.aliwork.YDClient; import com.malk.service.aliwork.YDService; import com.malk.service.dingtalk.DDClient; import com.malk.service.dingtalk.DDClient_Attendance; import com.malk.service.dingtalk.DDClient_Contacts; import com.malk.service.fxiaoke.FXKClient; import com.malk.utils.UtilDateTime; import com.malk.utils.UtilMap; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.*; @Slf4j @Service public class HuaGaoServiceImpl implements HuaGaoService { @Autowired private YDService ydService; @Autowired private YDClient ydClient; @Value("${dingtalk.appKey}") private String appKey; @Value("${dingtalk.appSecret}") private String appSecret; @Autowired private DDClient_Contacts ddClient_contacts; @Autowired private DDClient_Attendance ddClientAttendance; @Autowired private DDClient ddClient; @Autowired private FXKClient fxkClient; @Autowired private YdUserInputMapper ydUserInputMapper; @Autowired private YdNonProdPriceMapper ydNonProdPriceMapper; @Autowired private YdProdWorkHoursPriceMapper ydProdWorkHoursPriceMapper; @Autowired private static final long DEPT_ID = 971482089L; // 合作加盟校区 /// 创建企业账号: loginI/userId 都为 SHR 工号 private Map crcreateUser_dingTalk(String name, String randomAccount, String randomPassword) { Map param = new HashMap(); param.put("access_token", ddClient.getAccessToken()); Map body = new HashMap(); body.put("exclusive_account", "true"); body.put("exclusive_account_type", "dingtalk"); body.put("login_id", randomAccount); body.put("init_password", randomPassword); body.put("name", name); body.put("userid", randomAccount); body.put("dept_id_list", DEPT_ID); Object result = DDR.doPost("https://oapi.dingtalk.com/topapi/v2/user/create", (Map) null, param, body).getResult(); return (Map) result; } /** * 同步钉钉企业账号 */ @Override public void syncDingTalk_exclusive() { List dataList = ydService.queryFormData_all(YDParam.builder() .formUuid("FORM-0086C4597047459BBB37C79E404745C9CK0C") .build()); log.info("钉钉企业账号同步开始,共{}条数据", dataList.size()); dataList.forEach(data -> { if ("".equals(UtilMap.getString(data, "textField_m1mw64v4"))) { String message = ""; String randomAccount = generateRandomAccount(); String randomPassword = generateRandomSixDigitPassword(); try { Map textField_m21lkesk = this.crcreateUser_dingTalk(UtilMap.getString(data, "textField_m21lkesk"), randomAccount, randomPassword); System.out.println(""); } catch (McException e) { message = e.getMessage(); log.error(e.getMessage(), e); } ydClient.operateData(YDParam.builder() .formInstanceId(UtilMap.getString(data, "instanceId")) .useLatestVersion(true) .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_m1mw64v4, textField_m1mw64v5", randomAccount, randomPassword))) .build(), YDConf.FORM_OPERATION.update); } }); } /** * 重置企业账号密码 */ @Override public void resetPwd(Map data) { ddClient_contacts.updateUser_dingTalk(ddClient.getAccessToken(), UtilMap.getString(data, "userId"), Arrays.asList(DEPT_ID), UtilMap.map("init_password", UtilMap.getString(data, "password"))); } SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public void getCheckWorkDateDetails(Map data) { List users = new ArrayList<>(); users.add("284156461536271475"); String[] strings = users.toArray(new String[0]); log.info("users:{}", JSON.toJSONString(strings)); List mapList = ddClientAttendance.getAttColumnVal(ddClient.getAccessToken(appKey, appSecret),"284156461536271475", Arrays.asList("82772106,89349019"),"2025-01-20 08:00:00", "2025-01-21 08:00:00"); System.out.println("====="+mapList); // mapList.get(0) String FORMtime = "2025-01-01 00:00:00"; String TOtime = "2025-01-31 00:00:00"; // dateFormat.format(FORMtime); // dateFormat.format(TOtime); //工作时长(实际工时) // Step 1. 提取原始数据到日期-字段ID-值的映射 Map> dateData = new HashMap<>(); for (Map element : mapList) { // 获取字段ID Map columnVo = (Map) element.get("column_vo"); Long id = ((Number) columnVo.get("id")).longValue(); // 遍历该字段的所有日期数据 List> columnVals = (List>) element.get("column_vals"); for (Map entry : columnVals) { String fullDate = entry.get("date"); // System.out.println("fullDate:====="+fullDate); String date = fullDate.split(" ")[0]; // 提取日期部分 Double value = Double.parseDouble(entry.get("value")); // 存储到日期映射中 dateData.computeIfAbsent(date, k -> new HashMap<>()) .put(id, value); } } // Step 2. 按日期处理业务逻辑 Map finalResult = new LinkedHashMap<>(); // 保持日期顺序 for (Map.Entry> entry : dateData.entrySet()) { String date = entry.getKey(); Map idValues = entry.getValue(); // 获取目标字段的值 Double targetValue = idValues.get(89349019L); // ID=89349019 Double refValue = idValues.get(82772106L); // ID=82772106 // 逻辑判断 if (targetValue == null || refValue == null) { System.err.println("日期 " + date + " 缺少必要字段数据,跳过计算"); continue; } double result; if (targetValue >= 8) { result = targetValue; // 直接返回 } else { result = targetValue + (refValue / 60); // 组合计算 } finalResult.put(date, result); } // Step 3. 打印最终结果 System.out.println("===== 计算结果 ====="); finalResult.forEach((date, value) -> { System.out.printf("日期: %s \t 结果值: %.1f%n", date, value); }); } @Override public void syncKqData(LocalDateTime startTime, LocalDateTime endTime) { String stTime=UtilDateTime.formatLocal(startTime,UtilDateTime.DATE_TIME_PATTERN); String edTime=UtilDateTime.formatLocal(endTime,UtilDateTime.DATE_TIME_PATTERN); List list=ydService.queryAllFormData(YDParam.builder().formUuid("FORM-5061F7AE543B429C8241EC730A6F31653NNK").build()); for(Map map:list){ Map formData= UtilMap.getMap(map,"formData"); String deptId=String.valueOf(UtilMap.getList(formData,"departmentSelectField_m8e4zaju_id").get(0)); String price=UtilMap.getString(formData,"numberField_m8e4zajw_value"); List users=ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(),Long.parseLong(deptId)); for (String user : users) { List valList=ddClientAttendance.getAttColumnVal(ddClient.getAccessToken(),user, Arrays.asList("82772106","89349019","82772125"),stTime,edTime); if(valList!=null&&valList.size()==3){ Map> dateMap=toDateMap(valList); for (String date:dateMap.keySet()) { Map dataMap=dateMap.get(date); String workTime="休息".equals(dataMap.get("82772125"))? dataMap.get("89349019"): NumberUtil.add(dataMap.get("89349019"),dataMap.get("82772106")).toString(); saveData(user,date,workTime,price); //同步到数据库 LambdaQueryWrapper ydUserInputLambdaQueryWrapper = new LambdaQueryWrapper<>(); ydUserInputLambdaQueryWrapper.eq(YdUserInput::getUserId,user) .eq(YdUserInput::getDate, date); YdUserInput ydUserInput = ydUserInputMapper.selectOne(ydUserInputLambdaQueryWrapper); if (Objects.nonNull(ydUserInput)){ ydUserInput.setWorkHours(workTime); ydUserInput.setPrice(price); ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price)); ydUserInputMapper.update(ydUserInput,ydUserInputLambdaQueryWrapper); }else { try { ydUserInput = new YdUserInput(); ydUserInput.setUserId(user); SimpleDateFormat formatter = new SimpleDateFormat(UtilDateTime.DATE_TIME_PATTERN); ydUserInput.setDate(formatter.parse(date)); ydUserInput.setWorkHours(workTime); ydUserInput.setPrice(price); ydUserInput.setTotalPrice(NumberUtil.mul(workTime,price)); ydUserInputMapper.insert(ydUserInput); }catch (ParseException e){ log.info("无法解析日期字符串: {}",e.getMessage()); } } } } } } } @Override public void upsertNonProdPrice(Map map) { String formInstId = UtilMap.getString(map, "formInstId"); Map formData = ydClient.queryData(YDParam.builder() .formInstId(formInstId) .build(), YDConf.FORM_QUERY.retrieve_id).getFormData(); String type = UtilMap.getString(formData, "textField_m8fljzks"); String form = UtilMap.getString(formData, "textField_m8fljzkt"); String position = UtilMap.getString(formData, "textField_m8fljzku"); String materialCodeLeft = UtilMap.getString(formData, "textField_m8fljzkv"); String price = UtilMap.getString(formData, "numberField_m8fljzkw"); LambdaQueryWrapper ydNonProdPriceLambdaQueryWrapper = new LambdaQueryWrapper<>(); ydNonProdPriceLambdaQueryWrapper.eq(YdNonProdPrice::getType,type) .eq(YdNonProdPrice::getForm,form) .eq(YdNonProdPrice::getPosition,position) .eq(YdNonProdPrice::getMaterialCodeLeft,materialCodeLeft); YdNonProdPrice ydNonProdPrice = ydNonProdPriceMapper.selectOne(ydNonProdPriceLambdaQueryWrapper); if (Objects.nonNull(ydNonProdPrice)){ ydNonProdPrice.setPrice(price); ydNonProdPriceMapper.update(ydNonProdPrice,ydNonProdPriceLambdaQueryWrapper); }else { ydNonProdPrice = new YdNonProdPrice(); ydNonProdPrice.setType(type); ydNonProdPrice.setForm(form); ydNonProdPrice.setPosition(position); ydNonProdPrice.setMaterialCodeLeft(materialCodeLeft); ydNonProdPrice.setPrice(price); ydNonProdPriceMapper.insert(ydNonProdPrice); } } @Override public void upsertWorkHoursPrice(Map map) { String formInstId = UtilMap.getString(map, "formInstId"); Map formData = ydClient.queryData(YDParam.builder() .formInstId(formInstId) .build(), YDConf.FORM_QUERY.retrieve_id).getFormData(); String type = UtilMap.getString(formData, "selectField_m8zib4co"); String price = UtilMap.getString(formData, "numberField_m8zib4cp"); LambdaQueryWrapper ydProdWorkHoursPriceLambdaQueryWrapper = new LambdaQueryWrapper<>(); ydProdWorkHoursPriceLambdaQueryWrapper.eq(YdProdWorkHoursPrice::getType,type); YdProdWorkHoursPrice ydProdWorkHoursPrice = ydProdWorkHoursPriceMapper.selectOne(ydProdWorkHoursPriceLambdaQueryWrapper); if (Objects.nonNull(ydProdWorkHoursPrice)){ ydProdWorkHoursPrice.setPrice(price); ydProdWorkHoursPriceMapper.update(ydProdWorkHoursPrice,ydProdWorkHoursPriceLambdaQueryWrapper); }else { ydProdWorkHoursPrice = new YdProdWorkHoursPrice(); ydProdWorkHoursPrice.setType(type); ydProdWorkHoursPrice.setPrice(price); ydProdWorkHoursPriceMapper.insert(ydProdWorkHoursPrice); } } /*@Override public void syncUserInput(LocalDateTime startTime, LocalDateTime endTime) { List dataList = getYdFormDataList("FORM-78BF5DE20E244369BD475C11A5CA48A0ZAQJ", "", YDConf.FORM_QUERY.retrieve_list_all); for (Map data : dataList) { Map formData = UtilMap.getMap(data, "formData"); YdUserInput ydUserInput = new YdUserInput(); ydUserInput.setUser(UtilMap.getList(formData, "employeeField_m8cu0g58").get(0).toString()); ydUserInput.setUserId(UtilMap.getList(formData, "employeeField_m8cu0g58_id").get(0).toString()); ydUserInput.setDate(new Date(UtilMap.getLong(formData,"dateField_m8e53oef"))); ydUserInput.setWorkHours(UtilMap.getString(formData,"numberField_m8ctvm2e")); ydUserInput.setPrice(UtilMap.getString(formData,"numberField_m8e53oeg")); ydUserInput.setTotalPrice(UtilMap.getString(formData,"numberField_m8e53oeh")); ydUserInputMapper.insert(ydUserInput); } }*/ private List getYdFormDataList(String formUuid, String searchCondition, YDConf.FORM_QUERY formQuery) { List list = new ArrayList<>(); DDR_New ddrNew = new DDR_New(); int pageNumber = 1; int pageSize = 100; do { ddrNew = ydClient.queryData(YDParam.builder().formUuid(formUuid) .searchCondition(searchCondition) .pageNumber(pageNumber) .pageSize(pageSize).build(), formQuery); list.addAll((List) ddrNew.getData()); pageNumber++; }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize); return list; } private Map> toDateMap(List valList){ Map> result = new HashMap<>(); for(Map map:valList){ String columnId=UtilMap.getString(UtilMap.getMap(map,"column_vo"),"id"); List list=UtilMap.getList(map,"column_vals"); for(Map map1:list){ String date=UtilMap.getString(map1,"date"); String value=UtilMap.getString(map1,"value"); value=columnId.equals("82772106")?NumberUtil.round(NumberUtil.div(value,"60"),2).toString():value; // 工作时长 分钟转小时 if(result.containsKey(date)){ result.get(date).put(columnId,value); }else{ result.put(date,UtilMap.map(columnId,value)); } } } return result; } private void saveData(String userId,String date,String gs,String price){ Long dateTime= UtilDateTime.getLocalDateTimeTimeStamp(UtilDateTime.parseLocalDateTime(date)); Map saveMap=UtilMap.map("employeeField_m8cu0g58, dateField_m8e53oef, numberField_m8ctvm2e, numberField_m8e53oeg, numberField_m8e53oeh", Arrays.asList(userId),dateTime,gs,price,NumberUtil.mul(gs,price)); ydClient.operateData(YDParam.builder().formUuid("FORM-78BF5DE20E244369BD475C11A5CA48A0ZAQJ") .searchCondition(JSONObject.toJSONString(UtilMap.map("employeeField_m8cu0g58, dateField_m8e53oef", userId,Arrays.asList(dateTime,dateTime)))) .formDataJson(JSONObject.toJSONString(saveMap)).build(), YDConf.FORM_OPERATION.upsert); } /** * 生成一个由大写字母和数字组成的八位随机账号。 * * @return 生成的随机账号字符串 */ public static String generateRandomAccount() { // 可选字符集合:大写字母A-Z和数字0-9 final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; final int LENGTH = 8; // 账号长度 Random random = new Random(); StringBuilder sb = new StringBuilder(LENGTH); for (int i = 0; i < LENGTH; i++) { // 随机选择一个字符 int index = random.nextInt(CHARS.length()); char randomChar = CHARS.charAt(index); sb.append(randomChar); } return sb.toString(); } /** * 生成一个六位数的随机密码。 * * @return 生成的随机密码字符串 */ public static String generateRandomSixDigitPassword() { Random random = new Random(); int min = 100000; // 六位数最小值 int max = 999999; // 六位数最大值 // 生成一个介于[min, max]之间的随机数 int randomNumber = random.nextInt(max - min + 1) + min; // 将生成的随机数转换为字符串 return String.valueOf(randomNumber); } }