src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -310,18 +310,26 @@ @Override public List<Map<String, Object>> customerList(Customer customer) { LambdaQueryWrapper<Customer> queryWrapper = Wrappers.lambdaQuery(); queryWrapper.select(Customer::getId, Customer::getCustomerName, Customer::getTaxpayerIdentificationNumber); LoginUser loginUser = SecurityUtils.getLoginUser(); Long loginUserId = loginUser.getUserId(); CustomerDto query = new CustomerDto(); if (customer != null) { BeanUtils.copyProperties(customer, query); } // è·ååå§æ¥è¯¢ç»æ List<Map<String, Object>> result = customerMapper.selectMaps(queryWrapper); // å¤ç¨å®¢æ·å表çå¯è§æ§è§åï¼é¿å æå«äººçç§æµ·å®¢æ·æ´é²ç»å½åè´¦å· List<CustomerVo> visibleCustomers = customerMapper.list(query, loginUserId); if (CollectionUtils.isEmpty(visibleCustomers)) { return Collections.emptyList(); } // å°ä¸å线å½å转æ¢ä¸ºé©¼å³°å½å return result.stream().map(map -> map.entrySet().stream() .collect(Collectors.toMap( entry -> underlineToCamel(entry.getKey()), Map.Entry::getValue)) ).collect(Collectors.toList()); return visibleCustomers.stream().map(item -> { Map<String, Object> map = new LinkedHashMap<>(); map.put("id", item.getId()); map.put("customerName", item.getCustomerName()); map.put("taxpayerIdentificationNumber", item.getTaxpayerIdentificationNumber()); return map; }).collect(Collectors.toList()); } // åé å ¬æµ·å®¢æ·ç»ç§æµ· src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java
@@ -1,6 +1,8 @@ package com.ruoyi.staff.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.R; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; @@ -31,8 +33,10 @@ @Operation(summary = "æ°å¢/ä¿®æ¹äººåæå¡è§åé ç½®") @PostMapping("/add") public R add(@RequestBody PersonalAttendanceLocationConfig personalAttendanceLocationConfig){ if (personalAttendanceLocationConfig.getId() != null && !personalAttendanceLocationConfigService.canEdit(personalAttendanceLocationConfig.getId())) { return R.fail("è¯¥çæ¬¡é 置已被æç并产çæå¡è®°å½ï¼ä¸è½ç¼è¾"); } // çæ¬¡éè¦ä¸è½å¤éå¤ if (personalAttendanceLocationConfig.getId() == null && personalAttendanceLocationConfigService.lambdaQuery().eq(PersonalAttendanceLocationConfig::getShift, personalAttendanceLocationConfig.getShift()).one() != null) { return R.fail("çæ¬¡ä¸è½éå¤"); @@ -42,15 +46,35 @@ @Operation(summary = "å页æ¥è¯¢äººåæå¡è§åé ç½®") @GetMapping("/listPage") public R listPage(Page page){ public R listPage(Page page, PersonalAttendanceLocationConfig query){ page.addOrder(OrderItem.desc("id")); return R.ok(personalAttendanceLocationConfigService.page(page)); LambdaQueryWrapper<PersonalAttendanceLocationConfig> wrapper = new LambdaQueryWrapper<PersonalAttendanceLocationConfig>() .ne(PersonalAttendanceLocationConfig::getId, 999); if (query.getSysDeptId() != null) { wrapper.eq(PersonalAttendanceLocationConfig::getSysDeptId, query.getSysDeptId()); } if (query.getShift() != null && !query.getShift().isEmpty()) { wrapper.eq(PersonalAttendanceLocationConfig::getShift, query.getShift()); } IPage<PersonalAttendanceLocationConfig> result = personalAttendanceLocationConfigService.page(page, wrapper); result.getRecords().forEach(item -> { boolean locked = personalAttendanceLocationConfigService.hasAttendanceUsage(item.getId()); item.setUsageLocked(locked); item.setCanEdit(!locked); item.setCanDelete(!locked); }); return R.ok(result); } @Operation(summary = "å é¤äººåæå¡è§åé ç½®") @DeleteMapping("/del") public R del(@RequestBody List<Integer> ids) { for (Integer id : ids) { if (!personalAttendanceLocationConfigService.canDelete(id)) { return R.fail("åå¨å·²æçä¸å·²ææå¡è®°å½ççæ¬¡é ç½®ï¼ä¸è½å é¤"); } } return R.ok(personalAttendanceLocationConfigService.removeBatchByIds(ids)); } src/main/java/com/ruoyi/staff/controller/PersonalShiftController.java
@@ -60,7 +60,7 @@ } @Operation(summary = "çæ¬¡ç¶æä¿®æ¹") @PostMapping("update") @PostMapping("/update") public R performanceShiftUpdate(@RequestBody PersonalShift personalShift) { personalShiftService.performanceShiftUpdate(personalShift); return R.ok(); src/main/java/com/ruoyi/staff/init/DataInitializer.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,33 @@ package com.ruoyi.staff.init; import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Slf4j @Component @RequiredArgsConstructor public class DataInitializer implements ApplicationRunner { private final PersonalAttendanceLocationConfigMapper configMapper; @Override public void run(ApplicationArguments args) { initLeaveConfig(); } private void initLeaveConfig() { PersonalAttendanceLocationConfig config = configMapper.selectById(999); if (config == null) { config = new PersonalAttendanceLocationConfig(); config.setId(999); config.setShift("请å"); configMapper.insert(config); log.info("å·²åå§å请åçæ¬¡é ç½®(id=999)"); } } } src/main/java/com/ruoyi/staff/mapper/PersonalShiftMapper.java
@@ -31,4 +31,6 @@ List<Map<String, Object>> performanceShiftYearList(@Param("time") String time, @Param("userName") String userName, @Param("sysDeptId") Integer sysDeptId); List<PerformanceShiftMapDto> performanceShiftList(@Param("time") String time, @Param("userName") String userName, @Param("sysDeptId") Integer sysDeptId); boolean existsAttendanceUsedByConfig(@Param("configId") Integer configId); } src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java
@@ -61,6 +61,28 @@ @Schema(description = "çæ¬¡") private String shift; /** * æ¯å¦å·²è¢«æçä¸å·²ææå¡è®°å½ä½¿ç¨ */ @Schema(description = "æ¯å¦å·²è¢«æçä¸å·²ææå¡è®°å½ä½¿ç¨") @TableField(exist = false) private Boolean usageLocked; /** * æ¯å¦å¯ç¼è¾ */ @Schema(description = "æ¯å¦å¯ç¼è¾") @TableField(exist = false) private Boolean canEdit; /** * æ¯å¦å¯å é¤ */ @Schema(description = "æ¯å¦å¯å é¤") @TableField(exist = false) private Boolean canDelete; @Schema(description = "åå»ºç¨æ·") @TableField(fill = FieldFill.INSERT) private Integer createUser; src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java
@@ -13,4 +13,19 @@ */ public interface PersonalAttendanceLocationConfigService extends IService<PersonalAttendanceLocationConfig> { /** * å¤æçæ¬¡é ç½®æ¯å¦å·²è¢«æçä¸å·²ææå¡è®°å½ä½¿ç¨ã */ boolean hasAttendanceUsage(Integer configId); /** * å¤æçæ¬¡é ç½®æ¯å¦å 许ç¼è¾ã */ boolean canEdit(Integer configId); /** * å¤æçæ¬¡é ç½®æ¯å¦å 许å é¤ã */ boolean canDelete(Integer configId); } src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java
@@ -1,15 +1,12 @@ package com.ruoyi.staff.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper; import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper; import com.ruoyi.staff.mapper.PersonalShiftMapper; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; /** * <p> @@ -20,6 +17,26 @@ * @since 2026-02-11 09:41:34 */ @Service @RequiredArgsConstructor public class PersonalAttendanceLocationConfigServiceImpl extends ServiceImpl<PersonalAttendanceLocationConfigMapper, PersonalAttendanceLocationConfig> implements PersonalAttendanceLocationConfigService { private final PersonalShiftMapper personalShiftMapper; @Override public boolean hasAttendanceUsage(Integer configId) { if (configId == null) { return false; } return personalShiftMapper.existsAttendanceUsedByConfig(configId); } @Override public boolean canEdit(Integer configId) { return !hasAttendanceUsage(configId); } @Override public boolean canDelete(Integer configId) { return !hasAttendanceUsage(configId); } } src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
@@ -72,7 +72,8 @@ List<PersonalShift> personalShifts = personalShiftMapper.selectList(Wrappers.<PersonalShift>lambdaQuery() .eq(PersonalShift::getStaffOnJobId, staffOnJob.getId()) .eq(PersonalShift::getWorkTime, currentDate.atStartOfDay()) .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId)); .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId) .ne(PersonalShift::getPersonalAttendanceLocationConfigId, 999)); if (CollectionUtil.isEmpty(personalShifts)){ throw new BaseException("å½åç¨æ·å½å¤©æ²¡ææçæ°æ®"); } @@ -230,13 +231,16 @@ List<PersonalShift> personalShifts = personalShiftMapper.selectList(Wrappers.<PersonalShift>lambdaQuery() .eq(PersonalShift::getStaffOnJobId, staffOnJob.getId()) .eq(PersonalShift::getWorkTime, currentDate.atStartOfDay()) .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId)); .isNotNull(PersonalShift::getPersonalAttendanceLocationConfigId) .ne(PersonalShift::getPersonalAttendanceLocationConfigId, 999)); if (CollectionUtil.isNotEmpty(personalShifts)){ PersonalAttendanceLocationConfig personalAttendanceLocationConfig = personalAttendanceLocationConfigMapper.selectById(personalShifts.get(0).getPersonalAttendanceLocationConfigId()); if (personalAttendanceLocationConfig != null) { resultDto.setStartAt(personalAttendanceLocationConfig.getStartAt()); resultDto.setEndAt(personalAttendanceLocationConfig.getEndAt()); resultDto.setShift(personalAttendanceLocationConfig.getShift()); } } return resultDto; } src/main/resources/mapper/staff/PersonalAttendanceRecordsMapper.xml
@@ -42,7 +42,7 @@ order by personal_attendance_records.id desc </select> <!-- æ¥è¯¢æå®æ¥ææ²¡æèå¤è®°å½çå¨èåå·¥ï¼å¨æå®æ¶é´ä¹åå ¥èçï¼ --> <!-- æ¥è¯¢æå®æ¥æææçï¼é请åï¼ä½æ²¡æèå¤è®°å½çå¨èåå·¥ï¼æ²¡æçè§ä¸ºä¼æ¯ä¸æ è®°ç¼ºå¤ --> <select id="selectStaffWithoutAttendanceRecordBeforeTime" resultType="com.ruoyi.staff.pojo.StaffOnJob"> SELECT soj.* FROM staff_on_job soj @@ -50,8 +50,11 @@ AND soj.create_time < #{entryDeadline} AND EXISTS ( SELECT 1 FROM personal_attendance_location_config palc WHERE palc.sys_dept_id = soj.sys_dept_id FROM personal_shift ps WHERE ps.staff_on_job_id = soj.id AND DATE(ps.work_time) = #{date} AND ps.personal_attendance_location_config_id IS NOT NULL AND ps.personal_attendance_location_config_id != 999 ) AND NOT EXISTS ( SELECT 1 src/main/resources/mapper/staff/PersonalShiftMapper.xml
@@ -18,6 +18,7 @@ u.id user_id FROM personal_shift s LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id <where> u.id IS NOT NULL @@ -26,6 +27,7 @@ </if> <if test="time != null and time != ''"> and DATE_FORMAT(s.work_time, '%Y-%m') = DATE_FORMAT(#{time}, '%Y-%m') AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-%m-01'))) </if> <if test="userName != null and userName != ''"> and u.staff_name like concat('%', #{userName}, '%') @@ -44,10 +46,12 @@ GROUP_CONCAT(DATE_FORMAT(s.work_time, '%c'), 'ï¼', IFNULL(palc.shift, '') order by s.work_time SEPARATOR ';') month_str FROM personal_shift s LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id <where> <if test="time != null and time != ''"> and DATE_FORMAT(s.work_time, '%Y') = DATE_FORMAT(#{time}, '%Y' ) AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-01-01'))) </if> <if test="userName != null and userName != ''"> and u.staff_name like concat('%', #{userName}, '%') @@ -67,10 +71,12 @@ GROUP_CONCAT(DATE_FORMAT(s.work_time, '%c'), 'ï¼', IFNULL(palc.shift, '') order by s.work_time SEPARATOR ';') month_str FROM personal_shift s LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id <where> <if test="time != null and time != ''"> and DATE_FORMAT(s.work_time, '%Y') = DATE_FORMAT(#{time}, '%Y' ) AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-01-01'))) </if> <if test="userName != null and userName != ''"> and u.staff_name like concat('%', #{userName}, '%') @@ -88,10 +94,12 @@ GROUP_CONCAT(s.work_time, 'ï¼', IFNULL(palc.shift, ''), 'ï¼', s.id order by s.work_time SEPARATOR ';') AS shift_time, u.id user_id FROM personal_shift s LEFT JOIN staff_on_job u ON u.id = s.staff_on_job_id LEFT JOIN staff_leave sl ON sl.staff_on_job_id = u.id LEFT JOIN personal_attendance_location_config palc ON palc.id = s.personal_attendance_location_config_id <where> <if test="time != null and time != ''"> and DATE_FORMAT(s.work_time, '%Y-%m') = DATE_FORMAT(#{time}, '%Y-%m' ) AND (u.staff_state = 1 OR (u.staff_state = 0 AND sl.leave_date IS NOT NULL AND sl.leave_date >= DATE_FORMAT(#{time}, '%Y-%m-01'))) </if> <if test="userName != null and userName != ''"> and u.staff_name like concat('%', #{userName}, '%') @@ -104,4 +112,15 @@ order by s.create_time </select> <select id="existsAttendanceUsedByConfig" resultType="boolean"> SELECT EXISTS ( SELECT 1 FROM personal_shift ps INNER JOIN personal_attendance_records par ON par.staff_on_job_id = ps.staff_on_job_id AND par.date = DATE(ps.work_time) WHERE ps.personal_attendance_location_config_id = #{configId} ) </select> </mapper>