Quellcode durchsuchen

feat(kyl): add kyl multi-module project

WanJL vor 1 Monat
Ursprung
Commit
01f167a3d5
58 geänderte Dateien mit 3883 neuen und 159 gelöschten Zeilen
  1. 39 0
      kyl/.gitignore
  2. 5 1
      kyl/kyl-framework/pom.xml
  3. 63 0
      kyl/kyl-framework/src/main/java/com/kyl/config/CustomRedisConfig.java
  4. 7 0
      kyl/kyl-security/src/main/java/com/kyl/controller/DeptController.java
  5. 9 2
      kyl/kyl-security/src/main/java/com/kyl/controller/RoleController.java
  6. 19 0
      kyl/kyl-security/src/main/java/com/kyl/entity/RoleResource.java
  7. 2 0
      kyl/kyl-security/src/main/java/com/kyl/mapper/ResourceMapper.java
  8. 28 0
      kyl/kyl-security/src/main/java/com/kyl/mapper/RoleResourceMapper.java
  9. 9 0
      kyl/kyl-security/src/main/java/com/kyl/mapper/UserRoleMapper.java
  10. 25 0
      kyl/kyl-security/src/main/java/com/kyl/service/RoleResourceService.java
  11. 3 0
      kyl/kyl-security/src/main/java/com/kyl/service/RoleService.java
  12. 0 5
      kyl/kyl-security/src/main/java/com/kyl/service/impl/DeptServiceImpl.java
  13. 1 1
      kyl/kyl-security/src/main/java/com/kyl/service/impl/ResourceServiceImpl.java
  14. 65 6
      kyl/kyl-security/src/main/java/com/kyl/service/impl/RoleServiceImpl.java
  15. 23 0
      kyl/kyl-security/src/main/java/com/kyl/vo/UserRoleVo.java
  16. 24 7
      kyl/kyl-security/src/main/resources/mapper/DeptMapper.xml
  17. 15 0
      kyl/kyl-security/src/main/resources/mapper/ResourceMapper.xml
  18. 18 0
      kyl/kyl-security/src/main/resources/mapper/RoleResourceMapper.xml
  19. 18 0
      kyl/kyl-security/src/main/resources/mapper/UserRoleMapper.xml
  20. 203 30
      kyl/kyl-security/src/main/resources/temp.json
  21. 61 0
      kyl/kyl-service/src/main/java/com/kyl/constant/AccreditationRecordConstants.java
  22. 32 0
      kyl/kyl-service/src/main/java/com/kyl/constant/PendingTasksConstant.java
  23. 51 0
      kyl/kyl-service/src/main/java/com/kyl/constant/RetreatConstant.java
  24. 0 22
      kyl/kyl-service/src/main/java/com/kyl/dto/ElderDto.java
  25. 0 30
      kyl/kyl-service/src/main/java/com/kyl/entity/Elder.java
  26. 4 0
      kyl/kyl-service/src/main/java/com/kyl/entity/FlowInfo.java
  27. 59 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/AccreditationRecordMapper.java
  28. 43 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/BalanceMapper.java
  29. 43 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/BillMapper.java
  30. 44 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/CheckInConfigMapper.java
  31. 65 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/CheckInMapper.java
  32. 81 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/ContractMapper.java
  33. 67 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/ElderMapper.java
  34. 25 0
      kyl/kyl-service/src/main/java/com/kyl/mapper/HiActinstMapper.java
  35. 64 0
      kyl/kyl-service/src/main/java/com/kyl/service/AccreditationRecordService.java
  36. 111 0
      kyl/kyl-service/src/main/java/com/kyl/service/ActFlowCommService.java
  37. 572 0
      kyl/kyl-service/src/main/java/com/kyl/service/ActFlowCommServiceImpl.java
  38. 304 0
      kyl/kyl-service/src/main/java/com/kyl/service/CheckInService.java
  39. 117 0
      kyl/kyl-service/src/main/java/com/kyl/service/ElderService.java
  40. 108 0
      kyl/kyl-service/src/main/java/com/kyl/service/PendingTasksService.java
  41. 72 0
      kyl/kyl-service/src/main/java/com/kyl/vo/RecordVo.java
  42. 151 0
      kyl/kyl-service/src/main/resources/bpmn/checkIn.bpmn
  43. BIN
      kyl/kyl-service/src/main/resources/bpmn/checkIn.png
  44. 156 0
      kyl/kyl-service/src/main/resources/mapper/AccreditationRecordMapper.xml
  45. 132 0
      kyl/kyl-service/src/main/resources/mapper/BalanceMapper.xml
  46. 176 0
      kyl/kyl-service/src/main/resources/mapper/BillMapper.xml
  47. 154 0
      kyl/kyl-service/src/main/resources/mapper/CheckInConfigMapper.xml
  48. 108 0
      kyl/kyl-service/src/main/resources/mapper/CheckInMapper.xml
  49. 195 0
      kyl/kyl-service/src/main/resources/mapper/ContractMapper.xml
  50. 93 0
      kyl/kyl-service/src/main/resources/mapper/ElderMapper.xml
  51. 28 0
      kyl/kyl-service/src/main/resources/temp.json
  52. 49 0
      kyl/kyl-web/src/main/java/com/kyl/controller/ApplicationsController.java
  53. 40 0
      kyl/kyl-web/src/main/java/com/kyl/controller/CheckInController.java
  54. 44 0
      kyl/kyl-web/src/main/java/com/kyl/controller/PendingTasksController.java
  55. 9 0
      kyl/kyl-web/src/main/resources/application.yaml
  56. 37 0
      kyl/kyl-web/src/test/java/com/kyl/service/Activiti7DeployTest.java
  57. 0 54
      kyl/logs/kyl.log.2026-02-08.log
  58. 12 1
      kyl/pom.xml

+ 39 - 0
kyl/.gitignore

@@ -0,0 +1,39 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+.kotlin
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 5 - 1
kyl/kyl-framework/pom.xml

@@ -109,7 +109,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-cache</artifactId>
         </dependency>
-
+        <!--activiti7依赖-->
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-spring-boot-starter</artifactId>
+        </dependency>
     </dependencies>
 
     <!-- 项目构建配置 -->

+ 63 - 0
kyl/kyl-framework/src/main/java/com/kyl/config/CustomRedisConfig.java

@@ -0,0 +1,63 @@
+package com.kyl.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.time.Duration;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title CustomRedisConfig
+ * @description
+ * @create 2026/2/7
+ */
+@Configuration
+@EnableCaching
+public class CustomRedisConfig {
+
+    @Bean
+    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
+        // 创建ObjectMapper并配置
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        objectMapper.activateDefaultTyping(
+                objectMapper.getPolymorphicTypeValidator(),
+                ObjectMapper.DefaultTyping.NON_FINAL
+        );
+        // 支持Java8时间类型
+        objectMapper.registerModule(new JavaTimeModule());
+
+        // 创建JSON序列化器
+        GenericJackson2JsonRedisSerializer jsonSerializer =
+                new GenericJackson2JsonRedisSerializer(objectMapper);
+
+        // 配置缓存默认设置
+        RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
+                .entryTtl(Duration.ofMinutes(10))  // 设置默认过期时间
+                .disableCachingNullValues()  // 不缓存null值
+                .serializeKeysWith(RedisSerializationContext.SerializationPair
+                        .fromSerializer(new StringRedisSerializer()))  // Key使用字符串序列化
+                .serializeValuesWith(RedisSerializationContext.SerializationPair
+                        .fromSerializer(jsonSerializer));  // Value使用JSON序列化
+
+        return RedisCacheManager.builder(redisConnectionFactory)
+                .cacheDefaults(cacheConfig)
+                .build();
+    }
+
+
+}
+

+ 7 - 0
kyl/kyl-security/src/main/java/com/kyl/controller/DeptController.java

@@ -2,6 +2,7 @@ package com.kyl.controller;
 
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.kyl.base.ResponseResult;
+import com.kyl.constant.DeptCacheConstant;
 import com.kyl.dto.DeptDto;
 import com.kyl.entity.Dept;
 import com.kyl.service.DeptService;
