diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/EmployeeOnboardingController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/EmployeeOnboardingController.java index aa1c459..52e66b6 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/EmployeeOnboardingController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/EmployeeOnboardingController.java @@ -90,7 +90,7 @@ public class EmployeeOnboardingController extends BaseController { @Log(title = "入职管理", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() - public R edit(@Validated(EditGroup.class) @RequestBody EmployeeOnboardingBo bo) { + public R edit(@RequestBody EmployeeOnboardingBo bo) { return toAjax(iEmployeeOnboardingService.updateByBo(bo)); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaSalaryController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaSalaryController.java index e3e0e7e..e073f69 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaSalaryController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaSalaryController.java @@ -48,6 +48,14 @@ public class OaSalaryController extends BaseController { return iOaSalaryService.queryPageList(bo, pageQuery); } + /** + * 批量写入user到salary中 + */ + @GetMapping("/import") + public R importSalaryUser() { + return iOaSalaryService.importSalaryUser(); + } + /** * 导出薪资管理列表 */ @@ -105,4 +113,10 @@ public class OaSalaryController extends BaseController { @PathVariable Long[] salaryIds) { return toAjax(iOaSalaryService.deleteWithValidByIds(Arrays.asList(salaryIds), true)); } + + + @PostMapping("/calc") + public void calc(@RequestBody OaSalaryBo bo) { + iOaSalaryService.calcSalary(bo); + } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaSalaryBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaSalaryBo.java index 2ae1d09..8e42efc 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaSalaryBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaSalaryBo.java @@ -44,6 +44,7 @@ public class OaSalaryBo extends BaseEntity { */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") + @NotBlank(message = "发放时间不能为空") private Date payTime; /** @@ -56,5 +57,10 @@ public class OaSalaryBo extends BaseEntity { */ private String remark; + /** 以下二参数是用来分析材料并且计算的 */ + private String monthStr; + + private String filePath; + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/CalcResultVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/CalcResultVo.java new file mode 100644 index 0000000..b5355e9 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/CalcResultVo.java @@ -0,0 +1,59 @@ +package com.ruoyi.oa.domain.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class CalcResultVo { + + /** 迟到次数 */ + private Long lateCount; + + /** 早退十分钟次数 */ + private Long leaveEarly10Count; + + /** 早退30分钟次数 */ + private Long leaveEarly30Count; + + /** 旷工次数 */ + private Long absentCount; + + /** 旷工半天次数 */ + private Long absent05Count; + + /** 未打卡次数 */ + private Long notAttendance; + + /** 迟到日期 */ + private List lateDates; + + /** 早退10分钟日期 */ + private List leaveEarly10Dates; + + /** 早退30分钟日期 */ + private List leaveEarly30Dates; + + /** 矿工日期 */ + private List absentDates; + + /** 矿工半天日期 */ + private List absent05Dates; + + /** 未打卡日期 */ + private List notAttendanceDates; + + /** 迟到罚金 */ + private Long lateFee; + + /** 早退罚金 */ + private Long leaveEarlyFee; + + /** 打卡罚金 */ + private Long notAttendanceFee; + + /** 综合罚金 */ + private Long sumFee; + + +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaSalaryMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaSalaryMapper.java index 3557d9f..ad13f42 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaSalaryMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaSalaryMapper.java @@ -18,4 +18,7 @@ import org.apache.ibatis.annotations.Param; public interface OaSalaryMapper extends BaseMapperPlus { Page selectStaffVoPage(Page build,@Param(Constants.WRAPPER) Wrapper lqw); + + + OaSalary selectVoByUserId(Long userId); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaSalaryService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaSalaryService.java index e21932e..3d9d235 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaSalaryService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaSalaryService.java @@ -1,5 +1,6 @@ package com.ruoyi.oa.service; +import com.ruoyi.common.core.domain.R; import com.ruoyi.oa.domain.OaSalary; import com.ruoyi.oa.domain.vo.OaSalaryVo; import com.ruoyi.oa.domain.bo.OaSalaryBo; @@ -46,4 +47,17 @@ public interface IOaSalaryService { * 校验并批量删除薪资管理信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + + /** + * 计算工资 + * @param bo + */ + void calcSalary(OaSalaryBo bo); + + /** + * 导入当月所有人的记录 + * @return + */ + R importSalaryUser(); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/EmployeeOnboardingServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/EmployeeOnboardingServiceImpl.java index 49e2a94..c35a545 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/EmployeeOnboardingServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/EmployeeOnboardingServiceImpl.java @@ -130,6 +130,6 @@ public class EmployeeOnboardingServiceImpl implements IEmployeeOnboardingService @Override public EmployeeOnboardingVo queryByUserId(Long userId) { - return baseMapper.selectVoById(userId); + return baseMapper.selectVoByUserId(userId); } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaSalaryServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaSalaryServiceImpl.java index 685ccef..62c5a5d 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaSalaryServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaSalaryServiceImpl.java @@ -1,13 +1,39 @@ package com.ruoyi.oa.service.impl; import cn.hutool.core.bean.BeanUtil; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.service.UserService; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.flowable.utils.TaskUtils; +import com.ruoyi.oa.domain.OaSalaryItem; +import com.ruoyi.oa.domain.vo.CalcResultVo; +import com.ruoyi.oa.domain.vo.SysOaHolidayVo; +import com.ruoyi.oa.mapper.OaSalaryItemMapper; +import com.ruoyi.oa.service.IOaSalaryItemService; +import com.ruoyi.oa.service.ISysOaHolidayService; +import com.ruoyi.oa.utils.OwnHttpUtils; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.workflow.mapper.WfDeployFormMapper; +import com.ruoyi.workflow.service.IWfTaskService; +import liquibase.pro.packaged.A; import lombok.RequiredArgsConstructor; +import org.apache.catalina.User; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.TaskService; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.history.HistoricProcessInstanceQuery; +import org.flowable.engine.repository.Deployment; +import org.flowable.task.api.TaskQuery; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.oa.domain.bo.OaSalaryBo; import com.ruoyi.oa.domain.vo.OaSalaryVo; @@ -15,9 +41,15 @@ import com.ruoyi.oa.domain.OaSalary; import com.ruoyi.oa.mapper.OaSalaryMapper; import com.ruoyi.oa.service.IOaSalaryService; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.*; /** * 薪资管理Service业务层处理 @@ -31,6 +63,29 @@ public class OaSalaryServiceImpl implements IOaSalaryService { private final OaSalaryMapper baseMapper; + private final IWfTaskService wfTaskService; + + private final WfDeployFormMapper deployFormMapper; + + @Resource + private RepositoryService repositoryService; + + @Resource + private TaskService taskService; + + @Resource + private HistoryService historyService; + + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysOaHolidayService holidayService; + + @Autowired + private OaSalaryItemMapper salaryItemMapper; + /** * 查询薪资管理 */ @@ -49,6 +104,19 @@ public class OaSalaryServiceImpl implements IOaSalaryService { return TableDataInfo.build(result); } + @Override + public R importSalaryUser() { + SysUser sysUser = new SysUser(); + List sysUsers = userService.selectUserList(sysUser); + for (SysUser user : sysUsers) { + OaSalary oaSalary = new OaSalary(); + oaSalary.setUserId(user.getUserId()); + oaSalary.setBaseSalary(Double.valueOf(user.getLaborCost())); + oaSalary.setPayTime(new Date()); + baseMapper.insert(oaSalary); + } + return R.ok(); + } /** * 查询薪资管理列表 */ @@ -109,4 +177,280 @@ public class OaSalaryServiceImpl implements IOaSalaryService { } return baseMapper.deleteBatchIds(ids) > 0; } + + /** + * 计算薪资 + * @param bo + */ + @Override + public void calcSalary(OaSalaryBo bo) { + // 1先获取对应的json路径 "/home/ubuntu/lyq/fad_oa_kqdeal/202411.json" + String jsonPath = OwnHttpUtils.getJsonName(bo.getMonthStr(), bo.getFilePath()); + // 2拿到所有的用户 + SysUser sysUser = new SysUser(); + Date yearMonth = StringToDate(combineYearMonth(bo.getMonthStr())); + List sysUsers = userService.selectUserList(sysUser); + // 3遍历user列表 拿出所有的nickName分别拿到他们的json 进行第二步分析 + for (SysUser user : sysUsers) { + OaSalary salary = baseMapper.selectVoByUserId(user.getUserId()); + if (salary == null) { + return; + } + // 3.1 拿到一个人打卡机的记录 + CalcResultVo res = OwnHttpUtils.getBaseCalc(jsonPath,user.getNickName()); + // 3.2 通过打卡机拿到的记录去和差旅表、请假申请表、假期表做比对 + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() + .startedBy(String.valueOf(user.getUserId())) + .orderByProcessInstanceStartTime() + .desc(); + // 3.3 查询到他所有的任务 其中包括了差旅申请和请假申请的事 + List list = historicProcessInstanceQuery.list(); + for (HistoricProcessInstance historicProcessInstance : list) { + Deployment deployment = repositoryService.createDeploymentQuery() + .deploymentId(historicProcessInstance.getDeploymentId()).singleResult(); + // 这个deployment可以拿到他的分类信息 这里我需要的是 trip和absence + if (deployment.getCategory()=="absence" || deployment.getCategory()=="trip") { + TaskQuery taskQuery = taskService.createTaskQuery() + .taskCategory(deployment.getCategory()); + taskQuery.list().forEach(task -> { + Map processVariables = task.getProcessVariables(); + String startTime = String.valueOf(processVariables.get("startTime")); + String endTime = String.valueOf(processVariables.get("endTime")); + List timeRange = getDateRange(startTime, endTime); + if (deployment.getCategory().equals("absence")){ + // 这里的item为1时则为是上午 否则为下午 + Long startTimeItem = (Long) processVariables.get("startTimeItem"); + Long endTimeItem = (Long) processVariables.get("endTimeItem"); + } + // 计算缺席的某天是否请假或者出差 + List absentDates = res.getAbsentDates(); + List realDates = new ArrayList<>(); + List real05Dates = new ArrayList<>(); + for (String absentDate : absentDates) { + // 形如2024-11-01 + String fullDate = combineYearMonthAndDay(bo.getMonthStr(), absentDate); + boolean contains = timeRange.contains(fullDate); + // 如果为false 则说明此天没有请假或者出差则将其记录 + if (!contains) { + realDates.add(fullDate); + } + } + for (String real05Date : real05Dates) { + String fullDate = combineYearMonthAndDay(bo.getMonthStr(), real05Date); + boolean contains = timeRange.contains(fullDate); + if (!contains) { + real05Dates.add(fullDate); + } + } + // 这次已经将缺勤拿出来了 现在还要判断今天是否为节假日 + List realDate2 =new ArrayList<>(); + for (String realDate : realDates) { + SysOaHolidayVo sysOaHolidayVo = holidayService.queryHolidayByDate(StringToDate(realDate)); + if (sysOaHolidayVo != null && sysOaHolidayVo.getType()!=0 ) { + // 如果不为节假日则加入进去 + realDate2.add(realDate); + } + } + List real05Date2 =new ArrayList<>(); + for (String real05Date : real05Dates) { + SysOaHolidayVo sysOaHolidayVo = holidayService.queryHolidayByDate(StringToDate(real05Date)); + if (sysOaHolidayVo != null && sysOaHolidayVo.getType()!=0 ) { + // 如果不为节假日则加入进去 + real05Date2.add(real05Date); + } + + } + buildItemAbsent(realDate2, salary,1.0,yearMonth); + buildItemAbsent(real05Date2, salary,0.5,yearMonth); + }); + } + } + + // 3.4创建其他的item包括了好多罚金 + // 3.4.1 迟到罚金 + StringBuilder sb= new StringBuilder(); + for (String lateDate : res.getLateDates()) { + sb.append(lateDate); + sb.append(","); + } + sb.append("迟到日期"); + OaSalaryItem oaSalaryItem = new OaSalaryItem(); + oaSalaryItem.setSalaryId(salary.getSalaryId()); + oaSalaryItem.setPrice(Double.valueOf(res.getLateFee())); + oaSalaryItem.setType(4L); + oaSalaryItem.setFlag(0L); + oaSalaryItem.setReason(sb.toString()); + oaSalaryItem.setSignTime(yearMonth); + salaryItemMapper.insert(oaSalaryItem); + // 3.4.2 早退罚金 + sb= new StringBuilder(); + for (String lateDate : res.getLeaveEarly10Dates()) { + sb.append(lateDate); + sb.append(","); + } + sb.append("早退日期十分钟"); + for (String lateDate : res.getLeaveEarly30Dates()) { + sb.append(lateDate); + sb.append(","); + } + sb.append("早退日期三十分钟"); + oaSalaryItem = new OaSalaryItem(); + oaSalaryItem.setSalaryId(salary.getSalaryId()); + oaSalaryItem.setPrice(Double.valueOf(res.getLeaveEarlyFee())); + oaSalaryItem.setType(5L); + oaSalaryItem.setFlag(0L); + oaSalaryItem.setReason(sb.toString()); + oaSalaryItem.setSignTime(yearMonth); + salaryItemMapper.insert(oaSalaryItem); + // 3.4.3 打卡罚金 + sb= new StringBuilder(); + for (String lateDate : res.getLateDates()) { + sb.append(lateDate); + sb.append(","); + } + sb.append("未打卡"); + oaSalaryItem = new OaSalaryItem(); + oaSalaryItem.setSalaryId(salary.getSalaryId()); + oaSalaryItem.setPrice(Double.valueOf(res.getNotAttendanceFee())); + oaSalaryItem.setType(6L); + oaSalaryItem.setFlag(0L); + oaSalaryItem.setReason(sb.toString()); + oaSalaryItem.setSignTime(yearMonth); + salaryItemMapper.insert(oaSalaryItem); + } + + } + + + + private void buildItemAbsent(List realDate2, OaSalary salary,Double flag,Date yearMonth) { + // 最终这个为缺勤日期 + OaSalaryItem oaSalaryItem = new OaSalaryItem(); + StringBuilder sb = new StringBuilder(); + // 接下来将他拼接成一个字符串为扣款原因矿工问题 + for (String s : realDate2) { + sb.append(s); + sb.append(","); + } + if (flag>0.5){ + sb.append("旷工整天"); + }else{ + sb.append("旷工半天"); + } + oaSalaryItem.setType(3L); + oaSalaryItem.setReason(String.valueOf(sb)); + oaSalaryItem.setPrice(2* salary.getBaseSalary()* realDate2.size()*flag); + oaSalaryItem.setFlag(0L); + oaSalaryItem.setSignTime(yearMonth); + oaSalaryItem.setSalaryId(salary.getSalaryId()); + salaryItemMapper.insert(oaSalaryItem); + } + + /** + * 获取从 startTime 到 endTime(含首尾)的所有日期列表 + * + * @param startTime 字符串格式 "yyyy-MM-dd" 的开始日期 + * @param endTime 字符串格式 "yyyy-MM-dd" 的结束日期 + * @return 日期列表,每个元素形如 "yyyy-MM-dd" + */ + public static List getDateRange(String startTime, String endTime) { + // 1. 定义解析与输出格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + try { + // 2. 解析成 LocalDate + LocalDate startDate = LocalDate.parse(startTime, formatter); + LocalDate endDate = LocalDate.parse(endTime, formatter); + + // 若开始日期大于结束日期,则抛异常(也可根据需求改成自动调换顺序) + if (startDate.isAfter(endDate)) { + throw new IllegalArgumentException("开始日期不得晚于结束日期: " + + startTime + " > " + endTime); + } + + // 3. 循环遍历日期,加入列表 + List dateList = new ArrayList<>(); + LocalDate currentDate = startDate; + while (!currentDate.isAfter(endDate)) { + // 每次加入 "yyyy-MM-dd" 格式字符串 + dateList.add(currentDate.format(formatter)); + // 加 1 天 + currentDate = currentDate.plusDays(1); + } + + return dateList; + } catch (DateTimeParseException e) { + // 如果传入的日期字符串格式不对,抛出异常或自行处理 + throw new IllegalArgumentException("日期格式错误,要求 yyyy-MM-dd", e); + } + } + + + /** + * 将形如 "202411" (yyyyMM) 和 "11-04" (MM-dd) 拼装成 "2024-11-04" (yyyy-MM-dd) + * + * @param yearMonth 形如 "202411" 的字符串 (前4位为年份, 后2位为月份) + * @param monthDay 形如 "11-04" 的字符串 (前2位为月份, 后2位为天数) + * @return 拼装好的 "yyyy-MM-dd" + */ + private String combineYearMonthAndDay(String yearMonth, String monthDay) { + // 1. 拆解第一个参数: "202411" => 年 (2024), 月 (11) + String year = yearMonth.substring(0, 4); // "2024" + String monthFromYearMonth = yearMonth.substring(4, 6); // "11" + + // 2. 拆解第二个参数: "11-04" => 月 (11), 日 (04) + String[] parts = monthDay.split("-"); + if (parts.length != 2) { + throw new IllegalArgumentException("传入的 monthDay 格式不正确, 应形如 'MM-dd'。实际传入: " + monthDay); + } + String monthFromMonthDay = parts[0]; // "11" + String day = parts[1]; // "04" + + // 3. 校验两个“月”是否一致(可选) + if (!monthFromYearMonth.equals(monthFromMonthDay)) { + throw new IllegalArgumentException("yearMonth 与 monthDay 中的 '月' 不匹配: " + + monthFromYearMonth + " != " + monthFromMonthDay); + } + + // 4. 组合成 yyyy-MM-dd 格式 + return year + "-" + monthFromYearMonth + "-" + day; + } + + /** + * 将形如 "202411" (yyyyMM) 和 "11-04" (MM-dd) 拼装成 "2024-11-04" (yyyy-MM-dd) + * + * @param yearMonth 形如 "202411" 的字符串 (前4位为年份, 后2位为月份) + * @return 拼装好的 "yyyy-MM-dd" + */ + private String combineYearMonth(String yearMonth) { + // 1. 拆解第一个参数: "202411" => 年 (2024), 月 (11) + String year = yearMonth.substring(0, 4); // "2024" + String monthFromYearMonth = yearMonth.substring(4, 6); // "11" + // 4. 组合成 yyyy-MM-dd 格式 + return year + "-" + monthFromYearMonth; + } + + private Date StringToDate(String dateStr) { + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + // 1. 先解析成 LocalDateTime + LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter); + + // 2. 转换为 Instant(指定时区) + Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); + + // 3. 转换成旧版 Date + return Date.from(instant); + + } + + private String DateToString(Date date) { + // 2. 构造解析器,指定格式。例如 "yyyy-MM-dd" + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 3. 调用 parse() 将字符串转为 Date + + return sdf.format(date); + + } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaHolidayServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaHolidayServiceImpl.java index d0649c2..64881f7 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaHolidayServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaHolidayServiceImpl.java @@ -120,7 +120,7 @@ public class SysOaHolidayServiceImpl implements ISysOaHolidayService { @Override public SysOaHolidayVo queryHolidayByDate(Date date) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(SysOaHoliday::getHolidayTime, date); + lqw.like(SysOaHoliday::getHolidayTime, date); return baseMapper.selectVoOne(lqw); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/utils/OwnHttpUtils.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/utils/OwnHttpUtils.java new file mode 100644 index 0000000..bd361d6 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/utils/OwnHttpUtils.java @@ -0,0 +1,167 @@ +package com.ruoyi.oa.utils; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.oa.domain.vo.CalcResultVo; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +public class OwnHttpUtils { + + + + public static String getJsonName(String monthStr, String filePath) { + // 目标接口地址 + String jsonBody = String.format("{\"month_str\":\"%s\",\"file_path\":\"%s\"}", monthStr, filePath); + return getResult("dakaji_fenxi",jsonBody); + } + + + public static CalcResultVo getBaseCalc(String fileName, String personName) { + // 目标接口地址 + String jsonBody = String.format("{\"file_name\":\"%s\",\"person_name\":\"%s\"}", fileName, personName); + jsonBody = getResult("get_person_info",jsonBody); + System.out.println(jsonBody); + // 1. 将 JSON 字符串解析成 JSONObject + JSONObject jsonObject = JSON.parseObject(jsonBody); + + CalcResultVo calcResultVo = new CalcResultVo(); + // 2. 获取数值类型 + Long lateCount = jsonObject.getLong("迟到次数"); + calcResultVo.setLateCount(lateCount); + Long leaveEarly10Count = jsonObject.getLong("早退10分钟次数"); + Long leaveEarly30Count = jsonObject.getLong("早退30分钟次数"); + Long absentCount = jsonObject.getLong("旷工次数"); + Long absent05Count = jsonObject.getLong("旷工半天次数"); + Long notAttendance = jsonObject.getLong("未打卡次数"); + + + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray lateDatesArr = jsonObject.getJSONArray("迟到日期"); + if (lateDatesArr != null) { + // 如果想要 List 形式,可以这样: + List lateDates = lateDatesArr.toJavaList(String.class); + calcResultVo.setLateDates(lateDates); + } + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray leaveEarly10Dates = jsonObject.getJSONArray("早退10分钟日期"); + if (leaveEarly10Dates != null) { + // 如果想要 List 形式,可以这样: + List lateDates = leaveEarly10Dates.toJavaList(String.class); + calcResultVo.setLeaveEarly10Dates(lateDates); + } + + + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray leaveEarly30Dates = jsonObject.getJSONArray("早退30分钟日期"); + if (leaveEarly30Dates != null) { + // 如果想要 List 形式,可以这样: + List lateDates = leaveEarly30Dates.toJavaList(String.class); + calcResultVo.setLeaveEarly30Dates(lateDates); + } + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray absentDates = jsonObject.getJSONArray("旷工日期"); + if (absentDates != null) { + // 如果想要 List 形式,可以这样: + List lateDates = absentDates.toJavaList(String.class); + calcResultVo.setAbsentDates(lateDates); + } + + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray absent05Dates = jsonObject.getJSONArray("旷工半天日期"); + if (absent05Dates != null) { + // 如果想要 List 形式,可以这样: + List lateDates = absent05Dates.toJavaList(String.class); + calcResultVo.setAbsent05Dates(lateDates); + } + + // 3. 获取数组类型(列表),使用 getJSONArray 再转成 Java 的 List 或数组 + JSONArray notAttendanceDates = jsonObject.getJSONArray("未打卡日期"); + if (notAttendanceDates != null) { + // 如果想要 List 形式,可以这样: + List lateDates = notAttendanceDates.toJavaList(String.class); + calcResultVo.setNotAttendanceDates(lateDates); + } + + + // 例如获取 迟到罚金 + Long lateFee = jsonObject.getLong("迟到罚金"); + Long leaveEarlyFee = jsonObject.getLong("早退罚金"); + Long notAttendanceFee = jsonObject.getLong("打卡罚金"); + calcResultVo.setLateCount(lateCount); + calcResultVo.setLeaveEarly10Count(leaveEarly10Count); + calcResultVo.setLeaveEarly30Count(leaveEarly30Count); + calcResultVo.setAbsentCount(absentCount); + calcResultVo.setAbsent05Count(absent05Count); + calcResultVo.setNotAttendance(notAttendance); + calcResultVo.setLateFee(lateFee); + calcResultVo.setLeaveEarlyFee(leaveEarlyFee); + calcResultVo.setNotAttendanceFee(notAttendanceFee); + return calcResultVo; + } + + public static void main(String[] args) { + String fileName = "/home/ubuntu/lyq/fad_oa_kqdeal/202411.json"; + String personName = "丁苗松"; + String jsonBody = String.format("{\"file_name\":\"%s\",\"person_name\":\"%s\"}", fileName, personName); + + + + } + + + private static String getResult(String apiName, String jsonBody) { + try { + String baseUrl = "http://49.232.154.205:23108/"; + // 3. 打开连接 + URL url = new URL(baseUrl+apiName); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + // 4. 设置请求方式为 POST + connection.setRequestMethod("POST"); + + // 5. 设置请求头 Content-Type: application/json + connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + + // 允许写输出流 + connection.setDoOutput(true); + + // 6. 通过输出流发送 JSON 请求体 + try (OutputStream os = connection.getOutputStream()) { + byte[] input = jsonBody.getBytes("UTF-8"); + os.write(input, 0, input.length); + } + + // 7. 获取响应码 + int responseCode = connection.getResponseCode(); + System.out.println("Response Code : " + responseCode); + + // 8. 如果响应成功(200),读取响应体 + if (responseCode == HttpURLConnection.HTTP_OK) { + try (BufferedReader br = new BufferedReader( + new InputStreamReader(connection.getInputStream(), "UTF-8"))) { + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine); + } + connection.disconnect(); + return response.toString(); + } + } else { + System.out.println("Request failed. Response code: " + responseCode); + connection.disconnect(); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/ruoyi-oa/src/main/resources/mapper/oa/EmployeeOnboardingMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/EmployeeOnboardingMapper.xml index 867da05..4d29795 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/EmployeeOnboardingMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/EmployeeOnboardingMapper.xml @@ -31,18 +31,17 @@ - update employee_onboarding - id_photo = #{idPhoto}, - joining_date = #{joiningDate}, + id_photo = #{idPhoto}, + joining_date = #{joiningDate}, manager_id = #{managerId}, highest_degree = #{highestDegree}, remark = #{remark}, del_flag = #{delFlag}, birth_date = #{birthDate}, ethnicity = #{ethnicity}, - confirm_date = #{confirmDate}, + confirm_date = #{confirmDate}, status = #{status}, marital_status = #{maritalStatus}, political_status = #{politicalStatus}, @@ -79,6 +78,7 @@ - SELECT + SELECT os.salary_id, os.user_id, os.pay_time, os.base_salary, - (os.base_salary * DAY(LAST_DAY(#{payTime})) + - COALESCE(SUM(CASE - WHEN osi.flag = 1 THEN osi.price - WHEN osi.flag = 0 AND osi.type = 3 THEN -2 * osi.price - WHEN osi.flag = 0 THEN -osi.price - ELSE 0 - END), 0) - ) AS real_salary, + ( + os.base_salary * DAY(LAST_DAY(#{payTime})) + + COALESCE(SUM( + CASE + WHEN osi.flag = 1 THEN osi.price + WHEN osi.flag = 0 THEN -osi.price + ELSE 0 + END + ), 0) + ) AS real_salary, osi.salary_item_id, osi.sign_time, su.nick_name - FROM oa_salary os - LEFT JOIN oa_salary_item osi ON osi.salary_id = os.salary_id + FROM oa_salary os + LEFT JOIN oa_salary_item osi + ON osi.salary_id = os.salary_id AND YEAR(osi.sign_time) = YEAR(#{payTime}) AND MONTH(osi.sign_time) = MONTH(#{payTime}) - LEFT JOIN sys_user su on os.user_id = su.user_id - WHERE YEAR(os.pay_time) = YEAR(#{payTime}) - AND MONTH(os.pay_time) = MONTH(#{payTime}) - GROUP BY os.salary_id, os.user_id, os.pay_time, os.base_salary, osi.salary_item_id, osi.type, osi.reason, osi.price, osi.sign_time; - ${ew.getCustomSqlSegment} + LEFT JOIN sys_user su ON os.user_id = su.user_id + + + + YEAR(os.pay_time) = YEAR(#{payTime}) + AND MONTH(os.pay_time) = MONTH(#{payTime}) + + + + AND ${ew.customSqlSegment} + + + + GROUP BY + os.salary_id, + os.user_id, + os.pay_time, + os.base_salary, + osi.salary_item_id, + osi.type, + osi.reason, + osi.price, + osi.sign_time + + + + diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development index 20b1ce2..5abea97 100644 --- a/ruoyi-ui/.env.development +++ b/ruoyi-ui/.env.development @@ -5,8 +5,8 @@ VUE_APP_TITLE = 福安德综合办公系统 ENV = 'development' # 若依管理系统/开发环境 -# VUE_APP_BASE_API = '/prod-api' -VUE_APP_BASE_API = 'http://110.41.139.73:8080' +VUE_APP_BASE_API = '/prod-api' +# VUE_APP_BASE_API = 'http://110.41.139.73:8080' # 应用访问路径 例如使用前缀 /admin/ VUE_APP_CONTEXT_PATH = '/' diff --git a/ruoyi-ui/src/views/components/ClaimDetail/index.vue b/ruoyi-ui/src/views/components/ClaimDetail/index.vue index 7341c2b..818b8fb 100644 --- a/ruoyi-ui/src/views/components/ClaimDetail/index.vue +++ b/ruoyi-ui/src/views/components/ClaimDetail/index.vue @@ -6,7 +6,7 @@
-

差旅费报销申请单

+

报销申请单

diff --git a/ruoyi-ui/src/views/oa/apply/trip/index.vue b/ruoyi-ui/src/views/oa/apply/trip/index.vue new file mode 100644 index 0000000..98de25a --- /dev/null +++ b/ruoyi-ui/src/views/oa/apply/trip/index.vue @@ -0,0 +1,329 @@ + + + diff --git a/ruoyi-ui/src/views/oa/claim/add.vue b/ruoyi-ui/src/views/oa/claim/add.vue index ece98c3..5dc9804 100644 --- a/ruoyi-ui/src/views/oa/claim/add.vue +++ b/ruoyi-ui/src/views/oa/claim/add.vue @@ -5,7 +5,7 @@
-

差旅费报销申请单

+

报销申请单

提交 diff --git a/ruoyi-ui/src/views/oa/claim/detail.vue b/ruoyi-ui/src/views/oa/claim/detail.vue index 02e0e6c..7579b5c 100644 --- a/ruoyi-ui/src/views/oa/claim/detail.vue +++ b/ruoyi-ui/src/views/oa/claim/detail.vue @@ -71,7 +71,7 @@
-

差旅费报销申请单

+

报销申请单

diff --git a/ruoyi-ui/src/views/oa/claim/index.vue b/ruoyi-ui/src/views/oa/claim/index.vue index 4e5e43a..745cc21 100644 --- a/ruoyi-ui/src/views/oa/claim/index.vue +++ b/ruoyi-ui/src/views/oa/claim/index.vue @@ -299,7 +299,7 @@ export default { this.loading = false; this.form = response.data; this.open = true; - this.title = "修改差旅费报销"; + this.title = "修改报销"; }); }, /** 提交按钮 */ @@ -330,7 +330,7 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const claimIds = row.claimId || this.ids; - this.$modal.confirm('是否确认删除差旅费报销编号为"' + claimIds + '"的数据项?').then(() => { + this.$modal.confirm('是否确认删除报销编号为"' + claimIds + '"的数据项?').then(() => { this.loading = true; return delOaClaim(claimIds); }).then(() => {