diff --git a/chenhai-admin/pom.xml b/chenhai-admin/pom.xml index c48e98b..2c8b99a 100644 --- a/chenhai-admin/pom.xml +++ b/chenhai-admin/pom.xml @@ -60,6 +60,8 @@ true + + diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/CarouselAdsController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/CarouselAdsController.java index 98ddcb4..0d2d30e 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/CarouselAdsController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/CarouselAdsController.java @@ -32,7 +32,7 @@ public class CarouselAdsController extends BaseController * 查询轮播广告列表 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:list')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @GetMapping("/list") public TableDataInfo list(CarouselAds carouselAds) { @@ -45,7 +45,7 @@ public class CarouselAdsController extends BaseController * 导出轮播广告列表 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:export')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @Log(title = "轮播广告", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, CarouselAds carouselAds) @@ -59,7 +59,7 @@ public class CarouselAdsController extends BaseController * 获取轮播广告详细信息 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:query')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @GetMapping(value = "/{carouselId}") public AjaxResult getInfo(@PathVariable("carouselId") Long carouselId) { @@ -70,7 +70,7 @@ public class CarouselAdsController extends BaseController * 新增轮播广告 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:add')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @Log(title = "轮播广告", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody CarouselAds carouselAds) @@ -82,7 +82,7 @@ public class CarouselAdsController extends BaseController * 修改轮播广告 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:edit')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "轮播广告", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody CarouselAds carouselAds) @@ -94,7 +94,7 @@ public class CarouselAdsController extends BaseController * 删除轮播广告 */ // @PreAuthorize("@ss.hasPermi('muhu:ads:remove')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "轮播广告", businessType = BusinessType.DELETE) @DeleteMapping("/{carouselIds}") public AjaxResult remove(@PathVariable Long[] carouselIds) diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/DisasterWarningController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/DisasterWarningController.java index c41e76d..9630c7f 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/DisasterWarningController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/DisasterWarningController.java @@ -38,7 +38,7 @@ public class DisasterWarningController extends BaseController * 查询灾害预警信息列表 */ // @PreAuthorize("@ss.hasPermi('muhu:warning:list')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @GetMapping("/list") public TableDataInfo list(DisasterWarning disasterWarning) { @@ -51,7 +51,7 @@ public class DisasterWarningController extends BaseController * 导出灾害预警信息列表 */ // @PreAuthorize("@ss.hasPermi('muhu:warning:export')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')") @Log(title = "灾害预警信息", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, DisasterWarning disasterWarning) @@ -65,7 +65,7 @@ public class DisasterWarningController extends BaseController * 获取灾害预警信息详细信息 */ // @PreAuthorize("@ss.hasPermi('muhu:warning:query')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')") @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") Long id) { @@ -76,7 +76,7 @@ public class DisasterWarningController extends BaseController * 新增灾害预警信息 */ // @PreAuthorize("@ss.hasPermi('muhu:warning:add')") - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "灾害预警信息", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody DisasterWarning disasterWarning) diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/MerchantInfoController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/MerchantInfoController.java index fa9284c..50cd5e3 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/MerchantInfoController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/MerchantInfoController.java @@ -1,6 +1,9 @@ package com.chenhai.web.controller.vet; import java.util.List; + +import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.system.service.ISysUserService; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -34,6 +37,9 @@ public class MerchantInfoController extends BaseController @Autowired private IMerchantInfoService merchantInfoService; + @Autowired + private ISysUserService sysUserService; // 需要注入用户服务 + /** * 查询商家信息列表 */ @@ -42,10 +48,28 @@ public class MerchantInfoController extends BaseController public TableDataInfo list(MerchantInfo merchantInfo) { startPage(); + + // 获取当前用户ID + Long currentUserId = SecurityUtils.getUserId(); + + // 判断是否为管理员或管理员 + boolean isAdmin = SecurityUtils.isAdmin(currentUserId); + boolean isManager = false; // 需要根据你的系统实现判断 + + // 如果你有判断manager的方法 + // boolean isManager = SecurityUtils.isManager(currentUserId); + + // 如果你有用户服务,可以通过用户信息判断 + // boolean isManager = sysUserService.isManagerRole(currentUserId); + + // 如果不是管理员或管理员,则只能查询自己的店铺 + if (!isAdmin && !isManager) { + merchantInfo.setUserId(currentUserId); + } + List list = merchantInfoService.selectMerchantInfoList(merchantInfo); return getDataTable(list); } - /** * 导出商家信息列表 */ @@ -54,11 +78,28 @@ public class MerchantInfoController extends BaseController @PostMapping("/export") public void export(HttpServletResponse response, MerchantInfo merchantInfo) { + // 获取当前用户ID + Long currentUserId = SecurityUtils.getUserId(); + + // 判断是否为管理员或管理员 + boolean isAdmin = SecurityUtils.isAdmin(currentUserId); + boolean isManager = false; // 需要根据你的系统实现判断 + + // 如果你有判断manager的方法 + // boolean isManager = SecurityUtils.isManager(currentUserId); + + // 如果你有用户服务,可以通过用户信息判断 + // boolean isManager = sysUserService.isManagerRole(currentUserId); + + // 如果不是管理员或管理员,则只能导出自己的店铺 + if (!isAdmin && !isManager) { + merchantInfo.setUserId(currentUserId); + } + List list = merchantInfoService.selectMerchantInfoList(merchantInfo); ExcelUtil util = new ExcelUtil(MerchantInfo.class); util.exportExcel(response, list, "商家信息数据"); } - /** * 获取商家信息详细信息 */ @@ -77,6 +118,13 @@ public class MerchantInfoController extends BaseController @PostMapping public AjaxResult add(@RequestBody MerchantInfo merchantInfo) { + Long currentUserId = SecurityUtils.getUserId(); + merchantInfo.setUserId(currentUserId); + + // 设置默认审核状态 + merchantInfo.setAuditStatus("0"); // 未审核 + merchantInfo.setShopStatus("0"); // 未上架 + return toAjax(merchantInfoService.insertMerchantInfo(merchantInfo)); } @@ -88,6 +136,13 @@ public class MerchantInfoController extends BaseController @PutMapping public AjaxResult edit(@RequestBody MerchantInfo merchantInfo) { + Long currentUserId = SecurityUtils.getUserId(); + /* if (!SecurityUtils.isAdmin()) { + MerchantInfo existingMerchant = merchantInfoService.selectMerchantInfoByShopId(merchantInfo.getShopId()); + if (existingMerchant == null || !currentUserId.equals(existingMerchant.getUserId())) { + return error("只能修改自己的商家信息"); + } + }*/ return toAjax(merchantInfoService.updateMerchantInfo(merchantInfo)); } @@ -101,4 +156,76 @@ public class MerchantInfoController extends BaseController { return toAjax(merchantInfoService.deleteMerchantInfoByShopIds(shopIds)); } + + + /** + * 提交商家审核 + */ + @PreAuthorize("@ss.hasPermi('vet:merchant:submit')") + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/submitAudit/{shopId}") + public AjaxResult submitMerchantForAudit(@PathVariable("shopId") Long shopId) + { + return toAjax(merchantInfoService.submitMerchantForAudit(shopId)); + } + + /** + * 审核商家 + */ + /* @PreAuthorize("@ss.hasPermi('vet:merchant:audit')")*/ + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/audit") + public AjaxResult auditMerchant(@RequestBody MerchantInfo merchantInfo) + { + Long auditUserId = SecurityUtils.getUserId(); + return toAjax(merchantInfoService.auditMerchant( + merchantInfo.getShopId(), + merchantInfo.getAuditStatus(), + merchantInfo.getAuditOpinion(), + auditUserId + )); + } + + /** + * 上架商家 + */ + @PreAuthorize("@ss.hasPermi('vet:merchant:publish')") + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/publish/{shopId}") + public AjaxResult publishMerchant(@PathVariable("shopId") Long shopId) + { + return toAjax(merchantInfoService.publishMerchant(shopId)); + } + + /** + * 下架商家 + */ + @PreAuthorize("@ss.hasPermi('vet:merchant:offline')") + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/offline/{shopId}") + public AjaxResult offlineMerchant(@PathVariable("shopId") Long shopId) + { + return toAjax(merchantInfoService.offlineMerchant(shopId)); + } + + /** + * 取消商家审核 + */ + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/cancelAudit/{shopId}") + public AjaxResult cancelMerchantAudit(@PathVariable("shopId") Long shopId) + { + return toAjax(merchantInfoService.cancelMerchantAudit(shopId)); + } + + /** + * 重新提交商家审核(审核不通过后重新提交) + */ + @PreAuthorize("@ss.hasPermi('vet:merchant:resubmit')") + @Log(title = "商家信息", businessType = BusinessType.UPDATE) + @PostMapping("/resubmitAudit/{shopId}") + public AjaxResult resubmitMerchantForAudit(@PathVariable("shopId") Long shopId) + { + return toAjax(merchantInfoService.resubmitMerchantForAudit(shopId)); + } } diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetCommentsController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetCommentsController.java index c728617..419b074 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetCommentsController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetCommentsController.java @@ -1,6 +1,8 @@ package com.chenhai.web.controller.vet; import java.util.List; + +import com.chenhai.common.annotation.SensitiveCheck; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -72,6 +74,7 @@ public class VetCommentsController extends BaseController /** * 新增兽医回复 */ + @SensitiveCheck @PreAuthorize("@ss.hasPermi('vet:comments:add') or @ss.hasRole('vetnotshenhe') or @ss.hasRole('vet')") @Log(title = "兽医回复", businessType = BusinessType.INSERT) @PostMapping @@ -83,6 +86,7 @@ public class VetCommentsController extends BaseController /** * 修改兽医回复 */ + @SensitiveCheck @PreAuthorize("@ss.hasPermi('vet:comments:edit') or @ss.hasRole('vetnotshenhe') or @ss.hasRole('vet')") @Log(title = "兽医回复", businessType = BusinessType.UPDATE) @PutMapping 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 2d07c16..86cce7b 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,6 +1,7 @@ package com.chenhai.web.controller.vet; import com.chenhai.common.annotation.Log; +import com.chenhai.common.annotation.SensitiveCheck; import com.chenhai.common.core.controller.BaseController; import com.chenhai.common.core.domain.AjaxResult; import com.chenhai.common.core.page.TableDataInfo; @@ -300,6 +301,7 @@ public class VetExperienceArticleController extends BaseController { /** * 发布新文章(论坛发布) */ + @SensitiveCheck @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "发布经验文章", businessType = BusinessType.INSERT) @PostMapping @@ -366,6 +368,7 @@ public class VetExperienceArticleController extends BaseController { /** * 修改文章 */ + @SensitiveCheck @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "修改经验文章", businessType = BusinessType.UPDATE) @PutMapping diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java index 652a16f..0b9300b 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java @@ -1,6 +1,8 @@ package com.chenhai.web.controller.vet; import java.util.List; + +import com.chenhai.common.annotation.SensitiveCheck; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -65,6 +67,7 @@ public class VetExpertsController extends BaseController /** * 新增专家信息 */ + @SensitiveCheck @PreAuthorize("@ss.hasPermi('vet:experts:add') or @ss.hasRole('muhu')") @Log(title = "专家信息", businessType = BusinessType.INSERT) @PostMapping diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java index 54f2a4a..3085cac 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java @@ -2,6 +2,7 @@ package com.chenhai.web.controller.vet; import java.util.List; +import com.chenhai.common.annotation.SensitiveCheck; import com.chenhai.common.utils.SecurityUtils; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; @@ -24,6 +25,7 @@ import com.chenhai.vet.service.IVetKnowledgeService; import com.chenhai.common.utils.poi.ExcelUtil; import com.chenhai.common.core.page.TableDataInfo; + /** * 兽医文章Controller * @@ -40,7 +42,8 @@ public class VetKnowledgeController extends BaseController /** * 查询兽医文章列表 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:list') or @ss.hasRole('muhu') or @ss.hasRole('vet')") + + @PreAuthorize("@ss.hasPermi('vet:knowledge:list') or @ss.hasRole('muhu') or @ss.hasRole('vet')or @ss.hasRole('manger')") @GetMapping("/list") public TableDataInfo list(VetKnowledge vetKnowledge) { @@ -52,7 +55,8 @@ public class VetKnowledgeController extends BaseController /** * 导出兽医文章列表 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:export') or @ss.hasRole('muhu')") + + @PreAuthorize("@ss.hasPermi('vet:knowledge:export') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, VetKnowledge vetKnowledge) @@ -65,7 +69,7 @@ public class VetKnowledgeController extends BaseController /** * 获取兽医文章详细信息 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:query') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:query') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") Long id) { @@ -75,7 +79,8 @@ public class VetKnowledgeController extends BaseController /** * 新增兽医文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:add') or @ss.hasRole('muhu')") + @SensitiveCheck + @PreAuthorize("@ss.hasPermi('vet:knowledge:add') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody VetKnowledge vetKnowledge) @@ -99,12 +104,13 @@ public class VetKnowledgeController extends BaseController /** * 删除兽医文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:remove') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:remove')") @Log(title = "兽医文章", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult remove(@PathVariable Long[] ids) { - return toAjax(vetKnowledgeService.deleteVetKnowledgeByIds(ids)); + // 直接调用service方法,返回AjaxResult + return vetKnowledgeService.deleteVetKnowledgeByIds(ids); } /** @@ -120,7 +126,7 @@ public class VetKnowledgeController extends BaseController /** * 审核文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:audit') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:audit') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.UPDATE) @PutMapping("/audit/{id}") public AjaxResult audit(@PathVariable Long id, @@ -135,7 +141,7 @@ public class VetKnowledgeController extends BaseController /** * 发布文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.UPDATE) @PutMapping("/publish/{id}") public AjaxResult publish(@PathVariable Long id) { @@ -145,7 +151,7 @@ public class VetKnowledgeController extends BaseController /** * 上架文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.UPDATE) @PutMapping("/online/{id}") public AjaxResult online(@PathVariable Long id) { @@ -155,7 +161,7 @@ public class VetKnowledgeController extends BaseController /** * 下架文章 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @Log(title = "兽医文章", businessType = BusinessType.UPDATE) @PutMapping("/offline/{id}") public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) { @@ -178,6 +184,7 @@ public class VetKnowledgeController extends BaseController return getDataTable(list); } + /** * 获取已发布文章的详细信息(公开接口) */ @@ -196,5 +203,4 @@ public class VetKnowledgeController extends BaseController } return error("文章不存在或未发布"); } - } \ No newline at end of file diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java index 441dd1a..00dad2e 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java @@ -7,17 +7,24 @@ import com.chenhai.common.core.domain.model.LoginUser; import com.chenhai.common.core.page.TableDataInfo; import com.chenhai.common.enums.BusinessType; import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.common.utils.StringUtils; import com.chenhai.common.utils.poi.ExcelUtil; import com.chenhai.system.service.ISysUserService; import com.chenhai.vet.domain.VetPersonalInfo; +import com.chenhai.vet.domain.VetQualification; +import com.chenhai.vet.mapper.VetQualificationMapper; import com.chenhai.vet.service.IVetPersonalInfoService; +import com.chenhai.vet.service.IVetQualificationService; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Comparator; +import java.util.stream.Collectors; /** * 兽医个人信息Controller @@ -34,6 +41,8 @@ public class VetPersonalInfoController extends BaseController @Autowired private ISysUserService userService; + @Autowired + private IVetQualificationService vetQualificationService; /** * 获取当前登录用户ID @@ -215,30 +224,139 @@ public class VetPersonalInfoController extends BaseController /** * 新增兽医个人信息 */ + /** + * 新增兽医个人信息(带完整校验) + */ @PreAuthorize("@ss.hasPermi('vet:info:add')") @Log(title = "兽医个人信息", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody VetPersonalInfo vetPersonalInfo) { - // 自动设置当前用户ID - Long currentUserId = getCurrentUserId(); - if (currentUserId == null) { - return error("用户未登录"); - } + try { + // 1. 自动设置当前用户ID + Long currentUserId = getCurrentUserId(); + if (currentUserId == null) { + return error("用户未登录"); + } + + // 2. 检查是否已存在该用户的个人信息 + VetPersonalInfo existing = vetPersonalInfoService.selectVetPersonalInfoByUserId(currentUserId); + if (existing != null) { + return error("您已经创建了个人信息,请使用修改功能"); + } + + // 3. 姓名校验(2-20个汉字) + String realName = vetPersonalInfo.getRealName(); + if (realName == null || realName.trim().isEmpty()) { + return error("真实姓名不能为空"); + } + + realName = realName.trim(); + if (!realName.matches("^[\\u4e00-\\u9fa5]{2,20}$")) { + return error("姓名必须是2-20个汉字"); + } + vetPersonalInfo.setRealName(realName); + + // 4. 身份证校验 + String idCard = vetPersonalInfo.getIdCard(); + if (StringUtils.isNotEmpty(idCard)) { + idCard = idCard.trim().toUpperCase(); + + // 身份证格式校验 + if (!isValidIdCard(idCard)) { + return error("身份证号格式不正确"); + } + + // 检查身份证是否已被使用 + VetPersonalInfo query = new VetPersonalInfo(); + query.setIdCard(idCard); + List idCardUsers = vetPersonalInfoService.selectVetPersonalInfoList(query); + if (!idCardUsers.isEmpty()) { + for (VetPersonalInfo user : idCardUsers) { + if (!user.getUserId().equals(currentUserId)) { + return error("该身份证号已被其他用户使用"); + } + } + } + + vetPersonalInfo.setIdCard(idCard); + } + + // 5. 电话校验 + String phone = vetPersonalInfo.getPhone(); + if (StringUtils.isNotEmpty(phone)) { + phone = phone.trim(); + if (!isValidPhone(phone)) { + return error("手机号格式不正确"); + } + vetPersonalInfo.setPhone(phone); + } + + // 6. 联系方式校验 + String iphone = vetPersonalInfo.getIphone(); + if (StringUtils.isNotEmpty(iphone)) { + iphone = iphone.trim(); + if (!isValidPhone(iphone)) { + return error("联系方式格式不正确"); + } + vetPersonalInfo.setIphone(iphone); + } + + // 7. 邮箱校验 + String email = vetPersonalInfo.getEmail(); + if (StringUtils.isNotEmpty(email)) { + email = email.trim(); + if (!isValidEmail(email)) { + return error("邮箱格式不正确"); + } + vetPersonalInfo.setEmail(email); + } + + // 8. 自动设置用户ID和创建者 + vetPersonalInfo.setUserId(currentUserId); + vetPersonalInfo.setCreateBy(getCurrentUsername()); - // 检查是否已存在该用户的个人信息 - VetPersonalInfo existing = vetPersonalInfoService.selectVetPersonalInfoByUserId(currentUserId); - if (existing != null) { - return error("您已经创建了个人信息,请使用修改功能"); + return toAjax(vetPersonalInfoService.insertVetPersonalInfo(vetPersonalInfo)); + + } catch (RuntimeException e) { + return error(e.getMessage()); } + } - // 自动设置用户ID和创建者 - vetPersonalInfo.setUserId(currentUserId); - vetPersonalInfo.setCreateBy(getCurrentUsername()); + /** + * 验证身份证号格式(18位) + */ + private boolean isValidIdCard(String idCard) { + if (StringUtils.isEmpty(idCard)) { + return false; + } + // 18位身份证正则 + String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9X]$"; + return idCard.matches(regex); + } - return toAjax(vetPersonalInfoService.insertVetPersonalInfo(vetPersonalInfo)); + /** + * 验证手机号格式 + */ + private boolean isValidPhone(String phone) { + if (StringUtils.isEmpty(phone)) { + return false; + } + // 手机号正则(11位) + String regex = "^1[3-9]\\d{9}$"; + return phone.matches(regex); } + /** + * 验证邮箱格式 + */ + private boolean isValidEmail(String email) { + if (StringUtils.isEmpty(email)) { + return false; + } + String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; + return email.matches(regex); + } /** * 修改兽医个人信息 */ @@ -254,7 +372,6 @@ public class VetPersonalInfoController extends BaseController return error("无权修改他人信息"); } } - return toAjax(vetPersonalInfoService.updateVetPersonalInfo(vetPersonalInfo)); } @@ -296,8 +413,9 @@ public class VetPersonalInfoController extends BaseController util.exportExcel(response, list, "兽医个人信息数据"); } + /** - * 获取当前登录用户的兽医信息(快捷方法) + * 获取当前用户的兽医信息(包含资质信息) */ @Log(title = "兽医个人信息", businessType = BusinessType.OTHER) @PreAuthorize("@ss.hasPermi('vet:info:query')") @@ -309,10 +427,61 @@ public class VetPersonalInfoController extends BaseController return error("用户未登录"); } + Map result = new HashMap<>(); + + // 1. 获取兽医个人信息 VetPersonalInfo info = vetPersonalInfoService.selectVetPersonalInfoByUserId(userId); + + // 2. 获取资质信息 + List qualifications = vetQualificationService.selectQualificationsByUserId(userId); + + // 3. 如果没有个人信息记录,创建空对象 if (info == null) { - return error("您还没有创建兽医个人信息"); + info = new VetPersonalInfo(); + info.setUserId(userId); + } + + // 4. 如果有资质信息,填充到个人信息中 + VetQualification latestQualification = null; + if (qualifications != null && !qualifications.isEmpty()) { + latestQualification = qualifications.get(0); + + // 填充真实姓名 + if (StringUtils.isNotEmpty(latestQualification.getRealName()) && + StringUtils.isEmpty(info.getRealName())) { + info.setRealName(latestQualification.getRealName()); + } + + // 填充身份证号 + if (StringUtils.isNotEmpty(latestQualification.getIdCard()) && + StringUtils.isEmpty(info.getIdCard())) { + info.setIdCard(latestQualification.getIdCard()); + } + } + + result.put("personalInfo", info); + result.put("qualification", latestQualification); + result.put("hasQualifications", latestQualification != null); + + return success(result); + } + + /** + * 从资质信息填充个人信息 + */ + private void fillPersonalInfoFromQualification(VetPersonalInfo personalInfo, VetQualification qualification) { + if (qualification == null) return; + + // 填充真实姓名 + if (StringUtils.isNotEmpty(qualification.getRealName()) && + StringUtils.isEmpty(personalInfo.getRealName())) { + personalInfo.setRealName(qualification.getRealName()); + } + + // 填充身份证号 + if (StringUtils.isNotEmpty(qualification.getIdCard()) && + StringUtils.isEmpty(personalInfo.getIdCard())) { + personalInfo.setIdCard(qualification.getIdCard()); } - return success(info); } } \ 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 a10e72b..66904ff 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 @@ -3,6 +3,7 @@ package com.chenhai.web.controller.vet; import java.util.List; import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.vet.domain.dto.BatchSubmitAuditDTO; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -195,4 +196,40 @@ public class VetProductController extends BaseController List list = vetProductService.selectAllVetProductList(vetProduct); return getDataTable(list); } + + /** + * 批量提交产品审核(按商家) + */ + @PreAuthorize("@ss.hasPermi('vet:product:batch:submit')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/batchSubmitAudit/{shopId}") + public AjaxResult batchSubmitProductsForAudit(@PathVariable("shopId") Long shopId) + { + return toAjax(vetProductService.batchSubmitProductsForAudit(shopId)); + } + /** + * 根据商家ID查询产品列表 + */ + @Log(title = "兽医产品信息", businessType = BusinessType.OTHER) + @PreAuthorize("@ss.hasPermi('vet:product:list')") + @GetMapping("/shop/{shopId}") + public TableDataInfo getProductsByShopId(@PathVariable("shopId") Long shopId, VetProduct vetProduct) + { + startPage(); + // 设置商家ID + vetProduct.setShopId(shopId); + List list = vetProductService.selectVetProductList(vetProduct); + return getDataTable(list); + } + + /** + * 重新提交产品审核(审核不通过后重新提交) + */ + @PreAuthorize("@ss.hasPermi('vet:product:resubmit')") + @Log(title = "兽医产品信息", businessType = BusinessType.UPDATE) + @PostMapping("/resubmitAudit/{id}") + public AjaxResult resubmitForAudit(@PathVariable("id") Long id) + { + return toAjax(vetProductService.resubmitForAudit(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 b8c2442..ab6941d 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 @@ -7,6 +7,7 @@ import com.chenhai.common.core.page.TableDataInfo; import com.chenhai.common.enums.BusinessType; 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.service.IVetQualificationService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -176,6 +177,11 @@ public class VetQualificationController extends BaseController VetQualification query = new VetQualification(); query.setQualificationId(qualificationId); + // 非管理员只能查询自己的资质 + if (!SecurityUtils.isAdmin(userId)) { + query.setUserId(userId); + } + // 查询指定资质 List qualifications = vetQualificationService.selectVetQualificationList(query); if (qualifications == null || qualifications.isEmpty()) { @@ -184,11 +190,6 @@ public class VetQualificationController extends BaseController VetQualification qualification = qualifications.get(0); - // 权限验证:非管理员只能查看自己的资质 - if (!SecurityUtils.isAdmin(userId) && !qualification.getUserId().equals(userId)) { - throw new ServiceException("无权查看此资质的证书"); - } - // 处理分页 startPage(); @@ -235,15 +236,21 @@ public class VetQualificationController extends BaseController { try { Long currentUserId = SecurityUtils.getUserId(); - boolean isAdmin = SecurityUtils.isAdmin(currentUserId); + // 权限检查:只有管理员和证书所有者可以查看 Map certificateInfo = vetQualificationService - .selectCertificateWithQualificationByCertId(certId, isAdmin ? null : currentUserId); + .selectCertificateWithQualificationByCertId(certId, currentUserId); if (certificateInfo == null || certificateInfo.isEmpty()) { return AjaxResult.error("证书不存在或没有权限查看"); } + // 再次权限验证(双重保险) + Long certOwnerId = (Long) certificateInfo.get("userId"); + if (!SecurityUtils.isAdmin(currentUserId) && !currentUserId.equals(certOwnerId)) { + return AjaxResult.error("无权查看此证书"); + } + Object expireDateObj = certificateInfo.get("expireDate"); if (expireDateObj instanceof Date) { Date expireDate = (Date) expireDateObj; @@ -257,6 +264,7 @@ public class VetQualificationController extends BaseController return AjaxResult.success(certificateInfo); } catch (Exception e) { + log.error("查询证书失败,certId: {}", certId, e); return AjaxResult.error("查询证书失败:" + e.getMessage()); } } @@ -439,29 +447,536 @@ public class VetQualificationController extends BaseController /** * 提交审核 */ + /** + * 提交审核(带完整校验,不改变原有逻辑) + */ @Log(title = "兽医资质", businessType = BusinessType.UPDATE) @PostMapping("/submit") public AjaxResult submitQualification(@RequestBody Object requestBody) { try { + Long sysUserId = SecurityUtils.getUserId(); + String username = SecurityUtils.getUsername(); + + if (sysUserId == null) { + return error("用户未登录"); + } + + // 1. 提取数据并进行校验(不改变原有数据结构) if (requestBody instanceof Map) { @SuppressWarnings("unchecked") Map requestData = (Map) requestBody; - return processNewFormat(requestData); - } else { + + // 姓名校验 + String realName = (String) requestData.get("realName"); + if (realName == null || realName.trim().isEmpty()) { + return error("真实姓名不能为空"); + } + realName = realName.trim(); + if (!realName.matches("^[\\u4e00-\\u9fa5]{2,20}$")) { + return error("姓名必须是2-20个汉字"); + } + + // 身份证校验 + String idCard = (String) requestData.get("idCard"); + if (idCard == null || idCard.trim().isEmpty()) { + return error("身份证号不能为空"); + } + idCard = idCard.trim().toUpperCase(); + if (!isValidIdCard(idCard)) { + return error("身份证号格式不正确"); + } + + // 检查身份证是否已被使用 + VetQualification query = new VetQualification(); + query.setIdCard(idCard); + List idCardUsers = vetQualificationService.selectVetQualificationList(query); + if (!idCardUsers.isEmpty()) { + for (VetQualification user : idCardUsers) { + if (!user.getUserId().equals(sysUserId)) { + return error("该身份证号已被其他用户使用"); + } + } + } + + // 证书列表校验 + Object certificatesObj = requestData.get("certificates"); + if (certificatesObj == null) { + return error("证书列表不能为空"); + } + + List certificatesList; + if (certificatesObj instanceof List) { + certificatesList = (List) certificatesObj; + } else { + return error("证书列表格式不正确"); + } + + if (certificatesList.isEmpty()) { + return error("请至少添加一个证书"); + } + ObjectMapper mapper = new ObjectMapper(); - Map requestData = mapper.convertValue(requestBody, Map.class); + for (int i = 0; i < certificatesList.size(); i++) { + Object certObj = certificatesList.get(i); + Map certMap; + + if (certObj instanceof Map) { + certMap = (Map) certObj; + } else { + certMap = mapper.convertValue(certObj, Map.class); + } + + String certName = (String) certMap.get("certName"); + if (certName == null || certName.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的名称不能为空"); + } + + String certificateNo = (String) certMap.get("certificateNo"); + if (certificateNo == null || certificateNo.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的编号不能为空"); + } - if (requestData.containsKey("realName") && requestData.containsKey("certificates")) { - return processNewFormat(requestData); + String issueOrg = (String) certMap.get("issueOrg"); + if (issueOrg == null || issueOrg.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的发证机关不能为空"); + } + + Object issueDateObj = certMap.get("issueDate"); + if (issueDateObj == null) { + return error("第" + (i + 1) + "个证书的发证日期不能为空"); + } + + Object expireDateObj = certMap.get("expireDate"); + if (expireDateObj == null) { + return error("第" + (i + 1) + "个证书的有效期不能为空"); + } + + // 日期逻辑校验 + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date issueDate; + Date expireDate; + + if (issueDateObj instanceof Date) { + issueDate = (Date) issueDateObj; + } else { + issueDate = sdf.parse(issueDateObj.toString()); + } + + if (expireDateObj instanceof Date) { + expireDate = (Date) expireDateObj; + } else { + expireDate = sdf.parse(expireDateObj.toString()); + } + + if (expireDate.before(issueDate)) { + return error("第" + (i + 1) + "个证书的有效期不能早于发证日期"); + } + } catch (Exception e) { + return error("第" + (i + 1) + "个证书的日期格式不正确,请使用yyyy-MM-dd格式"); + } + + // 证书编号唯一性检查 + if (StringUtils.isNotEmpty(certificateNo)) { + VetQualification certQuery = new VetQualification(); + certQuery.setCertificateNo(certificateNo); + List existingCerts = vetQualificationService.selectVetQualificationList(certQuery); + if (!existingCerts.isEmpty()) { + for (VetQualification existing : existingCerts) { + if (!existing.getUserId().equals(sysUserId)) { + return error("证书编号 '" + certificateNo + "' 已被其他用户使用"); + } + } + } + } + } + + // 经营范围校验 + Object scopeIdsObj = requestData.get("scopeIds"); + if (scopeIdsObj == null) { + return error("请选择经营范围"); + } + + if (scopeIdsObj instanceof List) { + @SuppressWarnings("unchecked") + List scopeIdsList = (List) scopeIdsObj; + if (scopeIdsList.isEmpty()) { + return error("请选择经营范围"); + } + } else if (scopeIdsObj instanceof String) { + String scopeIds = (String) scopeIdsObj; + if (StringUtils.isEmpty(scopeIds)) { + return error("请选择经营范围"); + } + } + + // 资质类型校验 + String qualificationType = (String) requestData.get("qualificationType"); + if (StringUtils.isEmpty(qualificationType)) { + return error("请选择资质类型"); + } + + // 校验通过,调用原有逻辑 + return processNewFormat(requestData); + + } else { + // 旧格式处理 + VetQualification vetQualification; + if (requestBody instanceof VetQualification) { + vetQualification = (VetQualification) requestBody; } else { - return processOldFormat(requestBody); + ObjectMapper mapper = new ObjectMapper(); + vetQualification = mapper.convertValue(requestBody, VetQualification.class); + } + + // 姓名校验 + String realName = vetQualification.getRealName(); + if (realName == null || realName.trim().isEmpty()) { + return error("真实姓名不能为空"); } + realName = realName.trim(); + if (!realName.matches("^[\\u4e00-\\u9fa5]{2,20}$")) { + return error("姓名必须是2-20个汉字"); + } + + // 身份证校验 + String idCard = vetQualification.getIdCard(); + if (idCard == null || idCard.trim().isEmpty()) { + return error("身份证号不能为空"); + } + idCard = idCard.trim().toUpperCase(); + if (!isValidIdCard(idCard)) { + return error("身份证号格式不正确"); + } + + // 检查身份证是否已被使用 + VetQualification query = new VetQualification(); + query.setIdCard(idCard); + List idCardUsers = vetQualificationService.selectVetQualificationList(query); + if (!idCardUsers.isEmpty()) { + for (VetQualification user : idCardUsers) { + if (!user.getUserId().equals(sysUserId)) { + return error("该身份证号已被其他用户使用"); + } + } + } + + // 证书列表校验 + List certificateList = vetQualification.getCertificateList(); + if (certificateList == null || certificateList.isEmpty()) { + return error("请至少添加一个证书"); + } + + for (int i = 0; i < certificateList.size(); i++) { + VetQualification.CertificateInfo cert = certificateList.get(i); + + String certName = cert.getCertName(); + if (certName == null || certName.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的名称不能为空"); + } + + String certificateNo = cert.getCertificateNo(); + if (certificateNo == null || certificateNo.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的编号不能为空"); + } + + String issueOrg = cert.getIssueOrg(); + if (issueOrg == null || issueOrg.trim().isEmpty()) { + return error("第" + (i + 1) + "个证书的发证机关不能为空"); + } + + if (cert.getIssueDate() == null) { + return error("第" + (i + 1) + "个证书的发证日期不能为空"); + } + + if (cert.getExpireDate() == null) { + return error("第" + (i + 1) + "个证书的有效期不能为空"); + } + + if (cert.getExpireDate().before(cert.getIssueDate())) { + return error("第" + (i + 1) + "个证书的有效期不能早于发证日期"); + } + + // 证书编号唯一性检查 + if (StringUtils.isNotEmpty(certificateNo)) { + VetQualification certQuery = new VetQualification(); + certQuery.setCertificateNo(certificateNo); + List existingCerts = vetQualificationService.selectVetQualificationList(certQuery); + if (!existingCerts.isEmpty()) { + for (VetQualification existing : existingCerts) { + if (!existing.getUserId().equals(sysUserId)) { + return error("证书编号 '" + certificateNo + "' 已被其他用户使用"); + } + } + } + } + } + + // 经营范围校验 + String scopeIds = vetQualification.getScopeIds(); + if (StringUtils.isEmpty(scopeIds)) { + return error("请选择经营范围"); + } + + // 资质类型校验 + String qualificationType = vetQualification.getQualificationType(); + if (StringUtils.isEmpty(qualificationType)) { + return error("请选择资质类型"); + } + + // 校验通过,调用原有逻辑 + return processOldFormat(requestBody); } + } catch (RuntimeException e) { + return error(e.getMessage()); } catch (Exception e) { + log.error("提交审核失败", e); return AjaxResult.error("提交失败:" + e.getMessage()); } } + /** + * 验证身份证号格式和合法性(18位) + * 符合国家标准GB 11643-1999 + */ + private boolean isValidIdCard(String idCard) { + if (StringUtils.isEmpty(idCard)) { + return false; + } + + // 清理输入 + idCard = idCard.trim().toUpperCase(); + + // 1. 基本格式校验(18位,最后一位可能是数字或X) + String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9X]$"; + if (!idCard.matches(regex)) { + return false; + } + + // 2. 校验码验证(必须) + return validateIdCardCheckCode(idCard); + } + + + + /** + * 验证身份证校验码 + * 根据ISO 7064:1983.MOD 11-2算法 + */ + private boolean validateIdCardCheckCode(String idCard) { + if (idCard == null || idCard.length() != 18) { + return false; + } + + // 校验因子(加权因子) + int[] factor = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + + // 校验码对应值 + char[] parityBit = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; + + int sum = 0; + try { + for (int i = 0; i < 17; i++) { + sum += Character.getNumericValue(idCard.charAt(i)) * factor[i]; + } + } catch (Exception e) { + return false; + } + + int mod = sum % 11; + char checkCode = parityBit[mod]; + + return checkCode == idCard.charAt(17); + } + + /** + * 验证出生日期合法性 + */ + private boolean validateBirthDate(String idCard) { + if (idCard == null || idCard.length() < 14) { + return false; + } + + try { + // 提取出生日期(第7-14位) + String birthDateStr = idCard.substring(6, 14); + int year = Integer.parseInt(birthDateStr.substring(0, 4)); + int month = Integer.parseInt(birthDateStr.substring(4, 6)); + int day = Integer.parseInt(birthDateStr.substring(6, 8)); + + // 年份范围校验(1900-当前年份) + int currentYear = Calendar.getInstance().get(Calendar.YEAR); + if (year < 1900 || year > currentYear) { + return false; + } + + // 月份范围校验 + if (month < 1 || month > 12) { + return false; + } + + // 日期范围校验 + if (day < 1 || day > 31) { + return false; + } + + // 月份天数校验 + Calendar cal = Calendar.getInstance(); + cal.setLenient(false); + cal.set(year, month - 1, day); + + try { + cal.getTime(); + return true; + } catch (Exception e) { + return false; + } + + } catch (NumberFormatException e) { + return false; + } + } + + /** + * 完整的身份证校验(包含所有验证) + */ + private String validateIdCardFull(String idCard, Long currentUserId) { + if (StringUtils.isEmpty(idCard)) { + return "身份证号不能为空"; + } + + idCard = idCard.trim().toUpperCase(); + + // 1. 长度校验 + if (idCard.length() != 18) { + return "身份证号必须为18位"; + } + + // 2. 格式校验 + if (!isValidIdCard(idCard)) { + return "身份证号格式不正确"; + } + + // 3. 出生日期校验 + if (!validateBirthDate(idCard)) { + return "身份证号中的出生日期不合法"; + } + + // 4. 年龄校验(必须年满18岁) + try { + String birthDateStr = idCard.substring(6, 14); + int year = Integer.parseInt(birthDateStr.substring(0, 4)); + int month = Integer.parseInt(birthDateStr.substring(4, 6)); + int day = Integer.parseInt(birthDateStr.substring(6, 8)); + + Calendar birthCal = Calendar.getInstance(); + birthCal.set(year, month - 1, day); + + Calendar today = Calendar.getInstance(); + + int age = today.get(Calendar.YEAR) - birthCal.get(Calendar.YEAR); + if (today.get(Calendar.MONTH) < birthCal.get(Calendar.MONTH)) { + age--; + } else if (today.get(Calendar.MONTH) == birthCal.get(Calendar.MONTH) + && today.get(Calendar.DAY_OF_MONTH) < birthCal.get(Calendar.DAY_OF_MONTH)) { + age--; + } + + if (age < 18) { + return "必须年满18周岁"; + } + + if (age > 100) { + return "年龄超过100岁,请核实身份证号"; + } + + } catch (Exception e) { + return "身份证号出生日期解析失败"; + } + + return null; // 校验通过 + } + + /** + * 从身份证提取性别(0:男, 1:女) + */ + private String getGenderFromIdCard(String idCard) { + if (!isValidIdCard(idCard)) { + return null; + } + // 第17位:奇数为男,偶数为女 + int genderNum = Character.getNumericValue(idCard.charAt(16)); + return genderNum % 2 == 1 ? "0" : "1"; + } + + /** + * 从身份证提取出生日期 + */ + private String getBirthdayFromIdCard(String idCard) { + if (!isValidIdCard(idCard)) { + return null; + } + String birthDateStr = idCard.substring(6, 14); + return birthDateStr.substring(0, 4) + "-" + + birthDateStr.substring(4, 6) + "-" + + birthDateStr.substring(6, 8); + } + + /** + * 从身份证提取年龄 + */ + private int getAgeFromIdCard(String idCard) { + if (!isValidIdCard(idCard)) { + return 0; + } + + try { + String birthDateStr = idCard.substring(6, 14); + int year = Integer.parseInt(birthDateStr.substring(0, 4)); + int month = Integer.parseInt(birthDateStr.substring(4, 6)); + int day = Integer.parseInt(birthDateStr.substring(6, 8)); + + Calendar birthCal = Calendar.getInstance(); + birthCal.set(year, month - 1, day); + + Calendar today = Calendar.getInstance(); + + int age = today.get(Calendar.YEAR) - birthCal.get(Calendar.YEAR); + if (today.get(Calendar.MONTH) < birthCal.get(Calendar.MONTH)) { + age--; + } else if (today.get(Calendar.MONTH) == birthCal.get(Calendar.MONTH) + && today.get(Calendar.DAY_OF_MONTH) < birthCal.get(Calendar.DAY_OF_MONTH)) { + age--; + } + + return age; + } catch (Exception e) { + return 0; + } + } + /** + * 验证手机号格式 + */ + private boolean isValidPhone(String phone) { + if (StringUtils.isEmpty(phone)) { + return false; + } + // 手机号正则(11位) + String regex = "^1[3-9]\\d{9}$"; + return phone.matches(regex); + } + + /** + * 验证邮箱格式 + */ + private boolean isValidEmail(String email) { + if (StringUtils.isEmpty(email)) { + return false; + } + String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; + return email.matches(regex); + } + private AjaxResult processNewFormat(Map requestData) { Long userId = SecurityUtils.getUserId(); int result = vetQualificationService.submitQualification(requestData); @@ -573,7 +1088,6 @@ public class VetQualificationController extends BaseController else return "未知"; } - /** * 修改单个证书信息并提交审核(根据证书ID修改单个证书) */ @@ -584,7 +1098,6 @@ public class VetQualificationController extends BaseController log.info("修改单个证书并提交审核请求数据: {}", requestData); // 1. 获取证书ID(要修改的证书) - // 1. 获取字符串格式的ID String certIdStr = null; Object certIdObj = requestData.get("certId"); if (certIdObj != null) { @@ -604,31 +1117,31 @@ public class VetQualificationController extends BaseController return AjaxResult.error("证书ID格式错误"); } - // 3. 继续原有逻辑(使用Long类型的certId) + // 3. 获取资质ID Long qualificationId = extractLongFromObject(requestData.get("qualificationId")); if (qualificationId == null) { return AjaxResult.error("资质ID不能为空"); } - // 3. 查询整个资质信息 + // 4. 查询整个资质信息 VetQualification existingQualification = vetQualificationService.selectVetQualificationByQualificationId(qualificationId); if (existingQualification == null) { return AjaxResult.error("资质信息不存在"); } - // 4. 权限检查 + // 5. 权限检查 Long currentUserId = SecurityUtils.getUserId(); if (!SecurityUtils.isAdmin(currentUserId) && !existingQualification.getUserId().equals(currentUserId)) { return AjaxResult.error("无权操作此证书"); } - // 5. 获取现有证书列表 + // 6. 获取现有证书列表 List certificateList = existingQualification.getCertificateList(); if (certificateList == null || certificateList.isEmpty()) { return AjaxResult.error("该资质没有证书信息"); } - // 6. 查找并更新指定证书 + // 7. 查找并更新指定证书 boolean certificateFound = false; for (VetQualification.CertificateInfo cert : certificateList) { if (cert.getCertificateId() != null && cert.getCertificateId().equals(certId)) { @@ -643,17 +1156,17 @@ public class VetQualificationController extends BaseController return AjaxResult.error("未找到要修改的证书"); } - // 7. 创建更新对象 + // 8. 创建更新对象 VetQualification updateQualification = new VetQualification(); updateQualification.setQualificationId(qualificationId); - // 8. 更新基础信息(如果有的话) + // 9. 更新基础信息(如果有的话) updateBasicInfo(requestData, updateQualification); - // 9. 更新证书列表到JSON + // 10. 更新证书列表到JSON updateCertificatesToJson(certificateList, updateQualification); - // 10. 更新主表字段(使用第一个证书的信息) + // 11. 更新主表字段(使用第一个证书的信息) if (!certificateList.isEmpty()) { VetQualification.CertificateInfo firstCert = certificateList.get(0); updateQualification.setCertName(firstCert.getCertName()); @@ -664,16 +1177,16 @@ public class VetQualificationController extends BaseController updateQualification.setExpireDate(firstCert.getExpireDate()); } - // 11. 设置审核状态为"待审核" + // 12. 设置审核状态为"待审核" updateQualification.setAuditStatus("0"); updateQualification.setAuditOpinion(null); updateQualification.setApplyTime(new Date()); - // 12. 设置更新人信息 + // 13. 设置更新人信息 updateQualification.setUpdateBy(SecurityUtils.getUsername()); updateQualification.setUpdateTime(new Date()); - // 13. 执行更新 + // 14. 执行更新 int result = vetQualificationService.updateVetQualification(updateQualification); if (result > 0) { diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java index 7e10b65..e1ba181 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java @@ -52,7 +52,7 @@ public class VetTrainingVideoController extends BaseController * 查询兽医培训视频列表 */ - @PreAuthorize("@ss.hasPermi('vet:training:list') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:list') or @ss.hasRole('muhu') or @ss.hasRole('vet')") @GetMapping("/list") public TableDataInfo list(VetTrainingVideo vetTrainingVideo) { @@ -64,7 +64,7 @@ public class VetTrainingVideoController extends BaseController /** * 导出兽医培训视频列表 */ - @PreAuthorize("@ss.hasPermi('vet:training:export') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:export') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "兽医培训视频", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, VetTrainingVideo vetTrainingVideo) @@ -77,7 +77,7 @@ public class VetTrainingVideoController extends BaseController /** * 获取兽医培训视频详细信息 */ - @PreAuthorize("@ss.hasPermi('vet:training:query') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:query') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") Long id) { @@ -87,7 +87,7 @@ public class VetTrainingVideoController extends BaseController /** * 新增兽医培训视频 */ - @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "兽医培训视频", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody VetTrainingVideo vetTrainingVideo) @@ -98,7 +98,7 @@ public class VetTrainingVideoController extends BaseController /** * 修改兽医培训视频 */ - @PreAuthorize("@ss.hasPermi('vet:training:edit') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:edit') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "兽医培训视频", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody VetTrainingVideo vetTrainingVideo) @@ -109,18 +109,18 @@ public class VetTrainingVideoController extends BaseController /** * 删除兽医培训视频 */ - @PreAuthorize("@ss.hasPermi('vet:training:remove') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:remove') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "兽医培训视频", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult remove(@PathVariable Long[] ids) { - return toAjax(vetTrainingVideoService.deleteVetTrainingVideoByIds(ids)); + return vetTrainingVideoService.deleteVetTrainingVideoByIds(ids); } /** * 上传培训视频 */ - @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @Log(title = "兽医培训视频", businessType = BusinessType.OTHER) @PostMapping("/uploadVideo") public AjaxResult uploadVideo(@RequestParam("file") MultipartFile file) @@ -206,7 +206,7 @@ public class VetTrainingVideoController extends BaseController /** * 批量提交审核 */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')") @PostMapping("/batch-submit-audit") public AjaxResult batchSubmitForAudit(@RequestBody List videoIds) { Long userId = getCurrentUserId(); @@ -217,7 +217,7 @@ public class VetTrainingVideoController extends BaseController /** * 批量审核(管理员接口) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:audit') or @ss.hasRole('muhu')or @ss.hasRole('manger')") @PostMapping("/batch-audit") public AjaxResult batchAuditVideo(@RequestBody Map batchAuditData) { @SuppressWarnings("unchecked") @@ -241,7 +241,7 @@ public class VetTrainingVideoController extends BaseController /** * 批量上架 */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @PostMapping("/batch-publish") public AjaxResult batchPublishVideo(@RequestBody List videoIds) { Long userId = getCurrentUserId(); @@ -252,7 +252,7 @@ public class VetTrainingVideoController extends BaseController /** * 批量下架 */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @PostMapping("/batch-offline") public AjaxResult batchOfflineVideo(@RequestBody List videoIds) { Long userId = getCurrentUserId(); @@ -263,7 +263,7 @@ public class VetTrainingVideoController extends BaseController /** * 审核单个视频(管理员接口) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:audit') or@ss.hasRole('muhu')") @PostMapping("/audit/{videoId}") public AjaxResult auditVideo(@PathVariable Long videoId, @RequestBody Map auditData) { @@ -289,7 +289,7 @@ public class VetTrainingVideoController extends BaseController /** * 上架单个视频(审核通过后才能上架) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @PostMapping("/publish/{videoId}") public AjaxResult publishVideo(@PathVariable Long videoId) { Long userId = getCurrentUserId(); @@ -304,7 +304,7 @@ public class VetTrainingVideoController extends BaseController /** * 下架单个视频 */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @PostMapping("/offline/{videoId}") public AjaxResult offlineVideo(@PathVariable Long videoId) { Long userId = getCurrentUserId(); @@ -319,7 +319,7 @@ public class VetTrainingVideoController extends BaseController /** * 提交审核(单个视频) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')") @PostMapping("/submit-audit/{videoId}") public AjaxResult submitForAudit(@PathVariable Long videoId) { Long userId = getCurrentUserId(); @@ -334,7 +334,7 @@ public class VetTrainingVideoController extends BaseController /** * 取消审核(单个视频) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasPermi('vet:training:cancelaudit') or @ss.hasRole('muhu')or @ss.hasRole('vet')") @PostMapping("/cancel-audit/{videoId}") public AjaxResult cancelAudit(@PathVariable Long videoId) { Long userId = getCurrentUserId(); @@ -363,7 +363,7 @@ public class VetTrainingVideoController extends BaseController * 查询公开视频列表(无需登录) * 已上架(status=1)且已审核通过(audit_status=1) */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @GetMapping("/public/list") public TableDataInfo publicList(VetTrainingVideo vetTrainingVideo) { @@ -377,7 +377,7 @@ public class VetTrainingVideoController extends BaseController * 获取公开视频详情(无需登录) * 只能查看已上架且审核通过的视频 */ - @PreAuthorize("@ss.hasRole('muhu')") + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") @GetMapping("/public/{id}") public AjaxResult getPublicInfo(@PathVariable("id") Long id) { @@ -388,7 +388,7 @@ public class VetTrainingVideoController extends BaseController } // 检查视频状态:必须已上架且审核通过 - if (!"1".equals(video.getStatus()) || !"1".equals(video.getAuditStatus())) { + if (!"1".equals(video.getStatus()) || !"2".equals(video.getAuditStatus())) { // 注意:审核通过是"2" return error("视频不可访问"); } @@ -401,5 +401,33 @@ public class VetTrainingVideoController extends BaseController return success(video); } + /** + * 重新提交审核(审核被拒绝后重新提交) + */ + @PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('vet')or @ss.hasRole('manger')") + @PostMapping("/resubmit-audit/{videoId}") + public AjaxResult resubmitForAudit(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + try { + // 查询视频信息 + VetTrainingVideo video = vetTrainingVideoService.selectVetTrainingVideoById(videoId); + if (video == null) { + return error("视频不存在"); + } + + // 检查权限:管理员或视频所有者 + boolean isAdmin = SecurityUtils.getLoginUser().getUser().isAdmin(); + if (!isAdmin && !userId.equals(video.getUserId())) { + return error("无权操作此视频"); + } + + boolean success = vetTrainingVideoService.resubmitForAudit(videoId, userId); + return success ? success("重新提交审核成功") : error("重新提交审核失败,请确保视频处于审核拒绝状态"); + } catch (Exception e) { + return error("重新提交审核失败: " + e.getMessage()); + } + } + + } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java b/chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java index b05d72f..6eb6db4 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java @@ -4,6 +4,8 @@ import com.chenhai.vet.domain.VetQualification; import com.chenhai.vet.domain.VetNotification; import com.chenhai.vet.mapper.VetQualificationMapper; import com.chenhai.vet.mapper.VetNotificationMapper; +import com.chenhai.vet.service.IVetQualificationService; +import com.chenhai.vet.service.VetNotificationService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -25,27 +27,45 @@ public class CertificateRemindTask { @Autowired private VetNotificationMapper vetNotificationMapper; + @Autowired + private IVetQualificationService vetQualificationService; + + @Autowired + private VetNotificationService vetNotificationService; + private final ObjectMapper objectMapper = new ObjectMapper(); + // 每天上午9点执行 - /*@Scheduled(cron = "0 0 9 * * ?")*/ - @Scheduled(cron = "0 */1 * * * ?") - public void dailyCertificateCheck() { + @Scheduled(cron = "0 0 9 * * ?") +// @Scheduled(cron = "0 */1 * * * ?") + public void checkExpiringCertificates() { + /* log.info("【证书过期检查】定时任务开始执行");*/ + try { - // 查询所有资质记录 - List qualifications = vetQualificationMapper.selectVetQualificationList(new VetQualification()); + // 1. 检查并发送提醒 + vetQualificationService.checkAndSendCertificateReminders(); - for (VetQualification qualification : qualifications) { - try { - // 检查该资质下的所有证书(包括JSON中的) - checkAllCertificates(qualification); - } catch (Exception e) { - // 静默处理单个资质检查失败 - } + // 2. 查询即将过期的证书并发送通知 + List expiringQualifications = + vetQualificationService.selectExpiringQualifications(null); + + /*log.info("【证书过期检查】找到 {} 个即将过期的资质证书", expiringQualifications.size());*/ + + for (VetQualification qualification : expiringQualifications) { + // 发送通知 + vetNotificationService.sendCertificateExpireRemind(qualification); + + /*log.info("已发送提醒:资质ID={}, 用户ID={}, 证书名称={}", + qualification.getQualificationId(), + qualification.getUserId(), + qualification.getCertName());*/ } + } catch (Exception e) { - // 静默处理整体任务失败 + /*log.error("【证书过期检查】执行失败:", e);*/ } + /*log.info("【证书过期检查】定时任务执行结束");*/ } /** diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java index e88765f..ae5b80f 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java @@ -50,6 +50,43 @@ public class MerchantInfo extends BaseEntity @Excel(name = "是否启用", readConverterExp = "1=启用,0禁用") private Integer isActive; + /** 审核状态(字典:audit_status) */ + @Excel(name = "审核状态", dictType = "audit_status") + private String auditStatus; + + /** 审核意见 */ + @Excel(name = "审核意见") + private String auditOpinion; + + /** 店铺logo */ + @Excel(name = "店铺logo") + private String shopLogo; + + /** 营业执照图片 */ + @Excel(name = "营业执照图片") + private String businessLicenseImage; + + /** 审核人ID */ + private Long auditUserId; + + /** 审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date auditTime; + + /** 店铺状态(字典:merchant_status) */ + @Excel(name = "店铺状态", dictType = "sys_publish_status") + private String shopStatus; + + /** 上架时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date publishTime; + + /** 下架时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date offlineTime; + + + public void setShopId(Long shopId) { this.shopId = shopId; @@ -130,6 +167,79 @@ public class MerchantInfo extends BaseEntity return isActive; } + 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; + } + + public String getShopStatus() { + return shopStatus; + } + + public void setShopStatus(String shopStatus) { + this.shopStatus = shopStatus; + } + + public Date getPublishTime() { + return publishTime; + } + + public void setPublishTime(Date publishTime) { + this.publishTime = publishTime; + } + + public Date getOfflineTime() { + return offlineTime; + } + + public void setOfflineTime(Date offlineTime) { + this.offlineTime = offlineTime; + } + public String getShopLogo() { + return shopLogo; + } + + public void setShopLogo(String shopLogo) { + this.shopLogo = shopLogo; + } + + public String getBusinessLicenseImage() { + return businessLicenseImage; + } + + public void setBusinessLicenseImage(String businessLicenseImage) { + this.businessLicenseImage = businessLicenseImage; + } + + + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -141,6 +251,15 @@ public class MerchantInfo extends BaseEntity .append("createdAt", getCreatedAt()) .append("updatedAt", getUpdatedAt()) .append("isActive", getIsActive()) + .append("auditStatus", getAuditStatus()) + .append("auditOpinion", getAuditOpinion()) + .append("auditUserId", getAuditUserId()) + .append("auditTime", getAuditTime()) + .append("shopStatus", getShopStatus()) + .append("publishTime", getPublishTime()) + .append("offlineTime", getOfflineTime()) + .append("shopLogo", getShopLogo()) + .append("businessLicenseImage", getBusinessLicenseImage()) .toString(); } } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetPersonalInfo.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetPersonalInfo.java index 0b6f76e..9d420bc 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetPersonalInfo.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetPersonalInfo.java @@ -107,6 +107,10 @@ public class VetPersonalInfo extends BaseEntity @Excel(name = "审核描述") private String auditDesc; + /** 头像路径 */ + @Excel(name = "头像路径") + private String avatar; + // 添加getter和setter public void setId(Long id) { @@ -318,6 +322,15 @@ public class VetPersonalInfo extends BaseEntity this.auditDesc = auditDesc; } + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -342,6 +355,7 @@ public class VetPersonalInfo extends BaseEntity .append("expertType", getExpertType()) .append("email", getEmail()) .append("nickName", getNickName()) + .append("avatar", getAvatar()) .append("user", getUser()) .toString(); } 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 f302c0f..4470d4d 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 @@ -147,6 +147,10 @@ public class VetProduct extends BaseEntity @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date auditTime; + /** 店铺ID */ + @Excel(name = "店铺ID") + private Long shopId; + public void setId(Long id) { this.id = id; @@ -459,6 +463,14 @@ public class VetProduct extends BaseEntity this.auditTime = auditTime; } + public Long getShopId() { + return shopId; + } + + public void setShopId(Long shopId) { + this.shopId = shopId; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -494,6 +506,7 @@ public class VetProduct extends BaseEntity .append("auditOpinion", getAuditOpinion()) .append("auditUserId", getAuditUserId()) .append("auditTime", getAuditTime()) + .append("shopId", getShopId()) .toString(); } } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/dto/BatchSubmitAuditDTO.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/dto/BatchSubmitAuditDTO.java new file mode 100644 index 0000000..74454bb --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/dto/BatchSubmitAuditDTO.java @@ -0,0 +1,39 @@ +// BatchSubmitAuditDTO.java +package com.chenhai.vet.domain.dto; + +public class BatchSubmitAuditDTO { + + /** 商家ID */ + private Long shopId; + + /** 产品ID列表 */ + private Long[] productIds; + + /** 提交人ID */ + private Long submitUserId; + + // getter和setter方法 + public Long getShopId() { + return shopId; + } + + public void setShopId(Long shopId) { + this.shopId = shopId; + } + + public Long[] getProductIds() { + return productIds; + } + + public void setProductIds(Long[] productIds) { + this.productIds = productIds; + } + + public Long getSubmitUserId() { + return submitUserId; + } + + public void setSubmitUserId(Long submitUserId) { + this.submitUserId = submitUserId; + } +} diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IMerchantInfoService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IMerchantInfoService.java index edca552..a2a5ca0 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IMerchantInfoService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IMerchantInfoService.java @@ -58,4 +58,59 @@ public interface IMerchantInfoService * @return 结果 */ public int deleteMerchantInfoByShopId(Long shopId); + + /** + * 提交商家审核 + * + * @param shopId 商家ID + * @return 结果 + */ + public int submitMerchantForAudit(Long shopId); + + /** + * 审核商家 + * + * @param shopId 商家ID + * @param auditStatus 审核状态 + * @param auditOpinion 审核意见 + * @param auditUserId 审核人ID + * @return 结果 + */ + public int auditMerchant(Long shopId, String auditStatus, String auditOpinion, Long auditUserId); + + /** + * 上架商家 + * + * @param shopId 商家ID + * @return 结果 + */ + public int publishMerchant(Long shopId); + + /** + * 下架商家 + * + * @param shopId 商家ID + * @return 结果 + */ + public int offlineMerchant(Long shopId); + + /** + * 取消商家审核 + * + * @param shopId 商家ID + * @return 结果 + */ + public int cancelMerchantAudit(Long shopId); + + // 在 IMerchantInfoService 接口中添加以下方法 + /** + * 重新提交商家审核(审核不通过后重新提交) + * + * @param shopId 商家ID + * @return 结果 + */ + int resubmitMerchantForAudit(Long shopId); + + } + diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java index 778a741..e5aa95e 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java @@ -51,7 +51,7 @@ public interface IVetKnowledgeService * @param ids 需要删除的兽医文章主键集合 * @return 结果 */ - public int deleteVetKnowledgeByIds(Long[] ids); + public AjaxResult deleteVetKnowledgeByIds(Long[] ids); /** * 删除兽医文章信息 @@ -59,8 +59,7 @@ public interface IVetKnowledgeService * @param id 兽医文章主键 * @return 结果 */ - public int deleteVetKnowledgeById(Long id); - + public AjaxResult deleteVetKnowledgeById(Long id); /** * 提交审核 * @param id 文章ID 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 06a99d7..e81639b 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 @@ -110,4 +110,22 @@ public interface IVetProductService */ public List selectAllVetProductList(VetProduct vetProduct); + /** + * 批量提交产品审核(按商家) + * + * @param shopId 商家ID + * @return 结果 + */ + public int batchSubmitProductsForAudit(Long shopId); + // 在 IVetProductService 接口中添加以下方法 + /** + * 重新提交审核(审核不通过后重新提交) + * + * @param id 产品ID + * @return 结果 + */ + int resubmitForAudit(Long id); + + + } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java index 88969bf..9b0a499 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java @@ -1,6 +1,8 @@ package com.chenhai.vet.service; import java.util.List; + +import com.chenhai.common.core.domain.AjaxResult; import com.chenhai.vet.domain.VetTrainingVideo; /** @@ -45,20 +47,19 @@ public interface IVetTrainingVideoService /** * 批量删除兽医培训视频 - * + * * @param ids 需要删除的兽医培训视频主键集合 * @return 结果 */ - public int deleteVetTrainingVideoByIds(Long[] ids); + public AjaxResult deleteVetTrainingVideoByIds(Long[] ids); /** * 删除兽医培训视频信息 - * + * * @param id 兽医培训视频主键 * @return 结果 */ - public int deleteVetTrainingVideoById(Long id); - + public AjaxResult deleteVetTrainingVideoById(Long id); // 批量操作 int batchSubmitForAudit(List videoIds, Long userId); int batchAuditVideo(List videoIds, String auditStatus, String auditOpinion, Long auditUserId); diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/MerchantInfoServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/MerchantInfoServiceImpl.java index 9e93fa1..b0aa0d9 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/MerchantInfoServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/MerchantInfoServiceImpl.java @@ -1,6 +1,7 @@ package com.chenhai.vet.service.impl; import java.util.List; +import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.chenhai.vet.mapper.MerchantInfoMapper; @@ -44,50 +45,204 @@ public class MerchantInfoServiceImpl implements IMerchantInfoService } /** - * 新增商家信息 + * 批量删除商家信息 * - * @param merchantInfo 商家信息 + * @param shopIds 需要删除的商家信息主键 * @return 结果 */ @Override - public int insertMerchantInfo(MerchantInfo merchantInfo) + public int deleteMerchantInfoByShopIds(Long[] shopIds) { - return merchantInfoMapper.insertMerchantInfo(merchantInfo); + return merchantInfoMapper.deleteMerchantInfoByShopIds(shopIds); } /** - * 修改商家信息 + * 删除商家信息信息 * - * @param merchantInfo 商家信息 + * @param shopId 商家信息主键 * @return 结果 */ @Override - public int updateMerchantInfo(MerchantInfo merchantInfo) + public int deleteMerchantInfoByShopId(Long shopId) { - return merchantInfoMapper.updateMerchantInfo(merchantInfo); + return merchantInfoMapper.deleteMerchantInfoByShopId(shopId); } /** - * 批量删除商家信息 - * - * @param shopIds 需要删除的商家信息主键 - * @return 结果 + * 提交商家审核 */ @Override - public int deleteMerchantInfoByShopIds(Long[] shopIds) - { - return merchantInfoMapper.deleteMerchantInfoByShopIds(shopIds); + public int submitMerchantForAudit(Long shopId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + // 检查是否已提交审核 + if (canSubmitForAudit(merchant)) { + merchant.setAuditStatus("1"); // 审核中 + merchant.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + return 0; } /** - * 删除商家信息信息 - * - * @param shopId 商家信息主键 - * @return 结果 + * 审核商家 */ @Override - public int deleteMerchantInfoByShopId(Long shopId) - { - return merchantInfoMapper.deleteMerchantInfoByShopId(shopId); + public int auditMerchant(Long shopId, String auditStatus, String auditOpinion, Long auditUserId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + merchant.setAuditStatus(auditStatus); + merchant.setAuditOpinion(auditOpinion); + merchant.setAuditUserId(auditUserId); + merchant.setAuditTime(new Date()); + merchant.setUpdatedAt(new Date()); + + // 如果审核通过,自动将店铺状态设为待上架 + if ("2".equals(auditStatus)) { // 审核通过 + if ("0".equals(merchant.getShopStatus())) { // 如果当前是未上架状态 + merchant.setShopStatus("0"); // 设为待上架状态 + } + } + + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + /** + * 上架商家 + */ + @Override + public int publishMerchant(Long shopId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + // 检查是否可以上架:需要审核通过且当前状态为待上架 + if ("2".equals(merchant.getAuditStatus()) && "1".equals(merchant.getShopStatus())) { + merchant.setShopStatus("1"); // 已上架 + merchant.setPublishTime(new Date()); + merchant.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + return 0; + } + + /** + * 下架商家 + */ + @Override + public int offlineMerchant(Long shopId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + // 只有已上架的商家才能下架 + if ("2".equals(merchant.getShopStatus())) { // 已上架状态 + merchant.setShopStatus("0"); // 已下架 + merchant.setOfflineTime(new Date()); + merchant.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + return 0; + } + + /** + * 取消商家审核 + */ + @Override + public int cancelMerchantAudit(Long shopId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + // 只有审核中的状态才能取消 + if ("1".equals(merchant.getAuditStatus())) { // 审核中 + merchant.setAuditStatus("0"); // 设为未审核 + merchant.setAuditOpinion(null); + merchant.setAuditUserId(null); + merchant.setAuditTime(null); + merchant.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + return 0; + } + + /** + * 检查商家是否可以提交审核 + */ + private boolean canSubmitForAudit(MerchantInfo merchant) { + // 只有未审核状态才能提交 + return "0".equals(merchant.getAuditStatus()) || + (merchant.getAuditStatus() == null); } + + + + @Override + public int insertMerchantInfo(MerchantInfo merchantInfo) { + // 设置默认值 + if (merchantInfo.getAuditStatus() == null) { + merchantInfo.setAuditStatus("0"); // 未审核 + } + if (merchantInfo.getShopStatus() == null) { + merchantInfo.setShopStatus("0"); // 未上架 + } + if (merchantInfo.getCreatedAt() == null) { + merchantInfo.setCreatedAt(new Date()); + } + if (merchantInfo.getUpdatedAt() == null) { + merchantInfo.setUpdatedAt(new Date()); + } + return merchantInfoMapper.insertMerchantInfo(merchantInfo); + } + + @Override + public int updateMerchantInfo(MerchantInfo merchantInfo) { + merchantInfo.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchantInfo); + } + + /** + * 重新提交商家审核(审核不通过后重新提交) + */ + @Override + public int resubmitMerchantForAudit(Long shopId) { + MerchantInfo merchant = merchantInfoMapper.selectMerchantInfoByShopId(shopId); + if (merchant == null) { + return 0; + } + + // 检查是否可以重新提交审核:只有审核不通过状态才能重新提交 + if (canResubmitForAudit(merchant)) { + merchant.setAuditStatus("1"); // 审核中 + merchant.setAuditOpinion(null); // 清空之前的审核意见 + merchant.setAuditUserId(null); // 清空审核人 + merchant.setAuditTime(null); // 清空审核时间 + merchant.setUpdatedAt(new Date()); + return merchantInfoMapper.updateMerchantInfo(merchant); + } + + return 0; + } + + /** + * 检查商家是否可以重新提交审核 + */ + private boolean canResubmitForAudit(MerchantInfo merchant) { + // 只有审核不通过状态才能重新提交 + return "3".equals(merchant.getAuditStatus()); + } + } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCommentsServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCommentsServiceImpl.java index 41ddb89..4c42a00 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCommentsServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCommentsServiceImpl.java @@ -18,6 +18,8 @@ import com.chenhai.vet.service.IVetCommentsService; import org.springframework.transaction.annotation.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; /** * 兽医回复Service业务层处理 @@ -39,6 +41,8 @@ public class VetCommentsServiceImpl implements IVetCommentsService @Autowired private IVetPersonalInfoService vetPersonalInfoService; + // 创建Jackson ObjectMapper实例 + private final ObjectMapper objectMapper = new ObjectMapper(); /** * 查询兽医回复 @@ -50,6 +54,12 @@ public class VetCommentsServiceImpl implements IVetCommentsService public VetComments selectVetCommentsById(Long id) { VetComments comment = vetCommentsMapper.selectVetCommentsById(id); + + // 处理images字段:如果是JSON字符串,解析为普通字符串 + if (comment != null && StringUtils.isNotEmpty(comment.getImages())) { + comment.setImages(parseImagesFromJsonString(comment.getImages())); + } + // 如果查询时字段为空,尝试填充兽医信息 if (comment != null && (StringUtils.isEmpty(comment.getTitle()) || StringUtils.isEmpty(comment.getHospital()) || @@ -71,7 +81,13 @@ public class VetCommentsServiceImpl implements IVetCommentsService List list = vetCommentsMapper.selectVetCommentsList(vetComments); // 为每个记录填充兽医信息 if (list != null) { - list.forEach(this::fillVetInfoToComment); + list.forEach(comment -> { + // 处理images字段 + if (StringUtils.isNotEmpty(comment.getImages())) { + comment.setImages(parseImagesFromJsonString(comment.getImages())); + } + fillVetInfoToComment(comment); + }); } return list; } @@ -86,6 +102,9 @@ public class VetCommentsServiceImpl implements IVetCommentsService @Transactional public int insertVetComments(VetComments vetComments) { + log.info("开始插入兽医回复,consultationId: {}", vetComments.getConsultationId()); + log.info("原始images值: {}", vetComments.getImages()); + // 获取当前登录用户信息 LoginUser loginUser = SecurityUtils.getLoginUser(); SysUser currentUser = null; @@ -108,7 +127,6 @@ public class VetCommentsServiceImpl implements IVetCommentsService // 自动填充兽医职称、医院和经验信息到数据库字段中 vetComments = autoFillVetInfoToFields(vetComments, loginUser.getUserId()); - } // 设置默认值 @@ -116,6 +134,11 @@ public class VetCommentsServiceImpl implements IVetCommentsService vetComments.setIsSensitive(0); } + // ========== 核心修复:确保images是有效的JSON字符串 ========== + String processedImages = ensureValidJsonStringForImages(vetComments.getImages()); + log.info("处理后的images值: {}", processedImages); + vetComments.setImages(processedImages); + int result = vetCommentsMapper.insertVetComments(vetComments); // 更新问诊单的回复数量和状态 @@ -126,8 +149,7 @@ public class VetCommentsServiceImpl implements IVetCommentsService consultation.setStatus("已回复"); consultationFormsService.updateMuhuConsultationForms(consultation); - // 如果是首次回复,可以记录回复兽医信息(如果有相应字段) - // 注意:这里需要根据实际问诊单结构来调整 + // 记录回复兽医信息到问诊单 recordVetInfoToConsultation(consultation, vetComments); } } catch (Exception e) { @@ -137,6 +159,201 @@ public class VetCommentsServiceImpl implements IVetCommentsService return result; } + /** + * 确保images字段是有效的JSON字符串(存储为逗号分隔的字符串) + */ + private String ensureValidJsonStringForImages(String input) { + // 1. 如果为空,返回空字符串的JSON + if (StringUtils.isEmpty(input)) { + return "\"\""; // 空字符串的JSON表示 + } + + String trimmed = input.trim(); + log.debug("原始images输入: {}", trimmed); + + // 2. 如果已经是有效的JSON字符串,直接返回 + if (isValidJson(trimmed) && trimmed.startsWith("\"") && trimmed.endsWith("\"")) { + log.debug("已是有效JSON字符串,直接返回"); + return trimmed; + } + + // 3. 处理各种格式的输入 + try { + // 3.1 如果是逗号分隔的字符串,直接转为JSON字符串 + if (trimmed.contains(",")) { + return convertToJsonString(trimmed); + } + + // 3.2 如果是JSON数组,提取内容转为字符串 + if (trimmed.startsWith("[")) { + return extractFromJsonArray(trimmed); + } + + // 3.3 单个图片路径,直接包装为JSON字符串 + return wrapAsJsonString(trimmed); + } catch (Exception e) { + log.error("处理images字段失败,使用空字符串: {}", trimmed, e); + return "\"\""; + } + } + + /** + * 将普通字符串转为JSON字符串 + */ + private String convertToJsonString(String plainText) { + String cleaned = cleanImageText(plainText); + String escaped = escapeForJson(cleaned); + String result = "\"" + escaped + "\""; + log.debug("普通文本转JSON字符串结果: {}", result); + return result; + } + + /** + * 从JSON数组中提取内容转为字符串 + */ + private String extractFromJsonArray(String jsonArray) { + try { + // 解析JSON数组 + JsonNode arrayNode = objectMapper.readTree(jsonArray); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < arrayNode.size(); i++) { + String path = arrayNode.get(i).asText(); + sb.append(cleanImagePath(path)); + if (i < arrayNode.size() - 1) { + sb.append(","); + } + } + + String result = "\"" + escapeForJson(sb.toString()) + "\""; + log.debug("JSON数组转字符串结果: {}", result); + return result; + } catch (Exception e) { + log.warn("解析JSON数组失败,直接处理原始字符串: {}", jsonArray, e); + return convertToJsonString(jsonArray); + } + } + + /** + * 包装单个路径为JSON字符串 + */ + private String wrapAsJsonString(String imagePath) { + String cleanedPath = cleanImagePath(imagePath); + String escapedPath = escapeForJson(cleanedPath); + String result = "\"" + escapedPath + "\""; + log.debug("单个图片转JSON字符串结果: {}", result); + return result; + } + + /** + * 解析数据库中的JSON字符串为普通字符串 + */ + private String parseImagesFromJsonString(String jsonString) { + if (StringUtils.isEmpty(jsonString)) { + return ""; + } + + String trimmed = jsonString.trim(); + + // 如果是JSON字符串(以双引号开头结尾),提取内容 + if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) { + try { + // 解析JSON字符串 + String parsed = objectMapper.readValue(trimmed, String.class); + return parsed; + } catch (Exception e) { + log.warn("解析images JSON字符串失败: {}", trimmed, e); + // 尝试直接提取内容 + return trimmed.substring(1, trimmed.length() - 1); + } + } + + // 如果不是JSON字符串,直接返回 + return trimmed; + } + + /** + * 清理图片文本(处理带冒号的情况) + */ + private String cleanImageText(String text) { + if (StringUtils.isEmpty(text)) { + return ""; + } + + String cleaned = text.trim(); + + // 移除开头的冒号和空格 + if (cleaned.startsWith(":")) { + cleaned = cleaned.substring(1).trim(); + } + + // 移除多余的引号 + if (cleaned.startsWith("\"") && cleaned.endsWith("\"")) { + cleaned = cleaned.substring(1, cleaned.length() - 1); + } + if (cleaned.startsWith("'") && cleaned.endsWith("'")) { + cleaned = cleaned.substring(1, cleaned.length() - 1); + } + + // 如果是数组形式,移除方括号 + if (cleaned.startsWith("[") && cleaned.endsWith("]")) { + cleaned = cleaned.substring(1, cleaned.length() - 1); + } + + return cleaned; + } + + /** + * 清理图片路径 + */ + private String cleanImagePath(String path) { + if (StringUtils.isEmpty(path)) { + return ""; + } + + String cleaned = path.trim(); + + // 移除多余的引号 + if (cleaned.startsWith("\"") && cleaned.endsWith("\"")) { + cleaned = cleaned.substring(1, cleaned.length() - 1); + } + if (cleaned.startsWith("'") && cleaned.endsWith("'")) { + cleaned = cleaned.substring(1, cleaned.length() - 1); + } + + return cleaned; + } + + /** + * JSON转义 + */ + private String escapeForJson(String str) { + if (str == null) { + return ""; + } + return str.replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t"); + } + + /** + * 检查字符串是否为有效的JSON + */ + private boolean isValidJson(String jsonStr) { + if (StringUtils.isEmpty(jsonStr)) { + return false; + } + try { + objectMapper.readTree(jsonStr); + return true; + } catch (Exception e) { + log.debug("JSON验证失败: {}, 错误: {}", jsonStr, e.getMessage()); + return false; + } + } + /** * 记录兽医信息到问诊单(可选) */ @@ -198,8 +415,6 @@ public class VetCommentsServiceImpl implements IVetCommentsService log.info("已自动填充兽医信息到字段:职称={}, 医院={}, 经验={}", vetInfo.getTitle(), vetInfo.getHospital(), vetInfo.getWorkExperience()); - // 可选:同时在内容中追加兽医信息 - vetComments = appendVetInfoToContent(vetComments, vetInfo); } else { log.warn("用户ID:{} 未找到兽医个人信息", userId); @@ -212,53 +427,6 @@ public class VetCommentsServiceImpl implements IVetCommentsService return vetComments; } - /** - * 可选方法:将兽医信息追加到回复内容末尾(如果需要) - */ - private VetComments appendVetInfoToContent(VetComments vetComments, VetPersonalInfo vetInfo) { - // 是否需要在内容中显示兽医信息的配置 - boolean showVetInfoInContent = true; // 可以从配置读取 - - if (showVetInfoInContent) { - StringBuilder vetSignature = new StringBuilder(); - - // 构建兽医信息签名 - if (StringUtils.isNotEmpty(vetInfo.getTitle())) { - vetSignature.append(vetInfo.getTitle()); - } - - if (StringUtils.isNotEmpty(vetInfo.getHospital())) { - if (vetSignature.length() > 0) { - vetSignature.append(" · "); - } - vetSignature.append(vetInfo.getHospital()); - } - - if (StringUtils.isNotEmpty(vetInfo.getWorkExperience())) { - if (vetSignature.length() > 0) { - vetSignature.append(" · "); - } - vetSignature.append("执业经验:").append(vetInfo.getWorkExperience()); - } - - // 如果有兽医信息,则添加到回复内容中 - if (vetSignature.length() > 0) { - String originalContent = vetComments.getContent(); - String vetInfoStr = "\n\n---\n" + vetSignature.toString(); - - // 检查是否已经包含兽医信息,避免重复添加 - if (originalContent != null && !originalContent.contains("---\n")) { - vetComments.setContent(originalContent + vetInfoStr); - log.info("已在回复内容中追加兽医信息:{}", vetSignature.toString()); - } else if (originalContent == null) { - vetComments.setContent(vetInfoStr.substring(2)); // 去掉开头的换行符 - } - } - } - - return vetComments; - } - /** * 为已有的评论记录填充兽医信息 * 用于查询时,如果发现字段为空,从兽医表补充信息 @@ -382,6 +550,9 @@ public class VetCommentsServiceImpl implements IVetCommentsService @Override public int updateVetComments(VetComments vetComments) { + log.info("开始修改兽医回复,ID: {}", vetComments.getId()); + log.info("修改前原始images值: {}", vetComments.getImages()); + boolean isAdmin = SecurityUtils.hasRole("admin") || SecurityUtils.hasPermi("*:*:*"); if (SecurityUtils.hasRole("vetnotshenhe") && !isAdmin) { @@ -395,9 +566,100 @@ public class VetCommentsServiceImpl implements IVetCommentsService } } + // ========== 关键修改:直接处理images字段 ========== + if (vetComments.getImages() != null) { + String images = vetComments.getImages().trim(); + log.info("修改接口收到的images值: {}", images); + + // 如果前端传的是JSON数组格式 + if (images.startsWith("[") && images.endsWith("]")) { + try { + // 解析JSON数组 + JsonNode arrayNode = objectMapper.readTree(images); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < arrayNode.size(); i++) { + String path = arrayNode.get(i).asText(); + sb.append(path); + if (i < arrayNode.size() - 1) { + sb.append(","); + } + } + + // 包装为JSON字符串 + String result = "\"" + sb.toString() + "\""; + vetComments.setImages(result); + log.info("修改后images值: {}", result); + } catch (Exception e) { + log.error("解析images JSON数组失败,使用空字符串", e); + vetComments.setImages("\"\""); + } + } + // 如果已经是JSON字符串格式,直接使用 + else if (images.startsWith("\"") && images.endsWith("\"")) { + log.info("images已是JSON字符串格式,直接使用"); + } + // 如果是普通字符串,包装为JSON字符串 + else { + String result = "\"" + escapeForJson(images) + "\""; + vetComments.setImages(result); + log.info("普通字符串包装为JSON字符串: {}", result); + } + } + + // 如果用户信息变更,更新相关字段 + updateUserInfoIfChanged(vetComments); + return vetCommentsMapper.updateVetComments(vetComments); } + + /** + * 如果用户信息变更,更新相关字段 + */ + private void updateUserInfoIfChanged(VetComments vetComments) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + return; + } + + Long currentUserId = loginUser.getUserId(); + SysUser currentUser = loginUser.getUser(); + + try { + VetComments originalComment = vetCommentsMapper.selectVetCommentsById(vetComments.getId()); + if (originalComment != null) { + // 检查用户是否变更(理论上不应该变,但做保护) + if (!currentUserId.equals(originalComment.getUserId())) { + log.warn("用户尝试修改他人回复,用户ID: {}, 原用户ID: {}", + currentUserId, originalComment.getUserId()); + throw new RuntimeException("只能修改自己的回复"); + } + + // 更新头像和回复名称(如果相关字段被修改) + if (StringUtils.isNotEmpty(currentUser.getNickName()) && + (vetComments.getReplyName() == null || vetComments.getReplyName().isEmpty())) { + vetComments.setReplyName(currentUser.getNickName()); + } + + if (StringUtils.isNotEmpty(currentUser.getAvatar()) && + (vetComments.getAvatar() == null || vetComments.getAvatar().isEmpty())) { + vetComments.setAvatar(currentUser.getAvatar()); + } + + // 自动填充兽医信息(如果字段为空) + if (StringUtils.isEmpty(vetComments.getTitle()) || + StringUtils.isEmpty(vetComments.getHospital()) || + StringUtils.isEmpty(vetComments.getExperience())) { + autoFillVetInfoToFields(vetComments, currentUserId); + } + } + } catch (Exception e) { + log.error("更新用户信息时发生错误", e); + // 不中断主流程 + } + } + /** * 批量删除兽医回复 * @@ -447,4 +709,27 @@ public class VetCommentsServiceImpl implements IVetCommentsService return vetCommentsMapper.deleteVetCommentsById(id); } + + /** + * 测试方法:验证图片格式转换 + */ + public void testImagesConversion() { + String[] testCases = { + "", + "/profile/upload/2026/02/10/image1.png", + "/path1.png,/path2.png", + "[\"/path1.png\",\"/path2.png\"]", + ": \"/path1.png,/path2.png", + "'/path1.png','/path2.png'", + "/005 10/01a/2026/02/05/tnp 00820:0097160397100254-0590i -60879231 da451 20260205181217028.3p,/pr061/0108/2026/02/10/3.20260210105754030.p2" + }; + + for (String testCase : testCases) { + String result = ensureValidJsonStringForImages(testCase); + log.info("测试输入: {}", testCase); + log.info("数据库存储: {}", result); + log.info("查询解析: {}", parseImagesFromJsonString(result)); + log.info("---"); + } + } } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java index 481d170..d1110c9 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java @@ -74,20 +74,108 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService * 批量删除兽医文章 */ @Override - public int deleteVetKnowledgeByIds(Long[] ids) + @Transactional(rollbackFor = Exception.class) + public AjaxResult deleteVetKnowledgeByIds(Long[] ids) { - return vetKnowledgeMapper.deleteVetKnowledgeByIds(ids); + try { + Long currentUserId = SecurityUtils.getUserId(); + if (currentUserId == null) { + return AjaxResult.error("用户未登录"); + } + + int successCount = 0; + int failedCount = 0; + List failedMessages = new ArrayList<>(); + + for (Long id : ids) { + try { + // 查询文章信息 + VetKnowledge article = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (article == null) { + failedCount++; + failedMessages.add("文章ID " + id + " 不存在"); + continue; + } + + // 检查是否是自己的文章(通过创建者判断) + String createBy = article.getCreateBy(); + String currentUsername = SecurityUtils.getUsername(); + + if (createBy == null || !createBy.equals(currentUsername)) { + // 如果不是自己的文章,检查是否是管理员 + if (!SecurityUtils.isAdmin(currentUserId)) { // 修改这里 + failedCount++; + failedMessages.add("文章ID " + id + " 不是您发布的文章,无法删除"); + continue; + } + } + + // 执行删除 + int result = vetKnowledgeMapper.deleteVetKnowledgeById(id); + if (result > 0) { + successCount++; + } else { + failedCount++; + failedMessages.add("文章ID " + id + " 删除失败"); + } + } catch (Exception e) { + failedCount++; + failedMessages.add("文章ID " + id + " 删除异常: " + e.getMessage()); + } + } + + if (failedCount == 0) { + return AjaxResult.success("成功删除 " + successCount + " 篇文章"); + } else { + return AjaxResult.warn("成功删除 " + successCount + " 篇,失败 " + failedCount + " 篇", failedMessages); + } + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("批量删除失败: " + e.getMessage()); + } } /** * 删除兽医文章信息 */ @Override - public int deleteVetKnowledgeById(Long id) + @Transactional(rollbackFor = Exception.class) + public AjaxResult deleteVetKnowledgeById(Long id) { - return vetKnowledgeMapper.deleteVetKnowledgeById(id); - } + try { + Long currentUserId = SecurityUtils.getUserId(); + if (currentUserId == null) { + return AjaxResult.error("用户未登录"); + } + // 查询文章信息 + VetKnowledge article = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (article == null) { + return AjaxResult.error("文章不存在"); + } + + // 检查是否是自己的文章(通过创建者判断) + String createBy = article.getCreateBy(); + String currentUsername = SecurityUtils.getUsername(); + + if (createBy == null || !createBy.equals(currentUsername)) { + // 如果不是自己的文章,检查是否是管理员 + if (!SecurityUtils.isAdmin(currentUserId)) { // 修改这里 + return AjaxResult.error("不是您发布的文章,无法删除"); + } + } + + int result = vetKnowledgeMapper.deleteVetKnowledgeById(id); + if (result > 0) { + return AjaxResult.success("文章删除成功"); + } else { + return AjaxResult.error("文章删除失败"); + } + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("删除失败: " + e.getMessage()); + } + } /** * 提交审核:将审核状态改为审核中 */ @@ -230,8 +318,6 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService if (current == null) { return AjaxResult.error("文章不存在"); } - - // 只有已下架状态(2)的文章才能上架 if (!"2".equals(current.getArticleStatus())) { return AjaxResult.error("只有已下架的文章可以上架"); @@ -287,7 +373,8 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService VetKnowledge vetKnowledge = new VetKnowledge(); vetKnowledge.setId(id); - vetKnowledge.setArticleStatus("2"); // 已下架 + vetKnowledge.setAuditStatus("0"); + vetKnowledge.setArticleStatus("0"); // 草稿 vetKnowledge.setAuditComment(auditComment.trim()); // 存储下架原因到审核意见字段 String username = SecurityUtils.getUsername(); diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java index 224a5a3..e5bb352 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java @@ -4,6 +4,7 @@ import com.chenhai.common.core.domain.entity.SysUser; import com.chenhai.common.core.domain.model.LoginUser; import com.chenhai.common.utils.DateUtils; import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.common.utils.StringUtils; import com.chenhai.vet.domain.VetPersonalInfo; import com.chenhai.vet.domain.VetQualification; import com.chenhai.vet.mapper.VetPersonalInfoMapper; @@ -105,11 +106,12 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { return list; } - - /** * 新增兽医个人信息 */ + /** + * 新增兽医个人信息(Service层校验) + */ @Override @Transactional public int insertVetPersonalInfo(VetPersonalInfo vetPersonalInfo) { @@ -120,48 +122,64 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { // 1. 强制绑定当前登录用户ID vetPersonalInfo.setUserId(loginUser.getUserId()); - // 2. 设置创建者和更新者 + // 2. 检查是否已存在该用户的兽医信息 + VetPersonalInfo existing = vetPersonalInfoMapper.selectVetPersonalInfoByUserId(vetPersonalInfo.getUserId()); + if (existing != null) { + throw new RuntimeException("该用户已存在兽医信息,请使用更新操作"); + } + + // 3. 身份证唯一性检查 + if (StringUtils.isNotEmpty(vetPersonalInfo.getIdCard())) { + VetPersonalInfo query = new VetPersonalInfo(); + query.setIdCard(vetPersonalInfo.getIdCard()); + List list = vetPersonalInfoMapper.selectVetPersonalInfoList(query); + if (!list.isEmpty()) { + for (VetPersonalInfo info : list) { + if (!info.getUserId().equals(vetPersonalInfo.getUserId())) { + throw new RuntimeException("该身份证号已被其他用户使用"); + } + } + } + } + + // 4. 设置创建者和更新者 vetPersonalInfo.setCreateBy(loginUser.getUsername()); vetPersonalInfo.setUpdateBy(loginUser.getUsername()); - // 3. 从用户表获取其他信息 + // 5. 从用户表获取其他信息 SysUser currentUser = sysUserService.selectUserById(loginUser.getUserId()); if (currentUser != null) { + // 如果头像为空,使用用户头像 + if (StringUtils.isEmpty(vetPersonalInfo.getAvatar()) + && StringUtils.isNotEmpty(currentUser.getAvatar())) { + vetPersonalInfo.setAvatar(currentUser.getAvatar()); + } // 如果昵称为空,使用用户昵称 - if ((vetPersonalInfo.getNickName() == null || vetPersonalInfo.getNickName().isEmpty()) - && currentUser.getNickName() != null) { + if (StringUtils.isEmpty(vetPersonalInfo.getNickName()) + && StringUtils.isNotEmpty(currentUser.getNickName())) { vetPersonalInfo.setNickName(currentUser.getNickName()); } - // 如果性别为空,使用用户性别 - if ((vetPersonalInfo.getGender() == null || vetPersonalInfo.getGender().isEmpty()) - && currentUser.getSex() != null) { + if (StringUtils.isEmpty(vetPersonalInfo.getGender()) + && StringUtils.isNotEmpty(currentUser.getSex())) { vetPersonalInfo.setGender(currentUser.getSex()); } - // 如果邮箱为空,使用用户邮箱 - if ((vetPersonalInfo.getEmail() == null || vetPersonalInfo.getEmail().isEmpty()) - && currentUser.getEmail() != null) { + if (StringUtils.isEmpty(vetPersonalInfo.getEmail()) + && StringUtils.isNotEmpty(currentUser.getEmail())) { vetPersonalInfo.setEmail(currentUser.getEmail()); } - // 如果电话为空,使用用户手机号 - if ((vetPersonalInfo.getPhone() == null || vetPersonalInfo.getPhone().isEmpty()) - && currentUser.getPhonenumber() != null) { + if (StringUtils.isEmpty(vetPersonalInfo.getPhone()) + && StringUtils.isNotEmpty(currentUser.getPhonenumber())) { vetPersonalInfo.setPhone(currentUser.getPhonenumber()); } } - // 4. 设置创建时间和更新时间 + // 6. 设置创建时间和更新时间 vetPersonalInfo.setCreateTime(DateUtils.getNowDate()); vetPersonalInfo.setUpdateTime(DateUtils.getNowDate()); - // 5. 检查是否已存在该用户的兽医信息 - VetPersonalInfo existing = vetPersonalInfoMapper.selectVetPersonalInfoByUserId(vetPersonalInfo.getUserId()); - if (existing != null) { - throw new RuntimeException("该用户已存在兽医信息,请使用更新操作"); - } - return vetPersonalInfoMapper.insertVetPersonalInfo(vetPersonalInfo); } else { throw new RuntimeException("用户未登录"); @@ -169,7 +187,7 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { } /** - * 修改兽医个人信息 + * 修改兽医个人信息(双向同步) */ @Override @Transactional @@ -183,21 +201,59 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { throw new RuntimeException("无权限修改其他用户的兽医信息"); } - // 2. 强制绑定当前登录用户ID + // 2. 检查头像是否变化 + String newAvatar = vetPersonalInfo.getAvatar(); + String oldAvatar = existing != null ? existing.getAvatar() : null; + boolean avatarChanged = newAvatar != null && !newAvatar.equals(oldAvatar); + + // 3. 强制绑定当前登录用户ID vetPersonalInfo.setUserId(loginUser.getUserId()); - // 3. 设置更新者 + // 4. 设置更新者 vetPersonalInfo.setUpdateBy(loginUser.getUsername()); - // 4. 设置更新时间 + // 5. 设置更新时间 vetPersonalInfo.setUpdateTime(DateUtils.getNowDate()); - return vetPersonalInfoMapper.updateVetPersonalInfo(vetPersonalInfo); + // 6. 更新兽医信息 + int result = vetPersonalInfoMapper.updateVetPersonalInfo(vetPersonalInfo); + + // 7. 如果头像有变化,同步到用户表 + if (result > 0 && avatarChanged && newAvatar != null && !newAvatar.isEmpty()) { + syncAvatarToUserTable(loginUser.getUserId(), newAvatar); + } + + return result; } else { throw new RuntimeException("用户未登录"); } } + /** + * 同步头像到用户表 + */ + private void syncAvatarToUserTable(Long userId, String avatar) { + try { + SysUser user = sysUserService.selectUserById(userId); + if (user != null) { + // 检查是否需要更新 + if (!avatar.equals(user.getAvatar())) { + // 调用正确的方法签名 + boolean success = sysUserService.updateUserAvatar(userId, avatar); + + if (success) { + System.out.println("头像同步到用户表成功,用户ID: " + userId); + } else { + System.err.println("头像同步到用户表失败,用户ID: " + userId); + } + } + } + } catch (Exception e) { + System.err.println("双向同步头像失败: " + e.getMessage()); + } + } + + @Override public int auditVetPersonalInfo(VetPersonalInfo vetPersonalInfo) { return vetPersonalInfoMapper.auditVetPersonalInfo(vetPersonalInfo); @@ -399,6 +455,12 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { vetInfo.setNickName(user.getNickName()); needUpdate = true; } + // 同步头像 - 新增 + if ((vetInfo.getAvatar() == null || vetInfo.getAvatar().isEmpty()) + && user.getAvatar() != null && !user.getAvatar().isEmpty()) { + vetInfo.setAvatar(user.getAvatar()); + needUpdate = true; + } // 如果邮箱为空,使用用户邮箱 if ((vetInfo.getEmail() == null || vetInfo.getEmail().isEmpty()) && user.getEmail() != null) { @@ -445,6 +507,10 @@ public class VetPersonalInfoServiceImpl implements IVetPersonalInfoService { if (vetInfo.getPhone() != null) { updateInfo.setPhone(vetInfo.getPhone()); } + // 同步头像 + if (vetInfo.getAvatar() != null) { + updateInfo.setAvatar(vetInfo.getAvatar()); + } // 设置更新时间 updateInfo.setUpdateTime(DateUtils.getNowDate()); 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 a43ced1..31407b8 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,11 +1,20 @@ package com.chenhai.vet.service.impl; +import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.List; +import com.chenhai.common.core.domain.model.LoginUser; import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.vet.domain.MerchantInfo; import com.chenhai.vet.domain.VetTrainingVideo; +import com.chenhai.vet.domain.dto.BatchSubmitAuditDTO; +import com.chenhai.vet.mapper.MerchantInfoMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import com.chenhai.vet.mapper.VetProductMapper; import com.chenhai.vet.domain.VetProduct; @@ -19,10 +28,12 @@ import org.springframework.transaction.annotation.Transactional; * @date 2026-01-15 */ @Service -public class VetProductServiceImpl implements IVetProductService +public class VetProductServiceImpl implements IVetProductService { @Autowired private VetProductMapper vetProductMapper; + @Autowired + private MerchantInfoMapper merchantInfoMapper; /** * 查询兽医产品信息 @@ -45,25 +56,151 @@ public class VetProductServiceImpl implements IVetProductService @Override public List selectVetProductList(VetProduct vetProduct) { - // 获取当前登录用户ID try { - Long userId = SecurityUtils.getUserId(); - // 设置查询条件,只查询当前用户的产品 - vetProduct.setUserId(userId); + // 1. 获取当前用户ID + Long currentUserId = SecurityUtils.getUserId(); + + // 2. 判断是否为管理员(传入用户ID作为参数) + boolean isAdmin = SecurityUtils.isAdmin(currentUserId); + + System.out.println("用户ID: " + currentUserId + ", 是否是管理员: " + isAdmin); + + // 3. 如果不是管理员,只查看自己店铺的产品 + if (!isAdmin) { + // 查询用户的店铺 + MerchantInfo merchantQuery = new MerchantInfo(); + merchantQuery.setUserId(currentUserId); + List merchantList = merchantInfoMapper.selectMerchantInfoList(merchantQuery); + + if (merchantList != null && !merchantList.isEmpty()) { + // 获取店铺ID + Long shopId = merchantList.get(0).getShopId(); + System.out.println("用户店铺ID: " + shopId); + + // 只查询该店铺的产品 + vetProduct.setShopId(shopId); + } else { + // 用户没有店铺,设置一个不存在的ID,确保查不到数据 + System.out.println("用户没有关联的店铺"); + vetProduct.setShopId(-1L); + } + } + // 如果是管理员,不设置shopId,可以查看所有产品 + + // 4. 执行查询 + List result = vetProductMapper.selectVetProductList(vetProduct); + System.out.println("查询到产品数量: " + (result != null ? result.size() : 0)); + + return result; + } catch (Exception e) { - // 如果获取不到用户ID,设置一个不存在的ID,确保查询不到数据 - vetProduct.setUserId(-1L); + System.out.println("查询异常: " + e.getMessage()); + e.printStackTrace(); + // 出错时返回空列表 + return new ArrayList<>(); } - return vetProductMapper.selectVetProductList(vetProduct); } +/* *//** + * 判断用户是否为管理员 + *//* + private boolean isUserAdmin(Long userId) { + try { + return SecurityUtils.isAdmin(); + } catch (Exception e) { + try { + return SecurityUtils.isAdmin(userId); + } catch (Exception e2) { + return false; + } + } + }*/ + + /* *//** + * 获取用户的所有店铺ID + *//* + private List getUserShopIds(Long userId) { + List shopIds = new ArrayList<>(); + try { + MerchantInfo merchantQuery = new MerchantInfo(); + merchantQuery.setUserId(userId); + List merchantList = merchantInfoMapper.selectMerchantInfoList(merchantQuery); + + if (merchantList != null) { + for (MerchantInfo merchant : merchantList) { + shopIds.add(merchant.getShopId()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return shopIds; + } + + *//** + * 根据店铺ID列表查询产品 + *//* + private List selectProductsByShopIds(VetProduct vetProduct, List shopIds) { + // 创建一个新的查询对象,避免修改原参数 + VetProduct query = new VetProduct(); + + // 复制查询条件 + if (vetProduct != null) { + query.setName(vetProduct.getName()); + query.setType(vetProduct.getType()); + query.setCategory(vetProduct.getCategory()); + query.setStatus(vetProduct.getStatus()); + query.setAuditStatus(vetProduct.getAuditStatus()); + // ... 复制其他查询条件 + } + + // 如果只有一个店铺ID,直接设置 + if (shopIds.size() == 1) { + query.setShopId(shopIds.get(0)); + return vetProductMapper.selectVetProductList(query); + } else { + // 多个店铺ID,需要特殊处理 + // 方法1:修改Mapper支持IN查询 + // 方法2:循环查询合并结果 + return selectProductsByShopIdsMulti(vetProduct, shopIds); + } + }*/ + + /** + * 多店铺ID查询产品(循环查询方式) + */ + private List selectProductsByShopIdsMulti(VetProduct vetProduct, List shopIds) { + List allProducts = new ArrayList<>(); + + for (Long shopId : shopIds) { + VetProduct query = new VetProduct(); + if (vetProduct != null) { + query.setName(vetProduct.getName()); + query.setType(vetProduct.getType()); + query.setCategory(vetProduct.getCategory()); + query.setStatus(vetProduct.getStatus()); + query.setAuditStatus(vetProduct.getAuditStatus()); + // ... 复制其他条件 + } + query.setShopId(shopId); + + List shopProducts = vetProductMapper.selectVetProductList(query); + if (shopProducts != null) { + allProducts.addAll(shopProducts); + } + } + + return allProducts; + } + + /** * 新增兽医产品信息 * * @param vetProduct 兽医产品信息 * @return 结果 */ - /* @Override + /* @Override public int insertVetProduct(VetProduct vetProduct) { return vetProductMapper.insertVetProduct(vetProduct); @@ -241,19 +378,34 @@ public class VetProductServiceImpl implements IVetProductService @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); + // 如果已经传入了shopId,就不需要查询 + if (vetProduct.getShopId() == null) { + // 设置默认值 + vetProduct.setStatus("0"); + vetProduct.setAuditStatus("0"); + vetProduct.setIsDeleted(0); + vetProduct.setCreatedAt(new Date()); + vetProduct.setUpdatedAt(new Date()); + + // 设置当前用户ID并查询店铺ID + try { + Long userId = SecurityUtils.getUserId(); + vetProduct.setUserId(userId); + + // 查询用户的店铺 + MerchantInfo merchantQuery = new MerchantInfo(); + merchantQuery.setUserId(userId); // 这里直接调用setter方法 + List merchantList = merchantInfoMapper.selectMerchantInfoList(merchantQuery); + + if (merchantList != null && !merchantList.isEmpty()) { + vetProduct.setShopId(merchantList.get(0).getShopId()); + } else { + throw new RuntimeException("用户未关联任何店铺,无法创建产品"); + } + + } catch (Exception e) { + throw new RuntimeException("获取用户店铺信息失败:" + e.getMessage()); + } } return vetProductMapper.insertVetProduct(vetProduct); @@ -272,4 +424,87 @@ public class VetProductServiceImpl implements IVetProductService } return vetProductMapper.selectVetProductList(vetProduct); } + + + /** + * 批量提交产品审核(按商家) + */ + @Override + public int batchSubmitProductsForAudit(Long shopId) { + int successCount = 0; + + // 创建查询条件 + VetProduct example = new VetProduct(); + example.setShopId(shopId); + + // 只查询未删除、未在审核中的产品 + example.setIsDeleted(0); + example.setAuditStatus("0"); // 未审核状态 + + List products = vetProductMapper.selectVetProductList(example); + + for (VetProduct product : products) { + // 检查是否可以提交审核 + if (canSubmitForAudit(product)) { + // 提交审核 + product.setAuditStatus("1"); // 审核中 + product.setUpdatedAt(new Date()); + vetProductMapper.updateVetProduct(product); + successCount++; + } + } + + return successCount; + } + + /** + * 检查产品是否可以提交审核 + */ + private boolean canSubmitForAudit(VetProduct product) { + // 检查状态:已删除、已在审核中或已审核完成的不允许提交 + if (product.getIsDeleted() != null && product.getIsDeleted() == 1) { + return false; + } + + // 审核状态:0-未审核,1-审核中,2-审核通过,3-审核不通过 + String auditStatus = product.getAuditStatus(); + if (auditStatus == null) { + auditStatus = "0"; + } + + // 只有未审核状态才能提交 + return "0".equals(auditStatus); + } + + /** + * 重新提交审核(审核不通过后重新提交) + */ + @Override + @Transactional + public int resubmitForAudit(Long id) { + VetProduct product = vetProductMapper.selectVetProductById(id); + if (product == null) { + throw new RuntimeException("产品不存在"); + } + + // 只有审核不通过状态可以重新提交 + if (!"3".equals(product.getAuditStatus())) { + throw new RuntimeException("只有审核不通过状态的产品可以重新提交"); + } + + // 检查产品状态,必须是草稿状态 + if (!"0".equals(product.getStatus())) { + throw new RuntimeException("产品状态不正确,只有草稿状态的产品可以重新提交审核"); + } + + // 重置审核信息 + product.setAuditStatus("1"); // 设置为审核中状态 + product.setAuditOpinion(null); // 清空审核意见 + product.setAuditUserId(null); // 清空审核人 + product.setAuditTime(null); // 清空审核时间 + product.setUpdatedAt(new Date()); + + return vetProductMapper.updateVetProduct(product); + } } + 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 0911286..6da6408 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 @@ -275,50 +275,50 @@ public class VetQualificationServiceImpl implements IVetQualificationService { @Override public Map selectCertificateWithQualificationByCertId(Long certId, Long userId) { try { - log.debug("开始查询证书,certId={}, userId={}", certId, userId); + // 1. 查询用户有权限查看的所有资质 + List qualifications; - VetQualification query = new VetQualification(); - if (userId != null) { + if (userId == null) { + // userId为null时表示管理员查询,但这里应该传入实际用户ID + throw new ServiceException("用户ID不能为空"); + } else { + // 普通用户只查询自己的资质 + VetQualification query = new VetQualification(); query.setUserId(userId); + qualifications = vetQualificationMapper.selectVetQualificationList(query); } - 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); + // 权限验证:确保证书属于当前用户 + if (!qualification.getUserId().equals(userId)) { + throw new ServiceException("无权查看此证书"); + } + return buildCertificateResult(qualification, certMap, foundCertId); } } } catch (Exception e) { - log.error("解析资质证书JSON失败,qualificationId: {}", qualification.getQualificationId(), e); + // 解析JSON失败,继续下一个资质 } } - log.warn("未找到证书,certId={}, userId={}", certId, userId); return null; } catch (Exception e) { - log.error("查询证书信息失败:certId={}, userId={}", certId, userId, e); + if (e instanceof ServiceException) { + throw e; + } throw new ServiceException("查询证书信息失败:" + e.getMessage()); } } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java index 3ad392e..fc92457 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java @@ -1,7 +1,9 @@ package com.chenhai.vet.service.impl; +import java.util.ArrayList; import java.util.List; +import com.chenhai.common.core.domain.AjaxResult; import com.chenhai.common.utils.SecurityUtils; import org.slf4j.Logger; @@ -69,7 +71,7 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService } vetTrainingVideo.setUserId(userId); // 确保设置用户ID - vetTrainingVideo.setStatus("0"); // 私有 + vetTrainingVideo.setStatus("0"); // 草稿(原私有) vetTrainingVideo.setAuditStatus("0"); // 待审核 vetTrainingVideo.setDelFlag("0"); // 正常 @@ -123,9 +125,62 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService * @return 结果 */ @Override - public int deleteVetTrainingVideoByIds(Long[] ids) + @Transactional(rollbackFor = Exception.class) + public AjaxResult deleteVetTrainingVideoByIds(Long[] ids) { - return vetTrainingVideoMapper.deleteVetTrainingVideoByIds(ids); + try { + Long currentUserId = SecurityUtils.getUserId(); + if (currentUserId == null) { + return AjaxResult.error("用户未登录"); + } + + int successCount = 0; + int failedCount = 0; + List failedMessages = new ArrayList<>(); + + for (Long id : ids) { + try { + // 查询视频信息 + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(id); + if (video == null) { + failedCount++; + failedMessages.add("视频ID " + id + " 不存在"); + continue; + } + + // 检查是否是自己的视频(通过userId字段判断) + if (!currentUserId.equals(video.getUserId())) { + // 如果不是自己的视频,检查是否是管理员 + if (!SecurityUtils.isAdmin(currentUserId)) { // 修改这里 + failedCount++; + failedMessages.add("视频ID " + id + " 不是您发布的视频,无法删除"); + continue; + } + } + + // 执行删除 + int result = vetTrainingVideoMapper.deleteVetTrainingVideoById(id); + if (result > 0) { + successCount++; + } else { + failedCount++; + failedMessages.add("视频ID " + id + " 删除失败"); + } + } catch (Exception e) { + failedCount++; + failedMessages.add("视频ID " + id + " 删除异常: " + e.getMessage()); + } + } + + if (failedCount == 0) { + return AjaxResult.success("成功删除 " + successCount + " 个视频"); + } else { + return AjaxResult.warn("成功删除 " + successCount + " 个,失败 " + failedCount + " 个", failedMessages); + } + } catch (Exception e) { + logger.error("批量删除视频失败", e); + return AjaxResult.error("批量删除失败: " + e.getMessage()); + } } /** @@ -135,9 +190,39 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService * @return 结果 */ @Override - public int deleteVetTrainingVideoById(Long id) + @Transactional(rollbackFor = Exception.class) + public AjaxResult deleteVetTrainingVideoById(Long id) { - return vetTrainingVideoMapper.deleteVetTrainingVideoById(id); + try { + Long currentUserId = SecurityUtils.getUserId(); + if (currentUserId == null) { + return AjaxResult.error("用户未登录"); + } + + // 查询视频信息 + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(id); + if (video == null) { + return AjaxResult.error("视频不存在"); + } + + // 检查是否是自己的视频(通过userId字段判断) + if (!currentUserId.equals(video.getUserId())) { + // 如果不是自己的视频,检查是否是管理员 + if (!SecurityUtils.isAdmin(currentUserId)) { // 修改这里 + return AjaxResult.error("不是您发布的视频,无法删除"); + } + } + + int result = vetTrainingVideoMapper.deleteVetTrainingVideoById(id); + if (result > 0) { + return AjaxResult.success("视频删除成功"); + } else { + return AjaxResult.error("视频删除失败"); + } + } catch (Exception e) { + logger.error("删除视频失败,ID: {}", id, e); + return AjaxResult.error("删除失败: " + e.getMessage()); + } } @Override @@ -160,15 +245,19 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService continue; } - // 状态验证:只有审核拒绝或无需审核状态才能重新提交审核 - String auditStatus = video.getAuditStatus(); - if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { - logger.warn("视频 {} 当前状态 {} 不能提交审核", videoId, auditStatus); + // 状态验证:只有草稿状态(0)且待审核状态(0)的视频才能提交审核 + if (!"0".equals(video.getStatus())) { + logger.warn("视频 {} 不是草稿状态,不能提交审核", videoId); + continue; + } + // 修改为:允许待审核(0)和审核拒绝(3)状态重新提交 + if (!"0".equals(video.getAuditStatus()) && !"3".equals(video.getAuditStatus())) { + logger.warn("视频 {} 当前状态 {} 不能提交审核", videoId, video.getAuditStatus()); continue; } - // 更新为待审核状态 - video.setAuditStatus("0"); // 待审核 + // 更新为审核中状态 + video.setAuditStatus("1"); // 审核中 video.setUpdateTime(DateUtils.getNowDate()); int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); @@ -190,8 +279,13 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService public int batchAuditVideo(List videoIds, String auditStatus, String auditOpinion, Long auditUserId) { int successCount = 0; + // 验证审核状态值(2-通过,3-拒绝) + if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { + throw new RuntimeException("无效的审核状态值"); + } + // 如果是拒绝审核,必须填写意见 - if ("2".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { + if ("3".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { throw new RuntimeException("审核拒绝时必须填写审核意见"); } @@ -204,14 +298,13 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService continue; } - // 状态验证:只有待审核状态才能审核 - if (!"0".equals(video.getAuditStatus())) { + if (!"1".equals(video.getAuditStatus())) { logger.warn("视频 {} 当前状态 {} 不能审核", videoId, video.getAuditStatus()); continue; } // 更新审核信息 - video.setAuditStatus(auditStatus); + video.setAuditStatus(auditStatus); // 2-通过,3-拒绝 video.setAuditOpinion(auditOpinion); video.setAuditUserId(auditUserId); video.setAuditTime(DateUtils.getNowDate()); @@ -251,19 +344,19 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService continue; } - // 状态验证:只有审核通过且未上架的视频才能上架 + // 状态验证:只有审核通过(2)且为草稿状态(0)的视频才能发布 if (!"2".equals(video.getAuditStatus())) { logger.warn("视频 {} 未通过审核,当前审核状态: {}", videoId, video.getAuditStatus()); continue; } - - if ("1".equals(video.getStatus())) { - logger.warn("视频 {} 已上架", videoId); + if (!"0".equals(video.getStatus())) { + logger.warn("视频 {} 当前状态不能发布", videoId); continue; } - // 更新为上架状态 - video.setStatus("1"); // 已上架 + // 更新为已发布状态 + video.setStatus("1"); // 已发布 + video.setPublishTime(DateUtils.getNowDate()); video.setUpdateTime(DateUtils.getNowDate()); int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); @@ -272,7 +365,7 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService } } catch (Exception e) { - logger.error("批量上架失败,视频ID: {}", videoId, e); + logger.error("批量发布失败,视频ID: {}", videoId, e); // 继续处理下一个,不中断批量操作 } } @@ -300,13 +393,13 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService continue; } - // 状态验证:只有已上架的视频才能下架 + // 状态验证:只有已发布状态(1)的视频才能下架 if (!"1".equals(video.getStatus())) { - logger.warn("视频 {} 未上架,当前状态: {}", videoId, video.getStatus()); + logger.warn("视频 {} 未发布,当前状态: {}", videoId, video.getStatus()); continue; } - // 更新为下架状态 + // 更新为已下架状态 video.setStatus("0"); // 已下架 video.setUpdateTime(DateUtils.getNowDate()); @@ -326,133 +419,170 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService @Override public boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId) { - VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (video == null) { - throw new RuntimeException("视频不存在"); - } + if (video == null) { + return false; + } - // 只有待审核状态才能审核 - if (!"0".equals(video.getAuditStatus())) { - throw new RuntimeException("当前状态不能审核"); - } + // 只有审核中状态(1)才能审核 + if (!"1".equals(video.getAuditStatus())) { + return false; + } - // 审核拒绝时必须填写审核意见 - if ("2".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { - throw new RuntimeException("审核拒绝时必须填写审核意见"); - } + // 审核状态验证:只能是2(通过)或3(拒绝) + if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { + return false; + } - // 更新审核信息 - video.setAuditStatus(auditStatus); - video.setAuditOpinion(auditOpinion); - video.setAuditUserId(auditUserId); - video.setAuditTime(DateUtils.getNowDate()); - video.setUpdateTime(DateUtils.getNowDate()); + // 审核拒绝时必须填写审核意见 + if ("3".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { + return false; + } - return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + // 更新审核信息 + video.setAuditStatus(auditStatus); + video.setAuditOpinion(auditOpinion); + video.setAuditUserId(auditUserId); + video.setAuditTime(DateUtils.getNowDate()); + video.setUpdateTime(DateUtils.getNowDate()); + + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + } catch (Exception e) { + logger.error("审核视频失败,视频ID: {}", videoId, e); + return false; + } } + /** + * 发布单个视频 + */ @Override public boolean publishVideo(Long videoId, Long userId) { - VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (video == null) { - throw new RuntimeException("视频不存在"); - } - -// // 验证权限:只能操作自己的视频 -// if (!userId.equals(video.getUserId())) { -// throw new RuntimeException("无权操作此视频"); -// } + if (video == null) { + return false; + } - // 状态验证:只有审核通过且未上架的视频才能上架 - if (!"1".equals(video.getAuditStatus())) { - throw new RuntimeException("只有审核通过的视频才能上架"); - } + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + return false; + } - if ("1".equals(video.getStatus())) { - throw new RuntimeException("视频已上架"); - } + // 状态验证:只有审核通过(2)且为草稿状态(0)的视频才能发布 + if (!"2".equals(video.getAuditStatus())) { + return false; + } + if (!"0".equals(video.getStatus())) { + return false; + } - // 更新为上架状态 - video.setStatus("1"); // 已上架 - video.setUpdateTime(DateUtils.getNowDate()); + // 更新为已发布状态 + video.setStatus("1"); // 已发布 + video.setPublishTime(DateUtils.getNowDate()); + video.setUpdateTime(DateUtils.getNowDate()); - return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + } catch (Exception e) { + logger.error("发布视频失败,视频ID: {}", videoId, e); + return false; + } } @Override public boolean offlineVideo(Long videoId, Long userId) { - VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (video == null) { - throw new RuntimeException("视频不存在"); - } + if (video == null) { + return false; + } - // 验证权限:只能操作自己的视频 - if (!userId.equals(video.getUserId())) { - throw new RuntimeException("无权操作此视频"); - } + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + return false; + } - // 状态验证:只有已上架的视频才能下架 - if (!"1".equals(video.getStatus())) { - throw new RuntimeException("只有已上架的视频才能下架"); - } + // 状态验证:只有已发布状态(1)的视频才能下架 + if (!"1".equals(video.getStatus())) { + return false; + } - // 更新为下架状态 - video.setStatus("0"); // 已下架 - video.setUpdateTime(DateUtils.getNowDate()); + // 更新为已下架状态 + video.setStatus("0");// 已下架 + video.setUpdateTime(DateUtils.getNowDate()); - return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + } catch (Exception e) { + logger.error("下架视频失败,视频ID: {}", videoId, e); + return false; + } } + /** + * 提交审核(单个视频) + */ @Override public boolean submitForAudit(Long videoId, Long userId) { - VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (video == null) { - throw new RuntimeException("视频不存在"); - } + if (video == null) { + return false; + } - // ============ 注意:这里移除了权限检查 ============ - // 原来的权限检查代码删除了: - // if (!userId.equals(video.getUserId())) { - // throw new RuntimeException("无权操作此视频"); - // } - // ================================================= + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + return false; + } - // 状态验证:只有审核拒绝或无需审核状态才能提交审核 - String auditStatus = video.getAuditStatus(); - if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { - throw new RuntimeException("当前状态不能提交审核"); - } + // 只有草稿状态(0)且待审核状态(0)的视频才能提交审核 + if (!"0".equals(video.getStatus())) { + return false; + } + if (!"0".equals(video.getAuditStatus()) && !"3".equals(video.getAuditStatus())) { + return false; + } - // 更新为待审核状态 - video.setAuditStatus("0"); // 待审核 - video.setUpdateTime(DateUtils.getNowDate()); + // 更新为审核中状态 + video.setAuditStatus("1"); // 审核中 + video.setUpdateTime(DateUtils.getNowDate()); - return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); + return result > 0; + } catch (Exception e) { + logger.error("提交审核失败,视频ID: {}", videoId, e); + return false; + } } @Override @Transactional(rollbackFor = Exception.class) public boolean cancelAudit(Long videoId, Long userId) { - VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (video == null) { - throw new RuntimeException("视频不存在"); - } + if (video == null) { + return false; + } - // 状态验证:只有待审核状态才能取消审核 - if (!"0".equals(video.getAuditStatus())) { - throw new RuntimeException("只有待审核状态才能取消审核"); - } + // 状态验证:只有待审核状态才能取消审核 + if (!"0".equals(video.getAuditStatus()) && !"1".equals(video.getAuditStatus())) { + return false; + } - // 更新为无需审核状态 - video.setAuditStatus("3"); // 无需审核 - video.setUpdateTime(DateUtils.getNowDate()); + // 更新为无需审核状态 + video.setAuditStatus("0"); // 无需审核 + video.setUpdateTime(DateUtils.getNowDate()); - return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; + } catch (Exception e) { + logger.error("取消审核失败,视频ID: {}", videoId, e); + return false; + } } /** @@ -478,7 +608,7 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService public List selectPublicVideoList(VetTrainingVideo vetTrainingVideo) { // 设置强制条件:已上架且审核通过 vetTrainingVideo.setStatus("1"); // 已上架 - vetTrainingVideo.setAuditStatus("1"); // 审核通过 + vetTrainingVideo.setAuditStatus("2"); // 审核通过(注意:这里是2) vetTrainingVideo.setDelFlag("0"); // 未删除 return vetTrainingVideoMapper.selectPublicVideoList(vetTrainingVideo); @@ -491,9 +621,9 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService public List selectPublicVideoPageList(VetTrainingVideo vetTrainingVideo) { // 设置强制条件:已上架且审核通过 vetTrainingVideo.setStatus("1"); // 已上架 - vetTrainingVideo.setAuditStatus("1"); // 审核通过 + vetTrainingVideo.setAuditStatus("2"); // 审核通过(注意:这里是2) vetTrainingVideo.setDelFlag("0"); // 未删除 return vetTrainingVideoMapper.selectVetTrainingVideoList(vetTrainingVideo); } -} +} \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml b/chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml index 97d05de..37c1432 100644 --- a/chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml +++ b/chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml @@ -125,7 +125,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select u.user_id, u.dept_id, u.nick_name, u.user_type, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date,u.area_code, u.create_by, u.create_time, u.remark, a.id as sys_area_id, a.name as sys_area_name, a.code as sys_area_code from sys_user u + select u.user_id, u.dept_id, u.nick_name, u.user_type, u.user_name, u.email, u.avatar, + u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.area_code, + u.create_by, u.create_time, u.remark, + a.id as sys_area_id, a.name as sys_area_name, a.code as sys_area_code, + a.parent_code, a.type, a.sort, a.status, a.name_path, a.code_path, a.deleted + from sys_user u left join sys_area a on u.area_code = a.code where u.del_flag = '0' @@ -126,16 +133,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND u.phonenumber like concat('%', #{phonenumber}, '%') - + AND date_format(u.create_time,'%Y%m%d') >= date_format(#{params.beginTime},'%Y%m%d') - + AND date_format(u.create_time,'%Y%m%d') <= date_format(#{params.endTime},'%Y%m%d') AND (u.area_code = #{areaCode} OR u.area_code IN ( SELECT a.code FROM sys_area a WHERE find_in_set(#{areaCode}, code_path) )) - ${params.dataScope} diff --git a/chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml b/chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml index caf3b42..d61a979 100644 --- a/chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml @@ -13,10 +13,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + - select shop_id, shop_name, shop_address, phone, user_id, created_at, updated_at, is_active from merchant_info + select shop_id, shop_name, shop_address, phone, user_id, created_at, updated_at, is_active ,shop_logo, business_license_image, audit_status, audit_opinion, audit_user_id, audit_time, shop_status, publish_time, offline_time from merchant_info @@ -47,6 +59,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" created_at, updated_at, is_active, + shop_logo, + business_license_image, + audit_status, + audit_opinion, + audit_user_id, + audit_time, + shop_status, + publish_time, + offline_time, #{shopName}, @@ -56,6 +77,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{createdAt}, #{updatedAt}, #{isActive}, + #{shopLogo}, + #{businessLicenseImage}, + #{auditStatus}, + #{auditOpinion}, + #{auditUserId}, + #{auditTime}, + #{shopStatus}, + #{publishTime}, + #{offlineTime}, @@ -69,6 +99,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" created_at = #{createdAt}, updated_at = #{updatedAt}, is_active = #{isActive}, + shop_logo = #{shopLogo}, + business_license_image = #{businessLicenseImage}, + audit_status = #{auditStatus}, + audit_opinion = #{auditOpinion}, + audit_user_id = #{auditUserId}, + audit_time = #{auditTime}, + shop_status = #{shopStatus}, + publish_time = #{publishTime}, + offline_time = #{offlineTime}, where shop_id = #{shopId} diff --git a/chenhai-system/src/main/resources/mapper/vet/VetPersonalInfoMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetPersonalInfoMapper.xml index db373c2..f0fd59c 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetPersonalInfoMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetPersonalInfoMapper.xml @@ -23,6 +23,7 @@ + @@ -37,6 +38,7 @@ + @@ -57,11 +59,13 @@ v.audit_status, v.audit_time, v.auditor, v.audit_desc, u.user_id as u_user_id, u.nick_name as u_nick_name, + u.avatar as u_avatar, u.email as u_email from vet_personal_info v left join sys_user u on v.user_id = u.user_id + @@ -74,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and created_at = #{createdAt} and updated_at = #{updatedAt} and audit_status = #{auditStatus} + and shop_id = #{shopId} @@ -116,6 +118,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" audit_opinion, audit_user_id, audit_time, + shop_id, #{name}, @@ -149,6 +152,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{auditOpinion}, #{auditUserId}, #{auditTime}, + #{shopId}, @@ -186,6 +190,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" audit_opinion = #{auditOpinion}, audit_user_id = #{auditUserId}, audit_time = #{auditTime}, + shop_id = #{shopId}, where id = #{id} diff --git a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml index 5558422..66cffba 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml @@ -203,7 +203,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and v.status = '1' - and v.audit_status = '1' + and v.audit_status = '2' and v.del_flag = '0' diff --git a/chenhai-ui/src/views/vet/info/index.vue b/chenhai-ui/src/views/vet/info/index.vue index 1852fce..35a9528 100644 --- a/chenhai-ui/src/views/vet/info/index.vue +++ b/chenhai-ui/src/views/vet/info/index.vue @@ -278,6 +278,7 @@