Browse Source

方案制定功能

master
ChaiNingQi 2 months ago
parent
commit
5fcfa28a4c
  1. 25
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysVetAuditController.java
  2. 147
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/TreatmentPlanController.java
  3. 54
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java
  4. 4
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java
  5. 153
      chenhai-system/src/main/java/com/chenhai/vet/domain/FarmerInfo.java
  6. 271
      chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlan.java
  7. 233
      chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlanDetailVO.java
  8. 140
      chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlanMedicine.java
  9. 79
      chenhai-system/src/main/java/com/chenhai/vet/mapper/TreatmentPlanMapper.java
  10. 41
      chenhai-system/src/main/java/com/chenhai/vet/mapper/TreatmentPlanMedicineMapper.java
  11. 15
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java
  12. 102
      chenhai-system/src/main/java/com/chenhai/vet/service/ITreatmentPlanService.java
  13. 241
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/TreatmentPlanServiceImpl.java
  14. 299
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java
  15. 170
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java
  16. 68
      chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml
  17. 156
      chenhai-system/src/main/resources/mapper/vet/TreatmentPlanMapper.xml
  18. 79
      chenhai-system/src/main/resources/mapper/vet/TreatmentPlanMedicineMapper.xml
  19. 1
      chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml
  20. 6
      chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml
  21. 44
      chenhai-ui/src/api/vet/plan.js
  22. 368
      chenhai-ui/src/views/vet/plan/index.vue

25
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysVetAuditController.java

@ -86,16 +86,36 @@ public class SysVetAuditController extends BaseController
/**
* 查询兽医资质列表含证书信息
*/
@PreAuthorize("@ss.hasPermi('vet:qualification:list')")
/**
* 查询兽医资质列表含证书信息
*/
@PreAuthorize("@ss.hasPermi('vet:qualification:list') or @ss.hasRole('manger')")
@GetMapping("/listQualification")
public TableDataInfo listQualification(VetQualification vetQualification)
{
startPage();
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
// 管理员和manger角色可以查看所有数据
if (!SecurityUtils.isAdmin(userId) && !SecurityUtils.hasRole("manger")) {
vetQualification.setUserId(userId);
}
List<VetQualification> list = vetQualificationService.selectVetQualificationList(vetQualification);
// 调试日志
for (VetQualification qualification : list) {
System.out.println("===== 资质信息 =====");
System.out.println("qualificationId: " + qualification.getQualificationId());
System.out.println("auditStatus: " + qualification.getAuditStatus());
System.out.println("auditStatusLabel: " + qualification.getAuditStatusLabel());
System.out.println("certStatus: " + qualification.getCertStatus());
System.out.println("certStatusLabel: " + qualification.getCertStatusLabel());
System.out.println("scopeNames: " + qualification.getScopeNames());
System.out.println("certificateList size: " +
(qualification.getCertificateList() != null ? qualification.getCertificateList().size() : 0));
}
return getDataTable(list);
}
@ -109,5 +129,4 @@ public class SysVetAuditController extends BaseController
vetQualification.setAuditTime(new Date());
return toAjax(vetQualificationService.updateVetQualification(vetQualification));
}
}

147
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/TreatmentPlanController.java

@ -0,0 +1,147 @@
package com.chenhai.web.controller.vet;
import java.util.List;
import com.chenhai.muhu.domain.MuhuConsultationForms;
import com.chenhai.muhu.service.IMuhuConsultationFormsService;
import com.chenhai.system.domain.ConsultationForms;
import com.chenhai.system.service.IConsultationFormsService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.chenhai.common.annotation.Log;
import com.chenhai.common.core.controller.BaseController;
import com.chenhai.common.core.domain.AjaxResult;
import com.chenhai.common.enums.BusinessType;
import com.chenhai.vet.domain.TreatmentPlan;
import com.chenhai.vet.service.ITreatmentPlanService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 治疗方案Controller
*
* @author ruoyi
* @date 2026-02-25
*/
@RestController
@RequestMapping("/vet/plan")
public class TreatmentPlanController extends BaseController {
@Autowired
private ITreatmentPlanService treatmentPlanService;
@Autowired
private IConsultationFormsService consultationFormsService;
@Autowired
private IMuhuConsultationFormsService muhuConsultationFormsService;
/**
* 查询治疗方案列表
*/
@PreAuthorize("@ss.hasPermi('vet:plan:list')")
@GetMapping("/list")
public TableDataInfo list(TreatmentPlan treatmentPlan) {
startPage();
List<TreatmentPlan> list = treatmentPlanService.selectTreatmentPlanList(treatmentPlan);
return getDataTable(list);
}
@GetMapping("/listByConsultationId")
public TableDataInfo listByConsultationId(@RequestParam(required = false) Long consultationId) {
TreatmentPlan treatmentPlan = new TreatmentPlan();
// 如果传了consultationId就按ID查询
if (consultationId != null) {
treatmentPlan.setConsultationId(consultationId);
}
startPage();
List<TreatmentPlan> list = treatmentPlanService.selectTreatmentPlanList(treatmentPlan);
return getDataTable(list);
}
/**
* 导出治疗方案列表
*/
@PreAuthorize("@ss.hasPermi('vet:plan:export')")
@Log(title = "治疗方案", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, TreatmentPlan treatmentPlan) {
List<TreatmentPlan> list = treatmentPlanService.selectTreatmentPlanList(treatmentPlan);
ExcelUtil<TreatmentPlan> util = new ExcelUtil<TreatmentPlan>(TreatmentPlan.class);
util.exportExcel(response, list, "治疗方案数据");
}
/**
* 获取治疗方案详细信息
*/
@PreAuthorize("@ss.hasPermi('vet:plan:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(treatmentPlanService.selectTreatmentPlanById(id));
}
/**
* 新增治疗方案
*/
@PreAuthorize("@ss.hasPermi('vet:plan:add')")
@Log(title = "治疗方案", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TreatmentPlan treatmentPlan) {
return toAjax(treatmentPlanService.insertTreatmentPlan(treatmentPlan));
}
/**
* 修改治疗方案
*/
@PreAuthorize("@ss.hasPermi('vet:plan:edit')")
@Log(title = "治疗方案", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TreatmentPlan treatmentPlan) {
return toAjax(treatmentPlanService.updateTreatmentPlan(treatmentPlan));
}
/**
* 删除治疗方案
*/
@PreAuthorize("@ss.hasPermi('vet:plan:remove')")
@Log(title = "治疗方案", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(treatmentPlanService.deleteTreatmentPlanByIds(ids));
}
/**
* 根据问诊单ID获取预填的治疗方案数据
*/
@GetMapping("/createFromConsultation/{consultationId}")
public AjaxResult createFromConsultation(@PathVariable Long consultationId)
{
// 查询问诊单
MuhuConsultationForms consultation = muhuConsultationFormsService.selectMuhuConsultationFormsByFormId(consultationId);
if (consultation == null) {
return error("问诊单不存在");
}
// 创建治疗方案对象
TreatmentPlan plan = new TreatmentPlan();
plan.setConsultationId(consultationId);
plan.setFarmerName(consultation.getFarmerName()); // 发布者姓名
plan.setAnimalType(consultation.getAnimalType()); // 牲畜种类
plan.setSymptoms(consultation.getDescription()); // 病情描述
// 设置方案标题优先使用问诊单标题没有则自动生成
if (consultation.getTitle() != null && !consultation.getTitle().isEmpty()) {
plan.setTitle(consultation.getTitle());
} else {
plan.setTitle("问诊单" + consultationId + "的治疗方案");
}
// 默认值
plan.setStatus("0"); // 待处理
plan.setTreatmentMethod("0"); // 药物治疗
return success(plan);
}
}

54
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java

@ -3,6 +3,7 @@ package com.chenhai.web.controller.vet;
import com.chenhai.common.annotation.Log;
import com.chenhai.common.core.controller.BaseController;
import com.chenhai.common.core.domain.AjaxResult;
import com.chenhai.common.core.domain.entity.SysUser;
import com.chenhai.common.core.domain.model.LoginUser;
import com.chenhai.common.core.page.TableDataInfo;
import com.chenhai.common.enums.BusinessType;
@ -221,9 +222,6 @@ public class VetPersonalInfoController extends BaseController
return success(info);
}
/**
* 新增兽医个人信息
*/
/**
* 新增兽医个人信息带完整校验
*/
@ -417,6 +415,9 @@ public class VetPersonalInfoController extends BaseController
/**
* 获取当前用户的兽医信息包含资质信息
*/
/**
* 获取当前用户的兽医信息 - 完全兼容若依个人中心
*/
@Log(title = "兽医个人信息", businessType = BusinessType.OTHER)
@PreAuthorize("@ss.hasPermi('vet:info:query')")
@GetMapping("/current")
@ -427,42 +428,33 @@ public class VetPersonalInfoController extends BaseController
return error("用户未登录");
}
Map<String, Object> result = new HashMap<>();
// 1. 获取兽医个人信息
VetPersonalInfo info = vetPersonalInfoService.selectVetPersonalInfoByUserId(userId);
// 1. 获取用户信息若依个人中心需要
SysUser user = userService.selectUserById(userId);
// 2. 获取资质信息
List<VetQualification> qualifications = vetQualificationService.selectQualificationsByUserId(userId);
// 2. 获取兽医信息
VetPersonalInfo vetInfo = vetPersonalInfoService.selectVetPersonalInfoByUserId(userId);
// 3. 如果没有个人信息记录创建空对象
if (info == null) {
info = new VetPersonalInfo();
info.setUserId(userId);
// 3. 如果有兽医信息且头像不为空覆盖用户头像
if (vetInfo != null && StringUtils.isNotEmpty(vetInfo.getAvatar())) {
user.setAvatar(vetInfo.getAvatar());
}
// 4. 如果有资质信息填充到个人信息中
VetQualification latestQualification = null;
if (qualifications != null && !qualifications.isEmpty()) {
latestQualification = qualifications.get(0);
// 填充真实姓名
if (StringUtils.isNotEmpty(latestQualification.getRealName()) &&
StringUtils.isEmpty(info.getRealName())) {
info.setRealName(latestQualification.getRealName());
}
// 填充身份证号
if (StringUtils.isNotEmpty(latestQualification.getIdCard()) &&
StringUtils.isEmpty(info.getIdCard())) {
info.setIdCard(latestQualification.getIdCard());
}
}
// 4. 获取资质信息
List<VetQualification> qualifications = vetQualificationService.selectQualificationsByUserId(userId);
VetQualification latestQualification = qualifications != null && !qualifications.isEmpty()
? qualifications.get(0) : null;
result.put("personalInfo", info);
// 5. 组装返回结果 - 完全兼容若依前端
Map<String, Object> result = new HashMap<>();
result.put("user", user); // 若依个人中心主要读这个
result.put("personalInfo", vetInfo); // 兽医详细信息
result.put("qualification", latestQualification);
result.put("hasQualifications", latestQualification != null);
// 6. 额外添加头像字段确保前端能读到
result.put("avatar", user.getAvatar());
result.put("nickName", user.getNickName());
return success(result);
}

