活动介绍

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(StringUtils.hasLength(username),User::getUsername,username); wrapper.eq(StringUtils.hasLength(phone),User::getPhone,phone); wrapper.orderByDesc(User::getId);

时间: 2024-04-10 18:31:56 浏览: 68
这段代码使用了 MyBatis-Plus 的 LambdaQueryWrapper 来构建一个查询条件。其中,LambdaQueryWrapper 是一个查询条件的封装类,用于快速构建查询条件。 在这段代码中,首先创建了一个 LambdaQueryWrapper 对象 wrapper,并且没有指定查询的实体类类型,即 User 类。接着使用 eq 方法来添加查询条件,eq 方法的参数依次为:条件是否生效、实体类字段对应的属性表达式、要匹配的值。这里使用了 StringUtils.hasLength 方法来判断传入的 username 和 phone 是否为空,如果不为空,则将对应的查询条件添加到 wrapper 中。 最后,使用 orderByDesc 方法来设置按照 User 实体类中的 id 字段进行降序排序。 这段代码的作用是构建一个根据 username 和 phone 进行查询,并按照 id 字段进行降序排序的查询条件。
相关问题

QueryWrapper<UserVehicle> wrapper = new QueryWrapper<>();这一句是什么意思

<think>好的,我现在要帮助用户理解“QueryWrapper<UserVehicle> wrapper = new QueryWrapper<>();”这行代码的含义。用户之前的问题是关于如何将参数传递改为DTO,现在转向了MyBatis-Plus的QueryWrapper。 首先,我需要确定用户的基础知识。用户可能对MyBatis-Plus有一定了解,但可能不熟悉QueryWrapper的具体用法。用户之前的问题涉及Spring MVC和Service层的代码,所以可能在使用Spring Boot和MyBatis-Plus进行开发。 接下来,我需要解析这行代码的各个部分。QueryWrapper是MyBatis-Plus中的类,用于构建查询条件。泛型<UserVehicle>指定了实体类,这样Wrapper知道操作哪个表。创建实例后,用户可以通过链式调用添加条件,比如eq、like等。 然后,要思考用户为什么会问这个问题。用户可能在Service层代码中看到QueryWrapper的使用,或者在师傅的指导下进行改造,需要理解这行代码的作用。用户可能想要了解如何构建动态查询,或者为什么使用Wrapper而不是其他方式。 用户的需求可能不仅仅是了解这行代码的字面意思,而是想理解其背后的设计模式和优势。比如,QueryWrapper如何简化SQL编写,提高可维护性,或者如何与DTO结合使用。此外,用户可能希望知道实际应用中的例子,比如如何添加不同的查询条件。 还要考虑用户可能的后续问题,比如QueryWrapper与LambdaQueryWrapper的区别,或者如何结合分页使用。因此,在回答时需要涵盖这些扩展点,帮助用户建立全面的理解。 最后,要确保语言通俗易懂,避免过多的技术术语,同时提供示例代码,让用户能够直观看到如何使用QueryWrapper构建查询条件。这样用户不仅能理解概念,还能应用到实际项目中。</think>让我们用通俗易懂的方式解析`QueryWrapper<UserVehicle> wrapper = new QueryWrapper<>();`这行代码: --- ### **代码含义解析** ```java QueryWrapper<UserVehicle> wrapper = new QueryWrapper<>(); ``` 1. **`QueryWrapper`** - 是MyBatis-Plus框架提供的查询条件构造器 - 作用类似SQL语句中的WHERE子句 - 通过链式调用方法动态构建查询条件 2. **`<UserVehicle>`** - 泛型参数,指定操作的实体类 - 会自动映射到数据库表(需配合`@TableName`注解) 3. **`new QueryWrapper<>()`** - 创建具体实例对象 - 后续通过该对象添加查询条件 --- ### **实际应用场景** 假设要查询`user_vehicle`表中满足以下条件的记录: ```sql WHERE user_name LIKE '%张%' AND vin = 'LSVNV133X2H000001' AND create_time > '2023-01-01' ``` 对应Java代码实现: ```java wrapper.like("user_name", "张") // 模糊查询 .eq("vin", "LSVNV133X2H000001") // 等值查询 .gt("create_time", LocalDate.of(2023,1,1)); // 大于条件 ``` --- ### **核心优势** 1. **类型安全** - 相比拼接字符串,避免SQL注入风险 - 示例对比: ```java // ❌ 危险方式 String sql = "WHERE user_name = '" + input + "'"; // ✅ 安全方式 wrapper.eq("user_name", input); ``` 2. **链式编程** ```java wrapper.select("id", "user_name") // 指定查询字段 .like("vin", "ABC") .orderByDesc("create_time"); ``` 3. **动态条件构建** ```java if (StringUtils.isNotBlank(dto.getVin())) { wrapper.eq("vin", dto.getVin()); } ``` --- ### **扩展知识:Wrapper家族** | 类型 | 特点 | 适用场景 | |---------------------|------------------------------|--------------------------| | `QueryWrapper` | 普通条件构造器 | 常规查询条件拼接 | | `LambdaQueryWrapper`| 使用lambda表达式引用字段 | 避免字段名硬编码 | | `UpdateWrapper` | 包含SET语句的条件构造器 | 更新操作时使用 | **Lambda版本示例**: ```java LambdaQueryWrapper<UserVehicle> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.like(UserVehicle::getUserName, "张") // 通过方法引用指定字段 .eq(UserVehicle::getVin, "LSVNV133X2H000001"); ``` --- ### **最佳实践建议** 1. **与DTO结合使用** ```java public List<UserVehicle> queryByDto(VehicleQueryDto dto) { QueryWrapper<UserVehicle> wrapper = new QueryWrapper<>(); if (dto.getMinPrice() != null) { wrapper.ge("price", dto.getMinPrice()); // ge=greater or equal } return mapper.selectList(wrapper); } ``` 2. **分页查询组合** ```java Page<UserVehicle> page = new Page<>(1, 10); // 第1页,每页10条 Page<UserVehicle> result = mapper.selectPage(page, wrapper); ``` 3. **复杂条件支持** ```java wrapper.nested(w -> w .like("user_name", "张") .or() .isNull("dept_name") ) .between("mileage", 1000, 5000); ```

详细解释一下这段代码 public ApiResult<PageInfo<CheckPlan>> getCheckPlanList(@RequestBody QueryPage<CheckPlanDetailVo> queryPage){ CheckPlanDetailVo checkPlan = queryPage.getQuery(); PageHelper.startPage(checkPlan.getPageNum(),checkPlan.getPageSize()); LambdaQueryWrapper<CheckPlan> lambda = new QueryWrapper<CheckPlan>().lambda(); if(checkPlan!=null){ if(!StringUtils.isEmpty(checkPlan.getFarmName())){ lambda.like(CheckPlan::getFarmName,checkPlan.getFarmName()); } if(!StringUtils.isEmpty(checkPlan.getFarmCode())){ lambda.like(CheckPlan::getFarmCode,checkPlan.getFarmCode()); } if(!StringUtils.isEmpty(checkPlan.getRegion())){ lambda.like(CheckPlan::getRegion,checkPlan.getRegion()); } if(!StringUtils.isEmpty(checkPlan.getCheckStatus())){ lambda.eq(CheckPlan::getCheckStatus,checkPlan.getCheckStatus()); } if(!StringUtils.isEmpty(checkPlan.getStage())){ lambda.like(CheckPlan::getStage,checkPlan.getStage()); } if(!StringUtils.isEmpty(checkPlan.getUserName()) && null != checkPlan.getFlag() && 1 == checkPlan.getFlag()){ lambda.and(e-> e.eq(CheckPlan::getUserName,checkPlan.getUserName()).or().eq(CheckPlan::getCreatePerson,checkPlan.getCreatePerson())); } } lambda.eq(CheckPlan::getMarkForDelete,0); lambda.orderByDesc(CheckPlan::getCreateTime); List<CheckPlan> checkPlanList = checkPlanService.list(lambda); return ApiResult.ok(PageInfo.of(checkPlanList)); }