@@ -10,6 +11,8 @@ import com.kyl.vo.TreeVo;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Caching;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -77,6 +80,10 @@ public class DeptController {
      * @return 修改结果(true=成功,false=失败)
      */
     @Operation(summary = "修改部门状态", description = "单独修改部门的启用/禁用状态,0表示启用,1表示禁用,需传入部门编号和目标状态")
+    @Caching(evict = {
+            @CacheEvict(value = DeptCacheConstant.TREE,allEntries = true),
+            @CacheEvict(value = DeptCacheConstant.LIST,allEntries = true),
+    })
     @PatchMapping("/is_enable")
     public ResponseResult<Boolean> updateIsEnable(@RequestBody DeptDto deptDto) {
         String dataState = deptDto.getDataState();

+ 9 - 2
kyl/kyl-security/src/main/java/com/kyl/controller/RoleController.java

@@ -8,9 +8,11 @@ import com.kyl.constant.SuperConstant;
 import com.kyl.dto.RoleDto;
 import com.kyl.entity.Role;
 import com.kyl.service.RoleService;
-import com.kyl.service.impl.RoleServiceImpl;
+import com.kyl.service.RoleResourceService;
 import com.kyl.utils.BeanConv;
 import com.kyl.vo.RoleVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -55,5 +57,10 @@ public class RoleController {
         PageResponse<RoleVo> page = roleService.findRolePage(roleDto, pageNum, pageSize);
         return ResponseResult.success(page);
     }
-
+    //修改角色的菜单权限
+    //前端传入的参数有2个,一个是角色id,一个是菜单编号集合
+    @PatchMapping
+    public ResponseResult<String> updateRoleMenu(@RequestBody RoleDto roleDto){
+        return ResponseResult.success(roleService.updateRole(roleDto));
+    }
 }

+ 19 - 0
kyl/kyl-security/src/main/java/com/kyl/entity/RoleResource.java

@@ -0,0 +1,19 @@
+package com.kyl.entity;
+
+
+import com.kyl.base.BaseEntity;
+import lombok.Data;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title RoleResource
+ * @description
+ * @create 2026/2/9
+ */
+@Data
+public class RoleResource extends BaseEntity {
+    private Long roleId;
+    private Long resourceNo;
+    private String dataState;
+}

+ 2 - 0
kyl/kyl-security/src/main/java/com/kyl/mapper/ResourceMapper.java

@@ -33,6 +33,8 @@ public interface ResourceMapper extends BaseMapper<Resource> {
      */
     List<ResourceVo> findResourceListByRoleIds(@Param("roleIds")List<Long> roleIds,@Param("resourceType") String resourceType);
 
+    List<ResourceVo> findResourcesByRoleIds(@Param("roleIds")List<Long> roleIds);
+
     /**
      * 根据角色Id列表查询按钮列表
      * @param roleIds

+ 28 - 0
kyl/kyl-security/src/main/java/com/kyl/mapper/RoleResourceMapper.java

@@ -0,0 +1,28 @@
+package com.kyl.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kyl.dto.RoleDto;
+import com.kyl.entity.RoleResource;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title RolesResourceMapper
+ * @description
+ * @create 2026/2/9
+ */
+@Mapper
+public interface RoleResourceMapper extends BaseMapper<RoleResource> {
+
+    int countRoleResourceByRoleId(Long roleId);
+
+    int deleteRoleResourceByRoleId(Long id);
+
+
+    int createRoleResource(@Param("roleDto") RoleDto roleDto);
+}

+ 9 - 0
kyl/kyl-security/src/main/java/com/kyl/mapper/UserRoleMapper.java

@@ -3,8 +3,11 @@ package com.kyl.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.kyl.entity.UserRole;
+import com.kyl.vo.UserRoleVo;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * @author WanJl
  * @version 1.0
@@ -14,4 +17,10 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface UserRoleMapper extends BaseMapper<UserRole> {
+    /**
+     * 根据用户id查询用户角色
+     * @param userId
+     * @return
+     */
+    List<UserRoleVo> selectByUserId(Long userId);
 }

+ 25 - 0
kyl/kyl-security/src/main/java/com/kyl/service/RoleResourceService.java

@@ -0,0 +1,25 @@
+package com.kyl.service;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kyl.dto.RoleDto;
+import com.kyl.entity.RoleResource;
+import com.kyl.mapper.RoleResourceMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title RolesResourceService
+ * @description
+ * @create 2026/2/9
+ */
+@Service
+public class RoleResourceService extends ServiceImpl<RoleResourceMapper, RoleResource> {
+
+}

+ 3 - 0
kyl/kyl-security/src/main/java/com/kyl/service/RoleService.java

@@ -32,4 +32,7 @@ public interface RoleService extends IService<Role> {
      * @return
      */
     PageResponse<RoleVo> findRolePage(RoleDto roleDto, Integer pageNum, Integer pageSize);
+
+
+    boolean updateRole(RoleDto roleDto);
 }

+ 0 - 5
kyl/kyl-security/src/main/java/com/kyl/service/impl/DeptServiceImpl.java

@@ -1,19 +1,15 @@
 package com.kyl.service.impl;
 
 
-import cn.hutool.core.bean.BeanUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kyl.constant.DeptCacheConstant;
 import com.kyl.constant.SuperConstant;
 import com.kyl.dto.DeptDto;
 import com.kyl.entity.Dept;
-import com.kyl.entity.User;
 import com.kyl.exception.BaseException;
 import com.kyl.mapper.DeptMapper;
 import com.kyl.service.DeptService;
-import com.kyl.service.UserService;
 import com.kyl.utils.BeanConv;
 import com.kyl.utils.EmptyUtil;
 import com.kyl.utils.NoProcessing;
@@ -51,7 +47,6 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements De
     @Override
     public List<DeptVo> findDeptVoListByCondition(DeptDto deptDto) {
         // 先去redis数据库里查询,如果redis数据库里没有,则去MySQL数据库里查询
-
         List<DeptVo> deptVoList = deptMapper.findDeptVoListByCondition(deptDto);
         //查询完后,缓存到redis数据库中
         return deptVoList;

+ 1 - 1
kyl/kyl-security/src/main/java/com/kyl/service/impl/ResourceServiceImpl.java

@@ -192,7 +192,7 @@ public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> i
 
     @Override
     public List<ResourceVo> findResourceListByRoleIds(List<Long> id) {
-        return resourceMapper.findResourceListByRoleIds(id,null);
+        return resourceMapper.findResourcesByRoleIds(id);
     }
 
 

+ 65 - 6
kyl/kyl-security/src/main/java/com/kyl/service/impl/RoleServiceImpl.java

@@ -2,17 +2,21 @@ package com.kyl.service.impl;
 
 
 import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
 import com.kyl.base.PageResponse;
+import com.kyl.constant.SuperConstant;
 import com.kyl.dto.RoleDto;
 import com.kyl.entity.Role;
+import com.kyl.entity.RoleResource;
+import com.kyl.entity.UserRole;
 import com.kyl.mapper.RoleMapper;
-import com.kyl.service.DeptService;
-import com.kyl.service.ResourceService;
-import com.kyl.service.RoleService;
+import com.kyl.service.*;
+import com.kyl.utils.BeanConv;
 import com.kyl.utils.EmptyUtil;
+import com.kyl.utils.ObjectUtil;
 import com.kyl.vo.DeptVo;
 import com.kyl.vo.ResourceVo;
 import com.kyl.vo.RoleVo;
@@ -43,6 +47,10 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
     private ResourceService resourceService;
     @Resource
     private DeptService deptService;
+    @Resource
+    UserRoleService userRoleService;
+    @Resource
+    RoleResourceService roleResourceService;
 
     @Override
     public List<RoleVo> findRoleVoListByUserId(Long userId) {
@@ -83,16 +91,17 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
         if (!EmptyUtil.isNullOrEmpty(roleVoPageResponse.getRecords())) {
             //4、装配对于的资源数据权限
             List<ResourceVo> resourceVoList = resourceService.findResourceListByRoleIds(roleIdList);
+            log.info("资源列表条数---->{}", resourceVoList.size());
             //5、装配当前的部门数据权限
             List<DeptVo> deptVoList = deptService.findDeptVoListByRoleIds(roleIdList);
             roleVoPageResponse.getRecords().forEach(roleVo -> {
                 //创建一个资源集合
-                Set<String> resourceNoSet = resourceVoList.stream()
+                List<String> resourceNoSet = resourceVoList.stream()
                         //资源的角色id如果和当前角色id一致
                         .filter(resourceVo -> resourceVo.getRoleId().equals(String.valueOf(roleVo.getId())))
-                        .map(ResourceVo::getResourceNo).collect(Collectors.toSet());
+                        .map(ResourceVo::getResourceNo).collect(Collectors.toList());
                 String[] resourceNoSetArray = resourceNoSet.toArray(new String[0]);
-                log.info("资源编号集合------->{}", Arrays.toString(resourceNoSetArray));
+                log.info("角色id--->{}资源编号集合长度------->{}", roleVo.getId(),resourceNoSetArray.length);
                 roleVo.setCheckedResourceNos(resourceNoSetArray);
 
                 //装配部门数据权限
@@ -106,4 +115,54 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
 
         return roleVoPageResponse;
     }
+
+    @Override
+    public boolean updateRole(RoleDto roleDto) {
+        Role role = BeanConv.toBean(roleDto, Role.class);
+
+        //判断是修改角色 还是 修改角色对应的资源菜单
+        if (ObjectUtil.isNotEmpty(role.getDataScope())){
+            //1、启用禁用角色--如果角色已经分配用户,就不能禁用角色
+            if (ObjectUtil.isNotEmpty(roleDto.getDataState())&& "1".equals(roleDto.getDataState())){
+                Long count = userRoleService.lambdaQuery().eq(UserRole::getRoleId, role.getId()).count();
+                //判断是否已经分配用户
+                if (count>0){
+                    throw new RuntimeException("角色已经分配用户,不能禁用角色");
+                }
+            }
+            //2、修改角色信息
+            boolean flag = this.updateById(role);
+            if (!flag){
+                throw new RuntimeException("修改角色信息失败");
+            }
+            return true;
+        }
+        //3、修改角色对应的菜单
+        if (ObjectUtil.isEmpty(role.getDataScope())){
+            //删除角色对应的菜单
+            roleResourceService.remove(new QueryWrapper<RoleResource>().eq("role_id", role.getId()));
+            //保存角色对应的菜单
+            if (roleDto.getCheckedResourceNos() == null|| roleDto.getCheckedResourceNos().length == 0){
+                return true;
+            }
+            String[] checkedResourceNos = roleDto.getCheckedResourceNos();
+            List<RoleResource> roleResourceList = new ArrayList<>();
+            for (String checkedResourceNo : checkedResourceNos) {
+                RoleResource roleResource = new RoleResource();
+                roleResource.setRoleId(role.getId());   //角色Id
+                roleResource.setResourceNo(Long.valueOf(checkedResourceNo));//资源Id
+                roleResource.setDataState(SuperConstant.DATA_STATE_0);  //启用
+                roleResourceList.add(roleResource);
+            }
+            //判断集合是否为空
+            if (roleResourceList.isEmpty()){
+                return true;
+            }
+            boolean saved = roleResourceService.saveBatch(roleResourceList);
+            if (!saved) {
+                throw new RuntimeException("保存角色对应的菜单失败");
+            }
+        }
+        return true;
+    }
 }

+ 23 - 0
kyl/kyl-security/src/main/java/com/kyl/vo/UserRoleVo.java

@@ -0,0 +1,23 @@
+package com.kyl.vo;
+
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title UserRoleVo
+ * @description
+ * @create 2026/3/29
+ */
+@Data
+public class UserRoleVo {
+    @ApiModelProperty(value = "用户角色id")
+    private Long id;
+    @ApiModelProperty(value = "用户名称")
+    private String userName;
+    @ApiModelProperty(value = "角色名称")
+    private String roleName;
+
+}

+ 24 - 7
kyl/kyl-security/src/main/resources/mapper/DeptMapper.xml

@@ -31,13 +31,26 @@
         <result property="remark" column="remark" />
         <result property="createDay" column="create_day"/>
         <result property="leaderName" column="leader_name"/>
-        <result property="roleId" column="role_id"/>
+        <result property="roleId" column="role_ids"/>
     </resultMap>
     <select id="findDeptVoListByCondition" resultMap="BaseResultVoMap">
-        SELECT d.id,d.parent_dept_no,d.dept_no,d.dept_name,d.sort_no,d.data_state,
-               d.create_time,d.update_time,d.create_by,d.update_by,d.leader_id,d.remark,
-               u.real_name as leader_name,GROUP_CONCAT(rd.role_id) AS role_id,
-               DATE_FORMAT(d.create_time,'%Y-%m-%d') as create_day
+        SELECT
+        d.id,
+        d.parent_dept_no,
+        d.dept_no,
+        d.dept_name,
+        d.sort_no,
+        d.data_state,
+        d.create_time,
+        d.update_time,
+        d.create_by,
+        d.update_by,
+        d.leader_id,
+        d.remark,
+        u.real_name as leader_name,
+        -- 核心优化:将多个角色ID合并为一个字段,避免重复
+        GROUP_CONCAT(rd.role_id) AS role_ids,
+        DATE_FORMAT(d.create_time,'%Y-%m-%d') as create_day
         FROM sys_dept d
         LEFT JOIN sys_user u ON u.id = d.leader_id
         LEFT JOIN sys_role_dept rd ON d.dept_no = rd.dept_no
@@ -52,7 +65,11 @@
                 AND d.data_state = #{deptDto.dataState}
             </if>
         </where>
-        ORDER BY d.sort_no ASC,d.create_time ASC
+        GROUP BY
+        d.id, d.parent_dept_no, d.dept_no, d.dept_name,
+        d.sort_no, d.data_state, d.create_time, d.update_time,
+        d.create_by, d.update_by, d.leader_id, d.remark, u.real_name
+        ORDER BY d.sort_no ASC, d.create_time ASC;
     </select>
     <select id="findDeptVoListByRoleIds" resultMap="BaseResultVoMap">
         SELECT d.id, d.parent_dept_no, d.dept_no, d.dept_name, d.sort_no, d.data_state, d.create_time,
@@ -65,7 +82,7 @@
         <where>
             rd.role_id IN
             <foreach collection="roleIdList" item="item" open="(" close=")" separator=",">
-                rd.role_id = #{roleIdList.item}
+                rd.role_id = #{item}
             </foreach>
         </where>
 

+ 15 - 0
kyl/kyl-security/src/main/resources/mapper/ResourceMapper.xml

@@ -93,5 +93,20 @@
         </where>
         ORDER BY r.sort_no ASC
     </select>
+    <select id="findResourcesByRoleIds" resultMap="BaseResultVoMap">
+        SELECT r.id,r.resource_no,r.parent_resource_no,r.resource_name,r.resource_type,
+        r.request_path,r.label,r.data_state,r.sort_no,r.icon,r.create_time,r.update_time,
+        r.remark,r.create_by,r.update_by,rr.role_id AS role_id
+        FROM sys_role_resource rr
+        LEFT JOIN sys_resource r ON r.resource_no = rr.resource_no
+        <where>
+            AND r.data_state = '0'
+            AND rr.role_id IN
+            <foreach item="item" index="index" collection="roleIds" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </where>
+        ORDER BY r.sort_no ASC
+    </select>
 
 </mapper>

+ 18 - 0
kyl/kyl-security/src/main/resources/mapper/RoleResourceMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.RoleResourceMapper">
+
+    <insert id="createRoleResource" parameterType="com.kyl.dto.RoleDto">
+        INSERT INTO sys_role_resource(role_id, resource_id) VALUES
+        <foreach item="item" index="index" collection="roleDto.checkedResourceNos" separator="," open="(" close=")">
+            #{roleDto.id},#{item}
+        </foreach>
+    </insert>
+    <delete id="deleteRoleResourceByRoleId">
+        DELETE FROM sys_role_resource WHERE role_id = #{roleId}
+    </delete>
+
+    <select id="countRoleResourceByRoleId" resultType="java.lang.Integer">
+        SELECT COUNT(1) FROM sys_role_resource WHERE role_id = #{roleId}
+    </select>
+</mapper>

+ 18 - 0
kyl/kyl-security/src/main/resources/mapper/UserRoleMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.UserRoleMapper">
+
+
+    <select id="selectByUserId" resultType="com.kyl.vo.UserRoleVo">
+        SELECT
+        ur.id AS id,
+        r.name AS roleName,
+        u.real_name AS userName
+        FROM
+        user_role ur
+        LEFT JOIN role r ON ur.role_id = r.id
+        LEFT JOIN user u ON ur.user_id = u.id
+        WHERE
+        ur.user_id = #{userId}
+    </select>
+</mapper>

+ 203 - 30
kyl/kyl-security/src/main/resources/temp.json

@@ -1,32 +1,205 @@
-{
-  "code": 200,
-  "msg": "操作成功",
-  "data": {
-    "items": [
-      {
-        "id": "100001000000000",
-        "label": "智慧养老院",
-        "children": [
-          {
-            "id": "100001001000000",
-            "label": "院长办公室"
-          },
-          {
-            "id": "100001002000000",
-            "label": "财务部",
-            "children": [
-              {
-                "id": "100001002001000",
-                "label": "会计组"
-              },
-              {
-                "id": "100001002002000",
-                "label": "结算组"
-              }
-            ]
-          }
-        ]
+[
+  "java.util.ArrayList",
+  [
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588305,
+        "createTime": "2024-09-25 19:21:19",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-02-07 23:30:49",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "院长办公室",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001001000000",
+        "deptName": "院长办公室",
+        "sortNo": 1,
+        "leaderId": 1671403256519078147,
+        "leaderName": "院长",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588306,
+        "createTime": "2024-09-25 19:22:09",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-02-07 23:34:46",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "财务部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001002000000",
+        "deptName": "财务部",
+        "sortNo": 2,
+        "leaderId": 1671403256519078149,
+        "leaderName": "结算组主管",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588309,
+        "createTime": "2024-09-25 19:23:00",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-01-28 14:08:00",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "行政部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001003000000",
+        "deptName": "行政部",
+        "sortNo": 3,
+        "leaderId": 1671403256519078151,
+        "leaderName": "行政部部长",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588311,
+        "createTime": "2024-09-25 19:23:23",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-02-07 23:39:57",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "后勤部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001004000000",
+        "deptName": "后勤部",
+        "sortNo": 4,
+        "leaderId": 1671403256519078147,
+        "leaderName": "院长",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588314,
+        "createTime": "2024-09-25 19:23:56",
+        "createDay": "2024-09-25",
+        "updateTime": "2024-09-25 19:23:56",
+        "createBy": 1671403256519078138,
+        "updateBy": null,
+        "dataState": "0",
+        "remark": "护理部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001005000000",
+        "deptName": "护理部",
+        "sortNo": 5,
+        "leaderId": 1671403256519078157,
+        "leaderName": "护理组主管",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588316,
+        "createTime": "2024-09-25 19:24:25",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-01-28 14:08:26",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "销售部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001006000000",
+        "deptName": "销售部",
+        "sortNo": 6,
+        "leaderId": 1671403256519078159,
+        "leaderName": "销售部部长",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588318,
+        "createTime": "2024-09-25 19:24:43",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-01-28 14:09:22",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "法务部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001007000000",
+        "deptName": "法务部",
+        "sortNo": 7,
+        "leaderId": 1671403256519078162,
+        "leaderName": "法务部部长",
+        "roleId": null,
+        "level": 4
+      }
+    ],
+    [
+      "com.kyl.vo.DeptVo",
+      {
+        "id": 1671445634122588320,
+        "createTime": "2024-09-25 19:25:04",
+        "createDay": "2024-09-25",
+        "updateTime": "2026-02-07 23:40:14",
+        "createBy": 1671403256519078138,
+        "updateBy": 1671403256519078138,
+        "dataState": "0",
+        "remark": "售后保障部",
+        "createType": null,
+        "creator": null,
+        "adminCreator": null,
+        "updater": null,
+        "parentDeptNo": "100001000000000",
+        "deptNo": "100001008000000",
+        "deptName": "售后保障部",
+        "sortNo": 8,
+        "leaderId": 1671403256519078161,
+        "leaderName": "养老顾问",
+        "roleId": null,
+        "level": 4
       }
     ]
-  }
-}
+  ]
+]

+ 61 - 0
kyl/kyl-service/src/main/java/com/kyl/constant/AccreditationRecordConstants.java

@@ -0,0 +1,61 @@
+package com.kyl.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title AccreditationRecordConstants
+ * @description
+ * @create 2026/3/29
+ */
+@Getter
+@AllArgsConstructor
+public enum AccreditationRecordConstants {
+    /*
+        审核状态
+        1. 通过
+        2. 拒绝
+        3. 驳回
+        4. 撤回
+        5. 撤销
+     */
+    AUDIT_STATUS_PASS(1,"通过"),
+    AUDIT_STATUS_REJECT(2,"拒绝"),
+    AUDIT_STATUS_DISAPPROVE(3,"驳回"),
+    AUDIT_STATUS_WITHDRAWS(4,"撤回"),
+    AUDIT_STATUS_CANCEL(5,"撤销"),
+    /*
+        记录类型
+        1. 退住
+        2. 请假
+        3. 入住
+     */
+    RECORD_TYPE_CHECK_OUT(1,"退住"),
+    RECORD_TYPE_LEAVE(2,"请假"),
+    RECORD_TYPE_CHECK_IN(3,"入住"),
+    /*
+        处理类型
+        0. 已审批
+        1. 已处理
+     */
+    RECORD_HANDLE_TYPE_AUDIT(0,"已审批"),
+    RECORD_HANDLE_TYPE_PROCESSED(1,"已处理");
+
+
+
+
+    /**
+     * 编码
+     * 代表枚举值的状态码
+     */
+    public int code;
+    /**
+     * 信息
+     * 与状态码对应的描述信息
+     */
+    public String msg;
+
+}

+ 32 - 0
kyl/kyl-service/src/main/java/com/kyl/constant/PendingTasksConstant.java

@@ -0,0 +1,32 @@
+package com.kyl.constant;
+
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title PendingTasksConstant
+ * @description
+ * @create 2026/3/29
+ */
+public class PendingTasksConstant {
+
+    //状态(1:申请中,2:已完成,3:已关闭)
+    public static final Integer TASK_STATUS_APPLICATION = 1;
+    public static final Integer TASK_STATUS_FINISHED = 2;
+    public static final Integer TASK_STATUS_CLOSED = 3;
+
+
+    //类型(1:退住,2:请假,3:入住)
+    public static final Integer TASK_TYPE_RETREAT = 1;
+    public static final Integer TASK_TYPE_LEAVE = 2;
+    public static final Integer TASK_TYPE_CHECK_IN = 3;
+
+
+    /**
+     * 是否处理完成
+     *  0:未处理
+     *  1:已处理
+     */
+    public static final Integer TASK_IS_HANDLE_UNTREATED = 0;
+    public static final Integer TASK_IS_HANDLE_FINISHED = 1;
+}

+ 51 - 0
kyl/kyl-service/src/main/java/com/kyl/constant/RetreatConstant.java

@@ -0,0 +1,51 @@
+package com.kyl.constant;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title RetreatConstant
+ * @description
+ * @create 2026/3/29
+ */
+public class RetreatConstant {
+
+    /**
+     * 法务部门编号
+     */
+    public static final String LEGAL_DEPT_CODE = "100001007000000";
+
+    /**
+     * 护理部 部门编号
+     */
+    public static final String NURSING_DEPT_CODE = "100001005000000";
+
+    /**
+     * 财务部门编号
+     */
+    public static final String SETTLEMENT_DEPT_CODE = "100001002000000";
+
+    /**
+     * 院长办公室部门编号
+     */
+    public static final String DEAN_OFFICE_DEPT_CODE = "100001001000000";
+
+
+    /**
+     * 退住业务-审核步骤编号
+     * 0:发起申请
+     * 1:护理组长审批
+     * 2:法务解除合同
+     * 3:结算员调整账单
+     * 4:结算组长审批
+     * 5:副院长审批
+     * 6:结算员结清费用
+     */
+    public static final Integer ACCRADITATION_STEP_NO_ZERO = 0;
+    public static final Integer ACCRADITATION_STEP_NO_ONE = 1;
+    public static final Integer ACCRADITATION_STEP_NO_TWO = 2;
+    public static final Integer ACCRADITATION_STEP_NO_THREE = 3;
+    public static final Integer ACCRADITATION_STEP_NO_FOUR = 4;
+    public static final Integer ACCRADITATION_STEP_NO_FIVE = 5;
+    public static final Integer ACCRADITATION_STEP_NO_SIX = 6;
+
+}

+ 0 - 22
kyl/kyl-service/src/main/java/com/kyl/dto/ElderDto.java

@@ -11,40 +11,18 @@ import lombok.Data;
 @Data
 @ApiModel(value = "老人实体类", description = "前端传入的参数对象")
 public class ElderDto extends BaseDto {
-
-    /**
-     * 姓名
-     */
     @ApiModelProperty(value = "姓名")
     private String name;
-
-    /**
-     * 头像
-     */
     @ApiModelProperty(value = "头像")
     private String image;
-
-    /**
-     * 状态
-     */
     @ApiModelProperty(value = "状态")
     private Integer status;
-
-    /**
-     * 身份证号
-     */
     @ApiModelProperty(value = "身份证号")
     private String idCardNo;
-
-    /**
-     * 手机号
-     */
     @ApiModelProperty(value = "手机号")
     private String phone;
-
     @ApiModelProperty(value = "年龄")
     private String age;
-
     @ApiModelProperty(value = "性别")
     private String sex;
 }

+ 0 - 30
kyl/kyl-service/src/main/java/com/kyl/entity/Elder.java

@@ -11,52 +11,22 @@ import lombok.Data;
 @Data
 @ApiModel(value = "老人实体类", description = "对应数据库中老人表结构")
 public class Elder extends BaseEntity {
-
-    /**
-     * 姓名
-     */
     @ApiModelProperty("姓名")
     private String name;
-
-    /**
-     * 头像
-     */
     @ApiModelProperty("头像")
     private String image;
-
-    /**
-     * 状态(0:禁用,1:启用  2:请假 3:退住中 4入住中 5已退住)
-     */
     @ApiModelProperty("状态(0:禁用,1:启用  2:请假 3:退住中 4入住中 5已退住)")
     private Integer status;
-
-    /**
-     * 身份证号
-     */
     @ApiModelProperty("身份证号")
     private String idCardNo;
-
-    /**
-     * 手机号
-     */
     @ApiModelProperty("手机号")
     private String phone;
-
     @ApiModelProperty(value = "年龄")
     private String age;
-
     @ApiModelProperty(value = "性别")
     private String sex;
-
-    /**
-     * 床位编号
-     */
     @ApiModelProperty("床位编号")
     private String bedNumber;
-
-    /**
-     * 床位ID
-     */
     @ApiModelProperty("床位ID")
     private Long bedId;
 

+ 4 - 0
kyl/kyl-service/src/main/java/com/kyl/entity/FlowInfo.java

@@ -2,11 +2,15 @@ package com.kyl.entity;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Date;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 @ApiModel(value = "流程信息实体类", description = "对应数据库中流程信息表结构")
 public class FlowInfo {
     @ApiModelProperty(value = "主键")

+ 59 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/AccreditationRecordMapper.java

@@ -0,0 +1,59 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.AccreditationRecord;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+
+/**
+ * 审批记录表 Mapper接口
+ */
+@Mapper
+public interface AccreditationRecordMapper {
+
+    /**
+     * 新增审批记录
+     */
+    int insert(AccreditationRecord record);
+
+    /**
+     * 根据ID删除
+     */
+    int deleteById(Long id);
+
+    /**
+     * 根据ID更新(全字段)
+     */
+    int updateById(AccreditationRecord record);
+
+    /**
+     * 根据ID查询
+     */
+    AccreditationRecord selectById(Long id);
+
+    /**
+     * 动态条件查询列表
+     */
+    List<AccreditationRecord> selectList(@Param("query") AccreditationRecord query);
+
+    /**
+     * 批量插入
+     */
+    int batchInsert(@Param("list") List<AccreditationRecord> list);
+
+    @Select("select * from accraditation_record where bussniess_id = #{bussniessId} and type = #{type} order by step_no")
+    public List<AccreditationRecord> getAccraditationRecordByBuisId(@Param("bussniessId")long bussniessId, @Param("type")Integer type);
+
+    @Select("select * from accraditation_record where bussniess_id = #{bussniessId} and type = #{type} order by step_no desc limit 1")
+    public AccreditationRecord getLastByBuisId(@Param("bussniessId")long bussniessId, @Param("type")Integer type);
+
+    @Delete("delete from accraditation_record where id =  #{id}")
+    void delete(long id);
+
+    @Select("select * from accraditation_record where bussniess_id = #{bussniessId} and type = #{type} order by step_no ASC limit 1")
+    AccreditationRecord getFirstByBuisId(@Param("bussniessId")Long bussniessId, @Param("type")Integer type);
+}

+ 43 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/BalanceMapper.java

@@ -0,0 +1,43 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.Balance;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ * 余额表 Mapper接口
+ */
+@Mapper
+public interface BalanceMapper {
+
+    /**
+     * 新增余额记录
+     */
+    int insert(Balance balance);
+
+    /**
+     * 根据ID删除
+     */
+    int deleteById(Long id);
+
+    /**
+     * 根据ID动态更新
+     */
+    int updateById(Balance balance);
+
+    /**
+     * 根据ID查询
+     */
+    Balance selectById(Long id);
+
+    /**
+     * 动态条件查询列表
+     */
+    List<Balance> selectList(@Param("query") Balance query);
+
+    /**
+     * 批量插入
+     */
+    int batchInsert(@Param("list") List<Balance> list);
+}

+ 43 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/BillMapper.java

@@ -0,0 +1,43 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.Bill;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ * 账单表 Mapper接口
+ */
+@Mapper
+public interface BillMapper {
+
+    /**
+     * 新增账单
+     */
+    int insert(Bill bill);
+
+    /**
+     * 根据ID删除
+     */
+    int deleteById(Long id);
+
+    /**
+     * 根据ID动态更新
+     */
+    int updateById(Bill bill);
+
+    /**
+     * 根据ID查询
+     */
+    Bill selectById(Long id);
+
+    /**
+     * 动态条件查询列表
+     */
+    List<Bill> selectList(@Param("query") Bill query);
+
+    /**
+     * 批量插入
+     */
+    int batchInsert(@Param("list") List<Bill> list);
+}

+ 44 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/CheckInConfigMapper.java

@@ -0,0 +1,44 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.CheckInConfig;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ *
+ * 入住配置表 Mapper接口
+ */
+@Mapper
+public interface CheckInConfigMapper {
+
+    /**
+     * 新增入住配置
+     */
+    int insert(CheckInConfig config);
+
+    /**
+     * 根据ID删除
+     */
+    int deleteById(Long id);
+
+    /**
+     * 根据ID动态更新
+     */
+    int updateById(CheckInConfig config);
+
+    /**
+     * 根据ID查询
+     */
+    CheckInConfig selectById(Long id);
+
+    /**
+     * 动态条件查询列表
+     */
+    List<CheckInConfig> selectList(@Param("query") CheckInConfig query);
+
+    /**
+     * 批量插入
+     */
+    int batchInsert(@Param("list") List<CheckInConfig> list);
+}

+ 65 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/CheckInMapper.java

@@ -0,0 +1,65 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.CheckIn;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 入住申请表 Mapper 接口
+ *
+ * @author 编程助手
+ * @date 2026-03-22
+ */
+@Mapper // 按要求添加MyBatis的Mapper注解
+public interface CheckInMapper {
+
+    /**
+     * 新增入住申请
+     *
+     * @param checkIn 入住申请实体
+     * @return 影响行数
+     */
+    int insertCheckIn(CheckIn checkIn);
+
+    /**
+     * 根据ID删除入住申请
+     *
+     * @param id 申请ID
+     * @return 影响行数
+     */
+    int deleteCheckInById(@Param("id") Long id);
+
+    /**
+     * 根据ID更新入住申请(动态更新非空字段)
+     *
+     * @param checkIn 入住申请实体
+     * @return 影响行数
+     */
+    int updateCheckInById(CheckIn checkIn);
+
+    /**
+     * 根据ID查询入住申请详情
+     *
+     * @param id 申请ID
+     * @return 入住申请实体
+     */
+    CheckIn selectCheckInById(@Param("id") Long id);
+
+    /**
+     * 多条件查询入住申请列表
+     *
+     * @param checkIn 查询条件(支持老人ID、流程状态、审核状态、申请人等)
+     * @return 入住申请列表
+     */
+    List<CheckIn> selectCheckInList(CheckIn checkIn);
+
+    /**
+     * 根据老人ID查询入住申请记录
+     *
+     * @param elderId 老人ID
+     * @return 入住申请列表
+     */
+    List<CheckIn> selectCheckInByElderId(@Param("elderId") Long elderId);
+}

+ 81 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/ContractMapper.java

@@ -0,0 +1,81 @@
+package com.kyl.mapper;
+
+import com.kyl.entity.Contract;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 合同表 Mapper 接口
+ * 包含基础增删改查及合同业务专属查询能力
+ */
+@Mapper
+public interface ContractMapper {
+
+    /**
+     * 新增合同记录
+     * @param contract 合同实体
+     * @return 受影响行数
+     */
+    int insert(Contract contract);
+
+    /**
+     * 根据ID删除合同记录
+     * @param id 主键ID
+     * @return 受影响行数
+     */
+    int deleteById(Long id);
+
+    /**
+     * 批量删除合同记录
+     * @param ids 主键ID集合
+     * @return 受影响行数
+     */
+    int deleteBatchIds(@Param("ids") List<Long> ids);
+
+    /**
+     * 根据ID更新合同记录(动态更新非空字段)
+     * @param contract 合同实体
+     * @return 受影响行数
+     */
+    int updateById(Contract contract);
+
+    /**
+     * 根据ID查询合同记录
+     * @param id 主键ID
+     * @return 合同实体
+     */
+    Contract selectById(Long id);
+
+    /**
+     * 多条件查询合同列表
+     * 支持:老人ID、会员ID、合同状态、合同编号、时间范围等条件组合
+     * @param contract 查询条件
+     * @return 合同记录列表
+     */
+    List<Contract> selectList(Contract contract);
+
+    /**
+     * 根据老人ID查询合同(单条,老人唯一有效合同)
+     * @param elderId 老人ID
+     * @return 合同实体
+     */
+    Contract selectByElderId(Long elderId);
+
+    /**
+     * 根据合同编号查询合同
+     * @param contractNo 合同编号
+     * @return 合同实体
+     */
+    Contract selectByContractNo(@Param("contractNo") String contractNo);
+
+    /**
+     * 查询指定状态的有效合同(未过期+指定状态)
+     * @param status 合同状态
+     * @param currentTime 当前时间(用于判断未过期)
+     * @return 合同列表
+     */
+    List<Contract> selectValidContractByStatus(@Param("status") Integer status, @Param("currentTime") LocalDateTime currentTime);
+}

+ 67 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/ElderMapper.java

@@ -0,0 +1,67 @@
+package com.kyl.mapper;
+
+
+import com.kyl.entity.Elder;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title ElderMapper
+ * @description
+ * @create 2026/3/22
+ */
+@Mapper
+public interface ElderMapper {
+
+    /**
+     * 新增老人信息
+     *
+     * @param elder 老人实体
+     * @return 影响行数
+     */
+    int insertElder(Elder elder);
+
+    /**
+     * 根据ID删除老人信息
+     *
+     * @param id 老人ID
+     * @return 影响行数
+     */
+    int deleteElderById(@Param("id") Long id);
+
+    /**
+     * 根据ID更新老人信息(动态更新,只更新非空字段)
+     *
+     * @param elder 老人实体
+     * @return 影响行数
+     */
+    int updateElderById(Elder elder);
+
+    /**
+     * 根据ID查询老人信息
+     *
+     * @param id 老人ID
+     * @return 老人实体
+     */
+    Elder selectElderById(@Param("id") Long id);
+
+    /**
+     * 条件查询老人列表(支持多条件组合查询)
+     *
+     * @param elder 查询条件(支持姓名、身份证号、状态、手机号等)
+     * @return 老人列表
+     */
+    List<Elder> selectElderList(Elder elder);
+
+    /**
+     * 根据身份证号查询老人信息
+     *
+     * @param idCardNo 身份证号
+     * @return 老人实体
+     */
+    Elder selectElderByIdCardNo(@Param("idCardNo") String idCardNo);
+}

+ 25 - 0
kyl/kyl-service/src/main/java/com/kyl/mapper/HiActinstMapper.java

@@ -0,0 +1,25 @@
+package com.kyl.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+/**
+ * 活动信息表
+ * @author wanjl
+ */
+@Mapper
+public interface HiActinstMapper {
+
+    /**
+     * 删除活动历史信息,在任意跳转和
+     * @param taskId
+     */
+    @Delete("delete from ACT_HI_ACTINST  where task_id_ = #{taskId}")
+    void deleteHiActivityInstByTaskId(@Param("taskId") String taskId);
+
+
+    @Update("update ACT_HI_TASKINST  set END_TIME_ = null where id_ = #{taskId}")
+    void unDoHiTaskInstByTaskId(@Param("taskId") String taskId);
+}

+ 64 - 0
kyl/kyl-service/src/main/java/com/kyl/service/AccreditationRecordService.java

@@ -0,0 +1,64 @@
+package com.kyl.service;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.kyl.entity.AccreditationRecord;
+import com.kyl.entity.UserRole;
+import com.kyl.mapper.AccreditationRecordMapper;
+import com.kyl.mapper.UserRoleMapper;
+import com.kyl.utils.ObjectUtil;
+import com.kyl.vo.RecordVo;
+import com.kyl.vo.UserRoleVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title AccreditationRecordService
+ * @description
+ * @create 2026/3/29
+ */
+@Service
+public class AccreditationRecordService {
+    @Autowired
+    private StringRedisTemplate redisTemplate;
+    private static final String RECORD_STEP_NO_PREFIX = "RECORD:";  //审批步骤编号前缀
+    @Autowired
+    private UserRoleMapper userRoleMapper;
+    @Autowired
+    AccreditationRecordMapper accreditationRecordMapper;
+    /**
+     * 保存审核记录
+     */
+    public void saveRecord(RecordVo recordVo){
+        AccreditationRecord record = new AccreditationRecord();
+        record.setApproverId(recordVo.getUserId());//审批人id
+        record.setBussniessId(recordVo.getId());//业务id
+        record.setCreateTime(LocalDateTime.now());//创建时间
+        record.setType(recordVo.getType());//审批类型
+        record.setOpinion(recordVo.getOption());//审批意见
+        record.setApproverName(recordVo.getRealName());//审批人姓名
+        record.setCurrentStep(recordVo.getStep());//当前审核步骤
+        record.setAuditStatus(recordVo.getStatus());//审批状态
+        record.setHandleType(recordVo.getHandleType());//处理类型
+        //审批步骤--是自增的
+        record.setStepNo(redisTemplate.boundValueOps(RECORD_STEP_NO_PREFIX+recordVo.getId()).increment());
+        //寻找下一个审核人
+        if (ObjectUtil.isNotEmpty(recordVo.getNextAssignee())){
+            //获取审核人的姓名和角色---审核人姓名、审核人角色、审核人id
+            List<UserRoleVo> userRoleList =userRoleMapper.selectByUserId(recordVo.getNextAssignee());
+            UserRoleVo userRoleVo = userRoleList.get(0);    //获取审核人信息
+            record.setNextApproverRole(userRoleVo.getRoleName());//下一个审核人角色
+            record.setNextApprover(userRoleVo.getUserName());//下一个审核人姓名
+            record.setNextApproverId(recordVo.getNextAssignee());//下一个审核人id
+            record.setNextStep(recordVo.getNextStep());//下一个审核步骤
+        }
+        accreditationRecordMapper.insert(record);//保存审核记录
+
+    }
+}

+ 111 - 0
kyl/kyl-service/src/main/java/com/kyl/service/ActFlowCommService.java

@@ -0,0 +1,111 @@
+package com.kyl.service;
+
+import com.kyl.base.PageResponse;
+import com.kyl.dto.PendingTasksDto;
+import com.kyl.entity.*;
+import org.activiti.engine.runtime.ProcessInstance;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author wanjl
+ */
+public interface ActFlowCommService {
+
+
+    /**
+     * 获取当前办理人id
+     * @param formKey
+     * @param bussinessKey
+     * @return
+     */
+    public Long getNextAssignee(String formKey, String bussinessKey);
+
+
+    /**
+     * 部署流程定义
+     */
+    public void saveNewDeploy(FlowInfo flowInfo) ;
+
+    /**
+     * 启动流程实例
+     */
+    public ProcessInstance startProcess(String formKey, Map<String, Object> variables, String bussinessKey, Long id) ;
+
+    /**
+     * 查看个人任务列表
+     */
+    public List<Map<String, Object>> myTaskList(String userid);
+
+    /**
+     * 查看个人任务信息
+     * @param pendingTasksDto
+     */
+    public PageResponse<PendingTasks> myTaskInfoList(PendingTasksDto pendingTasksDto) ;
+
+
+    /**
+     * 完成提交任务
+     */
+    public void completeProcess(String title, String taskId, String userId, Integer code, Integer status) ;
+
+    public void start(Long id, String formKey, User user, Map<String, Object> variables, boolean autoFinished) ;
+
+    /**
+     * 关闭 思路:改变流程当前节点的下一个节点为空 并完成这个节点的任务,并删除痕迹
+     * @param taskId 任务id
+     * @param status 状态 1申请中 2已完成 3已关闭
+     */
+    public void closeProcess(String taskId, Integer status) ;
+
+    /**
+     * 是否查看当前审核用户的任务
+     * @param taskId
+     * @param status
+     * @param checkIn
+     * @return
+     */
+    public Integer isCurrentUserAndStep(String taskId, Integer status, CheckIn checkIn) ;
+
+
+    /**
+     * 是否查看当前审核用户的任务
+     * @param taskId
+     * @param status
+     * @param retreat
+     * @return
+     */
+    public Integer isCurrentUserAndStep(String taskId, Integer status, Retreat retreat) ;
+
+
+    /**
+     * 驳回任务
+     * @param taskId
+     * @param first 是否默认退回流程第一个节点,true 是,false默认是上一个节点,
+     */
+    public void rollBackTask(String taskId, boolean first);
+
+    /**
+     * 撤回任务
+     * @param taskId
+     * @param first 是否默认退回流程第一个节点,true 是,false默认是上一个节点,
+     */
+    public void withdrawTask(String taskId, boolean first);
+
+    /**
+     * 跳转任务
+     * @param taskId
+     * @param first 是否默认跳转流程第一个节点,true 是,false默认是上一个节点,
+     */
+    public void jumpTask(String taskId, boolean first);
+
+    /**
+     * 跳转任意节点
+     *
+     * @param taskId 当前操作节点
+     * @param first 是否默认第一 是否驳回
+     */
+    public void anyJump(String taskId, boolean first) ;
+
+}

+ 572 - 0
kyl/kyl-service/src/main/java/com/kyl/service/ActFlowCommServiceImpl.java

@@ -0,0 +1,572 @@
+package com.kyl.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.kyl.base.PageResponse;
+import com.kyl.constant.PendingTasksConstant;
+import com.kyl.dto.PendingTasksDto;
+import com.kyl.entity.*;
+import com.kyl.mapper.AccreditationRecordMapper;
+import com.kyl.mapper.HiActinstMapper;
+import com.kyl.utils.ObjectUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.activiti.bpmn.model.*;
+import org.activiti.bpmn.model.Process;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricActivityInstanceQuery;
+import org.activiti.engine.history.HistoricTaskInstance;
+import org.activiti.engine.history.HistoricTaskInstanceQuery;
+import org.activiti.engine.impl.identity.Authentication;
+import org.activiti.engine.repository.Deployment;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.activiti.engine.task.TaskInfo;
+import org.activiti.engine.task.TaskQuery;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+@Transactional
+public class ActFlowCommServiceImpl implements ActFlowCommService {
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    private HistoryService historyService;
+
+    @Autowired
+    private HiActinstMapper hiActinstMapper;
+
+    @Autowired
+    private AccreditationRecordMapper accraditationRecordMapper;
+
+
+    @Override
+    public Long getNextAssignee(String formKey, String bussinessKey) {
+        Task task = taskService.createTaskQuery()
+                .processDefinitionKey(formKey) //流程Key
+                .processInstanceBusinessKey(bussinessKey)
+                .singleResult();
+        if (task != null) {
+            return Long.valueOf(task.getAssignee());
+        }
+        return null;
+    }
+
+    /**
+     * 部署流程定义
+     */
+    @Override
+    public void saveNewDeploy(FlowInfo flowInfo) {
+        Deployment deployment = repositoryService.createDeployment()
+                .addClasspathResource(flowInfo.getFilePath())
+                .name(flowInfo.getFlowName())
+                .key(flowInfo.getFlowKey())
+                .deploy();
+        System.out.println("流程部署id:" + deployment.getId());
+        System.out.println("流程部署名称:" + deployment.getName());
+    }
+
+    /**
+     * 启动流程实例
+     */
+    @Override
+    public ProcessInstance startProcess(String formKey, Map<String, Object> variables, String bussinessKey, Long id) {
+        variables.put("bussinessKey", bussinessKey);
+        //启动流程
+        log.info("【启动流程】,formKey :{},bussinessKey:{}", formKey, bussinessKey);
+        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(formKey, bussinessKey, variables);
+        //流程实例ID
+        String processDefinitionId = processInstance.getProcessDefinitionId();
+        log.info("【启动流程】- 成功,processDefinitionId:{}", processDefinitionId);
+        return processInstance;
+    }
+
+    /**
+     * 查看个人任务列表
+     */
+    @Override
+    public List<Map<String, Object>> myTaskList(String userid) {
+
+        /**
+         * 根据负责人id  查询任务
+         */
+        TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(userid);
+
+        List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();
+
+        List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
+        for (Task task : list) {
+            Map<String, Object> map = new HashMap<String, Object>();
+            map.put("taskid", task.getId());
+            map.put("taskname", task.getName());
+            map.put("description", task.getDescription());
+            map.put("priority", task.getPriority());
+            map.put("owner", task.getOwner());
+            map.put("assignee", task.getAssignee());
+            map.put("delegationState", task.getDelegationState());
+            map.put("processInstanceId", task.getProcessInstanceId());
+            map.put("executionId", task.getExecutionId());
+            map.put("processDefinitionId", task.getProcessDefinitionId());
+            map.put("createTime", task.getCreateTime());
+            map.put("taskDefinitionKey", task.getTaskDefinitionKey());
+            map.put("dueDate", task.getDueDate());
+            map.put("category", task.getCategory());
+            map.put("parentTaskId", task.getParentTaskId());
+            map.put("tenantId", task.getTenantId());
+            listmap.add(map);
+        }
+
+        return listmap;
+    }
+
+    /**
+     * 查看个人任务信息
+     * @param pendingTasksDto
+     */
+    @Override
+    public PageResponse<PendingTasks> myTaskInfoList(PendingTasksDto pendingTasksDto) {
+
+        /**
+         * 根据负责人id  查询任务
+         */
+        HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery();
+
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getIsHandle())) {
+            //是否是待处理
+            if (pendingTasksDto.getIsHandle() == 1) {
+                taskQuery.finished();
+            } else {
+                taskQuery.unfinished();
+            }
+        }
+
+        //判断是我的申请还是我的待办
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getApplicatId())) {
+            taskQuery.taskAssignee(pendingTasksDto.getApplicatId().toString());
+            taskQuery.processVariableValueEquals("assignee0", pendingTasksDto.getApplicatId());
+            taskQuery.taskNameLike("%申请");
+        } else {
+            taskQuery.taskAssignee(pendingTasksDto.getAssigneeId().toString());
+            taskQuery.taskNameLike("%处理");
+        }
+        //时间范围
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getStartTime()) && ObjectUtil.isNotEmpty(pendingTasksDto.getEndTime())) {
+            taskQuery.taskCreatedAfter(pendingTasksDto.getStartTime()).taskCreatedBefore(pendingTasksDto.getEndTime());
+        }
+        //单据类别(1:退住,2:请假,3:入住)
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getType())) {
+            taskQuery.processVariableValueEquals("processType", pendingTasksDto.getType());
+        }
+        //请求的任务ID
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getCode())) {
+            taskQuery.processVariableValueEquals("processCode", pendingTasksDto.getCode());
+        }
+
+        //任务状态(1:申请中,2:已完成,3:已关闭)
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getStatus())) {
+            taskQuery.processVariableValueEquals("processStatus", pendingTasksDto.getStatus());
+        }
+        //模糊查询当前申请人的单据
+        if (ObjectUtil.isNotEmpty(pendingTasksDto.getApplicat())) {
+            taskQuery.processVariableValueLike("assignee0Name", "%" + pendingTasksDto.getApplicat() + "%");
+        }
+
+        //统计条数
+        long count = taskQuery.count();
+        //执行查询
+        List<HistoricTaskInstance> list = taskQuery.includeProcessVariables().orderByHistoricTaskInstanceStartTime().desc().listPage((pendingTasksDto.getPageNum() - 1) * pendingTasksDto.getPageSize(), pendingTasksDto.getPageSize());
+
+
+        //log.info(" 任务查询 {} " , taskQuery);
+        //封装数据
+        List<PendingTasks> pendingTasks = new ArrayList<>();
+        for (HistoricTaskInstance task : list) {
+
+            Map<String, Object> variableInstances = task.getProcessVariables();
+            PendingTasks pendingTask = new PendingTasks();
+            pendingTask.setId(task.getId());
+            pendingTask.setCode(variableInstances.get("processCode").toString());
+
+            pendingTask.setType(Integer.parseInt(variableInstances.get("processType").toString()));
+
+            pendingTask.setTitle(variableInstances.get("processTitle").toString());
+            pendingTask.setApplicat(variableInstances.get("assignee0Name").toString());
+            pendingTask.setStatus(Integer.parseInt(variableInstances.get("processStatus").toString()));
+            pendingTask.setAssigneeId(Long.valueOf(task.getAssignee()));
+
+            Long bussinessId = Long.parseLong(variableInstances.get("bussinessKey").toString().split(":")[1]);
+            pendingTask.setApplicationTime(getStartTime(bussinessId, pendingTask.getType()));
+            if (!pendingTask.getStatus().equals(PendingTasksConstant.TASK_STATUS_APPLICATION)) {
+                pendingTask.setFinishTime(getFinishTime(bussinessId, pendingTask.getType()));
+            }
+            pendingTask.setCheckInId(bussinessId);
+            pendingTasks.add(pendingTask);
+        }
+        //按照申请时间倒序查询
+        List<PendingTasks> tasks = pendingTasks.stream()
+                .sorted(Comparator.comparing(PendingTasks::getApplicationTime).reversed())
+                .collect(Collectors.toList());
+        //数据返回,逻辑分页
+        return PageResponse.of(tasks, pendingTasksDto.getPageNum(), pendingTasksDto.getPageSize(), (count + pendingTasksDto.getPageSize() - 1) / pendingTasksDto.getPageSize(), count);
+    }
+
+    private LocalDateTime getStartTime(Long id, Integer type) {
+        return accraditationRecordMapper.getFirstByBuisId(id, type).getCreateTime();
+    }
+
+    private LocalDateTime getFinishTime(Long id, Integer type) {
+        return accraditationRecordMapper.getLastByBuisId(id, type).getCreateTime();
+    }
+
+
+    /**
+     * 完成提交任务
+     */
+    @Override
+    public void completeProcess(String title, String taskId, String userId, Integer code, Integer status) {
+        //任务Id 查询任务对象
+        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+
+        if (task == null) {
+            log.error("completeProcess - task is null!!");
+            return;
+        }
+
+
+        //任务对象  获取流程实例Id
+        String processInstanceId = task.getProcessInstanceId();
+
+        Authentication.setAuthenticatedUserId(userId);
+
+        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId);
+        List<HistoricTaskInstance> list = historicTaskInstanceQuery.list();
+        if (CollUtil.isNotEmpty(list)) {
+            list.forEach(v -> {
+                if (v.getFormKey().equals((Integer.parseInt(task.getFormKey()) + 1) + "")) {
+                    historyService.deleteHistoricTaskInstance(v.getId());
+                }
+                if (code.equals(3) && (v.getFormKey().equals("0"))) {
+                    historyService.deleteHistoricTaskInstance(v.getId());
+                }
+            });
+        }
+        //完成办理
+        Map<String, Object> variables = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(status)) {
+            variables.put("processStatus", status);
+        }
+        if (ObjectUtil.isNotEmpty(title)) {
+            variables.put("processTitle", title);
+        }
+        variables.put("ops", code);
+        taskService.complete(taskId, variables);
+    }
+
+    @Override
+    public void start(Long id, String formKey, User user, Map<String, Object> variables, boolean autoFinished) {
+        //使用流程变量设置字符串(格式 : Evection:Id 的形式)
+        //使用正在执行对象表中的一个字段BUSINESS_KEY(Activiti提供的一个字段),让启动的流程(流程实例)关联业务
+        String bussinessKey = formKey + ":" + id;
+        ProcessInstance processInstance = startProcess(formKey, variables, bussinessKey, id);
+        //	流程实例ID
+        String processDefinitionId = processInstance.getProcessDefinitionId();
+        log.info("processDefinitionId is {}", processDefinitionId);
+        List<Map<String, Object>> taskList = myTaskList(user.getId().toString());
+        if (!CollectionUtils.isEmpty(taskList)) {
+            for (Map<String, Object> map : taskList) {
+                if (map.get("assignee").toString().equals(user.getId().toString()) &&
+                        map.get("processDefinitionId").toString().equals(processDefinitionId)) {
+                    log.info("processDefinitionId is {}", map.get("processDefinitionId").toString());
+                    log.info("taskid is {}", map.get("taskid").toString());
+                    if (autoFinished) {
+                        completeProcess("", map.get("taskid").toString(), user.getId().toString(), 1, PendingTasksConstant.TASK_STATUS_APPLICATION);
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * 撤销思路
+     *  - 设置流程变量为已结束
+     *  - 删除流程实例
+     *
+     * @param taskId 任务id
+     * @param status 状态 1申请中 2已完成 3已关闭
+     */
+    @Override
+    public void closeProcess(String taskId, Integer status) {
+
+        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
+        // 从任务中拿到流程实例id
+        String processInstanceId = historicTaskInstance.getProcessInstanceId();
+
+        //设置流程变量
+        String executionId = taskService.createTaskQuery().processInstanceId(processInstanceId).list().get(0).getExecutionId();
+        // 设置参数
+        Map<String, Object> variable = new HashMap<>();
+        // 设置为已关闭
+        variable.put("processStatus", status);
+        //记录流程变量
+        runtimeService.setVariables(executionId, variable);
+        //删除流程实例
+        runtimeService.deleteProcessInstance(processInstanceId,"申请人撤销");
+
+    }
+
+    /**
+     * 是否查看当前审核用户的任务
+     *
+     * @param taskId
+     * @param status
+     * @param checkIn
+     * @return
+     */
+    @Override
+    public Integer isCurrentUserAndStep(String taskId, Integer status, CheckIn checkIn) {
+        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
+        if (checkIn.getFlowStatus().equals(status) && checkIn.getStatus().equals(CheckIn.Status.APPLICATION.getCode())) {
+            if (historicTaskInstance.getFormKey().equals(checkIn.getFlowStatus().toString())) {
+                return 1;
+            }
+            return 0;
+        }
+        if (historicTaskInstance.getFormKey().equals((checkIn.getFlowStatus() - 1) + "") && checkIn.getStatus().equals(CheckIn.Status.APPLICATION.getCode())) {
+            return 2;
+        }
+        return 3;
+    }
+
+
+    /**
+     * 是否查看当前审核用户的任务
+     * @param taskId
+     * @param status
+     * @param retreat
+     * @return
+     */
+    @Override
+    public Integer isCurrentUserAndStep(String taskId, Integer status, Retreat retreat) {
+        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
+        if (retreat.getFlowStatus().equals(status) && retreat.getStatus().equals(CheckIn.Status.APPLICATION.getCode())) {
+            if (historicTaskInstance.getFormKey().equals(retreat.getFlowStatus().toString())) {
+                return 1;
+            }
+            return 0;
+        }
+        if (historicTaskInstance.getFormKey().equals((retreat.getFlowStatus() - 1) + "") && retreat.getStatus().equals(CheckIn.Status.APPLICATION.getCode())) {
+            return 2;
+        }
+        return 3;
+    }
+
+
+    /**
+     * 驳回任务
+     * @param taskId
+     * @param first  是否默认退回流程第一个节点,true 是,false默认是上一个节点
+     */
+    @Override
+    public void rollBackTask(String taskId, boolean first) {
+        anyJump(taskId, first);
+    }
+
+    /**
+     * 撤回任务
+     *
+     * @param taskId
+     * @param first  是否默认退回流程第一个节点,true 是,false默认是上一个节点,
+     */
+    @Override
+    public void withdrawTask(String taskId, boolean first) {
+        anyJump(taskId, first);
+    }
+
+    /**
+     * 跳转任务
+     *
+     * @param taskId
+     * @param first  是否默认跳转流程第一个节点,true 是,false默认是上一个节点,
+     */
+    @Override
+    public void jumpTask(String taskId, boolean first) {
+        anyJump(taskId, first);
+    }
+
+    /**
+     * 跳转任意节点
+     *
+     * @param taskId 当前操作节点
+     * @param first  是否默认第一 是否驳回
+     */
+    @Override
+    public void anyJump(String taskId, boolean first) {
+        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
+        //实例定义id:checkIn:1:0f97a26d-5697-11ee-bf3f-5405db5be13e
+        String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
+        //实例id:16ea626d-5755-11ee-849a-5405db5be13e
+        String processInstanceId = historicTaskInstance.getProcessInstanceId();
+        // 对上一个节点和发起节点的支持:Activity_0pnd103
+        String activityId = null;
+        //找到需要驳回的节点中,比如:现在是:养老顾问-入住配置,那么要找的就是上一个节点:副院长-审批
+        HistoricActivityInstance targetActivity = getRejectTargetActivity(null, processInstanceId, first);
+        if (targetActivity != null) {
+            activityId = targetActivity.getActivityId();
+        }
+        if (StrUtil.isEmpty(activityId)) {
+            return;
+        }
+        try {
+            //获取流程中的bpmn文件
+            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
+            //流程实例
+            Process process = bpmnModel.getMainProcess();
+            // 解析调整的目标节点
+            //找到目标节点  -->  副院长-审批
+            FlowNode targetFlowNode = (FlowNode) process.getFlowElement(activityId);
+            //找到当前节点的所有连线
+            List<SequenceFlow> incomingFlows = targetFlowNode.getIncomingFlows();
+
+            List<SequenceFlow> targetSequenceFlow = new ArrayList<>();
+            //遍历所有连线
+            for (SequenceFlow incomingFlow : incomingFlows) {
+                //连线的入节点
+                FlowNode source = (FlowNode) incomingFlow.getSourceFlowElement();
+                List<SequenceFlow> sequenceFlows;
+                if (source instanceof ParallelGateway) {// 如果是并行网关同级节点,则跳转到所有节点
+                    sequenceFlows = source.getOutgoingFlows();
+                } else {
+                    sequenceFlows = source.getOutgoingFlows();// 否则直接跳转到对应节点,包括为执行过的节点
+                }
+                targetSequenceFlow.addAll(sequenceFlows);
+            }
+            //获取当前任务中的所有待执行的任务
+            List<Task> list = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
+            for (Task t : list) {
+                //把一个任务动态转向目标节点
+                //参数1:目标节点   参数2:当前任务   参数3:当前任务id    参数4:目标节点所有连线   参数5:默认flase,找上一个节点
+                trunToTarget(process, t, first ? taskId : list.get(0).getId(), targetSequenceFlow, first);
+            }
+            if (!first) { // 撤回 删除最后的节点
+                historyService.deleteHistoricTaskInstance(taskId);
+                hiActinstMapper.deleteHiActivityInstByTaskId(taskId);
+            } else {
+                // 撤回 删除第一个
+                List<HistoricTaskInstance> list1 = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().orderByTaskCreateTime().asc().list();
+                if (CollUtil.isNotEmpty(list1)) {
+                    HistoricTaskInstance firstTask = list1.get(0);
+                    historyService.deleteHistoricTaskInstance(firstTask.getId());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 把一个任务动态转向目标节点
+     * @param process   目标节点
+     * @param task  当前任务
+     * @param taskId             当前任务id
+     * @param targetSequenceFlow  目标节点所有连线
+     * @param first  默认flase,找上一个节点
+     */
+    private void trunToTarget(Process process, TaskInfo task, String
+            taskId, List<SequenceFlow> targetSequenceFlow, boolean first) {
+
+        //当前节点:入住选配-处理
+        FlowNode curFlowNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey());
+        if (curFlowNode == null) {
+            //遍历节点中的所有子模块
+            for (FlowElement flowElement : process.getFlowElements()) {
+                if (flowElement instanceof SubProcess) {
+                    SubProcess subProcess = (SubProcess) flowElement;
+                    FlowElement fe = subProcess.getFlowElement(task.getTaskDefinitionKey());
+                    if (fe != null) {
+                        curFlowNode = (FlowNode) fe;
+                        break;
+                    }
+                }
+            }
+        }
+        //备份原始连线
+        List<SequenceFlow> tempOutgoingSequenceFlows = new ArrayList<>(curFlowNode.getOutgoingFlows());
+        //最新任务id与要删除的id一致
+        if (taskId.equals(task.getId())) {
+            //当前节点设置流出的连线
+            curFlowNode.setOutgoingFlows(targetSequenceFlow);
+            //完成当前任务
+            taskService.complete(task.getId());
+            if (!first) {
+                //删除任务实例
+                historyService.deleteHistoricTaskInstance(task.getId());
+                //删除历史任务
+                hiActinstMapper.deleteHiActivityInstByTaskId(task.getId());
+            }
+        }
+        //恢复之前的连线
+        curFlowNode.setOutgoingFlows(tempOutgoingSequenceFlows);
+    }
+
+    /**
+     * 获取历史撤回或回退目标节点,支持上一节点,第一个节点
+     *
+     * @param taskId            要回退的taskId
+     * @param processInstanceId
+     * @return
+     */
+    private HistoricActivityInstance getRejectTargetActivity(String taskId, String processInstanceId, boolean first) {
+
+        HistoricActivityInstance targetActivity = null;
+        HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).activityType("userTask");
+
+        // 取得所有历史任务按时间降序排序
+        List<HistoricActivityInstance> historicActivityInstances = null;
+        if (first) {// 退到第一个节点
+            historicActivityInstances = query.orderByHistoricActivityInstanceStartTime().asc().list();
+            return historicActivityInstances.get(0);
+        } else { // 找到最近一个节点
+            historicActivityInstances = query.orderByHistoricActivityInstanceStartTime().desc().list();
+        }
+
+        if (CollectionUtils.isEmpty(historicActivityInstances) || historicActivityInstances.size() < 2) {
+            return null;
+        }
+        if (!StringUtils.isBlank(taskId)) {
+            return targetActivity;
+        }
+        // 不传活动id的情况直接找第一个任务
+        // 最后一条是当前正在进行的任务 需要找到最近的但是名称和当前任务不一样的任务去撤回
+        HistoricActivityInstance current = historicActivityInstances.get(0);
+        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+            if (!current.getActivityId().equals(historicActivityInstance.getActivityId())) {
+                if (historicActivityInstance.getActivityType().equals("userTask")) {
+                    targetActivity = historicActivityInstance;
+                    break;
+                }
+            }
+        }
+        return targetActivity;
+    }
+}

+ 304 - 0
kyl/kyl-service/src/main/java/com/kyl/service/CheckInService.java

@@ -0,0 +1,304 @@
+package com.kyl.service;
+
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.kyl.base.ResponseResult;
+import com.kyl.constant.AccreditationRecordConstants;
+import com.kyl.constant.RetreatConstant;
+import com.kyl.dto.CheckInDto;
+import com.kyl.dto.ElderDto;
+import com.kyl.entity.CheckIn;
+import com.kyl.entity.Dept;
+import com.kyl.entity.Elder;
+import com.kyl.entity.User;
+import com.kyl.mapper.CheckInMapper;
+import com.kyl.mapper.UserMapper;
+import com.kyl.utils.BeanConv;
+import com.kyl.utils.CodeUtil;
+import com.kyl.utils.ObjectUtil;
+import com.kyl.utils.UserThreadLocal;
+import com.kyl.vo.RecordVo;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.impl.identity.Authentication;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title CheckInService
+ * @description 入住服务
+ * @create 2026/3/22
+ */
+@Service
+public class CheckInService {
+    @Autowired
+    private ElderService elderService;
+    //入住申请编号前缀
+    private static final String CHECK_IN_CODE_PREFIX = "RZ";
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+    @Autowired
+    private CheckInMapper checkInMapper;
+    @Autowired
+    private UserMapper userMapper;
+    @Autowired
+    private AccreditationRecordService accreditationRecordService;
+    //流程实例
+    @Autowired
+    private RuntimeService runtimeService;
+    //任务服务
+    @Autowired
+    private TaskService taskService;
+    @Autowired
+    private DeptService deptService;
+    /**
+     * 创建入住申请
+     * @return 统一响应结果
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public ResponseResult createCheckIn(CheckInDto checkInDto){
+        if (ObjectUtil.isEmpty(checkInDto))
+            return ResponseResult.error("请填写入住信息");
+        //1、验证状态,如果老人已经发起申请,就不能再次发起
+        //获取老人信息
+        ElderDto elderDto = checkInDto.getElderDto();
+        //获取老人信息-身份证号
+        String idCardNo = elderDto.getIdCardNo();
+        //根据身份证号查询老人信息
+        Elder elder = elderService.selectElderByIdCardNo(idCardNo);
+        //验证--老人的状态:(0:禁用,1:启用  2:请假 3:退住中 4入住中 5已退住)
+        if (ObjectUtil.isNotEmpty(elder) && !elder.getStatus().equals(5)){
+            return ResponseResult.error(elder.getName()+"已经发起入住申请,请勿重复操作");
+        }
+
+        //2、保存老人信息
+        //获取其他信息
+        String otherApplyInfo = checkInDto.getOtherApplyInfo();
+        //封装为JSON格式的数据
+        JSONObject jsonObject = JSONUtil.toBean(otherApplyInfo, JSONObject.class);
+        elderDto.setAge(jsonObject.getStr("age"));
+        elderDto.setSex(jsonObject.getStr("sex"));
+        elderDto.setImage(jsonObject.getStr("image"));
+        elderService.insertElder(elderDto);
+
+        //3、保存入住申请信息
+        CheckIn checkIn = BeanConv.toBean(checkInDto, CheckIn.class);
+        //设置入住申请的所有信息
+        checkIn.setOtherApplyInfo(JSONUtil.toJsonStr(checkInDto));
+        //生成编号
+        String checkInCode = CodeUtil.generateCode(CHECK_IN_CODE_PREFIX, redisTemplate, 5);
+        checkIn.setCheckInCode(checkInCode);
+        //生成标题
+        checkIn.setTitle(elderDto.getName()+"的入住申请");
+        //老人id
+        checkIn.setElderId(elderDto.getId());
+
+        //疗养顾问,申请人--当前系统的登录人
+        String subject = UserThreadLocal.getSubject();
+        User user = JSONUtil.toBean(subject, User.class);
+        //设置疗养顾问和申请人
+        checkIn.setCounselor(user.getRealName());
+        checkIn.setApplicat(user.getRealName());
+        //申请人id
+        checkIn.setApplicatId(user.getId());
+        //部门编号
+        checkIn.setDeptNo(user.getDeptNo());
+        //流程状态
+        checkIn.setFlowStatus(CheckIn.FlowStatus.APPLY.getCode());
+        //审核状态
+        checkIn.setStatus(CheckIn.Status.APPLICATION.getCode());
+
+        checkInMapper.insertCheckIn(checkIn);
+
+        //4、保存流程变量
+        Map<String,Object> variables= setVariables(checkIn);
+        //5、启动流程实例,并且自动完成首节点
+        start(checkIn.getId(),"checkIn",user,variables,true);
+
+
+        //6、保存审核记录
+        //获取到下一个审核人
+        Long nextAssignee = getNextAssignee("checkIn", "checkIn:" + checkIn.getId());
+        //封装审核记录信息
+        RecordVo recordVo = getRecordVo(
+                checkIn,    //入住的对象
+                user,   //当前登录的用户
+                AccreditationRecordConstants.RECORD_TYPE_CHECK_IN.getCode(),// 当前入住申请的审核状态  ?? 应该自动同意
+                "同意",   //操作的意见
+                "发起申请-申请入住",    //当前步骤
+                "护理组组长处理-入住评估",//下一步的操作人
+                nextAssignee,//下一个审核人id
+                AccreditationRecordConstants.RECORD_HANDLE_TYPE_PROCESSED.getCode()
+        );
+        //保存审核信息
+        accreditationRecordService.saveRecord(recordVo);
+
+        return ResponseResult.success();
+    }
+
+    /**
+     *
+     * @param checkIn 入住的对象
+     * @param user 当前登录的用户
+     * @param status 当前入住申请的审核状态
+     * @param option 操作的意见
+     * @param step 当前步骤
+     * @param nextStep 下一步的操作人
+     * @param nextAssignee 下一个审核人id
+     * @param handleType 处理类型(0:已审批,1:已处理)
+     * @return
+     */
+    private RecordVo getRecordVo(CheckIn checkIn, User user, Integer status,String option,
+                                 String step,String nextStep,Long nextAssignee, Integer handleType){
+        RecordVo record = new RecordVo();
+        record.setId(checkIn.getId());//入住id
+        record.setType(AccreditationRecordConstants.RECORD_TYPE_CHECK_IN.getCode());// 类型
+        record.setFlowStatus(checkIn.getFlowStatus());//流程状态
+        record.setHandleType(handleType);//处理类型
+        record.setStatus(status);//状态
+        record.setOption(option);//操作意见
+        record.setNextStep(nextStep);//下一步操作
+        record.setNextAssignee(nextAssignee);//下一个审核人
+        record.setUserId(user.getId());//用户id
+        record.setRealName(user.getRealName());//用户名称
+        record.setStep(step);//当前步骤
+        return record;
+    }
+
+
+
+    /**
+     * 获取下一个审批人
+     * @param processKey
+     * @param businessKey
+     * @return
+     */
+    private Long getNextAssignee(String processKey, String businessKey) {
+        //根据流程实例id和业务key查询当前任务
+        Task task = taskService.createTaskQuery()
+                .processDefinitionKey(processKey)
+                .processInstanceBusinessKey(businessKey)
+                .singleResult();
+        if (task != null){
+            return Long.parseLong(task.getAssignee());  //返回下一个审核人id
+        }
+        return null;
+    }
+
+
+
+    /**
+     * 启动流程实例,如果当前的登录人是第一节点的执行人,则自动执行任务
+     * @param checkInId 入住id
+     * @param processKey 流程定义key
+     * @param user 当前登录用户
+     * @param variables 流程变量
+     * @param isFirst 是否是第一个节点,是否要自动完成
+     */
+    private void start(Long checkInId, String processKey, User user, Map<String, Object> variables, boolean isFirst) {
+        //业务id
+        String businessKey = processKey+":"+checkInId;
+        //1、启动流程示例
+        startProcessInstance(processKey,variables,businessKey);
+
+        //用户登录,防止报错Authentication是org.activiti.engine.impl.identity.Authentication;
+        Authentication.setAuthenticatedUserId(user.getId().toString());
+        //查询任务--获取任务列表
+        List<Task> list = taskService.createTaskQuery()
+                .processDefinitionKey(processKey)//流程定义key
+                .taskAssignee(user.getId().toString())//当前任务执行人
+                .list();
+        list = list.stream().filter(t -> "0".equals(t.getFormKey()))//0表示发起入住申请,1表示入住评估处理....
+                .collect(Collectors.toList());//获取发起入住申请任务
+        //判断是否任务列表为空,判断是否自动处理
+        if (!CollectionUtils.isEmpty(list)&&isFirst){
+            for (Task task : list){
+                Map<String, Object> variables2 = new HashMap<>();
+                variables2.put("processStatus",1);
+                variables2.put("ops",1);
+
+                //提交任务
+                taskService.complete(task.getId(),variables2);
+            }
+        }
+
+    }
+
+
+    /**
+     * 启动流程实例
+     * @param processKey
+     * @param variables
+     * @param businessKey
+     * @return
+     */
+    private ProcessInstance startProcessInstance(String processKey, Map<String, Object> variables, String businessKey) {
+        ProcessInstance processInstance =
+                runtimeService.startProcessInstanceByKey(
+                        processKey, //流程定义key
+                        businessKey,//业务id
+                        variables//流程变量
+                );
+        return processInstance;
+    }
+
+
+
+    /**
+     * 设置流程变量
+     * @param checkIn
+     * @return
+     */
+    private Map<String,Object> setVariables(CheckIn checkIn){
+        //1、设置流程变量
+        Map<String,Object> variables = new HashMap<>();
+        //疗养顾问
+        variables.put("assignee0",checkIn.getApplicatId()); //疗养顾问id
+        //入住申请单的其他信息
+        variables.put("assigneeName",checkIn.getApplicat());//疗养顾问名称
+        variables.put("processTitle",checkIn.getTitle()); //流程标题
+
+        //护理部主管--获取护理部的主管的id
+        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("dept_no", RetreatConstant.NURSING_DEPT_CODE);   //根据护理部id找到护理部
+        Dept dept = deptService.getOne(queryWrapper);
+        variables.put("assignee1",dept.getLeaderId());  //护理部主管id
+        //院长-副院长
+        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
+        queryWrapper1.eq("dept_no",RetreatConstant.DEAN_OFFICE_DEPT_CODE);   //根据院长办公室id找到院长
+        List<User> userList = userMapper.selectList(queryWrapper1);//获取院长
+        variables.put("assignee2",userList.get(0).getId());
+
+        //疗养顾问
+        variables.put("assignee3",checkIn.getApplicatId());
+
+        //法务部员工
+        QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
+        queryWrapper2.eq("dept_no",RetreatConstant.LEGAL_DEPT_CODE);
+        List<User> userList1 = userMapper.selectList(queryWrapper2);//法务部员工
+        variables.put("assignee4",userList1.get(0).getId());
+
+        //设置流程类型
+        variables.put("processType",3); //类型(1:退住,2:请假,3:入住)
+        //流程类型code
+        variables.put("processCode",checkIn.getCheckInCode());
+        //流程类型状态
+        variables.put("processStatus",1);//流程状态 0:申请退住 1:申请审批 2:解除合同 3:调整账单 4:账单审批 5:退住审批 6:费用算清
+        return variables;
+    }
+
+}

+ 117 - 0
kyl/kyl-service/src/main/java/com/kyl/service/ElderService.java

@@ -0,0 +1,117 @@
+package com.kyl.service;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import com.kyl.dto.ElderDto;
+import com.kyl.entity.Elder;
+import com.kyl.mapper.ElderMapper;
+import com.kyl.utils.BeanConv;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title ElderService
+ * @description
+ * @create 2026/3/29
+ */
+@Service
+@Slf4j
+public class ElderService {
+
+    // 注入Mapper
+    @Autowired
+    private ElderMapper elderMapper;
+
+    /**
+     * 新增老人信息
+     * @param elder 老人实体
+     * @return 受影响行数
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public int insertElder(ElderDto elderDto) {
+        // 基础校验:身份证号不能为空
+        if (elderDto == null || elderDto.getIdCardNo() == null || elderDto.getIdCardNo().trim().isEmpty()) {
+            throw new IllegalArgumentException("老人身份证号不能为空");
+        }
+        // 校验身份证号是否已存在
+        Elder existElder = elderMapper.selectElderByIdCardNo(elderDto.getIdCardNo());
+        if (existElder != null) {
+            throw new RuntimeException("该身份证号已存在老人信息");
+        }
+        Elder elder = BeanConv.toBean(elderDto, Elder.class);
+        elder.setStatus(1);
+        return elderMapper.insertElder(elder);
+    }
+
+    /**
+     * 根据ID删除老人信息
+     * @param id 老人ID
+     * @return 受影响行数
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteElderById(Long id) {
+        if (id == null) {
+            throw new IllegalArgumentException("老人ID不能为空");
+        }
+        return elderMapper.deleteElderById(id);
+    }
+
+    /**
+     * 根据ID更新老人信息
+     * @param elder 老人实体
+     * @return 受影响行数
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public int updateElderById(Elder elder) {
+        if (elder == null || elder.getId() == null) {
+            throw new IllegalArgumentException("老人信息或ID不能为空");
+        }
+        // 校验老人是否存在
+        Elder existElder = elderMapper.selectElderById(elder.getId());
+        if (existElder == null) {
+            throw new RuntimeException("未查询到该老人信息");
+        }
+        return elderMapper.updateElderById(elder);
+    }
+
+    /**
+     * 根据ID查询老人信息
+     * @param id 老人ID
+     * @return 老人实体
+     */
+    public Elder selectElderById(Long id) {
+        if (id == null) {
+            throw new IllegalArgumentException("老人ID不能为空");
+        }
+        return elderMapper.selectElderById(id);
+    }
+
+    /**
+     * 条件查询老人列表
+     * @param elder 查询条件
+     * @return 老人列表
+     */
+    public List<Elder> selectElderList(Elder elder) {
+        return elderMapper.selectElderList(elder);
+    }
+
+    /**
+     * 根据身份证号查询老人信息
+     * @param idCardNo 身份证号
+     * @return 老人实体
+     */
+    public Elder selectElderByIdCardNo(String idCardNo) {
+        if (idCardNo == null || idCardNo.trim().isEmpty()) {
+            throw new IllegalArgumentException("身份证号不能为空");
+        }
+        log.info("根据身份证号查询老人信息.....................");
+        return elderMapper.selectElderByIdCardNo(idCardNo);
+    }
+}

+ 108 - 0
kyl/kyl-service/src/main/java/com/kyl/service/PendingTasksService.java

@@ -0,0 +1,108 @@
+package com.kyl.service;
+
+
+import com.kyl.base.PageResponse;
+import com.kyl.dto.PendingTasksDto;
+import com.kyl.entity.PendingTasks;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.history.HistoricTaskInstance;
+import org.activiti.engine.history.HistoricTaskInstanceQuery;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title PendingTasksService
+ * @description
+ * @create 2026/3/29
+ */
+@Service
+public class PendingTasksService {
+    /**
+     * Activiti7服务的历史记录服务
+     */
+    @Autowired
+    private HistoryService historyService;
+    public PageResponse getMyTaskList(PendingTasksDto pendingTasksDto){
+        //创建查询条件
+        HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery();//创建历史任务查询
+        //判断是否是已处理
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getIsHandle())){
+            if (pendingTasksDto.getIsHandle()==1){
+                taskInstanceQuery.finished();   //已处理
+            }else {
+                taskInstanceQuery.unfinished(); //未处理
+            }
+        }
+        //需要一系列的判断来查询
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getApplicatId())){   //申请人id 判断是代办还是申请
+            taskInstanceQuery.taskNameLike("%申请");  //模糊查询
+            taskInstanceQuery.taskAssignee(pendingTasksDto.getAssigneeId().toString());//指定处理人
+        }else {
+            taskInstanceQuery.taskNameLike("%处理");  //模糊查询
+            taskInstanceQuery.taskAssignee(pendingTasksDto.getAssigneeId().toString());//指定处理人
+        }
+
+
+        //根据时间范围查询
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getStartTime())&&ObjectUtils.isNotEmpty(pendingTasksDto.getEndTime())){
+            taskInstanceQuery   //查询条件
+                    .taskCreatedAfter(pendingTasksDto.getStartTime())   //创建时间
+                    .taskCompletedBefore(pendingTasksDto.getEndTime()); //完成时间
+        }
+        //单据类别
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getType())){
+            taskInstanceQuery.processVariableValueEquals("processType", pendingTasksDto.getType());
+        }
+        //单据编号
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getCode())){
+            taskInstanceQuery.processVariableValueEquals("processCode", pendingTasksDto.getCode());
+        }
+        //任务状态
+        if (ObjectUtils.isNotEmpty(pendingTasksDto.getStatus())){
+            taskInstanceQuery.processVariableValueEquals("processStatus", pendingTasksDto.getStatus());
+        }
+        //获取总条数
+        long total = taskInstanceQuery.count();
+        
+        //分页查询
+        List<HistoricTaskInstance> taskInstanceList = taskInstanceQuery
+                .includeTaskLocalVariables()    //获取任务变量
+                .orderByHistoricTaskInstanceStartTime().desc()//按照任务开始时间倒序
+                .listPage((pendingTasksDto.getPageNum() - 1 * pendingTasksDto.getPageSize()), //分页
+                        pendingTasksDto.getPageSize()   //每页条数
+                );
+
+        List<PendingTasks> pendingTasksList =new ArrayList<>();
+        for (HistoricTaskInstance taskInstance : taskInstanceList){
+            Map<String, Object> processVariables = taskInstance.getTaskLocalVariables();
+            PendingTasks pendingTasks = new PendingTasks();
+            pendingTasks.setId(taskInstance.getId());
+            pendingTasks.setCode(processVariables.get("processCode").toString());//单据编号
+            pendingTasks.setType(Integer.parseInt(processVariables.get("processType").toString()));//单据类别
+            pendingTasks.setTitle(processVariables.get("processTitle").toString());//任务标题
+            pendingTasks.setStatus(Integer.parseInt(processVariables.get("processStatus").toString()));//任务状态
+            pendingTasks.setApplicat(processVariables.get("assignee0Name").toString());//申请人
+            pendingTasks.setApplicatId(Long.valueOf(taskInstance.getAssignee()));//申请人id
+            LocalDateTime applicationTime = LocalDateTime.parse(processVariables.get("applicationTime").toString());
+            pendingTasks.setApplicationTime(applicationTime);
+
+            pendingTasksList.add(pendingTasks); //添加进列表
+        }
+
+
+        return PageResponse.of(
+                pendingTasksList,   //数据列表
+                pendingTasksDto.getPageNum(),//当前页
+                pendingTasksDto.getPageSize(),//每页条数
+                total//总条数
+        );
+    }
+}