4
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java

@ -444,9 +444,7 @@ public class VetQualificationController extends BaseController
return toAjax(vetQualificationService.deleteVetQualificationByQualificationIds(qualificationIds));
}
/**
* 提交审核
*/
/**
* 提交审核带完整校验不改变原有逻辑
*/

153
chenhai-system/src/main/java/com/chenhai/vet/domain/FarmerInfo.java

@ -0,0 +1,153 @@
package com.chenhai.vet.domain;
import com.chenhai.common.annotation.Excel;
import com.chenhai.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 农牧户信息对象 farmer_info
*
* @author ruoyi
* @date 2026-02-25
*/
public class FarmerInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 农牧户ID */
private Long farmerId;
/** 用户ID(关联sys_user) */
@Excel(name = "用户ID")
private Long userId;
/** 真实姓名 */
@Excel(name = "真实姓名")
private String realName;
/** 联系电话 */
@Excel(name = "联系电话")
private String phone;
/** 身份证号 */
@Excel(name = "身份证号")
private String idCard;
/** 地址 */
@Excel(name = "地址")
private String address;
/** 养殖类型 */
@Excel(name = "养殖类型")
private String farmingType;
/** 养殖规模 */
@Excel(name = "养殖规模")
private String farmingScale;
/** 头像 */
private String avatar;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getFarmerId() {
return farmerId;
}
public void setFarmerId(Long farmerId) {
this.farmerId = farmerId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getFarmingType() {
return farmingType;
}
public void setFarmingType(String farmingType) {
this.farmingType = farmingType;
}
public String getFarmingScale() {
return farmingScale;
}
public void setFarmingScale(String farmingScale) {
this.farmingScale = farmingScale;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("farmerId", getFarmerId())
.append("userId", getUserId())
.append("realName", getRealName())
.append("phone", getPhone())
.append("idCard", getIdCard())
.append("address", getAddress())
.append("farmingType", getFarmingType())
.append("farmingScale", getFarmingScale())
.append("avatar", getAvatar())
.append("status", getStatus())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.toString();
}
}

271
chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlan.java