这段代码是一个Java Spring Boot框架中的Controller方法,用于获取检查计划列表。该方法接收一个QueryPage对象作为参数,该对象包含一个CheckPlanDetailVo对象,用于封装查询条件和分页信息。具体流程如下: 1. 获取QueryPage对象中封装的CheckPlanDetailVo对象 2. 使用PageHelper.startPage()方法设置分页信息,包括页码和每页大小 3. 使用LambdaQueryWrapper构造查询条件,判断CheckPlanDetailVo对象中的属性是否为空或为null,如果不为空,则添加相应的查询条件 4. 添加一个标记为删除的查询条件,过滤掉已经被删除的记录 5. 按照创建时间倒序排列结果集 6. 调用checkPlanService的list()方法执行查询,获取检查计划列表 7. 将查询结果封装到ApiResult中,并使用PageInfo.of()方法包装分页信息,返回给调用方。 总体来说,这段代码使用了LambdaQueryWrapper实现了灵活的条件查询,并使用PageHelper和PageInfo实现了分页查询。
阅读全文

相关推荐

private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) { Map<String, Object> params = user.getParams(); QueryWrapper<SysUser> wrapper = Wrappers.query(); wrapper.eq("u.del_flag", SystemConstants.NORMAL) .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId()) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) .between(params.get("beginTime") != null && params.get("endTime") != null, "u.create_time", params.get("beginTime"), params.get("endTime")) .and(ObjectUtil.isNotNull(user.getDeptId()), w -> { List<SysDept> deptList = deptMapper.selectListByParentId(user.getDeptId()); List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId); ids.add(user.getDeptId()); w.in("u.dept_id", ids); }).eq(ObjectUtil.isNotNull(user.getGrade()),"eu.grade",user.getGrade()) .eq(ObjectUtil.isNotNull(user.getMajor()),"eu.major",user.getMajor()) .eq(ObjectUtil.isNotNull(user.getWestchinaExperience()),"eu.westchinaExperience",user.getWestchinaExperience()) .eq(ObjectUtil.isNotNull(user.getConfirmStatus()),"eu.confirmStatus",user.getConfirmStatus()) .eq(ObjectUtil.isNotNull(user.getSource()),"eu.source",user.getSource()) .and(ObjectUtil.isNotNull(user.getKeyWord()),k->{ }) .orderByDesc("u.create_time"); if (StringUtils.isNotBlank(user.getExcludeUserIds())) { wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong)); } return wrapper; } 这是我的sql,我想判断当keyWord不为空的时候,模糊查询姓名,手机号,年级,专业这几个字段

public Boolean importMaterial(MultipartFile excel/*,String selectedCompanyName*/) throws IOException { Workbook workbook; UserContext.UserInfo currentUserInfo = UserContext.getCurrentUserInfo(); String currentUserName = null == currentUserInfo ? null : currentUserInfo.getUserName(); try { File file = multiPartFileToFile2(excel); FileInputStream excelFile = new FileInputStream(file); workbook = new XSSFWorkbook(excelFile); Sheet sheet = workbook.getSheetAt(0); Project project = new Project(); project.setCreatedTime(ZonedDateTime.now(ZoneId.of("UTC"))); project.setUpdatedTime(ZonedDateTime.now(ZoneId.of("UTC"))); project.setCreatedBy(StringUtils.isBlank(project.getCreatedBy()) ? currentUserName : project.getCreatedBy()); project.setUpdatedBy(StringUtils.isBlank(project.getUpdatedBy()) ? currentUserName : project.getUpdatedBy()); //project.setCompany_name(selectedCompanyName); project.setIs_ask(IsAskEnum.待审批); List<MaterialApply> materialApplyList = new ArrayList<>(); boolean projectDataFound = false; boolean materialDataFound = false; for (Row row : sheet) { if (!projectDataFound) { if (isDataRow(row, 0, "申请单号:")) { project.setId(UniqueIdGenerator.generateUniqueId()); extractProjectData(row, project); projectDataFound = true; } } else { if (isDataRow(row, 1, "物料编码")) { materialDataFound = true; continue; } if (materialDataFound && isMaterialDataRow(row)) { MaterialApply materialApply = new MaterialApply(); materialApply.setId(UniqueIdGenerator.generateUniqueId()); materialApply.setProject_id(project.getId()); materialApply.setRequest_no(project.getRequest_no()); materialApply.setData_from("Excel导入"); materialApply.setCreated_by(StringUtils.isBlank(materialApply.getCreated_by()) ? currentUserName : materialApply.getCreated_by()); materialApply.setUpdated_by(StringUtils.isBlank(materialApply.getUpdated_by()) ? currentUserName : materialApply.getUpdated_by()); extractMaterialData(row, materialApply); materialApplyList.add(materialApply); //handleItemcode(materialApply.getMaterial_code()); } else if (isDataRow(row, 0, "下单原因")) { String applyReason = getCellStringValue(row, 2); project.setApply_reason(applyReason); break; // 假设下单原因之后没有更多数据 } } } workbook.close(); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("request_no", project.getRequest_no()); queryWrapper.eq("is_del", 0); boolean equals = projectService.exists(queryWrapper); if (equals){ throw new RuntimeException("申请单号已存在"); } //保存申请单数据 projectService.save(project); //保存物料申请单数据 boolean savedBatch = materialApplyService.saveBatch(materialApplyList); List<MultipartFile> excels = new ArrayList<>(); excels.add(excel); SendApproved(project, excels); return savedBatch; } catch (Exception e) { throw new RuntimeException(e); } }

这是我通过查询的一条数据 "comps": [ { "dataCreator": null, "dataCreatorName": null, "dataCreateon": null, "dataMender": null, "dataMenderName": null, "dataModifyon": null, "deviceCompId": null, "deviceId": 36, "componentNo": null, "componentName": null, "spec": null, "unitPrice": null, "qty": null, "amount": null, "vendor": null, "vendorContact": null, "vendorTel": null, "buyDate": null, "useDate": null, "lastMaintainDate": null, "maintainPeriodDay": null, "status": null, "remark": null } ], 代码如下 @Override public MPJLambdaWrapper<DeviceMaster> buildQueryWrapper(DeviceMaster bo) { MPJLambdaWrapper<DeviceMaster> lqw = JoinWrappers.lambda(DeviceMaster.class).selectAll(DeviceMaster.class) .selectCollection(DeviceMasterComp.class,DeviceMaster::getComps) .selectCollection(DeviceMasterAtt.class,DeviceMaster::getAtts) .selectCollection(DeviceMasterDtl.class,DeviceMaster::getDtls) .selectCollection(DeviceMasterItem.class,DeviceMaster::getItems); return appendQueryWrapper(lqw, bo); } private MPJLambdaWrapper<DeviceMaster> appendQueryWrapper(MPJLambdaWrapper<DeviceMaster> lqw, DeviceMaster bo) { lqw.leftJoin(DeviceMasterComp.class,DeviceMasterComp::getDeviceId,DeviceMaster::getDeviceId) .leftJoin(DeviceMasterAtt.class,DeviceMasterAtt::getDeviceId,DeviceMaster::getDeviceId) .leftJoin(DeviceMasterDtl.class,DeviceMasterDtl::getDeviceId,DeviceMaster::getDeviceId) .leftJoin(DeviceMasterItem.class,DeviceMasterItem::getDeviceId,DeviceMaster::getDeviceId); ConditionUtil.appendDateQueryCondition(lqw,bo.getParams(), DeviceMaster.class); lqw.in(CollectionUtil.isNotEmpty(bo.getIds()), DeviceMaster::getDeviceId, bo.getIds()); lqw.eq(bo.getDeviceId() != null, DeviceMaster::getDeviceId, bo.getDeviceId()); lqw.eq(bo.getCoId() != null, DeviceMaster::getCoId, bo.getCoId()); lqw.eq(StringUtils.isNotBlank(bo.getDeviceNo()), DeviceMaster::getDeviceNo, bo.getDeviceNo()); lqw.eq(bo.getDeviceTypeId()!=null, DeviceMaster::getDeviceTypeId, bo.getDeviceTypeId()); lqw.like(StringUtils.isNotBlank(bo.getName()), DeviceMaster::getName, bo.getName()); lqw.eq(StringUtils.isNotBlank(bo.getSpec()), DeviceMaster::getSpec, bo.getSpec()); lqw.eq(bo.getVendor() != null, DeviceMaster::getVendor, bo.getVendor()); lqw.eq(bo.getVendorContact() != null, DeviceMaster::getVendorContact, bo.getVendorContact()); lqw.eq(bo.getVendorTel() != null, DeviceMaster::getVendorTel, bo.getVendorTel()); lqw.eq(bo.getUnitPrice() != null, DeviceMaster::getUnitPrice, bo.getUnitPrice()); lqw.eq(bo.getQty() != null, DeviceMaster::getQty, bo.getQty()); lqw.eq(bo.getAmount() != null, DeviceMaster::getAmount, bo.getAmount()); lqw.eq(bo.getDepreciationAmount()!=null, DeviceMaster::getDepreciationAmount, bo.getDepreciationAmount()); lqw.eq(bo.getMaintainPeriodDay()!=null, DeviceMaster::getMaintainPeriodDay, bo.getMaintainPeriodDay()); lqw.eq(bo.getStatus()!=null, DeviceMaster::getStatus, bo.getStatus()); lqw.eq(bo.getDepartmentId()!=null, DeviceMaster::getDepartmentId, bo.getDepartmentId()); lqw.eq(bo.getKeepWorkerId()!=null, DeviceMaster::getKeepWorkerId, bo.getKeepWorkerId()); lqw.eq(bo.getUserWorkerId()!=null, DeviceMaster::getUserWorkerId, bo.getUserWorkerId()); lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), DeviceMaster::getWarehouse, bo.getWarehouse()); lqw.eq(StringUtils.isNotBlank(bo.getKeeperName()), DeviceMaster::getKeeperName, bo.getKeeperName()); lqw.eq(StringUtils.isNotBlank(bo.getUserName()), DeviceMaster::getUserName, bo.getUserName()); lqw.eq(StringUtils.isNotBlank(bo.getAccountCardNo()), DeviceMaster::getAccountCardNo, bo.getAccountCardNo()); lqw.eq(StringUtils.isNotBlank(bo.getEquipmentNo()), DeviceMaster::getEquipmentNo, bo.getEquipmentNo()); lqw.orderByAsc(DeviceMaster::getDeviceTypeId); return lqw; } 我初步判断是这个映射的问题,而且只有就是第一个使用selectCollection的才有这个问题,而其他后天的就没有问题,但是调换顺序后,出问题的就是那第一个的,并且我通过查询原始sql,看到原始数据,发现查询出来的数据是好的