+ 72 - 0
kyl/kyl-service/src/main/java/com/kyl/vo/RecordVo.java

@@ -0,0 +1,72 @@
+package com.kyl.vo;
+
+import lombok.Data;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title RecordVo
+ * @description 操作记录VO
+ */
+@Data
+public class RecordVo {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 类型:(1:退住  2:请假  3:入住)
+     */
+    private Integer type;
+
+    /**
+     * 入住:(流程状态  0:申请入住  1:入住评估  2:入住审批  3:入住配置  4:签约办理)
+     * 退住:(流程状态  0:申请退住  1:申请审批  2:解除合同  3:调整账单  4:账单审批  5:退住审批  6:费用算清)
+     */
+    private Integer flowStatus;
+
+    /**
+     * 审核状态
+     * 1:通过
+     * 2:拒绝
+     * 3:驳回
+     * 4:撤回
+     * 5:撤销
+     */
+    private Integer status;
+    /**
+     * 审核意见
+     */
+    private String option;
+    /**
+     * 审核步骤
+     */
+    private String step;
+    /**
+     * 下一步的操作
+     */
+    private String nextStep;
+    /**
+     * 下一个审核人
+     */
+    private Long nextAssignee;
+
+    /**
+     * 当前登录用户id
+     */
+    private Long userId;
+
+    /**
+     * 当前登录用户真实姓名
+     */
+    private String realName;
+
+    /**
+     * 处理类型(0:已审批,1:已处理)
+     */
+    private Integer handleType;
+
+
+}

