Browse Source

权限分配、兽医登录

master
maotiantian 2 months ago
parent
commit
c5b7decd65
  1. 1
      chenhai-admin/src/main/java/com/chenhai/web/controller/auth/MultiAuthController.java
  2. 15
      chenhai-admin/src/main/java/com/chenhai/web/controller/muhu/CarouselAdsController.java
  3. 20
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java
  4. 73
      chenhai-framework/src/main/java/com/chenhai/framework/web/service/SysLoginService.java
  5. 15
      chenhai-system/src/main/java/com/chenhai/muhu/domain/CarouselAds.java
  6. 11
      chenhai-system/src/main/java/com/chenhai/muhu/domain/DisasterWarning.java
  7. 13
      chenhai-system/src/main/java/com/chenhai/muhu/domain/MuhuConsultationForms.java
  8. 9
      chenhai-system/src/main/java/com/chenhai/muhu/mapper/CarouselAdsMapper.java
  9. 8
      chenhai-system/src/main/java/com/chenhai/muhu/service/ICarouselAdsService.java
  10. 14
      chenhai-system/src/main/java/com/chenhai/muhu/service/impl/CarouselAdsServiceImpl.java
  11. 22
      chenhai-system/src/main/java/com/chenhai/system/domain/SysMedicineRecommendation.java
  12. 11
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysUserMapper.java
  13. 10
      chenhai-system/src/main/java/com/chenhai/system/service/ISysUserService.java
  14. 16
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysUserServiceImpl.java
  15. 29
      chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java
  16. 2
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java
  17. 44
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java
  18. 14
      chenhai-system/src/main/resources/mapper/muhu/CarouselAdsMapper.xml
  19. 13
      chenhai-system/src/main/resources/mapper/muhu/DisasterWarningMapper.xml
  20. 39
      chenhai-system/src/main/resources/mapper/muhu/MuhuConsultationFormsMapper.xml
  21. 30
      chenhai-system/src/main/resources/mapper/system/SysUserMapper.xml
  22. 22
      chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml
  23. 38
      chenhai-ui/src/api/vet/merchant.js
  24. 39
      chenhai-ui/src/api/vet/product.js
  25. 42
      chenhai-ui/src/views/vet/knowledge/index.vue
  26. 584
      chenhai-ui/src/views/vet/merchant/index.vue
  27. 848
      chenhai-ui/src/views/vet/product/index.vue

1
chenhai-admin/src/main/java/com/chenhai/web/controller/auth/MultiAuthController.java