优化以下Java代码: public JSONObject createAttendanceUserSalary(String attendanceMonth,User opUser,Dto dto) throws Exception { JSONObject json = new JSONObject(); String msg = ""; //查询对应月份的所有有效的考勤记录 Dto pDto = Dtos.newDto(); pDto.put("attendanceMonth", attendanceMonth); pDto.put("deleteFlag", IMSCons.DELETE_FLAG_NO); pDto.putAll(dto); List<UserAttendance> attendanceList = userAttendanceMapper.list(pDto); if(attendanceList == null || attendanceList.size() <= 0) { json.put("msg", "对应月份["+attendanceMonth+"]考勤记录不存在!"); json.put("result", false); return json; } //查询考勤规则判断考勤规则是否存在 EntityWrapper<UserAttendanceSetting> settingWrapper = new EntityWrapper<UserAttendanceSetting>(); settingWrapper.eq("status", IMSCons.STATUSIS.YES); List<UserAttendanceSetting> settingList= userAttendanceSettingMapper.selectList(settingWrapper); if(settingList == null || settingList.size() <= 0) { json.put("msg", "考勤规则未设置!"); json.put("result", false); return json; } // 以80条为基准为一个线程处理 // 1.使用集合切割工具类分割需要处理的数组 List> groupList = CollectionUtils.partition(attendanceList, 67); CountDownLatch countDownLatch = new CountDownLatch(groupList.size()); ExecutorService executorService = Executors.newFixedThreadPool(groupList.size()); List<Future<String>> resultMsg = new ArrayList<Future<String>>(); //2.使用 Callable 接口创建一个匿名线程,并且使用线程池的线程启动 // 使用pool.submit将线程放入线程池中执行 for (int i = 0; i < groupList.size(); i++) { int finalI = i; Future<String> returnMsg = executorService.submit(new Callable<String>() { @Override public String call() throws Exception { String resultMsg = ""; //每月平均工作天数 BigDecimal workDayOfMonth = new BigDecimal(21.75); Dto pDto2 = Dtos.newDto(); List<UserAttendance> excutorList = groupList.get(finalI); for (UserAttendance data : excutorList) { // 业务内容,你需要对每个对象做的处理 pDto2 = Dtos.newDto(); pDto2.put("userId", data.getUserId()); pDto2.put("isDel", IMSCons.WHETHER_NO); List<User> userList = userMapper.listUser(pDto2); if(userList == null || userList.size() <= 0) { if (StringUtils.isBlank(resultMsg)) { resultMsg = "Excel中[" + data.getUserName() + "]员工不存在"; } else { resultMsg = resultMsg + ",[" + data.getUserName() + "]员工不存在"; } continue; } User user = userList.get(0); BigDecimal overtimePay = BigDecimal.ZERO; BigDecimal weekendOvertimePay = BigDecimal.ZERO; BigDecimal holidayOvertimePay = BigDecimal.ZERO; BigDecimal mealAllowance = BigDecimal.ZERO; BigDecimal absenteeismDeduction = BigDecimal.ZERO; BigDecimal cardMissingDeduction = BigDecimal.ZERO; BigDecimal casualLeaveDeduction = BigDecimal.ZERO; BigDecimal sickLeaveDeduction = BigDecimal.ZERO; BigDecimal longSickLeaveDeduction = BigDecimal.ZERO; BigDecimal commuterAllowanceDeduction = BigDecimal.ZERO; BigDecimal lessThanFull = BigDecimal.ZERO; BigDecimal fixedSubsidyDeduction = BigDecimal.ZERO; //遍历所有有效的考勤规则并获取考勤规则对应的费用金额 for(UserAttendanceSetting setting : settingList) { pDto2 = Dtos.newDto(); pDto2.put("attendanceSettingId", setting.getId()); pDto2.put("status", IMSCons.STATUSIS.YES); List<UserAttendanceSettingDetail> detailList = userAttendanceSettingDetailMapper.list(pDto2); if(detailList == null || detailList.size() <= 0) { if (StringUtils.isBlank(resultMsg)) { resultMsg = "考勤规则[" + setting.getAttendanceType() + "]对应的明细不存在"; } else { resultMsg = resultMsg + ",考勤规则[" + setting.getAttendanceType() + "]对应的明细不存在"; } return resultMsg; } //不同费用规则的数据明细获取,副经理级别以下的员工有加班费 if(setting.getAttendanceType().equals("加班费") && (user.getJobTitle().equals("助理") || user.getJobTitle().equals("专员") || user.getJobTitle().equals("资深专员") || user.getJobTitle().equals("主管"))) { for(UserAttendanceSettingDetail detal : detailList) { String location = detal.getLocation(); if(StringUtils.isNotBlank(user.getAddress()) && user.getAddress().contains(location)) { //判断当前员工是否是排除在外的,排除在外的员工所有费用为0 EntityWrapper<UserAttendanceSettingUser> settingUserWrapper = new EntityWrapper<UserAttendanceSettingUser>(); settingUserWrapper.eq("attendance_setting_id", setting.getId()); settingUserWrapper.eq("user_id", user.getUserId()); int settingUserCount = userAttendanceSettingUserMapper.selectCount(settingUserWrapper); if(settingUserCount <= 0) { overtimePay = data.getWorkingDayOvertime().multiply(detal.getNormalCalculationUnit()); weekendOvertimePay = data.getRestDaysOvertime().multiply(detal.getWeekendCalculationUnit()); holidayOvertimePay = data.getHolidayOvertime().multiply(detal.getHolidayCalculationUnit()); } break; } } }else if(setting.getAttendanceType().equals("门卫加班费")) { for(UserAttendanceSettingDetail detal : detailList) { String location = detal.getLocation(); if(user.getPosition().contains(location)) { weekendOvertimePay = data.getOtherRestDaysOvertime().multiply(detal.getWeekendCalculationUnit()); holidayOvertimePay = data.getOtherHolidayOvertime().multiply(detal.getHolidayCalculationUnit()); break; } } }else if (setting.getAttendanceType().equals("餐贴") || setting.getAttendanceType().equals("太仓餐贴")) { //不同费用规则的数据明细获取,副经理级别以下的员工有餐贴 if(user.getJobTitle().equals("助理") || user.getJobTitle().equals("专员") || user.getJobTitle().equals("资深专员") || user.getJobTitle().equals("主管")){ for(UserAttendanceSettingDetail detal : detailList) { //判断当前员工是否是排除在外的,排除在外的员工所有费用为0 EntityWrapper<UserAttendanceSettingUser> settingUserWrapper = new EntityWrapper<UserAttendanceSettingUser>(); settingUserWrapper.eq("attendance_setting_id", setting.getId()); settingUserWrapper.eq("user_id", user.getUserId()); int settingUserCount = userAttendanceSettingUserMapper.selectCount(settingUserWrapper); if(settingUserCount <= 0) { mealAllowance = new BigDecimal(data.getMealAllowanceTimes()).multiply(detal.getNormalCalculationUnit()); } break; } } }else if (setting.getAttendanceType().equals("当月新进未满整月")) { //先判断如果是工作日结果加1,如果是节假日判断是不是国庆节(1号、2号、3号)加1,判断是不是春节三天(初三、初一、初二)加1 //除了春节和国庆计算3天,其他假期要判断节假日开始的第一天是不是在星期一至星期五的其中一天,如果在结果加1,不在不计算 String firstDayOfMonth = IMSUtil.getFirstDayOfMonth(IMSUtil.date2String(data.getFirstAttendanceDate(), "yyyy-MM-dd")); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); if(firstDayOfMonth!=null && month == 10) { String monthStr = firstDayOfMonth.split("-")[1]; if(monthStr.equals("09")) { firstDayOfMonth = year+"-09-26"; } } int daysBetween = IMSUtil.daysBetween(IMSUtil.stringToDate(firstDayOfMonth), user.getEntryDate()); if(daysBetween > 0) { boolean sameMonth = IMSUtil.isSameMonth(user.getEntryDate(), IMSUtil.stringToDate(firstDayOfMonth)); int missingDays = 0; int holiday = 0; for (int j = 0; j < daysBetween; j++) { String addDate = IMSUtil.addDate(firstDayOfMonth, j); String result = HolidayUtil.holidayCheck(IMSUtil.stringToDate(addDate)); //判断是不是工作日,工作日结果加1;节假日中除了春节、国庆结果加3之外,判断节假日的开始第一天是不是在星期六之前,在星期六之前结果加1 if(result.equals("0")) { ++missingDays; }else if(result.equals("2")) { String lackResult = HolidayUtil.lackDayCheck(IMSUtil.stringToDate(addDate)); if (lackResult.equals("1")) { ++missingDays; } } } String lastMonth = IMSUtil.getLastDateWithStr(firstDayOfMonth,0); if(sameMonth) { lastMonth = IMSUtil.getLastDateWithStr(firstDayOfMonth,1); } EntityWrapper<UserSalary> userSalaryWrapper = new EntityWrapper<UserSalary>(); userSalaryWrapper.eq("salary_date", lastMonth); userSalaryWrapper.eq("user_id", user.getUserId()); userSalaryWrapper.eq("delete_flag", IMSCons.DELETE_FLAG_NO); List<UserSalary> salaryList = userSalaryMapper.selectList(userSalaryWrapper); if(salaryList != null && salaryList.size() > 0) { lessThanFull = salaryList.get(0).getJobWage() .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(new BigDecimal(missingDays)); } } }else if (setting.getAttendanceType().equals("新进人员固定补贴扣款")) { //先判断如果是工作日结果加1,如果是节假日判断是不是国庆节(1号、2号、3号)加1,判断是不是春节三天(初三、初一、初二)加1 //除了春节和国庆计算3天,其他假期要判断节假日开始的第一天是不是在星期一至星期五的其中一天,如果在结果加1,不在不计算 String firstDayOfMonth = IMSUtil.getFirstDayOfMonth(IMSUtil.date2String(data.getFirstAttendanceDate(), "yyyy-MM-dd")); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); if(firstDayOfMonth!=null && month == 10) { String monthStr = firstDayOfMonth.split("-")[1]; if(monthStr.equals("09")) { firstDayOfMonth = year+"-09-26"; } } int daysBetween = IMSUtil.daysBetween(IMSUtil.stringToDate(firstDayOfMonth), user.getEntryDate()); if(daysBetween > 0) { boolean sameMonth = IMSUtil.isSameMonth(user.getEntryDate(), IMSUtil.stringToDate(firstDayOfMonth)); int missingDays = 0; int holiday = 0; for (int j = 0; j < daysBetween; j++) { String addDate = IMSUtil.addDate(firstDayOfMonth, j); String result = HolidayUtil.holidayCheck(IMSUtil.stringToDate(addDate)); //判断是不是工作日,工作日结果加1;节假日中除了春节、国庆结果加3之外,判断节假日的开始第一天是不是在星期六之前,在星期六之前结果加1 if(result.equals("0")) { ++missingDays; }else if(result.equals("2")) { String lackResult = HolidayUtil.lackDayCheck(IMSUtil.stringToDate(addDate)); if(lackResult.equals("1")){ ++missingDays; } } } String lastMonth = IMSUtil.getLastDateWithStr(firstDayOfMonth,0); if(sameMonth) { lastMonth = IMSUtil.getLastDateWithStr(firstDayOfMonth,1); } EntityWrapper<UserSalary> userSalaryWrapper = new EntityWrapper<UserSalary>(); userSalaryWrapper.eq("salary_date", lastMonth); userSalaryWrapper.eq("user_id", user.getUserId()); userSalaryWrapper.eq("delete_flag", IMSCons.DELETE_FLAG_NO); List<UserSalary> salaryList = userSalaryMapper.selectList(userSalaryWrapper); if(salaryList != null && salaryList.size() > 0) { BigDecimal fixedSubsidy = salaryList.get(0).getSeniorityWage() .add(salaryList.get(0).getSkillWage()) .add(salaryList.get(0).getCommunicationExpense()) .add(salaryList.get(0).getFuelCosts()) .add(salaryList.get(0).getHighCosts()) .add(salaryList.get(0).getOtherSubsidies1()) .add(salaryList.get(0).getTelephoneCharge()); fixedSubsidyDeduction = fixedSubsidy.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(new BigDecimal(missingDays)); } } }else if (!setting.getAttendanceType().equals("加班费") && !setting.getAttendanceType().equals("门卫加班费") && !setting.getAttendanceType().equals("餐贴") && !setting.getAttendanceType().equals("太仓餐贴") && !setting.getAttendanceType().equals("当月新进未满整月") && !setting.getAttendanceType().equals("新进人员固定补贴扣款")) { //获取上个月的岗位工资(基本工资),用于计算请假扣款(事假、病假、长病假)、旷工扣款、漏签扣款、通勤补贴扣款 BigDecimal job_wage = BigDecimal.ZERO; BigDecimal commuterAllowance = BigDecimal.ZERO; String lastMonth = IMSUtil.getLastDateWithStr(attendanceMonth+"-01",0); EntityWrapper<UserSalary> userSalaryWrapper = new EntityWrapper<UserSalary>(); userSalaryWrapper.eq("salary_date", lastMonth); userSalaryWrapper.eq("user_id", user.getUserId()); userSalaryWrapper.eq("delete_flag", IMSCons.DELETE_FLAG_NO); List<UserSalary> salaryList = userSalaryMapper.selectList(userSalaryWrapper); if(salaryList != null && salaryList.size() > 0) { job_wage = salaryList.get(0).getJobWage(); commuterAllowance = salaryList.get(0).getCommuterAllowance(); }else { lastMonth = IMSUtil.getLastDateWithStr(attendanceMonth+"-01",1); userSalaryWrapper = new EntityWrapper<UserSalary>(); userSalaryWrapper.eq("salary_date", lastMonth); userSalaryWrapper.eq("user_id", user.getUserId()); userSalaryWrapper.eq("delete_flag", IMSCons.DELETE_FLAG_NO); salaryList = userSalaryMapper.selectList(userSalaryWrapper); if(salaryList != null && salaryList.size() > 0) { job_wage = salaryList.get(0).getJobWage(); commuterAllowance = salaryList.get(0).getCommuterAllowance(); }else { pDto2 = Dtos.newDto(); pDto2.put("salaryUserId", user.getUserId()); salaryList = userSalaryMapper.listSalarySubject(pDto2); if(salaryList != null && salaryList.size() > 0) { job_wage = salaryList.get(0).getJobWage(); commuterAllowance = salaryList.get(0).getCommuterAllowance(); } } } //判断当前员工是否是排除在外的,排除在外的员工所有费用为0 EntityWrapper<UserAttendanceSettingUser> settingUserWrapper = new EntityWrapper<UserAttendanceSettingUser>(); settingUserWrapper.eq("attendance_setting_id", setting.getId()); settingUserWrapper.eq("user_id", user.getUserId()); int settingUserCount = userAttendanceSettingUserMapper.selectCount(settingUserWrapper); if(settingUserCount <=0) { if(setting.getAttendanceType().equals("事假扣款")) {//detal.getNormalCalculationUnit() casualLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .divide(new BigDecimal(8),2,RoundingMode.HALF_UP) .multiply(data.getCasualLeave()); continue; }else if(setting.getAttendanceType().equals("病假扣款")) { sickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .divide(new BigDecimal(8),2,RoundingMode.HALF_UP) .multiply(data.getSickLeave()) .multiply(new BigDecimal(0.50)); continue; }else if(setting.getAttendanceType().equals("长病假扣款")) { BigDecimal months = data.getLongSickLeave().divide(new BigDecimal(30),2,RoundingMode.HALF_UP); //先判断当前员工工作年限(10年以下、10年以上) //判断当前员工司龄(5年以下、5年以上不满10年、10年以上不满15年、15年以上不满20年、20年以上) if(user.getWorkingYears()!=null && user.getWorkingYears().compareTo(new BigDecimal(10)) < 0) { //司龄不满2年 if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(3)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); }else { //医疗期外 //入司不满1年 if(user.getCompanyWorkingYears().compareTo(new BigDecimal(1)) < 0) { longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.60)); }else if(user.getCompanyWorkingYears().compareTo(new BigDecimal(1)) >= 0) { //入司满1年 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.50)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) < 0) { //入司满2年不到4年 //医疗期内 if(months.compareTo(new BigDecimal(3)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.30)); }else { //医疗期外 //入司不满1年 if(user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) > 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(3)) < 0) { longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.50)); }else if(user.getCompanyWorkingYears().compareTo(new BigDecimal(3)) >= 0) { //入司满1年 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(6)) < 0) { if(user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(5)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(3)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.20)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else { //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.20)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(6)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(8)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.10)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(8)) >= 0) { //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } }else { //司龄不满2年 if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); }else { //医疗期外 //入司不满1年 if(user.getCompanyWorkingYears().compareTo(new BigDecimal(1)) < 0) { longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.60)); }else if(user.getCompanyWorkingYears().compareTo(new BigDecimal(1)) >= 0) { //入司满1年 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.50)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) < 0) { //入司满2年不到4年 //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.30)); }else { //医疗期外 //入司不满1年 if(user.getCompanyWorkingYears().compareTo(new BigDecimal(2)) > 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(3)) < 0) { longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.50)); }else if(user.getCompanyWorkingYears().compareTo(new BigDecimal(3)) >= 0) { //入司满1年 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(6)) < 0) { if(user.getCompanyWorkingYears().compareTo(new BigDecimal(4)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(5)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(6)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.20)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else { //医疗期内 if(months.compareTo(new BigDecimal(9)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.20)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(6)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(8)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(9)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.10)); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(8)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(10)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(9)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(10)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(15)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(12)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(15)) >= 0 && user.getCompanyWorkingYears().compareTo(new BigDecimal(20)) < 0) { //医疗期内 if(months.compareTo(new BigDecimal(18)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } }else if(user.getCompanyWorkingYears()!=null && user.getCompanyWorkingYears().compareTo(new BigDecimal(20)) >= 0) { //医疗期内 if(months.compareTo(new BigDecimal(24)) <= 0) { longSickLeaveDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()); }else { //医疗期外 longSickLeaveDeduction = job_wage .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(data.getLongSickLeave()) .multiply(new BigDecimal(0.40)); } } } }else if(setting.getAttendanceType().equals("旷工扣款")) { absenteeismDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(new BigDecimal(data.getAbsenteeismTimes())); }else if(setting.getAttendanceType().equals("漏签扣款")) { cardMissingDeduction = job_wage.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .divide(new BigDecimal(8),2,RoundingMode.HALF_UP) .multiply(new BigDecimal(4)) .multiply(new BigDecimal(data.getCardMissingTimes())); }else if(setting.getAttendanceType().equals("通勤补贴扣款")) { //除法定节假日、年休、外出,其余全部计入通勤 if(commuterAllowance.compareTo(BigDecimal.ZERO) <= 0) { commuterAllowanceDeduction = BigDecimal.ZERO; }else { if(new BigDecimal(data.getCommuterAllowanceTimes()).compareTo(BigDecimal.ZERO)> 0) { BigDecimal allDays = new BigDecimal(data.getCommuterAllowanceTimes()); BigDecimal avgCommuterAllowance = commuterAllowance.divide(workDayOfMonth,2,RoundingMode.HALF_UP); if(allDays.compareTo(BigDecimal.ONE) >= 0) { commuterAllowanceDeduction = avgCommuterAllowance.multiply(allDays); if(commuterAllowanceDeduction.compareTo(commuterAllowance) > 0) { commuterAllowanceDeduction = commuterAllowance; } } } } } } } } insertOrUpdateAttendanceSalary( attendanceMonth, overtimePay, weekendOvertimePay, holidayOvertimePay, mealAllowance, absenteeismDeduction, cardMissingDeduction, casualLeaveDeduction, sickLeaveDeduction, longSickLeaveDeduction, commuterAllowanceDeduction,lessThanFull,fixedSubsidyDeduction, user, opUser); } return resultMsg; } }); resultMsg.add(returnMsg); countDownLatch.countDown(); } countDownLatch.await(); executorService.shutdown(); //关闭线程池 //3. 遍历结果 for ( Future<String> item :resultMsg){ String futureMsg = item.get(); if(StringUtils.isNotBlank(futureMsg)) { if(StringUtils.isBlank(msg)) { msg = futureMsg; }else { msg = msg + ";" + futureMsg; } } } // 特殊新进人员没有考勤记录也要计算新进人员扣款 String firstDayOfMonth = IMSUtil.getFirstDayOfMonth(attendanceMonth + "-01"); Dto pDto2 = Dtos.newDto(); pDto2.put("isDel", IMSCons.WHETHER_NO); pDto2.put("entryDateBegin", firstDayOfMonth); pDto2.put("entryDateEnd", IMSUtil.getLastDayOfMonth(attendanceMonth + "-01")); pDto2.putAll(dto); List<User> userList = userMapper.listUser(pDto2); if(userList != null && userList.size() > 0 && userList.get(0).getUserId()!=null) { for(User user : userList) { int daysBetween = IMSUtil.daysBetween(IMSUtil.stringToDate(firstDayOfMonth), user.getEntryDate()); if(daysBetween > 0) { int missingDays = 0; int holiday = 0; for (int j = 0; j < daysBetween; j++) { String addDate = IMSUtil.addDate(firstDayOfMonth, j); //判断新进人员当月应上班而缺少的天数 String result = HolidayUtil.holidayCheck(IMSUtil.stringToDate(addDate)); //判断是不是工作日,工作日结果加1;节假日中除了春节、国庆结果加3之外,判断节假日的开始第一天是不是在星期六之前,在星期六之前结果加1 if(result.equals("0")) { ++missingDays; }else if(result.equals("2")) { String lackResult = HolidayUtil.lackDayCheck(IMSUtil.stringToDate(addDate)); if(lackResult.equals("1")){ ++missingDays; } } } pDto2 = Dtos.newDto(); pDto2.put("salaryUserId", user.getUserId()); List<UserSalary> salaryList = userSalaryMapper.listSalarySubject(pDto2); BigDecimal lessThanFull = BigDecimal.ZERO; BigDecimal fixedSubsidyDeduction = BigDecimal.ZERO; //每月平均工作天数 BigDecimal workDayOfMonth = new BigDecimal(21.75); if(salaryList != null && salaryList.size() > 0) { lessThanFull = salaryList.get(0).getJobWage() .divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(new BigDecimal(missingDays)); BigDecimal fixedSubsidy = salaryList.get(0).getSeniorityWage() .add(salaryList.get(0).getSkillWage()) .add(salaryList.get(0).getCommunicationExpense()) .add(salaryList.get(0).getFuelCosts()) .add(salaryList.get(0).getHighCosts()) .add(salaryList.get(0).getOtherSubsidies1()) .add(salaryList.get(0).getTelephoneCharge()); fixedSubsidyDeduction = fixedSubsidy.divide(workDayOfMonth,2,RoundingMode.HALF_UP) .multiply(new BigDecimal(missingDays)); } if(lessThanFull.compareTo(BigDecimal.ZERO) > 0) { pDto2 = Dtos.newDto(); pDto2.put("userId", user.getUserId()); pDto2.put("attendanceMonth", attendanceMonth); pDto2.put("deleteFlag", IMSCons.DELETE_FLAG_NO); List<UserAttendanceSalary> attendanceSalaryList = baseMapper.list(pDto2); if(attendanceSalaryList == null || attendanceSalaryList.size() <= 0) { UserAttendanceSalary attendanceSalary = new UserAttendanceSalary(); attendanceSalary.setAttendanceMonth(attendanceMonth); attendanceSalary.setUserId(user.getUserId()); attendanceSalary.setUserName(user.getUsername()); attendanceSalary.setDeptId(Integer.valueOf(user.getDeptId())); attendanceSalary.setDeptName(user.getDeptNameShort()); attendanceSalary.setLessThanFull(lessThanFull); attendanceSalary.setFixedSubsidyDeduction(fixedSubsidyDeduction); attendanceSalary.setCreateId(opUser.getUserId()); attendanceSalary.setCreateName(opUser.getUsername()); attendanceSalary.setCreateDate(IMSUtil.getDateTime()); if(baseMapper.insert(attendanceSalary) > 0) { this.insertAttendanceSalaryHis(attendanceSalary, opUser); } }else { UserAttendanceSalary attendanceSalaryOld = attendanceSalaryList.get(0); UserAttendanceSalary attendanceSalaryNew =new UserAttendanceSalary(); IMSUtil.copyProperties(attendanceSalaryOld, attendanceSalaryNew); attendanceSalaryNew.setUpdateId(opUser.getUserId()); attendanceSalaryNew.setUpdateName(opUser.getUsername()); attendanceSalaryNew.setUpdateDate(IMSUtil.getDateTime()); attendanceSalaryNew.setLessThanFull(lessThanFull); attendanceSalaryNew.setFixedSubsidyDeduction(fixedSubsidyDeduction); if(baseMapper.updateById(attendanceSalaryNew) > 0) { this.updateAttendanceSalaryHis(attendanceSalaryNew,attendanceSalaryOld, opUser); } } } } } } json.put("msg", msg); json.put("result", true); return json; }

package com.jxyunge.sign.mybatis.entity.sys; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.jxyunge.sign.annotation.SearchParam; import com.jxyunge.sign.enums.sys.SearchConditionEnum; import com.jxyunge.sign.mybatis.entity.BaseEntity; import lombok.Data; import java.io.Serializable; import java.util.Date; /** * 系统日志 * @author zanmall */ @Data @TableName("tb_sys_log") public class SysLog extends BaseEntity implements Serializable { private static final long serialVersionUID = 1L; /* *//** * 主键 *//* @SearchParam(name = {"主键"},condition = {SearchConditionEnum.eq}) @TableId(type = IdType.ASSIGN_UUID) private String id;*/ /** * 用户名 */ private String username; /** * 用户操作 */ private String operation; /** * 请求方法 */ private String method; /** * 请求参数 */ private String params; /** * 执行时长(毫秒) */ private Long time; /** * IP地址 */ private String ip; /** * 创建时间 */ private Date createDate; /** * 业务id */ private String bizId; } package com.jxyunge.sign.aspect; import cn.hutool.core.date.SystemClock; import com.fasterxml.jackson.databind.ObjectMapper; import com.jxyunge.sign.mybatis.entity.sys.Admin; import com.jxyunge.sign.mybatis.entity.sys.SysLog; import com.jxyunge.sign.mybatis.service.sys.AdminService; import com.jxyunge.sign.mybatis.service.sys.SysLogService; import com.jxyunge.sign.request.input.common.PageParam; import com.jxyunge.sign.tools.IpHelper; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; /** * @author lgh */ @Slf4j @Aspect @AllArgsConstructor public class SysLogAspect { private final AdminService adminService; private final SysLogService sysLogService; private ObjectMapper objectMapper; @Around("@annotation(sysLog)") public Object around(ProceedingJoinPoint joinPoint, com.jxyunge.sign.annotation.SysLog sysLog) throws Throwable { long beginTime = SystemClock.now(); //执行方法 Object result = joinPoint.proceed(); //执行时长(毫秒) long time = SystemClock.now() - beginTime; SysLog sysLogEntity = new SysLog(); if(sysLog != null){ //注解上的描述 sysLogEntity.setOperation(sysLog.value()); } //请求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); sysLogEntity.setMethod(className + "." + methodName + "()"); sysLogEntity.setParams(null); //请求的参数 Object[] args = joinPoint.getArgs(); if(args != null && args.length > 0) { String params = null; try { if(args.length > 0 && args[0] != null && Objects.equals(args[0].getClass().getName(), PageParam.class.getName())){ PageParam<Object> pageParam = (PageParam<Object>) args[0]; List<Object> records = pageParam.getRecords(); // 过滤掉不可序列化的对象 List<Object> filteredRecords = filterSerializableObjects(records); params = objectMapper.writeValueAsString(filteredRecords); } else { // 过滤参数中的不可序列化对象 Object[] filteredArgs = filterSerializableObjects(args); params = objectMapper.writeValueAsString(filteredArgs); } } catch (Exception e) { // 如果序列化失败,记录参数类型信息或简单处理 params = getSafeParamRepresentation(args); log.warn("参数序列化失败,使用备用方案: {}", e.getMessage()); } sysLogEntity.setParams(params); } //设置IP地址 sysLogEntity.setIp(IpHelper.getIpAddr()); // 设置业务数据ID(String类型) String businessId = extractIdFromResult(result); if (businessId != null) { sysLogEntity.setBizId(businessId); } //用户名 Admin admin = adminService.getAdminFromReq(); if (!Objects.isNull(admin)) { sysLogEntity.setUsername(admin.getUsername()); } sysLogEntity.setTime(time); sysLogEntity.setCreateDate(new Date()); //保存系统日志 sysLogService.save(sysLogEntity); return result; } private String extractIdFromResult(Object result) { try { // 如果result为null,直接返回null if (result == null) { return null; } Class<?> clazz = result.getClass(); // 第一层:尝试从result的data字段/getData方法中获取实际数据 Object dataObject = null; try { // 尝试调用getData()方法 java.lang.reflect.Method getDataMethod = clazz.getMethod("getData"); dataObject = getDataMethod.invoke(result); } catch (Exception ignored) { // 如果没有getData方法,尝试直接访问data字段 try { java.lang.reflect.Field dataField = clazz.getDeclaredField("data"); dataField.setAccessible(true); dataObject = dataField.get(result); } catch (Exception ignored2) { // 如果既没有getData方法也没有data字段,直接使用result本身 dataObject = result; } } // 如果data为null,返回null if (dataObject == null) { return null; } // 第二层:从data对象中提取ID Class<?> dataClass = dataObject.getClass(); // 优先使用getter方法 try { java.lang.reflect.Method getIdMethod = dataClass.getMethod("getId"); Object idValue = getIdMethod.invoke(dataObject); if (idValue != null) { return idValue.toString(); } } catch (Exception ignored) { // 如果没有getId方法,尝试直接访问字段 } // 备用方案:直接访问字段 java.lang.reflect.Field[] fields = dataClass.getDeclaredFields(); for (java.lang.reflect.Field field : fields) { if (field.getName().equals("id") || field.getName().endsWith("Id")) { field.setAccessible(true); Object value = field.get(dataObject); if (value != null) { return value.toString(); } } } } catch (Exception e) { log.warn("从返回结果中提取ID失败: {}", e.getMessage()); } return null; } // 过滤可序列化对象的方法 private List<Object> filterSerializableObjects(List<Object> objects) { if (objects == null) return new ArrayList<>(); return objects.stream() .filter(this::isSerializable) .collect(Collectors.toList()); } private Object[] filterSerializableObjects(Object[] objects) { if (objects == null) return new Object[0]; return Arrays.stream(objects) .filter(this::isSerializable) .toArray(); } // 检查对象是否可序列化 private boolean isSerializable(Object obj) { if (obj == null) return true; try { // 尝试快速判断是否为常见不可序列化类型 Class<?> clazz = obj.getClass(); String className = clazz.getName(); // 过滤常见的不可序列化类 if (className.contains("java.util.Collections$") || className.contains("HttpServletRequest") || className.contains("HttpServletResponse") || className.contains("Session") || className.contains("ServletContext") || className.startsWith("org.apache.catalina") || className.startsWith("org.springframework.security")) { return false; } // 简单测试序列化 objectMapper.writeValueAsString(obj); return true; } catch (Exception e) { return false; } } // 获取安全的参数表示 private String getSafeParamRepresentation(Object[] args) { if (args == null || args.length == 0) { return "[]"; } List<String> paramInfos = new ArrayList<>(); for (int i = 0; i < args.length; i++) { if (args[i] != null) { String className = args[i].getClass().getSimpleName(); paramInfos.add("arg" + i + ": " + className); } else { paramInfos.add("arg" + i + ": null"); } } try { return objectMapper.writeValueAsString(paramInfos); } catch (Exception e) { return paramInfos.toString(); } } } package com.jxyunge.sign.annotation; import java.lang.annotation.*; /** * 自定义日志注解 * @author linyan */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SysLog { String value() default ""; } 我想要实现一个操作日志的功能,可查看到相关模块的新增,删除,编辑记录,点击详情可查看明细,看到相关的字段的改变,还能实现搜索功能,请你根据我提供给你的代码和需求,生成实现的代码,给出具体的步骤

最新推荐

recommend-type

【大学生电子设计】:备战2015全国大学生电子设计竞赛-信号源类赛题分析.pdf

【大学生电子设计】:备战2015全国大学生电子设计竞赛-信号源类赛题分析.pdf
recommend-type

湘潭大学人工智能专业2024级大一C语言期末考试题库项目-包含58个从头歌平台抓取并排版的C语言编程题目及解答-涵盖基础语法-数组操作-条件判断-循环结构-函数调用-指针应用等核心.zip

2025电赛预测湘潭大学人工智能专业2024级大一C语言期末考试题库项目_包含58个从头歌平台抓取并排版的C语言编程题目及解答_涵盖基础语法_数组操作_条件判断_循环结构_函数调用_指针应用等核心.zip
recommend-type

Pansophica开源项目:智能Web搜索代理的探索

Pansophica开源项目是一个相对较新且具有创新性的智能Web搜索代理,它突破了传统搜索引擎的界限,提供了一种全新的交互方式。首先,我们来探讨“智能Web搜索代理”这一概念。智能Web搜索代理是一个软件程序或服务,它可以根据用户的查询自动执行Web搜索,并尝试根据用户的兴趣、历史搜索记录或其他输入来提供个性化的搜索结果。 Pansophica所代表的不仅仅是搜索结果的展示,它还强调了一个交互式的体验,在动态和交互式虚拟现实中呈现搜索结果。这种呈现方式与现有的搜索体验有着根本的不同。目前的搜索引擎,如Google、Bing和Baidu等,多以静态文本和链接列表的形式展示结果。而Pansophica通过提供一个虚拟现实环境,使得搜索者可以“扭转”视角,进行“飞行”探索,以及“弹网”来浏览不同的内容。这种多维度的交互方式使得信息的浏览变得更加快速和直观,有望改变用户与网络信息互动的方式。 接着,我们关注Pansophica的“开源”属性。所谓开源,指的是软件的源代码可以被公众获取,任何个人或组织都可以自由地使用、学习、修改和分发这些代码。开源软件通常由社区进行开发和维护,这样的模式鼓励了协作创新并减少了重复性劳动,因为全世界的开发者都可以贡献自己的力量。Pansophica项目作为开源软件,意味着其他开发者可以访问和使用其源代码,进一步改进和扩展其功能,甚至可以为Pansophica构建新的应用或服务。 最后,文件名称“Pansophica-src-1.3”表明了我们讨论的特定版本的Pansophica开源代码。数字“1.3”很可能指的是该版本号,表明这是Pansophica项目的第1.3个公开版本。这个版本号对于开发者来说很重要,因为它可以帮助他们追踪更新的进度、比较版本间的差异以及选择最适合其项目的版本。 综合以上信息,Pansophica开源项目不仅在搜索代理领域引入了创新的交互方式,而且通过开源的方式,提供了技术共享和协作的可能性。对于IT行业来说,开源项目是推动技术发展的重要力量,它激发了社区的活力,促进了知识的传播和技术的进步。通过构建一个开源社区,Pansophica可以吸引来自世界各地的开发者和研究人员,共同探索如何将搜索技术与交互式虚拟现实技术结合起来,为用户带来更加丰富和有效的信息检索体验。同时,Pansophica的开源性质也使其更容易适应未来技术的发展,随着社区的不断贡献和反馈,这一平台有望在功能和性能上得到持续的优化和增强。
recommend-type

跨平台内容提取无忧:coze工作流应对社交媒体挑战

# 1. 社交媒体内容提取的必要性与挑战 ## 1.1 内容提取的必要性 在数字时代,社交媒体内容是信息与数据流动的主干道,公司、个人和研究者都在寻求从这些信息中提取价值。无论是为了市场趋势分析、品牌监控、消费者洞察还是公共舆论监测,有效的社交媒体内容提取变得至关重要。这不仅有助于企业做出数据驱动的决策,也能使个人更好地理
recommend-type

vrrp主设备发送的免费arp

<think>好的,我现在需要回答用户关于VRRP主设备发送免费ARP的目的和工作原理的问题。首先,我得回忆一下VRRP的基本概念和工作机制。VRRP,虚拟路由冗余协议,主要用于在局域网中提供默认网关的冗余备份,确保网络的高可用性。主设备(Master)负责转发流量,而备用设备(Backup)则在主设备故障时接管工作。 用户的问题集中在主设备发送免费ARP的目的和机制上。根据引用[2],免费ARP用于通知下游设备虚拟MAC地址的变更。当主设备被选举出来后,它需要让局域网内的其他设备知道虚拟IP对应的MAC地址已经指向自己,这样流量才会被正确路由到主设备。免费ARP的作用应该就是更新这些设备的
recommend-type

为Ghost博客平台打造的Meteor流星包装使用指南

从给定文件信息中,我们可以提炼出以下IT知识点: ### 标题知识点:流星Ghost软件包 1. **流星Ghost软件包的用途**:流星Ghost软件包是专为Ghost博客平台设计的流星(Meteor)应用程序。流星是一个开源的全栈JavaScript平台,用于开发高性能和易于编写的Web应用程序。Ghost是一个开源博客平台,它提供了一个简单且专业的写作环境。 2. **软件包的作用**:流星Ghost软件包允许用户在流星平台上轻松集成Ghost博客。这样做的好处是可以利用流星的实时特性以及易于开发和部署的应用程序框架,同时还能享受到Ghost博客系统的便利和美观。 ### 描述知识点:流星Ghost软件包的使用方法 1. **软件包安装方式**:用户可以通过流星的命令行工具添加名为`mrt:ghost`的软件包。`mrt`是流星的一个命令行工具,用于添加、管理以及配置软件包。 2. **初始化Ghost服务器**:描述中提供了如何在服务器启动时运行Ghost的基本代码示例。这段代码使用了JavaScript的Promise异步操作,`ghost().then(function (ghostServer) {...})`这行代码表示当Ghost服务器初始化完成后,会在Promise的回调函数中提供一个Ghost服务器实例。 3. **配置Ghost博客**:在`then`方法中,首先会获取到Ghost服务器的配置对象`config`,用户可以在此处进行自定义设置,例如修改主题、配置等。 4. **启动Ghost服务器**:在配置完成之后,通过调用`ghostServer.start()`来启动Ghost服务,使其能够处理博客相关的请求。 5. **Web浏览器导航**:一旦流星服务器启动并运行,用户便可以通过Web浏览器访问Ghost博客平台。 ### 标签知识点:JavaScript 1. **JavaScript作为流星Ghost软件包的开发语言**:标签指出流星Ghost软件包是使用JavaScript语言开发的。JavaScript是一种在浏览器端广泛使用的脚本语言,它也是流星平台的基础编程语言。 2. **流星和Ghost共同使用的语言**:JavaScript同样也是Ghost博客平台的开发语言。这表明流星Ghost软件包可以无缝集成,因为底层技术栈相同。 ### 压缩包子文件的文件名称列表知识点:meteor-ghost-master 1. **版本控制和软件包结构**:文件名称`meteor-ghost-master`暗示了该软件包可能托管在像GitHub这样的版本控制系统上。文件名中的`master`通常指的是主分支或主版本。 2. **软件包的目录结构**:通过文件名称可以推断出该软件包可能拥有一个标准的流星软件包结构,包含了初始化、配置、运行等必要的模块和文件。 3. **软件包的维护状态**:由于文件名没有包含特定的版本号,我们无法直接得知软件包的最新更新情况。通常,软件包维护者会将最新的版本代码放在`master`分支上。 ### 总结 流星Ghost软件包提供了一个有效的解决方案,使得流星平台的开发者能够在他们的应用中添加Ghost博客功能。软件包的使用简便,通过流星的命令行工具安装,并通过JavaScript代码配置和启动Ghost服务。通过流星Ghost软件包,开发者能够享受流星的实时特性以及Ghost博客系统的便利性。此外,软件包的命名和结构也暗示了其维护和版本控制的模式,有助于开发者更好地理解如何使用和维护这一软件包。
recommend-type

抖音标题生成自动化:用coze工作流释放创意

# 1. 抖音标题生成自动化的重要性 随着社交媒体平台的崛起,内容的吸引力很大程度上取决于标题的创意与精准性。抖音作为一个日活亿级的短视频平台,高质量的标题能够有效提高视频的点击率,增加内容的传播。但是,人工撰写标题不仅耗时耗力,而且很难做到快速响应热点,自动化标题生成工具应运而生。coze工作流,作为一种实现自动化生成抖音标题的工具,其重要性不言而喻。它能够利用大数据分析和机器学习技术,提高标题的吸引
recommend-type

spss消费结构因子分析

<think>好的,我现在需要帮助用户在SPSS中进行消费结构的因子分析。首先,我要回忆一下因子分析的基本步骤和SPSS的操作流程。用户可能对SPSS不太熟悉,所以步骤要详细,同时需要结合他们提供的引用内容,特别是引用[2]中的适用条件和检验方法。 首先,用户提到了消费结构的数据,这可能包括多个变量,如食品、住房、交通等支出。因子分析适用于这种情况,可以降维并找出潜在因子。根据引用[2],需要检查样本量是否足够,变量间是否有相关性,以及KMO和Bartlett检验的结果。 接下来,我需要按照步骤组织回答:数据准备、适用性检验、因子提取、因子旋转、命名解释、计算得分。每个步骤都要简明扼要,说
recommend-type

OpenMediaVault的Docker映像:快速部署与管理指南

根据提供的文件信息,我们将详细讨论与标题和描述中提及的Docker、OpenMediaVault以及如何部署OpenMediaVault的Docker镜像相关的一系列知识点。 首先,Docker是一个开源的应用容器引擎,允许开发者打包应用及其依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。 OpenMediaVault是一个基于Debian的NAS(网络附加存储)解决方案。它专为家庭或小型办公室提供文件共享、网络附加存储以及打印服务。它提供了一个易用的Web界面,通过这个界面用户可以管理服务器配置、网络设置、用户权限、文件服务等。 在描述中提到了一些Docker命令行操作: 1. `git clone`:用于克隆仓库到本地,这里的仓库指的是“docker-images-openmedivault”。 2. `docker build -t omv`:这是一个构建Docker镜像的命令,其中`-t`参数用于标记镜像名称和标签,这里是标记为“omv”。 3. `docker run`:运行一个容器实例,`-t`参数用于分配一个伪终端,`-i`参数用于交互式操作,`-p 80:80`则是将容器的80端口映射到宿主机的80端口。 启动服务的部分涉及OpenMediaVault的配置和初始化: - ssh服务:用于远程登录到服务器的协议。 - php5-fpm:是PHP的一个FastCGI实现,用于加速PHP的运行。 - nginx:是一个高性能的HTTP和反向代理服务器,常用于优化静态内容的分发。 - openmediavault引擎:指的是OpenMediaVault的核心服务。 - rrdcached:用于收集和缓存性能数据,这些数据可以被rrdtool图形化工具读取。 - collectd:是一个守护进程,用于收集系统性能和提供各种存储方式和传输方式来存储所收集的数据。 为了访问服务,需要在浏览器中输入"http:// IP_OF_DOCKER",其中`IP_OF_DOCKER`指的是运行Docker容器的主机IP地址。 描述中还提到了一个步骤:“在System-> Network-> Interfaces中添加带有dhcp的eth0”,这指的是需要在OpenMediaVault的Web管理界面中配置网络接口。`eth0`是网络接口的名称,通常代表第一个以太网接口。DHCP(动态主机配置协议)是一种自动为网络中的设备分配IP地址的协议,这样设备就可以连接网络并开始通信,无需手动配置IP地址。 【压缩包子文件的文件名称列表】中的“docker-images-openmediavault-master”暗示了这是一个包含Docker镜像文件的代码仓库。通常,“master”分支是代码的主分支,包含了代码库中最新且通常是最稳定的版本。用户可以通过克隆该仓库到本地来获取所有相关的Dockerfile、配置脚本及依赖文件,以便能够自行构建和运行OpenMediaVault的Docker镜像。 综上所述,这些知识点涵盖了从基本的Docker概念、Docker命令行操作、OpenMediaVault服务启动和管理,到具体的网络配置及Docker仓库操作,都是进行Docker化OpenMediaVault部署的关键步骤。
recommend-type

小红书文案提取一步到位:coze工作流操作全攻略

# 1. coze工作流概述 工作流系统是企业信息化和数字化转型的核心组件之一,它通过自动化流程管理提升效率,确保业务流程的顺畅执行。coze工作流作为当前市场上较为先进的工作流解决方案,它不仅仅是一套软件工具,更是一个集成化的平台,旨在通过流程自动化和智能化提升企业运营效率。 coze工作流的引入不仅有助于标准化和优化企业的业务流程,还可以通过可配置的流程设计,满足不同部门的特定需求。在组织的业务流程中