diff --git a/src/main/java/com/example/caseData/controller/CaseExchangeController.java b/src/main/java/com/example/caseData/controller/CaseExchangeController.java index e8adc29..db0c5a5 100644 --- a/src/main/java/com/example/caseData/controller/CaseExchangeController.java +++ b/src/main/java/com/example/caseData/controller/CaseExchangeController.java @@ -657,4 +657,28 @@ public class CaseExchangeController { resultMap.put("data", resultPage.getRecords()); return Response.success(resultMap); } + + /** + * 病例交流-投票 + */ + @PostMapping("/exchange/vote/{exchange_id}") + public Response AddCaseExchangeVote( + @Validated() + @PathVariable("exchange_id") String exchangeId, + @ModelAttribute addCaseExchangeVote r + ) { + + String userId = (String) httpServletRequest.getAttribute("userId"); + + if (userId == null) { + return Response.error("操作失败"); + } + + boolean res = caseExchangeService.AddCaseExchangeVote(exchangeId,userId,r.getOptionId()); + if (!res){ + return Response.error("操作失败"); + } + + return Response.success(); + } } diff --git a/src/main/java/com/example/caseData/controller/ClinicalController.java b/src/main/java/com/example/caseData/controller/ClinicalController.java index 333cb84..33fe68f 100644 --- a/src/main/java/com/example/caseData/controller/ClinicalController.java +++ b/src/main/java/com/example/caseData/controller/ClinicalController.java @@ -13,11 +13,9 @@ import com.example.caseData.dto.caseClinicalVideo.CaseClinicalVideoDto; import com.example.caseData.dto.caseClinicalVideoAuthor.CaseClinicalVideoAuthorDto; import com.example.caseData.dto.statsCaseClinicalDoctor.StatsCaseClinicalDoctorDto; import com.example.caseData.dto.statsCaseClinicalHospital.StatsCaseClinicalHospitalDto; +import com.example.caseData.dto.statsCaseClinicalLabel.StatsCaseClinicalLabelDto; import com.example.caseData.model.*; -import com.example.caseData.request.clinicalRequest.getClinicalArticleSearchPage; -import com.example.caseData.request.clinicalRequest.getClinicalDoctorSearchPage; -import com.example.caseData.request.clinicalRequest.getClinicalHospitalSearchPage; -import com.example.caseData.request.clinicalRequest.getClinicalVideoSearchPage; +import com.example.caseData.request.clinicalRequest.*; import com.example.caseData.service.CaseClinicalArticleService; import com.example.caseData.service.CaseClinicalVideoService; import com.example.caseData.utils.Replace; @@ -69,6 +67,9 @@ public class ClinicalController extends BaseController { @Resource private CaseClinicalVideoService caseClinicalVideoService; + @Resource + private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao; + /** @@ -289,6 +290,31 @@ public class ClinicalController extends BaseController { return Response.success(resultMap); } + /** + * 临床病例库-疾病标签-搜索 + */ + @PostMapping("/clinical/label/search") + public Response> getClinicalLabelSearchPage( + @Validated() + @RequestBody getClinicalLabelSearchPage request + ) { + request.validateForPage(); + + Page page = new Page<>(request.getPage(), request.getPageSize()); + + IPage resultPage = statsCaseClinicalLabelDao.getStatsCaseClinicalLabelSearchPage( + page, + request.getLabelName(), + request.handleOrder() + ); + + Map resultMap = new HashMap<>(); + resultMap.put("page", resultPage.getCurrent()); + resultMap.put("pageSize", resultPage.getSize()); + resultMap.put("total", resultPage.getTotal()); + resultMap.put("data", resultPage.getRecords()); + return Response.success(resultMap); + } } diff --git a/src/main/java/com/example/caseData/dao/StatsCaseClinicalLabelDao.java b/src/main/java/com/example/caseData/dao/StatsCaseClinicalLabelDao.java new file mode 100644 index 0000000..3460d80 --- /dev/null +++ b/src/main/java/com/example/caseData/dao/StatsCaseClinicalLabelDao.java @@ -0,0 +1,48 @@ +package com.example.caseData.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.example.caseData.dto.statsCaseClinicalHospital.StatsCaseClinicalHospitalDto; +import com.example.caseData.dto.statsCaseClinicalLabel.StatsCaseClinicalLabelDto; +import com.example.caseData.model.StatsCaseExchangeUserModel; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; + +import java.util.Map; + +@Mapper +public interface StatsCaseClinicalLabelDao extends BaseMapper { + + /** + * 医院病例库推荐-搜索 + * @param page 分页数据 + * @param labelName 疾病标签名称 + * @param order 排序 + */ + IPage getStatsCaseClinicalLabelSearchPage( + Page page, + @Param("labelName") String labelName, + @Param("order") Map order + ); + + /** + * Inc 自增 + * @param field 字段名称 + * @param numeral 增加的数值 + * @return 更新的行数 + */ + @Update("UPDATE stats_case_exchange_label SET ${field} = ${field} + #{numeral} WHERE label_iden = #{labelIden}") + int inc(@Param("labelIden") Long labelIden, @Param("field") String field, @Param("numeral") int numeral); + + /** + * Dec 自减 + * + * @param field 字段名称 + * @param numeral 减少的数值 + * @return 更新的行数 + */ + @Update("UPDATE stats_case_exchange_label SET ${field} = ${field} - #{numeral} WHERE label_iden = #{labelIdenuserId}") + int dec(@Param("labelIden") Long labelIden, @Param("field") String field, @Param("numeral") int numeral); +} diff --git a/src/main/java/com/example/caseData/dto/statsCaseClinicalLabel/StatsCaseClinicalLabelDto.java b/src/main/java/com/example/caseData/dto/statsCaseClinicalLabel/StatsCaseClinicalLabelDto.java new file mode 100644 index 0000000..e0cefee --- /dev/null +++ b/src/main/java/com/example/caseData/dto/statsCaseClinicalLabel/StatsCaseClinicalLabelDto.java @@ -0,0 +1,128 @@ +package com.example.caseData.dto.statsCaseClinicalLabel; + +import cn.hutool.core.bean.BeanUtil; +import com.example.caseData.dto.caseClinicalDoctor.CaseClinicalDoctorDto; +import com.example.caseData.model.StatsCaseClinicalDoctorModel; +import com.example.caseData.model.StatsCaseClinicalLabelModel; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@Data +public class StatsCaseClinicalLabelDto { + /** + * 主键id + */ + @JsonProperty("stats_id") + private String statsId; + + @JsonProperty("label_iden") + private String labelIden; + + @JsonProperty("label_name") + private String labelName; + + /** + * 数量-文章 + */ + @JsonProperty("article_num") + private Integer articleNum = 0; + + /** + * 总阅读量-文章 + */ + @JsonProperty("article_read_num") + private Integer articleReadNum = 0; + + /** + * 总收藏量-文章 + */ + @JsonProperty("article_collect_num") + private Integer articleCollectNum = 0; + + /** + * 最后一篇文章发表时间 + */ + @JsonProperty("last_push_date") + private LocalDateTime lastPushDate; + + /** + * 数量-视频 + */ + @JsonProperty("video_num") + private Integer videoNum = 0; + + /** + * 总阅读量-视频 + */ + @JsonProperty("video_read_num") + private Integer videoReadNum = 0; + + /** + * 总收藏量-视频 + */ + @JsonProperty("video_collect_num") + private Integer videoCollectNum = 0; + + /** + * 创建时间 + */ + @JsonProperty("created_at") + private LocalDateTime createdAt; + + /** + * 修改时间 + */ + @JsonProperty("updated_at") + private LocalDateTime updatedAt; + + /** + * 基础数据-医生 + */ + @JsonProperty("case_clinical_doctor") + private CaseClinicalDoctorDto caseClinicalDoctor; + + /** + * 列表 + */ + public static List GetListDto(List models) { + if (models == null || models.isEmpty()) { + return Collections.emptyList(); + } + + return models.stream() + .map(model -> { + StatsCaseClinicalLabelDto dto = BeanUtil.copyProperties(model, StatsCaseClinicalLabelDto.class); + + // 示例:手动处理字段类型不一致 + if (model.getStatsId() != null) { + dto.setStatsId(String.valueOf(model.getStatsId())); // Long -> String + } + + return dto; + }) + .collect(Collectors.toList()); + } + + /** + * 详情 + */ + public static StatsCaseClinicalLabelDto GetDto(StatsCaseClinicalLabelModel model) { + if (model == null) { + return null; + } + + StatsCaseClinicalLabelDto dto = BeanUtil.copyProperties(model, StatsCaseClinicalLabelDto.class); + + // 示例:手动处理字段类型不一致 + if (model.getStatsId() != null) { + dto.setStatsId(String.valueOf(model.getStatsId())); // Long -> String + } + + return dto; + } +} diff --git a/src/main/java/com/example/caseData/model/StatsCaseClinicalLabelModel.java b/src/main/java/com/example/caseData/model/StatsCaseClinicalLabelModel.java new file mode 100644 index 0000000..7d3855d --- /dev/null +++ b/src/main/java/com/example/caseData/model/StatsCaseClinicalLabelModel.java @@ -0,0 +1,98 @@ +package com.example.caseData.model; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 统计表-病例库-临床-疾病标签实体类 + */ +@Data // Lombok 注解,自动生成 getter/setter 等 +@TableName("`stats_case_clinical_label`") // 指定数据库表名 +public class StatsCaseClinicalLabelModel { + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) // 使用雪花算法生成 ID(适用于分布式系统) + private Long statsId; + + /** + * 疾病标签唯一标识 + */ + @TableField("label_iden") + private String labelIden; + + /** + * 疾病标签名称 + */ + @TableField("label_name") + private String labelName; + + /** + * 数量-文章 + */ + @TableField("article_num") + private Integer articleNum; + + /** + * 总阅读量-文章 + */ + @TableField("article_read_num") + private Integer articleReadNum; + + /** + * 总收藏量-文章 + */ + @TableField("article_collect_num") + private Integer articleCollectNum; + + /** + * 总评论量-文章 + */ + @TableField("article_comment_num") + private Integer articleCommentNum; + + /** + * 最后一篇文章发表时间 + */ + @TableField("last_push_date") + private LocalDateTime lastPushDate; + + /** + * 数量-视频 + */ + @TableField("video_num") + private Integer videoNum; + + /** + * 总阅读量-视频 + */ + @TableField("video_read_num") + private Integer videoReadNum; + + /** + * 总收藏量-视频 + */ + @TableField("video_collect_num") + private Integer videoCollectNum; + + /** + * 总评论量-视频 + */ + @TableField("video_comment_num") + private Integer videoCommentNum; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createdAt; + + /** + * 修改时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updatedAt; +} diff --git a/src/main/java/com/example/caseData/request/caseExchangeRequest/addCaseExchangeVote.java b/src/main/java/com/example/caseData/request/caseExchangeRequest/addCaseExchangeVote.java new file mode 100644 index 0000000..950483e --- /dev/null +++ b/src/main/java/com/example/caseData/request/caseExchangeRequest/addCaseExchangeVote.java @@ -0,0 +1,12 @@ +package com.example.caseData.request.caseExchangeRequest; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +@Data +public class addCaseExchangeVote { + // 父级 次级评论此字段必须存在 + @JsonProperty("option_id") + private String optionId; +} diff --git a/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalArticleSearchPage.java b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalArticleSearchPage.java index 8f6b117..ea477ed 100644 --- a/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalArticleSearchPage.java +++ b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalArticleSearchPage.java @@ -33,6 +33,10 @@ public class getClinicalArticleSearchPage { @JsonProperty("doctor_id") private String doctorId; + // 疾病标签唯一标识 + @JsonProperty("label_iden") + private String labelIden; + // 是否需要数量(0:否 1:是) @JsonProperty("is_need_num") private Integer isNeedNum = 0; diff --git a/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalLabelSearchPage.java b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalLabelSearchPage.java new file mode 100644 index 0000000..f4164f9 --- /dev/null +++ b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalLabelSearchPage.java @@ -0,0 +1,84 @@ +package com.example.caseData.request.clinicalRequest; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Min; +import lombok.Data; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +@Data +public class getClinicalLabelSearchPage { + // ✅ 分页参数 + @Min(value = 1, message = "页码最小为 1") + private Integer page = 1; + + @JsonProperty("page_size") + @Min(value = 1, message = "每页个数最小为 1") + private Integer pageSize = 20; + + // 疾病标签名称 + @JsonProperty("label_name") + private String labelName; + + // 排序字段 + private OrderRequest order; + + /** + * 排序字段嵌套结构体 + */ + @Data + public static class OrderRequest { + @JsonProperty("updated_at") + private String updatedAt; // 更新时间排序 + + @JsonProperty("label_name") + private String labelName; // 医院名称 + + @JsonProperty("article_num") + private String articleNum; // 数量-文章 + + + public Map toMap() { + Map map = new HashMap<>(); + if (StringUtils.hasText(updatedAt)) { + map.put("a.updated_at", updatedAt); + } + + if (StringUtils.hasText(labelName)) { + map.put("b.label_name", labelName); + } + + if (StringUtils.hasText(articleNum)) { + map.put("a.article_num", articleNum); + } + + // 默认排序(如果用户未传递任何排序字段) + if (map.isEmpty()) { + map.put("a.updated_at", "desc"); + } + + return map; + } + } + + /** + * 获取排序字段,若无用户输入则使用默认排序 + */ + public Map handleOrder() { + return order != null ? order.toMap() : new OrderRequest().toMap(); + } + + // ✅ 校验分页参数 + public void validateForPage() { + // 如果 page 为空,设为默认值 1 + if (page == null) { + page = 1; + } + + if (pageSize == null) { + pageSize = 20; + } + } +} diff --git a/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalVideoSearchPage.java b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalVideoSearchPage.java index 729b459..a7184be 100644 --- a/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalVideoSearchPage.java +++ b/src/main/java/com/example/caseData/request/clinicalRequest/getClinicalVideoSearchPage.java @@ -33,6 +33,10 @@ public class getClinicalVideoSearchPage { @JsonProperty("doctor_id") private String doctorId; + // 疾病标签唯一标识 + @JsonProperty("label_iden") + private String labelIden; + // 是否需要数量(0:否 1:是) @JsonProperty("is_need_num") private Integer isNeedNum = 0; diff --git a/src/main/java/com/example/caseData/service/CaseExchangeService.java b/src/main/java/com/example/caseData/service/CaseExchangeService.java index c41203c..394a010 100644 --- a/src/main/java/com/example/caseData/service/CaseExchangeService.java +++ b/src/main/java/com/example/caseData/service/CaseExchangeService.java @@ -495,4 +495,45 @@ public class CaseExchangeService { return true; } + + /** + * 新增投票-病例交流 + * @param exchangeId 病例交流id + * @param userId 用户id + * @return bool + */ + @Transactional + public boolean AddCaseExchangeVote(String exchangeId,String userId,String optionId){ + // 获取病例交流数据 + CaseExchangeModel article = caseExchangeDao.selectById(exchangeId); + if (article == null) { + return false; + } + + // 检测用户是否已收藏过 + UserCollectExchangeModel userCollectExchange = getUserCollectExchangeStatus(exchangeId,userId); + if (userCollectExchange != null) { + return true; + } + + // 新增收藏 + UserCollectExchangeModel userCollectExchangeData = new UserCollectExchangeModel(); + userCollectExchangeData.setUserId(Long.valueOf(userId)); + userCollectExchangeData.setExchangeId(Long.valueOf(exchangeId)); + int res = userCollectExchangeDao.insert(userCollectExchangeData); + if (res <= 0){ + return false; + } + + // 增加病例交流收藏数 + caseExchangeDao.inc(Long.valueOf(exchangeId),"collect_num",1); + + // 增加病例交流总收藏数 + statsCaseExchangeDao.inc(1L,"exchange_collect_num",1); + + // 增加用户交流收藏数 + statsCaseExchangeUserDao.inc(Long.valueOf(userId),"exchange_collect_num",1); + + return true; + } } diff --git a/src/main/resources/mapper/StatsCaseClinicalLabelMapper.xml b/src/main/resources/mapper/StatsCaseClinicalLabelMapper.xml new file mode 100644 index 0000000..fe35f9b --- /dev/null +++ b/src/main/resources/mapper/StatsCaseClinicalLabelMapper.xml @@ -0,0 +1,31 @@ + + + + + \ No newline at end of file