@ -26,6 +26,7 @@ public class MultiAuthController {
/** /**
* 微信小程序登录 - 保持原逻辑 * 微信小程序登录 - 保持原逻辑
*/ */
@PostMapping("/wechat/login") @PostMapping("/wechat/login")
public AjaxResult wechatLogin(@Valid @RequestBody WechatLoginBody loginBody) { public AjaxResult wechatLogin(@Valid @RequestBody WechatLoginBody loginBody) {
Map<String, Object> result = loginService.wechatLogin( Map<String, Object> result = loginService.wechatLogin(

15
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.hasPermi('muhu:ads:list')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger') or @ss.hasRole('vet')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(CarouselAds carouselAds) public TableDataInfo list(CarouselAds carouselAds)
{ {
@ -45,7 +45,7 @@ public class CarouselAdsController extends BaseController
* 导出轮播广告列表 * 导出轮播广告列表
*/ */
// @PreAuthorize("@ss.hasPermi('muhu:ads:export')") // @PreAuthorize("@ss.hasPermi('muhu:ads:export')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "轮播广告", businessType = BusinessType.EXPORT) @Log(title = "轮播广告", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, CarouselAds carouselAds) public void export(HttpServletResponse response, CarouselAds carouselAds)
@ -59,10 +59,13 @@ public class CarouselAdsController extends BaseController
* 获取轮播广告详细信息 * 获取轮播广告详细信息
*/ */
// @PreAuthorize("@ss.hasPermi('muhu:ads:query')") // @PreAuthorize("@ss.hasPermi('muhu:ads:query')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger') or @ss.hasRole('vet')")
@GetMapping(value = "/{carouselId}") @GetMapping(value = "/{carouselId}")
public AjaxResult getInfo(@PathVariable("carouselId") Long carouselId) public AjaxResult getInfo(@PathVariable("carouselId") Long carouselId)
{ {
// 先增加浏览量
carouselAdsService.incrementViewCount(carouselId);
// 再查询详情
return success(carouselAdsService.selectCarouselAdsByCarouselId(carouselId)); return success(carouselAdsService.selectCarouselAdsByCarouselId(carouselId));
} }
@ -70,7 +73,7 @@ public class CarouselAdsController extends BaseController
* 新增轮播广告 * 新增轮播广告
*/ */
// @PreAuthorize("@ss.hasPermi('muhu:ads:add')") // @PreAuthorize("@ss.hasPermi('muhu:ads:add')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu') or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "轮播广告", businessType = BusinessType.INSERT) @Log(title = "轮播广告", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@RequestBody CarouselAds carouselAds) public AjaxResult add(@RequestBody CarouselAds carouselAds)
@ -82,7 +85,7 @@ public class CarouselAdsController extends BaseController
* 修改轮播广告 * 修改轮播广告
*/ */
// @PreAuthorize("@ss.hasPermi('muhu:ads:edit')") // @PreAuthorize("@ss.hasPermi('muhu:ads:edit')")
@PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "轮播广告", businessType = BusinessType.UPDATE) @Log(title = "轮播广告", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody CarouselAds carouselAds) public AjaxResult edit(@RequestBody CarouselAds carouselAds)
@ -94,7 +97,7 @@ public class CarouselAdsController extends BaseController
* 删除轮播广告 * 删除轮播广告
*/ */
// @PreAuthorize("@ss.hasPermi('muhu:ads:remove')") // @PreAuthorize("@ss.hasPermi('muhu:ads:remove')")
@PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "轮播广告", businessType = BusinessType.DELETE) @Log(title = "轮播广告", businessType = BusinessType.DELETE)
@DeleteMapping("/{carouselIds}") @DeleteMapping("/{carouselIds}")
public AjaxResult remove(@PathVariable Long[] carouselIds) public AjaxResult remove(@PathVariable Long[] carouselIds)

20
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java

@ -43,7 +43,7 @@ public class VetKnowledgeController extends BaseController
* 查询兽医文章列表 * 查询兽医文章列表
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:list') or @ss.hasRole('muhu') or @ss.hasRole('vet')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:list') or @ss.hasRole('muhu') or @ss.hasRole('vet') or @ss.hasRole('manger')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(VetKnowledge vetKnowledge) public TableDataInfo list(VetKnowledge vetKnowledge)
{ {
@ -56,7 +56,7 @@ public class VetKnowledgeController extends BaseController
* 导出兽医文章列表 * 导出兽医文章列表
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:export') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:export') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.EXPORT) @Log(title = "兽医文章", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, VetKnowledge vetKnowledge) public void export(HttpServletResponse response, VetKnowledge vetKnowledge)
@ -69,7 +69,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 获取兽医文章详细信息 * 获取兽医文章详细信息
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:query') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:query') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) public AjaxResult getInfo(@PathVariable("id") Long id)
{ {
@ -80,20 +80,20 @@ public class VetKnowledgeController extends BaseController
* 新增兽医文章 * 新增兽医文章
*/ */
@SensitiveCheck @SensitiveCheck
@PreAuthorize("@ss.hasPermi('vet:knowledge:add') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:add') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.INSERT) @Log(title = "兽医文章", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@RequestBody VetKnowledge vetKnowledge) public AjaxResult add(@RequestBody VetKnowledge vetKnowledge)
{ {
vetKnowledge.setArticleStatus("0"); // 草稿 vetKnowledge.setArticleStatus("0"); // 草稿
vetKnowledge.setAuditStatus("0"); // 待审核
vetKnowledge.setAuditStatus("1"); // 待审核
return toAjax(vetKnowledgeService.insertVetKnowledge(vetKnowledge)); return toAjax(vetKnowledgeService.insertVetKnowledge(vetKnowledge));
} }
/** /**
* 修改兽医文章 * 修改兽医文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:edit') or @ss.hasRole('muhu')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:edit') or @ss.hasRole('muhu') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody VetKnowledge vetKnowledge) public AjaxResult edit(@RequestBody VetKnowledge vetKnowledge)
@ -104,7 +104,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 删除兽医文章 * 删除兽医文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:remove')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:remove') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.DELETE) @Log(title = "兽医文章", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) public AjaxResult remove(@PathVariable Long[] ids)
@ -141,7 +141,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 发布文章 * 发布文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/publish/{id}") @PutMapping("/publish/{id}")
public AjaxResult publish(@PathVariable Long id) { public AjaxResult publish(@PathVariable Long id) {
@ -151,7 +151,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 上架文章 * 上架文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/online/{id}") @PutMapping("/online/{id}")
public AjaxResult online(@PathVariable Long id) { public AjaxResult online(@PathVariable Long id) {
@ -161,7 +161,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 下架文章 * 下架文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')or @ss.hasRole('manger') or @ss.hasRole('vet')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/offline/{id}") @PutMapping("/offline/{id}")
public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) { public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) {

73
chenhai-framework/src/main/java/com/chenhai/framework/web/service/SysLoginService.java

@ -1,5 +1,6 @@
package com.chenhai.framework.web.service; package com.chenhai.framework.web.service;
import com.chenhai.common.core.domain.entity.SysUserAuth;
import com.chenhai.common.utils.*; import com.chenhai.common.utils.*;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -278,25 +279,17 @@ public class SysLoginService
throw new ServiceException("获取手机号失败"); throw new ServiceException("获取手机号失败");
} }
// 4. 查询手机号是否已注册
SysUser existingUser = userService.selectUserByPhone(phone);
// 4. 转换用户类型代码
String targetUserTypeCode = "herdsman".equals(userType) ? "02" : "01";
// 5. 用户不存在创建新用户
if (existingUser == null) {
String userTypeCode = "herdsman".equals(userType) ? "02" : "01";
existingUser = createUserForWechat(phone, userTypeCode, nickName, avatarUrl, clientType);
} else {
// 6. 用户已存在检查用户类型是否匹配
String existingUserType = existingUser.getUserType();
String expectedUserType = "herdsman".equals(userType) ? "02" : "01";
if (!existingUserType.equals(expectedUserType)) {
String existingTypeName = "01".equals(existingUserType) ? "兽医" : "牧户";
String expectedTypeName = "01".equals(expectedUserType) ? "兽医" : "牧户";
throw new ServiceException("该手机号已注册为" + existingTypeName + ",请使用" + expectedTypeName + "小程序");
}
// 5. 查询该手机号指定类型的用户
SysUser existingUser = userService.selectUserByPhoneAndType(phone, targetUserTypeCode);
if (existingUser != null) {
// 6. 该类型用户已存在更新信息
log.info("该手机号已注册为{}用户,更新信息: phone={}, userId={}",
"02".equals(targetUserTypeCode) ? "牧户" : "兽医", phone, existingUser.getUserId());
// 7. 用户类型匹配更新用户信息
if (nickName != null) { if (nickName != null) {
existingUser.setNickName(nickName); existingUser.setNickName(nickName);
} }
@ -304,12 +297,31 @@ public class SysLoginService
existingUser.setAvatar(avatarUrl); existingUser.setAvatar(avatarUrl);
} }
userService.updateUser(existingUser); userService.updateUser(existingUser);
} else {
// 7. 该类型用户不存在创建新用户
log.info("手机号{}未注册为{}用户,创建新用户",
phone, "02".equals(targetUserTypeCode) ? "牧户" : "兽医");
existingUser = createUserForWechat(phone, targetUserTypeCode, nickName, avatarUrl, clientType);
} }
// 8. 绑定微信openid
userAuthService.bindAuth(existingUser.getUserId(), authType, openid, sessionKey);
// 8. 检查微信是否已绑定 - 使用 findUserByAuth 替代
SysUser boundUser = userAuthService.findUserByAuth(authType, openid);
if (boundUser != null) {
if (!boundUser.getUserId().equals(existingUser.getUserId())) {
// 微信已绑定其他账号
throw new ServiceException("该微信已绑定其他账号");
}
// 已绑定当前用户无需重复绑定
log.info("微信已绑定当前用户: userId={}, openid={}", existingUser.getUserId(), openid);
} else {
// 9. 绑定微信openid
userAuthService.bindAuth(existingUser.getUserId(), authType, openid, sessionKey);
log.info("微信绑定成功: userId={}, openid={}", existingUser.getUserId(), openid);
}
// 9. 创建登录用户
// 10. 创建登录用户
LoginUser loginUser = new LoginUser( LoginUser loginUser = new LoginUser(
existingUser.getUserId(), existingUser.getUserId(),
existingUser.getDeptId(), existingUser.getDeptId(),
@ -320,23 +332,23 @@ public class SysLoginService
recordLoginInfo(loginUser.getUserId()); recordLoginInfo(loginUser.getUserId());
// 10. 生成token
// 11. 生成token
String token = tokenService.createToken(loginUser); String token = tokenService.createToken(loginUser);
// 11. 清理Redis临时数据
// 12. 清理Redis临时数据
redisCache.deleteObject("wechat:session:" + tempCode); redisCache.deleteObject("wechat:session:" + tempCode);
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put("token", token); result.put("token", token);
result.put("message", "绑定成功"); result.put("message", "绑定成功");
result.put("userType", "02".equals(targetUserTypeCode) ? "herdsman" : "vet");
return result; return result;
} catch (Exception e) { } catch (Exception e) {
// 保持原异常处理方式返回 AjaxResult.error 的字符串
log.error("微信绑定失败: {}", e.getMessage(), e);
throw new ServiceException("绑定失败: " + e.getMessage()); throw new ServiceException("绑定失败: " + e.getMessage());
} }
} }
/** /**
* 手机号+密码登录 - 多端登录新增 * 手机号+密码登录 - 多端登录新增
*/ */
@ -434,10 +446,13 @@ public class SysLoginService
// 2. 验证密码强度 // 2. 验证密码强度
validatePassword(password); validatePassword(password);
// 3. 检查手机号是否已注册
checkPhoneRegistered(phone);
// 3. 检查该手机号是否已注册为兽医
SysUser existingVet = userService.selectUserByPhoneAndType(phone, "01"); // 兽医类型
if (existingVet != null) {
throw new ServiceException("该手机号已注册为兽医账号");
}
// 4. 创建牧户用户
// 4. 创建兽医用户允许手机号已注册为牧户
SysUser user = createVetUser(phone, password, clientType); SysUser user = createVetUser(phone, password, clientType);
// 5. 创建登录用户 // 5. 创建登录用户
@ -504,6 +519,10 @@ public class SysLoginService
if (authUser != null) { if (authUser != null) {
throw new ServiceException("该手机号已注册"); throw new ServiceException("该手机号已注册");
} }
SysUser existingVet = userService.selectUserByPhoneAndType(phone, "01");
if (existingVet != null) {
throw new ServiceException("该手机号已注册为兽医账号");
}
} }
/** /**

15
chenhai-system/src/main/java/com/chenhai/muhu/domain/CarouselAds.java

@ -149,6 +149,10 @@ public class CarouselAds extends BaseEntity
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedAt; private Date updatedAt;
/** 浏览量 */
@Excel(name = "浏览量")
private Long viewCount;
public void setAdsType(String adsType) public void setAdsType(String adsType)
{ {
this.adsType = adsType; this.adsType = adsType;
@ -469,6 +473,16 @@ public class CarouselAds extends BaseEntity
return updatedAt; return updatedAt;
} }
public void setViewCount(Long viewCount)
{
this.viewCount = viewCount;
}
public Long getViewCount()
{
return viewCount;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -504,6 +518,7 @@ public class CarouselAds extends BaseEntity
.append("createdAt", getCreatedAt()) .append("createdAt", getCreatedAt())
.append("updatedAt", getUpdatedAt()) .append("updatedAt", getUpdatedAt())
.append("adsType",getAdsType()) .append("adsType",getAdsType())
.append("viewCount", getViewCount())
.toString(); .toString();
} }
} }

11
chenhai-system/src/main/java/com/chenhai/muhu/domain/DisasterWarning.java

@ -62,6 +62,9 @@ public class DisasterWarning extends BaseEntity
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime; private Date createdTime;
/** 关键词搜索(非数据库字段) */
private String keyword;
public void setId(Long id) public void setId(Long id)
{ {
this.id = id; this.id = id;
@ -172,6 +175,14 @@ public class DisasterWarning extends BaseEntity
return createdTime; return createdTime;
} }
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

13
chenhai-system/src/main/java/com/chenhai/muhu/domain/MuhuConsultationForms.java

@ -83,8 +83,8 @@ public class MuhuConsultationForms extends BaseEntity
@Excel(name = "头像") @Excel(name = "头像")
private String avatar; private String avatar;
/** 今日回复总数(非数据库字段,用于统计) */
private Long todayReplyCount;
/** 今日回复总数(所有问诊单的今日回复总和) */
private Long totalTodayReplyCount;
public void setFormId(Long formId) public void setFormId(Long formId)
{ {
@ -246,12 +246,12 @@ public class MuhuConsultationForms extends BaseEntity
return avatar; return avatar;
} }
public Long getTodayReplyCount() {
return todayReplyCount;
public Long getTotalTodayReplyCount() {
return totalTodayReplyCount;
} }
public void setTodayReplyCount(Long todayReplyCount) {
this.todayReplyCount = todayReplyCount;
public void setTotalTodayReplyCount(Long totalTodayReplyCount) {
this.totalTodayReplyCount = totalTodayReplyCount;
} }
@ -274,7 +274,6 @@ public class MuhuConsultationForms extends BaseEntity
.append("replyCount", getReplyCount()) .append("replyCount", getReplyCount())
.append("createdTime", getCreatedTime()) .append("createdTime", getCreatedTime())
.append("avatar", getAvatar()) .append("avatar", getAvatar())
.append("todayReplyCount", getTodayReplyCount())
.toString(); .toString();
} }
} }

9
chenhai-system/src/main/java/com/chenhai/muhu/mapper/CarouselAdsMapper.java

@ -1,6 +1,7 @@
package com.chenhai.muhu.mapper; package com.chenhai.muhu.mapper;
import com.chenhai.muhu.domain.CarouselAds; import com.chenhai.muhu.domain.CarouselAds;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -59,4 +60,12 @@ public interface CarouselAdsMapper
* @return 结果 * @return 结果
*/ */
public int deleteCarouselAdsByCarouselIds(Long[] carouselIds); public int deleteCarouselAdsByCarouselIds(Long[] carouselIds);
/**
* 增加浏览量
*
* @param carouselId 轮播广告主键
* @return 结果
*/
public int incrementViewCount(@Param("carouselId") Long carouselId);
} }

8
chenhai-system/src/main/java/com/chenhai/muhu/service/ICarouselAdsService.java

@ -59,4 +59,12 @@ public interface ICarouselAdsService
* @return 结果 * @return 结果
*/ */
public int deleteCarouselAdsByCarouselId(Long carouselId); public int deleteCarouselAdsByCarouselId(Long carouselId);
/**
* 增加浏览量
*
* @param carouselId 轮播广告主键
* @return 结果
*/
public int incrementViewCount(Long carouselId);
} }

14
chenhai-system/src/main/java/com/chenhai/muhu/service/impl/CarouselAdsServiceImpl.java

@ -6,6 +6,7 @@ import com.chenhai.muhu.mapper.CarouselAdsMapper;
import com.chenhai.muhu.service.ICarouselAdsService; import com.chenhai.muhu.service.ICarouselAdsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
@ -92,4 +93,17 @@ public class CarouselAdsServiceImpl implements ICarouselAdsService
{ {
return carouselAdsMapper.deleteCarouselAdsByCarouselId(carouselId); return carouselAdsMapper.deleteCarouselAdsByCarouselId(carouselId);
} }
/**
* 增加浏览量
*
* @param carouselId 轮播广告主键
* @return 结果
*/
@Override
@Transactional
public int incrementViewCount(Long carouselId)
{
return carouselAdsMapper.incrementViewCount(carouselId);
}
} }

22
chenhai-system/src/main/java/com/chenhai/system/domain/SysMedicineRecommendation.java

@ -146,6 +146,12 @@ public class SysMedicineRecommendation extends BaseEntity
@Excel(name = "纬度") @Excel(name = "纬度")
private BigDecimal latitude; private BigDecimal latitude;
/** 排序字段 */
private String orderByColumn;
/** 排序方向 */
private String orderDirection;
public void setId(Long id) public void setId(Long id)
{ {
this.id = id; this.id = id;
@ -494,6 +500,22 @@ public class SysMedicineRecommendation extends BaseEntity
return searchKeywords; return searchKeywords;
} }
public String getOrderByColumn() {
return orderByColumn;
}
public void setOrderByColumn(String orderByColumn) {
this.orderByColumn = orderByColumn;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
this.orderDirection = orderDirection;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

11
chenhai-system/src/main/java/com/chenhai/system/mapper/SysUserMapper.java

@ -156,4 +156,15 @@ public interface SysUserMapper
public SysUser checkEmailUnique(String email); public SysUser checkEmailUnique(String email);
public int updateUserAreaCode(@Param("userId") Long userId, @Param("areaCode") String areaCode); public int updateUserAreaCode(@Param("userId") Long userId, @Param("areaCode") String areaCode);
/**
* 根据手机号和用户类型查询用户
*/
SysUser selectUserByPhoneAndType(@Param("phonenumber") String phone,
@Param("userType") String userType);
/**
* 查询手机号已注册的类型列表
*/
List<String> selectUserTypesByPhone(@Param("phonenumber") String phone);
} }

10
chenhai-system/src/main/java/com/chenhai/system/service/ISysUserService.java

@ -232,4 +232,14 @@ public interface ISysUserService
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName); public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
public int updateUserAreaCode(Long userId, String areaCode); public int updateUserAreaCode(Long userId, String areaCode);
/**
* 根据手机号和用户类型查询用户
*/
SysUser selectUserByPhoneAndType(String phone, String userType);
/**
* 查询手机号已注册的所有类型
*/
List<String> selectUserTypesByPhone(String phone);
} }

16
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysUserServiceImpl.java

@ -579,4 +579,20 @@ public class SysUserServiceImpl implements ISysUserService
public int updateUserAreaCode(Long userId, String areaCode) { public int updateUserAreaCode(Long userId, String areaCode) {
return userMapper.updateUserAreaCode(userId, areaCode); return userMapper.updateUserAreaCode(userId, areaCode);
} }
@Override
public SysUser selectUserByPhoneAndType(String phone, String userType) {
if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(userType)) {
return null;
}
return userMapper.selectUserByPhoneAndType(phone, userType);
}
@Override
public List<String> selectUserTypesByPhone(String phone) {
if (StringUtils.isEmpty(phone)) {
return new ArrayList<>();
}
return userMapper.selectUserTypesByPhone(phone);
}
} }

29
chenhai-system/src/main/java/com/chenhai/vet/domain/MerchantInfo.java

@ -85,7 +85,9 @@ public class MerchantInfo extends BaseEntity
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date offlineTime; private Date offlineTime;
/** 产品数量 */
@Excel(name = "产品数量")
private Long productCount;
public void setShopId(Long shopId) public void setShopId(Long shopId)
{ {
@ -238,7 +240,13 @@ public class MerchantInfo extends BaseEntity
this.businessLicenseImage = businessLicenseImage; this.businessLicenseImage = businessLicenseImage;
} }
public Long getProductCount() {
return productCount;
}
public void setProductCount(Long productCount) {
this.productCount = productCount;
}
@Override @Override
public String toString() { public String toString() {
@ -251,15 +259,16 @@ public class MerchantInfo extends BaseEntity
.append("createdAt", getCreatedAt()) .append("createdAt", getCreatedAt())
.append("updatedAt", getUpdatedAt()) .append("updatedAt", getUpdatedAt())
.append("isActive", getIsActive()) .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())
.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())
.append("productCount", getProductCount())
.toString(); .toString();
} }
} }

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

@ -55,7 +55,7 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService
vetKnowledge.setArticleStatus("0"); // 草稿 vetKnowledge.setArticleStatus("0"); // 草稿
} }
if (vetKnowledge.getAuditStatus() == null) { if (vetKnowledge.getAuditStatus() == null) {
vetKnowledge.setAuditStatus("0"); // 待审核
vetKnowledge.setAuditStatus("1"); // 待审核
} }
return vetKnowledgeMapper.insertVetKnowledge(vetKnowledge); return vetKnowledgeMapper.insertVetKnowledge(vetKnowledge);
} }

