From e5cc01382fa8af1b8bb1db729e5224010f6ce53e Mon Sep 17 00:00:00 2001 From: ChaiNingQi <2032830459@qq.com> Date: Thu, 29 Jan 2026 18:39:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E8=B4=A8=E4=B8=8A=E4=BC=A0=E5=92=8C?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E4=BF=A1=E6=81=AF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vet/VetExperienceArticleController.java | 588 ++-- .../controller/vet/VetProductController.java | 63 + .../vet/VetQualificationController.java | 557 +++- .../vet/domain/BusinessScopeConstants.java | 66 - .../vet/domain/VetArticleCategory.java | 112 - .../vet/domain/VetExperienceArticle.java | 21 +- .../com/chenhai/vet/domain/VetProduct.java | 64 +- .../chenhai/vet/domain/VetQualification.java | 476 ++- .../vet/mapper/VetArticleCategoryMapper.java | 13 - .../mapper/VetExperienceArticleMapper.java | 54 +- .../vet/mapper/VetQualificationMapper.java | 4 + .../service/IVetExperienceArticleService.java | 68 +- .../vet/service/IVetProductService.java | 43 + .../vet/service/IVetQualificationService.java | 10 + .../impl/VetExperienceArticleServiceImpl.java | 212 +- .../service/impl/VetProductServiceImpl.java | 162 +- .../impl/VetQualificationServiceImpl.java | 1019 +++++-- .../mapper/vet/VetArticleCategoryMapper.xml | 34 - .../mapper/vet/VetExperienceArticleMapper.xml | 90 +- .../resources/mapper/vet/VetProductMapper.xml | 19 +- .../mapper/vet/VetQualificationMapper.xml | 41 + chenhai-ui/src/api/vet/product.js | 41 + chenhai-ui/src/views/vet/article/index.vue | 2546 ++++++----------- chenhai-ui/src/views/vet/product/index.vue | 345 ++- 24 files changed, 3696 insertions(+), 2952 deletions(-) delete mode 100644 chenhai-system/src/main/java/com/chenhai/vet/domain/BusinessScopeConstants.java delete mode 100644 chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java delete mode 100644 chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java delete mode 100644 chenhai-system/src/main/resources/mapper/vet/VetArticleCategoryMapper.xml diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java index e26df4b..cffcff9 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExperienceArticleController.java @@ -1,27 +1,22 @@ package com.chenhai.web.controller.vet; -import com.chenhai.common.utils.DictUtils; + 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.VetArticleCategory; import com.chenhai.vet.domain.VetExperienceArticle; -import com.chenhai.vet.mapper.VetArticleCategoryMapper; 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.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; - /** - * 兽医经验分享Controller + * 兽医经验文章论坛Controller(列表样式) */ @RestController @RequestMapping("/vet/article") @@ -30,423 +25,171 @@ public class VetExperienceArticleController extends BaseController { @Autowired private IVetExperienceArticleService vetExperienceArticleService; - @Autowired // 确保有这个注解 - private VetArticleCategoryMapper vetArticleCategoryMapper; + @Autowired + private JdbcTemplate jdbcTemplate; - /** - * 简单收藏管理(使用Map存储) - */ + // 简单收藏管理 private static final Map> COLLECTION_STORE = new ConcurrentHashMap<>(); - /** - * 查询兽医经验文章列表 + * 查询所有文章列表(论坛首页) */ @GetMapping("/list") public TableDataInfo list(VetExperienceArticle vetExperienceArticle) { - startPage(); - List 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("/options") - public AjaxResult getCategoryOptions() { - VetArticleCategory query = new VetArticleCategory(); - query.setStatus("0"); - - List categories = vetArticleCategoryMapper.selectVetArticleCategoryList(query); - - // 排序(如果sortOrder为null,放到最后) - if (categories != null) { - categories.sort((c1, c2) -> { - Integer order1 = c1.getSortOrder() != null ? c1.getSortOrder() : 999; - Integer order2 = c2.getSortOrder() != null ? c2.getSortOrder() : 999; - return order1.compareTo(order2); - }); - } - - List> options = new ArrayList<>(); - for (VetArticleCategory category : categories) { - Map option = new LinkedHashMap<>(); - option.put("value", category.getId()); - option.put("label", category.getName()); - options.add(option); + // 默认只查询已发布的文章 + if (vetExperienceArticle.getStatus() == null) { + vetExperienceArticle.setStatus("1"); } - - return AjaxResult.success(options); - } - - - - /** - * 根据分类查询文章 - */ - @GetMapping("/{categoryId}/articles") - public TableDataInfo getArticlesByCategory( - @PathVariable Long categoryId, - @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { - startPage(); - - // 创建查询对象 - VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); // 只查询已发布的文章 - query.setCategoryId(categoryId); // 设置分类ID - - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); + List list = vetExperienceArticleService.selectVetExperienceArticleList(vetExperienceArticle); return getDataTable(list); } - - /** - * 获取文章标签选项 - */ - @GetMapping("/tags/options") - public AjaxResult getTagOptions() { - List> options = new ArrayList<>(); - - // 根据你提供的字典数据写死 - options.add(createOption("1", "疫苗")); - options.add(createOption("2", "传染病")); - options.add(createOption("3", "防治")); - options.add(createOption("4", "养殖")); - options.add(createOption("5", "饲养管理")); - options.add(createOption("6", "繁殖")); - options.add(createOption("7", "牛羊")); - options.add(createOption("8", "药物使用")); - options.add(createOption("9", "特殊病例")); - - return success(options); - } - /** - * 根据标签值查询文章 + * 查询我的文章列表(个人中心) */ - @GetMapping("/tags/{dictValue}/articles") - public TableDataInfo getArticlesByTag( - @PathVariable String dictValue, - @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + @GetMapping("/myList") + public TableDataInfo myList(VetExperienceArticle vetExperienceArticle) { + Long userId = SecurityUtils.getUserId(); + System.out.println("【DEBUG】当前用户ID: " + userId); - startPage(); - - // 标签映射 - String tagName = getTagNameByDictValue(dictValue); - - if (tagName == null || tagName.isEmpty()) { - return getDataTable(new ArrayList<>()); + if (userId == null) { + throw new RuntimeException("用户未登录"); } + // 创建新的查询对象,确保参数正确设置 VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); - query.setTags(tagName); + query.setUserId(userId); // 强制设置用户ID - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); - return getDataTable(list); - } + // 传递其他查询条件 + query.setStatus(vetExperienceArticle.getStatus()); + query.setTitle(vetExperienceArticle.getTitle()); + query.setCategoryId(vetExperienceArticle.getCategoryId()); + query.setCategoryName(vetExperienceArticle.getCategoryName()); + query.setTags(vetExperienceArticle.getTags()); - /** - * 辅助方法:创建选项 - */ - private Map createOption(String value, String label) { - Map option = new HashMap<>(); - option.put("value", value); - option.put("label", label); - return option; - } - - /** - * 根据字典值获取标签名称 - */ - private String getTagNameByDictValue(String dictValue) { - // 写死映射 - Map tagMap = new HashMap<>(); - tagMap.put("1", "疫苗"); - tagMap.put("2", "传染病"); - tagMap.put("3", "防治"); - tagMap.put("4", "养殖"); - tagMap.put("5", "饲养管理"); - tagMap.put("6", "繁殖"); - tagMap.put("7", "牛羊"); - tagMap.put("8", "药物使用"); - tagMap.put("9", "特殊病例"); - - return tagMap.get(dictValue); - } - - /** - * 备用:直接使用标签名称查询的接口 - */ - @GetMapping("/tags/byName/articles") - public TableDataInfo getArticlesByTagName( - @RequestParam("tagName") String tagName, - @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + System.out.println("【DEBUG】查询条件: " + query); startPage(); - - VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); - query.setTags(tagName); - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); return getDataTable(list); } - /** - * 获取所有兽医已发布的文章 + * 查看文章详情(包含相关文章) */ - @GetMapping("/forum/home") - public AjaxResult getForumHome() { - Map forumData = new HashMap<>(); - - // 1. 推荐文章(精选+置顶) - List featuredArticles = vetExperienceArticleService.selectFeaturedArticles(8); - forumData.put("featuredArticles", featuredArticles); - - // 2. 最新文章 - List latestArticles = vetExperienceArticleService.selectLatestArticles(10); - forumData.put("latestArticles", latestArticles); - - // 3. 热门文章(按浏览数) - List hotArticles = vetExperienceArticleService.selectHotArticles(10); - forumData.put("hotArticles", hotArticles); - - // 4. 文章统计 - Map statistics = vetExperienceArticleService.selectForumStatistics(); - forumData.put("statistics", statistics); - - return success(forumData); - } + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + // 增加浏览数 + vetExperienceArticleService.incrementViewCount(id); - /** - * 浏览文章详情(论坛模式) - * 增加浏览数,可以查看所有兽医的文章 - */ - @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("文章不存在或未发布"); + if (article == null) { + return error("文章不存在"); } - // 2. 增加浏览数 - vetExperienceArticleService.incrementViewCount(id); - - // 3. 判断是否是当前用户发布的文章 - Long currentUserId = getUserId(); - boolean isOwner = currentUserId != null && currentUserId.equals(article.getUserId()); - - // 4. 获取相关文章 - List relatedArticles = vetExperienceArticleService.selectRelatedArticles(id, article.getCategoryId(), 4); + // 获取相关文章(同一分类的其他文章) + List relatedArticles = vetExperienceArticleService.selectRelatedArticles( + id, article.getCategoryId(), 4); - // 5. 获取作者的其他文章 - List authorArticles = vetExperienceArticleService.selectArticlesByVetId(article.getUserId(), 5); + // 获取作者其他文章 + List authorArticles = vetExperienceArticleService.selectArticlesByUserId( + article.getUserId(), 5); Map result = new HashMap<>(); result.put("article", article); - result.put("isOwner", isOwner); result.put("relatedArticles", relatedArticles); result.put("authorArticles", authorArticles); + // 判断是否是当前用户 + Long currentUserId = SecurityUtils.getUserId(); + result.put("isOwner", currentUserId != null && currentUserId.equals(article.getUserId())); + result.put("isCollected", currentUserId != null && + COLLECTION_STORE.getOrDefault(currentUserId, Collections.emptySet()).contains(id)); + 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(); + @PostMapping + public AjaxResult add(@RequestBody VetExperienceArticle article) { + Long currentUserId = SecurityUtils.getUserId(); String currentUsername = SecurityUtils.getUsername(); // 设置作者信息 article.setUserId(currentUserId); - article.setVetName(currentUsername); // 暂时用用户名,可以根据需要从用户表获取真实姓名 - - // 设置文章状态为已发布 - article.setStatus("1"); - article.setPublishTime(new Date()); - - // 敏感词检查 - Map 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); + article.setVetName(currentUsername); - int result = vetExperienceArticleService.insertVetExperienceArticle(article); - return toAjax(result).put("articleId", article.getId()); + // 默认状态为已发布 + if (article.getStatus() == null) { + article.setStatus("1"); } - 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.setUserId(currentUserId); - - if (status != null && !status.isEmpty()) { - query.setStatus(status); + // 设置发布时间 + if (article.getPublishTime() == null && "1".equals(article.getStatus())) { + article.setPublishTime(new Date()); } - startPage(); - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); - return getDataTable(list); + int result = vetExperienceArticleService.insertVetExperienceArticle(article); + return toAjax(result).put("articleId", article.getId()); } /** - * 获取我的收藏文章列表 + * 修改文章 */ - @GetMapping("/forum/myCollections") - public TableDataInfo getMyCollections() { - Long currentUserId = getUserId(); - if (currentUserId == null) { - return getDataTable(new ArrayList<>()); - } - - // 获取我的收藏文章ID - Set articleIds = COLLECTION_STORE.get(currentUserId); - if (articleIds == null || articleIds.isEmpty()) { - return getDataTable(new ArrayList<>()); - } + @Log(title = "修改经验文章", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody VetExperienceArticle vetExperienceArticle) { + // 只有作者可以修改自己的文章 + Long currentUserId = SecurityUtils.getUserId(); + VetExperienceArticle original = vetExperienceArticleService.selectVetExperienceArticleById(vetExperienceArticle.getId()); - // 查询文章详情 - List result = new ArrayList<>(); - for (Long articleId : articleIds) { - VetExperienceArticle article = vetExperienceArticleService.selectVetExperienceArticleById(articleId); - if (article != null && "1".equals(article.getStatus())) { - result.add(article); - } + if (original == null || !original.getUserId().equals(currentUserId)) { + return error("没有权限修改此文章"); } - // 按ID倒序(模拟按收藏时间倒序) - result.sort((a1, a2) -> a2.getId().compareTo(a1.getId())); - - return getDataTable(result); + return toAjax(vetExperienceArticleService.updateVetExperienceArticle(vetExperienceArticle)); } + /** - * 获取我的文章简单统计(直接在Controller实现) + * 删除文章 */ - @GetMapping("/my/simpleStats") - public AjaxResult getMySimpleStats() { - // 获取当前用户ID - 使用系统的方法 + @Log(title = "删除经验文章", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + // 只能删除自己的文章 Long currentUserId = SecurityUtils.getUserId(); - System.out.println("当前用户ID: " + currentUserId); // 调试用 - - if (currentUserId == null) { - // 如果是开发测试,可以使用临时用户ID - currentUserId = 1L; // 测试用 - System.out.println("使用测试用户ID: " + currentUserId); + for (Long id : ids) { + VetExperienceArticle article = vetExperienceArticleService.selectVetExperienceArticleById(id); + if (article != null && !article.getUserId().equals(currentUserId)) { + return error("没有权限删除他人文章"); + } } - // 查询当前用户已发布的文章 - VetExperienceArticle query = new VetExperienceArticle(); - query.setUserId(currentUserId); - query.setStatus("1"); // 只查询已发布的 - - System.out.println("查询条件: userId=" + currentUserId + ", status=1"); - - List myArticles = vetExperienceArticleService.selectVetExperienceArticleList(query); - - System.out.println("查询到文章数量: " + myArticles.size()); - - // 统计 - Map stats = new HashMap<>(); - stats.put("publishedCount", myArticles.size()); - - // 使用stream简化统计 - int totalLikes = myArticles.stream() - .mapToInt(a -> a.getLikeCount() != null ? a.getLikeCount() : 0) - .sum(); - - int totalCollects = myArticles.stream() - .mapToInt(a -> a.getCollectCount() != null ? a.getCollectCount() : 0) - .sum(); - - int totalViews = myArticles.stream() - .mapToInt(a -> a.getViewCount() != null ? a.getViewCount() : 0) - .sum(); - - stats.put("totalLikes", totalLikes); - stats.put("totalCollects", totalCollects); - stats.put("totalViews", totalViews); - stats.put("userId", currentUserId); - - return success(stats); + return toAjax(vetExperienceArticleService.deleteVetExperienceArticleByIds(ids)); } /** * 点赞文章 */ - @PostMapping("/forum/{id}/like") + @Log(title = "点赞文章", businessType = BusinessType.UPDATE) + @PostMapping("/{id}/like") public AjaxResult likeArticle(@PathVariable Long id) { int result = vetExperienceArticleService.incrementLikeCount(id); - return toAjax(result); + return toAjax(result).put("message", "点赞成功"); } /** * 收藏文章 */ - @PostMapping("/forum/{id}/collect") - public AjaxResult collectArticle(@PathVariable("id") Long id) { - Long currentUserId = getUserId(); + @PostMapping("/{id}/collect") + public AjaxResult collectArticle(@PathVariable Long id) { + Long currentUserId = SecurityUtils.getUserId(); if (currentUserId == null) { return error("请先登录"); } @@ -467,113 +210,110 @@ public class VetExperienceArticleController extends BaseController { // 检查是否已收藏 if (myCollections.contains(id)) { - return error("已收藏过该文章"); + // 取消收藏 + myCollections.remove(id); + return success("已取消收藏"); + } else { + // 添加收藏 + myCollections.add(id); + // 增加文章收藏数 + vetExperienceArticleService.incrementCollectCount(id); + return success("收藏成功"); } - - // 添加收藏 - myCollections.add(id); - - // 增加文章收藏数 - vetExperienceArticleService.incrementCollectCount(id); - - return success("收藏成功"); } + /** - * 搜索文章 + * 获取我的收藏文章列表 */ - @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"); // 只搜索已发布的文章 + @GetMapping("/myCollections") + public TableDataInfo getMyCollections() { + Long currentUserId = SecurityUtils.getUserId(); + if (currentUserId == null) { + return getDataTable(new ArrayList<>()); + } - if (keyword != null && !keyword.trim().isEmpty()) { - query.setTitle(keyword.trim()); + // 获取我的收藏文章ID + Set articleIds = COLLECTION_STORE.get(currentUserId); + if (articleIds == null || articleIds.isEmpty()) { + return getDataTable(new ArrayList<>()); } - if (categoryId != null) { - query.setCategoryId(categoryId); + // 查询文章详情 + List result = new ArrayList<>(); + for (Long articleId : articleIds) { + VetExperienceArticle article = vetExperienceArticleService.selectVetExperienceArticleById(articleId); + if (article != null && "1".equals(article.getStatus())) { + result.add(article); + } } + // 按收藏时间倒序(这里用ID倒序模拟) + result.sort((a1, a2) -> a2.getId().compareTo(a1.getId())); + startPage(); - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); - /*List list = vetExperienceArticleService.searchArticles(keyword);*/ - return getDataTable(list); + return getDataTable(result); } - /** - * 获取热门标签 + * 获取论坛统计信息 */ - /*@GetMapping("/forum/hotTags") - public AjaxResult getHotTags(@RequestParam(value = "limit", defaultValue = "15") Integer limit) { - List> hotTags = vetExperienceArticleService.selectHotTags(limit); - return success(hotTags); - }*/ + @GetMapping("/statistics") + public AjaxResult getStatistics() { + return success(vetExperienceArticleService.selectForumStatistics()); + } + /** - * 2. 根据标签搜索文章(带分页) + * 获取最新文章 */ - /* @GetMapping("/listByTag") - public TableDataInfo listByTag(@RequestParam("tag") String tag, - @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { - startPage(); - - // 创建查询对象 - VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); // 只查已发布的 - query.setTags(tag); // 设置标签条件 - - List list = vetExperienceArticleService.selectVetExperienceArticleList(query); - return getDataTable(list); - }*/ + @GetMapping("/latest") + public AjaxResult getLatestArticles(@RequestParam(defaultValue = "10") Integer limit) { + List articles = vetExperienceArticleService.selectLatestArticles(limit); + return success(articles); + } /** - * 新增文章 - 调整为论坛发布模式 + * 获取分类选项 */ - /* @PreAuthorize("@ss.hasPermi('vet:article:add')")*/ - @Log(title = "兽医经验文章", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody VetExperienceArticle vetExperienceArticle) { - // 调用论坛发布接口 - return publishForumArticle(vetExperienceArticle); - } + @GetMapping("/options") + public AjaxResult getCategoryOptions() { + // 直接从字典表查询 + String sql = "SELECT dict_value as value, dict_label as label, dict_sort as sortOrder " + + "FROM sys_dict_data " + + "WHERE dict_type = 'vet_experience_category' AND status = '0' " + + "ORDER BY dict_sort ASC"; + + List> options = jdbcTemplate.query(sql, (rs, rowNum) -> { + Map option = new HashMap<>(); + option.put("value", rs.getString("value")); // 字典值作为value + option.put("label", rs.getString("label")); // 字典标签作为label + option.put("sortOrder", rs.getInt("sortOrder")); // 排序字段 + return option; + }); + return success(options); + } /** - * 敏感词检查方法 + * 获取标签选项 */ - private Map checkSensitiveWords(VetExperienceArticle article) { - Map result = new HashMap<>(); - result.put("hasSensitive", false); - result.put("sensitiveWords", ""); + @GetMapping("/tags/options") + public AjaxResult getTagOptions() { + List> options = new ArrayList<>(); - // TODO: 实现敏感词检查逻辑 - // 可以调用专门的敏感词服务 - // List sensitiveWords = sensitiveWordService.detect(article.getTitle() + " " + article.getContent()); + String[][] tagData = { + {"疫苗", "疫苗"}, {"传染病", "传染病"}, {"防治", "防治"}, + {"养殖", "养殖"}, {"饲养管理", "饲养管理"}, {"繁殖", "繁殖"}, + {"牛羊", "牛羊"}, {"药物使用", "药物使用"}, {"特殊病例", "特殊病例"} + }; - // 示例逻辑 - if (article.getTitle() != null && article.getTitle().contains("敏感词示例")) { - result.put("hasSensitive", true); - result.put("sensitiveWords", "敏感词示例"); + for (String[] tag : tagData) { + Map option = new HashMap<>(); + option.put("label", tag[0]); + option.put("value", tag[1]); + options.add(option); } - return result; - } - - /** - * 导出兽医经验文章列表 - */ - /* @PreAuthorize("@ss.hasPermi('vet:article:export')")*/ - @Log(title = "兽医经验文章", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, VetExperienceArticle vetExperienceArticle) { - List list = vetExperienceArticleService.selectVetExperienceArticleList(vetExperienceArticle); - ExcelUtil util = new ExcelUtil<>(VetExperienceArticle.class); - util.exportExcel(response, list, "兽医经验文章数据"); + return success(options); } } \ No newline at end of file diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java index 65010a8..c5a1fdd 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java @@ -1,6 +1,8 @@ package com.chenhai.web.controller.vet; import java.util.List; + +import com.chenhai.common.utils.SecurityUtils; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -103,4 +105,65 @@ public class VetProductController extends BaseController } + + /** + * 提交审核 + */ + @PreAuthorize("@ss.hasPermi('vet:product:submit')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/submitAudit/{id}") + public AjaxResult submitForAudit(@PathVariable("id") Long id) + { + return toAjax(vetProductService.submitForAudit(id)); + } + + /** + * 审核产品 + */ + @PreAuthorize("@ss.hasPermi('vet:product:audit')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/audit") + public AjaxResult auditProduct(@RequestBody VetProduct vetProduct) + { + Long auditUserId = SecurityUtils.getUserId(); + return toAjax(vetProductService.auditProduct( + vetProduct.getId(), + vetProduct.getAuditStatus(), + vetProduct.getAuditOpinion(), + auditUserId + )); + } + + /** + * 上架产品 + */ + @PreAuthorize("@ss.hasPermi('vet:product:publish')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/publish/{id}") + public AjaxResult publishProduct(@PathVariable("id") Long id) + { + return toAjax(vetProductService.publishProduct(id)); + } + + /** + * 下架产品 + */ + @PreAuthorize("@ss.hasPermi('vet:product:offline')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/offline/{id}") + public AjaxResult offlineProduct(@PathVariable("id") Long id) + { + return toAjax(vetProductService.offlineProduct(id)); + } + + /** + * 取消审核 + */ + @PreAuthorize("@ss.hasPermi('vet:product:edit')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/cancelAudit/{id}") + public AjaxResult cancelAudit(@PathVariable("id") Long id) + { + return toAjax(vetProductService.cancelAudit(id)); + } } diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java index 8f909ac..9c63c5c 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetQualificationController.java @@ -6,27 +6,19 @@ 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.file.FileUtils; -import com.chenhai.common.utils.poi.ExcelUtil; -import com.chenhai.vet.domain.BusinessScopeConstants; import com.chenhai.vet.domain.VetQualification; import com.chenhai.vet.service.IVetQualificationService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.io.File; -import java.net.URLEncoder; -import java.text.SimpleDateFormat; import java.util.*; - -import static com.chenhai.framework.datasource.DynamicDataSourceContextHolder.log; +import java.text.SimpleDateFormat; /** * 兽医资质控制器(合并证书功能) @@ -37,17 +29,13 @@ import static com.chenhai.framework.datasource.DynamicDataSourceContextHolder.lo @RequestMapping("/vet/qualification") public class VetQualificationController extends BaseController { + private static final Logger log = LoggerFactory.getLogger(VetQualificationController.class); @Autowired private IVetQualificationService vetQualificationService; @Autowired private JdbcTemplate jdbcTemplate; - @Value("${chenhai.profile}") - private String uploadRootPath; - - private static final String QUALIFICATION_FILE_PATH = "/vet/qualification/"; - /** * 获取资质类型选项(下拉框用) */ @@ -88,7 +76,6 @@ public class VetQualificationController extends BaseController return AjaxResult.success(options); } - /** * 查询兽医资质列表(含证书信息) */ @@ -123,32 +110,108 @@ public class VetQualificationController extends BaseController } /** - * 用户详情页查询资质证书 + * 查询用户的证书列表(展开每个证书) */ @PreAuthorize("@ss.hasPermi('vet:qualification:list')") - @GetMapping("/listForDetail") - public TableDataInfo listForDetail(@RequestParam(value = "userId", required = false) Long userId) + @GetMapping("/certificate/list") + public TableDataInfo getCertificateList(VetQualification vetQualification) { startPage(); - Long currentUserId = SecurityUtils.getUserId(); + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + vetQualification.setUserId(userId); + } - if (currentUserId == null) { - return getDataTable(List.of()); + List qualifications = vetQualificationService.selectVetQualificationList(vetQualification); + + List> certificateList = new ArrayList<>(); + for (VetQualification qualification : qualifications) { + List certList = qualification.getCertificateList(); + if (certList != null && !certList.isEmpty()) { + for (VetQualification.CertificateInfo cert : certList) { + Map certMap = new HashMap<>(); + certMap.put("qualificationId", qualification.getQualificationId()); + certMap.put("realName", qualification.getRealName()); + + certMap.put("certName", cert.getCertName()); + certMap.put("certificateNo", cert.getCertificateNo()); + certMap.put("issueDate", cert.getIssueDate()); + certMap.put("expireDate", cert.getExpireDate()); + certMap.put("issueOrg", cert.getIssueOrg()); + certMap.put("certificateFiles", cert.getCertificateFiles()); + certMap.put("certStatus", cert.getCertStatus()); + certMap.put("certStatusLabel", getCertStatusLabel(cert.getCertStatus())); + + if (cert.getCertId() != null) { + certMap.put("certId", String.valueOf(cert.getCertId())); // 转为String + } + else if (qualification.getCertId() != null) { + certMap.put("certId", String.valueOf(qualification.getCertId())); // 转为String + } + + certificateList.add(certMap); + } + } } + return getDataTable(certificateList); + } + + /** + * 根据证书ID查询证书详细信息 + * 证书信息存储在资质的certificatesJson字段中,通过数据库JSON查询获取 + */ + @GetMapping("/certificate/{certId}") + public AjaxResult getCertificateByCertId(@PathVariable("certId") Long certId) + { + try { + Long currentUserId = SecurityUtils.getUserId(); + boolean isAdmin = SecurityUtils.isAdmin(currentUserId); + + Map certificateInfo = vetQualificationService + .selectCertificateWithQualificationByCertId(certId, isAdmin ? null : currentUserId); + + if (certificateInfo == null || certificateInfo.isEmpty()) { + return AjaxResult.error("证书不存在或没有权限查看"); + } + + Object expireDateObj = certificateInfo.get("expireDate"); + if (expireDateObj instanceof Date) { + Date expireDate = (Date) expireDateObj; + String certStatus = calculateCertStatus(expireDate); + String certStatusLabel = getCertStatusLabel(certStatus); + + certificateInfo.put("certStatus", certStatus); + certificateInfo.put("certStatusLabel", certStatusLabel); + } + + return AjaxResult.success(certificateInfo); - if (userId == null) { - return getDataTable(List.of()); + } catch (Exception e) { + return AjaxResult.error("查询证书失败:" + e.getMessage()); } + } - // 权限检查:管理员或查看自己 - if (!SecurityUtils.isAdmin(currentUserId) && !userId.equals(currentUserId)) { - return getDataTable(List.of()); + /** + * 计算证书状态 + */ + private String calculateCertStatus(Date expireDate) { + if (expireDate == null) { + return "0"; } - VetQualification query = new VetQualification(); - query.setUserId(userId); - List list = vetQualificationService.selectVetQualificationList(query); - return getDataTable(list); + Date today = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 30); + Date thirtyDaysLater = calendar.getTime(); + + if (expireDate.before(today)) { + return "2"; + } else if (expireDate.before(thirtyDaysLater)) { + return "1"; + } else { + return "0"; + } } /** @@ -165,52 +228,43 @@ public class VetQualificationController extends BaseController if (list.isEmpty()) { result.put("needPopup", true); result.put("message", "请先填写兽医资质信息"); + result.put("status", "empty"); } else { VetQualification qualification = list.get(0); - if ("0".equals(qualification.getAuditStatus())) { - result.put("needPopup", false); - result.put("message", "您的资质正在审核中,请耐心等待"); - result.put("status", "pending"); - } else if ("1".equals(qualification.getAuditStatus())) { - result.put("needPopup", false); - result.put("message", "您的资质已审核通过"); - result.put("status", "approved"); - } else if ("2".equals(qualification.getAuditStatus())) { + String auditStatus = qualification.getAuditStatus(); + + boolean needPopup = auditStatus == null; + + if (auditStatus == null) { result.put("needPopup", true); - result.put("message", "您的资质审核不通过,请重新填写"); - result.put("status", "rejected"); - } else { - result.put("needPopup", false); result.put("message", "请先提交资质审核"); result.put("status", "needSubmit"); + } else { + result.put("needPopup", false); + + switch (auditStatus) { + case "0": + case "3": + result.put("message", "您的资质正在审核中,请耐心等待"); + result.put("status", "pending"); + break; + case "1": + result.put("message", "您的资质已审核通过"); + result.put("status", "approved"); + break; + case "2": + result.put("message", "您的资质审核不通过"); + result.put("status", "rejected"); + break; + default: + result.put("message", "您的资质已提交审核"); + result.put("status", "submitted"); + break; + } } } - return AjaxResult.success(result); - } - - /** - * 获取经营范围详情 - */ - @GetMapping("/scope/detail/{scopeId}") - public AjaxResult getScopeDetail(@PathVariable String scopeId) { - Map detail = new HashMap<>(); - detail.put("scopeId", scopeId); - detail.put("scopeName", BusinessScopeConstants.getScopeName(scopeId)); - detail.put("requiredQualifications", BusinessScopeConstants.getRequiredQualifications(scopeId)); - return AjaxResult.success(detail); - } - /** - * 导出兽医资质列表 - */ - @PreAuthorize("@ss.hasPermi('vet:qualification:export')") - @Log(title = "兽医资质", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, VetQualification vetQualification) - { - List list = vetQualificationService.selectVetQualificationList(vetQualification); - ExcelUtil util = new ExcelUtil(VetQualification.class); - util.exportExcel(response, list, "兽医资质数据"); + return AjaxResult.success(result); } /** @@ -225,7 +279,6 @@ public class VetQualificationController extends BaseController return AjaxResult.error("资质信息不存在"); } - // 权限检查:管理员或查看自己 Long currentUserId = SecurityUtils.getUserId(); if (!SecurityUtils.isAdmin(currentUserId) && !qualification.getUserId().equals(currentUserId)) { return AjaxResult.error("没有权限查看此资质"); @@ -248,7 +301,6 @@ public class VetQualificationController extends BaseController vetQualification.setUserId(sysUserId); vetQualification.setCreateBy(username); - // 设置默认提醒天数 if (vetQualification.getRemindDays() == null) { vetQualification.setRemindDays(30); } @@ -268,7 +320,6 @@ public class VetQualificationController extends BaseController String sql = "INSERT IGNORE INTO vet_user (sys_user_id, username, create_time) VALUES (?, ?, NOW())"; jdbcTemplate.update(sql, sysUserId, username); } catch (Exception e) { - // 忽略异常 } } @@ -280,7 +331,6 @@ public class VetQualificationController extends BaseController @PutMapping public AjaxResult edit(@RequestBody VetQualification vetQualification) { - // 检查权限:普通用户只能修改自己的资质 Long currentUserId = SecurityUtils.getUserId(); if (!SecurityUtils.isAdmin(currentUserId)) { VetQualification existing = vetQualificationService.selectVetQualificationByQualificationId(vetQualification.getQualificationId()); @@ -300,7 +350,6 @@ public class VetQualificationController extends BaseController @DeleteMapping("/{qualificationIds}") public AjaxResult remove(@PathVariable Long[] qualificationIds) { - // 检查权限 Long currentUserId = SecurityUtils.getUserId(); if (!SecurityUtils.isAdmin(currentUserId)) { for (Long id : qualificationIds) { @@ -319,39 +368,70 @@ public class VetQualificationController extends BaseController */ @Log(title = "兽医资质", businessType = BusinessType.UPDATE) @PostMapping("/submit") - public AjaxResult submitQualification(@RequestBody VetQualification vetQualification) { + public AjaxResult submitQualification(@RequestBody Object requestBody) { try { - Long userId = SecurityUtils.getUserId(); - String username = SecurityUtils.getUsername(); - - // 设置必要字段 - vetQualification.setUserId(userId); - vetQualification.setCreateBy(username); - vetQualification.setAuditStatus("0"); // 设置为待审核状态 - vetQualification.setApplyTime(new Date()); // 设置申请时间 - - int result; - // 如果已有资质ID,则为更新操作(重新提交审核) - if (vetQualification.getQualificationId() != null) { - vetQualification.setUpdateBy(username); - result = vetQualificationService.updateVetQualification(vetQualification); + if (requestBody instanceof Map) { + @SuppressWarnings("unchecked") + Map requestData = (Map) requestBody; + return processNewFormat(requestData); } else { - // 新增资质记录并提交审核 - result = vetQualificationService.insertVetQualification(vetQualification); - } + ObjectMapper mapper = new ObjectMapper(); + Map requestData = mapper.convertValue(requestBody, Map.class); - if (result > 0) { - return AjaxResult.success("资质提交成功,等待审核", vetQualification); - } else { - return AjaxResult.error("资质提交失败"); + if (requestData.containsKey("realName") && requestData.containsKey("certificates")) { + return processNewFormat(requestData); + } else { + return processOldFormat(requestBody); + } } - } catch (Exception e) { - log.error("提交资质失败", e); return AjaxResult.error("提交失败:" + e.getMessage()); } } + private AjaxResult processNewFormat(Map requestData) { + Long userId = SecurityUtils.getUserId(); + int result = vetQualificationService.submitQualification(requestData); + + if (result > 0) { + return AjaxResult.success("资质提交成功,等待审核"); + } else { + return AjaxResult.error("资质提交失败"); + } + } + + private AjaxResult processOldFormat(Object requestBody) { + VetQualification vetQualification; + if (requestBody instanceof VetQualification) { + vetQualification = (VetQualification) requestBody; + } else { + ObjectMapper mapper = new ObjectMapper(); + vetQualification = mapper.convertValue(requestBody, VetQualification.class); + } + + Long userId = SecurityUtils.getUserId(); + String username = SecurityUtils.getUsername(); + + vetQualification.setUserId(userId); + vetQualification.setCreateBy(username); + vetQualification.setAuditStatus("0"); + vetQualification.setApplyTime(new Date()); + + int result; + if (vetQualification.getQualificationId() != null) { + vetQualification.setUpdateBy(username); + result = vetQualificationService.updateVetQualification(vetQualification); + } else { + result = vetQualificationService.insertVetQualification(vetQualification); + } + + if (result > 0) { + return AjaxResult.success("资质提交成功,等待审核", vetQualification); + } else { + return AjaxResult.error("资质提交失败"); + } + } + /** * 审核操作 */ @@ -369,7 +449,6 @@ public class VetQualificationController extends BaseController public AjaxResult getByUserId(@PathVariable Long userId) { Long currentUserId = SecurityUtils.getUserId(); - // 权限检查 if (!SecurityUtils.isAdmin(currentUserId) && !userId.equals(currentUserId)) { return error("没有权限查看其他用户的资质"); } @@ -378,22 +457,6 @@ public class VetQualificationController extends BaseController return success(list); } - /** - * 获取即将过期的资质证书 - */ - @GetMapping("/expiring/{userId}") - public AjaxResult getExpiringQualifications(@PathVariable Long userId) { - Long currentUserId = SecurityUtils.getUserId(); - - // 权限检查 - if (!SecurityUtils.isAdmin(currentUserId) && !userId.equals(currentUserId)) { - return error("没有权限查看其他用户的证书"); - } - - List list = vetQualificationService.selectExpiringQualifications(userId); - return success(list); - } - /** * 获取证书统计信息 */ @@ -401,7 +464,6 @@ public class VetQualificationController extends BaseController public AjaxResult getStatistics(@PathVariable Long userId) { Long currentUserId = SecurityUtils.getUserId(); - // 权限检查 if (!SecurityUtils.isAdmin(currentUserId) && !userId.equals(currentUserId)) { return error("没有权限查看其他用户的统计信息"); } @@ -417,7 +479,6 @@ public class VetQualificationController extends BaseController public AjaxResult manualCheck(@PathVariable Long userId) { Long currentUserId = SecurityUtils.getUserId(); - // 权限检查 if (!SecurityUtils.isAdmin(currentUserId) && !userId.equals(currentUserId)) { return error("没有权限为其他用户检查证书"); } @@ -425,4 +486,262 @@ public class VetQualificationController extends BaseController vetQualificationService.manualCheckCertificates(userId); return success("证书检查完成"); } + + /** + * 获取证书状态标签 + */ + private String getCertStatusLabel(String certStatus) { + if ("0".equals(certStatus)) return "正常"; + else if ("1".equals(certStatus)) return "即将过期"; + else if ("2".equals(certStatus)) return "已过期"; + else return "未知"; + } + + + /** + * 修改单个证书信息并提交审核(根据证书ID修改单个证书) + */ + @Log(title = "兽医资质证书", businessType = BusinessType.UPDATE) + @PostMapping("/certificate/updateAndSubmit") + public AjaxResult updateCertificateAndSubmit(@RequestBody Map requestData) { + try { + log.info("修改单个证书并提交审核请求数据: {}", requestData); + + // 1. 获取证书ID(要修改的证书) + // 1. 获取字符串格式的ID + String certIdStr = null; + Object certIdObj = requestData.get("certId"); + if (certIdObj != null) { + certIdStr = certIdObj.toString(); + } + + if (certIdStr == null || certIdStr.trim().isEmpty()) { + return AjaxResult.error("证书ID不能为空"); + } + + // 2. 字符串转Long + Long certId; + try { + certId = Long.parseLong(certIdStr); + } catch (NumberFormatException e) { + log.error("证书ID格式错误: {}", certIdStr, e); + return AjaxResult.error("证书ID格式错误"); + } + + // 3. 继续原有逻辑(使用Long类型的certId) + Long qualificationId = extractLongFromObject(requestData.get("qualificationId")); + if (qualificationId == null) { + return AjaxResult.error("资质ID不能为空"); + } + + // 3. 查询整个资质信息 + VetQualification existingQualification = vetQualificationService.selectVetQualificationByQualificationId(qualificationId); + if (existingQualification == null) { + return AjaxResult.error("资质信息不存在"); + } + + // 4. 权限检查 + Long currentUserId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(currentUserId) && !existingQualification.getUserId().equals(currentUserId)) { + return AjaxResult.error("无权操作此证书"); + } + + // 5. 获取现有证书列表 + List certificateList = existingQualification.getCertificateList(); + if (certificateList == null || certificateList.isEmpty()) { + return AjaxResult.error("该资质没有证书信息"); + } + + // 6. 查找并更新指定证书 + boolean certificateFound = false; + for (VetQualification.CertificateInfo cert : certificateList) { + if (cert.getCertificateId() != null && cert.getCertificateId().equals(certId)) { + // 更新证书信息 + updateSingleCertificate(cert, requestData); + certificateFound = true; + break; + } + } + + if (!certificateFound) { + return AjaxResult.error("未找到要修改的证书"); + } + + // 7. 创建更新对象 + VetQualification updateQualification = new VetQualification(); + updateQualification.setQualificationId(qualificationId); + + // 8. 更新基础信息(如果有的话) + updateBasicInfo(requestData, updateQualification); + + // 9. 更新证书列表到JSON + updateCertificatesToJson(certificateList, updateQualification); + + // 10. 更新主表字段(使用第一个证书的信息) + if (!certificateList.isEmpty()) { + VetQualification.CertificateInfo firstCert = certificateList.get(0); + updateQualification.setCertName(firstCert.getCertName()); + updateQualification.setCertificateNo(firstCert.getCertificateNo()); + updateQualification.setIssueOrg(firstCert.getIssueOrg()); + updateQualification.setCertificateFiles(firstCert.getCertificateFiles()); + updateQualification.setIssueDate(firstCert.getIssueDate()); + updateQualification.setExpireDate(firstCert.getExpireDate()); + } + + // 11. 设置审核状态为"待审核" + updateQualification.setAuditStatus("0"); + updateQualification.setAuditOpinion(null); + updateQualification.setApplyTime(new Date()); + + // 12. 设置更新人信息 + updateQualification.setUpdateBy(SecurityUtils.getUsername()); + updateQualification.setUpdateTime(new Date()); + + // 13. 执行更新 + int result = vetQualificationService.updateVetQualification(updateQualification); + + if (result > 0) { + log.info("单个证书修改并提交审核成功,certId: {}, qualificationId: {}", certId, qualificationId); + return AjaxResult.success("证书修改成功,资质已提交审核"); + } else { + return AjaxResult.error("操作失败,请稍后重试"); + } + + } catch (Exception e) { + log.error("修改单个证书并提交审核失败", e); + return AjaxResult.error("操作失败: " + e.getMessage()); + } + } + + /** + * 更新单个证书信息 + */ + private void updateSingleCertificate(VetQualification.CertificateInfo cert, Map requestData) { + if (requestData.containsKey("certName")) { + cert.setCertName((String) requestData.get("certName")); + } + if (requestData.containsKey("certificateNo")) { + cert.setCertificateNo((String) requestData.get("certificateNo")); + } + if (requestData.containsKey("issueOrg")) { + cert.setIssueOrg((String) requestData.get("issueOrg")); + } + if (requestData.containsKey("certificateFiles")) { + cert.setCertificateFiles((String) requestData.get("certificateFiles")); + } + if (requestData.containsKey("issueDate")) { + Object issueDateObj = requestData.get("issueDate"); + if (issueDateObj instanceof String) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + cert.setIssueDate(sdf.parse((String) issueDateObj)); + } catch (Exception e) { + log.warn("解析发证日期失败: {}", issueDateObj); + } + } + } + if (requestData.containsKey("expireDate")) { + Object expireDateObj = requestData.get("expireDate"); + if (expireDateObj instanceof String) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + cert.setExpireDate(sdf.parse((String) expireDateObj)); + } catch (Exception e) { + log.warn("解析到期日期失败: {}", expireDateObj); + } + } + } + } + + /** + * 更新基础信息 + */ + private void updateBasicInfo(Map requestData, VetQualification updateQualification) { + if (requestData.containsKey("realName")) { + updateQualification.setRealName((String) requestData.get("realName")); + } + if (requestData.containsKey("idCard")) { + updateQualification.setIdCard((String) requestData.get("idCard")); + } + if (requestData.containsKey("qualificationType")) { + updateQualification.setQualificationType((String) requestData.get("qualificationType")); + } + if (requestData.containsKey("scopeIds")) { + Object scopeIdsObj = requestData.get("scopeIds"); + if (scopeIdsObj instanceof List) { + @SuppressWarnings("unchecked") + List scopeIdsList = (List) scopeIdsObj; + updateQualification.setScopeIds(String.join(",", scopeIdsList)); + } else if (scopeIdsObj instanceof String) { + updateQualification.setScopeIds((String) scopeIdsObj); + } + } + } + + /** + * 更新证书列表到JSON + */ + private void updateCertificatesToJson(List certificateList, VetQualification updateQualification) { + try { + List> certMaps = new ArrayList<>(); + for (VetQualification.CertificateInfo cert : certificateList) { + Map certMap = new HashMap<>(); + certMap.put("certName", cert.getCertName()); + certMap.put("certificateNo", cert.getCertificateNo()); + certMap.put("issueOrg", cert.getIssueOrg()); + certMap.put("certificateFiles", cert.getCertificateFiles()); + + if (cert.getIssueDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + certMap.put("issueDate", sdf.format(cert.getIssueDate())); + } + + if (cert.getExpireDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + certMap.put("expireDate", sdf.format(cert.getExpireDate())); + } + + if (cert.getCertificateId() != null) { + certMap.put("certId", cert.getCertificateId()); + } + + if (cert.getCertStatus() != null) { + certMap.put("certStatus", cert.getCertStatus()); + } + + certMaps.add(certMap); + } + + ObjectMapper mapper = new ObjectMapper(); + String certificatesJson = mapper.writeValueAsString(certMaps); + updateQualification.setCertificatesJson(certificatesJson); + + } catch (Exception e) { + log.error("更新证书JSON失败", e); + throw new RuntimeException("更新证书JSON失败"); + } + } + + /** + * 从对象中提取Long值 + */ + private Long extractLongFromObject(Object obj) { + if (obj == null) { + return null; + } + try { + if (obj instanceof Number) { + return ((Number) obj).longValue(); + } else if (obj instanceof String) { + String str = ((String) obj).trim(); + if (!str.isEmpty()) { + return Long.parseLong(str); + } + } + } catch (Exception e) { + log.warn("提取Long值失败: {}", obj, e); + } + + return null; + } } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/BusinessScopeConstants.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/BusinessScopeConstants.java deleted file mode 100644 index 32e3a64..0000000 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/BusinessScopeConstants.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.chenhai.vet.domain; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * 经营范围常量 - */ -public class BusinessScopeConstants { - - // 经营范围映射 - public static final Map SCOPE_MAP = new LinkedHashMap() {{ - put("1", "畜禽诊疗"); - put("2", "宠物诊疗"); - put("3", "动物防疫"); - put("4", "检疫检验"); - put("5", "兽药经营"); - put("6", "饲料经营"); - put("7", "畜牧技术咨询"); - put("8", "畜禽养殖"); - put("9", "宠物美容"); - put("10", "宠物寄养"); - }}; - - // 所需资质映射 - public static final Map REQUIRED_QUALIFICATIONS = new LinkedHashMap() {{ - put("1", "执业兽医资格证、动物诊疗许可证"); - put("2", "执业兽医资格证、动物诊疗许可证、宠物诊疗许可证"); - put("3", "执业兽医资格证、动物防疫员证"); - put("4", "官方兽医资格证、检疫员证"); - put("5", "兽药经营许可证、GSP证书"); - put("6", "饲料经营许可证"); - put("7", "高级畜牧师证、技术顾问证书"); - put("8", "养殖场备案证、动物防疫合格证"); - put("9", "宠物美容师资格证"); - put("10", "动物防疫合格证、寄养场所备案证"); - }}; - - /** - * 根据ID获取经营范围名称 - */ - public static String getScopeName(String scopeId) { - return SCOPE_MAP.get(scopeId); - } - - /** - * 根据ID获取所需资质 - */ - public static String getRequiredQualifications(String scopeId) { - return REQUIRED_QUALIFICATIONS.get(scopeId); - } - - /** - * 获取所有经营范围选项 - */ - public static Map getAllScopes() { - return SCOPE_MAP; - } - - /** - * 验证经营范围ID是否有效 - */ - public static boolean isValidScopeId(String scopeId) { - return SCOPE_MAP.containsKey(scopeId); - } -} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java deleted file mode 100644 index f3ee642..0000000 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetArticleCategory.java +++ /dev/null @@ -1,112 +0,0 @@ -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(); - } -} diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java index 294e828..62c5ddd 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperienceArticle.java @@ -65,7 +65,7 @@ public class VetExperienceArticle extends BaseEntity private String categoryName; /** 标签(逗号分隔) */ - @Excel(name = "标签", readConverterExp = "逗=号分隔") + @Excel(name = "标签", dictType = "vet_experience_tag") private String tags; /** 是否置顶(0否 1是) */ @@ -77,9 +77,26 @@ public class VetExperienceArticle extends BaseEntity private String isFeatured; /** 状态(0草稿 1已发布 2审核中 3已驳回) */ - @Excel(name = "状态", readConverterExp = "0=草稿,1=已发布,2=审核中,3=已驳回") + @Excel(name = "状态", dictType = "article_status") private String status; + /** 审核状态(0待审核 1审核中 2审核通过 3审核驳回 4敏感内容驳回) */ + private String auditStatus; + + /** 审核意见 */ + private String auditOpinion; + + /** 审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date auditTime; + + /** 审核人ID */ + private Long auditorId; + + /** 审核人姓名 */ + private String auditorName; + + /** 是否包含敏感词(0否 1是) */ @Excel(name = "是否包含敏感词", readConverterExp = "0=否,1=是") private String isSensitive; diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetProduct.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetProduct.java index 39a65b1..f302c0f 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetProduct.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetProduct.java @@ -25,14 +25,15 @@ public class VetProduct extends BaseEntity @Excel(name = "产品名称") private String name; - /** 产品类型:medicine-兽药/vaccine-疫苗/supplement-保健品 */ - @Excel(name = "产品类型:medicine-兽药/vaccine-疫苗/supplement-保健品") + /** 产品类型(字典:vet_product_type) */ + @Excel(name = "产品类型", dictType = "medicine_type") private String type; - /** 产品分类 */ - @Excel(name = "产品分类") + /** 产品分类(字典:vet_product_category) */ + @Excel(name = "产品分类", dictType = "vet_product_category") private String category; + /** 规格 */ @Excel(name = "规格") private String specification; @@ -105,8 +106,8 @@ public class VetProduct extends BaseEntity @Excel(name = "注意事项") private String precautions; - /** 状态:0-草稿/1-上架/2-下架 */ - @Excel(name = "状态:0-草稿/1-上架/2-下架") + /** 上架状态(字典:vet_product_status) */ + @Excel(name = "上架状态", dictType = "sys_publish_status") private String status; /** 删除标识:0-正常/1-删除 */ @@ -131,6 +132,21 @@ public class VetProduct extends BaseEntity @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") private Date updatedAt; + + /** 审核状态(字典:audit_status) */ + @Excel(name = "审核状态", dictType = "audit_status") + private String auditStatus; + /** 审核意见 */ + @Excel(name = "审核意见") + private String auditOpinion; + + /** 审核人ID */ + private Long auditUserId; + + /** 审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date auditTime; + public void setId(Long id) { this.id = id; @@ -411,6 +427,38 @@ public class VetProduct extends BaseEntity return updatedAt; } + public String getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(String auditStatus) { + this.auditStatus = auditStatus; + } + + public String getAuditOpinion() { + return auditOpinion; + } + + public void setAuditOpinion(String auditOpinion) { + this.auditOpinion = auditOpinion; + } + + public Long getAuditUserId() { + return auditUserId; + } + + public void setAuditUserId(Long auditUserId) { + this.auditUserId = auditUserId; + } + + public Date getAuditTime() { + return auditTime; + } + + public void setAuditTime(Date auditTime) { + this.auditTime = auditTime; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -442,6 +490,10 @@ public class VetProduct extends BaseEntity .append("userId", getUserId()) .append("createdAt", getCreatedAt()) .append("updatedAt", getUpdatedAt()) + .append("auditStatus", getAuditStatus()) + .append("auditOpinion", getAuditOpinion()) + .append("auditUserId", getAuditUserId()) + .append("auditTime", getAuditTime()) .toString(); } } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetQualification.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetQualification.java index f1e042e..a906c8d 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetQualification.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetQualification.java @@ -2,16 +2,20 @@ package com.chenhai.vet.domain; import com.chenhai.common.annotation.Excel; import com.chenhai.common.core.domain.BaseEntity; +import com.chenhai.common.utils.StringUtils; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.SimpleDateFormat; +import java.util.*; + -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.ArrayList; /** * 兽医资质对象 vet_qualification(合并证书功能) @@ -22,6 +26,13 @@ import java.util.ArrayList; public class VetQualification extends BaseEntity { private static final long serialVersionUID = 1L; + private static final Logger log = LoggerFactory.getLogger(VetQualification.class); + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final Object idLock = new Object(); + private static long lastGeneratedId = System.currentTimeMillis(); + + private static final long MAX_SAFE_ID = 9007199254740991L; // JavaScript最大安全整数 + private static final long MIN_SAFE_ID = 100000000L; // 最小8位数 /** 资质ID */ private Long qualificationId; @@ -60,7 +71,7 @@ public class VetQualification extends BaseEntity @Excel(name = "审核时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date auditTime; - /** 审核状态(0待审核 1通过 2拒绝 ) */ + /** 审核状态(0待审核 1通过 2拒绝) */ @Excel(name = "审核状态", dictType = "qualification_shenhe") private String auditStatus; @@ -79,7 +90,8 @@ public class VetQualification extends BaseEntity @Excel(name = "经营范围名称", dictType = "scope_names") private String scopeNames; - // 新增证书相关字段 + /** 证书ID(数据库字段) */ + private Long certId; /** 证书名称 */ @Excel(name = "证书名称") @@ -118,17 +130,376 @@ public class VetQualification extends BaseEntity @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date lastRemindTime; - // 查询条件字段(非数据库字段) /** 是否查询即将过期 */ private Boolean expiringOnly; - // 显示标签字段 + /** 显示标签字段 */ private String qualificationTypeLabel; private String auditStatusLabel; private String scopeNamesLabel; private String certStatusLabel; - // 从 JSON 反序列化时使用的方法 + /** 证书JSON字符串(数据库字段) */ + private String certificatesJson; + + /** 证书列表(从JSON解析而来) */ + private transient List certificateList; + + /** + * 证书信息内部类 + */ + public static class CertificateInfo { + private Long certificateId; + private String certName; + private String certificateNo; + + @JsonFormat(pattern = "yyyy-MM-dd") + private Date issueDate; + + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expireDate; + + private String issueOrg; + private String certificateFiles; + private String certStatus; + private String certStatusLabel; + private String auditStatus; + private String auditStatusLabel; + private Long qualificationId; + private String realName; + + public CertificateInfo() {} + + public CertificateInfo(String certName, String certificateNo, Date issueDate, + Date expireDate, String issueOrg, String certificateFiles) { + this.certName = certName; + this.certificateNo = certificateNo; + this.issueDate = issueDate; + this.expireDate = expireDate; + this.issueOrg = issueOrg; + this.certificateFiles = certificateFiles; + } + + @JsonIgnore + public Long getCertId() { + return certificateId; + } + + public void setCertId(Long certId) { + this.certificateId = certId; + } + + public Long getCertificateId() { + return certificateId; + } + + public void setCertificateId(Long certificateId) { + this.certificateId = certificateId; + } + + public String getCertName() { + return certName; + } + + public void setCertName(String certName) { + this.certName = certName; + } + + public String getCertificateNo() { + return certificateNo; + } + + public void setCertificateNo(String certificateNo) { + this.certificateNo = certificateNo; + } + + public Date getIssueDate() { + return issueDate; + } + + public void setIssueDate(Date issueDate) { + this.issueDate = issueDate; + } + + public Date getExpireDate() { + return expireDate; + } + + public void setExpireDate(Date expireDate) { + this.expireDate = expireDate; + } + + public String getIssueOrg() { + return issueOrg; + } + + public void setIssueOrg(String issueOrg) { + this.issueOrg = issueOrg; + } + + public String getCertificateFiles() { + return certificateFiles; + } + + public void setCertificateFiles(String certificateFiles) { + this.certificateFiles = certificateFiles; + } + + public String getCertStatus() { + return certStatus; + } + + public void setCertStatus(String certStatus) { + this.certStatus = certStatus; + } + + public String getCertStatusLabel() { + return certStatusLabel; + } + + public void setCertStatusLabel(String certStatusLabel) { + this.certStatusLabel = certStatusLabel; + } + + public String getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(String auditStatus) { + this.auditStatus = auditStatus; + } + + public String getAuditStatusLabel() { + return auditStatusLabel; + } + + public void setAuditStatusLabel(String auditStatusLabel) { + this.auditStatusLabel = auditStatusLabel; + } + + public Long getQualificationId() { + return qualificationId; + } + + public void setQualificationId(Long qualificationId) { + this.qualificationId = qualificationId; + } + + public String getRealName() { + return realName; + } + + public void setRealName(String realName) { + this.realName = realName; + } + } + + /** + * 获取证书列表 - 从certificatesJson解析 + */ + @JsonIgnore + public List getCertificateList() { + if (certificateList == null) { + certificateList = new ArrayList<>(); + + if (StringUtils.isNotEmpty(certificatesJson)) { + try { + List> certMaps = objectMapper.readValue( + certificatesJson, + objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class) + ); + + for (Map certMap : certMaps) { + CertificateInfo cert = new CertificateInfo(); + cert.setCertName((String) certMap.get("certName")); + cert.setCertificateNo((String) certMap.get("certificateNo")); + cert.setIssueOrg((String) certMap.get("issueOrg")); + cert.setCertificateFiles((String) certMap.get("certificateFiles")); + + Object issueDateObj = certMap.get("issueDate"); + Object expireDateObj = certMap.get("expireDate"); + + if (issueDateObj instanceof String) { + try { + cert.setIssueDate(new SimpleDateFormat("yyyy-MM-dd").parse((String) issueDateObj)); + } catch (Exception e) {} + } + + if (expireDateObj instanceof String) { + try { + cert.setExpireDate(new SimpleDateFormat("yyyy-MM-dd").parse((String) expireDateObj)); + } catch (Exception e) {} + } + + cert.setQualificationId(this.qualificationId); + cert.setRealName(this.realName); + + Long certificateId = null; + Object certIdObj = certMap.get("certId"); + + if (certIdObj != null) { + try { + if (certIdObj instanceof Number) { + certificateId = ((Number) certIdObj).longValue(); + } else if (certIdObj instanceof String) { + certificateId = Long.parseLong((String) certIdObj); + } + } catch (Exception e) {} + } + + // 修复这里:确保ID不为null且不为0,否则使用稳定ID生成器 + if (certificateId == null || certificateId == 0) { + certificateId = generateSafeCertificateId(); + } + + cert.setCertificateId(certificateId); + certificateList.add(cert); + } + } catch (Exception e) { + log.error("解析certificatesJson失败: {}", certificatesJson, e); + } + } else if (StringUtils.isNotEmpty(certName) || StringUtils.isNotEmpty(certificateNo)) { + CertificateInfo cert = new CertificateInfo(); + cert.setCertName(certName); + cert.setCertificateNo(certificateNo); + cert.setIssueDate(issueDate); + cert.setExpireDate(expireDate); + cert.setIssueOrg(issueOrg); + cert.setCertificateFiles(certificateFiles); + cert.setQualificationId(this.qualificationId); + cert.setRealName(this.realName); + + Long certificateId = this.certId; + if (certificateId == null || certificateId == 0) { + certificateId = generateSafeCertificateId(); + } + cert.setCertificateId(certificateId); + certificateList.add(cert); + } + + updateCertificateStatus(); + } + + return certificateList; + } + /** + * 生成安全的证书ID(避免JavaScript精度丢失) + */ + + private Long generateSafeCertificateId() { + // 当前毫秒时间戳(13位) + long timestamp = System.currentTimeMillis(); + + // 取时间戳的后12位(确保在安全范围内) + long id = timestamp % 1000000000000L; // 12位数字 + + // 加上1亿,确保是9位数以上 + id += 100000000L; + + // 双重检查:确保不超过JavaScript安全上限 + if (id > MAX_SAFE_ID) { + // 如果超过,取模回到安全范围 + id = id % (MAX_SAFE_ID - 100000000L) + 100000000L; + } + + return id; + } + /** + * 设置证书列表,并同步更新JSON字段 + */ + + public void setCertificateList(List certificateList) { + this.certificateList = certificateList; + + if (certificateList != null && !certificateList.isEmpty()) { + try { + List> certMapList = new ArrayList<>(); + + for (CertificateInfo cert : certificateList) { + Map certMap = new HashMap<>(); + certMap.put("certName", cert.getCertName()); + certMap.put("certificateNo", cert.getCertificateNo()); + certMap.put("issueOrg", cert.getIssueOrg()); + certMap.put("certificateFiles", cert.getCertificateFiles()); + + if (cert.getIssueDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + certMap.put("issueDate", sdf.format(cert.getIssueDate())); + } + + if (cert.getExpireDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + certMap.put("expireDate", sdf.format(cert.getExpireDate())); + } + + // 确保每个证书都有ID + if (cert.getCertificateId() == null || cert.getCertificateId() == 0) { + cert.setCertificateId(generateSafeCertificateId()); + } + + certMap.put("certId", cert.getCertificateId()); + + if (cert.getCertStatus() != null) { + certMap.put("certStatus", cert.getCertStatus()); + } + + certMapList.add(certMap); + } + + this.certificatesJson = objectMapper.writeValueAsString(certMapList); + + // 更新主表字段 + if (!certificateList.isEmpty()) { + CertificateInfo firstCert = certificateList.get(0); + this.certName = firstCert.getCertName(); + this.certificateNo = firstCert.getCertificateNo(); + this.issueDate = firstCert.getIssueDate(); + this.expireDate = firstCert.getExpireDate(); + this.issueOrg = firstCert.getIssueOrg(); + this.certificateFiles = firstCert.getCertificateFiles(); + this.certStatus = firstCert.getCertStatus(); + + if (firstCert.getCertificateId() != null) { + this.certId = firstCert.getCertificateId(); + } + } + } catch (Exception e) { + log.error("序列化证书列表失败", e); + } + } + } + + /** + * 更新证书状态 + */ + public void updateCertificateStatus() { + if (certificateList != null) { + for (CertificateInfo cert : certificateList) { + if (cert.getExpireDate() != null) { + Date today = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 30); + Date thirtyDaysLater = calendar.getTime(); + + if (cert.getExpireDate().before(today)) { + cert.setCertStatus("2"); + cert.setCertStatusLabel("已过期"); + } else if (cert.getExpireDate().before(thirtyDaysLater)) { + cert.setCertStatus("1"); + cert.setCertStatusLabel("即将过期"); + } else { + cert.setCertStatus("0"); + cert.setCertStatusLabel("正常"); + } + } else { + cert.setCertStatus("0"); + cert.setCertStatusLabel("正常"); + } + } + } + } + @JsonProperty("scopeIds") public void setScopeIdsFromJson(List scopeIdList) { if (scopeIdList != null && !scopeIdList.isEmpty()) { @@ -138,7 +509,6 @@ public class VetQualification extends BaseEntity } } - // 序列化为 JSON 时使用的方法 @JsonProperty("scopeIds") public List getScopeIdsAsList() { if (scopeIds != null && !scopeIds.trim().isEmpty()) { @@ -147,29 +517,15 @@ public class VetQualification extends BaseEntity return new ArrayList<>(); } - // 数据库操作的 getter(Jackson 忽略) @JsonIgnore public String getScopeIds() { return scopeIds; } - // 数据库操作的 setter public void setScopeIds(String scopeIds) { this.scopeIds = scopeIds; } - // 为了方便,添加一个获取列表的方法(不映射到 JSON) - @JsonIgnore - public List getScopeIdList() { - return getScopeIdsAsList(); - } - - // 为了方便,添加一个设置列表的方法(不映射到 JSON) - public void setScopeIdList(List scopeIdList) { - setScopeIdsFromJson(scopeIdList); - } - - // getter 和 setter 方法 public Long getQualificationId() { return qualificationId; } @@ -274,7 +630,14 @@ public class VetQualification extends BaseEntity this.scopeNames = scopeNames; } - // 新增证书字段的 getter 和 setter + public Long getCertId() { + return certId; + } + + public void setCertId(Long certId) { + this.certId = certId; + } + public String getCertName() { return certName; } @@ -387,6 +750,66 @@ public class VetQualification extends BaseEntity this.certStatusLabel = certStatusLabel; } + public String getCertificatesJson() { + return certificatesJson; + } + + public void setCertificatesJson(String certificatesJson) { + this.certificatesJson = certificatesJson; + } + + @JsonIgnore + public List> getCertificates() { + if (StringUtils.isEmpty(certificatesJson)) { + return new ArrayList<>(); + } + + try { + return objectMapper.readValue( + certificatesJson, + objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class) + ); + } catch (Exception e) { + log.error("解析certificatesJson失败", e); + return new ArrayList<>(); + } + } + + /** + * 设置证书列表(兼容性方法,转换为certificatesJson存储) + */ + public void setCertificates(List> certificates) { + if (certificates != null && !certificates.isEmpty()) { + try { + this.certificatesJson = objectMapper.writeValueAsString(certificates); + + // 更新主表字段 + Map firstCert = certificates.get(0); + this.certName = (String) firstCert.get("certName"); + this.certificateNo = (String) firstCert.get("certificateNo"); + this.issueOrg = (String) firstCert.get("issueOrg"); + this.certificateFiles = (String) firstCert.get("certificateFiles"); + + Object issueDateObj = firstCert.get("issueDate"); + Object expireDateObj = firstCert.get("expireDate"); + + if (issueDateObj instanceof String) { + try { + this.issueDate = new SimpleDateFormat("yyyy-MM-dd").parse((String) issueDateObj); + } catch (Exception e) {} + } + + if (expireDateObj instanceof String) { + try { + this.expireDate = new SimpleDateFormat("yyyy-MM-dd").parse((String) expireDateObj); + } catch (Exception e) {} + } + } catch (Exception e) { + log.error("序列化证书列表失败", e); + } + } + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -404,6 +827,7 @@ public class VetQualification extends BaseEntity .append("auditorId", getAuditorId()) .append("scopeIds", getScopeIds()) .append("scopeNames", getScopeNames()) + .append("certId", getCertId()) .append("certName", getCertName()) .append("certType", getCertType()) .append("issueOrg", getIssueOrg()) @@ -418,6 +842,8 @@ public class VetQualification extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("certificatesJson", getCertificatesJson()) .toString(); } + } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java deleted file mode 100644 index 89bc71a..0000000 --- a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetArticleCategoryMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.chenhai.vet.mapper; - -import com.chenhai.vet.domain.VetArticleCategory; -import org.apache.ibatis.annotations.Mapper; -import java.util.List; - -@Mapper -public interface VetArticleCategoryMapper { - /** - * 这个方法名必须和XML中的id完全一致 - */ - List selectVetArticleCategoryList(VetArticleCategory vetArticleCategory); -} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java index 96be52e..7bac1ed 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExperienceArticleMapper.java @@ -2,21 +2,20 @@ 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 +public interface VetExperienceArticleMapper { /** * 查询兽医经验文章 - * + * * @param id 兽医经验文章主键 * @return 兽医经验文章 */ @@ -24,7 +23,7 @@ public interface VetExperienceArticleMapper /** * 查询兽医经验文章列表 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 兽医经验文章集合 */ @@ -32,7 +31,7 @@ public interface VetExperienceArticleMapper /** * 新增兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -40,7 +39,7 @@ public interface VetExperienceArticleMapper /** * 修改兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -48,7 +47,7 @@ public interface VetExperienceArticleMapper /** * 删除兽医经验文章 - * + * * @param id 兽医经验文章主键 * @return 结果 */ @@ -56,39 +55,50 @@ public interface VetExperienceArticleMapper /** * 批量删除兽医经验文章 - * + * * @param ids 需要删除的数据主键集合 * @return 结果 */ public int deleteVetExperienceArticleByIds(Long[] ids); /** - * 根据条件查询文章(支持排序和限制条数) + * 根据条件查询文章列表(论坛专用) + * + * @param params 查询参数 + * @return 文章集合 */ - List selectArticlesByCondition(Map params); - - List searchArticles(@Param("keyword") String keyword, - @Param("status") String status); - - + public List selectArticlesByCondition(Map params); /** * 增加浏览数 + * + * @param id 文章主键 + * @return 结果 */ - int incrementViewCount(@Param("id") Long id); + public int incrementViewCount(Long id); /** * 增加点赞数 + * + * @param id 文章主键 + * @return 结果 */ - int incrementLikeCount(@Param("id") Long id); + public int incrementLikeCount(Long id); /** * 增加收藏数 + * + * @param id 文章主键 + * @return 结果 */ - int incrementCollectCount(@Param("id") Long id); + public int incrementCollectCount(Long id); /** - * 根据标签筛选文章 + * 搜索文章 + * + * @param keyword 关键词 + * @param status 文章状态 + * @return 文章集合 */ - List selectArticlesByTag(@Param("tag") String tag); -} + public List searchArticles(@Param("keyword") String keyword, @Param("status") String status); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java index d74d143..a68da06 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetQualificationMapper.java @@ -2,8 +2,10 @@ package com.chenhai.vet.mapper; import com.chenhai.vet.domain.VetQualification; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; +import java.util.Map; /** * 兽医资质Mapper接口 @@ -67,4 +69,6 @@ public interface VetQualificationMapper */ List selectQualificationsByUserId(Long userId); + Map selectCertificateByCertId(@Param("certId") Long certId, @Param("userId") Long userId); + } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java index a127930..20e49bd 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetExperienceArticleService.java @@ -2,20 +2,19 @@ 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 +public interface IVetExperienceArticleService { /** * 查询兽医经验文章 - * + * * @param id 兽医经验文章主键 * @return 兽医经验文章 */ @@ -23,7 +22,7 @@ public interface IVetExperienceArticleService /** * 查询兽医经验文章列表 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 兽医经验文章集合 */ @@ -31,7 +30,7 @@ public interface IVetExperienceArticleService /** * 新增兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -39,7 +38,7 @@ public interface IVetExperienceArticleService /** * 修改兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -47,7 +46,7 @@ public interface IVetExperienceArticleService /** * 批量删除兽医经验文章 - * + * * @param ids 需要删除的兽医经验文章主键集合 * @return 结果 */ @@ -55,65 +54,82 @@ public interface IVetExperienceArticleService /** * 删除兽医经验文章信息 - * + * * @param id 兽医经验文章主键 * @return 结果 */ public int deleteVetExperienceArticleById(Long id); - /** - * 获取推荐文章(精选+置顶) - */ - List selectFeaturedArticles(Integer limit); - - List searchArticles(String keyword); - /** * 获取最新文章 + * + * @param limit 限制数量 + * @return 文章集合 */ List selectLatestArticles(Integer limit); /** * 获取热门文章(按浏览数排序) + * + * @param limit 限制数量 + * @return 文章集合 */ List selectHotArticles(Integer limit); /** - * 根据兽医ID获取文章 + * 根据用户ID获取文章 + * + * @param userId 用户ID + * @param limit 限制数量 + * @return 文章集合 */ - List selectArticlesByVetId(Long vetId, Integer limit); + List selectArticlesByUserId(Long userId, Integer limit); /** * 获取相关文章 + * + * @param excludeId 排除的文章ID + * @param categoryId 分类ID + * @param limit 限制数量 + * @return 文章集合 */ List selectRelatedArticles(Long excludeId, Long categoryId, Integer limit); /** * 增加浏览数 + * + * @param id 文章ID + * @return 结果 */ int incrementViewCount(Long id); /** * 增加点赞数 + * + * @param id 文章ID + * @return 结果 */ int incrementLikeCount(Long id); /** * 增加收藏数 + * + * @param id 文章ID + * @return 结果 */ int incrementCollectCount(Long id); /** * 获取论坛统计信息 + * + * @return 统计信息 */ Map selectForumStatistics(); - /** - * 获取热门标签 + * 搜索文章 + * + * @param keyword 关键词 + * @return 文章集合 */ - /* List> selectHotTags(Integer limit);*/ - - List selectArticlesByTag(String tag); - - List selectMyCollections(Long userId); -} + List searchArticles(String keyword); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java index 33f98ae..2eaf006 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java @@ -59,4 +59,47 @@ public interface IVetProductService */ public int deleteVetProductById(Long id); + /** + * 提交审核 + * + * @param id 产品ID + * @return 结果 + */ + public int submitForAudit(Long id); + + /** + * 审核产品 + * + * @param id 产品ID + * @param auditStatus 审核状态 + * @param auditOpinion 审核意见 + * @param auditUserId 审核人ID + * @return 结果 + */ + public int auditProduct(Long id, String auditStatus, String auditOpinion, Long auditUserId); + + /** + * 上架产品 + * + * @param id 产品ID + * @return 结果 + */ + public int publishProduct(Long id); + + /** + * 下架产品 + * + * @param id 产品ID + * @return 结果 + */ + public int offlineProduct(Long id); + + /** + * 取消审核 + * + * @param id 产品ID + * @return 结果 + */ + public int cancelAudit(Long id); + } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetQualificationService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetQualificationService.java index 3304f02..265ec06 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetQualificationService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetQualificationService.java @@ -88,4 +88,14 @@ public interface IVetQualificationService */ Map getCertificateStatistics(Long userId); + /** + * 提交资质审核(新方法,处理复杂数据结构) + */ + int submitQualification(Map requestData); + + /** + * 根据证书ID查询证书及所属资质信息 + */ + Map selectCertificateWithQualificationByCertId(Long certId, Long userId); + } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java index 0c4f6ea..4e5f5d5 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExperienceArticleServiceImpl.java @@ -1,8 +1,6 @@ package com.chenhai.vet.service.impl; import java.util.*; -import java.util.stream.Collectors; - import com.chenhai.common.utils.DateUtils; import com.github.pagehelper.PageHelper; import org.springframework.beans.factory.annotation.Autowired; @@ -13,19 +11,19 @@ import com.chenhai.vet.service.IVetExperienceArticleService; /** * 兽医经验文章Service业务层处理 - * + * * @author ruoyi * @date 2026-01-06 */ @Service -public class VetExperienceArticleServiceImpl implements IVetExperienceArticleService +public class VetExperienceArticleServiceImpl implements IVetExperienceArticleService { @Autowired private VetExperienceArticleMapper vetExperienceArticleMapper; /** * 查询兽医经验文章 - * + * * @param id 兽医经验文章主键 * @return 兽医经验文章 */ @@ -37,7 +35,7 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer /** * 查询兽医经验文章列表 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 兽医经验文章 */ @@ -49,7 +47,7 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer /** * 新增兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -62,7 +60,7 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer /** * 修改兽医经验文章 - * + * * @param vetExperienceArticle 兽医经验文章 * @return 结果 */ @@ -75,7 +73,7 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer /** * 批量删除兽医经验文章 - * + * * @param ids 需要删除的兽医经验文章主键 * @return 结果 */ @@ -87,7 +85,7 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer /** * 删除兽医经验文章信息 - * + * * @param id 兽医经验文章主键 * @return 结果 */ @@ -97,190 +95,178 @@ public class VetExperienceArticleServiceImpl implements IVetExperienceArticleSer return vetExperienceArticleMapper.deleteVetExperienceArticleById(id); } - @Override - public List selectFeaturedArticles(Integer limit) { - PageHelper.clearPage(); - Map 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 searchArticles(String keyword) { - - PageHelper.clearPage(); - Map params = new HashMap<>(); - params.put("keyword", keyword); - params.put("status", 1); - - return vetExperienceArticleMapper.selectArticlesByCondition(params); - } + /** + * 获取最新文章 + * + * @param limit 限制数量 + * @return 文章集合 + */ @Override public List selectLatestArticles(Integer limit) { PageHelper.clearPage(); Map params = new HashMap<>(); - params.put("status", 1); + params.put("status", "1"); params.put("orderBy", "publish_time"); params.put("orderType", "desc"); params.put("limit", limit != null ? limit : 10); return vetExperienceArticleMapper.selectArticlesByCondition(params); } + /** + * 获取热门文章(按浏览数排序) + * + * @param limit 限制数量 + * @return 文章集合 + */ @Override public List selectHotArticles(Integer limit) { PageHelper.clearPage(); Map params = new HashMap<>(); - params.put("status", 1); + params.put("status", "1"); params.put("orderBy", "view_count"); params.put("orderType", "desc"); params.put("limit", limit != null ? limit : 10); return vetExperienceArticleMapper.selectArticlesByCondition(params); } + /** + * 根据用户ID获取文章 + * + * @param userId 用户ID + * @param limit 限制数量 + * @return 文章集合 + */ @Override - public List selectArticlesByVetId(Long vetId, Integer limit) { + public List selectArticlesByUserId(Long userId, Integer limit) { PageHelper.clearPage(); Map params = new HashMap<>(); - params.put("vetId", vetId); - params.put("status", 1); + params.put("status", "1"); + params.put("userId", userId); params.put("orderBy", "publish_time"); params.put("orderType", "desc"); params.put("limit", limit != null ? limit : 5); return vetExperienceArticleMapper.selectArticlesByCondition(params); } + /** + * 获取相关文章 + * + * @param excludeId 排除的文章ID + * @param categoryId 分类ID + * @param limit 限制数量 + * @return 文章集合 + */ @Override public List selectRelatedArticles(Long excludeId, Long categoryId, Integer limit) { PageHelper.clearPage(); Map params = new HashMap<>(); + params.put("status", "1"); 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); } - + /** + * 增加浏览数 + * + * @param id 文章ID + * @return 结果 + */ @Override public int incrementViewCount(Long id) { return vetExperienceArticleMapper.incrementViewCount(id); } + /** + * 增加点赞数 + * + * @param id 文章ID + * @return 结果 + */ @Override public int incrementLikeCount(Long id) { return vetExperienceArticleMapper.incrementLikeCount(id); } + /** + * 增加收藏数 + * + * @param id 文章ID + * @return 结果 + */ @Override public int incrementCollectCount(Long id) { return vetExperienceArticleMapper.incrementCollectCount(id); } + /** + * 获取论坛统计信息 + * + * @return 统计信息 + */ @Override public Map selectForumStatistics() { - PageHelper.clearPage(); Map statistics = new HashMap<>(); - // 获取文章总数 - VetExperienceArticle countQuery = new VetExperienceArticle(); - countQuery.setStatus("1"); - List allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(countQuery); + // 获取所有已发布文章 + VetExperienceArticle query = new VetExperienceArticle(); + query.setStatus("1"); + List allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(query); + + // 统计文章总数 statistics.put("totalArticles", allArticles.size()); - // 获取兽医总数(去重) - Set vetIds = new HashSet<>(); + // 统计作者总数(去重) + Set authorIds = new HashSet<>(); for (VetExperienceArticle article : allArticles) { - vetIds.add(article.getUserId()); + if (article.getUserId() != null) { + authorIds.add(article.getUserId()); + } } - statistics.put("totalVets", vetIds.size()); + statistics.put("totalAuthors", authorIds.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); + // 统计总收藏数 + int totalCollects = 0; + for (VetExperienceArticle article : allArticles) { + totalCollects += article.getCollectCount() != null ? article.getCollectCount() : 0; + } + statistics.put("totalCollects", totalCollects); + return statistics; } /** - * 根据标签筛选文章(简单实现) + * 搜索文章 + * + * @param keyword 关键词 + * @return 文章集合 */ @Override - public List selectArticlesByTag(String tag) { - if (tag == null || tag.trim().isEmpty()) { - return new ArrayList<>(); - } - return vetExperienceArticleMapper.selectArticlesByTag(tag.trim()); - } - - /* @Override - public List> selectHotTags(Integer limit) { - // 从所有文章中提取标签并统计热度 - VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); - List allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(query); - - Map 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> hotTags = new ArrayList<>(); - tagCount.entrySet().stream() - .sorted(Map.Entry.comparingByValue().reversed()) - .limit(limit != null ? limit : 15) - .forEach(entry -> { - Map tagInfo = new HashMap<>(); - tagInfo.put("name", entry.getKey()); - tagInfo.put("count", entry.getValue()); - hotTags.add(tagInfo); - }); - - return hotTags; - }*/ - - @Override - public List selectMyCollections(Long userId) { - // 这里需要根据实际业务逻辑实现 - // 由于你的系统中没有专门的收藏表,这里提供一个临时方案: - - // 方案1:模拟数据(临时使用) - VetExperienceArticle query = new VetExperienceArticle(); - query.setStatus("1"); // 只查询已发布的文章 - - List allArticles = vetExperienceArticleMapper.selectVetExperienceArticleList(query); - - // 临时逻辑:假设收藏的文章是点赞数较高的文章 - return allArticles.stream() - .sorted((a1, a2) -> { - Integer likes1 = a1.getLikeCount() != null ? a1.getLikeCount() : 0; - Integer likes2 = a2.getLikeCount() != null ? a2.getLikeCount() : 0; - return likes2.compareTo(likes1); - }) - .limit(20) // 限制数量 - .collect(Collectors.toList()); + public List searchArticles(String keyword) { + PageHelper.clearPage(); + Map params = new HashMap<>(); + params.put("status", "1"); + params.put("keyword", keyword); + params.put("orderBy", "publish_time"); + params.put("orderType", "desc"); + params.put("limit", 20); + return vetExperienceArticleMapper.selectArticlesByCondition(params); } - -} +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java index 4d0ff2c..7364865 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java @@ -1,12 +1,16 @@ package com.chenhai.vet.service.impl; +import java.util.Date; import java.util.List; +import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.vet.domain.VetTrainingVideo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.chenhai.vet.mapper.VetProductMapper; import com.chenhai.vet.domain.VetProduct; import com.chenhai.vet.service.IVetProductService; +import org.springframework.transaction.annotation.Transactional; /** * 兽医产品信息Service业务层处理 @@ -50,11 +54,11 @@ public class VetProductServiceImpl implements IVetProductService * @param vetProduct 兽医产品信息 * @return 结果 */ - @Override + /* @Override public int insertVetProduct(VetProduct vetProduct) { return vetProductMapper.insertVetProduct(vetProduct); - } + }*/ /** * 修改兽医产品信息 @@ -91,4 +95,158 @@ public class VetProductServiceImpl implements IVetProductService { return vetProductMapper.deleteVetProductById(id); } + + /** + * 提交审核 + */ + @Override + @Transactional + public int submitForAudit(Long id) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有草稿状态的产品可以提交审核 + if (!"0".equals(product.getStatus())) { + throw new RuntimeException("只有草稿状态的产品可以提交审核"); + } + + // 检查当前审核状态 - 只有待审核状态可以提交审核 + String currentAuditStatus = product.getAuditStatus(); + if (!"0".equals(currentAuditStatus)) { + throw new RuntimeException("只有待审核状态的产品可以提交审核"); + } + + product.setAuditStatus("1"); // 设置为审核中状态 + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } + + /** + * 审核产品 + */ + @Override + @Transactional + public int auditProduct(Long id, String auditStatus, String auditOpinion, Long auditUserId) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有审核中状态可以完成审核 + if (!"1".equals(product.getAuditStatus())) { + throw new RuntimeException("只有审核中状态的产品可以完成审核"); + } + + // 验证审核状态的合法性(2,3) + if (!("2".equals(auditStatus) || "3".equals(auditStatus))) { + throw new RuntimeException("无效的审核状态,只能设置为审核通过或审核拒绝"); + } + + product.setAuditStatus(auditStatus); + product.setAuditOpinion(auditOpinion); + product.setAuditUserId(auditUserId); + product.setAuditTime(new Date()); + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } + + + /** + * 上架产品 + */ + @Override + @Transactional + public int publishProduct(Long id) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有审核通过且草稿状态的产品可以上架 + if (!"2".equals(product.getAuditStatus())) { + throw new RuntimeException("只有审核通过的产品可以上架"); + } + + if (!"0".equals(product.getStatus())) { + throw new RuntimeException("产品状态不正确"); + } + + product.setStatus("1"); // 上架 + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } + /** + * 下架产品 + */ + @Override + @Transactional + public int offlineProduct(Long id) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有已上架的产品可以下架 + if (!"1".equals(product.getStatus())) { + throw new RuntimeException("只有已上架的产品可以下架"); + } + + product.setStatus("0"); // 下架 + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } + + /** + * 取消审核 + */ + @Override + @Transactional + public int cancelAudit(Long id) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有草稿状态且审核中状态可以取消审核 + if (!"0".equals(product.getStatus()) || !"1".equals(product.getAuditStatus())) { + throw new RuntimeException("只有草稿且审核中状态的产品可以取消审核"); + } + + product.setAuditStatus("0"); // 设置回待审核状态 + product.setAuditOpinion(null); + product.setAuditUserId(null); + product.setAuditTime(null); + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } + + // 修改 insertVetProduct 方法,修改默认值设置: + @Override + @Transactional + public int insertVetProduct(VetProduct vetProduct) + { + // 设置默认值 + vetProduct.setStatus("0"); // 默认草稿状态 + vetProduct.setAuditStatus("0"); // 新增产品默认待审核状态 + vetProduct.setIsDeleted(0); + vetProduct.setCreatedAt(new Date()); + vetProduct.setUpdatedAt(new Date()); + + // 设置当前用户ID + try { + Long userId = SecurityUtils.getUserId(); + vetProduct.setUserId(userId); + } catch (Exception e) { + vetProduct.setUserId(1L); + } + + return vetProductMapper.insertVetProduct(vetProduct); + } } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java index ae8fed9..d86f7cf 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetQualificationServiceImpl.java @@ -1,32 +1,45 @@ package com.chenhai.vet.service.impl; -import com.chenhai.common.utils.DateUtils; +import com.chenhai.common.exception.ServiceException; import com.chenhai.common.utils.SecurityUtils; import com.chenhai.common.utils.StringUtils; import com.chenhai.vet.domain.VetQualification; import com.chenhai.vet.mapper.VetQualificationMapper; import com.chenhai.vet.service.IVetQualificationService; -import com.chenhai.vet.service.VetNotificationService; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.text.SimpleDateFormat; import java.util.*; /** * 兽医资质Service业务层处理(合并证书功能) */ @Service -public class VetQualificationServiceImpl implements IVetQualificationService -{ +public class VetQualificationServiceImpl implements IVetQualificationService { @Autowired private VetQualificationMapper vetQualificationMapper; @Autowired private JdbcTemplate jdbcTemplate; - @Autowired - private VetNotificationService vetNotificationService; + // 添加ObjectMapper用于JSON处理 + private final ObjectMapper objectMapper = new ObjectMapper(); + + private static final Logger log = LoggerFactory.getLogger(VetQualificationServiceImpl.class); + + // 日期格式化 + private final SimpleDateFormat dateFormat; + + public VetQualificationServiceImpl() { + dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + // ==================== 基础CRUD方法 ==================== /** * 查询兽医资质列表 @@ -34,34 +47,455 @@ public class VetQualificationServiceImpl implements IVetQualificationService @Override public List selectVetQualificationList(VetQualification vetQualification) { List list = vetQualificationMapper.selectVetQualificationList(vetQualification); - // 处理经营范围名称(scope_ids转scope_names) for (VetQualification qualification : list) { - if ((qualification.getScopeNames() == null || qualification.getScopeNames().isEmpty()) - && qualification.getScopeIds() != null && !qualification.getScopeIds().isEmpty()) { - String scopeNames = getScopeNamesFromDict(qualification.getScopeIds()); - qualification.setScopeNames(scopeNames); + processQualificationInfo(qualification); + } + return list; + } + + /** + * 查询兽医资质 + */ + @Override + public VetQualification selectVetQualificationByQualificationId(Long qualificationId) { + VetQualification qualification = vetQualificationMapper.selectVetQualificationByQualificationId(qualificationId); + if (qualification != null) { + processQualificationInfo(qualification); + } + return qualification; + } + + /** + * 新增兽医资质 + */ + @Override + public int insertVetQualification(VetQualification vetQualification) { + prepareQualificationForSave(vetQualification); + return vetQualificationMapper.insertVetQualification(vetQualification); + } + + /** + * 修改兽医资质 + */ + @Override + public int updateVetQualification(VetQualification vetQualification) { + if (vetQualification.getQualificationId() == null) { + throw new ServiceException("资质ID不能为空"); + } + + VetQualification existing = vetQualificationMapper.selectVetQualificationByQualificationId(vetQualification.getQualificationId()); + if (existing == null) { + throw new ServiceException("资质信息不存在"); + } + + // 更新基本信息 + updateBasicQualificationInfo(existing, vetQualification); + + // 处理证书更新 + processCertificateUpdate(existing, vetQualification); + + // 设置更新信息 + existing.setUpdateBy(SecurityUtils.getUsername()); + existing.setUpdateTime(new Date()); + + // 更新证书状态 + updateCertificateStatus(existing); + + return vetQualificationMapper.updateVetQualification(existing); + } + + /** + * 批量删除兽医资质 + */ + @Override + public int deleteVetQualificationByQualificationIds(Long[] qualificationIds) { + return vetQualificationMapper.deleteVetQualificationByQualificationIds(qualificationIds); + } + + /** + * 删除兽医资质信息 + */ + @Override + public int deleteVetQualificationByQualificationId(Long qualificationId) { + return vetQualificationMapper.deleteVetQualificationByQualificationId(qualificationId); + } + + // ==================== 业务方法 ==================== + + /** + * 根据用户ID查询资质证书列表 + */ + @Override + public List selectQualificationsByUserId(Long userId) { + VetQualification query = new VetQualification(); + query.setUserId(userId); + return selectVetQualificationList(query); + } + + /** + * 根据证书ID查询证书及所属资质信息 + */ + @Override + public Map selectCertificateWithQualificationByCertId(Long certId, Long userId) { + try { + log.debug("开始查询证书,certId={}, userId={}", certId, userId); + + VetQualification query = new VetQualification(); + if (userId != null) { + query.setUserId(userId); } - // 更新证书状态 + List qualifications = selectVetQualificationList(query); + log.debug("查询到资质数量:{}", qualifications.size()); + + for (VetQualification qualification : qualifications) { + log.debug("检查资质ID:{},用户ID:{}", + qualification.getQualificationId(), qualification.getUserId()); + + if (StringUtils.isEmpty(qualification.getCertificatesJson())) { + log.debug("资质ID:{} 没有证书JSON数据", qualification.getQualificationId()); + continue; + } + + try { + List> certificates = parseCertificatesJson(qualification.getCertificatesJson()); + log.debug("资质ID:{} 解析到证书数量:{}", + qualification.getQualificationId(), certificates.size()); + + for (Map certMap : certificates) { + Long foundCertId = extractLongFromObject(certMap.get("certId")); + log.debug("检查证书ID:{},目标ID:{}", foundCertId, certId); + + if (foundCertId != null && foundCertId.equals(certId)) { + log.debug("找到匹配的证书,资质ID:{},证书ID:{}", + qualification.getQualificationId(), certId); + return buildCertificateResult(qualification, certMap, foundCertId); + } + } + } catch (Exception e) { + log.error("解析资质证书JSON失败,qualificationId: {}", qualification.getQualificationId(), e); + } + } + + log.warn("未找到证书,certId={}, userId={}", certId, userId); + return null; + + } catch (Exception e) { + log.error("查询证书信息失败:certId={}, userId={}", certId, userId, e); + throw new ServiceException("查询证书信息失败:" + e.getMessage()); + } + } + + /** + * 提交资质审核(新方法,处理复杂数据结构) + */ + @Override + public int submitQualification(Map requestData) { + VetQualification qualification = convertRequestToQualification(requestData); + qualification.setUserId(SecurityUtils.getUserId()); + qualification.setCreateBy(SecurityUtils.getUsername()); + + if (qualification.getCertId() == null) { + qualification.setCertId(generateCertificateId()); + } + + return insertVetQualification(qualification); + } + + /** + * 手动检查证书 + */ + @Override + public void manualCheckCertificates(Long userId) { + List qualifications = selectQualificationsByUserId(userId); + for (VetQualification qualification : qualifications) { updateCertificateStatus(qualification); + vetQualificationMapper.updateVetQualification(qualification); } - return list; + } + + /** + * 获取证书统计信息 + */ + @Override + public Map getCertificateStatistics(Long userId) { + List qualifications = selectQualificationsByUserId(userId); + Date today = new Date(); + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 30); + Date thirtyDaysLater = calendar.getTime(); + + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 7); + Date sevenDaysLater = calendar.getTime(); + + int totalCertificates = 0; + int expiring = 0; + int expired = 0; + int expiringSoon = 0; + + for (VetQualification qual : qualifications) { + List certs = qual.getCertificateList(); + totalCertificates += certs.size(); + + for (VetQualification.CertificateInfo cert : certs) { + if (cert.getExpireDate() != null) { + if (cert.getExpireDate().before(today)) { + expired++; + } else if (cert.getExpireDate().before(thirtyDaysLater)) { + expiring++; + if (cert.getExpireDate().before(sevenDaysLater)) { + expiringSoon++; + } + } + } + } + } + + int normal = totalCertificates - expiring - expired; + + Map statistics = new HashMap<>(); + statistics.put("total", totalCertificates); + statistics.put("normal", normal); + statistics.put("expiring", expiring); + statistics.put("expired", expired); + statistics.put("expiringSoon", expiringSoon); + statistics.put("qualificationCount", qualifications.size()); + + // 设置警告级别 + if (expired > 0) { + statistics.put("warningLevel", "DANGER"); + } else if (expiring > 0 || expiringSoon > 0) { + statistics.put("warningLevel", "WARNING"); + } else { + statistics.put("warningLevel", "NORMAL"); + } + + return statistics; + } + + // ==================== 工具方法 ==================== + + /** + * 处理资质信息(填充经营范围名称、更新证书状态) + */ + private void processQualificationInfo(VetQualification qualification) { + // 处理经营范围名称(scope_ids转scope_names) + if ((qualification.getScopeNames() == null || qualification.getScopeNames().isEmpty()) + && qualification.getScopeIds() != null && !qualification.getScopeIds().isEmpty()) { + String scopeNames = getScopeNamesFromDict(qualification.getScopeIds()); + qualification.setScopeNames(scopeNames); + } + + // 更新证书状态 + updateCertificateStatus(qualification); + } + + /** + * 准备保存前的资质数据 + */ + private void prepareQualificationForSave(VetQualification qualification) { + // 1. 如果certId为空,生成一个 + if (qualification.getCertId() == null) { + qualification.setCertId(generateCertificateId()); + } + + // 2. 处理基本信息 + if (StringUtils.isEmpty(qualification.getRealName())) { + qualification.setRealName("未知"); + } + + // 3. 处理审核状态 + if (qualification.getAuditStatus() == null) { + qualification.setAuditStatus("0"); // 0表示待审核 + } + + // 4. 处理经营范围 + if (qualification.getScopeIds() != null && !qualification.getScopeIds().isEmpty()) { + String scopeIdsStr = processScopeIds(qualification.getScopeIds()); + qualification.setScopeIds(scopeIdsStr); + + String scopeNames = getScopeNamesFromDict(scopeIdsStr); + qualification.setScopeNames(scopeNames); + } + + // 5. 处理证书信息 + if (qualification.getCertificatesJson() != null) { + extractFilePathsFromJson(qualification); + } + + // 6. 设置默认提醒天数 + if (qualification.getRemindDays() == null) { + qualification.setRemindDays(30); + } + + // 7. 验证并设置证书状态 + updateCertificateStatus(qualification); + + // 8. 设置创建时间 + if (qualification.getCreateTime() == null) { + qualification.setCreateTime(new Date()); + } + + // 9. 设置申请时间(用于审核) + if (qualification.getApplyTime() == null) { + qualification.setApplyTime(new Date()); + } + } + + /** + * 更新资质基本信息 + */ + private void updateBasicQualificationInfo(VetQualification existing, VetQualification update) { + if (StringUtils.isNotEmpty(update.getRealName())) { + existing.setRealName(update.getRealName()); + } + if (StringUtils.isNotEmpty(update.getIdCard())) { + existing.setIdCard(update.getIdCard()); + } + if (StringUtils.isNotEmpty(update.getQualificationType())) { + existing.setQualificationType(update.getQualificationType()); + } + if (StringUtils.isNotEmpty(update.getScopeIds())) { + existing.setScopeIds(update.getScopeIds()); + String scopeNames = getScopeNamesFromDict(update.getScopeIds()); + existing.setScopeNames(scopeNames); + } + + // 更新审核相关字段 + if (StringUtils.isNotEmpty(update.getAuditStatus())) { + existing.setAuditStatus(update.getAuditStatus()); + } + if (StringUtils.isNotEmpty(update.getAuditOpinion())) { + existing.setAuditOpinion(update.getAuditOpinion()); + } + if (update.getAuditTime() != null) { + existing.setAuditTime(update.getAuditTime()); + } + if (update.getAuditorId() != null) { + existing.setAuditorId(update.getAuditorId()); + } + } + + /** + * 处理证书更新 + */ + private void processCertificateUpdate(VetQualification existing, VetQualification update) { + // 获取要更新的证书信息 + List> certificatesToUpdate = getCertificatesToUpdate(update); + if (certificatesToUpdate == null || certificatesToUpdate.isEmpty()) { + return; + } + + // 获取现有的证书列表 + List existingCertList = existing.getCertificateList(); + Map existingCertMap = new HashMap<>(); + + for (VetQualification.CertificateInfo cert : existingCertList) { + if (cert.getCertificateId() != null) { + existingCertMap.put(cert.getCertificateId(), cert); + } + } + + // 处理证书更新 + List updatedCertList = new ArrayList<>(); + + for (Map certMap : certificatesToUpdate) { + Long certificateId = extractLongFromObject(certMap.get("certId")); + + if (certificateId != null) { + // 更新现有证书 + VetQualification.CertificateInfo existingCert = existingCertMap.get(certificateId); + if (existingCert != null) { + VetQualification.CertificateInfo updatedCert = updateCertificateInfo(existingCert, certMap); + updatedCertList.add(updatedCert); + existingCertMap.remove(certificateId); + } else { + // 新增证书 + VetQualification.CertificateInfo newCert = createCertificateFromMap(certMap); + updatedCertList.add(newCert); + } + } else { + // 新增证书(没有certId) + VetQualification.CertificateInfo newCert = createCertificateFromMap(certMap); + newCert.setCertificateId(generateCertificateId()); + updatedCertList.add(newCert); + } + } + + // 添加未被修改的原有证书 + updatedCertList.addAll(existingCertMap.values()); + + // 更新证书列表到资质对象 + existing.setCertificateList(updatedCertList); + + // 更新主表字段(使用第一个证书的信息) + if (!updatedCertList.isEmpty()) { + VetQualification.CertificateInfo firstCert = updatedCertList.get(0); + existing.setCertName(firstCert.getCertName()); + existing.setCertificateNo(firstCert.getCertificateNo()); + existing.setIssueOrg(firstCert.getIssueOrg()); + existing.setIssueDate(firstCert.getIssueDate()); + existing.setExpireDate(firstCert.getExpireDate()); + existing.setCertificateFiles(firstCert.getCertificateFiles()); + existing.setCertStatus(firstCert.getCertStatus()); + existing.setCertId(firstCert.getCertificateId()); + } + } + + // ==================== 工具方法(小功能) ==================== + + private Long generateCertificateId() { + return generateSafeCertificateId(); + } + + /** + * 生成安全的证书ID(与VetQualification中的方法保持一致) + */ + private Long generateSafeCertificateId() { + // JavaScript安全整数上限 2^53-1 + final long MAX_SAFE_ID = 9007199254740991L; + final long MIN_SAFE_ID = 100000000L; // 最小9位数 + + // 当前毫秒时间戳(13位) + long timestamp = System.currentTimeMillis(); + + // 取时间戳的后12位(确保在安全范围内) + long id = timestamp % 1000000000000L; // 12位数字 + + // 加上1亿,确保是9位数以上 + id += MIN_SAFE_ID; + + // 双重检查:确保不超过JavaScript安全上限 + if (id > MAX_SAFE_ID) { + // 如果超过,取模回到安全范围 + id = id % (MAX_SAFE_ID - MIN_SAFE_ID) + MIN_SAFE_ID; + } + + // 添加随机性确保唯一性 + Random random = new Random(); + id = id * 1000L + random.nextInt(1000); + + return id; } /** * 从字典表根据scope_ids获取scope_names */ private String getScopeNamesFromDict(String scopeIds) { - if (scopeIds == null || scopeIds.isEmpty()) { + if (StringUtils.isEmpty(scopeIds)) { return ""; } + String[] idArray = scopeIds.split(","); List cleanedIds = new ArrayList<>(); for (String id : idArray) { cleanedIds.add("'" + id.trim() + "'"); } - String inCondition = String.join(",", cleanedIds); + String inCondition = String.join(",", cleanedIds); String sql = "SELECT dict_label FROM sys_dict_data " + "WHERE dict_type = 'business_scope' " + "AND dict_value IN (" + inCondition + ") " + @@ -76,108 +510,413 @@ public class VetQualificationServiceImpl implements IVetQualificationService } /** - * 处理资质文件路径 + * 从JSON中提取文件路径 */ - private String processCertificateFiles(String certificateFilesJson) { + private void extractFilePathsFromJson(VetQualification qualification) { + if (StringUtils.isEmpty(qualification.getCertificatesJson())) { + return; + } + try { - if (StringUtils.isEmpty(certificateFilesJson)) { - return ""; + List> certs = parseCertificatesJson(qualification.getCertificatesJson()); + List filePaths = new ArrayList<>(); + + for (Map cert : certs) { + String filePath = (String) cert.get("certificateFiles"); + if (StringUtils.isNotEmpty(filePath)) { + filePaths.add(filePath); + } + } + + if (!filePaths.isEmpty() && + (qualification.getCertificateFiles() == null || qualification.getCertificateFiles().isEmpty())) { + qualification.setCertificateFiles(String.join(",", filePaths)); } - return certificateFilesJson; } catch (Exception e) { - return certificateFilesJson; + // 忽略异常 } } /** - * 查询兽医资质 + * 处理经营范围IDs(支持数组格式) */ - @Override - public VetQualification selectVetQualificationByQualificationId(Long qualificationId) { - VetQualification qualification = vetQualificationMapper.selectVetQualificationByQualificationId(qualificationId); - if (qualification != null) { - // 更新证书状态 - updateCertificateStatus(qualification); + private String processScopeIds(String scopeIds) { + if (StringUtils.isEmpty(scopeIds)) { + return ""; + } + + // 如果是以 [ 开头,可能是JSON数组格式 + if (scopeIds.trim().startsWith("[")) { + try { + List scopeIdList = objectMapper.readValue(scopeIds, List.class); + return String.join(",", scopeIdList); + } catch (Exception e) { + return scopeIds; + } + } + + // 如果是逗号分隔的字符串,直接返回 + return scopeIds; + } + + /** + * 将请求数据转换为VetQualification对象 + */ + private VetQualification convertRequestToQualification(Map requestData) { + VetQualification qualification = new VetQualification(); + + // 设置基本信息 + qualification.setRealName((String) requestData.get("realName")); + qualification.setIdCard((String) requestData.get("idCard")); + qualification.setQualificationType((String) requestData.get("qualificationType")); + + // 处理经营范围 + Object scopeIdsObj = requestData.get("scopeIds"); + if (scopeIdsObj != null) { + String scopeIdsStr; + if (scopeIdsObj instanceof List) { + @SuppressWarnings("unchecked") + List scopeIdsList = (List) scopeIdsObj; + scopeIdsStr = String.join(",", scopeIdsList); + } else if (scopeIdsObj instanceof String) { + scopeIdsStr = (String) scopeIdsObj; + } else { + scopeIdsStr = scopeIdsObj.toString(); + } + qualification.setScopeIds(scopeIdsStr); + } + + // 处理证书信息 + Object certificatesObj = requestData.get("certificates"); + if (certificatesObj != null && certificatesObj instanceof List) { + @SuppressWarnings("unchecked") + List> certificates = (List>) certificatesObj; + processCertificates(qualification, certificates); + } + + // 处理单独的certId字段 + Object certIdObj = requestData.get("certId"); + if (certIdObj != null) { + Long certId = extractLongFromObject(certIdObj); + if (certId != null) { + qualification.setCertId(certId); + } } + return qualification; } /** - * 新增兽医资质 + * 处理证书列表 */ - @Override - public int insertVetQualification(VetQualification vetQualification) { - if (vetQualification.getAuditStatus() == null) { - vetQualification.setAuditStatus("3"); + private void processCertificates(VetQualification qualification, List> certificates) { + if (certificates == null || certificates.isEmpty()) { + return; } - /*if (vetQualification.getCertificateFiles() == null || - vetQualification.getCertificateFiles().isEmpty()) { - vetQualification.setCertificateFiles("default.pdf"); + + // 取第一个证书设置到主字段 + Map firstCert = certificates.get(0); + qualification.setCertName((String) firstCert.get("certName")); + qualification.setIssueOrg((String) firstCert.get("issueOrg")); + qualification.setCertificateNo((String) firstCert.get("certificateNo")); + qualification.setIssueDate(parseDate(firstCert.get("issueDate"))); + qualification.setExpireDate(parseDate(firstCert.get("expireDate"))); + + // 确保每个证书都有独立ID + List> processedCerts = new ArrayList<>(); + for (Map cert : certificates) { + Map processedCert = new HashMap<>(cert); + + Object certIdObj = cert.get("certId"); + Long certId = extractLongFromObject(certIdObj); + + if (certId == null || certId == 0) { + certId = generateCertificateId(); + processedCert.put("certId", certId); + } + + processedCerts.add(processedCert); } -*/ - if (vetQualification.getScopeIds() != null && !vetQualification.getScopeIds().isEmpty()) { - String scopeNames = getScopeNamesFromDict(vetQualification.getScopeIds()); - vetQualification.setScopeNames(scopeNames); + + // 设置主表certId为第一个证书的ID + Map firstProcessedCert = processedCerts.get(0); + Long firstCertId = extractLongFromObject(firstProcessedCert.get("certId")); + if (firstCertId != null) { + qualification.setCertId(firstCertId); } - // 设置默认提醒天数 - if (vetQualification.getRemindDays() == null) { - vetQualification.setRemindDays(30); + // 保存所有证书信息 + qualification.setCertificatesJson(mergeCertificatesToJson(processedCerts)); + } + + /** + * 从对象中提取Long值 + */ + private Long extractLongFromObject(Object obj) { + if (obj == null) { + return null; } - // 验证并设置证书状态 - updateCertificateStatus(vetQualification); + try { + if (obj instanceof Number) { + return ((Number) obj).longValue(); + } else if (obj instanceof String) { + String str = ((String) obj).trim(); + if (!str.isEmpty()) { + return Long.parseLong(str); + } + } + } catch (Exception e) { + // 忽略解析异常 + } - return vetQualificationMapper.insertVetQualification(vetQualification); + return null; } /** - * 修改兽医资质 + * 解析日期 */ - @Override - public int updateVetQualification(VetQualification vetQualification) { - // 处理资质文件路径 - if (vetQualification.getCertificateFiles() != null) { - vetQualification.setCertificateFiles(processCertificateFiles(vetQualification.getCertificateFiles())); + private Date parseDate(Object dateObj) { + if (dateObj == null) { + return null; } - if (vetQualification.getScopeIds() != null) { - String scopeNames = getScopeNamesFromDict(vetQualification.getScopeIds()); - vetQualification.setScopeNames(scopeNames); + try { + if (dateObj instanceof Date) { + return (Date) dateObj; + } else if (dateObj instanceof String) { + // 尝试解析为时间戳字符串 + try { + long timestamp = Long.parseLong((String) dateObj); + return new Date(timestamp); + } catch (NumberFormatException e) { + // 按日期格式解析 + return dateFormat.parse((String) dateObj); + } + } else if (dateObj instanceof Long) { + return new Date((Long) dateObj); + } else if (dateObj instanceof Integer) { + return new Date(((Integer) dateObj).longValue() * 1000L); + } + } catch (Exception e) { + // 忽略解析异常 } - // 验证并更新证书状态 - updateCertificateStatus(vetQualification); + return null; + } - return vetQualificationMapper.updateVetQualification(vetQualification); + /** + * 合并多个证书为JSON字符串 + */ + private String mergeCertificatesToJson(List> certificates) { + try { + List> certList = new ArrayList<>(); + + for (Map cert : certificates) { + Map certMap = new HashMap<>(); + certMap.put("certName", cert.get("certName")); + certMap.put("certificateNo", cert.get("certificateNo")); + certMap.put("issueOrg", cert.get("issueOrg")); + certMap.put("issueDate", cert.get("issueDate")); + certMap.put("expireDate", cert.get("expireDate")); + certMap.put("certificateFiles", cert.get("certificateFiles")); + + Object certIdObj = cert.get("certId"); + if (certIdObj != null) { + Long certId = extractLongFromObject(certIdObj); + if (certId != null && certId != 0) { + certMap.put("certId", certId); + } else { + certMap.put("certId", generateCertificateId()); + } + } else { + certMap.put("certId", generateCertificateId()); + } + + certList.add(certMap); + } + + return objectMapper.writeValueAsString(certList); + } catch (Exception e) { + return "[]"; + } } /** - * 批量删除兽医资质 + * 更新证书信息 */ - @Override - public int deleteVetQualificationByQualificationIds(Long[] qualificationIds) { - return vetQualificationMapper.deleteVetQualificationByQualificationIds(qualificationIds); + private VetQualification.CertificateInfo updateCertificateInfo(VetQualification.CertificateInfo existingCert, + Map updateMap) { + if (updateMap.containsKey("certName")) { + existingCert.setCertName((String) updateMap.get("certName")); + } + if (updateMap.containsKey("certificateNo")) { + existingCert.setCertificateNo((String) updateMap.get("certificateNo")); + } + if (updateMap.containsKey("issueOrg")) { + existingCert.setIssueOrg((String) updateMap.get("issueOrg")); + } + if (updateMap.containsKey("issueDate")) { + Object issueDateObj = updateMap.get("issueDate"); + existingCert.setIssueDate(parseDate(issueDateObj)); + } + if (updateMap.containsKey("expireDate")) { + Object expireDateObj = updateMap.get("expireDate"); + existingCert.setExpireDate(parseDate(expireDateObj)); + } + if (updateMap.containsKey("certificateFiles")) { + existingCert.setCertificateFiles((String) updateMap.get("certificateFiles")); + } + if (updateMap.containsKey("certStatus")) { + existingCert.setCertStatus((String) updateMap.get("certStatus")); + } + + return existingCert; } /** - * 删除兽医资质信息 + * 从Map创建新证书 */ - @Override - public int deleteVetQualificationByQualificationId(Long qualificationId) { - return vetQualificationMapper.deleteVetQualificationByQualificationId(qualificationId); + private VetQualification.CertificateInfo createCertificateFromMap(Map certMap) { + VetQualification.CertificateInfo cert = new VetQualification.CertificateInfo(); + + cert.setCertName((String) certMap.get("certName")); + cert.setCertificateNo((String) certMap.get("certificateNo")); + cert.setIssueOrg((String) certMap.get("issueOrg")); + + Object issueDateObj = certMap.get("issueDate"); + cert.setIssueDate(parseDate(issueDateObj)); + + Object expireDateObj = certMap.get("expireDate"); + cert.setExpireDate(parseDate(expireDateObj)); + + cert.setCertificateFiles((String) certMap.get("certificateFiles")); + cert.setCertStatus((String) certMap.get("certStatus")); + + // 如果有certId,设置它 + Long certId = extractLongFromObject(certMap.get("certId")); + if (certId != null) { + cert.setCertificateId(certId); + } + + return cert; } /** - * 根据用户ID查询资质证书列表 + * 获取要更新的证书列表 */ - @Override - public List selectQualificationsByUserId(Long userId) { - VetQualification query = new VetQualification(); - query.setUserId(userId); - return selectVetQualificationList(query); + private List> getCertificatesToUpdate(VetQualification qualification) { + if (qualification.getCertificates() != null && !qualification.getCertificates().isEmpty()) { + return qualification.getCertificates(); + } else if (StringUtils.isNotEmpty(qualification.getCertificatesJson())) { + try { + return parseCertificatesJson(qualification.getCertificatesJson()); + } catch (Exception e) { + throw new ServiceException("解析证书JSON失败: " + e.getMessage()); + } + } + return null; + } + + /** + * 解析证书JSON + */ + private List> parseCertificatesJson(String certificatesJson) throws Exception { + return objectMapper.readValue( + certificatesJson, + objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class) + ); + } + + /** + * 构建证书查询结果 + */ + private Map buildCertificateResult(VetQualification qualification, + Map certMap, + Long certId) { + Map result = new HashMap<>(); + + // 资质信息 + result.put("qualificationId", qualification.getQualificationId()); + result.put("userId", qualification.getUserId()); + result.put("realName", qualification.getRealName()); + result.put("idCard", qualification.getIdCard()); + result.put("qualificationType", qualification.getQualificationType()); + result.put("scopeIds", qualification.getScopeIds()); + result.put("scopeNames", qualification.getScopeNames()); + result.put("auditStatus", qualification.getAuditStatus()); + result.put("auditOpinion", qualification.getAuditOpinion()); + result.put("applyTime", qualification.getApplyTime()); + result.put("auditTime", qualification.getAuditTime()); + result.put("createTime", qualification.getCreateTime()); + result.put("updateTime", qualification.getUpdateTime()); + + // 证书信息 + result.put("certId", certId); + result.put("certName", certMap.get("certName")); + result.put("certificateNo", certMap.get("certificateNo")); + result.put("issueOrg", certMap.get("issueOrg")); + result.put("certificateFiles", certMap.get("certificateFiles")); + result.put("issueDate", parseDate(certMap.get("issueDate"))); + result.put("expireDate", parseDate(certMap.get("expireDate"))); + + // 计算证书状态 + Date expireDate = (Date) result.get("expireDate"); + String certStatus = calculateCertificateStatus(expireDate); + result.put("certStatus", certStatus); + + return result; } + /** + * 计算证书状态 + */ + private String calculateCertificateStatus(Date expireDate) { + if (expireDate == null) { + return "0"; + } + + Date today = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 30); + Date thirtyDaysLater = calendar.getTime(); + + if (expireDate.before(today)) { + return "2"; // 已过期 + } else if (expireDate.before(thirtyDaysLater)) { + return "1"; // 即将过期 + } else { + return "0"; // 正常 + } + } + + /** + * 更新证书状态 + */ + private void updateCertificateStatus(VetQualification qualification) { + if (qualification.getExpireDate() == null) { + qualification.setCertStatus("0"); + return; + } + + Date today = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_YEAR, 30); + Date thirtyDaysLater = calendar.getTime(); + + if (qualification.getExpireDate().before(today)) { + qualification.setCertStatus("2"); // 已过期 + } else if (qualification.getExpireDate().before(thirtyDaysLater)) { + qualification.setCertStatus("1"); // 即将过期 + } else { + qualification.setCertStatus("0"); // 正常 + } + } + + // 在VetQualificationServiceImpl类中添加以下方法 + /** * 获取即将过期的资质证书(30天内) */ @@ -220,25 +959,21 @@ public class VetQualificationServiceImpl implements IVetQualificationService VetQualification query = new VetQualification(); List allQualifications = vetQualificationMapper.selectVetQualificationList(query); - int successCount = 0; - int failCount = 0; - for (VetQualification qualification : allQualifications) { try { - // 检查证书是否需要提醒 - if (shouldSendRemind(qualification, today, thresholdDate, remindDate)) { - // 调用通知服务发送站内信 - vetNotificationService.sendCertificateExpireRemind(qualification); - - // 更新最后提醒时间 - qualification.setLastRemindTime(new Date()); - vetQualificationMapper.updateVetQualification(qualification); - - successCount++; + // 获取所有证书,检查每个证书 + List certificateList = qualification.getCertificateList(); + + for (VetQualification.CertificateInfo cert : certificateList) { + if (shouldSendRemindForCertificate(cert, today, thresholdDate, remindDate, qualification)) { + // 更新最后提醒时间(可以记录到证书级别,或保持资质级别) + qualification.setLastRemindTime(new Date()); + vetQualificationMapper.updateVetQualification(qualification); + } } } catch (Exception e) { - failCount++; - e.printStackTrace(); + // 记录错误日志 + // log.error("检查资质证书过期提醒失败,qualificationId={}", qualification.getQualificationId(), e); } } } @@ -246,18 +981,19 @@ public class VetQualificationServiceImpl implements IVetQualificationService /** * 判断是否需要发送提醒 */ - private boolean shouldSendRemind(VetQualification qualification, Date today, - Date thresholdDate, Date remindDate) { - if (qualification.getExpireDate() == null) { + private boolean shouldSendRemindForCertificate(VetQualification.CertificateInfo cert, + Date today, Date thresholdDate, + Date remindDate, VetQualification qualification) { + if (cert.getExpireDate() == null) { return false; } // 检查是否即将过期(30天内) - if (qualification.getExpireDate().after(thresholdDate)) { + if (cert.getExpireDate().after(thresholdDate)) { return false; } - // 检查是否已提醒过(7天内) + // 检查是否已提醒过(7天内)- 这里保持资质级别的提醒频率 if (qualification.getLastRemindTime() != null) { Calendar cal = Calendar.getInstance(); cal.setTime(qualification.getLastRemindTime()); @@ -276,98 +1012,11 @@ public class VetQualificationServiceImpl implements IVetQualificationService } /** - * 更新证书状态 - */ - private void updateCertificateStatus(VetQualification qualification) { - if (qualification.getExpireDate() == null) { - qualification.setCertStatus("0"); - return; - } - - Date today = new Date(); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(today); - calendar.add(Calendar.DAY_OF_YEAR, 30); - Date thirtyDaysLater = calendar.getTime(); - - if (qualification.getExpireDate().before(today)) { - qualification.setCertStatus("2"); // 已过期 - } else if (qualification.getExpireDate().before(thirtyDaysLater)) { - qualification.setCertStatus("1"); // 即将过期 - } else { - qualification.setCertStatus("0"); // 正常 - } - } - - /** - * 手动检查证书 + * 计算剩余天数 */ - @Override - public void manualCheckCertificates(Long userId) { - List qualifications = selectQualificationsByUserId(userId); - for (VetQualification qualification : qualifications) { - updateCertificateStatus(qualification); - vetQualificationMapper.updateVetQualification(qualification); - } + private int calculateRemainingDays(Date expireDate) { + if (expireDate == null) return 0; + long diff = expireDate.getTime() - new Date().getTime(); + return (int) (diff / (1000 * 60 * 60 * 24)); } - - /** - * 获取证书统计信息 - */ - @Override - public Map getCertificateStatistics(Long userId) { - Map statistics = new HashMap<>(); - - List qualifications = selectQualificationsByUserId(userId); - Date today = new Date(); - - long total = qualifications.size(); - long expiring = 0; // 30天内过期 - long expired = 0; // 已过期 - int expiringSoon = 0; // 7天内过期 - - Calendar calendar = Calendar.getInstance(); - calendar.setTime(today); - calendar.add(Calendar.DAY_OF_YEAR, 30); - Date thirtyDaysLater = calendar.getTime(); - - calendar.setTime(today); - calendar.add(Calendar.DAY_OF_YEAR, 7); - Date sevenDaysLater = calendar.getTime(); - - for (VetQualification qual : qualifications) { - if (qual.getExpireDate() != null) { - if (qual.getExpireDate().before(today)) { - expired++; - } else if (qual.getExpireDate().before(thirtyDaysLater)) { - expiring++; - - // 7天内过期 - if (qual.getExpireDate().before(sevenDaysLater)) { - expiringSoon++; - } - } - } - } - - long normal = total - expiring - expired; - - statistics.put("total", total); - statistics.put("normal", normal); - statistics.put("expiring", expiring); - statistics.put("expired", expired); - statistics.put("expiringSoon", expiringSoon); - - // 设置警告级别 - if (expired > 0) { - statistics.put("warningLevel", "DANGER"); - } else if (expiring > 0 || expiringSoon > 0) { - statistics.put("warningLevel", "WARNING"); - } else { - statistics.put("warningLevel", "NORMAL"); - } - - return statistics; - } - } \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/vet/VetArticleCategoryMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetArticleCategoryMapper.xml deleted file mode 100644 index 817a1c8..0000000 --- a/chenhai-system/src/main/resources/mapper/vet/VetArticleCategoryMapper.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - select id, name, description, icon, sort_order, status, create_time, update_time - from vet_article_category - - - - - - \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml index ce1b41b..84f15a0 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetExperienceArticleMapper.xml @@ -32,16 +32,19 @@ - select id, title, content, summary, cover_image, images, user_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 + select id, title, content, summary, cover_image, images, user_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 - + + - + - + --> - - - update vet_experience_article - set view_count = view_count + 1, - update_time = sysdate() + set view_count = ifnull(view_count, 0) + 1, + update_time = now() where id = #{id} update vet_experience_article - set like_count = like_count + 1, - update_time = sysdate() + set like_count = ifnull(like_count, 0) + 1, + update_time = now() where id = #{id} update vet_experience_article - set collect_count = collect_count + 1, - update_time = sysdate() + set collect_count = ifnull(collect_count, 0) + 1, + update_time = now() where id = #{id} + insert into vet_experience_article @@ -175,7 +160,7 @@ is_sensitive, sensitive_words, publish_time, - create_time, + create_time, update_time, @@ -200,11 +185,12 @@ #{isSensitive}, #{sensitiveWords}, #{publishTime}, - #{createTime}, + now(), #{updateTime}, + update vet_experience_article @@ -229,27 +215,21 @@ is_sensitive = #{isSensitive}, sensitive_words = #{sensitiveWords}, publish_time = #{publishTime}, - update_time = #{updateTime}, + update_time = now(), where id = #{id} + delete from vet_experience_article where id = #{id} + delete from vet_experience_article where id in #{id} - - \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/vet/VetProductMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetProductMapper.xml index 47de597..eff0d7b 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetProductMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetProductMapper.xml @@ -33,10 +33,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + - select id, name, type, category, specification, unit, manufacturer, approval_number, ingredients, indications, usage_dosage, price, cost_price, stock, min_stock, main_image, images, treat_animals, treat_diseases, treatment_content, treatment_duration, precautions, status, is_deleted, clinic_id, user_id, created_at, updated_at from vet_product + select id, name, type, category, specification, unit, manufacturer, approval_number, ingredients, indications, usage_dosage, price, cost_price, stock, min_stock, main_image, images, treat_animals, treat_diseases, treatment_content, treatment_duration, precautions, status, is_deleted, clinic_id, user_id, created_at, updated_at,audit_status, audit_opinion, audit_user_id, audit_time from vet_product @@ -107,6 +112,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" user_id, created_at, updated_at, + audit_status, + audit_opinion, + audit_user_id, + audit_time, #{name}, @@ -136,6 +145,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{userId}, #{createdAt}, #{updatedAt}, + #{auditStatus}, + #{auditOpinion}, + #{auditUserId}, + #{auditTime}, @@ -169,6 +182,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" user_id = #{userId}, created_at = #{createdAt}, updated_at = #{updatedAt}, + audit_status = #{auditStatus}, + audit_opinion = #{auditOpinion}, + audit_user_id = #{auditUserId}, + audit_time = #{auditTime}, where id = #{id} diff --git a/chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml index e323a22..2468953 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetQualificationMapper.xml @@ -26,6 +26,7 @@ + @@ -36,6 +37,7 @@ + @@ -69,6 +71,8 @@ and vq.audit_opinion = #{auditOpinion} and vq.auditor_id = #{auditorId} and vq.scope_names = #{scopeNames} + + and vq.cert_id = #{certId} and vq.cert_name like concat('%', #{certName}, '%') and vq.cert_type = #{certType} @@ -97,7 +101,12 @@ real_name, id_card, qualification_type, + + certificate_no, + + + certificates_json, certificate_files, apply_time, audit_time, @@ -112,6 +121,7 @@ scope_ids, scope_names, + cert_id, cert_name, cert_type, issue_org, @@ -127,7 +137,12 @@ #{realName}, #{idCard}, #{qualificationType}, + + #{certificateNo}, + + + #{certificatesJson}, #{certificateFiles}, #{applyTime}, #{auditTime}, @@ -142,6 +157,7 @@ #{scopeIds}, #{scopeNames}, + #{certId}, #{certName}, #{certType}, #{issueOrg}, @@ -162,6 +178,10 @@ id_card = #{idCard}, qualification_type = #{qualificationType}, certificate_no = #{certificateNo}, + + + certificates_json = #{certificatesJson}, + certificate_files = #{certificateFiles}, apply_time = #{applyTime}, audit_time = #{auditTime}, @@ -174,6 +194,7 @@ scope_ids = #{scopeIds}, scope_names = #{scopeNames}, + cert_id = #{certId}, cert_name = #{certName}, cert_type = #{certType}, issue_org = #{issueOrg}, @@ -205,4 +226,24 @@ ORDER BY create_time DESC + \ No newline at end of file diff --git a/chenhai-ui/src/api/vet/product.js b/chenhai-ui/src/api/vet/product.js index 995030b..552b423 100644 --- a/chenhai-ui/src/api/vet/product.js +++ b/chenhai-ui/src/api/vet/product.js @@ -42,3 +42,44 @@ export function delProduct(id) { method: 'delete' }) } + +// 提交审核 +export function submitAudit(id) { + return request({ + url: '/vet/product/submitAudit/' + id, + method: 'post' + }) +} + +// 审核产品 +export function auditProduct(data) { + return request({ + url: '/vet/product/audit', + method: 'post', + data: data + }) +} + +// 上架产品 +export function publishProduct(id) { + return request({ + url: '/vet/product/publish/' + id, + method: 'post' + }) +} + +// 下架产品 +export function offlineProduct(id) { + return request({ + url: '/vet/product/offline/' + id, + method: 'post' + }) +} + +// 取消审核 +export function cancelAudit(id) { + return request({ + url: '/vet/product/cancelAudit/' + id, + method: 'post' + }) +} diff --git a/chenhai-ui/src/views/vet/article/index.vue b/chenhai-ui/src/views/vet/article/index.vue index 2b48166..5507c25 100644 --- a/chenhai-ui/src/views/vet/article/index.vue +++ b/chenhai-ui/src/views/vet/article/index.vue @@ -1,1716 +1,836 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/chenhai-ui/src/views/vet/product/index.vue b/chenhai-ui/src/views/vet/product/index.vue index d26e3af..6417805 100644 --- a/chenhai-ui/src/views/vet/product/index.vue +++ b/chenhai-ui/src/views/vet/product/index.vue @@ -24,9 +24,28 @@ style="width: 120px" > - - - + + + + + + + + + + + + + + + + + @@ -42,6 +61,20 @@ + + + + + + + + + 搜索 @@ -147,17 +180,12 @@
{{ scope.row.name }} - -
-
主图: {{ scope.row.mainImage || '无' }}
-
图片数量: {{ getImageCount(scope.row) }}
-
- + + + > + + + + + + @@ -389,9 +513,10 @@ - - - + + + + @@ -400,7 +525,16 @@ - + + + + + + + + + + @@ -654,7 +788,9 @@ - {{ currentDetail.category || '--' }} + + {{ getCategoryText(currentDetail.category) }} + {{ currentDetail.specification || '--' }} @@ -673,6 +809,11 @@ {{ getStatusText(currentDetail.status) }} + + + {{ getAuditStatusText(currentDetail.auditStatus) }} + + ¥{{ currentDetail.price || '0.00' }} @@ -727,7 +868,7 @@