@ -0,0 +1,271 @@
package com.chenhai.vet.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.chenhai.common.annotation.Excel;
import com.chenhai.common.core.domain.BaseEntity;
import java.util.List;
/**
* 治疗方案对象 treatment_plan
*
* @author ruoyi
* @date 2026-02-25
*/
public class TreatmentPlan extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 推荐的药品列表(非数据库字段) */
private List<TreatmentPlanMedicine> medicineList;
public List<TreatmentPlanMedicine> getMedicineList() {
return medicineList;
}
public void setMedicineList(List<TreatmentPlanMedicine> medicineList) {
this.medicineList = medicineList;
}
/** 方案编号 */
@Excel(name = "方案编号")
private String planNo;
/** 方案标题 */
@Excel(name = "方案标题")
private String title;
/** 农牧户ID(新增) */
private Long farmerId;
/** 农牧户姓名 */
@Excel(name = "农牧户姓名")
private String farmerName;
/** 联系电话 */
@Excel(name = "联系电话")
private String farmerPhone;
/** 动物类型 */
@Excel(name = "动物类型")
private String animalType;
/** 症状描述 */
@Excel(name = "症状描述")
private String symptoms;
/** 诊断结果 */
@Excel(name = "诊断结果")
private String diagnosis;
/** 治疗方式(0药物治疗 1手术治疗 2综合治疗) */
@Excel(name = "治疗方式", readConverterExp = "0=药物治疗,1=手术治疗,2=综合治疗")
private String treatmentMethod;
/** 治疗方案描述 */
@Excel(name = "治疗方案描述")
private String treatmentDesc;
/** 注意事项 */
@Excel(name = "注意事项")
private String precautions;
/** 状态(0待处理 1进行中 2已完成 3已取消) */
@Excel(name = "状态", readConverterExp = "0=待处理,1=进行中,2=已完成,3=已取消")
private String status;
/** 兽医ID(关联sys_user.user_id) */
@Excel(name = "兽医ID", readConverterExp = "关=联sys_user.user_id")
private Long userId;
/** 关联问诊单ID(新增字段) */
@Excel(name = "关联问诊单ID")
private Long consultationId;
/** 删除标志(0正常 1已删除) */
private String delFlag;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setPlanNo(String planNo)
{
this.planNo = planNo;
}
public String getPlanNo()
{
return planNo;
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
public Long getFarmerId() {
return farmerId;
}
public void setFarmerId(Long farmerId) {
this.farmerId = farmerId;
}
public void setFarmerName(String farmerName)
{
this.farmerName = farmerName;
}
public String getFarmerName()
{
return farmerName;
}
public void setFarmerPhone(String farmerPhone)
{
this.farmerPhone = farmerPhone;
}
public String getFarmerPhone()
{
return farmerPhone;
}
public void setAnimalType(String animalType)
{
this.animalType = animalType;
}
public String getAnimalType()
{
return animalType;
}
public void setSymptoms(String symptoms)
{
this.symptoms = symptoms;
}
public String getSymptoms()
{
return symptoms;
}
public void setDiagnosis(String diagnosis)
{
this.diagnosis = diagnosis;
}
public String getDiagnosis()
{
return diagnosis;
}
public void setTreatmentMethod(String treatmentMethod)
{
this.treatmentMethod = treatmentMethod;
}
public String getTreatmentMethod()
{
return treatmentMethod;
}
public void setTreatmentDesc(String treatmentDesc)
{
this.treatmentDesc = treatmentDesc;
}
public String getTreatmentDesc()
{
return treatmentDesc;
}
public void setPrecautions(String precautions)
{
this.precautions = precautions;
}
public String getPrecautions()
{
return precautions;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public Long getConsultationId() {
return consultationId;
}
public void setConsultationId(Long consultationId) {
this.consultationId = consultationId;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("planNo", getPlanNo())
.append("title", getTitle())
.append("farmerName", getFarmerName())
.append("farmerPhone", getFarmerPhone())
.append("animalType", getAnimalType())
.append("symptoms", getSymptoms())
.append("diagnosis", getDiagnosis())
.append("treatmentMethod", getTreatmentMethod())
.append("treatmentDesc", getTreatmentDesc())
.append("precautions", getPrecautions())
.append("status", getStatus())
.append("userId", getUserId())
.append("consultationId", getConsultationId())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("delFlag", getDelFlag())
.append("medicineList", getMedicineList())
.toString();
}
}

233
chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlanDetailVO.java

@ -0,0 +1,233 @@
package com.chenhai.vet.domain;
import com.chenhai.vet.domain.TreatmentPlanMedicine;
import com.chenhai.vet.domain.FarmerInfo;
import java.util.Date;
import java.util.List;
/**
* 治疗方案详情VO
*/
public class TreatmentPlanDetailVO {
/** 主键ID */
private Long id;
/** 方案编号 */
private String planNo;
/** 方案标题 */
private String title;
/** 农牧户ID */
private Long farmerId;
/** 农牧户姓名 */
private String farmerName;
/** 联系电话 */
private String farmerPhone;
/** 动物类型 */
private String animalType;
/** 症状描述 */
private String symptoms;
/** 诊断结果 */
private String diagnosis;
/** 治疗方式 */
private String treatmentMethod;
/** 治疗方案描述 */
private String treatmentDesc;
/** 注意事项 */
private String precautions;
/** 状态 */
private String status;
/** 兽医姓名 */
private String vetName;
/** 关联问诊单ID */
private Long consultationId;
/** 创建时间 */
private Date createTime;
/** 更新时间 */
private Date updateTime;
/** 备注 */
private String remark;
/** 推荐的药品列表 */
private List<TreatmentPlanMedicine> medicineList;
/** 农牧户详细信息 */
private FarmerInfo farmerInfo;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPlanNo() {
return planNo;
}
public void setPlanNo(String planNo) {
this.planNo = planNo;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Long getFarmerId() {
return farmerId;
}
public void setFarmerId(Long farmerId) {
this.farmerId = farmerId;
}
public String getFarmerName() {
return farmerName;
}
public void setFarmerName(String farmerName) {
this.farmerName = farmerName;
}
public String getFarmerPhone() {
return farmerPhone;
}
public void setFarmerPhone(String farmerPhone) {
this.farmerPhone = farmerPhone;
}
public String getAnimalType() {
return animalType;
}
public void setAnimalType(String animalType) {
this.animalType = animalType;
}
public String getSymptoms() {
return symptoms;
}
public void setSymptoms(String symptoms) {
this.symptoms = symptoms;
}
public String getDiagnosis() {
return diagnosis;
}
public void setDiagnosis(String diagnosis) {
this.diagnosis = diagnosis;
}
public String getTreatmentMethod() {
return treatmentMethod;
}
public void setTreatmentMethod(String treatmentMethod) {
this.treatmentMethod = treatmentMethod;
}
public String getTreatmentDesc() {
return treatmentDesc;
}
public void setTreatmentDesc(String treatmentDesc) {
this.treatmentDesc = treatmentDesc;
}
public String getPrecautions() {
return precautions;
}
public void setPrecautions(String precautions) {
this.precautions = precautions;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getVetName() {
return vetName;
}
public void setVetName(String vetName) {
this.vetName = vetName;
}
public Long getConsultationId() {
return consultationId;
}
public void setConsultationId(Long consultationId) {
this.consultationId = consultationId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public List<TreatmentPlanMedicine> getMedicineList() {
return medicineList;
}
public void setMedicineList(List<TreatmentPlanMedicine> medicineList) {
this.medicineList = medicineList;
}
public FarmerInfo getFarmerInfo() {
return farmerInfo;
}
public void setFarmerInfo(FarmerInfo farmerInfo) {
this.farmerInfo = farmerInfo;
}
}

140
chenhai-system/src/main/java/com/chenhai/vet/domain/TreatmentPlanMedicine.java

@ -0,0 +1,140 @@
package com.chenhai.vet.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.chenhai.common.annotation.Excel;
import com.chenhai.common.core.domain.BaseEntity;
import java.math.BigDecimal;
/**
* 治疗方案药品关联对象 treatment_plan_medicine
*
* @author ruoyi
* @date 2026-02-25
*/
public class TreatmentPlanMedicine extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 治疗方案ID */
@Excel(name = "治疗方案ID")
private Long planId;
/** 产品ID(关联vet_product.id) */
@Excel(name = "产品ID")
private Long productId;
/** 用法用量 */
@Excel(name = "用法用量")
private String usageDosage;
/** 疗程天数 */
@Excel(name = "疗程天数")
private Integer courseDays;
/** 推荐数量 */
@Excel(name = "推荐数量")
private Integer quantity;
/** 排序 */
@Excel(name = "排序")
private Integer sortOrder;
/** 产品信息(非数据库字段) */
private VetProduct productInfo;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setPlanId(Long planId)
{
this.planId = planId;
}
public Long getPlanId()
{
return planId;
}
public void setProductId(Long productId)
{
this.productId = productId;
}
public Long getProductId()
{
return productId;
}
public void setUsageDosage(String usageDosage)
{
this.usageDosage = usageDosage;
}
public String getUsageDosage()
{
return usageDosage;
}
public void setCourseDays(Integer courseDays)
{
this.courseDays = courseDays;
}
public Integer getCourseDays()
{
return courseDays;
}
public void setQuantity(Integer quantity)
{
this.quantity = quantity;
}
public Integer getQuantity()
{
return quantity;
}
public void setSortOrder(Integer sortOrder)
{
this.sortOrder = sortOrder;
}
public Integer getSortOrder()
{
return sortOrder;
}
public VetProduct getProductInfo() {
return productInfo;
}
public void setProductInfo(VetProduct productInfo) {
this.productInfo = productInfo;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("planId", getPlanId())
.append("productId", getProductId())
.append("usageDosage", getUsageDosage())
.append("courseDays", getCourseDays())
.append("quantity", getQuantity())
.append("sortOrder", getSortOrder())
.append("createTime", getCreateTime())
.toString();
}
}

79
chenhai-system/src/main/java/com/chenhai/vet/mapper/TreatmentPlanMapper.java

@ -0,0 +1,79 @@
package com.chenhai.vet.mapper;
import java.util.List;
import com.chenhai.vet.domain.TreatmentPlan;
import com.chenhai.vet.domain.TreatmentPlanDetailVO;
import org.apache.ibatis.annotations.Param;
/**
* 治疗方案Mapper接口
*
* @author ruoyi
* @date 2026-02-25
*/
public interface TreatmentPlanMapper
{
/**
* 查询治疗方案
*
* @param id 治疗方案主键
* @return 治疗方案
*/
public TreatmentPlan selectTreatmentPlanById(Long id);
/**
* 查询治疗方案列表
*
* @param treatmentPlan 治疗方案
* @return 治疗方案集合
*/
public List<TreatmentPlan> selectTreatmentPlanList(TreatmentPlan treatmentPlan);
/**
* 新增治疗方案
*
* @param treatmentPlan 治疗方案
* @return 结果
*/
public int insertTreatmentPlan(TreatmentPlan treatmentPlan);
/**
* 修改治疗方案
*
* @param treatmentPlan 治疗方案
* @return 结果
*/
public int updateTreatmentPlan(TreatmentPlan treatmentPlan);
/**
* 删除治疗方案
*
* @param id 治疗方案主键
* @return 结果
*/
public int deleteTreatmentPlanById(Long id);
/**
* 批量删除治疗方案
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteTreatmentPlanByIds(Long[] ids);
/**
* 查询当天最大方案编号
*
* @param dateStr 日期字符串yyyyMMdd
* @return 最大方案编号
*/
public String selectMaxPlanNoByDate(@Param("dateStr") String dateStr);
/**
* 查询治疗方案详情包含个人信息
*
* @param id 治疗方案主键
* @return 治疗方案详情
*/
public TreatmentPlanDetailVO selectTreatmentPlanDetail(Long id);
}

41
chenhai-system/src/main/java/com/chenhai/vet/mapper/TreatmentPlanMedicineMapper.java

@ -0,0 +1,41 @@
package com.chenhai.vet.mapper;
import com.chenhai.vet.domain.TreatmentPlanMedicine;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 治疗方案药品关联Mapper接口
*/
public interface TreatmentPlanMedicineMapper
{
/**
* 新增关联
*/
public int insertTreatmentPlanMedicine(TreatmentPlanMedicine treatmentPlanMedicine);
/**
* 批量新增关联
*/
public int batchInsertTreatmentPlanMedicine(List<TreatmentPlanMedicine> list);
/**
* 根据方案ID查询关联
*/
public List<TreatmentPlanMedicine> selectByPlanId(@Param("planId") Long planId);
/**
* 根据方案ID查询关联带产品信息
*/
public List<TreatmentPlanMedicine> selectByPlanIdWithProduct(@Param("planId") Long planId);
/**
* 根据方案ID删除关联
*/
public int deleteByPlanId(@Param("planId") Long planId);
/**
* 根据方案ID批量删除关联
*/
public int deleteByPlanIds(@Param("planIds") Long[] planIds);
}

15
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java

@ -73,4 +73,19 @@ public interface VetQualificationMapper
VetQualification selectVetQualificationById(Long qualificationId);
/**
* 查询审核状态
*
* @param userId 用户ID
* @return 审核状态
*/
public String selectAuditStatusByUserId(@Param("userId") Long userId);
/**
* 根据用户ID查询资质
*
* @param userId 用户ID
* @return 兽医资质
*/
public VetQualification selectVetQualificationByUserId(@Param("userId") Long userId);
}

102
chenhai-system/src/main/java/com/chenhai/vet/service/ITreatmentPlanService.java

@ -0,0 +1,102 @@
package com.chenhai.vet.service;
import java.util.List;
import com.chenhai.vet.domain.TreatmentPlan;
import com.chenhai.vet.domain.VetProduct;
import com.chenhai.vet.domain.TreatmentPlanDetailVO;
/**
* 治疗方案Service接口
*/
public interface ITreatmentPlanService
{
/**
* 查询治疗方案
*
* @param id 治疗方案主键
* @return 治疗方案
*/
public TreatmentPlan selectTreatmentPlanById(Long id);
/**
* 查询治疗方案详情含药品信息
*
* @param id 治疗方案主键
* @return 治疗方案详情
*/
public TreatmentPlanDetailVO selectTreatmentPlanDetail(Long id);
/**
* 查询治疗方案列表
*
* @param treatmentPlan 治疗方案
* @return 治疗方案集合
*/
public List<TreatmentPlan> selectTreatmentPlanList(TreatmentPlan treatmentPlan);
/**
* 新增治疗方案
*
* @param treatmentPlan 治疗方案
* @return 结果
*/
public int insertTreatmentPlan(TreatmentPlan treatmentPlan);
/**
* 修改治疗方案
*
* @param treatmentPlan 治疗方案
* @return 结果
*/
public int updateTreatmentPlan(TreatmentPlan treatmentPlan);
/**
* 批量删除治疗方案
*
* @param ids 需要删除的治疗方案主键集合
* @return 结果
*/
public int deleteTreatmentPlanByIds(Long[] ids);
/**
* 删除治疗方案信息
*
* @param id 治疗方案主键
* @return 结果
*/
public int deleteTreatmentPlanById(Long id);
/**
* 获取产品列表用于前端选择
* 只返回已上架(status='1')且审核通过(auditStatus='2')的产品
*
* @param keyword 搜索关键词
* @param animalType 动物类型
* @param userId 当前用户ID用于权限控制
* @return 产品列表
*/
public List<VetProduct> getProductList(String keyword, String animalType, Long userId);
/**
* 检查兽医是否有售药资格
*
* @param userId 用户ID
* @return true-有资格false-无资格
*/
public boolean checkVetQualification(Long userId);
/**
* 生成方案编号
*
* @return 方案编号
*/
public String generatePlanNo();
/**
* 查询当天最大方案编号
*
* @param dateStr 日期字符串yyyyMMdd
* @return 最大方案编号
*/
public String selectMaxPlanNoByDate(String dateStr);
}

241
chenhai-system/src/main/java/com/chenhai/vet/service/impl/TreatmentPlanServiceImpl.java

@ -0,0 +1,241 @@
package com.chenhai.vet.service.impl;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import com.chenhai.common.exception.ServiceException;
import com.chenhai.common.utils.DateUtils;
import com.chenhai.common.utils.SecurityUtils;
import com.chenhai.common.utils.StringUtils;
import com.chenhai.vet.domain.TreatmentPlan;
import com.chenhai.vet.domain.TreatmentPlanMedicine;
import com.chenhai.vet.domain.VetProduct;
import com.chenhai.vet.domain.VetQualification;
import com.chenhai.vet.domain.TreatmentPlanDetailVO;
import com.chenhai.vet.mapper.TreatmentPlanMapper;
import com.chenhai.vet.mapper.TreatmentPlanMedicineMapper;
import com.chenhai.vet.mapper.VetProductMapper;
import com.chenhai.vet.mapper.VetQualificationMapper;
import com.chenhai.vet.service.ITreatmentPlanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 治疗方案Service业务层处理
*/
@Service
public class TreatmentPlanServiceImpl implements ITreatmentPlanService
{
@Autowired
private TreatmentPlanMapper treatmentPlanMapper;
@Autowired
private TreatmentPlanMedicineMapper treatmentPlanMedicineMapper;
@Autowired
private VetProductMapper vetProductMapper;
@Autowired
private VetQualificationMapper vetQualificationMapper;
/**
* 查询治疗方案
*/
@Override
public TreatmentPlan selectTreatmentPlanById(Long id)
{
return treatmentPlanMapper.selectTreatmentPlanById(id);
}
/**
* 查询治疗方案详情含药品信息和兽医信息
*/
@Override
public TreatmentPlanDetailVO selectTreatmentPlanDetail(Long id) {
// 1. 查询治疗方案基本信息已关联个人信息
TreatmentPlanDetailVO detail = treatmentPlanMapper.selectTreatmentPlanDetail(id);
if (detail == null) {
return null;
}
// 2. 获取推荐的药品列表
List<TreatmentPlanMedicine> planMedicines = treatmentPlanMedicineMapper.selectByPlanIdWithProduct(id);
detail.setMedicineList(planMedicines);
return detail;
}
/**
* 查询治疗方案列表
*/
@Override
public List<TreatmentPlan> selectTreatmentPlanList(TreatmentPlan treatmentPlan)
{
return treatmentPlanMapper.selectTreatmentPlanList(treatmentPlan);
}
/**
* 新增治疗方案
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertTreatmentPlan(TreatmentPlan treatmentPlan)
{
// 设置当前兽医ID
Long userId = SecurityUtils.getUserId();
treatmentPlan.setUserId(userId);
treatmentPlan.setCreateTime(DateUtils.getNowDate());
// 生成方案编号如果没有提供
if (StringUtils.isEmpty(treatmentPlan.getPlanNo())) {
treatmentPlan.setPlanNo(generatePlanNo());
}
// 保存治疗方案
int rows = treatmentPlanMapper.insertTreatmentPlan(treatmentPlan);
// 如果有关联药品保存药品关联
if (treatmentPlan.getMedicineList() != null && !treatmentPlan.getMedicineList().isEmpty()) {
// 验证兽医资格如果有推荐药品
if (!checkVetQualification(userId)) {
throw new ServiceException("您暂无售药资格,无法推荐药品,请先完成资质认证");
}
for (TreatmentPlanMedicine medicine : treatmentPlan.getMedicineList()) {
medicine.setPlanId(treatmentPlan.getId());
medicine.setCreateTime(DateUtils.getNowDate());
}
treatmentPlanMedicineMapper.batchInsertTreatmentPlanMedicine(treatmentPlan.getMedicineList());
}
return rows;
}
/**
* 修改治疗方案
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateTreatmentPlan(TreatmentPlan treatmentPlan)
{
treatmentPlan.setUpdateTime(DateUtils.getNowDate());
// 先删除原有药品关联
treatmentPlanMedicineMapper.deleteByPlanId(treatmentPlan.getId());
// 重新保存药品关联
if (treatmentPlan.getMedicineList() != null && !treatmentPlan.getMedicineList().isEmpty()) {
for (TreatmentPlanMedicine medicine : treatmentPlan.getMedicineList()) {
medicine.setPlanId(treatmentPlan.getId());
medicine.setCreateTime(DateUtils.getNowDate());
}
treatmentPlanMedicineMapper.batchInsertTreatmentPlanMedicine(treatmentPlan.getMedicineList());
}
return treatmentPlanMapper.updateTreatmentPlan(treatmentPlan);
}
/**
* 批量删除治疗方案
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteTreatmentPlanByIds(Long[] ids)
{
// 删除药品关联
treatmentPlanMedicineMapper.deleteByPlanIds(ids);
// 删除方案
return treatmentPlanMapper.deleteTreatmentPlanByIds(ids);
}
/**
* 删除治疗方案信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteTreatmentPlanById(Long id)
{
// 删除药品关联
treatmentPlanMedicineMapper.deleteByPlanId(id);
// 删除方案
return treatmentPlanMapper.deleteTreatmentPlanById(id);
}
/**
* 获取产品列表用于前端选择
* 只返回已上架(status='1')且审核通过(auditStatus='2')的产品
*/
@Override
public List<VetProduct> getProductList(String keyword, String animalType, Long userId)
{
VetProduct query = new VetProduct();
// 只查询已上架且审核通过的产品
query.setStatus("1"); // 已上架
query.setAuditStatus("2"); // 审核通过
query.setIsDeleted(0); // 未删除
// 关键词搜索
if (StringUtils.isNotEmpty(keyword)) {
query.setName(keyword);
}
// 动物类型筛选如果有
if (StringUtils.isNotEmpty(animalType)) {
query.setTreatAnimals(animalType);
}
// 获取当前用户的店铺产品如果有权限
// 如果不传userId则查询所有商家的产品
if (userId != null) {
// 这里可以根据业务需求决定是否限制为当前用户店铺的产品
// query.setUserId(userId);
}
return vetProductMapper.selectVetProductList(query);
}
/**
* 检查兽医是否有售药资格
*/
@Override
public boolean checkVetQualification(Long userId)
{
VetQualification qualification = vetQualificationMapper.selectVetQualificationByUserId(userId);
return qualification != null && "1".equals(qualification.getAuditStatus());
}
/**
* 生成方案编号
*/
@Override
public String generatePlanNo()
{
String dateStr = DateUtils.dateTimeNow("yyyyMMdd");
String maxNo = treatmentPlanMapper.selectMaxPlanNoByDate(dateStr);
int serial = 1;
if (StringUtils.isNotEmpty(maxNo) && maxNo.length() >= 4) {
try {
serial = Integer.parseInt(maxNo.substring(maxNo.length() - 4)) + 1;
} catch (NumberFormatException e) {
serial = 1;
}
}
return "PLAN" + dateStr + String.format("%04d", serial);
}
/**
* 查询当天最大方案编号
*/
@Override
public String selectMaxPlanNoByDate(String dateStr)
{
return treatmentPlanMapper.selectMaxPlanNoByDate(dateStr);
}
}

299
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java

@ -12,6 +12,7 @@ import com.chenhai.vet.mapper.VetQualificationMapper;
import com.chenhai.vet.service.IVetPersonalInfoService;
import com.chenhai.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import com.chenhai.common.core.redis.RedisCache;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -37,14 +38,19 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
@Autowired
private ISysUserService sysUserService;
@Autowired
private RedisCache redisCache;
/**
* 查询兽医个人信息包含用户信息
* 查询兽医个人信息包含用户信息- 强制头像同步
*/
@Override
public VetPersonalInfo selectVetPersonalInfoById(Long id) {
VetPersonalInfo info = vetPersonalInfoMapper.selectVetPersonalInfoById(id);
// 如果关联查询没有加载用户信息手动加载
if (info != null) {
// 强制填充并同步用户信息
fillUserInfo(info);
}
return info;
}
@ -56,17 +62,19 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
return null;
}
// 2. 获取资质证书信息从资质表查询
List<VetQualification> qualifications = vetQualificationMapper.selectQualificationsByUserId(vetInfo.getUserId());
// 2. 强制同步用户信息
fillUserInfo(vetInfo);
// 3. 获取用户信息
// 3. 获取资质证书信息
List<VetQualification> qualifications = vetQualificationMapper.selectQualificationsByUserId(vetInfo.getUserId());
// 4. 获取用户信息
SysUser user = sysUserService.selectUserById(vetInfo.getUserId());
// 4. 组装返回结果
// 5. 组装返回结果
Map<String, Object> result = new HashMap<>();
result.put("vetInfo", vetInfo);
result.put("qualifications", qualifications); // 这里包含证书信息
result.put("qualifications", qualifications);
result.put("userInfo", user);
return result;
@ -80,12 +88,16 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
return null;
}
// 2. 获取资质证书信息
// 2. 强制同步用户信息
fillUserInfo(vetInfo);
// 3. 获取资质证书信息
List<VetQualification> qualifications = vetQualificationMapper.selectQualificationsByUserId(userId);
// 3. 获取用户信息
// 4. 获取用户信息
SysUser user = sysUserService.selectUserById(userId);
// 4. 组装返回结果
// 5. 组装返回结果
Map<String, Object> result = new HashMap<>();
result.put("vetInfo", vetInfo);
result.put("qualifications", qualifications);
@ -93,24 +105,82 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
return result;
}
/**
* 查询兽医个人信息列表包含用户信息
* 查询兽医个人信息列表包含用户信息- 强制头像同步
*/
@Override
public List<VetPersonalInfo> selectVetPersonalInfoList(VetPersonalInfo vetPersonalInfo) {
// 1. 先查询原始数据
List<VetPersonalInfo> list = vetPersonalInfoMapper.selectVetPersonalInfoList(vetPersonalInfo);
// 为每个记录填充用户信息
if (list != null) {
list.forEach(this::fillUserInfo);
// 2. 强制为每个记录同步头像
if (list != null && !list.isEmpty()) {
for (VetPersonalInfo info : list) {
try {
// 直接调用同步方法
syncAvatarFromUser(info);
} catch (Exception e) {
System.err.println("同步头像失败,ID: " + info.getId() + ", 错误: " + e.getMessage());
}
}
}
return list;
}
/**
* 新增兽医个人信息
* 专门的头像同步方法 - 直接从用户表同步头像到兽医表
*/
private void syncAvatarFromUser(VetPersonalInfo vetInfo) {
if (vetInfo == null || vetInfo.getUserId() == null) {
return;
}
// 1. 查询用户信息
SysUser user = sysUserService.selectUserById(vetInfo.getUserId());
if (user == null || StringUtils.isEmpty(user.getAvatar())) {
return;
}
// 2. 判断是否需要更新
boolean needUpdate = false;
if (StringUtils.isEmpty(vetInfo.getAvatar()) ||
!user.getAvatar().equals(vetInfo.getAvatar())) {
needUpdate = true;
}
// 3. 更新兽医表
if (needUpdate) {
VetPersonalInfo updateInfo = new VetPersonalInfo();
updateInfo.setId(vetInfo.getId());
updateInfo.setAvatar(user.getAvatar());
updateInfo.setUpdateTime(DateUtils.getNowDate());
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
updateInfo.setUpdateBy(loginUser.getUsername());
}
int result = vetPersonalInfoMapper.updateVetPersonalInfo(updateInfo);
if (result > 0) {
// 4. 更新当前对象的头像
vetInfo.setAvatar(user.getAvatar());
System.out.println("头像同步成功 - 兽医ID: " + vetInfo.getId() +
", 用户ID: " + vetInfo.getUserId() +
", 头像: " + user.getAvatar());
}
} else {
// 即使不需要更新也要确保返回对象中有头像
if (StringUtils.isEmpty(vetInfo.getAvatar()) && StringUtils.isNotEmpty(user.getAvatar())) {
vetInfo.setAvatar(user.getAvatar());
}
}
// 5. 设置用户信息
vetInfo.setUser(user);
}
/**
* 新增兽医个人信息Service层校验
* 新增兽医个人信息
*/
@Override
@Transactional
@ -146,12 +216,11 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
vetPersonalInfo.setCreateBy(loginUser.getUsername());
vetPersonalInfo.setUpdateBy(loginUser.getUsername());
// 5. 从用户表获取其他信息
// 5. 从用户表获取信息优先使用用户表数据
SysUser currentUser = sysUserService.selectUserById(loginUser.getUserId());
if (currentUser != null) {
// 如果头像为空使用用户头像
if (StringUtils.isEmpty(vetPersonalInfo.getAvatar())
&& StringUtils.isNotEmpty(currentUser.getAvatar())) {
// 头像强制使用用户表头像
if (StringUtils.isNotEmpty(currentUser.getAvatar())) {
vetPersonalInfo.setAvatar(currentUser.getAvatar());
}
// 如果昵称为空使用用户昵称
@ -180,14 +249,17 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
vetPersonalInfo.setCreateTime(DateUtils.getNowDate());
vetPersonalInfo.setUpdateTime(DateUtils.getNowDate());
return vetPersonalInfoMapper.insertVetPersonalInfo(vetPersonalInfo);
int result = vetPersonalInfoMapper.insertVetPersonalInfo(vetPersonalInfo);
// 7. 新增时不同步头像到用户表以用户表为准
return result;
} else {
throw new RuntimeException("用户未登录");
}
}
/**
* 修改兽医个人信息双向同步
* 修改兽医个人信息
*/
@Override
@Transactional
@ -195,32 +267,26 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
// 1. 验证权限确保当前用户只能修改自己的信息
VetPersonalInfo existing = vetPersonalInfoMapper.selectVetPersonalInfoById(vetPersonalInfo.getId());
if (existing != null && !existing.getUserId().equals(loginUser.getUserId())) {
throw new RuntimeException("无权限修改其他用户的兽医信息");
}
// 2. 检查头像是否变化
String newAvatar = vetPersonalInfo.getAvatar();
String oldAvatar = existing != null ? existing.getAvatar() : null;
boolean avatarChanged = newAvatar != null && !newAvatar.equals(oldAvatar);
// 3. 强制绑定当前登录用户ID
vetPersonalInfo.setUserId(loginUser.getUserId());
// 4. 设置更新者
vetPersonalInfo.setUpdateBy(loginUser.getUsername());
// 5. 设置更新时间
vetPersonalInfo.setUpdateTime(DateUtils.getNowDate());
// 6. 更新兽医信息
int result = vetPersonalInfoMapper.updateVetPersonalInfo(vetPersonalInfo);
// 7. 如果头像有变化同步到用户表
if (result > 0 && avatarChanged && newAvatar != null && !newAvatar.isEmpty()) {
// 头像同步并刷新缓存
if (result > 0 && avatarChanged && StringUtils.isNotEmpty(newAvatar)) {
syncAvatarToUserTable(loginUser.getUserId(), newAvatar);
refreshUserCache(loginUser); // 刷新缓存
}
return result;
@ -229,38 +295,66 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
}
}
/**
* 刷新用户缓存 - 使用RedisCache
*/
private void refreshUserCache(LoginUser loginUser) {
try {
// 重新查询用户信息
SysUser updatedUser = sysUserService.selectUserById(loginUser.getUserId());
if (updatedUser != null) {
// 更新LoginUser对象
loginUser.setUser(updatedUser);
// 获取token
String token = loginUser.getToken();
// 刷新Redis缓存 - 若依的缓存key格式
String tokenKey = "login_tokens:" + token;
// 重新存入Redis覆盖旧数据
redisCache.setCacheObject(tokenKey, loginUser);
System.out.println("Redis缓存刷新成功 - 用户ID: " + loginUser.getUserId() + ", tokenKey: " + tokenKey);
}
} catch (Exception e) {
System.err.println("Redis缓存刷新失败: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 同步头像到用户表
*/
private void syncAvatarToUserTable(Long userId, String avatar) {
if (userId == null || StringUtils.isEmpty(avatar)) {
return;
}
try {
SysUser user = sysUserService.selectUserById(userId);
if (user != null) {
// 检查是否需要更新
// 只要兽医头像和用户头像不一致就以兽医表为准更新用户表
if (!avatar.equals(user.getAvatar())) {
// 调用正确的方法签名
boolean success = sysUserService.updateUserAvatar(userId, avatar);
if (success) {
System.out.println("头像同步到用户表成功,用户ID: " + userId);
System.out.println("头像同步成功 - 用户ID: " + userId + ", 头像: " + avatar);
} else {
System.err.println("头像同步到用户表失败,用户ID: " + userId);
System.err.println("头像同步失败 - 用户ID: " + userId);
}
}
}
} catch (Exception e) {
System.err.println("双向同步头像失败: " + e.getMessage());
System.err.println("头像同步异常 - 用户ID: " + userId + ", 错误: " + e.getMessage());
}
}
@Override
public int auditVetPersonalInfo(VetPersonalInfo vetPersonalInfo) {
return vetPersonalInfoMapper.auditVetPersonalInfo(vetPersonalInfo);
}
/**
* 根据用户ID查询兽医个人信息
* 根据用户ID查询兽医个人信息 - 强制头像同步
*/
@Override
public VetPersonalInfo selectVetPersonalInfoByUserId(Long userId) {
@ -269,7 +363,10 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
}
VetPersonalInfo info = vetPersonalInfoMapper.selectVetPersonalInfoByUserId(userId);
if (info != null) {
// 强制填充并同步用户信息
fillUserInfo(info);
}
return info;
}
@ -280,7 +377,7 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
public Map<String, Object> getVetFullInfo(Long vetId) {
Map<String, Object> result = new HashMap<>();
// 1. 获取兽医个人信息包含用户信息
// 1. 获取兽医个人信息包含用户信息- 已强制同步头像
VetPersonalInfo personalInfo = this.selectVetPersonalInfoById(vetId);
if (personalInfo == null) {
return result;
@ -350,7 +447,7 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
public Map<String, Object> getVetFullInfoByUserId(Long userId) {
Map<String, Object> result = new HashMap<>();
// 1. 获取兽医个人信息包含用户信息
// 1. 获取兽医个人信息包含用户信息- 已强制同步头像
VetPersonalInfo personalInfo = this.selectVetPersonalInfoByUserId(userId);
if (personalInfo == null) {
// 如果没有兽医信息只返回用户信息
@ -439,111 +536,57 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService {
}
/**
* 填充用户信息到兽医信息中
* 填充用户信息到兽医信息中 - 强制头像同步
* 核心方法确保兽医表头像与用户表保持一致
*/
private void fillUserInfo(VetPersonalInfo vetInfo) {
if (vetInfo != null && vetInfo.getUser() == null && vetInfo.getUserId() != null) {
try {
SysUser user = sysUserService.selectUserById(vetInfo.getUserId());
vetInfo.setUser(user);
// 检查是否需要同步到数据库
boolean needUpdate = false;
// 用户表 兽医表同步如果兽医表的nickName与用户表不一致
if (user.getNickName() != null && !user.getNickName().equals(vetInfo.getNickName())) {
vetInfo.setNickName(user.getNickName());
needUpdate = true;
}
// 同步头像 - 新增
if ((vetInfo.getAvatar() == null || vetInfo.getAvatar().isEmpty())
&& user.getAvatar() != null && !user.getAvatar().isEmpty()) {
vetInfo.setAvatar(user.getAvatar());
needUpdate = true;
}
// 如果邮箱为空使用用户邮箱
if ((vetInfo.getEmail() == null || vetInfo.getEmail().isEmpty()) && user.getEmail() != null) {
vetInfo.setEmail(user.getEmail());
needUpdate = true;
}
// 如果电话为空使用用户手机号
if ((vetInfo.getPhone() == null || vetInfo.getPhone().isEmpty()) && user.getPhonenumber() != null) {
vetInfo.setPhone(user.getPhonenumber());
needUpdate = true;
}
// 如果需要更新同步到数据库
if (needUpdate) {
syncVetInfoFromUser(vetInfo);
}
} catch (Exception e) {
System.err.println("填充用户信息失败,用户ID: " + vetInfo.getUserId() + ", 错误: " + e.getMessage());
}
if (vetInfo != null && vetInfo.getUserId() != null) {
// 直接调用头像同步方法
syncAvatarFromUser(vetInfo);
}
}
/**
* 从用户信息同步到兽医表
* 手动同步所有兽医信息的头像用于修复历史数据
* 可通过Controller调用此方法修复已有数据
*/
private void syncVetInfoFromUser(VetPersonalInfo vetInfo) {
if (vetInfo == null || vetInfo.getId() == null) {
return;
}
@Transactional
public void syncAllVetAvatars() {
VetPersonalInfo query = new VetPersonalInfo();
List<VetPersonalInfo> list = vetPersonalInfoMapper.selectVetPersonalInfoList(query);
System.out.println("开始批量同步兽医头像,总记录数: " + list.size());
int successCount = 0;
for (VetPersonalInfo vetInfo : list) {
if (vetInfo.getUserId() != null) {
try {
// 只更新需要同步的字段
SysUser user = sysUserService.selectUserById(vetInfo.getUserId());
if (user != null && StringUtils.isNotEmpty(user.getAvatar())) {
// 如果兽医表头像为空或不同强制更新
if (StringUtils.isEmpty(vetInfo.getAvatar())
|| !user.getAvatar().equals(vetInfo.getAvatar())) {
VetPersonalInfo updateInfo = new VetPersonalInfo();
updateInfo.setId(vetInfo.getId());
updateInfo.setAvatar(user.getAvatar());
updateInfo.setUpdateTime(DateUtils.getNowDate());
if (vetInfo.getNickName() != null) {
updateInfo.setNickName(vetInfo.getNickName());
int result = vetPersonalInfoMapper.updateVetPersonalInfo(updateInfo);
if (result > 0) {
successCount++;
System.out.println("同步头像成功 - 兽医ID: " + vetInfo.getId() +
", 用户ID: " + vetInfo.getUserId());
}
if (vetInfo.getEmail() != null) {
updateInfo.setEmail(vetInfo.getEmail());
}
if (vetInfo.getPhone() != null) {
updateInfo.setPhone(vetInfo.getPhone());
}
// 同步头像
if (vetInfo.getAvatar() != null) {
updateInfo.setAvatar(vetInfo.getAvatar());
}
// 设置更新时间
updateInfo.setUpdateTime(DateUtils.getNowDate());
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
updateInfo.setUpdateBy(loginUser.getUsername());
}
vetPersonalInfoMapper.updateVetPersonalInfo(updateInfo);
System.out.println("已同步用户信息到兽医表,兽医ID: " + vetInfo.getId());
} catch (Exception e) {
System.err.println("同步用户信息到兽医表失败,兽医ID: " + vetInfo.getId() + ", 错误: " + e.getMessage());
System.err.println("同步头像失败 - 兽医ID: " + vetInfo.getId() +
", 错误: " + e.getMessage());
}
}
/**
* 同步更新用户昵称
*/
private void syncUserNickName(Long userId, String realName) {
if (userId == null || realName == null) {
return;
}
try {
SysUser user = sysUserService.selectUserById(userId);
if (user != null && !realName.equals(user.getNickName())) {
user.setNickName(realName);
sysUserService.updateUser(user);
}
} catch (Exception e) {
// 记录日志但不要影响主流程
System.err.println("同步用户昵称失败,用户ID: " + userId + ", 错误: " + e.getMessage());
}
System.out.println("批量同步完成,成功: " + successCount + " 条");
}
}

170
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java

@ -44,15 +44,103 @@ public class VetQualificationServiceImpl implements IVetQualificationService {
/**
* 查询兽医资质列表
*/
// VetQualificationServiceImpl 中修改 selectVetQualificationList 方法
@Override
public List<VetQualification> selectVetQualificationList(VetQualification vetQualification) {
List<VetQualification> list = vetQualificationMapper.selectVetQualificationList(vetQualification);
for (VetQualification qualification : list) {
processQualificationInfo(qualification);
// 确保解析certificatesJson到certificateList
if (StringUtils.isNotEmpty(qualification.getCertificatesJson())) {
try {
List<VetQualification.CertificateInfo> certificateList = parseCertificateInfoList(qualification.getCertificatesJson());
qualification.setCertificateList(certificateList);
} catch (Exception e) {
log.error("解析证书JSON失败, qualificationId: {}", qualification.getQualificationId(), e);
qualification.setCertificateList(new ArrayList<>());
}
}
}
return list;
}
/**
* 解析证书JSON到CertificateInfo列表
*/
/**
* 解析证书JSON到CertificateInfo列表
*/
private List<VetQualification.CertificateInfo> parseCertificateInfoList(String certificatesJson) throws Exception {
List<Map<String, Object>> certMaps = objectMapper.readValue(
certificatesJson,
objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)
);
List<VetQualification.CertificateInfo> certificateList = new ArrayList<>();
for (Map<String, Object> certMap : certMaps) {
VetQualification.CertificateInfo cert = new VetQualification.CertificateInfo();
// 设置证书ID
Long certId = extractLongFromObject(certMap.get("certId"));
cert.setCertificateId(certId != null ? certId : generateCertificateId());
// 设置基本字段
cert.setCertName((String) certMap.get("certName"));
cert.setCertificateNo((String) certMap.get("certificateNo"));
cert.setIssueOrg((String) certMap.get("issueOrg"));
cert.setCertificateFiles((String) certMap.get("certificateFiles"));
// 解析日期
cert.setIssueDate(parseDate(certMap.get("issueDate")));
cert.setExpireDate(parseDate(certMap.get("expireDate")));
// 计算证书状态
String certStatus = calculateCertificateStatus(cert.getExpireDate());
cert.setCertStatus(certStatus);
certificateList.add(cert);
}
return certificateList;
}
/**
* 获取证书状态标签
*/
private String getCertStatusLabel(String certStatus) {
if (certStatus == null) return "未知";
switch (certStatus) {
case "0": return "正常";
case "1": return "即将过期";
case "2": return "已过期";
default: return "未知";
}
}
/**
* 获取审核状态标签
*/
private String getAuditStatusLabel(String auditStatus) {
if (auditStatus == null) return "未知";
switch (auditStatus) {
case "0": return "待审核";
case "1": return "审核通过";
case "2": return "审核不通过";
default: return "未知";
}
}
/**
* 获取资格类型标签
*/
private String getQualificationTypeLabel(String qualificationType) {
if (qualificationType == null) return "未知";
switch (qualificationType) {
case "1": return "执业兽医师";
case "2": return "执业助理兽医师";
case "3": return "乡村兽医";
default: return "未知";
}
}
/**
* 查询兽医资质
*/
@ -173,6 +261,9 @@ public class VetQualificationServiceImpl implements IVetQualificationService {
*/
private void changeRoleToVet(Long userId) {
try {
System.out.println("========== changeRoleToVet 被调用了 ==========");
System.out.println("userId = " + userId);
System.out.println("当前时间 = " + new Date());
// 1. 先删除兽医未审核角色
String deleteUnapprovedSql = "DELETE FROM sys_user_role WHERE user_id = ? AND role_id = 6";
jdbcTemplate.update(deleteUnapprovedSql, userId);
@ -418,18 +509,62 @@ public class VetQualificationServiceImpl implements IVetQualificationService {
/**
* 处理资质信息填充经营范围名称更新证书状态
*/
/**
* 处理资质信息填充经营范围名称更新证书状态解析证书列表
*/
private void processQualificationInfo(VetQualification qualification) {
// 处理经营范围名称scope_ids转scope_names
if ((qualification.getScopeNames() == null || qualification.getScopeNames().isEmpty())
&& qualification.getScopeIds() != null && !qualification.getScopeIds().isEmpty()) {
// 1. 处理经营范围名称
if (StringUtils.isNotEmpty(qualification.getScopeIds())) {
String scopeNames = getScopeNamesFromDict(qualification.getScopeIds());
qualification.setScopeNames(scopeNames);
qualification.setScopeNamesLabel(scopeNames); // 设置标签字段
}
// 更新证书状态
updateCertificateStatus(qualification);
// 2. 解析证书JSON到证书列表
if (StringUtils.isNotEmpty(qualification.getCertificatesJson())) {
try {
List<VetQualification.CertificateInfo> certificateList = parseCertificateInfoList(qualification.getCertificatesJson());
qualification.setCertificateList(certificateList);
// 3. 更新每个证书的状态
String firstCertStatus = "0"; // 默认正常
Date today = new Date();
for (VetQualification.CertificateInfo cert : certificateList) {
String certStatus = calculateCertificateStatus(cert.getExpireDate());
cert.setCertStatus(certStatus);
// 记录第一个证书的状态用于主表显示
if (cert == certificateList.get(0)) {
firstCertStatus = certStatus;
}
}
// 4. 设置主表的证书状态用于列表显示
qualification.setCertStatus(firstCertStatus);
qualification.setCertStatusLabel(getCertStatusLabel(firstCertStatus));
} catch (Exception e) {
log.error("解析证书JSON失败, qualificationId: {}", qualification.getQualificationId(), e);
qualification.setCertificateList(new ArrayList<>());
qualification.setCertStatus("0");
qualification.setCertStatusLabel("正常");
}
} else {
qualification.setCertificateList(new ArrayList<>());
qualification.setCertStatus("0");
qualification.setCertStatusLabel("正常");
}
// 5. 设置审核状态标签
qualification.setAuditStatusLabel(getAuditStatusLabel(qualification.getAuditStatus()));
// 6. 设置资格类型标签
qualification.setQualificationTypeLabel(getQualificationTypeLabel(qualification.getQualificationType()));
}
/**
* 准备保存前的资质数据
*/
@ -619,18 +754,36 @@ public class VetQualificationServiceImpl implements IVetQualificationService {
}
/**
* 从字典表根据scope_ids获取scope_names
* 从字典表根据scope_ids获取scope_names增强版
*/
private String getScopeNamesFromDict(String scopeIds) {
if (StringUtils.isEmpty(scopeIds)) {
return "";
}
try {
// 处理JSON数组格式
if (scopeIds.trim().startsWith("[")) {
try {
List<String> scopeIdList = objectMapper.readValue(scopeIds, List.class);
scopeIds = String.join(",", scopeIdList);
} catch (Exception e) {
// 忽略继续处理
}
}
// 处理逗号分隔的字符串
String[] idArray = scopeIds.split(",");
List<String> cleanedIds = new ArrayList<>();
for (String id : idArray) {
if (StringUtils.isNotEmpty(id.trim())) {
cleanedIds.add("'" + id.trim() + "'");
}
}
if (cleanedIds.isEmpty()) {
return "";
}
String inCondition = String.join(",", cleanedIds);
String sql = "SELECT dict_label FROM sys_dict_data " +
@ -644,6 +797,11 @@ public class VetQualificationServiceImpl implements IVetQualificationService {
scopeIds);
return String.join(",", names);
} catch (Exception e) {
log.error("获取经营范围名称失败, scopeIds: {}", scopeIds, e);
return "";
}
}
/**

68
chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml

@ -127,48 +127,44 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectSysMedicineRecommendationVo"/>
<where>
<!-- 原有的条件保持不变 -->
<if test="medicineName != null and medicineName != ''"> and medicine_name like concat('%', #{medicineName}, '%')</if>
<if test="medicineType != null and medicineType != ''"> and medicine_type = #{medicineType}</if>
<if test="specification != null and specification != ''"> and specification = #{specification}</if>
<if test="price != null "> and price = #{price}</if>
<if test="originalPrice != null "> and original_price = #{originalPrice}</if>
<if test="soldQuantity != null "> and sold_quantity = #{soldQuantity}</if>
<if test="indications != null and indications != ''"> and indications = #{indications}</if>
<if test="usageDosage != null and usageDosage != ''"> and usage_dosage = #{usageDosage}</if>
<if test="precautions != null and precautions != ''"> and precautions = #{precautions}</if>
<if test="storageMethod != null and storageMethod != ''"> and storage_method = #{storageMethod}</if>
<if test="expiryDate != null and expiryDate != ''"> and expiry_date = #{expiryDate}</if>
<if test="createdAt != null "> and created_at = #{createdAt}</if>
<if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
<if test="manufacturer != null and manufacturer != ''"> and manufacturer like concat('%', #{manufacturer}, '%')</if>
<if test="salesType != null and salesType != ''"> and sales_type = #{salesType}</if>
<if test="expertId != null "> and expert_id = #{expertId}</if>
<if test="recommendReason != null and recommendReason != ''"> and recommend_reason like concat('%', #{recommendReason}, '%')</if>
<if test="recommendTime != null "> and recommend_time = #{recommendTime}</if>
<if test="storeName != null and storeName != ''"> and store_name like concat('%', #{storeName}, '%')</if>
<if test="storeAddress != null and storeAddress != ''"> and store_address like concat('%', #{storeAddress}, '%')</if>
<if test="images != null and images != ''"> and images like concat('%', #{images}, '%')</if>
<if test="imageUrl != null and imageUrl != ''"> and image_url like concat('%', #{imageUrl}, '%')</if>
<if test="medicineName != null and medicineName != ''"> and m.medicine_name like concat('%', #{medicineName}, '%')</if>
<if test="medicineType != null and medicineType != ''"> and m.medicine_type = #{medicineType}</if>
<if test="specification != null and specification != ''"> and m.specification = #{specification}</if>
<if test="price != null "> and m.price = #{price}</if>
<if test="originalPrice != null "> and m.original_price = #{originalPrice}</if>
<if test="soldQuantity != null "> and m.sold_quantity = #{soldQuantity}</if>
<if test="indications != null and indications != ''"> and m.indications = #{indications}</if>
<if test="usageDosage != null and usageDosage != ''"> and m.usage_dosage = #{usageDosage}</if>
<if test="precautions != null and precautions != ''"> and m.precautions = #{precautions}</if>
<if test="storageMethod != null and storageMethod != ''"> and m.storage_method = #{storageMethod}</if>
<if test="expiryDate != null and expiryDate != ''"> and m.expiry_date = #{expiryDate}</if>
<if test="createdAt != null "> and m.created_at = #{createdAt}</if>
<if test="updatedAt != null "> and m.updated_at = #{updatedAt}</if>
<if test="manufacturer != null and manufacturer != ''"> and m.manufacturer like concat('%', #{manufacturer}, '%')</if>
<if test="salesType != null and salesType != ''"> and m.sales_type = #{salesType}</if>
<if test="expertId != null "> and m.expert_id = #{expertId}</if>
<if test="recommendReason != null and recommendReason != ''"> and m.recommend_reason like concat('%', #{recommendReason}, '%')</if>
<if test="recommendTime != null "> and m.recommend_time = #{recommendTime}</if>
<if test="storeName != null and storeName != ''"> and m.store_name like concat('%', #{storeName}, '%')</if>
<if test="storeAddress != null and storeAddress != ''"> and m.store_address like concat('%', #{storeAddress}, '%')</if>
<if test="images != null and images != ''"> and m.images like concat('%', #{images}, '%')</if>
<if test="imageUrl != null and imageUrl != ''"> and m.image_url like concat('%', #{imageUrl}, '%')</if>
<!-- 新增搜索关键词条件 -->
<if test="searchKeywords != null and searchKeywords != ''">
and (
medicine_name like concat('%', #{searchKeywords}, '%')
or indications like concat('%', #{searchKeywords}, '%')
or manufacturer like concat('%', #{searchKeywords}, '%')
or store_name like concat('%', #{searchKeywords}, '%')
or usage_dosage like concat('%', #{searchKeywords}, '%')
or e.real_name like concat('%', #{searchKeywords}, '%') <!-- 搜索专家姓名 -->
or e.title like concat('%', #{searchKeywords}, '%') <!-- 搜索专家职称 -->
m.medicine_name like concat('%', #{searchKeywords}, '%')
or m.indications like concat('%', #{searchKeywords}, '%')
or m.manufacturer like concat('%', #{searchKeywords}, '%')
or m.store_name like concat('%', #{searchKeywords}, '%')
or m.usage_dosage like concat('%', #{searchKeywords}, '%')
or e.real_name like concat('%', #{searchKeywords}, '%')
or e.title like concat('%', #{searchKeywords}, '%')
)
</if>
</where>
<!-- 动态排序,默认按更新时间降序 -->
<if test="orderByColumn != null and orderByColumn != ''">
ORDER BY ${orderByColumn} ${orderDirection}
</if>
<if test="orderByColumn == null or orderByColumn == ''">
ORDER BY updated_at DESC
</if>
ORDER BY
m.created_at DESC,
m.id DESC
</select>
<select id="selectSysMedicineRecommendationById" parameterType="Long" resultMap="SysMedicineRecommendationResult">

156
chenhai-system/src/main/resources/mapper/vet/TreatmentPlanMapper.xml

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.vet.mapper.TreatmentPlanMapper">
<resultMap type="TreatmentPlan" id="TreatmentPlanResult">
<result property="id" column="id"/>
<result property="planNo" column="plan_no"/>
<result property="title" column="title"/>
<result property="farmerId" column="farmer_id"/>
<result property="farmerName" column="farmer_name"/>
<result property="farmerPhone" column="farmer_phone"/>
<result property="animalType" column="animal_type"/>
<result property="symptoms" column="symptoms"/>
<result property="diagnosis" column="diagnosis"/>
<result property="treatmentMethod" column="treatment_method"/>
<result property="treatmentDesc" column="treatment_desc"/>
<result property="precautions" column="precautions"/>
<result property="status" column="status"/>
<result property="userId" column="user_id"/>
<result property="consultationId" column="consultation_id"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
<result property="delFlag" column="del_flag"/>
</resultMap>
<!-- 带农牧户信息的 resultMap -->
<resultMap type="TreatmentPlan" id="TreatmentPlanWithFarmerResult" extends="TreatmentPlanResult">
<association property="farmerInfo" javaType="FarmerInfo"
column="farmer_id" select="com.chenhai.vet.mapper.FarmerMapper.selectFarmerById"/>
</resultMap>
<sql id="selectTreatmentPlanVo">
select id, plan_no, title, farmer_id, farmer_name, farmer_phone, animal_type,
symptoms, diagnosis, treatment_method, treatment_desc, precautions,
status, user_id, consultation_id, create_time, update_time, remark, del_flag
from treatment_plan
</sql>
<select id="selectTreatmentPlanList" parameterType="TreatmentPlan" resultMap="TreatmentPlanResult">
<include refid="selectTreatmentPlanVo"/>
<where>
<if test="planNo != null and planNo != ''"> and plan_no = #{planNo}</if>
<if test="treatmentMethod != null and treatmentMethod != ''">
and treatment_method like concat('%', #{treatmentMethod}, '%')
</if>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="farmerName != null and farmerName != ''"> and farmer_name like concat('%', #{farmerName}, '%')</if>
<if test="farmerPhone != null and farmerPhone != ''"> and farmer_phone = #{farmerPhone}</if>
<if test="animalType != null and animalType != ''"> and animal_type = #{animalType}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="userId != null"> and user_id = #{userId}</if>
<if test="consultationId != null"> and consultation_id = #{consultationId}</if>
and del_flag = '0'
</where>
order by create_time desc
</select>
<select id="selectTreatmentPlanById" parameterType="Long" resultMap="TreatmentPlanResult">
<include refid="selectTreatmentPlanVo"/>
where id = #{id}
</select>
<select id="selectTreatmentPlanDetail" parameterType="Long" resultMap="TreatmentPlanWithFarmerResult">
<include refid="selectTreatmentPlanVo"/>
where id = #{id}
</select>
<select id="selectMaxPlanNoByDate" parameterType="String" resultType="String">
select plan_no from treatment_plan
where plan_no like concat('PLAN', #{dateStr}, '%')
and del_flag = '0'
order by plan_no desc limit 1
</select>
<insert id="insertTreatmentPlan" parameterType="TreatmentPlan" useGeneratedKeys="true" keyProperty="id">
insert into treatment_plan
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="planNo != null">plan_no,</if>
<if test="title != null">title,</if>
<if test="farmerId != null">farmer_id,</if>
<if test="farmerName != null">farmer_name,</if>
<if test="farmerPhone != null">farmer_phone,</if>
<if test="animalType != null">animal_type,</if>
<if test="symptoms != null">symptoms,</if>
<if test="diagnosis != null">diagnosis,</if>
<if test="treatmentMethod != null">treatment_method,</if>
<if test="treatmentDesc != null">treatment_desc,</if>
<if test="precautions != null">precautions,</if>
<if test="status != null">status,</if>
<if test="userId != null">user_id,</if>
<if test="consultationId != null">consultation_id,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
<if test="delFlag != null">del_flag,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="planNo != null">#{planNo},</if>
<if test="title != null">#{title},</if>
<if test="farmerId != null">#{farmerId},</if>
<if test="farmerName != null">#{farmerName},</if>
<if test="farmerPhone != null">#{farmerPhone},</if>
<if test="animalType != null">#{animalType},</if>
<if test="symptoms != null">#{symptoms},</if>
<if test="diagnosis != null">#{diagnosis},</if>
<if test="treatmentMethod != null">#{treatmentMethod},</if>
<if test="treatmentDesc != null">#{treatmentDesc},</if>
<if test="precautions != null">#{precautions},</if>
<if test="status != null">#{status},</if>
<if test="userId != null">#{userId},</if>
<if test="consultationId != null">#{consultationId},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
<if test="delFlag != null">#{delFlag},</if>
</trim>
</insert>
<update id="updateTreatmentPlan" parameterType="TreatmentPlan">
update treatment_plan
<trim prefix="SET" suffixOverrides=",">
<if test="planNo != null">plan_no = #{planNo},</if>
<if test="title != null">title = #{title},</if>
<if test="farmerId != null">farmer_id = #{farmerId},</if>
<if test="farmerName != null">farmer_name = #{farmerName},</if>
<if test="farmerPhone != null">farmer_phone = #{farmerPhone},</if>
<if test="animalType != null">animal_type = #{animalType},</if>
<if test="symptoms != null">symptoms = #{symptoms},</if>
<if test="diagnosis != null">diagnosis = #{diagnosis},</if>
<if test="treatmentMethod != null">treatment_method = #{treatmentMethod},</if>
<if test="treatmentDesc != null">treatment_desc = #{treatmentDesc},</if>
<if test="precautions != null">precautions = #{precautions},</if>
<if test="status != null">status = #{status},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="consultationId != null">consultation_id = #{consultationId},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<update id="deleteTreatmentPlanById" parameterType="Long">
update treatment_plan set del_flag = '1' where id = #{id}
</update>
<update id="deleteTreatmentPlanByIds" parameterType="String">
update treatment_plan set del_flag = '1' where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

79
chenhai-system/src/main/resources/mapper/vet/TreatmentPlanMedicineMapper.xml

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.vet.mapper.TreatmentPlanMedicineMapper">
<resultMap type="TreatmentPlanMedicine" id="TreatmentPlanMedicineResult">
<result property="id" column="id"/>
<result property="planId" column="plan_id"/>
<result property="productId" column="product_id"/>
<result property="usageDosage" column="usage_dosage"/>
<result property="courseDays" column="course_days"/>
<result property="quantity" column="quantity"/>
<result property="sortOrder" column="sort_order"/>
<result property="createTime" column="create_time"/>
</resultMap>
<resultMap type="TreatmentPlanMedicine" id="TreatmentPlanMedicineWithProductResult" extends="TreatmentPlanMedicineResult">
<association property="productInfo" javaType="VetProduct"
column="product_id" select="com.chenhai.vet.mapper.VetProductMapper.selectVetProductById"/>
</resultMap>
<sql id="selectTreatmentPlanMedicineVo">
select id, plan_id, product_id, usage_dosage, course_days, quantity, sort_order, create_time
from treatment_plan_medicine
</sql>
<insert id="insertTreatmentPlanMedicine" parameterType="TreatmentPlanMedicine" useGeneratedKeys="true" keyProperty="id">
insert into treatment_plan_medicine
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="planId != null">plan_id,</if>
<if test="productId != null">product_id,</if>
<if test="usageDosage != null">usage_dosage,</if>
<if test="courseDays != null">course_days,</if>
<if test="quantity != null">quantity,</if>
<if test="sortOrder != null">sort_order,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="planId != null">#{planId},</if>
<if test="productId != null">#{productId},</if>
<if test="usageDosage != null">#{usageDosage},</if>
<if test="courseDays != null">#{courseDays},</if>
<if test="quantity != null">#{quantity},</if>
<if test="sortOrder != null">#{sortOrder},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<insert id="batchInsertTreatmentPlanMedicine" parameterType="java.util.List">
insert into treatment_plan_medicine (plan_id, product_id, usage_dosage, course_days, quantity, sort_order, create_time) values
<foreach collection="list" item="item" separator=",">
(#{item.planId}, #{item.productId}, #{item.usageDosage}, #{item.courseDays}, #{item.quantity}, #{item.sortOrder}, sysdate())
</foreach>
</insert>
<select id="selectByPlanId" parameterType="Long" resultMap="TreatmentPlanMedicineResult">
<include refid="selectTreatmentPlanMedicineVo"/>
where plan_id = #{planId}
order by sort_order
</select>
<select id="selectByPlanIdWithProduct" parameterType="Long" resultMap="TreatmentPlanMedicineWithProductResult">
<include refid="selectTreatmentPlanMedicineVo"/>
where plan_id = #{planId}
order by sort_order
</select>
<delete id="deleteByPlanId" parameterType="Long">
delete from treatment_plan_medicine where plan_id = #{planId}
</delete>
<delete id="deleteByPlanIds" parameterType="Long">
delete from treatment_plan_medicine where plan_id in
<foreach item="planId" collection="planIds" open="(" separator="," close=")">
#{planId}
</foreach>
</delete>
</mapper>

1
chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml

@ -73,7 +73,6 @@
where a.id = #{id} <!-- 添加表别名 a. -->
</select>
<!-- 查询兽医经验文章列表 -->
<!-- 查询兽医经验文章列表(已包含关联用户表) -->
<select id="selectVetExperienceArticleList" parameterType="VetExperienceArticle" resultMap="VetExperienceArticleResult">
<include refid="selectVetExperienceArticleVo"/>

6
chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml

@ -89,6 +89,12 @@
order by vq.qualification_id desc
</select>
<select id="selectVetQualificationByUserId" parameterType="Long" resultMap="VetQualificationResult">
<include refid="selectVetQualificationVo"/>
where user_id = #{userId}
order by qualification_id desc limit 1
</select>
<select id="selectVetQualificationByQualificationId" parameterType="Long" resultMap="VetQualificationResult">
<include refid="selectVetQualificationVo"/>
where vq.qualification_id = #{qualificationId}

44
chenhai-ui/src/api/vet/plan.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询治疗方案列表
export function listPlan(query) {
return request({
url: '/vet/plan/list',
method: 'get',
params: query
})
}
// 查询治疗方案详细
export function getPlan(id) {
return request({
url: '/vet/plan/' + id,
method: 'get'
})
}
// 新增治疗方案
export function addPlan(data) {
return request({
url: '/vet/plan',
method: 'post',
data: data
})
}
// 修改治疗方案
export function updatePlan(data) {
return request({
url: '/vet/plan',
method: 'put',
data: data
})
}
// 删除治疗方案
export function delPlan(id) {
return request({
url: '/vet/plan/' + id,
method: 'delete'
})
}

368
chenhai-ui/src/views/vet/plan/index.vue

@ -0,0 +1,368 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="方案编号" prop="planNo">
<el-input
v-model="queryParams.planNo"
placeholder="请输入方案编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="方案标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入方案标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="农牧户姓名" prop="farmerName">
<el-input
v-model="queryParams.farmerName"
placeholder="请输入农牧户姓名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系电话" prop="farmerPhone">
<el-input
v-model="queryParams.farmerPhone"
placeholder="请输入联系电话"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="治疗方式" prop="treatmentMethod">
<el-input
v-model="queryParams.treatmentMethod"
placeholder="请输入治疗方式"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="兽医ID" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入兽医ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['vet:plan:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vet:plan:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vet:plan:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['vet:plan:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="planList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" />
<el-table-column label="方案编号" align="center" prop="planNo" />
<el-table-column label="方案标题" align="center" prop="title" />
<el-table-column label="农牧户姓名" align="center" prop="farmerName" />
<el-table-column label="联系电话" align="center" prop="farmerPhone" />
<el-table-column label="动物类型" align="center" prop="animalType" />
<el-table-column label="症状描述" align="center" prop="symptoms" />
<el-table-column label="诊断结果" align="center" prop="diagnosis" />
<el-table-column label="治疗方式" align="center" prop="treatmentMethod" />
<el-table-column label="治疗方案描述" align="center" prop="treatmentDesc" />
<el-table-column label="注意事项" align="center" prop="precautions" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="兽医ID" align="center" prop="userId" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['vet:plan:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:plan:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改治疗方案对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="方案编号" prop="planNo">
<el-input v-model="form.planNo" placeholder="请输入方案编号" />
</el-form-item>
<el-form-item label="方案标题" prop="title">
<el-input v-model="form.title" placeholder="请输入方案标题" />
</el-form-item>
<el-form-item label="农牧户姓名" prop="farmerName">
<el-input v-model="form.farmerName" placeholder="请输入农牧户姓名" />
</el-form-item>
<el-form-item label="联系电话" prop="farmerPhone">
<el-input v-model="form.farmerPhone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="症状描述" prop="symptoms">
<el-input v-model="form.symptoms" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="诊断结果" prop="diagnosis">
<el-input v-model="form.diagnosis" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="治疗方式" prop="treatmentMethod">
<el-input v-model="form.treatmentMethod" placeholder="请输入治疗方式" />
</el-form-item>
<el-form-item label="治疗方案描述" prop="treatmentDesc">
<el-input v-model="form.treatmentDesc" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="注意事项" prop="precautions">
<el-input v-model="form.precautions" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="兽医ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入兽医ID" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="删除标志" prop="delFlag">
<el-input v-model="form.delFlag" placeholder="请输入删除标志" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listPlan, getPlan, delPlan, addPlan, updatePlan } from "@/api/vet/plan"
export default {
name: "Plan",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
planList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
planNo: null,
title: null,
farmerName: null,
farmerPhone: null,
animalType: null,
symptoms: null,
diagnosis: null,
treatmentMethod: null,
treatmentDesc: null,
precautions: null,
status: null,
userId: null,
},
//
form: {},
//
rules: {
planNo: [
{ required: true, message: "方案编号不能为空", trigger: "blur" }
],
title: [
{ required: true, message: "方案标题不能为空", trigger: "blur" }
],
animalType: [
{ required: true, message: "动物类型不能为空", trigger: "change" }
],
symptoms: [
{ required: true, message: "症状描述不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询治疗方案列表 */
getList() {
this.loading = true
listPlan(this.queryParams).then(response => {
this.planList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
planNo: null,
title: null,
farmerName: null,
farmerPhone: null,
animalType: null,
symptoms: null,
diagnosis: null,
treatmentMethod: null,
treatmentDesc: null,
precautions: null,
status: null,
userId: null,
createTime: null,
updateTime: null,
remark: null,
delFlag: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加治疗方案"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getPlan(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改治疗方案"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updatePlan(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addPlan(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除治疗方案编号为"' + ids + '"的数据项?').then(function() {
return delPlan(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('vet/plan/export', {
...this.queryParams
}, `plan_${new Date().getTime()}.xlsx`)
}
}
}
</script>
Loading…
Cancel
Save