Browse Source

兽医经验分享功能

master
ChaiNingQi 1 month ago
parent
commit
49dc2cb74a
  1. 90
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/CertificateTestController.java
  2. 317
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java
  3. 82
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetNotificationController.java
  4. 14
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java
  5. 104
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetServiceReviewController.java
  6. 4
      chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java
  7. 112
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java
  8. 351
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java
  9. 28
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetNotification.java
  10. 181
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetServiceReview.java
  11. 47
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java
  12. 89
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java
  13. 2
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetNotificationMapper.java
  14. 65
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetServiceReviewMapper.java
  15. 115
      chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java
  16. 65
      chenhai-system/src/main/java/com/chenhai/vet/service/IVetServiceReviewService.java
  17. 2
      chenhai-system/src/main/java/com/chenhai/vet/service/VetNotificationService.java
  18. 8
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCertificateServiceImpl.java
  19. 251
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java
  20. 7
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetNotificationServiceImpl.java
  21. 96
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetServiceReviewServiceImpl.java
  22. 238
      chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml
  23. 21
      chenhai-system/src/main/resources/mapper/vet/VetNotificationMapper.xml
  24. 112
      chenhai-system/src/main/resources/mapper/vet/VetServiceReviewMapper.xml
  25. 44
      chenhai-ui/src/api/vet/article.js
  26. 44
      chenhai-ui/src/api/vet/qualification.js
  27. 44
      chenhai-ui/src/api/vet/review.js
  28. 458
      chenhai-ui/src/views/vet/article/index.vue
  29. 10
      chenhai-ui/src/views/vet/certificate/index.vue
  30. 14
      chenhai-ui/src/views/vet/info/index.vue
  31. 392
      chenhai-ui/src/views/vet/qualification/index.vue
  32. 369
      chenhai-ui/src/views/vet/review/index.vue

90
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/CertificateTestController.java

@ -1,90 +0,0 @@
/*
package com.chenhai.vet.controller;
import com.chenhai.common.core.controller.BaseController;
import com.chenhai.common.core.domain.AjaxResult;
import com.chenhai.vet.domain.VetCertificate;
import com.chenhai.vet.service.IVetCertificateService;
import com.chenhai.vet.service.VetNotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
*/
/**
* 证书提醒测试控制器
*//*
@RestController
@RequestMapping("/test/certificate")
public class CertificateTestController extends BaseController {
@Autowired
private IVetCertificateService vetCertificateService;
@Autowired
private VetNotificationService vetNotificationService;
*/
/**
* 测试单个证书提醒
*//*
@GetMapping("/test-notify/{certId}")
public AjaxResult testNotify(@PathVariable Long certId) {
try {
logger.info("🎯 测试证书提醒,证书ID: {}", certId);
// 1. 获取证书
VetCertificate cert = vetCertificateService.selectVetCertificateById(certId);
if (cert == null) {
return error("证书不存在: " + certId);
}
// 2. 直接调用通知服务
logger.info("📨 调用通知服务,证书: {}", cert.getCertName());
vetNotificationService.sendCertificateExpireRemind(cert);
logger.info("✅ 通知服务调用完成");
// 3. 返回结果
return success("测试完成,证书ID: " + certId +
",证书名称: " + cert.getCertName() +
",请检查数据库通知表");
} catch (Exception e) {
logger.error("测试失败", e);
return error("测试失败: " + e.getMessage());
}
}
*/
/**
* 手动触发定时任务
*//*
@GetMapping("/trigger-task")
public AjaxResult triggerTask() {
try {
logger.info("🚀 手动触发证书检查任务");
vetCertificateService.checkAndSendCertificateReminders();
return success("定时任务已手动触发,请查看控制台日志");
} catch (Exception e) {
logger.error("触发定时任务失败", e);
return error("触发失败: " + e.getMessage());
}
}
*/
/**
* 检查通知表数据
*//*
@GetMapping("/check-notifications")
public AjaxResult checkNotifications() {
try {
// 这里需要查询通知表暂时返回简单信息
return success("请通过SQL查询通知表: SELECT * FROM vet_notification ORDER BY create_time DESC LIMIT 10");
} catch (Exception e) {
return error("检查失败: " + e.getMessage());
}
}
}*/

317
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java

@ -0,0 +1,317 @@
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.page.TableDataInfo;
import com.chenhai.common.enums.BusinessType;
import com.chenhai.common.utils.SecurityUtils;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.vet.domain.VetExperienceArticle;
import com.chenhai.vet.service.IVetExperienceArticleService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 兽医经验文章Controller
*/
@RestController
@RequestMapping("/vet/article")
public class VetExperienceArticleController extends BaseController {
@Autowired
private IVetExperienceArticleService vetExperienceArticleService;
/**
* 查询兽医经验文章列表
*/
@GetMapping("/list")
public TableDataInfo list(VetExperienceArticle vetExperienceArticle) {
startPage();
List<VetExperienceArticle> list = vetExperienceArticleService.selectVetExperienceArticleList(vetExperienceArticle);
return getDataTable(list);
}
/**
* 获取文章详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(vetExperienceArticleService.selectVetExperienceArticleById(id));
}
/**
* 修改兽医经验文章
*/
@PreAuthorize("@ss.hasPermi('vet:article:edit')")
@Log(title = "兽医经验文章", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody VetExperienceArticle vetExperienceArticle) {
return toAjax(vetExperienceArticleService.updateVetExperienceArticle(vetExperienceArticle));
}
/**
* 删除兽医经验文章
*/
@PreAuthorize("@ss.hasPermi('vet:article:remove')")
@Log(title = "兽医经验文章", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(vetExperienceArticleService.deleteVetExperienceArticleByIds(ids));
}
/**
* 获取所有兽医已发布的文章
*/
@GetMapping("/forum/home")
public AjaxResult getForumHome() {
Map<String, Object> forumData = new HashMap<>();
// 1. 推荐文章精选+置顶
List<VetExperienceArticle> featuredArticles = vetExperienceArticleService.selectFeaturedArticles(8);
forumData.put("featuredArticles", featuredArticles);
// 2. 最新文章
List<VetExperienceArticle> latestArticles = vetExperienceArticleService.selectLatestArticles(10);
forumData.put("latestArticles", latestArticles);
// 3. 热门文章按浏览数
List<VetExperienceArticle> hotArticles = vetExperienceArticleService.selectHotArticles(10);
forumData.put("hotArticles", hotArticles);
// 4. 文章统计
Map<String, Object> statistics = vetExperienceArticleService.selectForumStatistics();
forumData.put("statistics", statistics);
return success(forumData);
}
/**
* 浏览文章详情论坛模式
* 增加浏览数可以查看所有兽医的文章
*/
@GetMapping("/forum/detail/{id}")
public AjaxResult getForumArticleDetail(@PathVariable Long id) {
// 1. 获取文章详情
VetExperienceArticle article = vetExperienceArticleService.selectVetExperienceArticleById(id);
if (article == null || !"1".equals(article.getStatus())) {
return error("文章不存在或未发布");
}
// 2. 增加浏览数
vetExperienceArticleService.incrementViewCount(id);
// 3. 判断是否是当前用户发布的文章
Long currentUserId = getUserId();
boolean isOwner = currentUserId != null && currentUserId.equals(article.getVetId());
// 4. 获取相关文章
List<VetExperienceArticle> relatedArticles = vetExperienceArticleService.selectRelatedArticles(id, article.getCategoryId(), 4);
// 5. 获取作者的其他文章
List<VetExperienceArticle> authorArticles = vetExperienceArticleService.selectArticlesByVetId(article.getVetId(), 5);
Map<String, Object> result = new HashMap<>();
result.put("article", article);
result.put("isOwner", isOwner);
result.put("relatedArticles", relatedArticles);
result.put("authorArticles", authorArticles);
return success(result);
}
/**
* 发布新文章论坛发布接口
*/
@PreAuthorize("@ss.hasPermi('vet:article:add')")
@Log(title = "发布经验文章", businessType = BusinessType.INSERT)
@PostMapping("/forum/publish")
public AjaxResult publishForumArticle(@RequestBody VetExperienceArticle article) {
Long currentUserId = getUserId();
String currentUsername = SecurityUtils.getUsername();
// 设置作者信息
article.setVetId(currentUserId);
article.setVetName(currentUsername); // 暂时用用户名可以根据需要从用户表获取真实姓名
// 设置文章状态为已发布
article.setStatus("1");
article.setPublishTime(new Date());
// 敏感词检查
Map<String, Object> sensitiveCheck = checkSensitiveWords(article);
if ((Boolean) sensitiveCheck.get("hasSensitive")) {
// 包含敏感词标记但不阻止发布
article.setIsSensitive("1");
article.setSensitiveWords((String) sensitiveCheck.get("sensitiveWords"));
int result = vetExperienceArticleService.insertVetExperienceArticle(article);
if (result > 0) {
return success("文章发布成功,但包含敏感词,请注意修改。")
.put("articleId", article.getId())
.put("hasSensitive", true)
.put("sensitiveWords", sensitiveCheck.get("sensitiveWords"));
}
} else {
article.setIsSensitive("0");
article.setSensitiveWords(null);
int result = vetExperienceArticleService.insertVetExperienceArticle(article);
return toAjax(result).put("articleId", article.getId());
}
return error("发布失败");
}
/**
* 获取当前用户的文章
*/
@PreAuthorize("@ss.hasPermi('vet:article:my')")
@GetMapping("/forum/myArticles")
public TableDataInfo getMyForumArticles(
@RequestParam(value = "status", required = false) String status) {
Long currentUserId = getUserId();
VetExperienceArticle query = new VetExperienceArticle();
query.setVetId(currentUserId);
if (status != null && !status.isEmpty()) {
query.setStatus(status);
}
startPage();
List<VetExperienceArticle> list = vetExperienceArticleService.selectVetExperienceArticleList(query);
return getDataTable(list);
}
/**
* 点赞文章
*/
@PostMapping("/forum/{id}/like")
public AjaxResult likeArticle(@PathVariable Long id) {
int result = vetExperienceArticleService.incrementLikeCount(id);
return toAjax(result);
}
/**
* 收藏文章
*/
@PostMapping("/forum/{id}/collect")
public AjaxResult collectArticle(@PathVariable Long id) {
int result = vetExperienceArticleService.incrementCollectCount(id);
return toAjax(result);
}
/**
* 搜索文章
*/
@GetMapping("/forum/search")
public TableDataInfo searchForumArticles(
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "categoryId", required = false) Long categoryId,
@RequestParam(value = "tag", required = false) String tag) {
VetExperienceArticle query = new VetExperienceArticle();
query.setStatus("1"); // 只搜索已发布的文章
if (keyword != null && !keyword.trim().isEmpty()) {
query.setTitle(keyword.trim());
}
if (categoryId != null) {
query.setCategoryId(categoryId);
}
startPage();
List<VetExperienceArticle> list = vetExperienceArticleService.selectVetExperienceArticleList(query);
/*List<VetExperienceArticle> list = vetExperienceArticleService.searchArticles(keyword);*/
return getDataTable(list);
}
/*@GetMapping("/forum/search")
public TableDataInfo searchForumArticles(
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "categoryId", required = false) Long categoryId,
@RequestParam(value = "tag", required = false) String tag) {
startPage();
List<VetExperienceArticle> list = new ArrayList<>();
if (keyword != null && !keyword.trim().isEmpty()) {
list = vetExperienceArticleService.searchArticles(keyword);
} else {
VetExperienceArticle query = new VetExperienceArticle();
query.setStatus("1");
if (categoryId != null) {
query.setCategoryId(categoryId);
}
if (tag != null && !tag.trim().isEmpty()) {
query.setTags(tag.trim()); // 注意需确保MyBatis支持tags的模糊匹配
}
list = vetExperienceArticleService.selectVetExperienceArticleList(query);
}
return getDataTable(list);
}*/
/**
* 获取热门标签
*/
@GetMapping("/forum/hotTags")
public AjaxResult getHotTags(@RequestParam(value = "limit", defaultValue = "15") Integer limit) {
List<Map<String, Object>> hotTags = vetExperienceArticleService.selectHotTags(limit);
return success(hotTags);
}
/**
* 新增文章 - 调整为论坛发布模式
*/
@PreAuthorize("@ss.hasPermi('vet:article:add')")
@Log(title = "兽医经验文章", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody VetExperienceArticle vetExperienceArticle) {
// 调用论坛发布接口
return publishForumArticle(vetExperienceArticle);
}
/**
* 敏感词检查方法
*/
private Map<String, Object> checkSensitiveWords(VetExperienceArticle article) {
Map<String, Object> result = new HashMap<>();
result.put("hasSensitive", false);
result.put("sensitiveWords", "");
// TODO: 实现敏感词检查逻辑
// 可以调用专门的敏感词服务
// List<String> sensitiveWords = sensitiveWordService.detect(article.getTitle() + " " + article.getContent());
// 示例逻辑
if (article.getTitle() != null && article.getTitle().contains("敏感词示例")) {
result.put("hasSensitive", true);
result.put("sensitiveWords", "敏感词示例");
}
return result;
}
/**
* 导出兽医经验文章列表
*/
@PreAuthorize("@ss.hasPermi('vet:article:export')")
@Log(title = "兽医经验文章", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, VetExperienceArticle vetExperienceArticle) {
List<VetExperienceArticle> list = vetExperienceArticleService.selectVetExperienceArticleList(vetExperienceArticle);
ExcelUtil<VetExperienceArticle> util = new ExcelUtil<>(VetExperienceArticle.class);
util.exportExcel(response, list, "兽医经验文章数据");
}
}