+ 151 - 0
kyl/kyl-service/src/main/resources/bpmn/checkIn.bpmn

@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" id="sample-diagram" targetNamespace="http://activiti.org/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:process id="checkIn" name="入住申请" isExecutable="true">
+    <bpmn2:startEvent id="StartEvent_1">
+      <bpmn2:outgoing>Flow_0kgddhg</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:userTask id="Activity_1jub5re" name="发起入住申请" activiti:formKey="0" activiti:assignee="${assignee0}">
+      <bpmn2:incoming>Flow_0kgddhg</bpmn2:incoming>
+      <bpmn2:incoming>Flow_0d7t9lr</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_17qixah</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="Flow_0kgddhg" sourceRef="StartEvent_1" targetRef="Activity_1jub5re" />
+    <bpmn2:userTask id="Activity_0p8tm8u" name="入住评估-处理" activiti:formKey="1" activiti:assignee="${assignee1}">
+      <bpmn2:incoming>Flow_17qixah</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_18tp7b5</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="Flow_17qixah" sourceRef="Activity_1jub5re" targetRef="Activity_0p8tm8u" />
+    <bpmn2:userTask id="Activity_1ty9y2s" name="副院长审批-处理" activiti:formKey="2" activiti:assignee="${assignee2}">
+      <bpmn2:incoming>Flow_18tp7b5</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_1pyfqy4</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="Flow_18tp7b5" sourceRef="Activity_0p8tm8u" targetRef="Activity_1ty9y2s" />
+    <bpmn2:exclusiveGateway id="Gateway_039rxo5" name="审核是否通过">
+      <bpmn2:incoming>Flow_1pyfqy4</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_0znphtf</bpmn2:outgoing>
+      <bpmn2:outgoing>Flow_10tjhwc</bpmn2:outgoing>
+    </bpmn2:exclusiveGateway>
+    <bpmn2:sequenceFlow id="Flow_1pyfqy4" sourceRef="Activity_1ty9y2s" targetRef="Gateway_039rxo5" />
+    <bpmn2:userTask id="Activity_19dq5v9" name="入住选配-处理" activiti:formKey="3" activiti:assignee="${assignee3}">
+      <bpmn2:incoming>Flow_0znphtf</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_0gos0ln</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="Flow_0znphtf" name="是" sourceRef="Gateway_039rxo5" targetRef="Activity_19dq5v9">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${ops==1}</bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:userTask id="Activity_1qvscc0" name="签约办理-处理" activiti:formKey="4" activiti:assignee="${assignee4}">
+      <bpmn2:incoming>Flow_0gos0ln</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_0tcx6c3</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="Flow_0gos0ln" sourceRef="Activity_19dq5v9" targetRef="Activity_1qvscc0" />
+    <bpmn2:exclusiveGateway id="Gateway_1dkqre0" name="是否结束流程">
+      <bpmn2:incoming>Flow_10tjhwc</bpmn2:incoming>
+      <bpmn2:outgoing>Flow_14vuiaw</bpmn2:outgoing>
+      <bpmn2:outgoing>Flow_0d7t9lr</bpmn2:outgoing>
+    </bpmn2:exclusiveGateway>
+    <bpmn2:sequenceFlow id="Flow_10tjhwc" name="否" sourceRef="Gateway_039rxo5" targetRef="Gateway_1dkqre0">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${ops&gt;1}</bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:endEvent id="Event_1ygm06t">
+      <bpmn2:incoming>Flow_0tcx6c3</bpmn2:incoming>
+      <bpmn2:incoming>Flow_14vuiaw</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:sequenceFlow id="Flow_0tcx6c3" sourceRef="Activity_1qvscc0" targetRef="Event_1ygm06t" />
+    <bpmn2:sequenceFlow id="Flow_14vuiaw" name="是,拒绝" sourceRef="Gateway_1dkqre0" targetRef="Event_1ygm06t">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${ops==2}</bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:sequenceFlow id="Flow_0d7t9lr" name="否,驳回申请" sourceRef="Gateway_1dkqre0" targetRef="Activity_1jub5re">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${ops==3}</bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="checkIn">
+      <bpmndi:BPMNEdge id="Flow_0kgddhg_di" bpmnElement="Flow_0kgddhg">
+        <di:waypoint x="208" y="150" />
+        <di:waypoint x="260" y="150" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_17qixah_di" bpmnElement="Flow_17qixah">
+        <di:waypoint x="360" y="150" />
+        <di:waypoint x="420" y="150" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_18tp7b5_di" bpmnElement="Flow_18tp7b5">
+        <di:waypoint x="520" y="150" />
+        <di:waypoint x="580" y="150" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_1pyfqy4_di" bpmnElement="Flow_1pyfqy4">
+        <di:waypoint x="630" y="190" />
+        <di:waypoint x="630" y="265" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0znphtf_di" bpmnElement="Flow_0znphtf">
+        <di:waypoint x="655" y="290" />
+        <di:waypoint x="760" y="290" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="702" y="272" width="12" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0gos0ln_di" bpmnElement="Flow_0gos0ln">
+        <di:waypoint x="860" y="290" />
+        <di:waypoint x="940" y="290" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_10tjhwc_di" bpmnElement="Flow_10tjhwc">
+        <di:waypoint x="630" y="315" />
+        <di:waypoint x="630" y="375" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="640" y="333" width="12" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0tcx6c3_di" bpmnElement="Flow_0tcx6c3">
+        <di:waypoint x="990" y="330" />
+        <di:waypoint x="990" y="382" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_14vuiaw_di" bpmnElement="Flow_14vuiaw">
+        <di:waypoint x="655" y="400" />
+        <di:waypoint x="972" y="400" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="792" y="382" width="45" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="Flow_0d7t9lr_di" bpmnElement="Flow_0d7t9lr">
+        <di:waypoint x="605" y="400" />
+        <di:waypoint x="310" y="400" />
+        <di:waypoint x="310" y="190" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="425" y="382" width="67" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="172" y="132" width="36" height="36" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1jub5re_di" bpmnElement="Activity_1jub5re">
+        <dc:Bounds x="260" y="110" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_0p8tm8u_di" bpmnElement="Activity_0p8tm8u">
+        <dc:Bounds x="420" y="110" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1ty9y2s_di" bpmnElement="Activity_1ty9y2s">
+        <dc:Bounds x="580" y="110" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_039rxo5_di" bpmnElement="Gateway_039rxo5" isMarkerVisible="true">
+        <dc:Bounds x="605" y="265" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="536" y="283" width="67" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Gateway_1dkqre0_di" bpmnElement="Gateway_1dkqre0" isMarkerVisible="true">
+        <dc:Bounds x="605" y="375" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="597" y="432" width="67" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_1qvscc0_di" bpmnElement="Activity_1qvscc0">
+        <dc:Bounds x="940" y="250" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Activity_19dq5v9_di" bpmnElement="Activity_19dq5v9">
+        <dc:Bounds x="760" y="250" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Event_1ygm06t_di" bpmnElement="Event_1ygm06t">
+        <dc:Bounds x="972" y="382" width="36" height="36" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>

