Commit 659c0d22 by 宋宇航

考试违规

parent 6d117c30
# 开发规范指南
为保证代码质量、可维护性、安全性与可扩展性,请在开发过程中严格遵循以下规范。
## 一、项目基本信息
- **用户工作目录**`D:\codeminiapp\cnooc_zydeepen-cggl_expert-manage-miniapp`
- **项目名称**:Expert Manage MiniApp
- **项目版本**:1.0.0
- **代码作者**:yu123
- **操作系统**:Windows 11
- **当前时间**:2025-11-15 10:58:47
## 二、技术栈要求
- **主框架**:Spring Boot 2.7.18
- **语言版本**:Java 1.8
- **构建工具**:Maven
- **核心依赖**
- `spring-boot-starter-web`
- `spring-boot-starter-data-redis`
- `lombok`
- `spring-kafka`
- `retrofit`
- `fastjson`
- `jjwt`
- `commons-lang3`
- `commons-collections4`
- `guava`
- `spring-security-crypto`
- `hutool-all`
- `commons-codec`
- `bcprov-jdk15to18`
- `spring-boot-starter-validation`
- `easy-captcha`
- `aspectjweaver`
## 三、目录结构说明
```
cnooc_zydeepen-cggl_expert-manage-miniapp
└── src
└── main
├── java
│ └── com
│ └── cnooc
│ ├── expert
│ │ ├── auth
│ │ │ └── service
│ │ │ └── impl
│ │ ├── common
│ │ │ ├── cache
│ │ │ ├── constant
│ │ │ ├── crypto
│ │ │ ├── exception
│ │ │ ├── filter
│ │ │ ├── interceptor
│ │ │ ├── request
│ │ │ ├── response
│ │ │ └── utils
│ │ ├── config
│ │ ├── controller
│ │ │ ├── auth
│ │ │ ├── expert
│ │ │ │ └── model
│ │ │ │ ├── request
│ │ │ │ └── response
│ │ │ ├── portal
│ │ │ │ └── model
│ │ │ │ ├── request
│ │ │ │ └── response
│ │ │ └── workflow
│ │ ├── external
│ │ │ ├── common
│ │ │ ├── expert
│ │ │ │ ├── api
│ │ │ │ ├── auth
│ │ │ │ │ └── service
│ │ │ │ ├── model
│ │ │ │ │ ├── request
│ │ │ │ │ └── response
│ │ │ │ └── service
│ │ │ ├── portal
│ │ │ │ ├── api
│ │ │ │ └── service
│ │ │ └── workflow
│ │ │ ├── api
│ │ │ └── service
│ │ ├── service
│ │ └── system
│ │ ├── entity
│ │ │ ├── pojo
│ │ │ └── vo
│ │ └── operatelog
│ │ ├── aspect
│ │ └── dto
│ └── expertmanageminiapp
│ ├── manage
│ │ └── entity
│ │ ├── dto
│ │ └── vo
│ └── system
│ └── entity
│ └── dto
└── resources
```
## 四、分层架构规范
| 层级 | 职责说明 | 开发约束与注意事项 |
|-------------|----------------------------------|----------------------------------------------------------------|
| **Controller** | 处理 HTTP 请求与响应,定义 API 接口 | 不得直接访问数据库,必须通过 Service 层调用 |
| **Service** | 实现业务逻辑、事务管理与数据校验 | 必须通过 Repository 层访问数据库;返回 DTO 而非 Entity(除非必要) |
| **Repository** | 数据库访问与持久化操作 | 继承 `JpaRepository`;使用 `@EntityGraph` 避免 N+1 查询问题 |
| **Entity** | 映射数据库表结构 | 不得直接返回给前端(需转换为 DTO);包名统一为 `entity` |
### 接口与实现分离
- 所有接口实现类需放在接口所在包下的 `impl` 子包中。
## 五、安全与性能规范
### 输入校验
- 使用 `@Valid` 与 JSR-303 校验注解(如 `@NotBlank`, `@Size` 等)
- 注意:Spring Boot 2.7.x 中校验注解位于 `javax.validation.constraints.*`
- 禁止手动拼接 SQL 字符串,防止 SQL 注入攻击。
### 事务管理
- `@Transactional` 注解仅用于 **Service 层**方法。
- 避免在循环中频繁提交事务,影响性能。
## 六、代码风格规范
### 命名规范
| 类型 | 命名方式 | 示例 |
|------------|----------------------|-----------------------|
| 类名 | UpperCamelCase | `UserServiceImpl` |
| 方法/变量 | lowerCamelCase | `saveUser()` |
| 常量 | UPPER_SNAKE_CASE | `MAX_LOGIN_ATTEMPTS` |
### 注释规范
- 所有类、方法、字段需添加 **Javadoc** 注释。
- 所有注释使用中文(第一语言)。
### 类型命名规范(阿里巴巴风格)
| 后缀 | 用途说明 | 示例 |
|------|------------------------------|--------------|
| DTO | 数据传输对象 | `UserDTO` |
| DO | 数据库实体对象 | `UserDO` |
| BO | 业务逻辑封装对象 | `UserBO` |
| VO | 视图展示对象 | `UserVO` |
| Query| 查询参数封装对象 | `UserQuery` |
### 实体类简化工具
- 使用 Lombok 注解替代手动编写 getter/setter/构造方法:
- `@Data`
- `@NoArgsConstructor`
- `@AllArgsConstructor`
## 七、扩展性与日志规范
### 接口优先原则
- 所有业务逻辑通过接口定义(如 `UserService`),具体实现放在 `impl` 包中(如 `UserServiceImpl`)。
### 日志记录
- 使用 `@Slf4j` 注解代替 `System.out.println`
## 八、编码原则总结
| 原则 | 说明 |
|------------|--------------------------------------------|
| **SOLID** | 高内聚、低耦合,增强可维护性与可扩展性 |
| **DRY** | 避免重复代码,提高复用性 |
| **KISS** | 保持代码简洁易懂 |
| **YAGNI** | 不实现当前不需要的功能 |
| **OWASP** | 防范常见安全漏洞,如 SQL 注入、XSS 等 |
[1111/175928.101:ERROR:directory_reader_win.cc(43)] FindFirstFile +C:\Users\yu123\AppData\Local\Chrome\User Data\Crashpad\attachments: 系统找不到指定的路径。 (0x3)
......@@ -2,19 +2,12 @@ package com.cnooc.expert.controller.expert;
import com.cnooc.expert.common.response.ApiResult;
import com.cnooc.expert.common.response.BasePageResp;
import com.cnooc.expert.controller.expert.model.request.CompanyPageReq;
import com.cnooc.expert.controller.expert.model.request.DictNofilterListReq;
import com.cnooc.expert.controller.expert.model.request.PingBiaoXiangMuInfoGetByChouQuMaReq;
import com.cnooc.expert.controller.expert.model.request.PingBiaoXiangMuPageReq;
import com.cnooc.expert.controller.expert.model.request.QingJiaJinJiPageReq;
import com.cnooc.expert.controller.expert.model.response.DictListItemResp;
import com.cnooc.expert.controller.expert.model.response.ExpertInfoGetResp;
import com.cnooc.expert.controller.expert.model.response.NofilterListItemResp;
import com.cnooc.expert.controller.expert.model.response.PingBiaoXiangMuInfoGetByChouQuMaResp;
import com.cnooc.expert.controller.expert.model.response.SecondaryUnitListItemResp;
import com.cnooc.expert.controller.expert.model.request.*;
import com.cnooc.expert.controller.expert.model.response.*;
import com.cnooc.expert.service.ExpertService;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -22,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
@AllArgsConstructor
......@@ -133,4 +127,109 @@ public class ExpertController {
return ApiResult.successWithResult(expertService.pageJinJiQingJia(req));
}
// *** 违规信息/冻结信息 ***
// 违规信息
/**
* 专家个人违规记录查询
* @param req
* @return
*/
@GetMapping("/wei-gui/ji-lu/page")
public ApiResult<BasePageResp<WeiGuiPageResp>> weiGuiJiLuPage(@RequestBody @Validated WeiGuiJiLuPageReq req) {
return ApiResult.successWithResult(expertService.pageWeiGuiList(req));
}
/**
* 违规事项列表查询
* @return
*/
@GetMapping("wei-gui/shi-xiang-list")
public ApiResult<List<WeiGuiPageResp.WeiGuiShiXiang>> weiGuiShiXiangList() {
return ApiResult.successWithResult(expertService.listWeiGuiShiXiang());
}
/**
* 专家违规处理信息详情查询
* @param req
* @return
*/
@GetMapping("/wei-gui/chu-li-xiang-qing")
public ApiResult<Object> weiGuiChuLiXiangQing(@RequestBody @Validated WeiGuiInfoByZhunaJiaWeiGuiGuidReq req) {
return ApiResult.successWithResult(expertService.weiGuiChuLiXiangQing(req));
}
/**
* 根据专家违规guid查询违规处理原因
* @param req
* @return
*/
@GetMapping("/wei-gui/chu-li-yuan-yin")
public ApiResult<Object> weiGuiChuLiYuanYin(@RequestBody @Validated WeiGuiInfoByZhunaJiaWeiGuiGuidReq req) {
return ApiResult.successWithResult(expertService.weiGuiChuLiYuanYin());
}
/**
* 专家违规(审核)处理记录查询
* @param req
* @return
*/
@GetMapping("/wei-gui/chu-li-ji-lu")
public ApiResult<Object> weiGuiChuLiJiLu(@RequestBody @Validated WeiGuiInfoByZhunaJiaWeiGuiGuidReq req) {
return ApiResult.successWithResult(expertService.listWeiGuiChuLiJiLu());
}
// *** 课程培训 和 课后考试
// 课后考试
/**
* 课后考试列表查询
* @param req
* @return
*/
@PostMapping("/kaoShi/getKaoShiPage")
public ApiResult<BasePageResp<KaoShiPageResp>> getKaoShiPage(@RequestBody @Validated KaoShiPageReq req) {
return ApiResult.successWithResult(expertService.pageKaoShi(req));
}
// 课程培训
/**
* 培训课程列表查询
* @param req
* @return
*/
@PostMapping("/peiXun/getPeiXunPage")
public ApiResult<BasePageResp<PeiXunPageResp>> getPeiXunPage(@RequestBody @Validated PeiXunPageReq req) {
return ApiResult.successWithResult(expertService.pagePeiXunKeCheng(req));
}
/**
* 培训课程详情查询
* @param req
* @return
*/
@PostMapping("/peiXun/getPeiXunInfo")
public ApiResult<Object> getPeiXunInfo(@RequestBody @Validated PeiXunKeChengReq req) {
return ApiResult.successWithResult(expertService.getPeiXunInfo(req));
}
/**
* 课程详情下课节列表
* @param req
* @return
*/
@PostMapping("/peiXun/getPeiXunInfo")
public ApiResult<Object> getPeiXunKeChengKeJieList(@RequestBody @Validated PeiXunKeChengReq req) {
return ApiResult.successWithResult(expertService.getPeiXunKeChengKeJieList(req));
}
}
package com.cnooc.expert.controller.expert.model.request;
import com.cnooc.expert.common.request.BasePageRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author: FuHongZhang
* @date 2025-11-15 13:58
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class KaoShiPageReq extends BasePageRequest {
/**
* 课程名称
*/
private String courseName;
/**
* 课程类型Guid
*/
private String courseTypeGuid;
/**
* 课节名称
*/
private String lessonName;
/**
* 课程发布时间查询开始时间
*/
private Long courseReleaseStartTimestamp;
/**
* 课程发布时间查询结束时间
*/
private Long courseReleaseEndTimestamp;
/**
* 考试状态
*/
private Short examStatus;
/**
* 专家Guid todo 可能不需要传,需要从后端获取当前登录人guid
*/
private String expertGuid;
/**
* 课程类型名称
*/
private String courseTypeName;
/**
* 排除的课程类型列表 (续期培训,续期考试) 需要了解下业务,小程序端专家申请续期需要进行培训及考试吗
*/
private List<String> excludeCourseTypeList;
}
package com.cnooc.expert.controller.expert.model.request;
import lombok.Data;
/**
* @author: FuHongZhang
* @date 2025-11-15 14:46
*/
@Data
public class PeiXunKeChengReq {
/**
* 课程Guid
*/
private String courseGuid;
// -------查询课程详情下课节信息入参----------
private String userId; // 从服务上获取
// 必传
// private String courseGuid;
}
package com.cnooc.expert.controller.expert.model.request;
import com.cnooc.expert.common.request.BasePageRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author: FuHongZhang
* @date 2025-11-15 14:25
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PeiXunPageReq extends BasePageRequest {
/**
* courseName 课程名称
*/
private String courseName;
/**
* courseTypeGuid 课程类型Guid
*/
private String courseTypeGuid;
/**
* courseTypeName 课程类型名称
*/
private String courseTypeName;
/**
* courseReleaseStartTimestamp 课程发布时间查询开始时间
*/
private Long courseReleaseStartTimestamp;
/**
* courseReleaseEndTimestamp 课程发布时间查询结束时间
*/
private Long courseReleaseEndTimestamp;
/**
* 学习进度状态(10:未完成;20:已完成)
*/
private Short progressStatus;
/**
* 当前用户guid
*/
private String userGuid;
/**
* 当前用户guid
*/
private String expertGuid;
/**
* 二开 - 排除的课程类型列表 (续期考试,续期培训)
*/
private List<String> excludeCourseTypeList;
}
package com.cnooc.expert.controller.expert.model.request;
import lombok.Data;
/**
* @author: FuHongZhang
* @date 2025-11-15 11:23
*/
@Data
public class WeiGuiInfoByZhunaJiaWeiGuiGuidReq {
// 专家违规的guid
private String guid;
// 专家违规的guids weiguiReason
private String guids;
// 专家违规guid
private String zhuanJiaWeiGuiGuid;
}
package com.cnooc.expert.controller.expert.model.request;
import com.cnooc.expert.common.request.BasePageRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author: FuHongZhang
* @date 2025-11-14 17:39
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class WeiGuiJiLuPageReq extends BasePageRequest {
private String zhuanJiaGuid;
}
package com.cnooc.expert.controller.expert.model.response;
import lombok.Builder;
import lombok.Data;
/**
* @author: FuHongZhang
* @date 2025-11-15 13:59
*/
@Data
@Builder
public class KaoShiPageResp {
private String courseGuid;
private String courseName;
private Long courseReleaseTimestamp;
private String courseTypeName;
private Object examPassTimestamp;
private Integer examResult;
private Double jiGeScore;
private String lessonGuid;
private String lessonName;
private Double score;
private Object studyProgress;
private String testPaperGuid;
private Object zuiGaoScore;
}
package com.cnooc.expert.controller.expert.model.response;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author: FuHongZhang
* @date 2025-11-15 14:26
*/
@Data
@Builder
public class PeiXunPageResp {
/**
* courseGuid 课程Guid
*/
private String courseGuid;
/**
* courseName 课程名称
*/
private String courseName;
/**
* courseTypeName 课程类型名称
*/
private String courseTypeName;
/**
* lessonCount 课节数量
*/
private Integer lessonCount;
/**
* courseReleaseTimestamp 发布时间
*/
private Long courseReleaseTimestamp;
/**
* 学习进度
*/
private BigDecimal studyProgress;
/**
* 学习进度状态(10:未完成;20:已完成)
*/
private Short progressStatus;
/**
* 培训课程详情
*/
@Data
@Builder
public static class PeiXunKeChengInfo {
/** 课程唯一标识(GUID) */
private String courseGuid;
/** 课程介绍 */
private String courseIntroduction;
/** 课程名称 */
private String courseName;
/** 课程发布状态() */
private Short courseReleaseStatus;
/** 课程发布时间戳(毫秒) */
private Long courseReleaseTimestamp;
/** 课程类型唯一标识(GUID) */
private String courseTypeGuid;
/** 课程类型名称(如:日常培训、定期培训) */
private String courseTypeName;
/** 学习后是否需要考试(true=是,false=否) */
private Boolean isTestAfterLearn;
/** 课程包含的课节数量 */
private Integer lessonCount;
/** 关联的试卷唯一标识(GUID) */
private String testPaperGuid;
}
}
package com.cnooc.expert.controller.expert.model.response;
import lombok.Builder;
import lombok.Data;
import java.util.List;
/**
* @author: FuHongZhang
* @date 2025-11-14 20:28
*/
@Data
@Builder
public class WeiGuiPageResp {
private String bidSectionCode;
private String bidSectionName;
private String businessId;
private String chouquRenwuGuid;
private Long chuliEndTime;
private String chuliPeriod;
private Long chuliStartTime;
private String fujianGuid;
private Object serialNum;
private String shenFenZheng;
private Integer shenheStatus;
private String shenheStatusName;
private Long submitTime;
private String submitTimeStr;
private String submiter;
private Integer weiguiChuliShichang;
private String weiguiChuliShichangStr;
private String weiguiReason;
private String weiguiReasonName;
private String weiguiXiangxiMiaoshu;
private String zhuanJiaAdAccount;
private String zhuanJiaCode;
private Object zhuanJiaZhuangTai;
private String zhuanJiaZhuangTaiName;
private String zhuanjiaGuid;
private String zhuanjiaName;
private String zhuanjiaWeiguiGuid;
@Data
@Builder
public static class WeiGuiShiXiang {
private Long createTime;
private String creatorGuid;
private String creatorName;
private Boolean isDeleted;
private String modifierGuid;
private String modifierName;
private Long modifyTime;
private Integer qiYongstatus;
private String weiguiChuliReason;
private String weiguiChuliShichangs;
private String weiguiShixiangGuid;
}
@Data
@Builder
public static class WeiGuiChuLiXiangQingResp {
private String applyBusinessId;
private Integer applyshenheStatus;
private String businessId;
private String chouquRenwuGuid;
private Long chuliEndTime;
private Long chuliStartTime;
private Long createTime;
private String creatorGuid;
private String creatorName;
private String fujianGuid;
private Boolean isDeleted;
private String modifierGuid;
private String modifierName;
private Long modifyTime;
private String shenheRen;
private Integer shenheStatus;
private Long shenheTime;
private Long submitTime;
private String submiter;
private String submiterGuid;
private Long submiterPersonId;
private String tijiaorenEmail;
private String tijiaorenPhone;
private Integer weiguiChuliShichang;
private String weiguiReason;
private String weiguiReasonName;
private String weiguiXiangxiMiaoshu;
private String zhuanJiaAdAccount;
private String zhuanJiaCode;
private List<ZhuanJiaItem> zhuanJiaList;
private Object zhuanJiaZhuangTai;
private String zhuanjiaGuid;
private String zhuanjiaName;
private String zhuanjiaWeiguiGuid;
}
@Data
@Builder
public static class ZhuanJiaItem {
private String chouQuQingKuangGuid;
private String chouQuRenWuGuid;
private Object pingShenType;
private String zhuanJiaAdAccount;
private String zhuanJiaCode;
private String zhuanJiaGuid;
private String zhuanJiaName;
private Integer zhuanJiaZhuangTai;
}
@Data
@Builder
public static class WeiGuiChuLiYuanYin {
private Long createTime;
private String creatorGuid;
private String creatorName;
private Boolean isDeleted;
private String modifierGuid;
private String modifierName;
private Long modifyTime;
private Integer qiYongstatus;
private String weiguiChuliReason;
private String weiguiChuliShichangs;
private String weiguiShixiangGuid;
}
@Data
@Builder
public static class WeiGuiShenHeChuliJiLu {
private Object bianGengXuHao;
private String buTongGuoEndSequence;
private Object buTongGuoStartSequence;
private Long createTime;
private String createTimeText;
private String creatorGuid;
private String creatorName;
private String daiShenRenGuids;
private String daiShenRenNames;
private String fujianGuid;
private Boolean isCurrent;
private Boolean isDeleted;
private Boolean isFinish;
private String modifierGuid;
private String modifierName;
private Object modifyTime;
private String modifyTimeText;
private String remark;
private Object sequence;
private String shenHeBuMenGuid;
private String shenHeBuMenName;
private String shenHeFuJianGuid;
private String shenHeGuid;
private String shenHeRenGuid;
private String shenHeRenName;
private Integer shenHeStatus;
private Long shenHeTime;
private String shenHeTimeText;
private String shenHeYiJian;
private String shenPiJieGuoGuid;
private Object shenQingLeiXing;
private Boolean shiFouYiFaZhuanJia;
private Boolean shiFouZhuanJiao;
private String shiXiangGuid;
private String shiXiangName;
private Object shiXiangType;
private Object shouLiTime;
private String shouLiTimeText;
private String tiJiaoRenGuid;
private String tiJiaoRenName;
private Long tiJiaoTime;
private String tiJiaoTimeText;
private String xiaJiShenHeRenGuid;
private String xiaJiShenHeRenName;
private String xiangMuGuid;
private Boolean zhiJieHuiFu;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment