Compare commits
11 Commits
cd0aace6dc
...
7bc6b9f2a8
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bc6b9f2a8 | |||
|
|
495ce97ce7 | ||
|
|
1a33d1cef2 | ||
|
|
067dbdd58c | ||
|
|
f683e7caa7 | ||
|
|
bb9c4d9abb | ||
|
|
6e14a9683b | ||
|
|
814058eea7 | ||
|
|
9010154067 | ||
|
|
92ad9f88a0 | ||
|
|
3e863506aa |
@ -109,6 +109,10 @@
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.seer.teach.common.config;
|
||||
package com.seer.teach.admin.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ -58,5 +58,10 @@
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -25,5 +25,9 @@
|
||||
<artifactId>common-validation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,36 @@
|
||||
package com.seer.teach.common.enums.teacher;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ReportTypeEnum {
|
||||
|
||||
DAILY(0, "今天"),
|
||||
WEEKLY(1, "本周"),
|
||||
MONTHLY(2, "本月");
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String desc;
|
||||
|
||||
@JsonCreator
|
||||
public static ReportTypeEnum fromType(Integer type) {
|
||||
for (ReportTypeEnum e : values()) {
|
||||
if (e.type.equals(type)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("非法报告类型type:" + type);
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.seer.teach.common.utils;
|
||||
|
||||
import com.seer.teach.common.enums.teacher.ReportTypeEnum;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@ -29,6 +31,7 @@ public class DateUtils {
|
||||
|
||||
/**
|
||||
* 根据创建时间计算距离当前时间相差多少天
|
||||
*
|
||||
* @param createTime 创建时间(LocalDateTime)
|
||||
* @return 相差的天数,例如:5
|
||||
*/
|
||||
@ -43,46 +46,54 @@ public class DateUtils {
|
||||
|
||||
|
||||
/**
|
||||
* Ai报告获取开始时间
|
||||
* @param type 1-本周,2-本天
|
||||
* @return 开始时间
|
||||
* 获取开始时间
|
||||
*
|
||||
* @param type 类型
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime getStartTime(Integer type) {
|
||||
if (type == 1) {
|
||||
// 本天
|
||||
public static LocalDateTime getStartTime(ReportTypeEnum type) {
|
||||
if (type.getType().equals(0)) {
|
||||
// 今天
|
||||
return LocalDate.now().atStartOfDay();
|
||||
} else if(type == 0){
|
||||
} else if (type.getType().equals(1)) {
|
||||
// 本周
|
||||
return LocalDate.now().with(DayOfWeek.MONDAY).atStartOfDay();
|
||||
} else if (type.getType().equals(2)) {
|
||||
// 本月
|
||||
return LocalDate.now().withDayOfMonth(1).atStartOfDay();
|
||||
} else {
|
||||
throw new IllegalArgumentException("type只能为0或1");
|
||||
throw new IllegalArgumentException("type只能为0、1或2");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将秒数转换为小时或者天
|
||||
*
|
||||
* @param seconds 秒数
|
||||
* @param type 1-本周,2-本天
|
||||
* @param type 0-今天,1-本周,2-本月
|
||||
* @return 时间字符串
|
||||
*/
|
||||
public static String formatSecondsToHourMinute(Integer seconds, Integer type) {
|
||||
if (type == 1) {
|
||||
// 本天转换为小时
|
||||
int hours = seconds / 3600;
|
||||
return hours + "小时";
|
||||
} else if (type == 0){
|
||||
// 本周转换为天
|
||||
public static String formatSecondsToHourMinute(Integer seconds, ReportTypeEnum type) {
|
||||
if (type.getType().equals(0)) {
|
||||
// 今天转换为小时和分钟
|
||||
return formatSecondsToHourAndMinute(seconds);
|
||||
} else if (type.getType().equals(1) || type.getType().equals(2)) {
|
||||
// 本周和本月转换为天
|
||||
int days = seconds / 86400;
|
||||
return days + "天";
|
||||
} else {
|
||||
throw new IllegalArgumentException("type只能为0或1");
|
||||
throw new IllegalArgumentException("type只能为0、1或2");
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatSecondsToHourAndMinute(Integer seconds) {
|
||||
int hours = seconds / 3600;
|
||||
int minutes = (seconds % 3600) / 60;
|
||||
return hours + "小时" + minutes + "分";
|
||||
if (hours > 0) {
|
||||
return hours + "小时" + minutes + "分钟";
|
||||
} else {
|
||||
return minutes + "分钟";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -287,7 +287,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis</artifactId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ public class LoadBalancerConfig {
|
||||
String ip = Optional.ofNullable(exchange.getRequest().getRemoteAddress())
|
||||
.map(addr -> addr.getAddress().getHostAddress())
|
||||
.orElse("unknown");
|
||||
log.info("请求来自客户端: {}", ip);
|
||||
log.info("ipForwardFilter 请求来自客户端: {}", ip);
|
||||
ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
|
||||
.header("X-Forwarded-For", ip)
|
||||
.build();
|
||||
|
||||
@ -16,7 +16,7 @@ import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
// @Component
|
||||
public class CorsFilter implements WebFilter {
|
||||
|
||||
private static final String MAX_AGE = String.valueOf(1000 * 60 * 60 * 24);
|
||||
|
||||
@ -19,7 +19,7 @@ import java.time.LocalDateTime;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("mp_activities")
|
||||
@TableName("mp_activity")
|
||||
@Schema(name = "MpAgentActivityEntity对象", description = "活动表")
|
||||
public class MpActivityEntity extends BaseEntity {
|
||||
|
||||
@ -47,6 +47,8 @@ public class MpActivityEntity extends BaseEntity {
|
||||
@TableField("end_time")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 活动状态:0-禁用,1-启用
|
||||
*/
|
||||
|
||||
@ -17,7 +17,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("mp_agent_activity_participants")
|
||||
@TableName("mp_agent_activity_participant")
|
||||
@Schema(name = "MpAgentActivityParticipantEntity对象", description = "代理商活动参与记录表")
|
||||
public class MpAgentActivityParticipantEntity extends BaseEntity {
|
||||
|
||||
@ -28,8 +28,26 @@ public class MpAgentActivityParticipantEntity extends BaseEntity {
|
||||
private Integer activityId;
|
||||
|
||||
/**
|
||||
* 代理商ID(对应user表的ID)
|
||||
* 代理商ID
|
||||
*/
|
||||
@TableField("agent_id")
|
||||
private Integer agentId;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
@TableField("activity_name")
|
||||
private String activityName;
|
||||
|
||||
/**
|
||||
* 代理商名称
|
||||
*/
|
||||
@TableField("agent_name")
|
||||
private String agentName;
|
||||
|
||||
/**
|
||||
* 活动二维码 url
|
||||
*/
|
||||
@TableField("qr_code_url")
|
||||
private String qrCodeUrl;
|
||||
}
|
||||
@ -17,7 +17,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("mp_agent_employee_relations")
|
||||
@TableName("mp_agent_employee_relation")
|
||||
@Schema(name = "MpAgentEmployeeRelationEntity对象", description = "代理商员工关联表")
|
||||
public class MpAgentEmployeeRelationEntity extends BaseEntity {
|
||||
|
||||
@ -33,6 +33,13 @@ public class MpAgentEmployeeRelationEntity extends BaseEntity {
|
||||
@TableField("employee_user_id")
|
||||
private Integer employeeUserId;
|
||||
|
||||
|
||||
@TableField("agent_name")
|
||||
private String agentName;
|
||||
|
||||
@TableField("employee_name")
|
||||
private String employeeName;
|
||||
|
||||
/**
|
||||
* 员工职位
|
||||
*/
|
||||
|
||||
@ -8,7 +8,7 @@ import lombok.Data;
|
||||
* 代理商实体类
|
||||
*/
|
||||
@Data
|
||||
@TableName("mp_agents")
|
||||
@TableName("mp_agent")
|
||||
public class MpAgentEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
|
||||
@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -30,9 +31,9 @@ public class AdminActivityController {
|
||||
private final IAdminActivityService agentActivityService;
|
||||
|
||||
@Operation(summary = "活动列表")
|
||||
@GetMapping("/page-list")
|
||||
@PostMapping("/page-list")
|
||||
@SaCheckPermission("mp:admin:agent:activity:list")
|
||||
public ResultBean<PageListBean<AdminActivityResp>> pageList(MpActivityQueryReq query) {
|
||||
public ResultBean<PageListBean<AdminActivityResp>> pageList(@RequestBody @Validated MpActivityQueryReq query) {
|
||||
return ResultBean.success(agentActivityService.pageList(query));
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.seer.teach.mp.admin.service.IAdminAgentActivityLogService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -24,9 +25,9 @@ public class AdminAgentActivityLogController {
|
||||
private final IAdminAgentActivityLogService adminAgentActivityLogService;
|
||||
|
||||
@Operation(summary = "代理商活动操作日志列表")
|
||||
@GetMapping("/page-list")
|
||||
@PostMapping("/page-list")
|
||||
@SaCheckPermission("mp:admin:agent:activity:log:list")
|
||||
public ResultBean<PageListBean<AdminAgentActivityLogResp>> pageList(AgentActivityLogQueryReq query) {
|
||||
public ResultBean<PageListBean<AdminAgentActivityLogResp>> pageList(@RequestBody @Validated AgentActivityLogQueryReq query) {
|
||||
return ResultBean.success(adminAgentActivityLogService.pageList(query));
|
||||
}
|
||||
|
||||
|
||||
@ -5,20 +5,17 @@ import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminAgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.admin.service.IAdminAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -31,6 +28,10 @@ public class AdminAgentActivityParticipantController {
|
||||
|
||||
private final IAdminAgentActivityParticipantService adminAgentActivityParticipantService;
|
||||
|
||||
private final IMpAgentService mpAgentService;
|
||||
|
||||
private final IMpActivityService mpActivityService;
|
||||
|
||||
@Operation(summary = "代理商活动参与记录列表")
|
||||
@GetMapping("/page-list")
|
||||
@SaCheckPermission("mp:admin:agent:activity:participant:list")
|
||||
@ -48,8 +49,8 @@ public class AdminAgentActivityParticipantController {
|
||||
@Operation(summary = "新增")
|
||||
@PostMapping
|
||||
@SaCheckPermission("mp:admin:agent:activity:participant:save")
|
||||
public ResultBean<Boolean> save(@RequestBody MpAgentActivityParticipantEntity participantEntity) {
|
||||
return ResultBean.success(adminAgentActivityParticipantService.saveParticipant(participantEntity));
|
||||
public ResultBean<Boolean> save(@RequestBody @Validated AgentActivityParticipantReq req) {
|
||||
return ResultBean.success(adminAgentActivityParticipantService.saveParticipant(req));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新")
|
||||
@ -63,10 +64,19 @@ public class AdminAgentActivityParticipantController {
|
||||
@DeleteMapping
|
||||
@SaCheckPermission("mp:admin:agent:activity:participant:delete")
|
||||
public ResultBean<Boolean> delete(@RequestBody List<Integer> ids) {
|
||||
boolean result = true;
|
||||
for (Integer id : ids) {
|
||||
result &= adminAgentActivityParticipantService.deleteParticipant(id);
|
||||
return ResultBean.success(adminAgentActivityParticipantService.deleteById(ids));
|
||||
}
|
||||
return ResultBean.success(result);
|
||||
|
||||
|
||||
@Operation(summary = "查询代理商名称")
|
||||
@GetMapping("/agent-name")
|
||||
public ResultBean<List<String>> getAgentName() {
|
||||
return ResultBean.success(mpAgentService.getAgentName());
|
||||
}
|
||||
|
||||
@Operation(summary = "查询活动名称")
|
||||
@GetMapping("/activity-name")
|
||||
public ResultBean<List<String>> getActivityName() {
|
||||
return ResultBean.success(mpActivityService.getActivityName());
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ import com.seer.teach.mp.entity.MpAgentEntity;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -25,9 +26,9 @@ public class AdminAgentController {
|
||||
private final AdminAgentService adminAgentService;
|
||||
|
||||
@Operation(summary = "代理商列表")
|
||||
@GetMapping("/page-list")
|
||||
@PostMapping("/page-list")
|
||||
@SaCheckPermission("mp:admin:agent:list")
|
||||
public ResultBean<PageListBean<AgentResp>> pageList(AgentQueryReq query) {
|
||||
public ResultBean<PageListBean<AgentResp>> pageList(@RequestBody @Validated AgentQueryReq query) {
|
||||
return ResultBean.success(adminAgentService.pageList(query));
|
||||
}
|
||||
|
||||
|
||||
@ -6,19 +6,14 @@ import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeSaveReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AgentEmployeeRelationResp;
|
||||
import com.seer.teach.mp.admin.service.IAdminAgentEmployeeRelationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
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 org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@LogPrint
|
||||
@RequiredArgsConstructor
|
||||
@ -30,16 +25,23 @@ public class AdminAgentEmployeeRelationController {
|
||||
private final IAdminAgentEmployeeRelationService agentEmployeeRelationService;
|
||||
|
||||
@Operation(summary = "代理商员工关联列表")
|
||||
@GetMapping("/page-list")
|
||||
@PostMapping("/page-list")
|
||||
@SaCheckPermission("mp:admin:agent:employee:list")
|
||||
public ResultBean<PageListBean<AgentEmployeeRelationResp>> pageList(AgentEmployeeRelationQueryReq query) {
|
||||
public ResultBean<PageListBean<AgentEmployeeRelationResp>> pageList(@RequestBody @Validated AgentEmployeeRelationQueryReq query) {
|
||||
return ResultBean.success(agentEmployeeRelationService.pageList(query));
|
||||
}
|
||||
|
||||
@Operation(summary = "创建或更新代理商员工关联")
|
||||
@Operation(summary = "新增代理商员工关联")
|
||||
@PostMapping("/save")
|
||||
@SaCheckPermission("mp:admin:agent:employee:save")
|
||||
public ResultBean<Boolean> save(@Valid @RequestBody AgentEmployeeRelationReq request) {
|
||||
public ResultBean<Boolean> save(@RequestBody @Validated AgentEmployeeSaveReq request) {
|
||||
return ResultBean.success(agentEmployeeRelationService.save(request));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新代理商员工关联")
|
||||
@PostMapping("/update")
|
||||
@SaCheckPermission("mp:admin:agent:employee:update")
|
||||
public ResultBean<Boolean> update(@RequestBody @Validated AgentEmployeeRelationReq request) {
|
||||
return ResultBean.success(agentEmployeeRelationService.saveOrUpdateRelation(request));
|
||||
}
|
||||
|
||||
|
||||
@ -22,12 +22,9 @@ public class AgentActivityParticipantQueryReq {
|
||||
@Schema(description = "每页数量")
|
||||
private Integer pageSize = 10;
|
||||
|
||||
@Schema(description = "活动ID")
|
||||
private Integer activityId;
|
||||
@Schema(description = "活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "代理商ID")
|
||||
private Integer agentId;
|
||||
|
||||
@Schema(description = "家长ID")
|
||||
private Integer parentId;
|
||||
@Schema(description = "代理商名称")
|
||||
private String agentName;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.seer.teach.mp.admin.controller.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "代理商活动参与请求对象")
|
||||
public class AgentActivityParticipantReq {
|
||||
|
||||
@Schema(description = "代理商名称")
|
||||
@NotBlank(message = "代理商名称不能为空")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "活动名称")
|
||||
@NotBlank(message = "活动名称不能为空")
|
||||
private String activityName;
|
||||
}
|
||||
@ -8,11 +8,11 @@ import lombok.Data;
|
||||
@Data
|
||||
public class AgentEmployeeRelationQueryReq extends PageRequest {
|
||||
|
||||
@Schema(description = "代理商ID")
|
||||
private Integer agentId;
|
||||
@Schema(description = "代理商名称")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "员工用户ID")
|
||||
private Integer employeeUserId;
|
||||
@Schema(description = "员工名称")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "员工状态:0-禁用,1-启用")
|
||||
private Integer status;
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package com.seer.teach.mp.admin.controller.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "AgentEmployeeSaveReq", description = "新增代理商员工请求参数")
|
||||
public class AgentEmployeeSaveReq {
|
||||
|
||||
|
||||
@Schema(description = "代理商名称")
|
||||
@NotNull(message = "代理商名称不能为空")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "员工名称")
|
||||
@NotNull(message = "员工名称不能为空")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "员工职位")
|
||||
private String position;
|
||||
|
||||
@Schema(description = "员工状态:0-禁用,1-启用")
|
||||
private Integer status = 1;
|
||||
}
|
||||
@ -25,6 +25,12 @@ public class AdminAgentActivityParticipantResp {
|
||||
@Schema(description = "代理商ID")
|
||||
private Integer agentId;
|
||||
|
||||
@Schema(description = "代理商名称")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ -14,9 +14,15 @@ public class AgentEmployeeRelationResp {
|
||||
@Schema(description = "代理商ID")
|
||||
private Integer agentId;
|
||||
|
||||
@Schema(description = "代理商名称")
|
||||
private String agentName;
|
||||
|
||||
@Schema(description = "员工用户ID")
|
||||
private Integer employeeUserId;
|
||||
|
||||
@Schema(description = "员工名称")
|
||||
private String employeeName;
|
||||
|
||||
@Schema(description = "员工职位")
|
||||
private String position;
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.seer.teach.mp.admin.convert;
|
||||
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminAgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import org.mapstruct.Mapper;
|
||||
@ -15,4 +16,7 @@ public interface AdminAgentActivityParticipantConvert {
|
||||
AdminAgentActivityParticipantResp convertToResp(MpAgentActivityParticipantEntity entity);
|
||||
|
||||
List<AdminAgentActivityParticipantResp> convertToRespList(List<MpAgentActivityParticipantEntity> entity);
|
||||
|
||||
|
||||
MpAgentActivityParticipantEntity convertToEntity(AgentActivityParticipantReq entity);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.seer.teach.mp.admin.convert;
|
||||
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeSaveReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AgentEmployeeRelationResp;
|
||||
import com.seer.teach.mp.entity.MpAgentEmployeeRelationEntity;
|
||||
import org.mapstruct.Mapper;
|
||||
@ -21,4 +22,6 @@ public interface AdminAgentEmployeeRelationConvert {
|
||||
AgentEmployeeRelationResp convertToResp(MpAgentEmployeeRelationEntity entity);
|
||||
|
||||
List<AgentEmployeeRelationResp> convertToRespList(List<MpAgentEmployeeRelationEntity> mpAgentEmployeeRelationEntities);
|
||||
|
||||
MpAgentEmployeeRelationEntity convert(AgentEmployeeSaveReq request);
|
||||
}
|
||||
@ -36,7 +36,10 @@ public class AdminAgentService {
|
||||
MpAgentEntity query = AgentConvert.INSTANCE.convertOne(pageReq);
|
||||
IPage<MpAgentEntity> resultPage = mpAgentService.page(pageParam, new LambdaQueryWrapper<>(MpAgentEntity.class)
|
||||
.like(StringUtils.isNotBlank(query.getAgentName()), MpAgentEntity::getAgentName, query.getAgentName())
|
||||
.eq(query.getStatus() != null, MpAgentEntity::getStatus, query.getStatus())
|
||||
.like(StringUtils.isNotBlank(query.getContactName()), MpAgentEntity::getContactName, query.getContactName())
|
||||
.like(StringUtils.isNotBlank(query.getAgentCode()), MpAgentEntity::getAgentCode, query.getAgentCode())
|
||||
.like(StringUtils.isNotBlank(query.getAgentLevel()), MpAgentEntity::getAgentLevel, query.getAgentLevel())
|
||||
.like(StringUtils.isNotBlank(query.getContactPhone()), MpAgentEntity::getContactPhone, query.getContactPhone()));
|
||||
|
||||
return PageConverterUtils.convertPageListBean(resultPage, AgentConvert.INSTANCE::convertRespList);
|
||||
@ -84,13 +87,13 @@ public class AdminAgentService {
|
||||
* @return 是否成功
|
||||
*/
|
||||
public Boolean deleteById(List<Integer> ids) {
|
||||
if(ids == null || ids.isEmpty()){
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
log.warn("删除代理商时,ID列表为空");
|
||||
return false;
|
||||
}
|
||||
boolean result = mpAgentService.removeByIds(ids);
|
||||
log.info("删除代理商结果: {}", result);
|
||||
if(result){
|
||||
if (result) {
|
||||
log.info("删除代理商成功,ID列表: {}", ids);
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -2,9 +2,12 @@ package com.seer.teach.mp.admin.service;
|
||||
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminAgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 代理商活动参与记录表 管理端服务类
|
||||
@ -29,7 +32,7 @@ public interface IAdminAgentActivityParticipantService {
|
||||
* @param entity 参与记录实体
|
||||
* @return 操作是否成功
|
||||
*/
|
||||
boolean saveParticipant(MpAgentActivityParticipantEntity entity);
|
||||
boolean saveParticipant(AgentActivityParticipantReq entity);
|
||||
|
||||
/**
|
||||
* 更新代理商活动参与记录(管理端)
|
||||
@ -39,14 +42,6 @@ public interface IAdminAgentActivityParticipantService {
|
||||
*/
|
||||
boolean updateParticipant(MpAgentActivityParticipantEntity entity);
|
||||
|
||||
/**
|
||||
* 根据ID删除代理商活动参与记录(管理端)
|
||||
*
|
||||
* @param id 参与记录ID
|
||||
* @return 操作是否成功
|
||||
*/
|
||||
boolean deleteParticipant(Integer id);
|
||||
|
||||
/**
|
||||
* 根据ID获取代理商活动参与记录详情(管理端)
|
||||
*
|
||||
@ -54,4 +49,12 @@ public interface IAdminAgentActivityParticipantService {
|
||||
* @return 参与记录详情
|
||||
*/
|
||||
AdminAgentActivityParticipantResp getById(Integer id);
|
||||
|
||||
/**
|
||||
* 根据ID删除代理商活动参与记录(管理端)
|
||||
*
|
||||
* @param ids 参与记录ID
|
||||
* @return 操作是否成功
|
||||
*/
|
||||
Boolean deleteById(List<Integer> ids);
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.seer.teach.mp.admin.service;
|
||||
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeSaveReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AgentEmployeeRelationResp;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationReq;
|
||||
@ -56,4 +57,11 @@ public interface IAdminAgentEmployeeRelationService {
|
||||
* @return 员工关联列表
|
||||
*/
|
||||
List<AgentEmployeeRelationResp> getEmployeeRelationsByAgentId(Integer agentId);
|
||||
|
||||
/**
|
||||
* 新增代理商员工关联(管理端)
|
||||
* @param request 新增代理商员工关联请求对象
|
||||
* @return 新增是否成功
|
||||
*/
|
||||
boolean save(AgentEmployeeSaveReq request);
|
||||
}
|
||||
@ -13,8 +13,6 @@ import com.seer.teach.mp.service.IMpAgentActivityLogService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 代理商活动操作日志表 管理端服务实现类
|
||||
@ -32,31 +30,13 @@ public class AdminAgentActivityLogServiceImpl implements IAdminAgentActivityLogS
|
||||
@Override
|
||||
public PageListBean<AdminAgentActivityLogResp> pageList(AgentActivityLogQueryReq query) {
|
||||
Page<MpAgentActivityLogEntity> page = new Page<>(query.getPageNum(), query.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<MpAgentActivityLogEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 根据活动ID查询
|
||||
if (query.getActivityId() != null) {
|
||||
wrapper.eq(MpAgentActivityLogEntity::getActivityId, query.getActivityId());
|
||||
}
|
||||
|
||||
// 根据操作人ID查询
|
||||
if (query.getOperatorId() != null) {
|
||||
wrapper.eq(MpAgentActivityLogEntity::getOperatorId, query.getOperatorId());
|
||||
}
|
||||
|
||||
// 根据操作类型查询
|
||||
if (query.getOperationType() != null && !query.getOperationType().isEmpty()) {
|
||||
wrapper.eq(MpAgentActivityLogEntity::getOperationType, query.getOperationType());
|
||||
}
|
||||
|
||||
// 根据创建时间范围查询
|
||||
if (query.getStartTime() != null) {
|
||||
wrapper.ge(MpAgentActivityLogEntity::getCreateTime, query.getStartTime());
|
||||
}
|
||||
if (query.getEndTime() != null) {
|
||||
wrapper.le(MpAgentActivityLogEntity::getCreateTime, query.getEndTime());
|
||||
}
|
||||
wrapper.eq(query.getActivityId() != null, MpAgentActivityLogEntity::getActivityId, query.getActivityId())
|
||||
.eq(query.getOperatorId() != null, MpAgentActivityLogEntity::getOperatorId, query.getOperatorId())
|
||||
.eq(query.getOperationType() != null, MpAgentActivityLogEntity::getOperationType, query.getOperationType())
|
||||
.ge(query.getStartTime() != null, MpAgentActivityLogEntity::getCreateTime, query.getStartTime())
|
||||
.le(query.getEndTime() != null, MpAgentActivityLogEntity::getCreateTime, query.getEndTime())
|
||||
.orderByDesc(MpAgentActivityLogEntity::getUpdateTime);
|
||||
|
||||
IPage<MpAgentActivityLogEntity> result = mpAgentActivityLogService.page(page, wrapper);
|
||||
|
||||
|
||||
@ -1,19 +1,25 @@
|
||||
package com.seer.teach.mp.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentActivityParticipantReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminAgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.admin.convert.AdminAgentActivityParticipantConvert;
|
||||
import com.seer.teach.mp.admin.service.IAdminAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 代理商活动参与记录表 管理端服务实现类
|
||||
@ -28,66 +34,78 @@ public class AdminAgentActivityParticipantServiceImpl implements IAdminAgentActi
|
||||
|
||||
private final IMpAgentActivityParticipantService mpAgentActivityParticipantService;
|
||||
|
||||
private final IMpAgentService mpAgentService;
|
||||
|
||||
private final IMpActivityService mpActivityService;
|
||||
|
||||
@Override
|
||||
public PageListBean<AdminAgentActivityParticipantResp> pageList(AgentActivityParticipantQueryReq query) {
|
||||
Page<MpAgentActivityParticipantEntity> page = new Page<>(query.getPageNum(), query.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<MpAgentActivityParticipantEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 根据活动ID查询
|
||||
if (query.getActivityId() != null) {
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getActivityId, query.getActivityId());
|
||||
if (query.getActivityName() != null) {
|
||||
wrapper.like(MpAgentActivityParticipantEntity::getActivityName, query.getActivityName());
|
||||
}
|
||||
|
||||
// 根据代理商ID查询
|
||||
if (query.getAgentId() != null) {
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getAgentId, query.getAgentId());
|
||||
if (query.getAgentName() != null) {
|
||||
wrapper.like(MpAgentActivityParticipantEntity::getAgentName, query.getAgentName());
|
||||
}
|
||||
IPage<MpAgentActivityParticipantEntity> result = mpAgentActivityParticipantService.page(page, wrapper);
|
||||
|
||||
Page<MpAgentActivityParticipantEntity> result = mpAgentActivityParticipantService.page(page, wrapper);
|
||||
return PageConverterUtils.convertPageListBean(result, AdminAgentActivityParticipantConvert.INSTANCE::convertToRespList);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean saveParticipant(MpAgentActivityParticipantEntity entity) {
|
||||
public boolean saveParticipant(AgentActivityParticipantReq entity) {
|
||||
// 检查是否已存在相同的活动、代理商和家长记录
|
||||
LambdaQueryWrapper<MpAgentActivityParticipantEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getActivityId, entity.getActivityId())
|
||||
.eq(MpAgentActivityParticipantEntity::getAgentId, entity.getAgentId());
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getActivityName, entity.getActivityName())
|
||||
.eq(MpAgentActivityParticipantEntity::getAgentName, entity.getAgentName());
|
||||
|
||||
long count = mpAgentActivityParticipantService.count(wrapper);
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("该代理商活动参与记录已存在");
|
||||
}
|
||||
|
||||
return mpAgentActivityParticipantService.save(entity);
|
||||
Integer agentId = mpAgentService.lambdaQuery().eq(MpAgentEntity::getAgentName, entity.getAgentName()).one().getId();
|
||||
Integer activityId = mpActivityService.lambdaQuery().eq(MpActivityEntity::getActivityName, entity.getActivityName()).one().getId();
|
||||
MpAgentActivityParticipantEntity result = AdminAgentActivityParticipantConvert.INSTANCE.convertToEntity(entity);
|
||||
result.setActivityId(activityId);
|
||||
result.setAgentId(agentId);
|
||||
return mpAgentActivityParticipantService.save(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateParticipant(MpAgentActivityParticipantEntity entity) {
|
||||
// 检查是否存在相同的活动、代理商和家长记录(排除当前记录)
|
||||
LambdaQueryWrapper<MpAgentActivityParticipantEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getActivityId, entity.getActivityId())
|
||||
.eq(MpAgentActivityParticipantEntity::getAgentId, entity.getAgentId())
|
||||
wrapper.eq(MpAgentActivityParticipantEntity::getActivityName, entity.getActivityName())
|
||||
.eq(MpAgentActivityParticipantEntity::getAgentName, entity.getAgentName())
|
||||
.ne(MpAgentActivityParticipantEntity::getId, entity.getId());
|
||||
|
||||
long count = mpAgentActivityParticipantService.count(wrapper);
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("该代理商活动参与记录已存在");
|
||||
}
|
||||
|
||||
Integer agentId = mpAgentService.lambdaQuery().eq(MpAgentEntity::getAgentName, entity.getAgentName()).one().getId();
|
||||
Integer activityId = mpActivityService.lambdaQuery().eq(MpActivityEntity::getActivityName, entity.getActivityName()).one().getId();
|
||||
entity.setActivityId(activityId);
|
||||
entity.setAgentId(agentId);
|
||||
return mpAgentActivityParticipantService.updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteParticipant(Integer id) {
|
||||
return mpAgentActivityParticipantService.removeById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminAgentActivityParticipantResp getById(Integer id) {
|
||||
MpAgentActivityParticipantEntity entity = mpAgentActivityParticipantService.getById(id);
|
||||
return AdminAgentActivityParticipantConvert.INSTANCE.convertToResp(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteById(List<Integer> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return mpAgentActivityParticipantService.removeByIds(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,14 +3,19 @@ package com.seer.teach.mp.admin.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeSaveReq;
|
||||
import com.seer.teach.mp.admin.service.IAdminAgentEmployeeRelationService;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationQueryReq;
|
||||
import com.seer.teach.mp.admin.controller.req.AgentEmployeeRelationReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AgentEmployeeRelationResp;
|
||||
import com.seer.teach.mp.admin.convert.AdminAgentEmployeeRelationConvert;
|
||||
import com.seer.teach.mp.entity.MpAgentEmployeeRelationEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentEntity;
|
||||
import com.seer.teach.mp.service.IMpAgentEmployeeRelationService;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -31,12 +36,14 @@ public class AdminAgentEmployeeRelationServiceImpl implements IAdminAgentEmploye
|
||||
|
||||
private final IMpAgentEmployeeRelationService agentEmployeeRelationService;
|
||||
|
||||
private final IMpAgentService mpAgentService;
|
||||
|
||||
@Override
|
||||
public PageListBean<AgentEmployeeRelationResp> pageList(AgentEmployeeRelationQueryReq query) {
|
||||
Page<MpAgentEmployeeRelationEntity> pageParm = new Page<>(query.getPageNo(), query.getPageSize());
|
||||
var pageResult = agentEmployeeRelationService.page(pageParm, new LambdaQueryWrapper<>(MpAgentEmployeeRelationEntity.class)
|
||||
.eq(Objects.nonNull(query.getAgentId()), MpAgentEmployeeRelationEntity::getAgentId, query.getAgentId())
|
||||
.eq(Objects.nonNull(query.getEmployeeUserId()), MpAgentEmployeeRelationEntity::getEmployeeUserId, query.getEmployeeUserId())
|
||||
.like(Objects.nonNull(query.getAgentName()), MpAgentEmployeeRelationEntity::getAgentName, query.getAgentName())
|
||||
.like(Objects.nonNull(query.getEmployeeName()), MpAgentEmployeeRelationEntity::getEmployeeName, query.getEmployeeName())
|
||||
.eq(Objects.nonNull(query.getStatus()), MpAgentEmployeeRelationEntity::getStatus, query.getStatus()));
|
||||
|
||||
return PageConverterUtils.convertPageListBean(pageResult, AdminAgentEmployeeRelationConvert.INSTANCE::convertToRespList);
|
||||
@ -66,4 +73,12 @@ public class AdminAgentEmployeeRelationServiceImpl implements IAdminAgentEmploye
|
||||
.map(AdminAgentEmployeeRelationConvert.INSTANCE::convertToResp)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(AgentEmployeeSaveReq request) {
|
||||
AssertUtils.isNull(request.getAgentName(), ResultCodeEnum.AGENT_EMPLOYEE_ALREADY_EXISTS);
|
||||
MpAgentEmployeeRelationEntity relation = AdminAgentEmployeeRelationConvert.INSTANCE.convert(request);
|
||||
Integer agentId = mpAgentService.lambdaQuery().eq(MpAgentEntity::getAgentName, request.getAgentName()).one().getId();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,7 @@ spring:
|
||||
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml
|
||||
- optional:nacos:shared-database.yaml
|
||||
- optional:nacos:shared-redis.yaml
|
||||
- optional:nacos:shared-sa-token.yaml
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
|
||||
@ -25,6 +25,8 @@ CREATE TABLE `mp_agent_employee_relation` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '关联ID',
|
||||
`agent_id` int NOT NULL COMMENT '代理商ID(对应user表的ID)',
|
||||
`employee_user_id` int NOT NULL COMMENT '员工用户ID(对应user表的ID)',
|
||||
`agent_name` varchar(50) COMMENT '代理商名称',
|
||||
`employee_name` varchar(50) COMMENT '员工名称',
|
||||
`position` varchar(50) COMMENT '员工职位',
|
||||
`status` tinyint NOT NULL DEFAULT '1' COMMENT '员工状态:0-禁用,1-启用',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
@ -61,8 +63,11 @@ CREATE TABLE `mp_activity` (
|
||||
DROP TABLE IF EXISTS `mp_agent_activity_participant`;
|
||||
CREATE TABLE `mp_agent_activity_participant` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '参与记录ID',
|
||||
`activity_id` int NOT NULL COMMENT '活动ID',
|
||||
`agent_id` int NOT NULL COMMENT '代理商ID',
|
||||
`agent_id` int DEFAULT NULL COMMENT '代理商ID(对应user表的ID)',
|
||||
`activity_id` int DEFAULT NULL COMMENT '活动ID',
|
||||
`activity_name` varchar(100) NOT NULL COMMENT '活动名称',
|
||||
`agent_name` varchar(100) NOT NULL COMMENT '代理商名称',
|
||||
`qr_code_url` varchar(255) NOT NULL COMMENT '二维码url',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
|
||||
@ -16,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
@ -51,4 +52,12 @@ public class AppAgentActivityController {
|
||||
public ResultBean<AppActivityResp> getDetail(@PathVariable Integer id) {
|
||||
return ResultBean.success(agentActivityService.getById(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "活动二维码")
|
||||
@GetMapping("/{agentId}/{activityId}/qrcode")
|
||||
@SaCheckPermission("mp:app:agent:activity:qrcode")
|
||||
public ResultBean<String> getQrCode(@PathVariable("agentId") Integer agentId, @PathVariable("activityId") Integer activityId, @RequestParam("appId") String appId) {
|
||||
Integer userId = StpUtil.getLoginIdAsInt();
|
||||
return ResultBean.success(agentActivityService.getQrCode(userId,agentId,activityId,appId));
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.seer.teach.mp.app.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.DecryptionAnnotation;
|
||||
@ -37,6 +38,7 @@ public class AppAgentController {
|
||||
|
||||
@Operation(summary = "获取代理商详情")
|
||||
@GetMapping("/detail")
|
||||
@SaCheckPermission("mp:app:agent:detail")
|
||||
public ResultBean<AppMpAgentResp> getAgent() {
|
||||
Integer userId = StpUtil.getLoginIdAsInt();
|
||||
return ResultBean.success(appAgentService.getAgentRespByUserId(userId));
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.seer.teach.mp.app.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.DecryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.EncryptionAnnotation;
|
||||
@ -38,6 +39,7 @@ public class AppMpQrCodeController {
|
||||
*/
|
||||
@Operation(summary = "生成微信服务号二维码")
|
||||
@PostMapping("/official/generate")
|
||||
@SaCheckPermission("mp:app:qrcode:generate")
|
||||
public ResultBean<MpQrCodeResp> generateOfficialQrCode(@Valid @RequestBody MpGenerateQrCodeReq req) {
|
||||
return ResultBean.success(appOfficialQrCodeService.generateQrCode(req));
|
||||
}
|
||||
@ -48,6 +50,7 @@ public class AppMpQrCodeController {
|
||||
*/
|
||||
@Operation(summary = "生成微信小程序二维码")
|
||||
@PostMapping("/mini/generate")
|
||||
@SaCheckPermission("mp:app:qrcode:mini-generate")
|
||||
public ResultBean<String> generateQrCode(@Valid @RequestBody GetQrCodeReq reqParams) {
|
||||
OssImageUploadResp resp = wechatMiniProgramService.createQrcode(reqParams);
|
||||
return ResultBean.success(resp.getUrl());
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package com.seer.teach.mp.app.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.DecryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.EncryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.mp.app.controller.req.JsapiSignatureReq;
|
||||
import com.seer.teach.mp.app.controller.resp.JsapiSignatureResp;
|
||||
import com.seer.teach.mp.app.service.IAppMpSignatureService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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 jakarta.validation.Valid;
|
||||
|
||||
@EncryptionAnnotation
|
||||
@DecryptionAnnotation
|
||||
@Tag(name = "APP - 微信JS-SDK签名")
|
||||
@RestController
|
||||
@RequestMapping("/app/signature")
|
||||
@LogPrint
|
||||
@RequiredArgsConstructor
|
||||
public class AppMpSignatureController {
|
||||
|
||||
private final IAppMpSignatureService appMpSignatureService;
|
||||
|
||||
@Operation(summary = "生成JS-SDK签名")
|
||||
@PostMapping("/jsapi")
|
||||
@SaCheckPermission("mp:app:signature:jsapi")
|
||||
public ResultBean<JsapiSignatureResp> generateJsapiSignature(@Valid @RequestBody JsapiSignatureReq req) {
|
||||
JsapiSignatureResp resp = appMpSignatureService.generateJsapiSignature(req);
|
||||
return ResultBean.success(resp);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.seer.teach.mp.app.controller.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* JS-SDK签名请求参数
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "JS-SDK签名请求参数")
|
||||
public class JsapiSignatureReq {
|
||||
|
||||
@NotEmpty(message = "URL不能为空")
|
||||
@Schema(description = "当前网页的URL,不包含#及其后面部分")
|
||||
private String url;
|
||||
|
||||
@NotEmpty(message = "appId不能为空")
|
||||
@Schema(description = "公众号的唯一标识")
|
||||
private String appId;
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.seer.teach.mp.app.controller.resp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* JS-SDK签名响应参数
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "JS-SDK签名响应参数")
|
||||
public class JsapiSignatureResp {
|
||||
|
||||
@Schema(description = "生成签名的时间戳")
|
||||
private Long timestamp;
|
||||
|
||||
@Schema(description = "生成签名的随机串")
|
||||
private String nonceStr;
|
||||
|
||||
@Schema(description = "签名")
|
||||
private String signature;
|
||||
|
||||
@Schema(description = "公众号的唯一标识")
|
||||
private String appId;
|
||||
|
||||
public JsapiSignatureResp() {
|
||||
}
|
||||
|
||||
public JsapiSignatureResp(Long timestamp, String nonceStr, String signature, String appId) {
|
||||
this.timestamp = timestamp;
|
||||
this.nonceStr = nonceStr;
|
||||
this.signature = signature;
|
||||
this.appId = appId;
|
||||
}
|
||||
}
|
||||
@ -30,4 +30,14 @@ public interface IAppActivityService {
|
||||
* @return 活动详情
|
||||
*/
|
||||
AppActivityResp getById(Integer id);
|
||||
|
||||
/**
|
||||
* 获取活动二维码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param agentId 代理商ID
|
||||
* @param activityId 活动ID
|
||||
* @return 活动二维码
|
||||
*/
|
||||
String getQrCode(Integer userId,Integer agentId,Integer activityId,String appId);
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.seer.teach.mp.app.service;
|
||||
|
||||
import com.seer.teach.mp.app.controller.resp.JsapiSignatureResp;
|
||||
import com.seer.teach.mp.app.controller.req.JsapiSignatureReq;
|
||||
|
||||
/**
|
||||
* 微信公众号JS-SDK签名服务接口
|
||||
*/
|
||||
public interface IAppMpSignatureService {
|
||||
|
||||
/**
|
||||
* 生成JS-SDK签名
|
||||
*
|
||||
* @param req 签名请求参数
|
||||
* @return JS-SDK签名响应参数
|
||||
*/
|
||||
JsapiSignatureResp generateJsapiSignature(JsapiSignatureReq req);
|
||||
}
|
||||
@ -5,13 +5,22 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.mp.app.controller.req.AppAgentActivityQueryReq;
|
||||
import com.seer.teach.mp.app.controller.req.MpGenerateQrCodeReq;
|
||||
import com.seer.teach.mp.app.controller.resp.AppActivityResp;
|
||||
import com.seer.teach.mp.app.controller.resp.MpQrCodeResp;
|
||||
import com.seer.teach.mp.app.convert.AppAgentActivityConvert;
|
||||
import com.seer.teach.mp.app.service.AppOfficialQrCodeService;
|
||||
import com.seer.teach.mp.app.service.IAppActivityService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -34,6 +43,10 @@ public class AppActivityServiceImpl implements IAppActivityService {
|
||||
|
||||
private final IMpActivityService activityService;
|
||||
|
||||
private final AppOfficialQrCodeService officialQrCodeService;
|
||||
|
||||
private final IMpAgentActivityParticipantService agentActivityParticipantService;
|
||||
|
||||
@Override
|
||||
public PageListBean<AppActivityResp> pageList(AppAgentActivityQueryReq query, Integer agentId) {
|
||||
log.info("查询参数:{}", query);
|
||||
@ -53,4 +66,27 @@ public class AppActivityServiceImpl implements IAppActivityService {
|
||||
MpActivityEntity entity = activityService.getById(id);
|
||||
return AppAgentActivityConvert.INSTANCE.convertToResp(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQrCode(Integer userId,Integer agentId,Integer activityId,String appId) {
|
||||
MpActivityEntity activity = activityService.getById(activityId);
|
||||
AssertUtils.notNull(activity, ResultCodeEnum.INVALID_ACTIVITY);
|
||||
|
||||
if(activity.getStatus() != 1){
|
||||
throw new CommonException(ResultCodeEnum.INVALID_ACTIVITY);
|
||||
}
|
||||
MpAgentActivityParticipantEntity relation = agentActivityParticipantService.getParticipantsByActivityAndAgent(activityId, agentId);
|
||||
AssertUtils.notNull(relation, ResultCodeEnum.INVALID_ACTIVITY);
|
||||
if(StringUtils.isNotBlank(relation.getQrCodeUrl())){
|
||||
return relation.getQrCodeUrl();
|
||||
}
|
||||
MpGenerateQrCodeReq req = new MpGenerateQrCodeReq();
|
||||
req.setSceneStr("agentId=" + agentId + "&activityId=" + activityId);
|
||||
req.setAppId(appId);
|
||||
req.setType(2);
|
||||
MpQrCodeResp mpQrCodeResp = officialQrCodeService.generateQrCode(req);
|
||||
relation.setQrCodeUrl(mpQrCodeResp.getQrCodeUrl());
|
||||
agentActivityParticipantService.updateById(relation);
|
||||
return mpQrCodeResp.getQrCodeUrl();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.seer.teach.mp.app.service.impl;
|
||||
|
||||
import com.seer.teach.mp.app.controller.req.JsapiSignatureReq;
|
||||
import com.seer.teach.mp.app.controller.resp.JsapiSignatureResp;
|
||||
import com.seer.teach.mp.app.service.IAppMpSignatureService;
|
||||
import com.seer.teach.mp.factory.MpServiceFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 微信公众号JS-SDK签名服务实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AppMpSignatureServiceImpl implements IAppMpSignatureService {
|
||||
|
||||
private final MpServiceFactory mpServiceFactory;
|
||||
|
||||
@Override
|
||||
public JsapiSignatureResp generateJsapiSignature(JsapiSignatureReq req) {
|
||||
try {
|
||||
// 获取WxMpService实例
|
||||
var mpService = mpServiceFactory.getRequiredMpService(req.getAppId());
|
||||
|
||||
WxJsapiSignature wxJsapiSignature = mpService.createJsapiSignature(req.getUrl());
|
||||
|
||||
return new JsapiSignatureResp(wxJsapiSignature.getTimestamp(), wxJsapiSignature.getNonceStr(), wxJsapiSignature.getSignature(), req.getAppId());
|
||||
} catch (WxErrorException e) {
|
||||
log.error("生成JS-SDK签名失败,appId: {}, url: {}", req.getAppId(), req.getUrl(), e);
|
||||
throw new RuntimeException("生成JS-SDK签名失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,8 @@ package com.seer.teach.mp.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 代理商活动表 服务类
|
||||
@ -29,4 +31,10 @@ public interface IMpActivityService extends IService<MpActivityEntity> {
|
||||
* @return 操作是否成功
|
||||
*/
|
||||
boolean deleteActivity(Integer id);
|
||||
|
||||
/**
|
||||
* 获取代理商活动名称列表
|
||||
* @return 代理商活动名称列表
|
||||
*/
|
||||
List<String> getActivityName();
|
||||
}
|
||||
@ -31,4 +31,12 @@ public interface IMpAgentActivityParticipantService extends IService<MpAgentActi
|
||||
* @return 参与记录列表
|
||||
*/
|
||||
List<MpAgentActivityParticipantEntity> getListByAgentId(Integer agentId);
|
||||
|
||||
/**
|
||||
* 根据活动ID获取所有参与记录
|
||||
*
|
||||
* @param activityId 活动ID
|
||||
* @return 参与记录列表
|
||||
*/
|
||||
List<MpAgentActivityParticipantEntity> getOneByActivityId(Integer activityId);
|
||||
}
|
||||
@ -3,6 +3,8 @@ package com.seer.teach.mp.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.seer.teach.mp.entity.MpAgentEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 代理商服务接口
|
||||
*/
|
||||
@ -31,4 +33,10 @@ public interface IMpAgentService extends IService<MpAgentEntity> {
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean updateAgent(MpAgentEntity agentEntity);
|
||||
|
||||
/**
|
||||
* 获取代理商名称列表
|
||||
* @return 代理商名称列表
|
||||
*/
|
||||
List<String> getAgentName();
|
||||
}
|
||||
@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -104,6 +105,12 @@ public class MpActivityServiceImpl extends ServiceImpl<MpAgentActivityMapper, Mp
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActivityName() {
|
||||
return this.list().stream()
|
||||
.map(MpActivityEntity::getActivityName).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveOrUpdate(MpActivityEntity entity) {
|
||||
boolean result = super.saveOrUpdate(entity);
|
||||
|
||||
@ -42,4 +42,9 @@ public class MpAgentActivityParticipantServiceImpl extends ServiceImpl<MpAgentAc
|
||||
return super.list(new LambdaQueryWrapper<MpAgentActivityParticipantEntity>()
|
||||
.eq(MpAgentActivityParticipantEntity::getAgentId, agentId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MpAgentActivityParticipantEntity> getOneByActivityId(Integer activityId) {
|
||||
return super.list(new LambdaQueryWrapper<MpAgentActivityParticipantEntity>().eq(MpAgentActivityParticipantEntity::getActivityId, activityId));
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,8 @@ import com.seer.teach.mp.mapper.MpAgentMapper;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 代理商服务实现类
|
||||
*/
|
||||
@ -26,4 +28,10 @@ public class MpAgentServiceImpl extends ServiceImpl<MpAgentMapper, MpAgentEntity
|
||||
public Boolean updateAgent(MpAgentEntity agentEntity) {
|
||||
return this.updateById(agentEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAgentName() {
|
||||
List<MpAgentEntity> list = this.list();
|
||||
return list.stream().map(MpAgentEntity::getAgentName).toList();
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,13 @@
|
||||
package com.seer.teach.teacher.common.req;
|
||||
|
||||
import com.seer.teach.common.enums.teacher.ReportTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ -16,7 +16,7 @@ import jakarta.validation.constraints.NotNull;
|
||||
@Schema(description = "Ai报告请求实体类")
|
||||
public class AiReportReq {
|
||||
|
||||
@Schema(description = "报告类型(0-本周,1-本天)")
|
||||
@Schema(description ="报告类型(0-今天,1-本周,2-本月)")
|
||||
@NotNull(message = "报告类型不能为空")
|
||||
private Integer type;
|
||||
private ReportTypeEnum type;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.seer.teach.teacher.common.resp;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -32,6 +31,9 @@ public class AiReportResp {
|
||||
@Schema(description = "作业正确率")
|
||||
private String homeworkCorrectRate;
|
||||
|
||||
@Schema(description = "鼓励语句")
|
||||
private String encourage;
|
||||
|
||||
@Schema(description = "科目正确率")
|
||||
private List<SubjectCorrectRateResp> subjectCorrectRate;
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package com.seer.teach.teacher.common.resp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
@Schema(description = "举一反三类似题目返回实体类")
|
||||
public class SimilarQuestionResp {
|
||||
|
||||
@Schema(description = "题目Id")
|
||||
private Integer id;
|
||||
|
||||
@Schema(description = "做题富文本数据")
|
||||
private String questionHtml;
|
||||
|
||||
@Schema(description = "题型(1单选选择题 2多选选择题 4判断题 6填空题)")
|
||||
private Integer type;
|
||||
}
|
||||
@ -7,8 +7,8 @@ import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.teacher.common.req.AiReportReq;
|
||||
import com.seer.teach.teacher.common.resp.AiReportResp;
|
||||
import com.seer.teach.teacher.service.ReportService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
@ -5,19 +5,22 @@ import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.common.annotation.DecryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.EncryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.common.enums.AiScenarioCodeEnum;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionBookReq;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionPageListReq;
|
||||
import com.seer.teach.teacher.common.resp.SimilarQuestionResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionPageListResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionResp;
|
||||
import com.seer.teach.teacher.module.entity.IdEntity;
|
||||
import com.seer.teach.teacher.service.WrongQuestionService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
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;
|
||||
|
||||
@ -37,7 +40,7 @@ public class WrongQuestionController {
|
||||
@LogPrint
|
||||
@Operation(summary = "获取各科目的错题数量")
|
||||
public ResultBean<WrongQuestionResp> getWrongQuestionBook(@RequestBody @Validated WrongQuestionBookReq params) {
|
||||
WrongQuestionResp wrongQuestion = wrongQuestionService.getWrongQuestion(params);
|
||||
WrongQuestionResp wrongQuestion = wrongQuestionService.getWrongQuestionCount(params);
|
||||
return ResultBean.success(wrongQuestion);
|
||||
}
|
||||
|
||||
@ -57,13 +60,12 @@ public class WrongQuestionController {
|
||||
return ResultBean.success();
|
||||
}
|
||||
|
||||
@PostMapping("/generateQuestionsByQuestionId")
|
||||
@PostMapping("/getSimilarQuestions")
|
||||
@LogPrint
|
||||
@Operation(summary = "举一反三")
|
||||
public ResultBean<List<String>> generateSimilarQuestions(@RequestBody @Validated IdEntity params) {
|
||||
List<String> questions = wrongQuestionService.generateSimilarQuestions(params.getId(),
|
||||
AiScenarioCodeEnum.LEARN_BY_ANALOGY_GENERATE_QUESTIONS, 3);
|
||||
return ResultBean.success(questions);
|
||||
@Operation(summary = "举一反三获取相似题目")
|
||||
public ResultBean<List<SimilarQuestionResp>> getSimilarQuestions(@RequestBody @Validated IdEntity params) {
|
||||
List<SimilarQuestionResp> result = wrongQuestionService.getSimilarQuestionsByQuestionId(params.getId());
|
||||
return ResultBean.success(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ spring:
|
||||
import:
|
||||
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml
|
||||
- optional:nacos:shared-database.yaml
|
||||
- optional:nacos:shared-minio.yaml
|
||||
- optional:nacos:shared-redis.yaml
|
||||
- optional:nacos:shared-sa-token.yaml
|
||||
- optional:nacos:shared-minio.yaml
|
||||
|
||||
@ -12,5 +12,6 @@ public interface AiReportConvert {
|
||||
|
||||
AiReportConvert INSTANCE = Mappers.getMapper(AiReportConvert.class);
|
||||
|
||||
AiReportResp toAiReportResp(String studyTime, String readingTime, String practiceCount, String dailyStudyTime, String homeworkCorrectRate, List<SubjectCorrectRateResp> subjectCorrectRate);
|
||||
AiReportResp toAiReportResp(String studyTime, String readingTime, String practiceCount, String encourage,
|
||||
String dailyStudyTime, String homeworkCorrectRate, List<SubjectCorrectRateResp> subjectCorrectRate);
|
||||
}
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
package com.seer.teach.teacher.convert;
|
||||
|
||||
import com.seer.teach.teacher.common.resp.SimilarQuestionResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionResp;
|
||||
import com.seer.teach.teacher.module.entity.BankQuestionsEntity;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface WrongQuestionBookConvert {
|
||||
@ -13,4 +17,8 @@ public interface WrongQuestionBookConvert {
|
||||
|
||||
@Mapping(source = "totalWrongCount",target = "count")
|
||||
WrongQuestionResp toWrongQuestion(String totalWrongCount);
|
||||
|
||||
SimilarQuestionResp toSimilarQuestion(BankQuestionsEntity bankQuestionsEntity);
|
||||
|
||||
List<SimilarQuestionResp> toSimilarQuestionList(List<BankQuestionsEntity> bankQuestionsEntity);
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.enums.AiScenarioCodeEnum;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionBookReq;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionPageListReq;
|
||||
import com.seer.teach.teacher.common.resp.SimilarQuestionResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionPageListResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionResp;
|
||||
import com.seer.teach.teacher.module.entity.IdEntity;
|
||||
@ -24,7 +25,7 @@ public interface WrongQuestionService {
|
||||
* @param params 请求参数
|
||||
* @return 错题本
|
||||
*/
|
||||
WrongQuestionResp getWrongQuestion(WrongQuestionBookReq params);
|
||||
WrongQuestionResp getWrongQuestionCount(WrongQuestionBookReq params);
|
||||
|
||||
/**
|
||||
* 获取错题列表
|
||||
@ -51,4 +52,11 @@ public interface WrongQuestionService {
|
||||
* @return 举一反三
|
||||
*/
|
||||
List<String> generateSimilarQuestions(Integer id, AiScenarioCodeEnum scenarioCode, Integer count);
|
||||
|
||||
/**
|
||||
* 举一反三获取相似题目
|
||||
* @param id 题目Id
|
||||
* @return 相似题目
|
||||
*/
|
||||
List<SimilarQuestionResp> getSimilarQuestionsByQuestionId(Integer id);
|
||||
}
|
||||
@ -4,6 +4,7 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.seer.teach.common.entity.BaseEntity;
|
||||
import com.seer.teach.common.enums.MakeQuestionTypeEnums;
|
||||
import com.seer.teach.common.enums.teacher.ReportTypeEnum;
|
||||
import com.seer.teach.common.utils.DateUtils;
|
||||
import com.seer.teach.iot.api.UserDeviceServiceApi;
|
||||
import com.seer.teach.teacher.common.dto.ReportQuestionDTO;
|
||||
@ -18,18 +19,18 @@ import com.seer.teach.teacher.convert.QuestionConvert;
|
||||
import com.seer.teach.teacher.convert.ReportConvert;
|
||||
import com.seer.teach.teacher.module.entity.*;
|
||||
import com.seer.teach.teacher.service.*;
|
||||
import com.seer.teach.teacher.util.RateUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.*;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -47,6 +48,20 @@ public class ReportServiceImpl implements ReportService {
|
||||
|
||||
private static final String PERCENT_SIGN = "%";
|
||||
|
||||
private static final String FIRST_STUDY = "你近期首次学习,期待你的持续进步!";
|
||||
|
||||
private static final String NOT_STUDY = "你%s还没有学习哦! 快去学习吧~";
|
||||
|
||||
private static final String VERY_GREAT = "很棒哦! %s你的作业正确率提升了%d%%,继续保持优秀表现~";
|
||||
|
||||
private static final String NOT_BAD = "不错哦! %s你的作业正确率提升了%d%%,请继续加油~";
|
||||
|
||||
private static final String COME_ON = "加油哦! %s你的作业正确率有提升,再接再厉~";
|
||||
|
||||
private static final String CONTINUE_STUDYING = "继续努力哦! %s你的作业正确率还有提升空间~";
|
||||
|
||||
private static final String DON_LOSE_HEART = "别灰心哦!%s你的作业正确率有所下降,坚持学习一定会进步的~";
|
||||
|
||||
private final EvaluationTasksService evaluationTasksService;
|
||||
|
||||
private final UserDeviceServiceApi userDeviceServiceApi;
|
||||
@ -161,16 +176,144 @@ public class ReportServiceImpl implements ReportService {
|
||||
.reduce(0, Integer::sum);
|
||||
String readingTime = DateUtils.formatSecondsToHourAndMinute(readingSeconds);
|
||||
|
||||
// 鼓励语句
|
||||
String encourage = generateEncouragement(params.getType(), homeworkCorrectRate, userId);
|
||||
|
||||
// 日均学习时间
|
||||
long days = ChronoUnit.DAYS.between(startTime.toLocalDate(), endTime.toLocalDate()) + 1;
|
||||
String dailyStudyTime = (studySeconds / 60 / days) + MINUTE;
|
||||
|
||||
// 返回最终AI报告结果
|
||||
return AiReportConvert.INSTANCE.toAiReportResp(
|
||||
studyTime, readingTime, practiceCount, dailyStudyTime, homeworkCorrectRate, subjectRates
|
||||
);
|
||||
return AiReportConvert.INSTANCE.toAiReportResp(studyTime, readingTime, practiceCount, encourage,
|
||||
dailyStudyTime, homeworkCorrectRate, subjectRates);
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼓励语句
|
||||
*
|
||||
* @param type 时间类型
|
||||
* @param correctRate 当前正确率
|
||||
* @return 鼓励语
|
||||
*/
|
||||
private String generateEncouragement(ReportTypeEnum type, String correctRate, Integer userId) {
|
||||
// 时间段
|
||||
String timePeriod = type.getDesc();
|
||||
// 当前正确率
|
||||
BigDecimal currentRate = RateUtils.percentStrToRate(correctRate);
|
||||
|
||||
// 如果正确率为0%,说明没有做题,返回鼓励语
|
||||
if (currentRate.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return String.format(NOT_STUDY, timePeriod);
|
||||
}
|
||||
// 获取历史正确率进行对比
|
||||
Optional<BigDecimal> historyRateOpt = getHistoricalCorrectRate(userId, type);
|
||||
// 如果没有历史学习记录,返回提示语
|
||||
if (!historyRateOpt.isPresent()) {
|
||||
return FIRST_STUDY;
|
||||
}
|
||||
// 获取提升百分比
|
||||
BigDecimal historyRate = historyRateOpt.get();
|
||||
BigDecimal improvementPercent = RateUtils.calculateImprovementPercent(currentRate, historyRate);
|
||||
int improve = improvementPercent.intValue();
|
||||
if (improve >= 20) {
|
||||
return String.format(VERY_GREAT, timePeriod, improve);
|
||||
} else if (improve >= 10) {
|
||||
return String.format(NOT_BAD, timePeriod, improve);
|
||||
} else if (improve >= 5) {
|
||||
return String.format(COME_ON, timePeriod);
|
||||
} else if (improve > -5) {
|
||||
return String.format(CONTINUE_STUDYING, timePeriod);
|
||||
} else {
|
||||
return String.format(DON_LOSE_HEART, timePeriod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史作业正确率
|
||||
*
|
||||
* @param userId 用户Id
|
||||
* @param type 时间类型
|
||||
* @return 历史作业正确率
|
||||
*/
|
||||
private Optional<BigDecimal> getHistoricalCorrectRate(Integer userId, ReportTypeEnum type) {
|
||||
// 获取当前查询时间段的开始时间
|
||||
LocalDateTime currentTimeStart = DateUtils.getStartTime(type);
|
||||
|
||||
// 查询当前时间段之前的学习记录,按时间倒序排列
|
||||
List<LessonsEntity> previousLessons = lessonsService.lambdaQuery()
|
||||
.eq(LessonsEntity::getUserId, userId)
|
||||
.lt(LessonsEntity::getCreateTime, currentTimeStart)
|
||||
.orderByDesc(LessonsEntity::getCreateTime)
|
||||
.list();
|
||||
|
||||
List<EvaluationTasksEntity> previousEvaluations = evaluationTasksService.lambdaQuery()
|
||||
.eq(EvaluationTasksEntity::getUserId, userId)
|
||||
.lt(EvaluationTasksEntity::getCreateTime, currentTimeStart)
|
||||
.orderByDesc(EvaluationTasksEntity::getCreateTime)
|
||||
.list();
|
||||
|
||||
// 合并并按时间倒序排序,找出最近一次学习会话的时间范围
|
||||
List<LocalDateTime> allCreateTimes = Stream.concat(
|
||||
previousLessons.stream().map(LessonsEntity::getCreateTime),
|
||||
previousEvaluations.stream().map(EvaluationTasksEntity::getCreateTime))
|
||||
.sorted(Collections.reverseOrder()).collect(Collectors.toList());
|
||||
if (allCreateTimes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// 获取最近一次学习的时间
|
||||
LocalDateTime latestLearningTime = allCreateTimes.get(0);
|
||||
|
||||
// 根据报告类型确定历史时间段
|
||||
LocalDateTime periodStart, periodEnd;
|
||||
|
||||
switch (type) {
|
||||
case DAILY:
|
||||
// 查找最近一次学习的那一天的所有学习记录
|
||||
LocalDate learningDate = latestLearningTime.toLocalDate();
|
||||
periodStart = learningDate.atStartOfDay();
|
||||
periodEnd = learningDate.atTime(LocalTime.MAX);
|
||||
break;
|
||||
case WEEKLY:
|
||||
// 查找最近一次学习的那周
|
||||
LocalDate learningWeekStart = latestLearningTime.toLocalDate().with(DayOfWeek.MONDAY);
|
||||
LocalDate learningWeekEnd = learningWeekStart.plusDays(6);
|
||||
periodStart = learningWeekStart.atStartOfDay();
|
||||
periodEnd = learningWeekEnd.atTime(LocalTime.MAX);
|
||||
break;
|
||||
case MONTHLY:
|
||||
// 查找最近一次学习的那个月
|
||||
YearMonth learningMonth = YearMonth.from(latestLearningTime);
|
||||
periodStart = learningMonth.atDay(1).atStartOfDay();
|
||||
periodEnd = learningMonth.atEndOfMonth().atTime(LocalTime.MAX);
|
||||
break;
|
||||
default:
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// 获取该历史时期的完整学习数据
|
||||
List<LessonsEntity> lessons = lessonsService.lambdaQuery()
|
||||
.eq(LessonsEntity::getUserId, userId)
|
||||
.ge(LessonsEntity::getCreateTime, periodStart)
|
||||
.le(LessonsEntity::getCreateTime, periodEnd)
|
||||
.list();
|
||||
|
||||
List<EvaluationTasksEntity> evaluations = evaluationTasksService.lambdaQuery()
|
||||
.eq(EvaluationTasksEntity::getUserId, userId)
|
||||
.ge(EvaluationTasksEntity::getCreateTime, periodStart)
|
||||
.le(EvaluationTasksEntity::getCreateTime, periodEnd)
|
||||
.list();
|
||||
|
||||
int totalQ = getTotalQuestions(lessons) + getTotalQuestions(evaluations);
|
||||
if (totalQ == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
BigDecimal totalCorrect = calculateTotalCorrect(lessons).add(calculateTotalCorrect(evaluations));
|
||||
return Optional.of(totalCorrect.divide(BigDecimal.valueOf(totalQ), 2, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定用户的全部题目数据(包括测评和计划中的题目)。
|
||||
*
|
||||
@ -535,6 +678,11 @@ public class ReportServiceImpl implements ReportService {
|
||||
* @return 科目ID到名称的映射
|
||||
*/
|
||||
private Map<Integer, String> getSubjectsByIds(Set<Integer> ids) {
|
||||
log.info("获取科目名称,ID集合: {}", ids);
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
log.info("ID集合为空,返回空map");
|
||||
return new HashMap<>();
|
||||
}
|
||||
Map<Integer, String> map = new HashMap<>();
|
||||
for (SubjectsEntity s : subjectsService.listByIds(new ArrayList<>(ids))) {
|
||||
map.put(s.getId(), s.getSubject());
|
||||
|
||||
@ -7,11 +7,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.enums.*;
|
||||
import com.seer.teach.common.enums.AiScenarioCodeEnum;
|
||||
import com.seer.teach.common.enums.BankQuestionStatusEnum;
|
||||
import com.seer.teach.common.enums.QuestionResultEnums;
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionBookReq;
|
||||
import com.seer.teach.teacher.common.req.WrongQuestionPageListReq;
|
||||
import com.seer.teach.teacher.common.resp.SimilarQuestionResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionPageListResp;
|
||||
import com.seer.teach.teacher.common.resp.WrongQuestionResp;
|
||||
import com.seer.teach.teacher.convert.WrongQuestionBookConvert;
|
||||
@ -63,7 +67,7 @@ public class WrongQuestionServiceImpl implements WrongQuestionService {
|
||||
* @return 返回封装了总错题数的响应对象
|
||||
*/
|
||||
@Override
|
||||
public WrongQuestionResp getWrongQuestion(WrongQuestionBookReq params) {
|
||||
public WrongQuestionResp getWrongQuestionCount(WrongQuestionBookReq params) {
|
||||
Integer userId = StpUtil.getLoginIdAsInt();
|
||||
log.info("开始获取用户[{}]测评错题本数据", userId);
|
||||
|
||||
@ -243,6 +247,40 @@ public class WrongQuestionServiceImpl implements WrongQuestionService {
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 举一反三获取相似题目
|
||||
*
|
||||
* @param id 题目Id
|
||||
* @return 相似题目列表
|
||||
*/
|
||||
|
||||
@Override
|
||||
public List<SimilarQuestionResp> getSimilarQuestionsByQuestionId(Integer id) {
|
||||
// 根据题目Id获取题目
|
||||
BankQuestionsEntity questionBank = bankQuestionsService.getById(id);
|
||||
AssertUtils.notNull(questionBank, ResultCodeEnum.QUESTION_NOT_EXIST);
|
||||
// 获取知识点Id
|
||||
Integer knowId = questionBank.getKnowId();
|
||||
// 查询相同知识点的题目,排除原题目
|
||||
List<BankQuestionsEntity> questionsList = bankQuestionsService.lambdaQuery()
|
||||
.eq(BankQuestionsEntity::getKnowId, knowId)
|
||||
.ne(BankQuestionsEntity::getId, id)
|
||||
.list();
|
||||
List<SimilarQuestionResp> similarQuestionList = WrongQuestionBookConvert.INSTANCE.toSimilarQuestionList(questionsList);
|
||||
// 过滤掉questionHtml为空的题目
|
||||
List<SimilarQuestionResp> result = similarQuestionList.stream()
|
||||
.filter(question -> question.getQuestionHtml() != null && !question.getQuestionHtml().isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
// 将相似题目打乱顺序排序
|
||||
Collections.shuffle(result);
|
||||
// 返回10道知识点相同的题目
|
||||
return result.stream()
|
||||
.limit(10)
|
||||
// 重新编号(序号1-10)
|
||||
.peek((question) -> question.setId(result.indexOf(question) + 1))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步批量插入生成的相似题目到题库
|
||||
*
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
package com.seer.teach.teacher.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RateUtils {
|
||||
|
||||
/**
|
||||
* 百分比字符串转正确率("62%" -> 0.62)
|
||||
*
|
||||
* @param percent 百分比字符串
|
||||
* @return 正确率
|
||||
*/
|
||||
public static BigDecimal percentStrToRate(String percent) {
|
||||
if (percent == null || percent.trim().isEmpty() || "0%".equals(percent)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return new BigDecimal(percent.replace("%", ""))
|
||||
.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算提升百分比
|
||||
*
|
||||
* @param current 当前正确率
|
||||
* @param history 历史正确率
|
||||
* @return 提升百分比
|
||||
*/
|
||||
public static BigDecimal calculateImprovementPercent(BigDecimal current, BigDecimal history) {
|
||||
if (history.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
// 历史为 0,认为是首次学习
|
||||
return BigDecimal.valueOf(100);
|
||||
}
|
||||
BigDecimal improve = current.subtract(history)
|
||||
.divide(history, 2, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.setScale(0, RoundingMode.HALF_UP);
|
||||
// 限制范围 [-100, 100]
|
||||
return improve.max(BigDecimal.valueOf(-100))
|
||||
.min(BigDecimal.valueOf(100));
|
||||
}
|
||||
}
|
||||
@ -188,11 +188,10 @@ public class WrongQuestionUtils {
|
||||
String processed = originalHtml
|
||||
.replaceAll("<!--\\s*题目解析\\s*-->\\s*<p><b>解析:</b>", "<p>解析:")
|
||||
.replaceAll("<p>\\s*<b>答案:</b>\\s*", "<p>【正确答案】 ");
|
||||
String redX = " ❌";
|
||||
// String redX = " ❌";
|
||||
// 构建学生答案段
|
||||
String studentSegment = "<p>【你的答案】 "
|
||||
+ (safeStudentAnswer.isEmpty() ? "" : safeStudentAnswer)
|
||||
+ redX
|
||||
+ "</p>\n\n";
|
||||
// 插入到正确答案之前
|
||||
processed = processed.replaceFirst("<p>【正确答案】", studentSegment + "<p>【正确答案】");
|
||||
|
||||
@ -21,6 +21,7 @@ spring:
|
||||
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml
|
||||
- optional:nacos:shared-database.yaml
|
||||
- optional:nacos:shared-redis.yaml
|
||||
- optional:nacos:shared-sa-token.yaml
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user