BIN
kyl/kyl-service/src/main/resources/bpmn/checkIn.png


+ 156 - 0
kyl/kyl-service/src/main/resources/mapper/AccreditationRecordMapper.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.AccreditationRecordMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.kyl.entity.AccreditationRecord">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="opinion" property="opinion" jdbcType="VARCHAR"/>
+        <result column="type" property="type" jdbcType="TINYINT"/>
+        <result column="approver_id" property="approverId" jdbcType="BIGINT"/>
+        <result column="approver_name" property="approverName" jdbcType="VARCHAR"/>
+        <result column="approver_name_role" property="approverNameRole" jdbcType="VARCHAR"/>
+        <result column="next_approver_id" property="nextApproverId" jdbcType="BIGINT"/>
+        <result column="next_approver" property="nextApprover" jdbcType="VARCHAR"/>
+        <result column="next_approver_role" property="nextApproverRole" jdbcType="VARCHAR"/>
+        <result column="bussniess_id" property="bussniessId" jdbcType="BIGINT"/>
+        <result column="current_step" property="currentStep" jdbcType="VARCHAR"/>
+        <result column="next_step" property="nextStep" jdbcType="VARCHAR"/>
+        <result column="audit_status" property="auditStatus" jdbcType="TINYINT"/>
+        <result column="step_no" property="stepNo" jdbcType="BIGINT"/>
+        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
+        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
+        <result column="create_by" property="createBy" jdbcType="BIGINT"/>
+        <result column="update_by" property="updateBy" jdbcType="BIGINT"/>
+        <result column="handle_type" property="handleType" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <!-- 基础字段列 -->
+    <sql id="Base_Column_List">
+        id, opinion, type, approver_id, approver_name, approver_name_role,
+        next_approver_id, next_approver, next_approver_role, bussniess_id,
+        current_step, next_step, audit_status, step_no, create_time, update_time,
+        create_by, update_by, handle_type
+    </sql>
+
+    <!-- 1. 新增 -->
+    <insert id="insert" parameterType="com.kyl.entity.AccreditationRecord">
+        INSERT INTO accraditation_record
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="opinion != null">opinion,</if>
+            <if test="type != null">type,</if>
+            <if test="approverId != null">approver_id,</if>
+            <if test="approverName != null">approver_name,</if>
+            <if test="approverNameRole != null">approver_name_role,</if>
+            <if test="nextApproverId != null">next_approver_id,</if>
+            <if test="nextApprover != null">next_approver,</if>
+            <if test="nextApproverRole != null">next_approver_role,</if>
+            <if test="bussniessId != null">bussniess_id,</if>
+            <if test="currentStep != null">current_step,</if>
+            <if test="nextStep != null">next_step,</if>
+            <if test="auditStatus != null">audit_status,</if>
+            <if test="stepNo != null">step_no,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="handleType != null">handle_type,</if>
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            <if test="opinion != null">#{opinion},</if>
+            <if test="type != null">#{type},</if>
+            <if test="approverId != null">#{approverId},</if>
+            <if test="approverName != null">#{approverName},</if>
+            <if test="approverNameRole != null">#{approverNameRole},</if>
+            <if test="nextApproverId != null">#{nextApproverId},</if>
+            <if test="nextApprover != null">#{nextApprover},</if>
+            <if test="nextApproverRole != null">#{nextApproverRole},</if>
+            <if test="bussniessId != null">#{bussniessId},</if>
+            <if test="currentStep != null">#{currentStep},</if>
+            <if test="nextStep != null">#{nextStep},</if>
+            <if test="auditStatus != null">#{auditStatus},</if>
+            <if test="stepNo != null">#{stepNo},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="handleType != null">#{handleType},</if>
+        </trim>
+    </insert>
+
+    <!-- 2. 根据ID删除 -->
+    <delete id="deleteById" parameterType="java.lang.Long">
+        DELETE FROM accraditation_record WHERE id = #{id}
+    </delete>
+
+    <!-- 3. 根据ID更新(动态字段) -->
+    <update id="updateById" parameterType="com.kyl.entity.AccreditationRecord">
+        UPDATE accraditation_record
+        <set>
+            <if test="opinion != null">opinion = #{opinion},</if>
+            <if test="type != null">type = #{type},</if>
+            <if test="approverId != null">approver_id = #{approverId},</if>
+            <if test="approverName != null">approver_name = #{approverName},</if>
+            <if test="approverNameRole != null">approver_name_role = #{approverNameRole},</if>
+            <if test="nextApproverId != null">next_approver_id = #{nextApproverId},</if>
+            <if test="nextApprover != null">next_approver = #{nextApprover},</if>
+            <if test="nextApproverRole != null">next_approver_role = #{nextApproverRole},</if>
+            <if test="bussniessId != null">bussniess_id = #{bussniessId},</if>
+            <if test="currentStep != null">current_step = #{currentStep},</if>
+            <if test="nextStep != null">next_step = #{nextStep},</if>
+            <if test="auditStatus != null">audit_status = #{auditStatus},</if>
+            <if test="stepNo != null">step_no = #{stepNo},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="handleType != null">handle_type = #{handleType},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 4. 根据ID查询 -->
+    <select id="selectById" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM accraditation_record
+        WHERE id = #{id}
+    </select>
+
+    <!-- 5. 动态条件查询(核心:多条件判断) -->
+    <select id="selectList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM accraditation_record
+        <where>
+            <if test="query.id != null"> AND id = #{query.id}</if>
+            <if test="query.type != null"> AND type = #{query.type}</if>
+            <if test="query.approverId != null"> AND approver_id = #{query.approverId}</if>
+            <if test="query.approverName != null and query.approverName != ''">
+                AND approver_name LIKE CONCAT('%', #{query.approverName}, '%')
+            </if>
+            <if test="query.bussniessId != null"> AND bussniess_id = #{query.bussniessId}</if>
+            <if test="query.auditStatus != null"> AND audit_status = #{query.auditStatus}</if>
+            <if test="query.handleType != null"> AND handle_type = #{query.handleType}</if>
+            <if test="query.createTime != null"> AND create_time >= #{query.createTime}</if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 6. 批量插入 -->
+    <insert id="batchInsert">
+        INSERT INTO accraditation_record (
+        opinion, type, approver_id, approver_name, approver_name_role,
+        next_approver_id, next_approver, next_approver_role, bussniess_id,
+        current_step, next_step, audit_status, step_no, create_time, update_time,
+        create_by, update_by, handle_type
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.opinion},#{item.type},#{item.approverId},#{item.approverName},
+            #{item.approverNameRole},#{item.nextApproverId},#{item.nextApprover},
+            #{item.nextApproverRole},#{item.bussniessId},#{item.currentStep},
+            #{item.nextStep},#{item.auditStatus},#{item.stepNo},#{item.createTime},
+            #{item.updateTime},#{item.createBy},#{item.updateBy},#{item.handleType})
+        </foreach>
+    </insert>
+
+</mapper>

+ 132 - 0
kyl/kyl-service/src/main/resources/mapper/BalanceMapper.xml

@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.BalanceMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.kyl.entity.Balance">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="prepaid_balance" property="prepaidBalance" jdbcType="DECIMAL"/>
+        <result column="deposit_amount" property="depositAmount" jdbcType="DECIMAL"/>
+        <result column="arrears_amount" property="arrearsAmount" jdbcType="DECIMAL"/>
+        <result column="payment_deadline" property="paymentDeadline" jdbcType="TIMESTAMP"/>
+        <result column="status" property="status" jdbcType="INTEGER"/>
+        <result column="elder_id" property="elderId" jdbcType="BIGINT"/>
+        <result column="elder_name" property="elderName" jdbcType="VARCHAR"/>
+        <result column="bed_no" property="bedNo" jdbcType="VARCHAR"/>
+        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
+        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
+        <result column="create_by" property="createBy" jdbcType="BIGINT"/>
+        <result column="update_by" property="updateBy" jdbcType="BIGINT"/>
+        <result column="remark" property="remark" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <!-- 通用查询字段 -->
+    <sql id="Base_Column_List">
+        id, prepaid_balance, deposit_amount, arrears_amount, payment_deadline,
+        status, elder_id, elder_name, bed_no, create_time, update_time,
+        create_by, update_by, remark
+    </sql>
+
+    <!-- 1. 新增(动态字段) -->
+    <insert id="insert" parameterType="com.kyl.entity.Balance">
+        INSERT INTO balance
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="prepaidBalance != null">prepaid_balance,</if>
+            <if test="depositAmount != null">deposit_amount,</if>
+            <if test="arrearsAmount != null">arrears_amount,</if>
+            <if test="paymentDeadline != null">payment_deadline,</if>
+            <if test="status != null">status,</if>
+            <if test="elderId != null">elder_id,</if>
+            <if test="elderName != null">elder_name,</if>
+            <if test="bedNo != null">bed_no,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="remark != null">remark,</if>
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            <if test="prepaidBalance != null">#{prepaidBalance},</if>
+            <if test="depositAmount != null">#{depositAmount},</if>
+            <if test="arrearsAmount != null">#{arrearsAmount},</if>
+            <if test="paymentDeadline != null">#{paymentDeadline},</if>
+            <if test="status != null">#{status},</if>
+            <if test="elderId != null">#{elderId},</if>
+            <if test="elderName != null">#{elderName},</if>
+            <if test="bedNo != null">#{bedNo},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <!-- 2. 根据ID删除 -->
+    <delete id="deleteById" parameterType="java.lang.Long">
+        DELETE FROM balance WHERE id = #{id}
+    </delete>
+
+    <!-- 3. 根据ID动态更新(只更新非空字段) -->
+    <update id="updateById" parameterType="com.kyl.entity.Balance">
+        UPDATE balance
+        <set>
+            <if test="prepaidBalance != null">prepaid_balance = #{prepaidBalance},</if>
+            <if test="depositAmount != null">deposit_amount = #{depositAmount},</if>
+            <if test="arrearsAmount != null">arrears_amount = #{arrearsAmount},</if>
+            <if test="paymentDeadline != null">payment_deadline = #{paymentDeadline},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="elderId != null">elder_id = #{elderId},</if>
+            <if test="elderName != null">elder_name = #{elderName},</if>
+            <if test="bedNo != null">bed_no = #{bedNo},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </set>        WHERE id = #{id}
+    </update>
+
+    <!-- 4. 根据ID查询 -->
+    <select id="selectById" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM balance
+        WHERE id = #{id}
+    </select>
+
+    <!-- 5. 动态条件查询(支持多条件组合、模糊查询) -->
+    <select id="selectList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM balance
+        <where>
+            <if test="query.id != null"> AND id = #{query.id}</if>
+            <if test="query.elderId != null"> AND elder_id = #{query.elderId}</if>
+            <if test="query.elderName != null and query.elderName != ''">
+                AND elder_name LIKE CONCAT('%', #{query.elderName}, '%')
+            </if>
+            <if test="query.bedNo != null and query.bedNo != ''">
+                AND bed_no LIKE CONCAT('%', #{query.bedNo}, '%')
+            </if>
+            <if test="query.status != null"> AND status = #{query.status}</if>
+            <if test="query.paymentDeadline != null"> AND payment_deadline >= #{query.paymentDeadline}</if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 6. 批量插入 -->
+    <insert id="batchInsert">
+        INSERT INTO balance (
+        prepaid_balance, deposit_amount, arrears_amount, payment_deadline,
+        status, elder_id, elder_name, bed_no, create_time, update_time,
+        create_by, update_by, remark
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.prepaidBalance},#{item.depositAmount},#{item.arrearsAmount},
+            #{item.paymentDeadline},#{item.status},#{item.elderId},#{item.elderName},
+            #{item.bedNo},#{item.createTime},#{item.updateTime},#{item.createBy},
+            #{item.updateBy},#{item.remark})
+        </foreach>
+    </insert>
+
+</mapper>

+ 176 - 0
kyl/kyl-service/src/main/resources/mapper/BillMapper.xml

@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.BillMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.kyl.entity.Bill">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="bill_no" property="billNo" jdbcType="VARCHAR"/>
+        <result column="trading_order_no" property="tradingOrderNo" jdbcType="BIGINT"/>
+        <result column="bill_type" property="billType" jdbcType="TINYINT"/>
+        <result column="bill_month" property="billMonth" jdbcType="VARCHAR"/>
+        <result column="elder_id" property="elderId" jdbcType="BIGINT"/>
+        <result column="bill_amount" property="billAmount" jdbcType="DECIMAL"/>
+        <result column="payable_amount" property="payableAmount" jdbcType="DECIMAL"/>
+        <result column="prepaid_amount" property="prepaidAmount" jdbcType="DECIMAL"/>
+        <result column="deposit_amount" property="depositAmount" jdbcType="DECIMAL"/>
+        <result column="current_cost" property="currentCost" jdbcType="DECIMAL"/>
+        <result column="payment_deadline" property="paymentDeadline" jdbcType="TIMESTAMP"/>
+        <result column="transaction_status" property="transactionStatus" jdbcType="INTEGER"/>
+        <result column="bill_start_time" property="billStartTime" jdbcType="TIMESTAMP"/>
+        <result column="bill_end_time" property="billEndTime" jdbcType="TIMESTAMP"/>
+        <result column="total_days" property="totalDays" jdbcType="INTEGER"/>
+        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
+        <result column="lname" property="lname" jdbcType="VARCHAR"/>
+        <result column="type_name" property="typeName" jdbcType="VARCHAR"/>
+        <result column="update_time" property="updateTime" jdbcType="VARCHAR"/>
+        <result column="create_by" property="createBy" jdbcType="BIGINT"/>
+        <result column="update_by" property="updateBy" jdbcType="BIGINT"/>
+        <result column="remark" property="remark" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <!-- 通用查询字段 -->
+    <sql id="Base_Column_List">
+        id, bill_no, trading_order_no, bill_type, bill_month, elder_id,
+        bill_amount, payable_amount, prepaid_amount, deposit_amount, current_cost,
+        payment_deadline, transaction_status, bill_start_time, bill_end_time,
+        total_days, create_time, lname, type_name, update_time, create_by,
+        update_by, remark
+    </sql>
+
+    <!-- 1. 新增(动态字段) -->
+    <insert id="insert" parameterType="com.kyl.entity.Bill">
+        INSERT INTO bill
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="billNo != null">bill_no,</if>
+            <if test="tradingOrderNo != null">trading_order_no,</if>
+            <if test="billType != null">bill_type,</if>
+            <if test="billMonth != null">bill_month,</if>
+            <if test="elderId != null">elder_id,</if>
+            <if test="billAmount != null">bill_amount,</if>
+            <if test="payableAmount != null">payable_amount,</if>
+            <if test="prepaidAmount != null">prepaid_amount,</if>
+            <if test="depositAmount != null">deposit_amount,</if>
+            <if test="currentCost != null">current_cost,</if>
+            <if test="paymentDeadline != null">payment_deadline,</if>
+            <if test="transactionStatus != null">transaction_status,</if>
+            <if test="billStartTime != null">bill_start_time,</if>
+            <if test="billEndTime != null">bill_end_time,</if>
+            <if test="totalDays != null">total_days,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="lname != null">lname,</if>
+            <if test="typeName != null">type_name,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="remark != null">remark,</if>
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            <if test="billNo != null">#{billNo},</if>
+            <if test="tradingOrderNo != null">#{tradingOrderNo},</if>
+            <if test="billType != null">#{billType},</if>
+            <if test="billMonth != null">#{billMonth},</if>
+            <if test="elderId != null">#{elderId},</if>
+            <if test="billAmount != null">#{billAmount},</if>
+            <if test="payableAmount != null">#{payableAmount},</if>
+            <if test="prepaidAmount != null">#{prepaidAmount},</if>
+            <if test="depositAmount != null">#{depositAmount},</if>
+            <if test="currentCost != null">#{currentCost},</if>
+            <if test="paymentDeadline != null">#{paymentDeadline},</if>
+            <if test="transactionStatus != null">#{transactionStatus},</if>
+            <if test="billStartTime != null">#{billStartTime},</if>
+            <if test="billEndTime != null">#{billEndTime},</if>
+            <if test="totalDays != null">#{totalDays},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="lname != null">#{lname},</if>
+            <if test="typeName != null">#{typeName},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <!-- 2. 根据ID删除 -->
+    <delete id="deleteById" parameterType="java.lang.Long">
+        DELETE FROM bill WHERE id = #{id}
+    </delete>
+
+    <!-- 3. 根据ID动态更新(只更新非空字段) -->
+    <update id="updateById" parameterType="com.kyl.entity.Bill">
+        UPDATE bill
+        <set>
+            <if test="billNo != null">bill_no = #{billNo},</if>
+            <if test="tradingOrderNo != null">trading_order_no = #{tradingOrderNo},</if>
+            <if test="billType != null">bill_type = #{billType},</if>
+            <if test="billMonth != null">bill_month = #{billMonth},</if>
+            <if test="elderId != null">elder_id = #{elderId},</if>
+            <if test="billAmount != null">bill_amount = #{billAmount},</if>
+            <if test="payableAmount != null">payable_amount = #{payableAmount},</if>
+            <if test="prepaidAmount != null">prepaid_amount = #{prepaidAmount},</if>
+            <if test="depositAmount != null">deposit_amount = #{depositAmount},</if>
+            <if test="currentCost != null">current_cost = #{currentCost},</if>
+            <if test="paymentDeadline != null">payment_deadline = #{paymentDeadline},</if>
+            <if test="transactionStatus != null">transaction_status = #{transactionStatus},</if>
+            <if test="billStartTime != null">bill_start_time = #{billStartTime},</if>
+            <if test="billEndTime != null">bill_end_time = #{billEndTime},</if>
+            <if test="totalDays != null">total_days = #{totalDays},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="lname != null">lname = #{lname},</if>
+            <if test="typeName != null">type_name = #{typeName},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 4. 根据ID查询 -->
+    <select id="selectById" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM bill
+        WHERE id = #{id}
+    </select>
+
+    <!-- 5. 动态条件查询(支持多条件组合、模糊查询) -->
+    <select id="selectList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM bill
+        <where>
+            <if test="query.id != null"> AND id = #{query.id}</if>
+            <if test="query.billNo != null and query.billNo != ''">
+                AND bill_no LIKE CONCAT('%', #{query.billNo}, '%')
+            </if>
+            <if test="query.billType != null"> AND bill_type = #{query.billType}</if>
+            <if test="query.billMonth != null and query.billMonth != ''">
+                AND bill_month = #{query.billMonth}
+            </if>
+            <if test="query.elderId != null"> AND elder_id = #{query.elderId}</if>
+            <if test="query.transactionStatus != null"> AND transaction_status = #{query.transactionStatus}</if>
+            <if test="query.paymentDeadline != null"> AND payment_deadline >= #{query.paymentDeadline}</if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 6. 批量插入 -->
+    <insert id="batchInsert">
+        INSERT INTO bill (
+        bill_no, trading_order_no, bill_type, bill_month, elder_id,
+        bill_amount, payable_amount, prepaid_amount, deposit_amount, current_cost,
+        payment_deadline, transaction_status, bill_start_time, bill_end_time,
+        total_days, create_time, lname, type_name, update_time, create_by,
+        update_by, remark
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.billNo},#{item.tradingOrderNo},#{item.billType},#{item.billMonth},
+            #{item.elderId},#{item.billAmount},#{item.payableAmount},#{item.prepaidAmount},
+            #{item.depositAmount},#{item.currentCost},#{item.paymentDeadline},
+            #{item.transactionStatus},#{item.billStartTime},#{item.billEndTime},
+            #{item.totalDays},#{item.createTime},#{item.lname},#{item.typeName},
+            #{item.updateTime},#{item.createBy},#{item.updateBy},#{item.remark})
+        </foreach>
+    </insert>
+
+</mapper>

+ 154 - 0
kyl/kyl-service/src/main/resources/mapper/CheckInConfigMapper.xml

@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kyl.mapper.CheckInConfigMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.kyl.entity.CheckInConfig">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="elder_id" property="elderId" jdbcType="BIGINT"/>
+        <result column="check_in_start_time" property="checkInStartTime" jdbcType="TIMESTAMP"/>
+        <result column="check_in_end_time" property="checkInEndTime" jdbcType="TIMESTAMP"/>
+        <result column="nursing_level_id" property="nursingLevelId" jdbcType="BIGINT"/>
+        <result column="bed_no" property="bedNo" jdbcType="VARCHAR"/>
+        <result column="cost_start_time" property="costStartTime" jdbcType="TIMESTAMP"/>
+        <result column="cost_end_time" property="costEndTime" jdbcType="TIMESTAMP"/>
+        <result column="deposit_amount" property="depositAmount" jdbcType="DECIMAL"/>
+        <result column="nursing_cost" property="nursingCost" jdbcType="DECIMAL"/>
+        <result column="bed_cost" property="bedCost" jdbcType="DECIMAL"/>
+        <result column="other_cost" property="otherCost" jdbcType="DECIMAL"/>
+        <result column="medical_insurance_payment" property="medicalInsurancePayment" jdbcType="DECIMAL"/>
+        <result column="government_subsidy" property="governmentSubsidy" jdbcType="DECIMAL"/>
+        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
+        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
+        <result column="create_by" property="createBy" jdbcType="BIGINT"/>
+        <result column="update_by" property="updateBy" jdbcType="BIGINT"/>
+        <result column="remark" property="remark" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <!-- 通用查询字段 -->
+    <sql id="Base_Column_List">
+        id, elder_id, check_in_start_time, check_in_end_time, nursing_level_id,
+        bed_no, cost_start_time, cost_end_time, deposit_amount, nursing_cost,
+        bed_cost, other_cost, medical_insurance_payment, government_subsidy,
+        create_time, update_time, create_by, update_by, remark
+    </sql>
+
+    <!-- 1. 新增(动态字段) -->
+    <insert id="insert" parameterType="com.kyl.entity.CheckInConfig">
+        INSERT INTO check_in_config
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="elderId != null">elder_id,</if>
+            <if test="checkInStartTime != null">check_in_start_time,</if>
+            <if test="checkInEndTime != null">check_in_end_time,</if>
+            <if test="nursingLevelId != null">nursing_level_id,</if>
+            <if test="bedNo != null">bed_no,</if>
+            <if test="costStartTime != null">cost_start_time,</if>
+            <if test="costEndTime != null">cost_end_time,</if>
+            <if test="depositAmount != null">deposit_amount,</if>
+            <if test="nursingCost != null">nursing_cost,</if>
+            <if test="bedCost != null">bed_cost,</if>
+            <if test="otherCost != null">other_cost,</if>
+            <if test="medicalInsurancePayment != null">medical_insurance_payment,</if>
+            <if test="governmentSubsidy != null">government_subsidy,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="remark != null">remark,</if>
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            <if test="elderId != null">#{elderId},</if>
+            <if test="checkInStartTime != null">#{checkInStartTime},</if>
+            <if test="checkInEndTime != null">#{checkInEndTime},</if>
+            <if test="nursingLevelId != null">#{nursingLevelId},</if>
+            <if test="bedNo != null">#{bedNo},</if>
+            <if test="costStartTime != null">#{costStartTime},</if>
+            <if test="costEndTime != null">#{costEndTime},</if>
+            <if test="depositAmount != null">#{depositAmount},</if>
+            <if test="nursingCost != null">#{nursingCost},</if>
+            <if test="bedCost != null">#{bedCost},</if>
+            <if test="otherCost != null">#{otherCost},</if>
+            <if test="medicalInsurancePayment != null">#{medicalInsurancePayment},</if>
+            <if test="governmentSubsidy != null">#{governmentSubsidy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <!-- 2. 根据ID删除 -->
+    <delete id="deleteById" parameterType="java.lang.Long">
+        DELETE FROM check_in_config WHERE id = #{id}
+    </delete>
+
+    <!-- 3. 根据ID动态更新(只更新非空字段) -->
+    <update id="updateById" parameterType="com.kyl.entity.CheckInConfig">
+        UPDATE check_in_config
+        <set>
+            <if test="elderId != null">elder_id = #{elderId},</if>
+            <if test="checkInStartTime != null">check_in_start_time = #{checkInStartTime},</if>
+            <if test="checkInEndTime != null">check_in_end_time = #{checkInEndTime},</if>
+            <if test="nursingLevelId != null">nursing_level_id = #{nursingLevelId},</if>
+            <if test="bedNo != null">bed_no = #{bedNo},</if>
+            <if test="costStartTime != null">cost_start_time = #{costStartTime},</if>
+            <if test="costEndTime != null">cost_end_time = #{costEndTime},</if>
+            <if test="depositAmount != null">deposit_amount = #{depositAmount},</if>
+            <if test="nursingCost != null">nursing_cost = #{nursingCost},</if>
+            <if test="bedCost != null">bed_cost = #{bedCost},</if>
+            <if test="otherCost != null">other_cost = #{otherCost},</if>
+            <if test="medicalInsurancePayment != null">medical_insurance_payment = #{medicalInsurancePayment},</if>
+            <if test="governmentSubsidy != null">government_subsidy = #{governmentSubsidy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 4. 根据ID查询 -->
+    <select id="selectById" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM check_in_config
+        WHERE id = #{id}
+    </select>
+
+    <!-- 5. 动态条件查询(支持多条件组合、模糊查询) -->
+    <select id="selectList" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM check_in_config
+        <where>
+            <if test="query.id != null"> AND id = #{query.id}</if>
+            <if test="query.elderId != null"> AND elder_id = #{query.elderId}</if>
+            <if test="query.nursingLevelId != null"> AND nursing_level_id = #{query.nursingLevelId}</if>
+            <if test="query.bedNo != null and query.bedNo != ''">
+                AND bed_no LIKE CONCAT('%', #{query.bedNo}, '%')
+            </if>
+            <if test="query.checkInStartTime != null"> AND check_in_start_time >= #{query.checkInStartTime}</if>
+            <if test="query.checkInEndTime != null"> AND check_in_end_time &lt;= #{query.checkInEndTime}</if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 6. 批量插入 -->
+    <insert id="batchInsert">
+        INSERT INTO check_in_config (
+        elder_id, check_in_start_time, check_in_end_time, nursing_level_id,
+        bed_no, cost_start_time, cost_end_time, deposit_amount, nursing_cost,
+        bed_cost, other_cost, medical_insurance_payment, government_subsidy,
+        create_time, update_time, create_by, update_by, remark
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.elderId},#{item.checkInStartTime},#{item.checkInEndTime},
+            #{item.nursingLevelId},#{item.bedNo},#{item.costStartTime},#{item.costEndTime},
+            #{item.depositAmount},#{item.nursingCost},#{item.bedCost},#{item.otherCost},
+            #{item.medicalInsurancePayment},#{item.governmentSubsidy},#{item.createTime},
+            #{item.updateTime},#{item.createBy},#{item.updateBy},#{item.remark})
+        </foreach>
+    </insert>
+
+</mapper>

+ 108 - 0
kyl/kyl-service/src/main/resources/mapper/CheckInMapper.xml

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<!-- 对应指定的Mapper接口包名 -->
+<mapper namespace="com.kyl.mapper.CheckInMapper">
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, check_in_code, title, elder_id, counselor, check_in_time,
+        reason, remark, applicat, dept_no, applicat_id, create_time,
+        flow_status, status, other_apply_info, review_info, update_time
+    </sql>
+
+    <!-- 新增入住申请 -->
+    <insert id="insertCheckIn" parameterType="com.kyl.entity.CheckIn">
+        INSERT INTO check_in (
+            check_in_code, title, elder_id, counselor, check_in_time,
+            reason, remark, applicat, dept_no, applicat_id, create_time,
+            flow_status, status, other_apply_info, review_info, update_time
+        ) VALUES (
+                     #{checkInCode}, #{title}, #{elderId}, #{counselor}, #{checkInTime},
+                     #{reason}, #{remark}, #{applicat}, #{deptNo}, #{applicatId}, #{createTime},
+                     #{flowStatus}, #{status}, #{otherApplyInfo}, #{reviewInfo}, #{updateTime}
+                 )
+    </insert>
+
+    <!-- 根据ID删除入住申请 -->
+    <delete id="deleteCheckInById" parameterType="java.lang.Long">
+        DELETE FROM check_in WHERE id = #{id}
+    </delete>
+
+    <!-- 动态更新入住申请(只更新非空字段) -->
+    <update id="updateCheckInById" parameterType="com.kyl.entity.CheckIn">
+        UPDATE check_in
+        <set>
+            <if test="checkInCode != null and checkInCode != ''">check_in_code = #{checkInCode},</if>
+            <if test="title != null and title != ''">title = #{title},</if>
+            <if test="elderId != null">elder_id = #{elderId},</if>
+            <if test="counselor != null and counselor != ''">counselor = #{counselor},</if>
+            <if test="checkInTime != null">check_in_time = #{checkInTime},</if>
+            <if test="reason != null and reason != ''">reason = #{reason},</if>
+            <if test="remark != null and remark != ''">remark = #{remark},</if>
+            <if test="applicat != null and applicat != ''">applicat = #{applicat},</if>
+            <if test="deptNo != null and deptNo != ''">dept_no = #{deptNo},</if>
+            <if test="applicatId != null">applicat_id = #{applicatId},</if>
+            <if test="flowStatus != null">flow_status = #{flowStatus},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="otherApplyInfo != null">other_apply_info = #{otherApplyInfo},</if>
+            <if test="reviewInfo != null">review_info = #{reviewInfo},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 根据ID查询入住申请详情 -->
+    <select id="selectCheckInById" parameterType="java.lang.Long" resultType="com.kyl.entity.CheckIn">
+        SELECT <include refid="Base_Column_List"/>
+        FROM check_in
+        WHERE id = #{id}
+    </select>
+
+    <!-- 根据老人ID查询入住申请记录 -->
+    <select id="selectCheckInByElderId" parameterType="java.lang.Long" resultType="com.kyl.entity.CheckIn">
+        SELECT <include refid="Base_Column_List"/>
+        FROM check_in
+        WHERE elder_id = #{elderId}
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 多条件查询入住申请列表 -->
+    <select id="selectCheckInList" parameterType="com.kyl.entity.CheckIn" resultType="com.kyl.entity.CheckIn">
+        SELECT <include refid="Base_Column_List"/>
+        FROM check_in
+        <where>
+            <if test="checkInCode != null and checkInCode != ''">
+                AND check_in_code = #{checkInCode}
+            </if>
+            <if test="title != null and title != ''">
+                AND title LIKE CONCAT('%', #{title}, '%')
+            </if>
+            <if test="elderId != null">
+                AND elder_id = #{elderId}
+            </if>
+            <if test="flowStatus != null">
+                AND flow_status = #{flowStatus}
+            </if>
+            <if test="status != null">
+                AND status = #{status}
+            </if>
+            <if test="applicat != null and applicat != ''">
+                AND applicat LIKE CONCAT('%', #{applicat}, '%')
+            </if>
+            <if test="deptNo != null and deptNo != ''">
+                AND dept_no = #{deptNo}
+            </if>
+            <!-- 时间范围查询示例(可根据需求扩展) -->
+            <if test="createTimeStart != null">
+                AND create_time &gt;= #{createTimeStart}
+            </if>
+            <if test="createTimeEnd != null">
+                AND create_time &lt;= #{createTimeEnd}
+            </if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+</mapper>

+ 195 - 0
kyl/kyl-service/src/main/resources/mapper/ContractMapper.xml

@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<!-- 命名空间必须与Mapper接口全路径一致 -->
+<mapper namespace="com.kyl.mapper.ContractMapper">
+
+    <!-- 通用查询列片段:仅包含数据库实际字段(VO字段不参与) -->
+    <sql id="Base_Column_List">
+        id, name, member_phone, member_name, elder_name, contract_no,
+        pdf_url, member_id, elder_id, start_time, end_time, status,
+        sort, level_desc, check_in_no, sign_date, release_submitter,
+        release_date, release_pdf_url, create_time, update_time, del_flag
+    </sql>
+
+    <!-- 新增合同记录 -->
+    <insert id="insert" parameterType="com.kyl.entity.Contract">
+        INSERT INTO contract (
+        <if test="id != null">id,</if>
+        <if test="name != null and name != ''">name,</if>
+        <if test="memberPhone != null and memberPhone != ''">member_phone,</if>
+        <if test="memberName != null and memberName != ''">member_name,</if>
+        <if test="elderName != null and elderName != ''">elder_name,</if>
+        <if test="contractNo != null and contractNo != ''">contract_no,</if>
+        <if test="pdfUrl != null and pdfUrl != ''">pdf_url,</if>
+        <if test="memberId != null">member_id,</if>
+        <if test="elderId != null">elder_id,</if>
+        <if test="startTime != null">start_time,</if>
+        <if test="endTime != null">end_time,</if>
+        <if test="status != null">status,</if>
+        <if test="sort != null">sort,</if>
+        <if test="levelDesc != null and levelDesc != ''">level_desc,</if>
+        <if test="checkInNo != null and checkInNo != ''">check_in_no,</if>
+        <if test="signDate != null">sign_date,</if>
+        <if test="releaseSubmitter != null and releaseSubmitter != ''">release_submitter,</if>
+        <if test="releaseDate != null">release_date,</if>
+        <if test="releasePdfUrl != null and releasePdfUrl != ''">release_pdf_url,</if>
+        create_time,
+        update_time,
+        del_flag
+        ) VALUES (
+        <if test="id != null">#{id},</if>
+        <if test="name != null and name != ''">#{name},</if>
+        <if test="memberPhone != null and memberPhone != ''">#{memberPhone},</if>
+        <if test="memberName != null and memberName != ''">#{memberName},</if>
+        <if test="elderName != null and elderName != ''">#{elderName},</if>
+        <if test="contractNo != null and contractNo != ''">#{contractNo},</if>
+        <if test="pdfUrl != null and pdfUrl != ''">#{pdfUrl},</if>
+        <if test="memberId != null">#{memberId},</if>
+        <if test="elderId != null">#{elderId},</if>
+        <if test="startTime != null">#{startTime},</if>
+        <if test="endTime != null">#{endTime},</if>
+        <if test="status != null">#{status},</if>
+        <if test="sort != null">#{sort},</if>
+        <if test="levelDesc != null and levelDesc != ''">#{levelDesc},</if>
+        <if test="checkInNo != null and checkInNo != ''">#{checkInNo},</if>
+        <if test="signDate != null">#{signDate},</if>
+        <if test="releaseSubmitter != null and releaseSubmitter != ''">#{releaseSubmitter},</if>
+        <if test="releaseDate != null">#{releaseDate},</if>
+        <if test="releasePdfUrl != null and releasePdfUrl != ''">#{releasePdfUrl},</if>
+        #{createTime},
+        #{updateTime},
+        #{delFlag}
+        )
+    </insert>
+
+    <!-- 根据ID删除 -->
+    <delete id="deleteById" parameterType="java.lang.Long">
+        DELETE FROM contract WHERE id = #{id}
+    </delete>
+
+    <!-- 批量删除 -->
+    <delete id="deleteBatchIds" parameterType="java.util.List">
+        DELETE FROM contract WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <!-- 根据ID更新(动态更新非空字段) -->
+    <update id="updateById" parameterType="com.kyl.entity.Contract">
+        UPDATE contract
+        <set>
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="memberPhone != null and memberPhone != ''">member_phone = #{memberPhone},</if>
+            <if test="memberName != null and memberName != ''">member_name = #{memberName},</if>
+            <if test="elderName != null and elderName != ''">elder_name = #{elderName},</if>
+            <if test="contractNo != null and contractNo != ''">contract_no = #{contractNo},</if>
+            <if test="pdfUrl != null and pdfUrl != ''">pdf_url = #{pdfUrl},</if>
+            <if test="memberId != null">member_id = #{memberId},</if>
+            <if test="elderId != null">elder_id = #{elderId},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="sort != null">sort = #{sort},</if>
+            <if test="levelDesc != null and levelDesc != ''">level_desc = #{levelDesc},</if>
+            <if test="checkInNo != null and checkInNo != ''">check_in_no = #{checkInNo},</if>
+            <if test="signDate != null">sign_date = #{signDate},</if>
+            <if test="releaseSubmitter != null and releaseSubmitter != ''">release_submitter = #{releaseSubmitter},</if>
+            <if test="releaseDate != null">release_date = #{releaseDate},</if>
+            <if test="releasePdfUrl != null and releasePdfUrl != ''">release_pdf_url = #{releasePdfUrl},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 根据ID查询 -->
+    <select id="selectById" parameterType="java.lang.Long" resultType="com.kyl.entity.Contract">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM contract
+        WHERE id = #{id}
+        AND del_flag = 0
+    </select>
+
+    <!-- 根据老人ID查询合同 -->
+    <select id="selectByElderId" parameterType="java.lang.Long" resultType="com.kyl.entity.Contract">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM contract
+        WHERE elder_id = #{elderId}
+        AND del_flag = 0
+        AND end_time &gt; NOW() <!-- 筛选未过期合同 -->
+        LIMIT 1
+    </select>
+
+    <!-- 根据合同编号查询合同 -->
+    <select id="selectByContractNo" parameterType="java.lang.String" resultType="com.kyl.entity.Contract">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM contract
+        WHERE contract_no = #{contractNo}
+        AND del_flag = 0
+    </select>
+
+    <!-- 查询指定状态的有效合同 -->
+    <select id="selectValidContractByStatus" resultType="com.kyl.entity.Contract">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM contract
+        WHERE status = #{status}
+        AND end_time &gt; #{currentTime}
+        AND del_flag = 0
+        ORDER BY sign_date DESC
+    </select>
+
+    <!-- 多条件查询合同列表(核心动态SQL) -->
+    <select id="selectList" parameterType="com.kyl.entity.Contract" resultType="com.kyl.entity.Contract">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM contract
+        <where>
+            <!-- 通用逻辑删除过滤 -->
+            <if test="delFlag != null">
+                AND del_flag = #{delFlag}
+            </if>
+            <!-- 合同编号(模糊查询) -->
+            <if test="contractNo != null and contractNo != ''">
+                AND contract_no LIKE CONCAT('%', #{contractNo}, '%')
+            </if>
+            <!-- 老人ID -->
+            <if test="elderId != null">
+                AND elder_id = #{elderId}
+            </if>
+            <!-- 会员ID -->
+            <if test="memberId != null">
+                AND member_id = #{memberId}
+            </if>
+            <!-- 合同状态 -->
+            <if test="status != null">
+                AND status = #{status}
+            </if>
+            <!-- 入住编号 -->
+            <if test="checkInNo != null and checkInNo != ''">
+                AND check_in_no = #{checkInNo}
+            </if>
+            <!-- 签约时间范围(大于指定时间) -->
+            <if test="signDate != null">
+                AND sign_date &gt; #{signDate}
+            </if>
+            <!-- 合同有效期(开始时间小于当前,结束时间大于当前) -->
+            <if test="startTime != null and endTime != null">
+                AND start_time &lt; #{startTime}
+                AND end_time &gt; #{endTime}
+            </if>
+            <!-- 丙方名称(模糊查询) -->
+            <if test="memberName != null and memberName != ''">
+                AND member_name LIKE CONCAT('%', #{memberName}, '%')
+            </if>
+        </where>
+        ORDER BY sort ASC, create_time DESC
+    </select>
+
+</mapper>

+ 93 - 0
kyl/kyl-service/src/main/resources/mapper/ElderMapper.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<!-- 注意替换为实际的 Mapper 接口路径 -->
+<mapper namespace="com.kyl.mapper.ElderMapper">
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, image, id_card_no, age, sex, status, phone, 
+        create_time, update_time, create_by, update_by, remark, 
+        bed_number, bed_id
+    </sql>
+
+    <!-- 新增老人信息 -->
+    <insert id="insertElder" parameterType="com.kyl.entity.Elder">
+        INSERT INTO elder (
+            name, image, id_card_no, age, sex, status, phone,
+            create_time, update_time, create_by, update_by, remark,
+            bed_number, bed_id
+        ) VALUES (
+                     #{name}, #{image}, #{idCardNo}, #{age}, #{sex}, #{status}, #{phone},
+                     #{createTime}, #{updateTime}, #{createBy}, #{updateBy}, #{remark},
+                     #{bedNumber}, #{bedId}
+                 )
+    </insert>
+
+    <!-- 根据ID删除老人信息 -->
+    <delete id="deleteElderById" parameterType="java.lang.Long">
+        DELETE FROM elder WHERE id = #{id}
+    </delete>
+
+    <!-- 动态更新老人信息(只更新非空字段) -->
+    <update id="updateElderById" parameterType="com.kyl.entity.Elder">
+        UPDATE elder
+        <set>
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="image != null and image != ''">image = #{image},</if>
+            <if test="idCardNo != null and idCardNo != ''">id_card_no = #{idCardNo},</if>
+            <if test="age != null and age != ''">age = #{age},</if>
+            <if test="sex != null and sex != ''">sex = #{sex},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="phone != null and phone != ''">phone = #{phone},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="remark != null and remark != ''">remark = #{remark},</if>
+            <if test="bedNumber != null and bedNumber != ''">bed_number = #{bedNumber},</if>
+            <if test="bedId != null">bed_id = #{bedId},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <!-- 根据ID查询老人信息 -->
+    <select id="selectElderById" parameterType="java.lang.Long" resultType="com.kyl.entity.Elder">
+        SELECT <include refid="Base_Column_List"/>
+        FROM elder
+        WHERE id = #{id}
+    </select>
+
+    <!-- 根据身份证号查询老人信息 -->
+    <select id="selectElderByIdCardNo" parameterType="java.lang.String" resultType="com.kyl.entity.Elder">
+        SELECT <include refid="Base_Column_List"/>
+        FROM elder
+        WHERE id_card_no = #{idCardNo}
+    </select>
+
+    <!-- 多条件查询老人列表 -->
+    <select id="selectElderList" parameterType="com.kyl.entity.Elder" resultType="com.kyl.entity.Elder">
+        SELECT <include refid="Base_Column_List"/>
+        FROM elder
+        <where>
+            <if test="name != null and name != ''">
+                AND name LIKE CONCAT('%', #{name}, '%')
+            </if>
+            <if test="idCardNo != null and idCardNo != ''">
+                AND id_card_no = #{idCardNo}
+            </if>
+            <if test="status != null">
+                AND status = #{status}
+            </if>
+            <if test="phone != null and phone != ''">
+                AND phone LIKE CONCAT('%', #{phone}, '%')
+            </if>
+            <if test="bedNumber != null and bedNumber != ''">
+                AND bed_number = #{bedNumber}
+            </if>
+            <!-- 状态过滤:默认只查询启用状态,可根据需求调整 -->
+            AND status != 0
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+</mapper>

+ 28 - 0
kyl/kyl-service/src/main/resources/temp.json

@@ -0,0 +1,28 @@
+{
+  "elderDto": {
+    "idCardNo": "210234190606066166",
+    "name": "孙物抗",
+    "phone": "13212344321"
+  },
+  "memberElderDtos": [
+    {
+      "key": "0",
+      "name": "孙魔抗",
+      "phone": "13212348765",
+      "refId": "0",
+      "refName": "子女"
+    },
+    {
+      "key": "1",
+      "name": "6543",
+      "phone": "13456780954",
+      "refId": "2",
+      "refName": "亲属"
+    }
+  ],
+  "otherApplyInfo": "{\n  \"name\": 345,\n  \"idCardNo\": 210234190606066166,\n  \"sex\": 0,\n  \"birthdate\": \"1906-06-06\",\n  \"age\": 120,\n  \"phone\": 13212344321,\n  \"address\": \"123345667777\",\n  \"nationality\": \"汉族\",\n  \"politicStatus\": \"群众\",\n  \"religion\": \"佛教\",\n  \"maritalStatus\": \"已婚\",\n  \"education\": \"中专\",\n  \"sourceFinance\": \"退休金\",\n  \"hobby\": 123,\n  \"medicalSecurity\": \"城镇职工基本医疗保险\",\n  \"medicineCard\": 13212233444\n}",
+"taskId": "",
+"url1": "https://wanjl.oss-cn-beijing.aliyuncs.com/c90ba9f4-4b3a-4ee7-a1c5-674baad051b0.png",
+"url2": "https://wanjl.oss-cn-beijing.aliyuncs.com/aaa9dd65-f9c8-4fbe-af4c-5affb379aa98.jpg",
+"url3": "https://wanjl.oss-cn-beijing.aliyuncs.com/6b829553-87a4-4f39-b162-829a28829a33.jpg"
+}

+ 49 - 0
kyl/kyl-web/src/main/java/com/kyl/controller/ApplicationsController.java

@@ -0,0 +1,49 @@
+package com.kyl.controller;
+
+
+import com.kyl.base.PageResponse;
+import com.kyl.base.ResponseResult;
+import com.kyl.dto.ApplicationsDto;
+import com.kyl.dto.PendingTasksDto;
+import com.kyl.entity.PendingTasks;
+import com.kyl.service.PendingTasksService;
+import com.kyl.utils.BeanConv;
+import com.kyl.utils.UserThreadLocal;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title ApplicationsController
+ * @description
+ * @create 2026/3/29
+ */
+
+@RestController
+@RequestMapping("/applications")
+@Api(tags = "申请",description = "申请信息管理")
+public class ApplicationsController {
+    @Autowired
+    private PendingTasksService pendingTasksService;
+    @PostMapping("/selectByPage")
+    @ApiOperation(value = "查询申请信息", notes = "根据条件查询申请信息,传入申请信息对象")
+    public ResponseResult<List<PendingTasks>> selectByPage(@RequestBody ApplicationsDto applicationsDto){
+        //只查询当前的登录人的任务
+        Long userId = UserThreadLocal.getMgtUserId();
+        applicationsDto.setApplicatId(userId);  //设置当前登录人
+        //转换对象
+        PendingTasksDto bean = BeanConv.toBean(applicationsDto, PendingTasksDto.class);
+
+        PageResponse pageResponse = pendingTasksService.getMyTaskList(bean);
+        return ResponseResult.success(pageResponse);
+    }
+}
+

+ 40 - 0
kyl/kyl-web/src/main/java/com/kyl/controller/CheckInController.java

@@ -0,0 +1,40 @@
+package com.kyl.controller;
+
+
+import com.kyl.base.ResponseResult;
+import com.kyl.dto.CheckInDto;
+import com.kyl.service.CheckInService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title CheckInController
+ * @description
+ * @create 2026/3/22
+ */
+@RestController
+@RequestMapping("/checkIn")
+@Api(tags = "入住申请",description = "入住申请管理")
+public class CheckInController {
+    @Autowired
+    private CheckInService checkInService;
+    /**
+     * 创建入住申请
+     * @return 统一响应结果
+     */
+    @PostMapping("/create")
+    @ApiOperation(value = "创建入住申请", notes = "根据入住信息创建入住申请")
+    public ResponseResult createCheckIn(
+            @RequestBody @ApiParam(value = "入住信息",required = true) CheckInDto checkInDto){
+        return checkInService.createCheckIn(checkInDto);
+    }
+
+}

+ 44 - 0
kyl/kyl-web/src/main/java/com/kyl/controller/PendingTasksController.java

@@ -0,0 +1,44 @@
+package com.kyl.controller;
+
+
+import com.kyl.base.PageResponse;
+import com.kyl.base.ResponseResult;
+import com.kyl.dto.PendingTasksDto;
+import com.kyl.entity.PendingTasks;
+import com.kyl.service.PendingTasksService;
+import com.kyl.utils.UserThreadLocal;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title PendingTasksController
+ * @description 代办
+ * @create 2026/3/29
+ */
+@RestController
+@RequestMapping("/pending_tasks")
+@Api(tags = "代办",description = "代办信息管理")
+public class PendingTasksController {
+    @Autowired
+    private PendingTasksService pendingTasksService;
+    @PostMapping("/selectByPage")
+    @ApiOperation(value = "查询代办信息", notes = "根据条件查询代办信息,传入代办信息对象")
+    public ResponseResult<List<PendingTasks>> selectByPage(@RequestBody PendingTasksDto pendingTasksDto){
+        //只查询当前的登录人的任务
+        Long userId = UserThreadLocal.getMgtUserId();
+        pendingTasksDto.setAssigneeId(userId);  //设置当前登录人
+
+        PageResponse pageResponse = pendingTasksService.getMyTaskList(pendingTasksDto);
+        return ResponseResult.success(pageResponse);
+    }
+
+}

+ 9 - 0
kyl/kyl-web/src/main/resources/application.yaml

@@ -37,6 +37,15 @@ spring:
   redis:
     host: 192.168.200.128
     port: 6379
+  activiti:
+    #是否让activiti自动创建所有的历史表
+    history-level: full
+    #是否需要使用历史表,默认false不使用,而配置true是使用历史表
+    db-history-used: true
+    #流程自动部署,关闭,需要手动部署流程 服务启动的时候自动检查resources目录下的bpmn文件 如果为true自动部署流程
+    check-process-definitions: false
+    #关闭启动服务自动框架部署
+    deployment-mode: never-fail
 
 # MyBatis配置
 mybatis:

+ 37 - 0
kyl/kyl-web/src/test/java/com/kyl/service/Activiti7DeployTest.java

@@ -0,0 +1,37 @@
+package com.kyl.service;
+
+
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.repository.Deployment;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title test
+ * @description
+ * @create 2026/3/22
+ */
+@SpringBootTest
+public class Activiti7DeployTest {
+    @Autowired
+    private RepositoryService repositoryService;
+
+    /**
+     * 部署流程
+     */
+    @Test
+    public void deployProcess(){
+        String processName = "bpmn/checkIn.bpmn";
+        // 创建流程部署对象
+        Deployment deployment = repositoryService.createDeployment()    // 创建流程部署对象
+                .addClasspathResource(processName)  // 添加流程定义文件
+                .name("checkIn")    // 设置流程定义名称
+                .deploy();  // 部署流程定义
+        System.out.println("流程部署ID:" + deployment.getId());
+        System.out.println("流程部署名称:" + deployment.getName());
+
+    }
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 54
kyl/logs/kyl.log.2026-02-08.log


+ 12 - 1
kyl/pom.xml

@@ -46,6 +46,7 @@
         <xxl-job.version>2.3.0</xxl-job.version>
         <!--orika 拷贝工具 -->
         <orika-core.version>1.5.4</orika-core.version>
+        <activiti.version>7.1.0.M6</activiti.version>
     </properties>
     <!--依赖管理-->
     <dependencyManagement>
@@ -164,7 +165,11 @@
                 <artifactId>jjwt</artifactId>
                 <version>${jjwt.version}</version>
             </dependency>
-
+            <dependency>
+                <groupId>org.activiti</groupId>
+                <artifactId>activiti-spring-boot-starter</artifactId>
+                <version>${activiti.version}</version>
+            </dependency>
 
             <dependency>
                 <groupId>com.kyl</groupId>
@@ -210,6 +215,12 @@
                 <enabled>false</enabled>
             </snapshots>
         </repository>
+
+        <!--如果activiti依赖下载不了,可以配置如下地址进行下载-->
+        <repository>
+            <id>activiti-releases</id>
+            <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases</url>
+        </repository>
     </repositories>
     <!--构建配置-->
     <build>

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.