82
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetNotificationController.java

@ -1,5 +1,6 @@
package com.chenhai.web.controller.vet;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@ -100,4 +101,83 @@ public class VetNotificationController extends BaseController
{
return toAjax(vetNotificationService.deleteVetNotificationByIds(ids));
}
}
/**
* 根据当前用户ID获取通知列表
*/
@PreAuthorize("@ss.hasPermi('vet:notification:list')")
@GetMapping("/user/list")
public TableDataInfo getUserNotifications()
{
// 使用父类的 getUserId() 方法
Long currentUserId = getUserId();
if (currentUserId == null) {
logger.warn("无法获取当前用户ID,用户可能未登录");
return getDataTable(new ArrayList<>());
}
startPage();
List<VetNotification> list = vetNotificationService.getNotificationsByUserId(currentUserId);
return getDataTable(list);
}
/**
* 获取当前用户的未读通知数量
*/
@PreAuthorize("@ss.hasPermi('vet:notification:query')")
@GetMapping("/user/unread/count")
public AjaxResult getUnreadCount()
{
Long currentUserId = getUserId();
if (currentUserId == null) {
return success(0);
}
int unreadCount = vetNotificationService.getUnreadCount(currentUserId);
return success(unreadCount);
}
/**
* 标记单个通知为已读
*/
@PreAuthorize("@ss.hasPermi('vet:notification:edit')")
@Log(title = "标记通知已读", businessType = BusinessType.UPDATE)
@PutMapping("/{id}/read")
public AjaxResult markAsRead(@PathVariable Long id)
{
boolean result = vetNotificationService.markAsRead(id);
return toAjax(result ? 1 : 0);
}
/**
* 标记所有通知为已读
*/
@PreAuthorize("@ss.hasPermi('vet:notification:edit')")
@Log(title = "标记所有通知已读", businessType = BusinessType.UPDATE)
@PutMapping("/user/mark-all-read")
public AjaxResult markAllAsRead()
{
Long currentUserId = getUserId();
if (currentUserId == null) {
return error("用户未登录");
}
boolean result = vetNotificationService.markAllAsRead(currentUserId);
return toAjax(result ? 1 : 0);
}
/**
* 根据指定用户ID查询通知列表管理员功能
*/
@PreAuthorize("@ss.hasPermi('vet:notification:list')")
@GetMapping("/list/user/{userId}")
public TableDataInfo listByUserId(@PathVariable Long userId)
{
startPage();
VetNotification query = new VetNotification();
query.setUserId(userId);
List<VetNotification> list = vetNotificationService.selectVetNotificationList(query);
return getDataTable(list);
}
}

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