44
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java

@ -378,27 +378,40 @@ public class VetProductServiceImpl implements IVetProductService
@Transactional @Transactional
public int insertVetProduct(VetProduct vetProduct) public int insertVetProduct(VetProduct vetProduct)
{ {
// 如果已经传入了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);
// 设置默认值
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) {
throw new RuntimeException("获取用户信息失败");
}
// 关键修改如果前端已经传入了shopId直接使用不再查询
if (vetProduct.getShopId() != null) {
// 验证该店铺是否属于当前用户可选
// 这里可以添加验证逻辑确保用户只能给自己店铺添加产品
} else {
// 如果前端没有传入shopId则查询用户的默认店铺
try {
// 查询用户的店铺 // 查询用户的店铺
MerchantInfo merchantQuery = new MerchantInfo(); MerchantInfo merchantQuery = new MerchantInfo();
merchantQuery.setUserId(userId); // 这里直接调用setter方法
merchantQuery.setUserId(vetProduct.getUserId());
List<MerchantInfo> merchantList = merchantInfoMapper.selectMerchantInfoList(merchantQuery); List<MerchantInfo> merchantList = merchantInfoMapper.selectMerchantInfoList(merchantQuery);
if (merchantList != null && !merchantList.isEmpty()) { if (merchantList != null && !merchantList.isEmpty()) {
vetProduct.setShopId(merchantList.get(0).getShopId());
// 如果有多个店铺默认使用第一个
Long shopId = merchantList.get(0).getShopId();
vetProduct.setShopId(shopId);
} else { } else {
throw new RuntimeException("用户未关联任何店铺,无法创建产品"); throw new RuntimeException("用户未关联任何店铺,无法创建产品");
} }
@ -410,7 +423,6 @@ public class VetProductServiceImpl implements IVetProductService
return vetProductMapper.insertVetProduct(vetProduct); return vetProductMapper.insertVetProduct(vetProduct);
} }
/** /**
* 管理员查询所有兽医产品信息列表用于审核 * 管理员查询所有兽医产品信息列表用于审核
*/ */

14
chenhai-system/src/main/resources/mapper/muhu/CarouselAdsMapper.xml

@ -37,10 +37,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createdAt" column="created_at" /> <result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" /> <result property="updatedAt" column="updated_at" />
<result property="adsType" column="ads_type"/> <result property="adsType" column="ads_type"/>
<result property="viewCount" column="view_count" />
</resultMap> </resultMap>
<sql id="selectCarouselAdsVo"> <sql id="selectCarouselAdsVo">
select carousel_id, title, subtitle, image_url, alt_text, image_size, bg_color, text_color, button_text, button_class, link_type, link_url, link_params, sort_order, display_type, is_active, start_time, end_time, is_always_valid, caption_position, caption_style, button_style, display_count, click_count, status, review_notes, reviewed_by, reviewed_at, created_by, created_at, updated_at, ads_type from muhu_carousel_ads
select carousel_id, title, subtitle, image_url, alt_text, image_size, bg_color, text_color, button_text, button_class, link_type, link_url, link_params, sort_order, display_type, is_active, start_time, end_time, is_always_valid, caption_position, caption_style, button_style, display_count, click_count, status, review_notes, reviewed_by, reviewed_at, created_by, created_at, updated_at, ads_type, view_count from muhu_carousel_ads
</sql> </sql>
<select id="selectCarouselAdsList" parameterType="CarouselAds" resultMap="CarouselAdsResult"> <select id="selectCarouselAdsList" parameterType="CarouselAds" resultMap="CarouselAdsResult">
@ -77,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createdAt != null "> and created_at = #{createdAt}</if> <if test="createdAt != null "> and created_at = #{createdAt}</if>
<if test="updatedAt != null "> and updated_at = #{updatedAt}</if> <if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
<if test="adsType != null"> and ads_type = #{adsType}</if> <if test="adsType != null"> and ads_type = #{adsType}</if>
<if test="viewCount != null "> and view_count = #{viewCount}</if>
</where> </where>
</select> </select>
@ -119,6 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createdAt != null">created_at,</if> <if test="createdAt != null">created_at,</if>
<if test="updatedAt != null">updated_at,</if> <if test="updatedAt != null">updated_at,</if>
<if test="adsType != null">ads_type,</if> <if test="adsType != null">ads_type,</if>
<if test="viewCount != null">view_count,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if> <if test="title != null and title != ''">#{title},</if>
@ -152,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createdAt != null">#{createdAt},</if> <if test="createdAt != null">#{createdAt},</if>
<if test="updatedAt != null">#{updatedAt},</if> <if test="updatedAt != null">#{updatedAt},</if>
<if test="adsType != null">#{adsType},</if> <if test="adsType != null">#{adsType},</if>
<if test="viewCount != null">#{viewCount},</if>
</trim> </trim>
</insert> </insert>
@ -189,6 +193,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createdAt != null">created_at = #{createdAt},</if> <if test="createdAt != null">created_at = #{createdAt},</if>
<if test="updatedAt != null">updated_at = #{updatedAt},</if> <if test="updatedAt != null">updated_at = #{updatedAt},</if>
<if test="adsType != null">ads_type = #{adsType}</if> <if test="adsType != null">ads_type = #{adsType}</if>
<if test="viewCount != null">view_count = #{viewCount},</if>
</trim> </trim>
where carousel_id = #{carouselId} where carousel_id = #{carouselId}
</update> </update>
@ -203,4 +208,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{carouselId} #{carouselId}
</foreach> </foreach>
</delete> </delete>
<!-- 增加浏览量 -->
<update id="incrementViewCount">
update muhu_carousel_ads
set view_count = ifnull(view_count, 0) + 1
where carousel_id = #{carouselId}
</update>
</mapper> </mapper>

13
chenhai-system/src/main/resources/mapper/muhu/DisasterWarningMapper.xml

@ -35,6 +35,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="affectedRegions != null and affectedRegions != ''"> and affected_regions = #{affectedRegions}</if> <if test="affectedRegions != null and affectedRegions != ''"> and affected_regions = #{affectedRegions}</if>
<if test="lastUpdated != null "> and last_updated = #{lastUpdated}</if> <if test="lastUpdated != null "> and last_updated = #{lastUpdated}</if>
<if test="createdTime != null "> and created_time = #{createdTime}</if> <if test="createdTime != null "> and created_time = #{createdTime}</if>
<!-- 添加搜索字段:支持标题、内容、措施、编码、区域等多字段模糊搜索 -->
<if test="keyword != null and keyword != ''">
AND (
title LIKE CONCAT('%', #{keyword}, '%')
OR brief_content LIKE CONCAT('%', #{keyword}, '%')
OR detail_content LIKE CONCAT('%', #{keyword}, '%')
OR response_measures LIKE CONCAT('%', #{keyword}, '%')
OR warning_code LIKE CONCAT('%', #{keyword}, '%')
OR affected_regions LIKE CONCAT('%', #{keyword}, '%')
OR warning_type LIKE CONCAT('%', #{keyword}, '%')
OR warning_level LIKE CONCAT('%', #{keyword}, '%')
)
</if>
</where> </where>
</select> </select>

39
chenhai-system/src/main/resources/mapper/muhu/MuhuConsultationFormsMapper.xml

@ -21,8 +21,8 @@
<result property="createdTime" column="created_time" /> <result property="createdTime" column="created_time" />
<result property="avatar" column="avatar" /> <result property="avatar" column="avatar" />
<result property="images" column="images" /> <result property="images" column="images" />
<!-- 今日回复总数字段 -->
<result property="todayReplyCount" column="today_reply_count" />
<!-- 添加今日回复总数字段映射 -->
<result property="totalTodayReplyCount" column="total_today_reply_count" />
</resultMap> </resultMap>
<sql id="selectMuhuConsultationFormsVo"> <sql id="selectMuhuConsultationFormsVo">
@ -68,19 +68,46 @@
<!-- 查询今日问诊单列表,并统计今日回复总数 --> <!-- 查询今日问诊单列表,并统计今日回复总数 -->
<select id="selectTodayConsultationFormsList" parameterType="MuhuConsultationForms" resultMap="MuhuConsultationFormsResult"> <select id="selectTodayConsultationFormsList" parameterType="MuhuConsultationForms" resultMap="MuhuConsultationFormsResult">
SELECT SELECT
cf.*,
cf.form_id,
cf.farmer_name,
cf.user_id,
cf.title,
cf.description,
cf.animal_type,
cf.animal_age,
cf.animal_gender,
cf.images,
cf.status,
cf.is_sensitive,
cf.sensitive_words,
cf.view_count,
cf.created_time,
cf.avatar,
(SELECT COUNT(*) FROM vet_comments vc WHERE vc.consultation_id = cf.form_id) as reply_count, (SELECT COUNT(*) FROM vet_comments vc WHERE vc.consultation_id = cf.form_id) as reply_count,
COALESCE(( COALESCE((
SELECT COUNT(*) SELECT COUNT(*)
FROM vet_comments vc FROM vet_comments vc
WHERE vc.consultation_id = cf.form_id WHERE vc.consultation_id = cf.form_id
AND DATE(vc.create_time) = CURDATE()
), 0) as today_reply_count
AND DATE(vc.created_at) = CURDATE()
), 0) as today_reply_count,
-- 添加 total_today_reply_count 字段
COALESCE((
SELECT COUNT(*)
FROM vet_comments vc2
WHERE DATE(vc2.created_at) = CURDATE()
AND vc2.consultation_id IN (
SELECT form_id
FROM muhu_consultation_forms cf2
WHERE DATE(cf2.created_time) = CURDATE()
<if test="userId != null">
AND cf2.user_id = #{userId}
</if>
)
), 0) as total_today_reply_count
FROM muhu_consultation_forms cf FROM muhu_consultation_forms cf
<where> <where>
<!-- 只查询今天的数据 --> <!-- 只查询今天的数据 -->
AND DATE(cf.created_time) = CURDATE() AND DATE(cf.created_time) = CURDATE()
<if test="farmerName != null "> and cf.farmer_name = #{farmerName}</if> <if test="farmerName != null "> and cf.farmer_name = #{farmerName}</if>
<if test="userId != null "> and cf.user_id = #{userId}</if> <if test="userId != null "> and cf.user_id = #{userId}</if>
<if test="title != null and title != ''"> <if test="title != null and title != ''">

30
chenhai-system/src/main/resources/mapper/system/SysUserMapper.xml

@ -294,4 +294,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update sys_user set area_code = #{areaCode} where user_id = #{userId} update sys_user set area_code = #{areaCode} where user_id = #{userId}
</update> </update>
<!-- 根据手机号和用户类型查询用户 -->
<select id="selectUserByPhoneAndType" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.user_type,
u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status,
u.del_flag, u.login_ip, u.login_date, u.pwd_update_date,
u.area_code, u.create_by, u.create_time, u.remark,
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num,
d.leader, d.status as dept_status,
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope,
r.status as role_status,
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_dept d on u.dept_id = d.dept_id
left join sys_user_role ur on u.user_id = ur.user_id
left join sys_role r on r.role_id = ur.role_id
left join sys_area a on u.area_code = a.code
where u.phonenumber = #{phonenumber}
and u.user_type = #{userType}
and u.del_flag = '0'
</select>
<!-- 查询手机号已注册的类型列表 -->
<select id="selectUserTypesByPhone" resultType="string">
select distinct user_type
from sys_user
where phonenumber = #{phonenumber}
and del_flag = '0'
</select>
</mapper> </mapper>

22
chenhai-system/src/main/resources/mapper/vet/MerchantInfoMapper.xml

@ -22,10 +22,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="shopStatus" column="shop_status" /> <result property="shopStatus" column="shop_status" />
<result property="publishTime" column="publish_time" /> <result property="publishTime" column="publish_time" />
<result property="offlineTime" column="offline_time" /> <result property="offlineTime" column="offline_time" />
<result property="productCount" column="product_count" />
</resultMap> </resultMap>
<sql id="selectMerchantInfoVo"> <sql id="selectMerchantInfoVo">
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
select
m.shop_id,
m.shop_name,
m.shop_address,
m.phone,
m.user_id,
m.created_at,
m.updated_at,
m.is_active,
m.shop_logo,
m.business_license_image,
m.audit_status,
m.audit_opinion,
m.audit_user_id,
m.audit_time,
m.shop_status,
m.publish_time,
m.offline_time,
(select count(*) from vet_product p where p.shop_id = m.shop_id and p.is_deleted = 0) as product_count
from merchant_info m
</sql> </sql>
<select id="selectMerchantInfoList" parameterType="MerchantInfo" resultMap="MerchantInfoResult"> <select id="selectMerchantInfoList" parameterType="MerchantInfo" resultMap="MerchantInfoResult">

38
chenhai-ui/src/api/vet/merchant.js

@ -43,15 +43,17 @@ export function delMerchant(shopId) {
}) })
} }
// Post /vet/merchant/audit 审核
export function audit(shopId) {
// 审核商家(单个审核)
export function auditMerchant(data) {
// data 应该包含 { shopId, auditStatus, auditOpinion }
return request({ return request({
url: '/vet/merchant/audit/' + shopId,
method: 'post'
url: '/vet/merchant/audit',
method: 'post',
data: data
}) })
} }
///vet/merchant/submitAudit/{shopId}提交审核
// 提交审核
export function submitAudit(shopId) { export function submitAudit(shopId) {
return request({ return request({
url: '/vet/merchant/submitAudit/' + shopId, url: '/vet/merchant/submitAudit/' + shopId,
@ -59,7 +61,7 @@ export function submitAudit(shopId) {
}) })
} }
// /vet/merchant/publish/{shopId}上架
// 上架
export function publish(shopId) { export function publish(shopId) {
return request({ return request({
url: '/vet/merchant/publish/' + shopId, url: '/vet/merchant/publish/' + shopId,
@ -67,7 +69,7 @@ export function publish(shopId) {
}) })
} }
// /vet/merchant/offline/{shopId}下架
// 下架
export function offline(shopId) { export function offline(shopId) {
return request({ return request({
url: '/vet/merchant/offline/' + shopId, url: '/vet/merchant/offline/' + shopId,
@ -75,15 +77,7 @@ export function offline(shopId) {
}) })
} }
// Get /vet/product/shop/{shopId} 详情
export function getShop(shopId) {
return request({
url: '/vet/product/shop/' + shopId,
method: 'get'
})
}
// /vet/merchant/resubmitAudit/{shopId}商家重新提交审核
// 重新提交审核
export function resubmitAudit(shopId) { export function resubmitAudit(shopId) {
return request({ return request({
url: '/vet/merchant/resubmitAudit/' + shopId, url: '/vet/merchant/resubmitAudit/' + shopId,
@ -91,10 +85,20 @@ export function resubmitAudit(shopId) {
}) })
} }
// /vet/merchant/cancelAudit/{shopId}取消审核
// 取消审核
export function cancelAudit(shopId) { export function cancelAudit(shopId) {
return request({ return request({
url: '/vet/merchant/cancelAudit/' + shopId, url: '/vet/merchant/cancelAudit/' + shopId,
method: 'post' method: 'post'
}) })
} }
// 批量审核接口
export function batchAuditMerchant(data) {
// data 应该包含 { shopIds, auditStatus, auditOpinion }
return request({
url: '/vet/merchant/batch-audit',
method: 'post',
data: data
})
}

39
chenhai-ui/src/api/vet/product.js

@ -43,9 +43,7 @@ export function delProduct(id) {
}) })
} }
// auditStatus审核状态 auditOpinion审核意见 shopStatus店铺状态
// /vet/product/submitAudit/{id}提交审核
// 提交审核
export function submitAuditProduct(id) { export function submitAuditProduct(id) {
return request({ return request({
url: '/vet/product/submitAudit/' + id, url: '/vet/product/submitAudit/' + id,
@ -53,28 +51,31 @@ export function submitAuditProduct(id) {
}) })
} }
// /vet/product/publish/{id}上架
// 上架
export function publishProduct(id) { export function publishProduct(id) {
return request({ return request({
url: '/vet/product/publish/' + id, url: '/vet/product/publish/' + id,
method: 'post' method: 'post'
}) })
} }
// /vet/product/offline/{id}下架
// 下架
export function offlineProduct(id) { export function offlineProduct(id) {
return request({ return request({
url: '/vet/product/offline/' + id, url: '/vet/product/offline/' + id,
method: 'post' method: 'post'
}) })
} }
// /vet/product/cancelAudit/{id}取消审核
// 取消审核
export function cancelAuditProduct(id) { export function cancelAuditProduct(id) {
return request({ return request({
url: '/vet/product/cancelAudit/' + id, url: '/vet/product/cancelAudit/' + id,
method: 'post' method: 'post'
}) })
} }
// /vet/product/audit/list 管理员查询所有产品信息列表
// 管理员查询所有产品信息列表
export function listAuditProduct(query) { export function listAuditProduct(query) {
return request({ return request({
url: '/vet/product/audit/list', url: '/vet/product/audit/list',
@ -82,7 +83,8 @@ export function listAuditProduct(query) {
params: query params: query
}) })
} }
// /vet/product/batchSubmitAudit/{shopId}批量提交产品审核(按商家)
// 批量提交产品审核(按商家)
export function batchSubmitAuditProduct(shopId) { export function batchSubmitAuditProduct(shopId) {
return request({ return request({
url: '/vet/product/batchSubmitAudit/' + shopId, url: '/vet/product/batchSubmitAudit/' + shopId,
@ -90,7 +92,7 @@ export function batchSubmitAuditProduct(shopId) {
}) })
} }
// /vet/product/resubmitAudit/{id}产品重新提交审核
// 产品重新提交审核
export function resubmitAuditProduct(id) { export function resubmitAuditProduct(id) {
return request({ return request({
url: '/vet/product/resubmitAudit/' + id, url: '/vet/product/resubmitAudit/' + id,
@ -98,3 +100,22 @@ export function resubmitAuditProduct(id) {
}) })
} }
// 审核产品(单个审核)
export function auditProduct(data) {
// data 应该包含 { id, auditStatus, auditOpinion }
return request({
url: '/vet/product/audit',
method: 'post',
data: data
})
}
// 批量审核产品
export function batchAuditProduct(data) {
// data 应该包含 { ids, auditStatus, auditOpinion }
return request({
url: '/vet/product/batch-audit',
method: 'post',
data: data
})
}

42
chenhai-ui/src/views/vet/knowledge/index.vue

@ -81,17 +81,17 @@
v-hasPermi="['vet:knowledge:add']" v-hasPermi="['vet:knowledge:add']"
>发布文章</el-button> >发布文章</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-s-promotion"
size="mini"
:disabled="single"
@click="handleSubmitAudit"
v-hasPermi="['vet:knowledge:submit']"
>提交审核</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="info"-->
<!-- plain-->
<!-- icon="el-icon-s-promotion"-->
<!-- size="mini"-->
<!-- :disabled="single"-->
<!-- @click="handleSubmitAudit"-->
<!-- v-hasPermi="['vet:knowledge:submit']"-->
<!-- >提交审核</el-button>-->
<!-- </el-col>-->
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="primary" type="primary"
@ -216,16 +216,16 @@
v-if="scope.row.articleStatus === '0' && scope.row.auditStatus === '0'" v-if="scope.row.articleStatus === '0' && scope.row.auditStatus === '0'"
class="info-btn alter-btn" class="info-btn alter-btn"
>修改</el-button> >修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-s-promotion"
style="color: #dab708"
@click="handleSubmitAudit(scope.row.id)"
v-hasPermi="['vet:knowledge:submit']"
v-if="scope.row.articleStatus === '0' && scope.row.auditStatus === '0'"
class="info-btn submit-btn"
>提交审核</el-button>
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-s-promotion"-->
<!-- style="color: #dab708"-->
<!-- @click="handleSubmitAudit(scope.row.id)"-->
<!-- v-hasPermi="['vet:knowledge:submit']"-->
<!-- v-if="scope.row.articleStatus === '0' && scope.row.auditStatus === '0'"-->
<!-- class="info-btn submit-btn"-->
<!-- >提交审核</el-button>-->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"

584
chenhai-ui/src/views/vet/merchant/index.vue

@ -25,38 +25,6 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<!-- <el-form-item label="关联用户ID" prop="userId">-->
<!-- <el-input-->
<!-- v-model="queryParams.userId"-->
<!-- placeholder="请输入关联用户ID"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="创建时间" prop="createdAt">-->
<!-- <el-date-picker clearable-->
<!-- v-model="queryParams.createdAt"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择创建时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="更新时间" prop="updatedAt">-->
<!-- <el-date-picker clearable-->
<!-- v-model="queryParams.updatedAt"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择更新时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否启用" prop="isActive">-->
<!-- <el-input-->
<!-- v-model="queryParams.isActive"-->
<!-- placeholder="请输入是否启用"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@ -74,6 +42,18 @@
v-hasPermi="['vet:merchant:add']" v-hasPermi="['vet:merchant:add']"
>店铺资质</el-button> >店铺资质</el-button>
</el-col> </el-col>
<!-- 审核按钮 -->
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-finished"
size="mini"
:disabled="single"
@click="handleAuditDialog"
v-hasPermi="['vet:merchant:audit']"
>审核</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="success" type="success"
@ -111,50 +91,47 @@
<el-table v-loading="loading" :data="merchantList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="merchantList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="店铺ID,主键" align="center" prop="shopId" />-->
<el-table-column label="店铺logo" align="center" prop="shopLogo" width="100"> <el-table-column label="店铺logo" align="center" prop="shopLogo" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<image-preview :src="scope.row.shopLogo" :width="50" :height="50"/> <image-preview :src="scope.row.shopLogo" :width="50" :height="50"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="店铺名称" align="center" prop="shopName"/>
<el-table-column label="店铺名称" align="center" prop="shopName" min-width="120" show-overflow-tooltip/>
<el-table-column label="店铺地址" align="center" prop="shopAddress" width="150" :show-overflow-tooltip="true"/> <el-table-column label="店铺地址" align="center" prop="shopAddress" width="150" :show-overflow-tooltip="true"/>
<el-table-column label="联系电话" align="center" prop="phone" width="200"/>
<el-table-column label="联系电话" align="center" prop="phone" width="120"/>
<el-table-column label="营业执照" align="center" prop="businessLicenseImage" width="100"> <el-table-column label="营业执照" align="center" prop="businessLicenseImage" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<image-preview :src="scope.row.businessLicenseImage" :width="50" :height="50"/> <image-preview :src="scope.row.businessLicenseImage" :width="50" :height="50"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="审核状态" prop="auditStatus" width="120" align="center">
<!-- 产品数量列 -->
<el-table-column label="产品数量" align="center" width="100">
<template slot-scope="scope">
<el-tag size="small" :type="scope.row.productCount > 0 ? 'success' : 'info'">
{{ scope.row.productCount || 0 }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="审核状态" prop="auditStatus" width="100" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="getAuditStatusTagType(scope.row.auditStatus)" size="small"> <el-tag :type="getAuditStatusTagType(scope.row.auditStatus)" size="small">
{{ getAuditStatusText(scope.row.auditStatus) }} {{ getAuditStatusText(scope.row.auditStatus) }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="关联用户ID" align="center" prop="userId" />-->
<!-- <el-table-column label="创建时间" align="center" prop="createdAt" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="更新时间" align="center" prop="updatedAt" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <span>{{ parseTime(scope.row.updatedAt, '{y}-{m}-{d}') }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="是否启用" align="center" prop="isActive"/>-->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="300">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="350">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 查看产品按钮 - 审核通过后才显示 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-view" icon="el-icon-view"
@click="handleView(scope.row)"
@click="handleViewProducts(scope.row)"
class="info-btn view-btn" class="info-btn view-btn"
v-if="scope.row.auditStatus === '2'" v-if="scope.row.auditStatus === '2'"
>详情</el-button>
>查看产品</el-button>
<!-- 修改按钮 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -165,6 +142,7 @@
v-if="scope.row.auditStatus === '0' || scope.row.auditStatus === '3'" v-if="scope.row.auditStatus === '0' || scope.row.auditStatus === '3'"
class="info-btn alter-btn" class="info-btn alter-btn"
>修改</el-button> >修改</el-button>
<!-- 删除按钮 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -174,6 +152,18 @@
v-hasPermi="['vet:merchant:remove']" v-hasPermi="['vet:merchant:remove']"
class="info-btn delete-btn" class="info-btn delete-btn"
>删除</el-button> >删除</el-button>
<!-- 审核按钮管理员可见审核中状态 -->
<el-button
size="mini"
type="text"
icon="el-icon-finished"
style="color: #072eed"
@click="handleSingleAudit(scope.row)"
v-hasPermi="['vet:merchant:audit']"
v-if="scope.row.auditStatus === '1' && isAdmin"
class="info-btn audit-btn"
>审核</el-button>
<!-- 提交审核按钮待审核状态 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -183,9 +173,8 @@
v-hasPermi="['vet:product:submit']" v-hasPermi="['vet:product:submit']"
v-if="scope.row.auditStatus === '0'" v-if="scope.row.auditStatus === '0'"
class="info-btn submit-btn" class="info-btn submit-btn"
>
提交审核
</el-button>
>提交审核</el-button>
<!-- 取消审核按钮审核中状态非管理员可见 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -193,11 +182,10 @@
style="color: #5607b3" style="color: #5607b3"
@click="handleCancelAudit(scope.row)" @click="handleCancelAudit(scope.row)"
v-hasPermi="['vet:product:edit']" v-hasPermi="['vet:product:edit']"
v-if="scope.row.auditStatus === '1'"
v-if="scope.row.auditStatus === '1' && !isAdmin"
class="info-btn cancel-btn" class="info-btn cancel-btn"
>
取消审核
</el-button>
>取消审核</el-button>
<!-- 重新提交按钮审核拒绝状态 -->
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -207,9 +195,7 @@
v-hasPermi="['vet:product:submit']" v-hasPermi="['vet:product:submit']"
v-if="scope.row.auditStatus === '3'" v-if="scope.row.auditStatus === '3'"
class="info-btn resubmit-btn" class="info-btn resubmit-btn"
>
重新提交
</el-button>
>重新提交</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -240,28 +226,6 @@
<el-form-item label="营业执照" prop="businessLicenseImage"> <el-form-item label="营业执照" prop="businessLicenseImage">
<image-upload :limit=1 v-model="form.businessLicenseImage"/> <image-upload :limit=1 v-model="form.businessLicenseImage"/>
</el-form-item> </el-form-item>
<!-- <el-form-item label="关联用户ID" prop="userId">-->
<!-- <el-input v-model="form.userId" placeholder="请输入关联用户ID" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="创建时间" prop="createdAt">-->
<!-- <el-date-picker clearable-->
<!-- v-model="form.createdAt"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择创建时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="更新时间" prop="updatedAt">-->
<!-- <el-date-picker clearable-->
<!-- v-model="form.updatedAt"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择更新时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否启用" prop="isActive">-->
<!-- <el-input v-model="form.isActive" placeholder="请输入是否启用" />-->
<!-- </el-form-item>-->
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
@ -269,26 +233,129 @@
</div> </div>
</el-dialog> </el-dialog>
<!-- 详情弹窗 -->
<!-- 店铺产品列表弹窗 -->
<el-dialog <el-dialog
title="产品信息"
:visible.sync="replyOpen"
width="80%"
:title="'【' + currentShopName + '】的产品列表'"
:visible.sync="productDialogVisible"
width="95%"
append-to-body append-to-body
:close-on-click-modal="false" :close-on-click-modal="false"
@closed="handleProductDialogClose"
destroy-on-close
> >
<!-- 传递 shopId 给产品组件 -->
<product-list <product-list
:shop-id="shopId"
v-if="replyOpen"
v-if="productDialogVisible"
:shop-id="currentShopId"
:shop-name="currentShopName"
:key="'product_' + currentShopId + '_' + new Date().getTime()"
/> />
</el-dialog> </el-dialog>
<!-- 单个审核对话框 -->
<el-dialog
title="商家审核"
:visible.sync="auditDialogVisible"
width="500px"
append-to-body
:close-on-click-modal="false"
@closed="resetAuditForm"
>
<el-form ref="auditFormRef" :model="auditForm" :rules="auditRules" label-width="80px">
<el-form-item label="审核结果" prop="auditStatus">
<el-radio-group v-model="auditForm.auditStatus">
<el-radio
v-for="item in auditStatusOptions"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审核意见" prop="auditOpinion">
<el-input
v-model="auditForm.auditOpinion"
type="textarea"
:rows="4"
placeholder="请输入审核意见(审核拒绝时必须填写)"
maxlength="500"
show-word-limit
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitAudit" :loading="auditLoading"> </el-button>
<el-button @click="cancelAudit"> </el-button>
</div>
</el-dialog>
<!-- 批量审核对话框 -->
<el-dialog
title="批量审核商家"
:visible.sync="batchAuditDialogVisible"
width="500px"
append-to-body
:close-on-click-modal="false"
@closed="resetBatchAuditForm"
>
<el-form ref="batchAuditFormRef" :model="batchAuditForm" :rules="batchAuditRules" label-width="80px">
<el-form-item label="审核结果" prop="auditStatus">
<el-radio-group v-model="batchAuditForm.auditStatus">
<el-radio
v-for="item in auditStatusOptions"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审核意见" prop="auditOpinion">
<el-input
v-model="batchAuditForm.auditOpinion"
type="textarea"
:rows="4"
placeholder="请输入审核意见(审核拒绝时必须填写)"
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-alert
v-if="batchAuditForm.shopIds.length > 0"
type="info"
:closable="false"
style="margin-top: 10px;"
>
已选择 {{ batchAuditForm.shopIds.length }} 个商家进行批量审核
</el-alert>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitBatchAudit" :loading="batchAuditLoading"> </el-button>
<el-button @click="cancelBatchAudit"> </el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { listMerchant, getMerchant, delMerchant, addMerchant, updateMerchant, submitAudit, resubmitAudit, cancelAudit } from "@/api/vet/merchant"
import {
listMerchant,
getMerchant,
delMerchant,
addMerchant,
updateMerchant,
submitAudit,
resubmitAudit,
cancelAudit,
auditMerchant,
batchAuditMerchant
} from "@/api/vet/merchant"
import ProductList from '@/views/vet/product/index.vue' import ProductList from '@/views/vet/product/index.vue'
export default { export default {
@ -300,7 +367,9 @@ export default {
return { return {
// //
loading: true, loading: true,
shopId:null,
//
currentShopId: null,
currentShopName: '',
// //
ids: [], ids: [],
// //
@ -317,8 +386,11 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
replyOpen: false,
//
productDialogVisible: false,
//
isAdmin: false,
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -331,8 +403,10 @@ export default {
updatedAt: null, updatedAt: null,
isActive: null isActive: null
}, },
// //
form: {}, form: {},
// //
rules: { rules: {
shopName: [ shopName: [
@ -340,23 +414,73 @@ export default {
], ],
shopAddress: [ shopAddress: [
{ required: true, message: "店铺地址不能为空", trigger: "blur" } { required: true, message: "店铺地址不能为空", trigger: "blur" }
],
userId: [
{ required: true, message: "关联用户ID不能为空", trigger: "blur" }
],
createdAt: [
{ required: true, message: "创建时间不能为空", trigger: "blur" }
],
updatedAt: [
{ required: true, message: "更新时间不能为空", trigger: "blur" }
],
}
]
},
//
auditDialogVisible: false,
auditForm: {
shopId: null,
auditStatus: '2',
auditOpinion: ''
},
auditStatusOptions: [
{ value: '2', label: '审核通过', type: 'success' },
{ value: '3', label: '审核拒绝', type: 'danger' }
],
auditRules: {
auditOpinion: [
{
validator: (rule, value, callback) => {
if (this.auditForm.auditStatus === '3' && (!value || value.trim() === '')) {
callback(new Error('审核拒绝时必须填写审核意见'))
} else {
callback()
}
},
trigger: 'blur'
}
]
},
auditLoading: false,
//
batchAuditDialogVisible: false,
batchAuditForm: {
shopIds: [],
auditStatus: '2',
auditOpinion: ''
},
batchAuditRules: {
auditOpinion: [
{
validator: (rule, value, callback) => {
if (this.batchAuditForm.auditStatus === '3' && (!value || value.trim() === '')) {
callback(new Error('审核拒绝时必须填写审核意见'))
} else {
callback()
}
},
trigger: 'blur'
}
]
},
batchAuditLoading: false
} }
}, },
created() { created() {
this.getList() this.getList()
this.checkAdminRole()
}, },
methods: { methods: {
/** 检查是否是管理员 */
checkAdminRole() {
const userInfo = this.$store.getters.userInfo || {}
this.isAdmin = userInfo.roles && userInfo.roles.includes('admin')
},
/** 查询商家信息列表 */ /** 查询商家信息列表 */
getList() { getList() {
this.loading = true this.loading = true
@ -366,11 +490,13 @@ export default {
this.loading = false this.loading = false
}) })
}, },
// //
cancel() { cancel() {
this.open = false this.open = false
this.reset() this.reset()
}, },
// //
reset() { reset() {
this.form = { this.form = {
@ -385,30 +511,42 @@ export default {
} }
this.resetForm("form") this.resetForm("form")
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1 this.queryParams.pageNum = 1
this.getList() this.getList()
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
this.resetForm("queryForm") this.resetForm("queryForm")
this.handleQuery() this.handleQuery()
}, },
// //
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.shopId) this.ids = selection.map(item => item.shopId)
this.single = selection.length!==1
this.single = selection.length !== 1
this.multiple = !selection.length this.multiple = !selection.length
}, },
//
handleView(row) {
console.log('查看的店铺信息:', row)
console.log('shopId:', row.shopId)
this.shopRow = row
this.shopId = row.shopId
this.replyOpen = true
/** 查看店铺产品 */
handleViewProducts(row) {
// shopId
this.currentShopId = Number(row.shopId);
this.currentShopName = row.shopName;
this.productDialogVisible = true;
},
/** 关闭产品对话框 */
handleProductDialogClose() {
console.log('关闭产品对话框');
this.productDialogVisible = false;
this.currentShopId = null;
this.currentShopName = '';
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
@ -417,6 +555,7 @@ export default {
this.open = true this.open = true
this.title = "添加商家信息" this.title = "添加商家信息"
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset() this.reset()
@ -427,6 +566,7 @@ export default {
this.title = "修改商家信息" this.title = "修改商家信息"
}) })
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
@ -447,16 +587,18 @@ export default {
} }
}) })
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const shopIds = row.shopId || this.ids const shopIds = row.shopId || this.ids
this.$modal.confirm('是否确认删除商家信息编号为"' + shopIds + '"的数据项?').then(function() {
this.$modal.confirm('是否确认删除商家信息编号为"' + shopIds + '"的数据项?').then(() => {
return delMerchant(shopIds) return delMerchant(shopIds)
}).then(() => { }).then(() => {
this.getList() this.getList()
this.$modal.msgSuccess("删除成功") this.$modal.msgSuccess("删除成功")
}).catch(() => {}) }).catch(() => {})
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('vet/merchant/export', { this.download('vet/merchant/export', {
@ -488,26 +630,226 @@ export default {
// //
handleSubmitAudit(row) { handleSubmitAudit(row) {
submitAudit(row.shopId).then(response => {
this.$confirm('是否确认提交审核?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
return submitAudit(row.shopId)
}).then(response => {
this.$modal.msgSuccess("提交成功") this.$modal.msgSuccess("提交成功")
this.getList() this.getList()
})
}).catch(() => {})
}, },
// //
handleCancelAudit(row) { handleCancelAudit(row) {
cancelAudit(row.shopId).then(response => {
this.$confirm('确定要取消审核吗?取消后可以重新提交审核', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
return cancelAudit(row.shopId)
}).then(response => {
this.$modal.msgSuccess("取消成功") this.$modal.msgSuccess("取消成功")
this.getList() this.getList()
})
}).catch(() => {})
}, },
// //
handleResubmitAudit(row) { handleResubmitAudit(row) {
resubmitAudit(row.shopId).then(response => {
this.$confirm('是否确认重新提交审核?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
return resubmitAudit(row.shopId)
}).then(response => {
this.$modal.msgSuccess("重新提交成功") this.$modal.msgSuccess("重新提交成功")
this.getList() this.getList()
})
}).catch(() => {})
},
/** 打开审核对话框(顶部按钮点击) */
handleAuditDialog() {
if (this.ids.length === 0) {
this.$message.warning('请至少选择一个需要审核的商家')
return
}
if (this.ids.length === 1) {
//
const shopId = this.ids[0]
const shop = this.merchantList.find(item => item.shopId === shopId)
if (shop && shop.auditStatus !== '1') {
this.$message.warning('只有审核中的商家才能进行审核操作')
return
}
this.handleSingleAudit({ shopId })
} else {
//
this.handleBatchAudit()
}
},
/** 单个审核 */
handleSingleAudit(row) {
const shopId = row.shopId || row
//
if (row.auditStatus && row.auditStatus !== '1') {
this.$message.warning('只有审核中的商家才能进行审核操作')
return
}
this.auditForm = {
shopId: shopId,
auditStatus: '2',
auditOpinion: ''
}
this.auditDialogVisible = true
},
/** 批量审核 */
handleBatchAudit() {
//
const auditShops = this.merchantList.filter(item =>
this.ids.includes(item.shopId) && item.auditStatus === '1'
)
if (auditShops.length === 0) {
this.$message.warning('选中的商家中没有审核中的商家')
return
}
if (auditShops.length < this.ids.length) {
this.$message.warning('部分选中的商家不是审核中状态,将只对审核中的商家进行审核')
}
this.batchAuditForm = {
shopIds: auditShops.map(item => item.shopId),
auditStatus: '2',
auditOpinion: ''
}
this.batchAuditDialogVisible = true
},
/** 提交单个审核 */
async submitAudit() {
try {
await this.$refs.auditFormRef.validate()
const message = this.auditForm.auditStatus === '2'
? '是否确认审核通过该商家?'
: '是否确认审核拒绝该商家?'
await this.$confirm(message, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
this.auditLoading = true
const response = await auditMerchant({
shopId: this.auditForm.shopId,
auditStatus: this.auditForm.auditStatus,
auditOpinion: this.auditForm.auditOpinion || ''
})
if (response.code === 200) {
this.$message.success('审核成功')
this.auditDialogVisible = false
this.getList()
} else {
this.$message.error(response.msg || '审核失败')
}
} catch (error) {
if (error === 'cancel') return
console.error('审核错误:', error)
this.$message.error('审核失败:' + (error.message || '未知错误'))
} finally {
this.auditLoading = false
}
},
/** 提交批量审核 */
async submitBatchAudit() {
try {
await this.$refs.batchAuditFormRef.validate()
const message = this.batchAuditForm.auditStatus === '2'
? `是否确认审核通过选中的 ${this.batchAuditForm.shopIds.length} 个商家?`
: `是否确认审核拒绝选中的 ${this.batchAuditForm.shopIds.length} 个商家?`
await this.$confirm(message, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
this.batchAuditLoading = true
const response = await batchAuditMerchant({
shopIds: this.batchAuditForm.shopIds,
auditStatus: this.batchAuditForm.auditStatus,
auditOpinion: this.batchAuditForm.auditOpinion || ''
})
if (response.code === 200) {
this.$message.success(`批量审核成功,${response.msg || ''}`)
this.batchAuditDialogVisible = false
this.getList()
} else {
this.$message.error(response.msg || '批量审核失败')
}
} catch (error) {
if (error === 'cancel') return
console.error('批量审核错误:', error)
this.$message.error('批量审核失败:' + (error.message || '未知错误'))
} finally {
this.batchAuditLoading = false
}
},
/** 关闭审核对话框 */
cancelAudit() {
this.auditDialogVisible = false
this.resetAuditForm()
},
/** 关闭批量审核对话框 */
cancelBatchAudit() {
this.batchAuditDialogVisible = false
this.resetBatchAuditForm()
},
/** 重置审核表单 */
resetAuditForm() {
this.auditForm = {
shopId: null,
auditStatus: '2',
auditOpinion: ''
}
if (this.$refs.auditFormRef) {
this.$nextTick(() => {
this.$refs.auditFormRef.clearValidate()
})
}
},
/** 重置批量审核表单 */
resetBatchAuditForm() {
this.batchAuditForm = {
shopIds: [],
auditStatus: '2',
auditOpinion: ''
}
if (this.$refs.batchAuditFormRef) {
this.$nextTick(() => {
this.$refs.batchAuditFormRef.clearValidate()
})
}
} }
} }
} }

848
chenhai-ui/src/views/vet/product/index.vue
File diff suppressed because it is too large
View File

Loading…
Cancel
Save