bain-riper-cli 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +14 -0
- package/package.json +34 -0
- package/src/commands/add.js +28 -0
- package/src/commands/init.js +58 -0
- package/src/commands/list.js +44 -0
- package/src/index.js +86 -0
- package/src/modules.js +136 -0
- package/src/utils/checklist.js +49 -0
- package/src/utils/copier.js +100 -0
- package/src/utils/logger.js +18 -0
- package/templates/docs/reference-code/controller/EmployeeTrainingController.java +107 -0
- package/templates/docs/reference-code/domain/EmployeeTraining.java +89 -0
- package/templates/docs/reference-code/domain/bo/EmployeeTrainingBo.java +96 -0
- package/templates/docs/reference-code/domain/vo/EmployeeTrainingVo.java +100 -0
- package/templates/docs/reference-code/mapper/EmployeeTrainingMapper.java +17 -0
- package/templates/docs/reference-code/resources/mapper/EmployeeTrainingMapper.xml +7 -0
- package/templates/docs/reference-code/service/IEmployeeTrainingService.java +69 -0
- package/templates/docs/reference-code/service/impl/EmployeeTrainingServiceImpl.java +144 -0
- package/templates/openspec/config.yaml +126 -0
- package/templates/openspec/project-profile.md +107 -0
- package/templates/qoder/mcp.json +9 -0
- package/templates/qoder/rules/openspec_codegraph.md +162 -0
- package/templates/qoder/rules/openspec_output_specs.md +112 -0
- package/templates/qoder/rules/openspec_preflight.md +230 -0
- package/templates/qoder/rules/openspec_reverse_sync.md +97 -0
- package/templates/qoder/rules/openspec_specifications.md +84 -0
- package/templates/qoder/rules/openspec_task_tiers.md +109 -0
- package/templates/qoder/rules/project_constitution.md +90 -0
- package/templates/qoder/skills/requirement-breakdown/SKILL.md +126 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package com.reference.domain;
|
|
2
|
+
|
|
3
|
+
import com.baomidou.mybatisplus.annotation.IdType;
|
|
4
|
+
import com.baomidou.mybatisplus.annotation.TableId;
|
|
5
|
+
import com.baomidou.mybatisplus.annotation.TableName;
|
|
6
|
+
import lombok.Data;
|
|
7
|
+
import lombok.EqualsAndHashCode;
|
|
8
|
+
import org.dromara.common.tenant.core.TenantEntity;
|
|
9
|
+
|
|
10
|
+
import java.io.Serial;
|
|
11
|
+
import java.math.BigDecimal;
|
|
12
|
+
import java.time.LocalDate;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 员工培训档案对象 employee_training
|
|
16
|
+
*
|
|
17
|
+
* @author LiuBin
|
|
18
|
+
* @date 2025-12-07
|
|
19
|
+
*/
|
|
20
|
+
@Data
|
|
21
|
+
@EqualsAndHashCode(callSuper = true)
|
|
22
|
+
@TableName("employee_training")
|
|
23
|
+
public class EmployeeTraining extends TenantEntity {
|
|
24
|
+
|
|
25
|
+
@Serial
|
|
26
|
+
private static final long serialVersionUID = 1L;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 主键
|
|
30
|
+
*/
|
|
31
|
+
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
32
|
+
private Long id;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 员工信息ID
|
|
36
|
+
*/
|
|
37
|
+
private Long employeeId;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 姓名
|
|
41
|
+
*/
|
|
42
|
+
private String name;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 身份证号
|
|
46
|
+
*/
|
|
47
|
+
private String idCardNumber;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 培训课程
|
|
51
|
+
*/
|
|
52
|
+
private String trainingCourse;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 培训机构
|
|
56
|
+
*/
|
|
57
|
+
private String trainingInstitution;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 培训讲师
|
|
61
|
+
*/
|
|
62
|
+
private String trainer;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 参训时间
|
|
66
|
+
*/
|
|
67
|
+
private LocalDate trainingTime;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 服务期
|
|
71
|
+
*/
|
|
72
|
+
private LocalDate serviceEndDate;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 服务年限
|
|
76
|
+
*/
|
|
77
|
+
private String serviceYears;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 培训金额
|
|
81
|
+
*/
|
|
82
|
+
private BigDecimal trainingAmount;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 备注
|
|
86
|
+
*/
|
|
87
|
+
private String remark;
|
|
88
|
+
|
|
89
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
package com.reference.domain.bo;
|
|
2
|
+
|
|
3
|
+
import com.reference.domain.EmployeeTraining;
|
|
4
|
+
import io.github.linpeilie.annotations.AutoMapper;
|
|
5
|
+
import jakarta.validation.constraints.NotBlank;
|
|
6
|
+
import jakarta.validation.constraints.NotNull;
|
|
7
|
+
import lombok.Data;
|
|
8
|
+
import lombok.EqualsAndHashCode;
|
|
9
|
+
import org.dromara.common.core.validate.AddGroup;
|
|
10
|
+
import org.dromara.common.core.validate.EditGroup;
|
|
11
|
+
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
|
12
|
+
|
|
13
|
+
import java.math.BigDecimal;
|
|
14
|
+
import java.time.LocalDate;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 员工培训档案业务对象 employee_training
|
|
18
|
+
*
|
|
19
|
+
* @author LiuBin
|
|
20
|
+
* @date 2025-12-07
|
|
21
|
+
*/
|
|
22
|
+
@Data
|
|
23
|
+
@EqualsAndHashCode(callSuper = true)
|
|
24
|
+
@AutoMapper(target = EmployeeTraining.class, reverseConvertGenerate = false)
|
|
25
|
+
public class EmployeeTrainingBo extends BaseEntity {
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 主键
|
|
29
|
+
*/
|
|
30
|
+
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
|
31
|
+
private Long id;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 员工信息ID
|
|
35
|
+
*/
|
|
36
|
+
private Long employeeId;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 姓名
|
|
40
|
+
*/
|
|
41
|
+
@NotBlank(message = "姓名不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
42
|
+
private String name;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 身份证号
|
|
46
|
+
*/
|
|
47
|
+
@NotBlank(message = "身份证号不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
48
|
+
private String idCardNumber;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 培训课程
|
|
52
|
+
*/
|
|
53
|
+
@NotBlank(message = "培训课程不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
54
|
+
private String trainingCourse;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 培训机构
|
|
58
|
+
*/
|
|
59
|
+
@NotBlank(message = "培训机构不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
60
|
+
private String trainingInstitution;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 培训讲师
|
|
64
|
+
*/
|
|
65
|
+
private String trainer;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 参训时间
|
|
69
|
+
*/
|
|
70
|
+
@NotNull(message = "参训时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
71
|
+
private LocalDate trainingTime;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 服务期
|
|
75
|
+
*/
|
|
76
|
+
@NotNull(message = "服务期不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
77
|
+
private LocalDate serviceEndDate;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 服务年限
|
|
81
|
+
*/
|
|
82
|
+
@NotBlank(message = "服务年限不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
83
|
+
private String serviceYears;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 培训金额
|
|
87
|
+
*/
|
|
88
|
+
@NotNull(message = "培训金额不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
89
|
+
private BigDecimal trainingAmount;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 备注
|
|
93
|
+
*/
|
|
94
|
+
private String remark;
|
|
95
|
+
|
|
96
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package com.reference.domain.vo;
|
|
2
|
+
|
|
3
|
+
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
|
4
|
+
import cn.idev.excel.annotation.ExcelProperty;
|
|
5
|
+
import com.reference.domain.EmployeeTraining;
|
|
6
|
+
import io.github.linpeilie.annotations.AutoMapper;
|
|
7
|
+
import lombok.Data;
|
|
8
|
+
|
|
9
|
+
import java.io.Serial;
|
|
10
|
+
import java.io.Serializable;
|
|
11
|
+
import java.math.BigDecimal;
|
|
12
|
+
import java.time.LocalDate;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 员工培训档案视图对象 employee_training
|
|
16
|
+
*
|
|
17
|
+
* @author LiuBin
|
|
18
|
+
* @date 2025-12-07
|
|
19
|
+
*/
|
|
20
|
+
@Data
|
|
21
|
+
@ExcelIgnoreUnannotated
|
|
22
|
+
@AutoMapper(target = EmployeeTraining.class)
|
|
23
|
+
public class EmployeeTrainingVo implements Serializable {
|
|
24
|
+
|
|
25
|
+
@Serial
|
|
26
|
+
private static final long serialVersionUID = 1L;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 主键
|
|
30
|
+
*/
|
|
31
|
+
@ExcelProperty(value = "主键")
|
|
32
|
+
private Long id;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 员工信息ID
|
|
36
|
+
*/
|
|
37
|
+
@ExcelProperty(value = "员工信息ID")
|
|
38
|
+
private Long employeeId;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 姓名
|
|
42
|
+
*/
|
|
43
|
+
@ExcelProperty(value = "姓名")
|
|
44
|
+
private String name;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 身份证号
|
|
48
|
+
*/
|
|
49
|
+
@ExcelProperty(value = "身份证号")
|
|
50
|
+
private String idCardNumber;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 培训课程
|
|
54
|
+
*/
|
|
55
|
+
@ExcelProperty(value = "培训课程")
|
|
56
|
+
private String trainingCourse;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 培训机构
|
|
60
|
+
*/
|
|
61
|
+
@ExcelProperty(value = "培训机构")
|
|
62
|
+
private String trainingInstitution;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 培训讲师
|
|
66
|
+
*/
|
|
67
|
+
@ExcelProperty(value = "培训讲师")
|
|
68
|
+
private String trainer;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 参训时间
|
|
72
|
+
*/
|
|
73
|
+
@ExcelProperty(value = "参训时间")
|
|
74
|
+
private LocalDate trainingTime;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 服务期
|
|
78
|
+
*/
|
|
79
|
+
@ExcelProperty(value = "服务期")
|
|
80
|
+
private LocalDate serviceEndDate;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 服务年限
|
|
84
|
+
*/
|
|
85
|
+
@ExcelProperty(value = "服务年限")
|
|
86
|
+
private String serviceYears;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 培训金额
|
|
90
|
+
*/
|
|
91
|
+
@ExcelProperty(value = "培训金额")
|
|
92
|
+
private BigDecimal trainingAmount;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 备注
|
|
96
|
+
*/
|
|
97
|
+
@ExcelProperty(value = "备注")
|
|
98
|
+
private String remark;
|
|
99
|
+
|
|
100
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.reference.mapper;
|
|
2
|
+
|
|
3
|
+
import com.reference.domain.EmployeeTraining;
|
|
4
|
+
import com.reference.domain.vo.EmployeeTrainingVo;
|
|
5
|
+
import org.apache.ibatis.annotations.Mapper;
|
|
6
|
+
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 员工培训档案Mapper接口
|
|
10
|
+
*
|
|
11
|
+
* @author LiuBin
|
|
12
|
+
* @date 2025-12-07
|
|
13
|
+
*/
|
|
14
|
+
@Mapper
|
|
15
|
+
public interface EmployeeTrainingMapper extends BaseMapperPlus<EmployeeTraining, EmployeeTrainingVo> {
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.reference.service;
|
|
2
|
+
|
|
3
|
+
import com.reference.domain.bo.EmployeeTrainingBo;
|
|
4
|
+
import com.reference.domain.vo.EmployeeTrainingVo;
|
|
5
|
+
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
6
|
+
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
7
|
+
|
|
8
|
+
import java.util.Collection;
|
|
9
|
+
import java.util.List;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 员工培训档案Service接口
|
|
13
|
+
*
|
|
14
|
+
* @author LiuBin
|
|
15
|
+
* @date 2025-12-07
|
|
16
|
+
*/
|
|
17
|
+
public interface IEmployeeTrainingService {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 查询员工培训档案
|
|
21
|
+
*
|
|
22
|
+
* @param id 主键
|
|
23
|
+
* @return 员工培训档案
|
|
24
|
+
*/
|
|
25
|
+
EmployeeTrainingVo queryById(Long id);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 分页查询员工培训档案列表
|
|
29
|
+
*
|
|
30
|
+
* @param bo 查询条件
|
|
31
|
+
* @param pageQuery 分页参数
|
|
32
|
+
* @return 员工培训档案分页列表
|
|
33
|
+
*/
|
|
34
|
+
TableDataInfo<EmployeeTrainingVo> queryPageList(EmployeeTrainingBo bo, PageQuery pageQuery);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 查询符合条件的员工培训档案列表
|
|
38
|
+
*
|
|
39
|
+
* @param bo 查询条件
|
|
40
|
+
* @return 员工培训档案列表
|
|
41
|
+
*/
|
|
42
|
+
List<EmployeeTrainingVo> queryList(EmployeeTrainingBo bo);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 新增员工培训档案
|
|
46
|
+
*
|
|
47
|
+
* @param bo 员工培训档案
|
|
48
|
+
* @return 是否新增成功
|
|
49
|
+
*/
|
|
50
|
+
Boolean insertByBo(EmployeeTrainingBo bo);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 修改员工培训档案
|
|
54
|
+
*
|
|
55
|
+
* @param bo 员工培训档案
|
|
56
|
+
* @return 是否修改成功
|
|
57
|
+
*/
|
|
58
|
+
Boolean updateByBo(EmployeeTrainingBo bo);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 校验并批量删除员工培训档案信息
|
|
62
|
+
*
|
|
63
|
+
* @param ids 待删除的主键集合
|
|
64
|
+
* @param isValid 是否进行有效性校验
|
|
65
|
+
* @return 是否删除成功
|
|
66
|
+
*/
|
|
67
|
+
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
68
|
+
|
|
69
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
package com.reference.service.impl;
|
|
2
|
+
|
|
3
|
+
import com.reference.domain.EmployeeTraining;
|
|
4
|
+
import com.reference.domain.bo.EmployeeTrainingBo;
|
|
5
|
+
import com.reference.domain.vo.EmployeeTrainingVo;
|
|
6
|
+
import com.reference.mapper.EmployeeTrainingMapper;
|
|
7
|
+
import com.reference.service.IEmployeeTrainingService;
|
|
8
|
+
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
9
|
+
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
10
|
+
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
11
|
+
import lombok.RequiredArgsConstructor;
|
|
12
|
+
import lombok.extern.slf4j.Slf4j;
|
|
13
|
+
import org.dromara.common.core.utils.MapstructUtils;
|
|
14
|
+
import org.dromara.common.core.utils.StringUtils;
|
|
15
|
+
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
16
|
+
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
17
|
+
import org.springframework.stereotype.Service;
|
|
18
|
+
|
|
19
|
+
import java.math.BigDecimal;
|
|
20
|
+
import java.util.Collection;
|
|
21
|
+
import java.util.List;
|
|
22
|
+
import java.util.Map;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 员工培训档案Service业务层处理
|
|
26
|
+
*
|
|
27
|
+
* @author LiuBin
|
|
28
|
+
* @date 2025-12-07
|
|
29
|
+
*/
|
|
30
|
+
@Slf4j
|
|
31
|
+
@RequiredArgsConstructor
|
|
32
|
+
@Service
|
|
33
|
+
public class EmployeeTrainingServiceImpl implements IEmployeeTrainingService {
|
|
34
|
+
|
|
35
|
+
private final EmployeeTrainingMapper baseMapper;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 查询员工培训档案
|
|
39
|
+
*
|
|
40
|
+
* @param id 主键
|
|
41
|
+
* @return 员工培训档案
|
|
42
|
+
*/
|
|
43
|
+
@Override
|
|
44
|
+
public EmployeeTrainingVo queryById(Long id) {
|
|
45
|
+
return baseMapper.selectVoById(id);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 分页查询员工培训档案列表
|
|
50
|
+
*
|
|
51
|
+
* @param bo 查询条件
|
|
52
|
+
* @param pageQuery 分页参数
|
|
53
|
+
* @return 员工培训档案分页列表
|
|
54
|
+
*/
|
|
55
|
+
@Override
|
|
56
|
+
public TableDataInfo<EmployeeTrainingVo> queryPageList(EmployeeTrainingBo bo, PageQuery pageQuery) {
|
|
57
|
+
LambdaQueryWrapper<EmployeeTraining> lqw = buildQueryWrapper(bo);
|
|
58
|
+
Page<EmployeeTrainingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
59
|
+
return TableDataInfo.build(result);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 查询符合条件的员工培训档案列表
|
|
64
|
+
*
|
|
65
|
+
* @param bo 查询条件
|
|
66
|
+
* @return 员工培训档案列表
|
|
67
|
+
*/
|
|
68
|
+
@Override
|
|
69
|
+
public List<EmployeeTrainingVo> queryList(EmployeeTrainingBo bo) {
|
|
70
|
+
LambdaQueryWrapper<EmployeeTraining> lqw = buildQueryWrapper(bo);
|
|
71
|
+
return baseMapper.selectVoList(lqw);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private LambdaQueryWrapper<EmployeeTraining> buildQueryWrapper(EmployeeTrainingBo bo) {
|
|
75
|
+
Map<String, Object> params = bo.getParams();
|
|
76
|
+
LambdaQueryWrapper<EmployeeTraining> lqw = Wrappers.lambdaQuery();
|
|
77
|
+
lqw.eq(bo.getEmployeeId() != null, EmployeeTraining::getEmployeeId, bo.getEmployeeId());
|
|
78
|
+
lqw.like(StringUtils.isNotBlank(bo.getName()), EmployeeTraining::getName, bo.getName());
|
|
79
|
+
lqw.eq(StringUtils.isNotBlank(bo.getTrainingCourse()), EmployeeTraining::getTrainingCourse, bo.getTrainingCourse());
|
|
80
|
+
lqw.eq(StringUtils.isNotBlank(bo.getTrainingInstitution()), EmployeeTraining::getTrainingInstitution, bo.getTrainingInstitution());
|
|
81
|
+
lqw.eq(StringUtils.isNotBlank(bo.getTrainer()), EmployeeTraining::getTrainer, bo.getTrainer());
|
|
82
|
+
lqw.between(params.get("beginTrainingTime") != null && params.get("endTrainingTime") != null,
|
|
83
|
+
EmployeeTraining::getTrainingTime, params.get("beginTrainingTime"), params.get("endTrainingTime"));
|
|
84
|
+
lqw.between(params.get("beginServiceEndDate") != null && params.get("endServiceEndDate") != null,
|
|
85
|
+
EmployeeTraining::getServiceEndDate, params.get("beginServiceEndDate"), params.get("endServiceEndDate"));
|
|
86
|
+
lqw.eq(StringUtils.isNotBlank(bo.getServiceYears()), EmployeeTraining::getServiceYears, bo.getServiceYears());
|
|
87
|
+
lqw.eq(bo.getTrainingAmount() != null, EmployeeTraining::getTrainingAmount, bo.getTrainingAmount());
|
|
88
|
+
lqw.orderByDesc(EmployeeTraining::getId);
|
|
89
|
+
return lqw;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 新增员工培训档案
|
|
94
|
+
*
|
|
95
|
+
* @param bo 员工培训档案
|
|
96
|
+
* @return 是否新增成功
|
|
97
|
+
*/
|
|
98
|
+
@Override
|
|
99
|
+
public Boolean insertByBo(EmployeeTrainingBo bo) {
|
|
100
|
+
EmployeeTraining add = MapstructUtils.convert(bo, EmployeeTraining.class);
|
|
101
|
+
validEntityBeforeSave(add);
|
|
102
|
+
boolean flag = baseMapper.insert(add) > 0;
|
|
103
|
+
if (flag) {
|
|
104
|
+
bo.setId(add.getId());
|
|
105
|
+
}
|
|
106
|
+
return flag;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 修改员工培训档案
|
|
111
|
+
*
|
|
112
|
+
* @param bo 员工培训档案
|
|
113
|
+
* @return 是否修改成功
|
|
114
|
+
*/
|
|
115
|
+
@Override
|
|
116
|
+
public Boolean updateByBo(EmployeeTrainingBo bo) {
|
|
117
|
+
EmployeeTraining update = MapstructUtils.convert(bo, EmployeeTraining.class);
|
|
118
|
+
validEntityBeforeSave(update);
|
|
119
|
+
return baseMapper.updateById(update) > 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 保存前的数据校验
|
|
124
|
+
*/
|
|
125
|
+
private void validEntityBeforeSave(EmployeeTraining entity) {
|
|
126
|
+
// 做一些数据校验,如唯一约束
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 校验并批量删除员工培训档案信息
|
|
131
|
+
*
|
|
132
|
+
* @param ids 待删除的主键集合
|
|
133
|
+
* @param isValid 是否进行有效性校验
|
|
134
|
+
* @return 是否删除成功
|
|
135
|
+
*/
|
|
136
|
+
@Override
|
|
137
|
+
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
138
|
+
if (isValid) {
|
|
139
|
+
// 做一些业务上的校验,判断是否需要校验
|
|
140
|
+
}
|
|
141
|
+
return baseMapper.deleteByIds(ids) > 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
schema: spec-driven
|
|
2
|
+
|
|
3
|
+
# Project context (optional)
|
|
4
|
+
# This is shown to AI when creating artifacts.
|
|
5
|
+
context: |
|
|
6
|
+
# ===== 项目骨架(详见 openspec/project-profile.md)=====
|
|
7
|
+
Project Profile (项目骨架的唯一真相源):
|
|
8
|
+
- Path: openspec/project-profile.md
|
|
9
|
+
- Usage: 技术栈、分层目录、资源路径、领域约定、参考模板、repowiki 映射
|
|
10
|
+
等所有「换了项目必改」的信息均在此文件。§1 技术栈 / §2 项目骨架 /
|
|
11
|
+
§3 标准分层 / §4 领域约定 / §5 参考模板 / §6 repowiki 章节目录。
|
|
12
|
+
- Purpose: 实现「核心套件跨项目复用 / 只换 Profile」两层架构。
|
|
13
|
+
|
|
14
|
+
# ===== 前置必读资料(生成任何 artifact 前务必按需阅读相关章节)=====
|
|
15
|
+
Project Constitution (最高优先级,始终生效):
|
|
16
|
+
- Path: .qoder/rules/project_constitution.md
|
|
17
|
+
- Usage: 项目宪法(trigger: always_on)。10 条跨场景绝不可违反的底线:
|
|
18
|
+
§1 Spec is Truth / §2 Restate First / §3 多租户字段完整性 /
|
|
19
|
+
§4 SHALL-MUST 关键字 / §5 禁止重复造轮子 / §6 禁止猜测 API /
|
|
20
|
+
§7 标准分层目录 / §8 参考代码优先对齐 / §9 禁止独立编译任务 /
|
|
21
|
+
§10 Preflight 自检物理可见。宪法优先级高于其余所有 context 与 rules;
|
|
22
|
+
任一条款与下方规则冲突时以宪法为准。
|
|
23
|
+
|
|
24
|
+
Restate First (最先执行,先于前置阅读与 artifact 生成):
|
|
25
|
+
- Rule: 在任何前置阅读、CLI 调用、artifact 生成之前,必须先用 8 行以内
|
|
26
|
+
复述理解:任务目标 / 边界 / Done Contract / 关键风险或歧义;并等待
|
|
27
|
+
用户明确确认后才进入后续流程。若存在歧义必须先澄清。执行前
|
|
28
|
+
checkpoint、偏差暴露后、artifact 收尾时均需重新对齐核心目标。
|
|
29
|
+
- Purpose: 避免"四件套写完才发现理解错了"的返工(源自 SDD-RIPER Light)。
|
|
30
|
+
|
|
31
|
+
Clarify (Restate 通过后、前置阅读前执行):
|
|
32
|
+
- Rule: 必须用 AskUserQuestion 主动列出 3-5 个歧义点(每条给出
|
|
33
|
+
二选一或三选一候选答案),等用户作答并把答案回写到 Restate 末尾
|
|
34
|
+
形成"对齐纪要",再进入前置阅读。数据模型/接口/权限/租户/编制计划类
|
|
35
|
+
变更必须执行;纯修正、单枚举等简单任务可显式声明"本任务无需 Clarify"
|
|
36
|
+
并获"OK"后继续。
|
|
37
|
+
- Purpose: 把 Restate First 从"复述理解"升级为"主动暴露并锁死边界"
|
|
38
|
+
(源自 GitHub Spec-Kit /clarify 阶段)。
|
|
39
|
+
|
|
40
|
+
Task Tiers (Restate 末尾必须声明):
|
|
41
|
+
- Path: .qoder/rules/openspec_task_tiers.md
|
|
42
|
+
- Rule: Restate 8 行里必须增加"档位:<zero|fast|standard|deep> + 一句话理由"。
|
|
43
|
+
① zero:纯问答,不生成 artifact,不走 openspec;
|
|
44
|
+
② fast:单字段/单枚举/错别字/常量修订,直接 spec delta + 1 task,
|
|
45
|
+
跳过 design.md 与 Clarify(需显式声明),repowiki 最多 0-1 章节;
|
|
46
|
+
③ standard(默认):完整四件套 + Clarify 3-5 点 + repowiki 最多 2 章节;
|
|
47
|
+
④ deep:四件套 + codemap.md + Clarify ≥5 点(覆盖架构/数据/租户/性能)
|
|
48
|
+
+ Reverse Sync 零容忍 + repowiki 最多 3 章节。
|
|
49
|
+
升档必须等用户确认并补齐前置流程;AI 不得主动降档。
|
|
50
|
+
- Purpose: 让小任务轻量、大任务扎实(对标 SDD-RIPER Light/Standard 双档)。
|
|
51
|
+
|
|
52
|
+
Preflight 物理化展示 (进入 Step 1 前必须执行):
|
|
53
|
+
- Rule: 必须在主回复开头用 Markdown checkbox(- [x] / - [ ])显式
|
|
54
|
+
打印 .qoder/rules/openspec_preflight.md §二 自检清单的真实勾选状态,
|
|
55
|
+
禁止仅用"已完成 Preflight"等文字描述代替。未展示勾选结果 = 视为未执行。
|
|
56
|
+
- Purpose: 把软约束升级为物理约束(宪法 §10 落地、对标 Kiro hooks)。
|
|
57
|
+
|
|
58
|
+
Change Inputs (per-change, 最高优先级):
|
|
59
|
+
- Path: openspec/changes/<name>/inputs/
|
|
60
|
+
- Usage: 每个 change 自带的原始需求资料(PRD、会议纪要、接口草案、
|
|
61
|
+
原型图等)。生成 artifact 前必须完整阅读该目录;目录缺失或为空
|
|
62
|
+
时禁止凭空编写需求,须先向用户确认并将结果落盘到
|
|
63
|
+
inputs/requirement.md。inputs/ 随 change 一同归档以供回溯。
|
|
64
|
+
|
|
65
|
+
Knowledge Base (repowiki):
|
|
66
|
+
- Path: 见 openspec/project-profile.md §2(知识库路径)
|
|
67
|
+
- Usage: 涉及现有功能、架构、数据模型、API 的提案按需检索。
|
|
68
|
+
- Read Strategy (硬规则,降成本):
|
|
69
|
+
① 预判:根据 Restate 选最多 2 个主章节,无关章节禁止打开;
|
|
70
|
+
② 先 list_dir 再 read_file:对目标章节先列文件清单,按文件名
|
|
71
|
+
挑 1-3 个最相关的 .md 读取,禁止整目录批量 read_file;
|
|
72
|
+
③ 不重复读:本 session 内已读文件禁止再次 read_file,
|
|
73
|
+
跨轮对话中上一轮已读内容视为已读,仅在用户要求"重新读"时才重读;
|
|
74
|
+
④ Preflight §二 自检必须列出已读章节清单作为取证。
|
|
75
|
+
- Purpose: 把 repowiki 从"每轮全量扫描"改为"按需最小读取 + 跨轮缓存",
|
|
76
|
+
显著降低 token 与响应延迟(对标 Claude Code context window 管理)。
|
|
77
|
+
|
|
78
|
+
Reference Code Templates:
|
|
79
|
+
- Path: 见 openspec/project-profile.md §2(参考代码路径)
|
|
80
|
+
- Usage: 新增 CRUD / 导入导出 / 权限 / 分页等常规功能时,
|
|
81
|
+
必须以参考模板的七层结构、命名、注解、分页写法、多租户字段为准。
|
|
82
|
+
→ 完整七层文件清单见 openspec/project-profile.md §5。
|
|
83
|
+
|
|
84
|
+
Project Rules:
|
|
85
|
+
- Path: .qoder/rules/openspec_specifications.md
|
|
86
|
+
- Usage: OpenSpec 提案阶段的完整规范(前置阅读、目录结构、
|
|
87
|
+
依赖使用、实现复用原则、SHALL/MUST 输出规范均在此文件
|
|
88
|
+
中)。
|
|
89
|
+
|
|
90
|
+
# Per-artifact rules (optional)
|
|
91
|
+
rules:
|
|
92
|
+
proposal:
|
|
93
|
+
- 宪法优先:必须先遵守 .qoder/rules/project_constitution.md 10 条底线;宪法与以下规则冲突时以宪法为准
|
|
94
|
+
- Restate First:生成 proposal 前必须先用 8 行以内复述任务目标 / 边界 / Done Contract / 风险,并等待用户明确确认;未确认前禁止进入前置阅读或 artifact 生成
|
|
95
|
+
- Clarify:Restate 确认后必须用 AskUserQuestion 列 3-5 个歧义点(二选一或三选一候选)并等用户作答;简单任务可显式声明"无需 Clarify"并获"OK"后继续(数据模型/接口/权限/租户/编制计划类变更不得省略)
|
|
96
|
+
- Task Tier:Restate 末尾必须声明 zero/fast/standard/deep 档位 + 一句话理由;fast 档跳过 design.md 与 Clarify,standard 默认全套,deep 追加 codemap.md 与 ≥5 个 Clarify 点;AI 不得主动降档,升档须用户确认
|
|
97
|
+
- Preflight 物理化展示:进入 Step 1 前必须在主回复开头以 Markdown checkbox(- [x] / - [ ])显式打印 preflight §二 自检清单的真实勾选状态,禁止仅用文字描述代替
|
|
98
|
+
- 生成 proposal 前必须先阅读 openspec/changes/<name>/inputs/ 下所有文件;该目录缺失或为空时禁止凭空编写,须先确认需求并落盘到 inputs/requirement.md
|
|
99
|
+
- Why / What Changes 必须能在 inputs/requirement.md 中找到对应依据,不得夹带需求文档未提及的功能
|
|
100
|
+
- Why 部分必须引用 .qoder/repowiki 中对应章节,明确与现有能力的边界
|
|
101
|
+
- repowiki 按需读取:最多选 2 个主章节、先 list_dir 再 read_file 挑 1-3 个最相关 .md、本 session 已读文件禁止重读;Preflight 自检必须列出已读清单
|
|
102
|
+
- What Changes 中对每一项新增能力,须标注可参考的 docs/reference-code 模板路径
|
|
103
|
+
- Impact 必须列出受影响的 repowiki 章节(未来需要更新的知识条目)
|
|
104
|
+
- 禁止凭空假设技术栈,须以实际依赖为准(pom 路径见 openspec/project-profile.md §2)
|
|
105
|
+
- 避免重复造轮子:新增功能前先检索仓库现有实现与 pom.xml 已有的包,禁止引入功能重复的依赖或重复实现已有工具类
|
|
106
|
+
- 禁止猜测第三方包用法:若 reference-code 与仓库现有实现中均未找到同类型用法,必须先阅读包源码或 README 确认 API 存在后再引用
|
|
107
|
+
|
|
108
|
+
design:
|
|
109
|
+
- 宪法优先:遵守 .qoder/rules/project_constitution.md §7 标准分层、§8 参考代码对齐
|
|
110
|
+
- Context 部分必须引用 .qoder/repowiki/zh/content/数据模型设计 与 系统架构设计 对应章节
|
|
111
|
+
- Decisions 涉及 Domain/Mapper/Controller 选型时,须对齐参考模板的继承与注解写法(具体基类与注解名见 openspec/project-profile.md §4)
|
|
112
|
+
- Non-Goals 中显式声明不修改的 repowiki 现有模块
|
|
113
|
+
|
|
114
|
+
specs:
|
|
115
|
+
- 宪法优先:遵守 .qoder/rules/project_constitution.md §3 多租户、§4 SHALL/MUST
|
|
116
|
+
- Requirements 条目必须以 SHALL 或 MUST 开头(OpenSpec 归档校验要求)
|
|
117
|
+
- WHEN/THEN/AND 场景的行为描述需与 reference-code 中同类型功能的行为保持一致
|
|
118
|
+
- 数据模型类 spec 必须包含:建表 SQL 路径(见 openspec/project-profile.md §2)、表名 snake_case、主键与多租户字段(字段名见 openspec/project-profile.md §4)
|
|
119
|
+
|
|
120
|
+
tasks:
|
|
121
|
+
- 宪法优先:遵守 .qoder/rules/project_constitution.md §9 禁止独立编译任务
|
|
122
|
+
- 每个任务必须可独立验证(给出验证命令或证据)
|
|
123
|
+
- 涉及新增类的任务,必须指明参考的 docs/reference-code 文件路径
|
|
124
|
+
- 建表 / SQL 脚本任务统一放到建表 SQL 路径(见 openspec/project-profile.md §2)
|
|
125
|
+
- Mapper XML 统一放到 Mapper XML 路径(见 openspec/project-profile.md §2)
|
|
126
|
+
- 禁止包含独立的编译验证任务(如 mvn clean compile / mvn compile);单任务内的"编译无错误"作为验证证据可保留
|