@ -22,7 +22,7 @@ import java.util.List;
* @date 2025-12-26
*/
@RestController
@RequestMapping("/system/qualification")
@RequestMapping("/vet/qualification")
public class VetQualificationController extends BaseController
{
@Autowired
@ -31,7 +31,7 @@ public class VetQualificationController extends BaseController
/**
* 查询兽医资质列表
*/
@PreAuthorize("@ss.hasPermi('system:qualification:list')")
@PreAuthorize("@ss.hasPermi('vet:qualification:list')")
@GetMapping("/list")
public TableDataInfo list(VetQualification vetQualification)
{
@ -43,7 +43,7 @@ public class VetQualificationController extends BaseController
/**
* 导出兽医资质列表
*/
@PreAuthorize("@ss.hasPermi('system:qualification:export')")
@PreAuthorize("@ss.hasPermi('vet:qualification:export')")
@Log(title = "兽医资质", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, VetQualification vetQualification)
@ -56,7 +56,7 @@ public class VetQualificationController extends BaseController
/**
* 获取兽医资质详细信息
*/
@PreAuthorize("@ss.hasPermi('system:qualification:query')")
@PreAuthorize("@ss.hasPermi('vet:qualification:query')")
@GetMapping(value = "/{qualificationId}")
public AjaxResult getInfo(@PathVariable("qualificationId") Long qualificationId)
{
@ -66,7 +66,7 @@ public class VetQualificationController extends BaseController
/**
* 新增兽医资质
*/
@PreAuthorize("@ss.hasPermi('system:qualification:add')")
@PreAuthorize("@ss.hasPermi('vet:qualification:add')")
@Log(title = "兽医资质", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody VetQualification vetQualification)
@ -77,7 +77,7 @@ public class VetQualificationController extends BaseController
/**
* 修改兽医资质
*/
@PreAuthorize("@ss.hasPermi('system:qualification:edit')")
@PreAuthorize("@ss.hasPermi('vet:qualification:edit')")
@Log(title = "兽医资质", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody VetQualification vetQualification)
@ -88,7 +88,7 @@ public class VetQualificationController extends BaseController
/**
* 删除兽医资质
*/
@PreAuthorize("@ss.hasPermi('system:qualification:remove')")
@PreAuthorize("@ss.hasPermi('vet:qualification:remove')")
@Log(title = "兽医资质", businessType = BusinessType.DELETE)
@DeleteMapping("/{qualificationIds}")
public AjaxResult remove(@PathVariable Long[] qualificationIds)

104
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetServiceReviewController.java

@ -0,0 +1,104 @@
package com.chenhai.web.controller.vet;
import java.util.List;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.VetServiceReview;
import com.chenhai.vet.service.IVetServiceReviewService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 兽医服务评价Controller
*
* @author ruoyi
* @date 2026-01-06
*/
@RestController
@RequestMapping("/vet/review")
public class VetServiceReviewController extends BaseController
{
@Autowired
private IVetServiceReviewService vetServiceReviewService;
/**
* 查询兽医服务评价列表
*/
@PreAuthorize("@ss.hasPermi('vet:review:list')")
@GetMapping("/list")
public TableDataInfo list(VetServiceReview vetServiceReview)
{
startPage();
List<VetServiceReview> list = vetServiceReviewService.selectVetServiceReviewList(vetServiceReview);
return getDataTable(list);
}
/**
* 导出兽医服务评价列表
*/
@PreAuthorize("@ss.hasPermi('vet:review:export')")
@Log(title = "兽医服务评价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, VetServiceReview vetServiceReview)
{
List<VetServiceReview> list = vetServiceReviewService.selectVetServiceReviewList(vetServiceReview);
ExcelUtil<VetServiceReview> util = new ExcelUtil<VetServiceReview>(VetServiceReview.class);
util.exportExcel(response, list, "兽医服务评价数据");
}
/**
* 获取兽医服务评价详细信息
*/
@PreAuthorize("@ss.hasPermi('vet:review:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(vetServiceReviewService.selectVetServiceReviewById(id));
}
/**
* 新增兽医服务评价
*/
@PreAuthorize("@ss.hasPermi('vet:review:add')")
@Log(title = "兽医服务评价", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody VetServiceReview vetServiceReview)
{
return toAjax(vetServiceReviewService.insertVetServiceReview(vetServiceReview));
}
/**
* 修改兽医服务评价
*/
@PreAuthorize("@ss.hasPermi('vet:review:edit')")
@Log(title = "兽医服务评价", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody VetServiceReview vetServiceReview)
{
return toAjax(vetServiceReviewService.updateVetServiceReview(vetServiceReview));
}
/**
* 删除兽医服务评价
*/
@PreAuthorize("@ss.hasPermi('vet:review:remove')")
@Log(title = "兽医服务评价", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(vetServiceReviewService.deleteVetServiceReviewByIds(ids));
}
}

4
chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java

@ -27,10 +27,10 @@ public class CertificateRemindTask {
/* @Scheduled(cron = "0 0 2 * * ?")*/
@Scheduled(cron = "0 */1 * * * ?")
public void dailyCertificateCheck() {
log.info("开始执行每日证书检查任务...");
/*log.info("开始执行每日证书检查任务...");*/
try {
vetCertificateService.checkAndSendCertificateReminders();
log.info("每日证书检查任务执行完成");
/* log.info("每日证书检查任务执行完成");*/
} catch (Exception e) {
log.error("每日证书检查任务执行失败", e);
}

112
chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java

@ -0,0 +1,112 @@
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;
/**
* 文章分类对象 vet_article_category
*/
public class VetArticleCategory extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 分类ID */
private Long id;
/** 分类名称 */
@Excel(name = "分类名称")
private String name;
/** 分类描述 */
@Excel(name = "分类描述")
private String description;
/** 分类图标 */
private String icon;
/** 排序 */
@Excel(name = "排序")
private Integer sortOrder;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 文章数量(统计字段) */
private Integer articleCount;
// getter/setter 方法...
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Integer getSortOrder() {
return sortOrder;
}
public void setSortOrder(Integer sortOrder) {
this.sortOrder = sortOrder;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getArticleCount() {
return articleCount;
}
public void setArticleCount(Integer articleCount) {
this.articleCount = articleCount;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("name", getName())
.append("description", getDescription())
.append("icon", getIcon())
.append("sortOrder", getSortOrder())
.append("status", getStatus())
.append("articleCount", getArticleCount())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

351
chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java

@ -0,0 +1,351 @@
package com.chenhai.vet.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
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;
/**
* 兽医经验文章对象 vet_experience_article
*
* @author ruoyi
* @date 2026-01-06
*/
public class VetExperienceArticle extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 文章标题 */
@Excel(name = "文章标题")
private String title;
/** 文章内容(富文本) */
@Excel(name = "文章内容", readConverterExp = "富=文本")
private String content;
/** 文章摘要 */
@Excel(name = "文章摘要")
private String summary;
/** 封面图片 */
@Excel(name = "封面图片")
private String coverImage;
/** 文章图片(JSON数组) */
@Excel(name = "文章图片", readConverterExp = "J=SON数组")
private String images;
/** 作者(兽医)ID */
@Excel(name = "作者", readConverterExp = "兽=医")
private Long vetId;
/** 兽医姓名 */
@Excel(name = "兽医姓名")
private String vetName;
/** 兽医头像 */
@Excel(name = "兽医头像")
private String vetAvatar;
/** 兽医职称 */
@Excel(name = "兽医职称")
private String vetTitle;
/** 分类ID */
@Excel(name = "分类ID")
private Long categoryId;
/** 分类名称 */
@Excel(name = "分类名称")
private String categoryName;
/** 标签(逗号分隔) */
@Excel(name = "标签", readConverterExp = "逗=号分隔")
private String tags;
/** 是否置顶(0否 1是) */
@Excel(name = "是否置顶", readConverterExp = "0=否,1=是")
private String isTop;
/** 是否精选(0否 1是) */
@Excel(name = "是否精选", readConverterExp = "0=否,1=是")
private String isFeatured;
/** 状态(0草稿 1已发布 2审核中 3已驳回) */
@Excel(name = "状态", readConverterExp = "0=草稿,1=已发布,2=审核中,3=已驳回")
private String status;
/** 是否包含敏感词(0否 1是) */
@Excel(name = "是否包含敏感词", readConverterExp = "0=否,1=是")
private String isSensitive;
/** 敏感词列表 */
@Excel(name = "敏感词列表")
private String sensitiveWords;
/** 发布时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "发布时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date publishTime;
/** 浏览次数 */
@Excel(name = "浏览次数")
private Integer viewCount;
/** 点赞数 */
@Excel(name = "点赞数")
private Integer likeCount;
/** 收藏数 */
@Excel(name = "收藏数")
private Integer collectCount;
// 确保有对应的getter和setter
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Integer getLikeCount() {
return likeCount;
}
public void setLikeCount(Integer likeCount) {
this.likeCount = likeCount;
}
public Integer getCollectCount() {
return collectCount;
}
public void setCollectCount(Integer collectCount) {
this.collectCount = collectCount;
}
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
public void setContent(String content)
{
this.content = content;
}
public String getContent()
{
return content;
}
public void setSummary(String summary)
{
this.summary = summary;
}
public String getSummary()
{
return summary;
}
public void setCoverImage(String coverImage)
{
this.coverImage = coverImage;
}
public String getCoverImage()
{
return coverImage;
}
public void setImages(String images)
{
this.images = images;
}
public String getImages()
{
return images;
}
public void setVetId(Long vetId)
{
this.vetId = vetId;
}
public Long getVetId()
{
return vetId;
}
public void setVetName(String vetName)
{
this.vetName = vetName;
}
public String getVetName()
{
return vetName;
}
public void setVetAvatar(String vetAvatar)
{
this.vetAvatar = vetAvatar;
}
public String getVetAvatar()
{
return vetAvatar;
}
public void setVetTitle(String vetTitle)
{
this.vetTitle = vetTitle;
}
public String getVetTitle()
{
return vetTitle;
}
public void setCategoryId(Long categoryId)
{
this.categoryId = categoryId;
}
public Long getCategoryId()
{
return categoryId;
}
public void setCategoryName(String categoryName)
{
this.categoryName = categoryName;
}
public String getCategoryName()
{
return categoryName;
}
public void setTags(String tags)
{
this.tags = tags;
}
public String getTags()
{
return tags;
}
public void setIsTop(String isTop)
{
this.isTop = isTop;
}
public String getIsTop()
{
return isTop;
}
public void setIsFeatured(String isFeatured)
{
this.isFeatured = isFeatured;
}
public String getIsFeatured()
{
return isFeatured;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setIsSensitive(String isSensitive)
{
this.isSensitive = isSensitive;
}
public String getIsSensitive()
{
return isSensitive;
}
public void setSensitiveWords(String sensitiveWords)
{
this.sensitiveWords = sensitiveWords;
}
public String getSensitiveWords()
{
return sensitiveWords;
}
public void setPublishTime(Date publishTime)
{
this.publishTime = publishTime;
}
public Date getPublishTime()
{
return publishTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("title", getTitle())
.append("content", getContent())
.append("summary", getSummary())
.append("coverImage", getCoverImage())
.append("images", getImages())
.append("vetId", getVetId())
.append("vetName", getVetName())
.append("vetAvatar", getVetAvatar())
.append("vetTitle", getVetTitle())
.append("categoryId", getCategoryId())
.append("categoryName", getCategoryName())
.append("tags", getTags())
.append("isTop", getIsTop())
.append("isFeatured", getIsFeatured())
.append("status", getStatus())
.append("isSensitive", getIsSensitive())
.append("sensitiveWords", getSensitiveWords())
.append("publishTime", getPublishTime())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

28
chenhai-system/src/main/java/com/chenhai/vet/domain/VetNotification.java

@ -41,12 +41,34 @@ public class VetNotification extends BaseEntity
private String relatedId;
/** 是否已读 0:未读 1:已读 */
@Excel(name = "是否已读 0:未读 1:已读")
@Excel(name = "是否已读", dictType = "notification_is_read")
private Integer isRead;
/** 是否已读标签(用于前端显示) */
private String isReadLabel; // 添加这个字段
/** 提醒级别 1:低 2:中 3:高 */
@Excel(name = "提醒级别 1:低 2:中 3:高")
@Excel(name = "提醒级别", dictType = "notification_remindlevel")
private Integer remindLevel;
/** 提醒级别标签(用于前端显示) */
private String remindLevelLabel;
public String getIsReadLabel() {
return isReadLabel;
}
public void setIsReadLabel(String isReadLabel) {
this.isReadLabel = isReadLabel;
}
public String getRemindLevelLabel() {
return remindLevelLabel;
}
public void setRemindLevelLabel(String remindLevelLabel) {
this.remindLevelLabel = remindLevelLabel;
}
/** 阅读时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ -156,6 +178,8 @@ public class VetNotification extends BaseEntity
.append("remindLevel", getRemindLevel())
.append("createTime", getCreateTime())
.append("readTime", getReadTime())
.append("isReadLabel", getIsReadLabel())
.append("remindLevelLabel", getRemindLevelLabel())
.toString();
}
}

181
chenhai-system/src/main/java/com/chenhai/vet/domain/VetServiceReview.java

@ -0,0 +1,181 @@
package com.chenhai.vet.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
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;
/**
* 兽医服务评价对象 vet_service_review
*
* @author ruoyi
* @date 2026-01-06
*/
public class VetServiceReview extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 兽医用户ID */
@Excel(name = "兽医用户ID")
private Long vetUserId;
/** 客户用户ID */
@Excel(name = "客户用户ID")
private Long customerUserId;
/** 订单编号 */
@Excel(name = "订单编号")
private String orderNo;
/** 评分(1-5分) */
@Excel(name = "评分", readConverterExp = "1=-5分")
private BigDecimal rating;
/** 评价内容 */
@Excel(name = "评价内容")
private String content;
/** 评价时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "评价时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date reviewTime;
/** 是否匿名 */
@Excel(name = "是否匿名")
private String isAnonymous;
/** 回复内容 */
@Excel(name = "回复内容")
private String replyContent;
/** 回复时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "回复时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date replyTime;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setVetUserId(Long vetUserId)
{
this.vetUserId = vetUserId;
}
public Long getVetUserId()
{
return vetUserId;
}
public void setCustomerUserId(Long customerUserId)
{
this.customerUserId = customerUserId;
}
public Long getCustomerUserId()
{
return customerUserId;
}
public void setOrderNo(String orderNo)
{
this.orderNo = orderNo;
}
public String getOrderNo()
{
return orderNo;
}
public void setRating(BigDecimal rating)
{
this.rating = rating;
}
public BigDecimal getRating()
{
return rating;
}
public void setContent(String content)
{
this.content = content;
}
public String getContent()
{
return content;
}
public void setReviewTime(Date reviewTime)
{
this.reviewTime = reviewTime;
}
public Date getReviewTime()
{
return reviewTime;
}
public void setIsAnonymous(String isAnonymous)
{
this.isAnonymous = isAnonymous;
}
public String getIsAnonymous()
{
return isAnonymous;
}
public void setReplyContent(String replyContent)
{
this.replyContent = replyContent;
}
public String getReplyContent()
{
return replyContent;
}
public void setReplyTime(Date replyTime)
{
this.replyTime = replyTime;
}
public Date getReplyTime()
{
return replyTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("vetUserId", getVetUserId())
.append("customerUserId", getCustomerUserId())
.append("orderNo", getOrderNo())
.append("rating", getRating())
.append("content", getContent())
.append("reviewTime", getReviewTime())
.append("isAnonymous", getIsAnonymous())
.append("replyContent", getReplyContent())
.append("replyTime", getReplyTime())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

47
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java

@ -0,0 +1,47 @@
package com.chenhai.vet.mapper;
import com.chenhai.vet.domain.VetArticleCategory;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 文章分类Mapper接口
*/
@Mapper
public interface VetArticleCategoryMapper {
/**
* 查询文章分类
*/
VetArticleCategory selectVetArticleCategoryById(Long id);
/**
* 查询文章分类列表
*/
List<VetArticleCategory> selectVetArticleCategoryList(VetArticleCategory vetArticleCategory);
/**
* 查询启用的分类列表
*/
List<VetArticleCategory> selectEnabledCategories();
/**
* 新增文章分类
*/
int insertVetArticleCategory(VetArticleCategory vetArticleCategory);
/**
* 修改文章分类
*/
int updateVetArticleCategory(VetArticleCategory vetArticleCategory);
/**
* 删除文章分类
*/
int deleteVetArticleCategoryById(Long id);
/**
* 批量删除文章分类
*/
int deleteVetArticleCategoryByIds(Long[] ids);
}

89
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java

@ -0,0 +1,89 @@
package com.chenhai.vet.mapper;
import java.util.List;
import java.util.Map;
import com.chenhai.vet.domain.VetExperienceArticle;
import org.apache.ibatis.annotations.Param;
/**
* 兽医经验文章Mapper接口
*
* @author ruoyi
* @date 2026-01-06
*/
public interface VetExperienceArticleMapper
{
/**
* 查询兽医经验文章
*
* @param id 兽医经验文章主键
* @return 兽医经验文章
*/
public VetExperienceArticle selectVetExperienceArticleById(Long id);
/**
* 查询兽医经验文章列表
*
* @param vetExperienceArticle 兽医经验文章
* @return 兽医经验文章集合
*/
public List<VetExperienceArticle> selectVetExperienceArticleList(VetExperienceArticle vetExperienceArticle);
/**
* 新增兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
public int insertVetExperienceArticle(VetExperienceArticle vetExperienceArticle);
/**
* 修改兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
public int updateVetExperienceArticle(VetExperienceArticle vetExperienceArticle);
/**
* 删除兽医经验文章
*
* @param id 兽医经验文章主键
* @return 结果
*/
public int deleteVetExperienceArticleById(Long id);
/**
* 批量删除兽医经验文章
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteVetExperienceArticleByIds(Long[] ids);
/**
* 根据条件查询文章支持排序和限制条数
*/
List<VetExperienceArticle> selectArticlesByCondition(Map<String, Object> params);
List<VetExperienceArticle> searchArticles(@Param("keyword") String keyword,
@Param("status") String status);
/**
* 增加浏览数
*/
int incrementViewCount(@Param("id") Long id);
/**
* 增加点赞数
*/
int incrementLikeCount(@Param("id") Long id);
/**
* 增加收藏数
*/
int incrementCollectCount(@Param("id") Long id);
}

2
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetNotificationMapper.java

@ -117,4 +117,6 @@ public interface VetNotificationMapper
* @return 清理数量
*/
public int cleanExpiredNotifications(@Param("days") Integer days);
List<VetNotification> selectVetNotificationByUserId(Long userId);
}

65
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetServiceReviewMapper.java

@ -0,0 +1,65 @@
package com.chenhai.vet.mapper;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import com.chenhai.vet.domain.VetServiceReview;
/**
* 兽医服务评价Mapper接口
*
* @author ruoyi
* @date 2026-01-06
*/
public interface VetServiceReviewMapper
{
/**
* 查询兽医服务评价
*
* @param id 兽医服务评价主键
* @return 兽医服务评价
*/
public VetServiceReview selectVetServiceReviewById(Long id);
/**
* 查询兽医服务评价列表
*
* @param vetServiceReview 兽医服务评价
* @return 兽医服务评价集合
*/
public List<VetServiceReview> selectVetServiceReviewList(VetServiceReview vetServiceReview);
/**
* 新增兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
public int insertVetServiceReview(VetServiceReview vetServiceReview);
/**
* 修改兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
public int updateVetServiceReview(VetServiceReview vetServiceReview);
/**
* 删除兽医服务评价
*
* @param id 兽医服务评价主键
* @return 结果
*/
public int deleteVetServiceReviewById(Long id);
/**
* 批量删除兽医服务评价
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteVetServiceReviewByIds(Long[] ids);
}

115
chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java

@ -0,0 +1,115 @@
package com.chenhai.vet.service;
import java.util.List;
import java.util.Map;
import com.chenhai.vet.domain.VetExperienceArticle;
/**
* 兽医经验文章Service接口
*
* @author ruoyi
* @date 2026-01-06
*/
public interface IVetExperienceArticleService
{
/**
* 查询兽医经验文章
*
* @param id 兽医经验文章主键
* @return 兽医经验文章
*/
public VetExperienceArticle selectVetExperienceArticleById(Long id);
/**
* 查询兽医经验文章列表
*
* @param vetExperienceArticle 兽医经验文章
* @return 兽医经验文章集合
*/
public List<VetExperienceArticle> selectVetExperienceArticleList(VetExperienceArticle vetExperienceArticle);
/**
* 新增兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
public int insertVetExperienceArticle(VetExperienceArticle vetExperienceArticle);
/**
* 修改兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
public int updateVetExperienceArticle(VetExperienceArticle vetExperienceArticle);
/**
* 批量删除兽医经验文章
*
* @param ids 需要删除的兽医经验文章主键集合
* @return 结果
*/
public int deleteVetExperienceArticleByIds(Long[] ids);
/**
* 删除兽医经验文章信息
*
* @param id 兽医经验文章主键
* @return 结果
*/
public int deleteVetExperienceArticleById(Long id);
/**
* 获取推荐文章精选+置顶
*/
List<VetExperienceArticle> selectFeaturedArticles(Integer limit);
List<VetExperienceArticle> searchArticles(String keyword);
/**
* 获取最新文章
*/
List<VetExperienceArticle> selectLatestArticles(Integer limit);
/**
* 获取热门文章按浏览数排序
*/
List<VetExperienceArticle> selectHotArticles(Integer limit);
/**
* 根据兽医ID获取文章
*/
List<VetExperienceArticle> selectArticlesByVetId(Long vetId, Integer limit);
/**
* 获取相关文章
*/
List<VetExperienceArticle> selectRelatedArticles(Long excludeId, Long categoryId, Integer limit);
/**
* 增加浏览数
*/
int incrementViewCount(Long id);
/**
* 增加点赞数
*/
int incrementLikeCount(Long id);
/**
* 增加收藏数
*/
int incrementCollectCount(Long id);
/**
* 获取论坛统计信息
*/
Map<String, Object> selectForumStatistics();
/**
* 获取热门标签
*/
List<Map<String, Object>> selectHotTags(Integer limit);
}

65
chenhai-system/src/main/java/com/chenhai/vet/service/IVetServiceReviewService.java

@ -0,0 +1,65 @@
package com.chenhai.vet.service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import com.chenhai.vet.domain.VetServiceReview;
/**
* 兽医服务评价Service接口
*
* @author ruoyi
* @date 2026-01-06
*/
public interface IVetServiceReviewService
{
/**
* 查询兽医服务评价
*
* @param id 兽医服务评价主键
* @return 兽医服务评价
*/
public VetServiceReview selectVetServiceReviewById(Long id);
/**
* 查询兽医服务评价列表
*
* @param vetServiceReview 兽医服务评价
* @return 兽医服务评价集合
*/
public List<VetServiceReview> selectVetServiceReviewList(VetServiceReview vetServiceReview);
/**
* 新增兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
public int insertVetServiceReview(VetServiceReview vetServiceReview);
/**
* 修改兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
public int updateVetServiceReview(VetServiceReview vetServiceReview);
/**
* 批量删除兽医服务评价
*
* @param ids 需要删除的兽医服务评价主键集合
* @return 结果
*/
public int deleteVetServiceReviewByIds(Long[] ids);
/**
* 删除兽医服务评价信息
*
* @param id 兽医服务评价主键
* @return 结果
*/
public int deleteVetServiceReviewById(Long id);
}

2
chenhai-system/src/main/java/com/chenhai/vet/service/VetNotificationService.java

@ -61,4 +61,6 @@ public interface VetNotificationService {
* 标记所有通知为已读
*/
boolean markAllAsRead(Long userId);
List<VetNotification> selectByUserId(Long userId);
}

8
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCertificateServiceImpl.java

@ -138,8 +138,8 @@ public class VetCertificateServiceImpl implements IVetCertificateService
successCount++;
// 保留原来的日志输出
System.out.println("发送证书提醒:证书ID=" + certificate.getId() +
", 证书名称=" + certificate.getCertName());
/* System.out.println("发送证书提醒:证书ID=" + certificate.getId() +
", 证书名称=" + certificate.getCertName());*/
}
} catch (Exception e) {
failCount++;
@ -147,8 +147,8 @@ public class VetCertificateServiceImpl implements IVetCertificateService
}
}
// 添加统计日志
System.out.println("证书提醒任务完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
/*// 添加统计日志
System.out.println("证书提醒任务完成:成功 " + successCount + " 条,失败 " + failCount + " 条");*/
}
/**

251
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java

@ -0,0 +1,251 @@
package com.chenhai.vet.service.impl;
import java.util.*;
import com.chenhai.common.utils.DateUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.vet.mapper.VetExperienceArticleMapper;
import com.chenhai.vet.domain.VetExperienceArticle;
import com.chenhai.vet.service.IVetExperienceArticleService;
/**
* 兽医经验文章Service业务层处理
*
* @author ruoyi
* @date 2026-01-06
*/
@Service
public class VetExperienceArticleServiceImpl implements IVetExperienceArticleService
{
@Autowired
private VetExperienceArticleMapper vetExperienceArticleMapper;
/**
* 查询兽医经验文章
*
* @param id 兽医经验文章主键
* @return 兽医经验文章
*/
@Override
public VetExperienceArticle selectVetExperienceArticleById(Long id)
{
return vetExperienceArticleMapper.selectVetExperienceArticleById(id);
}
/**
* 查询兽医经验文章列表
*
* @param vetExperienceArticle 兽医经验文章
* @return 兽医经验文章
*/
@Override
public List<VetExperienceArticle> selectVetExperienceArticleList(VetExperienceArticle vetExperienceArticle)
{
return vetExperienceArticleMapper.selectVetExperienceArticleList(vetExperienceArticle);
}
/**
* 新增兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
@Override
public int insertVetExperienceArticle(VetExperienceArticle vetExperienceArticle)
{
vetExperienceArticle.setCreateTime(DateUtils.getNowDate());
return vetExperienceArticleMapper.insertVetExperienceArticle(vetExperienceArticle);
}
/**
* 修改兽医经验文章
*
* @param vetExperienceArticle 兽医经验文章
* @return 结果
*/
@Override
public int updateVetExperienceArticle(VetExperienceArticle vetExperienceArticle)
{
vetExperienceArticle.setUpdateTime(DateUtils.getNowDate());
return vetExperienceArticleMapper.updateVetExperienceArticle(vetExperienceArticle);
}
/**
* 批量删除兽医经验文章
*
* @param ids 需要删除的兽医经验文章主键
* @return 结果
*/
@Override
public int deleteVetExperienceArticleByIds(Long[] ids)
{
return vetExperienceArticleMapper.deleteVetExperienceArticleByIds(ids);
}
/**
* 删除兽医经验文章信息
*
* @param id 兽医经验文章主键
* @return 结果
*/
@Override
public int deleteVetExperienceArticleById(Long id)
{
return vetExperienceArticleMapper.deleteVetExperienceArticleById(id);
}
@Override
public List<VetExperienceArticle> selectFeaturedArticles(Integer limit) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("status", 1);
params.put("isFeatured", 1);
params.put("limit", limit != null ? limit : 8);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public List<VetExperienceArticle> searchArticles(String keyword) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("keyword", keyword);
params.put("status", 1);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public List<VetExperienceArticle> selectLatestArticles(Integer limit) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("status", 1);
params.put("orderBy", "publish_time");
params.put("orderType", "desc");
params.put("limit", limit != null ? limit : 10);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public List<VetExperienceArticle> selectHotArticles(Integer limit) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("status", 1);
params.put("orderBy", "view_count");
params.put("orderType", "desc");
params.put("limit", limit != null ? limit : 10);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public List<VetExperienceArticle> selectArticlesByVetId(Long vetId, Integer limit) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("vetId", vetId);
params.put("status", 1);
params.put("orderBy", "publish_time");
params.put("orderType", "desc");
params.put("limit", limit != null ? limit : 5);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public List<VetExperienceArticle> selectRelatedArticles(Long excludeId, Long categoryId, Integer limit) {
PageHelper.clearPage();
Map<String, Object> params = new HashMap<>();
params.put("excludeId", excludeId);
params.put("categoryId", categoryId);
params.put("status", 1);
params.put("orderBy", "publish_time");
params.put("orderType", "desc");
params.put("limit", limit != null ? limit : 4);
return vetExperienceArticleMapper.selectArticlesByCondition(params);
}
@Override
public int incrementViewCount(Long id) {
return vetExperienceArticleMapper.incrementViewCount(id);
}
@Override
public int incrementLikeCount(Long id) {
return vetExperienceArticleMapper.incrementLikeCount(id);
}
@Override
public int incrementCollectCount(Long id) {
return vetExperienceArticleMapper.incrementCollectCount(id);
}
@Override
public Map<String, Object> selectForumStatistics() {
PageHelper.clearPage();
Map<String, Object> statistics = new HashMap<>();
// 获取文章总数
VetExperienceArticle countQuery = new VetExperienceArticle();
countQuery.setStatus("1");
List<VetExperienceArticle> allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(countQuery);
statistics.put("totalArticles", allArticles.size());
// 获取兽医总数去重
Set<Long> vetIds = new HashSet<>();
for (VetExperienceArticle article : allArticles) {
vetIds.add(article.getVetId());
}
statistics.put("totalVets", vetIds.size());
// 获取总浏览数
int totalViews = 0;
for (VetExperienceArticle article : allArticles) {
totalViews += article.getViewCount() != null ? article.getViewCount() : 0;
}
statistics.put("totalViews", totalViews);
// 获取总点赞数
int totalLikes = 0;
for (VetExperienceArticle article : allArticles) {
totalLikes += article.getLikeCount() != null ? article.getLikeCount() : 0;
}
statistics.put("totalLikes", totalLikes);
return statistics;
}
@Override
public List<Map<String, Object>> selectHotTags(Integer limit) {
// 从所有文章中提取标签并统计热度
VetExperienceArticle query = new VetExperienceArticle();
query.setStatus("1");
List<VetExperienceArticle> allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(query);
Map<String, Integer> tagCount = new HashMap<>();
for (VetExperienceArticle article : allArticles) {
if (article.getTags() != null && !article.getTags().trim().isEmpty()) {
String[] tags = article.getTags().split(",");
for (String tag : tags) {
tag = tag.trim();
if (!tag.isEmpty()) {
tagCount.put(tag, tagCount.getOrDefault(tag, 0) + 1);
}
}
}
}
// 转换为List并按热度排序
List<Map<String, Object>> hotTags = new ArrayList<>();
tagCount.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.limit(limit != null ? limit : 15)
.forEach(entry -> {
Map<String, Object> tagInfo = new HashMap<>();
tagInfo.put("name", entry.getKey());
tagInfo.put("count", entry.getValue());
hotTags.add(tagInfo);
});
return hotTags;
}
}

7
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetNotificationServiceImpl.java

@ -87,7 +87,7 @@ public class VetNotificationServiceImpl implements VetNotificationService {
notification.setCreateTime(now); // 直接使用 Date
if (daysBetween <= 0) {
notification.setTitle("🔴 证书已过期");
notification.setTitle(" ⚠️ 证书已过期");
notification.setContent(String.format("您的《%s》证书已于%s过期!请立即更新证书以继续提供服务。",
certificate.getCertName(), formatDate(expireDate)));
notification.setRemindLevel(3);
@ -175,4 +175,9 @@ public class VetNotificationServiceImpl implements VetNotificationService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
@Override
public List<VetNotification> selectByUserId(Long userId) {
return vetNotificationMapper.selectVetNotificationByUserId(userId);
}
}

96
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetServiceReviewServiceImpl.java

@ -0,0 +1,96 @@
package com.chenhai.vet.service.impl;
import java.util.List;
import com.chenhai.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.vet.mapper.VetServiceReviewMapper;
import com.chenhai.vet.domain.VetServiceReview;
import com.chenhai.vet.service.IVetServiceReviewService;
/**
* 兽医服务评价Service业务层处理
*
* @author ruoyi
* @date 2026-01-06
*/
@Service
public class VetServiceReviewServiceImpl implements IVetServiceReviewService
{
@Autowired
private VetServiceReviewMapper vetServiceReviewMapper;
/**
* 查询兽医服务评价
*
* @param id 兽医服务评价主键
* @return 兽医服务评价
*/
@Override
public VetServiceReview selectVetServiceReviewById(Long id)
{
return vetServiceReviewMapper.selectVetServiceReviewById(id);
}
/**
* 查询兽医服务评价列表
*
* @param vetServiceReview 兽医服务评价
* @return 兽医服务评价
*/
@Override
public List<VetServiceReview> selectVetServiceReviewList(VetServiceReview vetServiceReview)
{
return vetServiceReviewMapper.selectVetServiceReviewList(vetServiceReview);
}
/**
* 新增兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
@Override
public int insertVetServiceReview(VetServiceReview vetServiceReview)
{
vetServiceReview.setCreateTime(DateUtils.getNowDate());
return vetServiceReviewMapper.insertVetServiceReview(vetServiceReview);
}
/**
* 修改兽医服务评价
*
* @param vetServiceReview 兽医服务评价
* @return 结果
*/
@Override
public int updateVetServiceReview(VetServiceReview vetServiceReview)
{
vetServiceReview.setUpdateTime(DateUtils.getNowDate());
return vetServiceReviewMapper.updateVetServiceReview(vetServiceReview);
}
/**
* 批量删除兽医服务评价
*
* @param ids 需要删除的兽医服务评价主键
* @return 结果
*/
@Override
public int deleteVetServiceReviewByIds(Long[] ids)
{
return vetServiceReviewMapper.deleteVetServiceReviewByIds(ids);
}
/**
* 删除兽医服务评价信息
*
* @param id 兽医服务评价主键
* @return 结果
*/
@Override
public int deleteVetServiceReviewById(Long id)
{
return vetServiceReviewMapper.deleteVetServiceReviewById(id);
}
}

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

@ -0,0 +1,238 @@
<?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.VetExperienceArticleMapper">
<resultMap type="VetExperienceArticle" id="VetExperienceArticleResult">
<result property="id" column="id"/>
<result property="title" column="title"/>
<result property="content" column="content"/>
<result property="summary" column="summary"/>
<result property="coverImage" column="cover_image"/>
<result property="images" column="images"/>
<result property="vetId" column="vet_id"/>
<result property="vetName" column="vet_name"/>
<result property="vetAvatar" column="vet_avatar"/>
<result property="vetTitle" column="vet_title"/>
<result property="categoryId" column="category_id"/>
<result property="categoryName" column="category_name"/>
<result property="tags" column="tags"/>
<result property="viewCount" column="view_count"/>
<result property="likeCount" column="like_count"/>
<result property="collectCount" column="collect_count"/>
<result property="isTop" column="is_top"/>
<result property="isFeatured" column="is_featured"/>
<result property="status" column="status"/>
<result property="isSensitive" column="is_sensitive"/>
<result property="sensitiveWords" column="sensitive_words"/>
<result property="publishTime" column="publish_time"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<sql id="selectVetExperienceArticleVo">
select id, title, content, summary, cover_image, images, vet_id, vet_name, vet_avatar, vet_title, category_id, category_name, tags, view_count, like_count, collect_count, is_top, is_featured, status, is_sensitive, sensitive_words, publish_time, create_time, update_time
from vet_experience_article
</sql>
<select id="selectVetExperienceArticleById" parameterType="Long" resultMap="VetExperienceArticleResult">
<include refid="selectVetExperienceArticleVo"/>
where id = #{id}
</select>
<select id="selectVetExperienceArticleList" parameterType="VetExperienceArticle" resultMap="VetExperienceArticleResult">
<include refid="selectVetExperienceArticleVo"/>
<where>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="vetId != null"> and vet_id = #{vetId}</if>
<if test="vetName != null and vetName != ''"> and vet_name like concat('%', #{vetName}, '%')</if>
<if test="categoryId != null"> and category_id = #{categoryId}</if>
<if test="categoryName != null and categoryName != ''"> and category_name like concat('%', #{categoryName}, '%')</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="isTop != null"> and is_top = #{isTop}</if>
<if test="isFeatured != null"> and is_featured = #{isFeatured}</if>
<if test="isSensitive != null"> and is_sensitive = #{isSensitive}</if>
</where>
order by create_time desc
</select>
<!-- 根据条件查询文章(论坛专用) -->
<select id="selectArticlesByCondition" parameterType="map" resultMap="VetExperienceArticleResult">
<!-- 关键:使用PageHelper的特殊注释 -->
/* keepOrder */
<include refid="selectVetExperienceArticleVo"/>
<where>
status = #{status}
<if test="keyword != null and keyword != ''">
and (
title like concat('%', #{keyword}, '%')
or content like concat('%', #{keyword}, '%')
or summary like concat('%', #{keyword}, '%')
or tags like concat('%', #{keyword}, '%')
)
</if>
<if test="vetId != null"> and vet_id = #{vetId}</if>
<if test="categoryId != null"> and category_id = #{categoryId}</if>
<if test="isFeatured != null"> and is_featured = #{isFeatured}</if>
<if test="isTop != null"> and is_top = #{isTop}</if>
<if test="excludeId != null"> and id != #{excludeId}</if>
</where>
<!-- 必须放在最后 -->
ORDER BY
<choose>
<when test="orderBy != null and orderType != null">
${orderBy} ${orderType}
</when>
<otherwise>
publish_time DESC
</otherwise>
</choose>
<!-- &lt;!&ndash; LIMIT必须紧跟在ORDER BY后面 &ndash;&gt;
<if test="limit != null and limit > 0">
LIMIT #{limit}
</if>-->
</select>
<!--<select id="searchArticles" parameterType="map" resultMap="VetExperienceArticleResult">
<include refid="selectVetExperienceArticleVo"/>
<where>
status = #{status}
<if test="keyword != null and keyword != ''">
and (
title like concat('%', #{keyword}, '%')
or content like concat('%', #{keyword}, '%')
or summary like concat('%', #{keyword}, '%')
or tags like concat('%', #{keyword}, '%')
)
</if>
</where>
order by publish_time desc
</select>-->
<!-- VetExperienceArticleMapper.xml -->
<select id="searchArticles" resultType="com.chenhai.vet.domain.VetExperienceArticle">
SELECT * FROM vet_experience_article
WHERE status = #{status}
AND (title LIKE CONCAT('%', #{keyword}, '%') OR content LIKE CONCAT('%', #{keyword}, '%') OR summary LIKE CONCAT('%', #{keyword}, '%'))
</select>
<!-- 增加浏览数 -->
<update id="incrementViewCount" parameterType="Long">
update vet_experience_article
set view_count = view_count + 1,
update_time = sysdate()
where id = #{id}
</update>
<!-- 增加点赞数 -->
<update id="incrementLikeCount" parameterType="Long">
update vet_experience_article
set like_count = like_count + 1,
update_time = sysdate()
where id = #{id}
</update>
<!-- 增加收藏数 -->
<update id="incrementCollectCount" parameterType="Long">
update vet_experience_article
set collect_count = collect_count + 1,
update_time = sysdate()
where id = #{id}
</update>
<insert id="insertVetExperienceArticle" parameterType="VetExperienceArticle" useGeneratedKeys="true" keyProperty="id">
insert into vet_experience_article
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">title,</if>
<if test="content != null and content != ''">content,</if>
<if test="summary != null">summary,</if>
<if test="coverImage != null">cover_image,</if>
<if test="images != null">images,</if>
<if test="vetId != null">vet_id,</if>
<if test="vetName != null and vetName != ''">vet_name,</if>
<if test="vetAvatar != null">vet_avatar,</if>
<if test="vetTitle != null">vet_title,</if>
<if test="categoryId != null">category_id,</if>
<if test="categoryName != null and categoryName != ''">category_name,</if>
<if test="tags != null">tags,</if>
<if test="viewCount != null">view_count,</if>
<if test="likeCount != null">like_count,</if>
<if test="collectCount != null">collect_count,</if>
<if test="isTop != null">is_top,</if>
<if test="isFeatured != null">is_featured,</if>
<if test="status != null and status != ''">status,</if>
<if test="isSensitive != null">is_sensitive,</if>
<if test="sensitiveWords != null">sensitive_words,</if>
<if test="publishTime != null">publish_time,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
<if test="content != null and content != ''">#{content},</if>
<if test="summary != null">#{summary},</if>
<if test="coverImage != null">#{coverImage},</if>
<if test="images != null">#{images},</if>
<if test="vetId != null">#{vetId},</if>
<if test="vetName != null and vetName != ''">#{vetName},</if>
<if test="vetAvatar != null">#{vetAvatar},</if>
<if test="vetTitle != null">#{vetTitle},</if>
<if test="categoryId != null">#{categoryId},</if>
<if test="categoryName != null and categoryName != ''">#{categoryName},</if>
<if test="tags != null">#{tags},</if>
<if test="viewCount != null">#{viewCount},</if>
<if test="likeCount != null">#{likeCount},</if>
<if test="collectCount != null">#{collectCount},</if>
<if test="isTop != null">#{isTop},</if>
<if test="isFeatured != null">#{isFeatured},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="isSensitive != null">#{isSensitive},</if>
<if test="sensitiveWords != null">#{sensitiveWords},</if>
<if test="publishTime != null">#{publishTime},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateVetExperienceArticle" parameterType="VetExperienceArticle">
update vet_experience_article
<trim prefix="SET" suffixOverrides=",">
<if test="title != null and title != ''">title = #{title},</if>
<if test="content != null and content != ''">content = #{content},</if>
<if test="summary != null">summary = #{summary},</if>
<if test="coverImage != null">cover_image = #{coverImage},</if>
<if test="images != null">images = #{images},</if>
<if test="vetId != null">vet_id = #{vetId},</if>
<if test="vetName != null and vetName != ''">vet_name = #{vetName},</if>
<if test="vetAvatar != null">vet_avatar = #{vetAvatar},</if>
<if test="vetTitle != null">vet_title = #{vetTitle},</if>
<if test="categoryId != null">category_id = #{categoryId},</if>
<if test="categoryName != null and categoryName != ''">category_name = #{categoryName},</if>
<if test="tags != null">tags = #{tags},</if>
<if test="viewCount != null">view_count = #{viewCount},</if>
<if test="likeCount != null">like_count = #{likeCount},</if>
<if test="collectCount != null">collect_count = #{collectCount},</if>
<if test="isTop != null">is_top = #{isTop},</if>
<if test="isFeatured != null">is_featured = #{isFeatured},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="isSensitive != null">is_sensitive = #{isSensitive},</if>
<if test="sensitiveWords != null">sensitive_words = #{sensitiveWords},</if>
<if test="publishTime != null">publish_time = #{publishTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteVetExperienceArticleById" parameterType="Long">
delete from vet_experience_article where id = #{id}
</delete>
<delete id="deleteVetExperienceArticleByIds" parameterType="Long">
delete from vet_experience_article where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

21
chenhai-system/src/main/resources/mapper/vet/VetNotificationMapper.xml

@ -15,11 +15,26 @@
<result property="remindLevel" column="remind_level"/>
<result property="createTime" column="create_time"/>
<result property="readTime" column="read_time"/>
<result property="isReadLabel" column="is_read_label"/>
<result property="remindLevelLabel" column="remind_level_label"/>
</resultMap>
<sql id="selectVetNotificationVo">
select id, user_id, title, content, type, related_id, is_read, remind_level, create_time, read_time
from vet_notification
select
n.id,
n.user_id,
n.title,
n.content,
n.type,
n.related_id,
n.is_read,
n.remind_level,
n.read_time,
n.create_time,
<!-- 添加字典标签 -->
(SELECT dict_label FROM sys_dict_data WHERE dict_type = 'notification_is_read' AND dict_value = CAST(n.is_read AS CHAR)) as is_read_label,
(SELECT dict_label FROM sys_dict_data WHERE dict_type = 'sys_notice_status' AND dict_value = CAST(n.remind_level AS CHAR)) as remind_level_label
from vet_notification n
</sql>
<select id="selectVetNotificationById" parameterType="Long" resultMap="VetNotificationResult">
@ -28,10 +43,10 @@
<!-- 已删除 is_deleted = 0 -->
</select>
<select id="selectVetNotificationList" parameterType="VetNotification" resultMap="VetNotificationResult">
<include refid="selectVetNotificationVo"/>
<where>
<!-- 已删除 is_deleted = 0 -->
<if test="userId != null"> and user_id = #{userId}</if>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="content != null and content != ''"> and content like concat('%', #{content}, '%')</if>

112
chenhai-system/src/main/resources/mapper/vet/VetServiceReviewMapper.xml

@ -0,0 +1,112 @@
<?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.VetServiceReviewMapper">
<resultMap type="VetServiceReview" id="VetServiceReviewResult">
<result property="id" column="id" />
<result property="vetUserId" column="vet_user_id" />
<result property="customerUserId" column="customer_user_id" />
<result property="orderNo" column="order_no" />
<result property="rating" column="rating" />
<result property="content" column="content" />
<result property="reviewTime" column="review_time" />
<result property="isAnonymous" column="is_anonymous" />
<result property="replyContent" column="reply_content" />
<result property="replyTime" column="reply_time" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectVetServiceReviewVo">
select id, vet_user_id, customer_user_id, order_no, rating, content, review_time, is_anonymous, reply_content, reply_time, create_by, create_time, update_by, update_time from vet_service_review
</sql>
<select id="selectVetServiceReviewList" parameterType="VetServiceReview" resultMap="VetServiceReviewResult">
<include refid="selectVetServiceReviewVo"/>
<where>
<if test="vetUserId != null "> and vet_user_id = #{vetUserId}</if>
<if test="customerUserId != null "> and customer_user_id = #{customerUserId}</if>
<if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
<if test="rating != null "> and rating = #{rating}</if>
<if test="content != null and content != ''"> and content = #{content}</if>
<if test="reviewTime != null "> and review_time = #{reviewTime}</if>
<if test="isAnonymous != null and isAnonymous != ''"> and is_anonymous = #{isAnonymous}</if>
<if test="replyContent != null and replyContent != ''"> and reply_content = #{replyContent}</if>
<if test="replyTime != null "> and reply_time = #{replyTime}</if>
</where>
</select>
<select id="selectVetServiceReviewById" parameterType="Long" resultMap="VetServiceReviewResult">
<include refid="selectVetServiceReviewVo"/>
where id = #{id}
</select>
<insert id="insertVetServiceReview" parameterType="VetServiceReview" useGeneratedKeys="true" keyProperty="id">
insert into vet_service_review
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="vetUserId != null">vet_user_id,</if>
<if test="customerUserId != null">customer_user_id,</if>
<if test="orderNo != null">order_no,</if>
<if test="rating != null">rating,</if>
<if test="content != null">content,</if>
<if test="reviewTime != null">review_time,</if>
<if test="isAnonymous != null">is_anonymous,</if>
<if test="replyContent != null">reply_content,</if>
<if test="replyTime != null">reply_time,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="vetUserId != null">#{vetUserId},</if>
<if test="customerUserId != null">#{customerUserId},</if>
<if test="orderNo != null">#{orderNo},</if>
<if test="rating != null">#{rating},</if>
<if test="content != null">#{content},</if>
<if test="reviewTime != null">#{reviewTime},</if>
<if test="isAnonymous != null">#{isAnonymous},</if>
<if test="replyContent != null">#{replyContent},</if>
<if test="replyTime != null">#{replyTime},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateVetServiceReview" parameterType="VetServiceReview">
update vet_service_review
<trim prefix="SET" suffixOverrides=",">
<if test="vetUserId != null">vet_user_id = #{vetUserId},</if>
<if test="customerUserId != null">customer_user_id = #{customerUserId},</if>
<if test="orderNo != null">order_no = #{orderNo},</if>
<if test="rating != null">rating = #{rating},</if>
<if test="content != null">content = #{content},</if>
<if test="reviewTime != null">review_time = #{reviewTime},</if>
<if test="isAnonymous != null">is_anonymous = #{isAnonymous},</if>
<if test="replyContent != null">reply_content = #{replyContent},</if>
<if test="replyTime != null">reply_time = #{replyTime},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteVetServiceReviewById" parameterType="Long">
delete from vet_service_review where id = #{id}
</delete>
<delete id="deleteVetServiceReviewByIds" parameterType="String">
delete from vet_service_review where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

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

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询兽医经验文章列表
export function listArticle(query) {
return request({
url: '/vet/article/list',
method: 'get',
params: query
})
}
// 查询兽医经验文章详细
export function getArticle(id) {
return request({
url: '/vet/article/' + id,
method: 'get'
})
}
// 新增兽医经验文章
export function addArticle(data) {
return request({
url: '/vet/article',
method: 'post',
data: data
})
}
// 修改兽医经验文章
export function updateArticle(data) {
return request({
url: '/vet/article',
method: 'put',
data: data
})
}
// 删除兽医经验文章
export function delArticle(id) {
return request({
url: '/vet/article/' + id,
method: 'delete'
})
}

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

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询兽医资质列表
export function listQualification(query) {
return request({
url: '/vet/qualification/list',
method: 'get',
params: query
})
}
// 查询兽医资质详细
export function getQualification(qualificationId) {
return request({
url: '/vet/qualification/' + qualificationId,
method: 'get'
})
}
// 新增兽医资质
export function addQualification(data) {
return request({
url: '/vet/qualification',
method: 'post',
data: data
})
}
// 修改兽医资质
export function updateQualification(data) {
return request({
url: '/vet/qualification',
method: 'put',
data: data
})
}
// 删除兽医资质
export function delQualification(qualificationId) {
return request({
url: '/vet/qualification/' + qualificationId,
method: 'delete'
})
}

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

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询兽医服务评价列表
export function listReview(query) {
return request({
url: '/vet/review/list',
method: 'get',
params: query
})
}
// 查询兽医服务评价详细
export function getReview(id) {
return request({
url: '/vet/review/' + id,
method: 'get'
})
}
// 新增兽医服务评价
export function addReview(data) {
return request({
url: '/vet/review',
method: 'post',
data: data
})
}
// 修改兽医服务评价
export function updateReview(data) {
return request({
url: '/vet/review',
method: 'put',
data: data
})
}
// 删除兽医服务评价
export function delReview(id) {
return request({
url: '/vet/review/' + id,
method: 'delete'
})
}

458
chenhai-ui/src/views/vet/article/index.vue

@ -0,0 +1,458 @@
<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="title">
<el-input
v-model="queryParams.title"
placeholder="请输入文章标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="作者" prop="vetId">
<el-input
v-model="queryParams.vetId"
placeholder="请输入作者"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="兽医姓名" prop="vetName">
<el-input
v-model="queryParams.vetName"
placeholder="请输入兽医姓名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="兽医头像" prop="vetAvatar">
<el-input
v-model="queryParams.vetAvatar"
placeholder="请输入兽医头像"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="兽医职称" prop="vetTitle">
<el-input
v-model="queryParams.vetTitle"
placeholder="请输入兽医职称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="分类ID" prop="categoryId">
<el-input
v-model="queryParams.categoryId"
placeholder="请输入分类ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="分类名称" prop="categoryName">
<el-input
v-model="queryParams.categoryName"
placeholder="请输入分类名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="标签" prop="tags">
<el-input
v-model="queryParams.tags"
placeholder="请输入标签"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否置顶" prop="isTop">
<el-input
v-model="queryParams.isTop"
placeholder="请输入是否置顶"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否精选" prop="isFeatured">
<el-input
v-model="queryParams.isFeatured"
placeholder="请输入是否精选"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否包含敏感词" prop="isSensitive">
<el-input
v-model="queryParams.isSensitive"
placeholder="请输入是否包含敏感词"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker clearable
v-model="queryParams.publishTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择发布时间">
</el-date-picker>
</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:article: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:article: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:article: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:article:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="articleList" @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="title" />
<el-table-column label="文章内容" align="center" prop="content" />
<el-table-column label="文章摘要" align="center" prop="summary" />
<el-table-column label="封面图片" align="center" prop="coverImage" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.coverImage" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="文章图片" align="center" prop="images" />
<el-table-column label="作者" align="center" prop="vetId" />
<el-table-column label="兽医姓名" align="center" prop="vetName" />
<el-table-column label="兽医头像" align="center" prop="vetAvatar" />
<el-table-column label="兽医职称" align="center" prop="vetTitle" />
<el-table-column label="分类ID" align="center" prop="categoryId" />
<el-table-column label="分类名称" align="center" prop="categoryName" />
<el-table-column label="标签" align="center" prop="tags" />
<el-table-column label="是否置顶" align="center" prop="isTop" />
<el-table-column label="是否精选" align="center" prop="isFeatured" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="是否包含敏感词" align="center" prop="isSensitive" />
<el-table-column label="敏感词列表" align="center" prop="sensitiveWords" />
<el-table-column label="发布时间" align="center" prop="publishTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<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:article:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:article: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="title">
<el-input v-model="form.title" placeholder="请输入文章标题" />
</el-form-item>
<el-form-item label="文章内容">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
<el-form-item label="文章摘要" prop="summary">
<el-input v-model="form.summary" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="封面图片" prop="coverImage">
<image-upload v-model="form.coverImage"/>
</el-form-item>
<el-form-item label="文章图片" prop="images">
<el-input v-model="form.images" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="作者" prop="vetId">
<el-input v-model="form.vetId" placeholder="请输入作者" />
</el-form-item>
<el-form-item label="兽医姓名" prop="vetName">
<el-input v-model="form.vetName" placeholder="请输入兽医姓名" />
</el-form-item>
<el-form-item label="兽医头像" prop="vetAvatar">
<el-input v-model="form.vetAvatar" placeholder="请输入兽医头像" />
</el-form-item>
<el-form-item label="兽医职称" prop="vetTitle">
<el-input v-model="form.vetTitle" placeholder="请输入兽医职称" />
</el-form-item>
<el-form-item label="分类ID" prop="categoryId">
<el-input v-model="form.categoryId" placeholder="请输入分类ID" />
</el-form-item>
<el-form-item label="分类名称" prop="categoryName">
<el-input v-model="form.categoryName" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item label="标签" prop="tags">
<el-input v-model="form.tags" placeholder="请输入标签" />
</el-form-item>
<el-form-item label="是否置顶" prop="isTop">
<el-input v-model="form.isTop" placeholder="请输入是否置顶" />
</el-form-item>
<el-form-item label="是否精选" prop="isFeatured">
<el-input v-model="form.isFeatured" placeholder="请输入是否精选" />
</el-form-item>
<el-form-item label="是否包含敏感词" prop="isSensitive">
<el-input v-model="form.isSensitive" placeholder="请输入是否包含敏感词" />
</el-form-item>
<el-form-item label="敏感词列表" prop="sensitiveWords">
<el-input v-model="form.sensitiveWords" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker clearable
v-model="form.publishTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择发布时间">
</el-date-picker>
</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 { listArticle, getArticle, delArticle, addArticle, updateArticle } from "@/api/vet/article"
export default {
name: "Article",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
articleList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
content: null,
summary: null,
coverImage: null,
images: null,
vetId: null,
vetName: null,
vetAvatar: null,
vetTitle: null,
categoryId: null,
categoryName: null,
tags: null,
isTop: null,
isFeatured: null,
status: null,
isSensitive: null,
sensitiveWords: null,
publishTime: null,
},
//
form: {},
//
rules: {
title: [
{ required: true, message: "文章标题不能为空", trigger: "blur" }
],
content: [
{ required: true, message: "文章内容不能为空", trigger: "blur" }
],
vetId: [
{ required: true, message: "作者不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询兽医经验文章列表 */
getList() {
this.loading = true
listArticle(this.queryParams).then(response => {
this.articleList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
title: null,
content: null,
summary: null,
coverImage: null,
images: null,
vetId: null,
vetName: null,
vetAvatar: null,
vetTitle: null,
categoryId: null,
categoryName: null,
tags: null,
isTop: null,
isFeatured: null,
status: null,
isSensitive: null,
sensitiveWords: null,
publishTime: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: 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
getArticle(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) {
updateArticle(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addArticle(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 delArticle(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('vet/article/export', {
...this.queryParams
}, `article_${new Date().getTime()}.xlsx`)
}
}
}
</script>

10
chenhai-ui/src/views/vet/certificate/index.vue

@ -79,7 +79,7 @@
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:certificate:add']"
v-hasPermi="['vet:certificate:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
@ -90,7 +90,7 @@
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:certificate:edit']"
v-hasPermi="['vet:certificate:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
@ -101,7 +101,7 @@
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:certificate:remove']"
v-hasPermi="['vet:certificate:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
@ -111,7 +111,7 @@
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:certificate:export']"
v-hasPermi="['vet:certificate:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@ -384,7 +384,7 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
this.download('system/certificate/export', {
this.download('vet/certificate/export', {
...this.queryParams
}, `certificate_${new Date().getTime()}.xlsx`)
}

14
chenhai-ui/src/views/vet/info/index.vue

@ -79,7 +79,7 @@
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:info:add']"
v-hasPermi="['vet:info:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
@ -90,7 +90,7 @@
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:info:edit']"
v-hasPermi="['vet:info:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
@ -101,7 +101,7 @@
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:info:remove']"
v-hasPermi="['vet:info:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
@ -111,7 +111,7 @@
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:info:export']"
v-hasPermi="['vet:info:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@ -141,14 +141,14 @@
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:info:edit']"
v-hasPermi="['vet:info:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:info:remove']"
v-hasPermi="['vet:info:remove']"
>删除</el-button>
</template>
</el-table-column>
@ -362,7 +362,7 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
this.download('system/info/export', {
this.download('vet/info/export', {
...this.queryParams
}, `info_${new Date().getTime()}.xlsx`)
}

392
chenhai-ui/src/views/vet/qualification/index.vue

@ -0,0 +1,392 @@
<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="兽医ID" prop="vetId">
<el-input
v-model="queryParams.vetId"
placeholder="请输入兽医ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="真实姓名" prop="realName">
<el-input
v-model="queryParams.realName"
placeholder="请输入真实姓名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input
v-model="queryParams.idCard"
placeholder="请输入身份证号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="证书编号" prop="certificateNo">
<el-input
v-model="queryParams.certificateNo"
placeholder="请输入证书编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申请时间" prop="applyTime">
<el-date-picker clearable
v-model="queryParams.applyTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申请时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核时间" prop="auditTime">
<el-date-picker clearable
v-model="queryParams.auditTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择审核时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核人ID" prop="auditorId">
<el-input
v-model="queryParams.auditorId"
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:qualification: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:qualification: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:qualification: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:qualification:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="qualificationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="资质ID" align="center" prop="qualificationId" />
<el-table-column label="兽医ID" align="center" prop="vetId" />
<el-table-column label="真实姓名" align="center" prop="realName" />
<el-table-column label="身份证号" align="center" prop="idCard" />
<el-table-column label="资质类型" align="center" prop="qualificationType" />
<el-table-column label="证书编号" align="center" prop="certificateNo" />
<el-table-column label="证书文件" align="center" prop="certificateFiles" />
<el-table-column label="申请时间" align="center" prop="applyTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="审核时间" align="center" prop="auditTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.auditTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="审核状态" align="center" prop="auditStatus" />
<el-table-column label="审核意见" align="center" prop="auditOpinion" />
<el-table-column label="审核人ID" align="center" prop="auditorId" />
<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:qualification:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:qualification: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="兽医ID" prop="vetId">
<el-input v-model="form.vetId" placeholder="请输入兽医ID" />
</el-form-item>
<el-form-item label="真实姓名" prop="realName">
<el-input v-model="form.realName" placeholder="请输入真实姓名" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入身份证号" />
</el-form-item>
<el-form-item label="证书编号" prop="certificateNo">
<el-input v-model="form.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
<el-form-item label="证书文件" prop="certificateFiles">
<el-input v-model="form.certificateFiles" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="申请时间" prop="applyTime">
<el-date-picker clearable
v-model="form.applyTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申请时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核时间" prop="auditTime">
<el-date-picker clearable
v-model="form.auditTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择审核时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核意见" prop="auditOpinion">
<el-input v-model="form.auditOpinion" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="审核人ID" prop="auditorId">
<el-input v-model="form.auditorId" 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>
<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 { listQualification, getQualification, delQualification, addQualification, updateQualification } from "@/api/vet/qualification"
export default {
name: "Qualification",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
qualificationList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
vetId: null,
realName: null,
idCard: null,
qualificationType: null,
certificateNo: null,
certificateFiles: null,
applyTime: null,
auditTime: null,
auditStatus: null,
auditOpinion: null,
auditorId: null,
},
//
form: {},
//
rules: {
vetId: [
{ required: true, message: "兽医ID不能为空", trigger: "blur" }
],
realName: [
{ required: true, message: "真实姓名不能为空", trigger: "blur" }
],
idCard: [
{ required: true, message: "身份证号不能为空", trigger: "blur" }
],
qualificationType: [
{ required: true, message: "资质类型不能为空", trigger: "change" }
],
certificateNo: [
{ required: true, message: "证书编号不能为空", trigger: "blur" }
],
certificateFiles: [
{ required: true, message: "证书文件不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询兽医资质列表 */
getList() {
this.loading = true
listQualification(this.queryParams).then(response => {
this.qualificationList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
qualificationId: null,
vetId: null,
realName: null,
idCard: null,
qualificationType: null,
certificateNo: null,
certificateFiles: null,
applyTime: null,
auditTime: null,
auditStatus: null,
auditOpinion: null,
auditorId: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: 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.qualificationId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加兽医资质"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const qualificationId = row.qualificationId || this.ids
getQualification(qualificationId).then(response => {
this.form = response.data
this.open = true
this.title = "修改兽医资质"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.qualificationId != null) {
updateQualification(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addQualification(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const qualificationIds = row.qualificationId || this.ids
this.$modal.confirm('是否确认删除兽医资质编号为"' + qualificationIds + '"的数据项?').then(function() {
return delQualification(qualificationIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('vet/qualification/export', {
...this.queryParams
}, `qualification_${new Date().getTime()}.xlsx`)
}
}
}
</script>

369
chenhai-ui/src/views/vet/review/index.vue

@ -0,0 +1,369 @@
<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="兽医用户ID" prop="vetUserId">
<el-input
v-model="queryParams.vetUserId"
placeholder="请输入兽医用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="客户用户ID" prop="customerUserId">
<el-input
v-model="queryParams.customerUserId"
placeholder="请输入客户用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订单编号" prop="orderNo">
<el-input
v-model="queryParams.orderNo"
placeholder="请输入订单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="评分" prop="rating">
<el-input
v-model="queryParams.rating"
placeholder="请输入评分"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="评价时间" prop="reviewTime">
<el-date-picker clearable
v-model="queryParams.reviewTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择评价时间">
</el-date-picker>
</el-form-item>
<el-form-item label="是否匿名" prop="isAnonymous">
<el-input
v-model="queryParams.isAnonymous"
placeholder="请输入是否匿名"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="回复时间" prop="replyTime">
<el-date-picker clearable
v-model="queryParams.replyTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择回复时间">
</el-date-picker>
</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:review: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:review: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:review: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:review:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="reviewList" @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="兽医用户ID" align="center" prop="vetUserId" />
<el-table-column label="客户用户ID" align="center" prop="customerUserId" />
<el-table-column label="订单编号" align="center" prop="orderNo" />
<el-table-column label="评分" align="center" prop="rating" />
<el-table-column label="评价内容" align="center" prop="content" />
<el-table-column label="评价时间" align="center" prop="reviewTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.reviewTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="是否匿名" align="center" prop="isAnonymous" />
<el-table-column label="回复内容" align="center" prop="replyContent" />
<el-table-column label="回复时间" align="center" prop="replyTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.replyTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<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:review:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:review: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="兽医用户ID" prop="vetUserId">
<el-input v-model="form.vetUserId" placeholder="请输入兽医用户ID" />
</el-form-item>
<el-form-item label="客户用户ID" prop="customerUserId">
<el-input v-model="form.customerUserId" placeholder="请输入客户用户ID" />
</el-form-item>
<el-form-item label="订单编号" prop="orderNo">
<el-input v-model="form.orderNo" placeholder="请输入订单编号" />
</el-form-item>
<el-form-item label="评分" prop="rating">
<el-input v-model="form.rating" placeholder="请输入评分" />
</el-form-item>
<el-form-item label="评价内容">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
<el-form-item label="评价时间" prop="reviewTime">
<el-date-picker clearable
v-model="form.reviewTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择评价时间">
</el-date-picker>
</el-form-item>
<el-form-item label="是否匿名" prop="isAnonymous">
<el-input v-model="form.isAnonymous" placeholder="请输入是否匿名" />
</el-form-item>
<el-form-item label="回复内容">
<editor v-model="form.replyContent" :min-height="192"/>
</el-form-item>
<el-form-item label="回复时间" prop="replyTime">
<el-date-picker clearable
v-model="form.replyTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择回复时间">
</el-date-picker>
</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 { listReview, getReview, delReview, addReview, updateReview } from "@/api/vet/review"
export default {
name: "Review",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
reviewList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
vetUserId: null,
customerUserId: null,
orderNo: null,
rating: null,
content: null,
reviewTime: null,
isAnonymous: null,
replyContent: null,
replyTime: null,
},
//
form: {},
//
rules: {
vetUserId: [
{ required: true, message: "兽医用户ID不能为空", trigger: "blur" }
],
customerUserId: [
{ required: true, message: "客户用户ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询兽医服务评价列表 */
getList() {
this.loading = true
listReview(this.queryParams).then(response => {
this.reviewList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
vetUserId: null,
customerUserId: null,
orderNo: null,
rating: null,
content: null,
reviewTime: null,
isAnonymous: null,
replyContent: null,
replyTime: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: 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
getReview(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) {
updateReview(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addReview(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 delReview(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('vet/review/export', {
...this.queryParams
}, `review_${new Date().getTime()}.xlsx`)
}
}
}
</script>
Loading…
Cancel
Save