Compare commits
13 Commits
941351d432
...
b386ef9106
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b386ef9106 | ||
|
|
cace0eb2f5 | ||
| 96d606afe9 | |||
| 6554cb5f61 | |||
| ccbf6ea777 | |||
| d6f73bc1b0 | |||
| a09c3224ed | |||
| 3477ca2eaf | |||
| cb83cc03f3 | |||
| 995a147502 | |||
|
|
7068df5eda | ||
| 2e68209ed1 | |||
| 7a2f9c4225 |
4
seer-admin/Jenkinsfile
vendored
4
seer-admin/Jenkinsfile
vendored
@ -7,7 +7,9 @@ pipeline {
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'DEPLOY_SERVERS'
|
||||
name: 'DEPLOY_SERVERS',
|
||||
defaultValue: '192.168.0.212',
|
||||
description: '部署的目标服务器,多个目标服务器以英文逗号分隔,如:192.168.0.212,192.168.0.47,192.168.0.79'
|
||||
)
|
||||
choice(
|
||||
name: 'spring.profiles.active',
|
||||
|
||||
@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = ApiConstants.SERVER_NAME, contextId = "wechatMiniProgramApi", path = "/seer/mp")
|
||||
public interface WechatMiniProgramApi {
|
||||
public interface MpMiniProgramApi {
|
||||
|
||||
@GetMapping("/wechat/sns/jscode2session")
|
||||
WxMiniProgramSessionDTO code2Session(@RequestParam("code") String code);
|
||||
@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = ApiConstants.SERVER_NAME, contextId = "wechatOfficialAccountApi", path = "/seer/mp")
|
||||
public interface WechatOfficialAccountApi {
|
||||
public interface MpOfficialAccountApi {
|
||||
|
||||
/**
|
||||
* 获取用户用户信息和授权 Token
|
||||
@ -0,0 +1,77 @@
|
||||
package com.seer.teach.mp.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.seer.teach.common.entity.BaseEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公众号菜单表
|
||||
* </p>
|
||||
*
|
||||
* @author Lingma
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("mp_account_menu")
|
||||
@Schema(name = "MpAccountMenuEntity", description = "公众号菜单表")
|
||||
public class MpAccountMenuEntity extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "公众号账号ID")
|
||||
@TableField("account_id")
|
||||
private Integer accountId;
|
||||
|
||||
@Schema(description = "菜单名称")
|
||||
@TableField("name")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "菜单类型")
|
||||
@TableField("type")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "菜单KEY值")
|
||||
@TableField("menu_key")
|
||||
private String menuKey;
|
||||
|
||||
@Schema(description = "菜单URL")
|
||||
@TableField("url")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "媒体文件ID")
|
||||
@TableField("media_id")
|
||||
private String mediaId;
|
||||
|
||||
@Schema(description = "小程序APPID")
|
||||
@TableField("appid")
|
||||
private String appid;
|
||||
|
||||
@Schema(description = "小程序页面路径")
|
||||
@TableField("pagepath")
|
||||
private String pagepath;
|
||||
|
||||
@Schema(description = "文章ID")
|
||||
@TableField("article_id")
|
||||
private String articleId;
|
||||
|
||||
@Schema(description = "父菜单ID,0表示一级菜单")
|
||||
@TableField("parent_id")
|
||||
private Integer parentId;
|
||||
|
||||
@Schema(description = "菜单JSON配置")
|
||||
@TableField("menu_config")
|
||||
private String menuConfig;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@TableField("sort")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:0-禁用,1-启用")
|
||||
@TableField("status")
|
||||
private Integer status;
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.seer.teach.mp.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 活动时间状态枚举
|
||||
* </p>
|
||||
*
|
||||
* @author Lingma
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
@Getter
|
||||
public enum ActivityTimeStatusEnum {
|
||||
|
||||
NOT_STARTED(-1, "未开始"),
|
||||
IN_PROGRESS(1, "进行中"),
|
||||
ENDED(2, "已结束");
|
||||
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
|
||||
ActivityTimeStatusEnum(Integer code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取枚举
|
||||
*/
|
||||
public static ActivityTimeStatusEnum fromCode(Integer code) {
|
||||
for (ActivityTimeStatusEnum status : ActivityTimeStatusEnum.values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.seer.teach.mp.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.seer.teach.mp.entity.MpAccountMenuEntity;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公众号菜单表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Lingma
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
public interface MpAccountMenuMapper extends BaseMapper<MpAccountMenuEntity> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.seer.teach.mp.admin.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.seer.teach.common.ResultBean;
|
||||
import com.seer.teach.mp.admin.controller.req.MpMenuSaveReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminMpMenuResp;
|
||||
import com.seer.teach.mp.admin.service.AdminMpAccountMenuService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公众号菜单表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Wang
|
||||
* @since 2025-08-02 15:45:13
|
||||
*/
|
||||
@Tag(name = "管理端 - 公众号菜单")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/mp/account/menu")
|
||||
public class AdminMpAccountMenuController {
|
||||
|
||||
private final AdminMpAccountMenuService adminMpAccountMenuService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建公众号菜单")
|
||||
@SaCheckPermission("admin:mp:account:menu:create")
|
||||
public ResultBean<Boolean> createAccountMenu(@Valid @RequestBody MpMenuSaveReq createReqVO) {
|
||||
return ResultBean.success(adminMpAccountMenuService.createAccountMenu(createReqVO));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除公众号菜单")
|
||||
@SaCheckPermission("admin:mp:account:menu:delete")
|
||||
public ResultBean<Boolean> deleteMenu(@RequestParam("accountId") Integer accountId) {
|
||||
return ResultBean.success(adminMpAccountMenuService.deleteMenuByAppId(accountId));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获取公众号菜单列表")
|
||||
@SaCheckPermission("admin:mp:account:menu:list")
|
||||
public ResultBean<List<AdminMpMenuResp>> getMenuList(@RequestParam("accountId") Integer accountId) {
|
||||
return ResultBean.success(adminMpAccountMenuService.getMenuList(accountId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,6 +11,6 @@ public class MpActivityQueryReq extends PageRequest {
|
||||
@Schema(description = "活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "活动状态:0-禁用,1-启用")
|
||||
@Schema(description = "活动状态:-1-未开始,1-进行中,2-已结束")
|
||||
private Integer status;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package com.seer.teach.mp.admin.controller.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "公众号菜单保存请求")
|
||||
@Data
|
||||
public class MpMenuSaveReq {
|
||||
|
||||
@Schema(description = "公众号ID", required = true)
|
||||
@NotNull(message = "公众号ID不能为空")
|
||||
private Integer accountId;
|
||||
|
||||
@Schema(description = "菜单配置JSON字符串")
|
||||
@Valid
|
||||
private List<Button> button;
|
||||
|
||||
@Schema(description = "菜单按钮结构")
|
||||
@Data
|
||||
public static class Button {
|
||||
|
||||
@Schema(description = "菜单的响应动作类型", example = "click")
|
||||
@Size(max = 32, message = "菜单类型长度不能超过32个字符")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "菜单标题", required = true, example = "今日歌曲")
|
||||
@NotBlank(message = "菜单标题不能为空")
|
||||
@Size(max = 60, message = "菜单标题长度不能超过60个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "菜单KEY值", example = "V1001_TODAY_MUSIC")
|
||||
@Size(max = 128, message = "菜单KEY值长度不能超过128个字符")
|
||||
private String key;
|
||||
|
||||
@Schema(description = "网页链接", example = "http://www.soso.com/")
|
||||
@Size(max = 1024, message = "网页链接长度不能超过1024个字符")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "媒体文件ID", example = "MEDIA_ID1")
|
||||
@Size(max = 128, message = "媒体文件ID长度不能超过128个字符")
|
||||
private String mediaId;
|
||||
|
||||
@Schema(description = "小程序的appid", example = "wx286b93c14bbf93aa")
|
||||
@Size(max = 32, message = "小程序appid长度不能超过32个字符")
|
||||
private String appid;
|
||||
|
||||
@Schema(description = "小程序的页面路径", example = "pages/lunar/index")
|
||||
@Size(max = 128, message = "小程序页面路径长度不能超过128个字符")
|
||||
private String pagepath;
|
||||
|
||||
@Schema(description = "发布后获得的合法 article_id", example = "ARTICLE_ID1")
|
||||
@Size(max = 128, message = "文章ID长度不能超过128个字符")
|
||||
private String articleId;
|
||||
|
||||
@Schema(description = "二级菜单结构体数组")
|
||||
@Valid
|
||||
private List<Button> subButton;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.seer.teach.mp.admin.controller.resp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "公众号菜单响应")
|
||||
@Data
|
||||
public class AdminMpMenuResp {
|
||||
|
||||
@Schema(description = "菜单ID")
|
||||
private Integer id;
|
||||
|
||||
@Schema(description = "公众号账号ID")
|
||||
private Integer accountId;
|
||||
|
||||
@Schema(description = "菜单名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "菜单类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "菜单KEY值")
|
||||
private String menuKey;
|
||||
|
||||
@Schema(description = "菜单URL")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "媒体文件ID")
|
||||
private String mediaId;
|
||||
|
||||
@Schema(description = "小程序APPID")
|
||||
private String appid;
|
||||
|
||||
@Schema(description = "小程序页面路径")
|
||||
private String pagepath;
|
||||
|
||||
@Schema(description = "文章ID")
|
||||
private String articleId;
|
||||
|
||||
@Schema(description = "父菜单ID")
|
||||
private Integer parentId;
|
||||
|
||||
@Schema(description = "菜单JSON配置")
|
||||
private String menuConfig;
|
||||
|
||||
@Schema(description = "排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:0-禁用,1-启用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "子菜单列表")
|
||||
private List<AdminMpMenuResp> subMenus;
|
||||
}
|
||||
@ -0,0 +1,264 @@
|
||||
package com.seer.teach.mp.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.seer.teach.mp.admin.controller.req.MpMenuSaveReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminMpMenuResp;
|
||||
import com.seer.teach.mp.entity.MpAccountEntity;
|
||||
import com.seer.teach.mp.entity.MpAccountMenuEntity;
|
||||
import com.seer.teach.mp.factory.MpServiceFactory;
|
||||
import com.seer.teach.mp.service.IMpAccountService;
|
||||
import com.seer.teach.mp.service.IMpAccountMenuService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.bean.menu.WxMenu;
|
||||
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Validated
|
||||
@Service
|
||||
public class AdminMpAccountMenuService {
|
||||
|
||||
private final IMpAccountService mpAccountService;
|
||||
|
||||
private final IMpAccountMenuService mpMenuService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private MpServiceFactory mpServiceFactory;
|
||||
|
||||
/**
|
||||
* 创建公众号菜单
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 是否创建成功
|
||||
*/
|
||||
public boolean createAccountMenu(@Valid MpMenuSaveReq createReqVO) {
|
||||
// 验证公众号是否存在
|
||||
MpAccountEntity account = mpAccountService.getById(createReqVO.getAccountId());
|
||||
if (account == null) {
|
||||
throw new RuntimeException("公众号不存在");
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取微信公众号服务
|
||||
WxMpService wxMpService = mpServiceFactory.getRequiredMpService(account.getAppId());
|
||||
|
||||
// 构建微信菜单对象
|
||||
WxMenu wxMpMenu = buildWxMpMenu(createReqVO);
|
||||
|
||||
// 调用微信API创建菜单
|
||||
wxMpService.getMenuService().menuCreate(wxMpMenu);
|
||||
|
||||
// 保存菜单配置到数据库
|
||||
saveMenuToDatabase(createReqVO, account);
|
||||
|
||||
log.info("[createAccount][创建公众号菜单成功,公众号ID为:{}]", account.getId());
|
||||
return true;
|
||||
} catch (WxErrorException e) {
|
||||
log.error("[createAccount][创建公众号菜单失败,公众号ID为:{}],错误信息:{}",
|
||||
createReqVO.getAccountId(), e.getError().getErrorMsg());
|
||||
throw new RuntimeException("创建公众号菜单失败:" + e.getError().getErrorMsg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建微信菜单对象
|
||||
*/
|
||||
private WxMenu buildWxMpMenu(MpMenuSaveReq createReqVO) {
|
||||
WxMenu wxMpMenu = new WxMenu();
|
||||
List<WxMenuButton> buttons = new ArrayList<>();
|
||||
|
||||
for (MpMenuSaveReq.Button button : createReqVO.getButton()) {
|
||||
buttons.add(convertToWxMpButton(button));
|
||||
}
|
||||
|
||||
wxMpMenu.setButtons(buttons);
|
||||
return wxMpMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将请求按钮转换为微信菜单按钮对象
|
||||
*/
|
||||
private WxMenuButton convertToWxMpButton(MpMenuSaveReq.Button button) {
|
||||
WxMenuButton wxButton = new WxMenuButton();
|
||||
wxButton.setType(button.getType());
|
||||
wxButton.setName(button.getName());
|
||||
|
||||
// 根据按钮类型设置相应属性
|
||||
if ("click".equalsIgnoreCase(button.getType())) {
|
||||
wxButton.setKey(button.getKey());
|
||||
} else if ("view".equalsIgnoreCase(button.getType())) {
|
||||
wxButton.setUrl(button.getUrl());
|
||||
} else if ("miniprogram".equalsIgnoreCase(button.getType())) {
|
||||
wxButton.setAppId(button.getAppid());
|
||||
wxButton.setPagePath(button.getPagepath());
|
||||
wxButton.setUrl(button.getUrl()); // 备用URL
|
||||
} else if ("media_id".equalsIgnoreCase(button.getType()) ||
|
||||
"view_limited".equalsIgnoreCase(button.getType())) {
|
||||
wxButton.setMediaId(button.getMediaId());
|
||||
} else if ("article_id".equalsIgnoreCase(button.getType()) ||
|
||||
"article_view_limited".equalsIgnoreCase(button.getType())) {
|
||||
wxButton.setArticleId(button.getArticleId());
|
||||
} else {
|
||||
// 其他类型如扫码、拍照等,设置key值
|
||||
if (button.getKey() != null) {
|
||||
wxButton.setKey(button.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (button.getSubButton() != null && !button.getSubButton().isEmpty()) {
|
||||
List<WxMenuButton> subButtons = new ArrayList<>();
|
||||
for (MpMenuSaveReq.Button subButton : button.getSubButton()) {
|
||||
subButtons.add(convertToWxMpButton(subButton));
|
||||
}
|
||||
wxButton.setSubButtons(subButtons);
|
||||
}
|
||||
|
||||
return wxButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存菜单配置到数据库
|
||||
*/
|
||||
private void saveMenuToDatabase(MpMenuSaveReq createReqVO, MpAccountEntity account) {
|
||||
// 保存新的菜单配置
|
||||
for (int i = 0; i < createReqVO.getButton().size(); i++) {
|
||||
MpMenuSaveReq.Button button = createReqVO.getButton().get(i);
|
||||
saveButtonToDatabase(button, account, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveButtonToDatabase(MpMenuSaveReq.Button button, MpAccountEntity account, Integer parentId, Integer sort) {
|
||||
MpAccountMenuEntity menuEntity = new MpAccountMenuEntity();
|
||||
menuEntity.setAccountId(account.getId());
|
||||
menuEntity.setAppid(account.getAppId());
|
||||
menuEntity.setName(button.getName());
|
||||
menuEntity.setType(button.getType());
|
||||
menuEntity.setMenuKey(button.getKey());
|
||||
menuEntity.setUrl(button.getUrl());
|
||||
menuEntity.setMediaId(button.getMediaId());
|
||||
menuEntity.setAppid(button.getAppid());
|
||||
menuEntity.setPagepath(button.getPagepath());
|
||||
menuEntity.setArticleId(button.getArticleId());
|
||||
menuEntity.setParentId(parentId);
|
||||
menuEntity.setSort(sort);
|
||||
menuEntity.setStatus(1);
|
||||
|
||||
mpMenuService.save(menuEntity);
|
||||
|
||||
// 如果有子菜单,递归保存
|
||||
if (button.getSubButton() != null && !button.getSubButton().isEmpty()) {
|
||||
Integer currentMenuId = menuEntity.getId();
|
||||
for (int i = 0; i < button.getSubButton().size(); i++) {
|
||||
com.seer.teach.mp.admin.controller.req.MpMenuSaveReq.Button subButton = button.getSubButton().get(i);
|
||||
saveButtonToDatabase(subButton, account, currentMenuId, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号菜单列表
|
||||
*
|
||||
* @param accountId 公众号ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
public List<AdminMpMenuResp> getMenuList(Integer accountId) {
|
||||
// 查询一级菜单
|
||||
List<MpAccountMenuEntity> menus = mpMenuService.list(
|
||||
com.baomidou.mybatisplus.core.toolkit.Wrappers.<MpAccountMenuEntity>lambdaQuery()
|
||||
.eq(MpAccountMenuEntity::getAccountId, accountId)
|
||||
.eq(MpAccountMenuEntity::getParentId, 0)
|
||||
.orderByAsc(MpAccountMenuEntity::getSort)
|
||||
);
|
||||
|
||||
List<AdminMpMenuResp> result = new ArrayList<>();
|
||||
for (MpAccountMenuEntity menu : menus) {
|
||||
AdminMpMenuResp resp = convertToMenuResp(menu);
|
||||
// 查询子菜单
|
||||
List<MpAccountMenuEntity> subMenus = mpMenuService.list(
|
||||
com.baomidou.mybatisplus.core.toolkit.Wrappers.<MpAccountMenuEntity>lambdaQuery()
|
||||
.eq(MpAccountMenuEntity::getAccountId, accountId)
|
||||
.eq(MpAccountMenuEntity::getParentId, menu.getId())
|
||||
.orderByAsc(MpAccountMenuEntity::getSort)
|
||||
);
|
||||
if (!subMenus.isEmpty()) {
|
||||
resp.setSubMenus(subMenus.stream()
|
||||
.map(this::convertToMenuResp)
|
||||
.toList());
|
||||
}
|
||||
result.add(resp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除公众号菜单
|
||||
*
|
||||
* @param accountId 菜单ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
public boolean deleteMenuByAppId(Integer accountId) {
|
||||
MpAccountEntity account = mpAccountService.getById(accountId);
|
||||
if(Objects.isNull(account)){
|
||||
log.error("[deleteMenu][删除公众号菜单失败,公众号ID为:{}]", accountId);
|
||||
return false;
|
||||
}
|
||||
String appId = account.getAppId();
|
||||
try {
|
||||
WxMpService wxMpService = mpServiceFactory.getRequiredMpService(appId);
|
||||
wxMpService.getMenuService().menuDelete();
|
||||
deleteMenuRecursive(appId);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("[deleteMenu][删除公众号菜单失败,菜单AppID为:{}]", appId, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归删除菜单
|
||||
*/
|
||||
private void deleteMenuRecursive(String appId) {
|
||||
mpMenuService.removeById(new LambdaQueryWrapper<MpAccountMenuEntity>().eq(MpAccountMenuEntity::getAppid, appId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换菜单实体为响应对象
|
||||
*/
|
||||
private AdminMpMenuResp convertToMenuResp(MpAccountMenuEntity menu) {
|
||||
AdminMpMenuResp resp = new AdminMpMenuResp();
|
||||
resp.setId(menu.getId());
|
||||
resp.setAccountId(menu.getAccountId());
|
||||
resp.setName(menu.getName());
|
||||
resp.setType(menu.getType());
|
||||
resp.setMenuKey(menu.getMenuKey());
|
||||
resp.setUrl(menu.getUrl());
|
||||
resp.setMediaId(menu.getMediaId());
|
||||
resp.setAppid(menu.getAppid());
|
||||
resp.setPagepath(menu.getPagepath());
|
||||
resp.setArticleId(menu.getArticleId());
|
||||
resp.setParentId(menu.getParentId());
|
||||
resp.setMenuConfig(menu.getMenuConfig());
|
||||
resp.setSort(menu.getSort());
|
||||
resp.setStatus(menu.getStatus());
|
||||
resp.setCreateTime(menu.getCreateTime());
|
||||
resp.setUpdateTime(menu.getUpdateTime());
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.mp.api.WechatOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.MpOfficialAccountApi;
|
||||
import com.seer.teach.mp.admin.controller.req.MpAccountPageReq;
|
||||
import com.seer.teach.mp.admin.controller.req.MpAccountReq;
|
||||
import com.seer.teach.mp.admin.controller.resp.AdminMpAccountResp;
|
||||
@ -36,7 +36,7 @@ public class AdminMpAccountService {
|
||||
|
||||
private final IMpAccountService mpAccountService;
|
||||
|
||||
private final WechatOfficialAccountApi wechatOfficialAccountApi;
|
||||
private final MpOfficialAccountApi mpOfficialAccountApi;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
@ -44,7 +44,7 @@ public class AdminMpAccountService {
|
||||
|
||||
public void loadCache() {
|
||||
mpServiceFactory.init();
|
||||
wechatOfficialAccountApi.initMpAccountCache();
|
||||
mpOfficialAccountApi.initMpAccountCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,7 +12,7 @@ import com.seer.teach.mp.admin.service.IAdminActivityService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -37,7 +37,7 @@ public class AdminActivityServiceImpl implements IAdminActivityService {
|
||||
|
||||
private final IMpActivityService agentActivityService;
|
||||
|
||||
private final IMpAgentActivityParticipantService agentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService agentActivityParticipantService;
|
||||
|
||||
@Override
|
||||
public PageListBean<AdminActivityResp> pageList(MpActivityQueryReq query) {
|
||||
|
||||
@ -19,7 +19,7 @@ import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import com.seer.teach.mp.service.IMpAgentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -39,7 +39,7 @@ import java.util.List;
|
||||
@RequiredArgsConstructor
|
||||
public class AdminAgentActivityRelationServiceImpl implements IAdminAgentActivityRelationService {
|
||||
|
||||
private final IMpAgentActivityParticipantService mpAgentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService mpAgentActivityParticipantService;
|
||||
|
||||
private final IMpAgentService mpAgentService;
|
||||
|
||||
|
||||
@ -7,7 +7,9 @@ pipeline {
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'DEPLOY_SERVERS'
|
||||
name: 'DEPLOY_SERVERS',
|
||||
defaultValue: '192.168.0.212',
|
||||
description: '部署的目标服务器,多个目标服务器以英文逗号分隔,如:192.168.0.212,192.168.0.47,192.168.0.79'
|
||||
)
|
||||
choice(
|
||||
name: 'spring.profiles.active',
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
-- 创建公众号菜单表
|
||||
DROP TABLE IF EXISTS `mp_account_menu`;
|
||||
CREATE TABLE `mp_account_menu` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
|
||||
`account_id` bigint NOT NULL COMMENT '公众号账号ID',
|
||||
`name` varchar(100) NOT NULL COMMENT '菜单名称',
|
||||
`type` varchar(32) DEFAULT NULL COMMENT '菜单类型:click,view,scancode_push,scancode_waitmsg,pic_sysphoto,pic_photo_or_album,pic_weixin,location_select,media_id,article_id,article_view_limited,miniprogram等',
|
||||
`menu_key` varchar(128) DEFAULT NULL COMMENT '菜单KEY值',
|
||||
`url` varchar(1024) DEFAULT NULL COMMENT '网页链接',
|
||||
`media_id` varchar(128) DEFAULT NULL COMMENT '媒体文件ID',
|
||||
`appid` varchar(32) DEFAULT NULL COMMENT '小程序的appid',
|
||||
`pagepath` varchar(128) DEFAULT NULL COMMENT '小程序的页面路径',
|
||||
`article_id` varchar(128) DEFAULT NULL COMMENT '文章ID',
|
||||
`parent_id` int NOT NULL DEFAULT '0' COMMENT '父菜单ID,0表示一级菜单',
|
||||
`menu_config` text COMMENT '菜单JSON配置',
|
||||
`sort` int DEFAULT '0' COMMENT '排序',
|
||||
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:0-禁用,1-启用',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_account_id` (`account_id`) USING BTREE,
|
||||
KEY `idx_parent_id` (`parent_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='公众号菜单表';
|
||||
@ -8,7 +8,7 @@ import com.seer.teach.common.annotation.EncryptionAnnotation;
|
||||
import com.seer.teach.common.annotation.LogPrint;
|
||||
import com.seer.teach.mp.app.controller.req.AppMpAgentActivityQrCodeQueryReq;
|
||||
import com.seer.teach.mp.app.controller.resp.AgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.app.service.IAppAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.app.service.IAppAgentActivityRelationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -38,7 +38,7 @@ import java.util.List;
|
||||
@RequiredArgsConstructor
|
||||
public class AppAgentActivityRelationController {
|
||||
|
||||
private final IAppAgentActivityParticipantService agentActivityParticipantService;
|
||||
private final IAppAgentActivityRelationService agentActivityParticipantService;
|
||||
|
||||
@Operation(summary = "获取代理商参加的活动列表")
|
||||
@GetMapping()
|
||||
@ -52,7 +52,6 @@ public class AppAgentActivityRelationController {
|
||||
@PostMapping("/qrcode")
|
||||
@SaCheckPermission("mp:app:agent:activity:qrcode")
|
||||
public ResultBean<String> getQrCode(@RequestBody AppMpAgentActivityQrCodeQueryReq req) {
|
||||
Integer userId = StpUtil.getLoginIdAsInt();
|
||||
return ResultBean.success(agentActivityParticipantService.getQrCode(req,userId));
|
||||
return ResultBean.success(agentActivityParticipantService.getQrCode(req));
|
||||
}
|
||||
}
|
||||
@ -31,7 +31,10 @@ public class AppParentAgentActivityController {
|
||||
@SaCheckLogin
|
||||
@Operation(summary = "家长报名参加代理商活动")
|
||||
public ResultBean<Boolean> signUpForActivity(@RequestBody @Validated AppMpSignUpActivityReq request) {
|
||||
Integer parentId = StpUtil.getLoginIdAsInt();
|
||||
Integer parentId = 0;
|
||||
if (StpUtil.isLogin()) {
|
||||
parentId = StpUtil.getLoginIdAsInt();
|
||||
}
|
||||
return ResultBean.success(appParentAgentActivityService.signUpForActivityWithInfo(request, parentId));
|
||||
}
|
||||
|
||||
@ -74,4 +77,5 @@ public class AppParentAgentActivityController {
|
||||
Integer parentId = StpUtil.getLoginIdAsInt();
|
||||
return ResultBean.success(appParentAgentActivityService.getChildCharacter(parentId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,6 +11,6 @@ public class AppActivityQueryReq extends PageRequest {
|
||||
@Schema(description = "活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "活动状态:0-禁用,1-启用")
|
||||
@Schema(description = "活动状态:-1-未开始,1-进行中,2-已结束")
|
||||
private Integer status;
|
||||
}
|
||||
@ -3,6 +3,8 @@ package com.seer.teach.mp.app.controller.resp;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(name = "AgentActivityParticipant", description = "代理商活动参与记录")
|
||||
@Data
|
||||
public class AgentActivityParticipantResp {
|
||||
@ -15,7 +17,19 @@ public class AgentActivityParticipantResp {
|
||||
@Schema(description = "代理商ID")
|
||||
private Integer agentId;
|
||||
|
||||
@Schema(description = "活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Schema(description = "活动描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "活动开始时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "活动结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "活动状态:-1-未开始,1-进行中,2-已结束")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@ -23,7 +23,7 @@ public class AppActivityResp {
|
||||
@Schema(description = "活动结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "活动状态:0-禁用,1-启用")
|
||||
@Schema(description = "活动状态:-1-未开始,1-进行中,2-已结束")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
|
||||
@ -64,7 +64,7 @@ public class AppMpNotificationService {
|
||||
if (outMessage == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
log.info("[handleMessage][appId({}) 回复微信服务端的消息,内容:{}]", appId, outMessage);
|
||||
// 第三步,返回消息
|
||||
if (StrUtil.isBlank(reqVO.getEncrypt_type())) { // 明文模式
|
||||
return outMessage.toXml();
|
||||
|
||||
@ -34,7 +34,7 @@ public class AppParentAgentActivityService implements IAppParentAgentActivitySer
|
||||
|
||||
private final IMpAgentService agentService;
|
||||
|
||||
private final IMpAgentActivityParticipantService mpAgentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService mpAgentActivityParticipantService;
|
||||
|
||||
private final AiModelCallService aiModelCallService;
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import java.util.List;
|
||||
* @author Lingma
|
||||
* @since 2025-12-30
|
||||
*/
|
||||
public interface IAppAgentActivityParticipantService {
|
||||
public interface IAppAgentActivityRelationService {
|
||||
|
||||
/**
|
||||
* 根据活动ID和代理商ID获取参与记录
|
||||
@ -28,8 +28,7 @@ public interface IAppAgentActivityParticipantService {
|
||||
* 获取二维码
|
||||
*
|
||||
* @param req 请求参数
|
||||
* @param userId 用户Id
|
||||
* @return 二维码的url
|
||||
*/
|
||||
String getQrCode(AppMpAgentActivityQrCodeQueryReq req, Integer userId);
|
||||
String getQrCode(AppMpAgentActivityQrCodeQueryReq req);
|
||||
}
|
||||
@ -5,21 +5,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.seer.teach.common.PageListBean;
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.PageConverterUtils;
|
||||
import com.seer.teach.mp.app.controller.req.AppActivityQueryReq;
|
||||
import com.seer.teach.mp.app.controller.req.MpGenerateQrCodeReq;
|
||||
import com.seer.teach.mp.app.controller.resp.AppActivityResp;
|
||||
import com.seer.teach.mp.app.controller.resp.MpQrCodeResp;
|
||||
import com.seer.teach.mp.app.convert.AppAgentActivityConvert;
|
||||
import com.seer.teach.mp.app.service.AppOfficialQrCodeService;
|
||||
import com.seer.teach.mp.app.service.IAppActivityService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -44,7 +38,7 @@ public class AppActivityServiceImpl implements IAppActivityService {
|
||||
|
||||
private final AppOfficialQrCodeService officialQrCodeService;
|
||||
|
||||
private final IMpAgentActivityParticipantService agentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService agentActivityParticipantService;
|
||||
|
||||
@Override
|
||||
public PageListBean<AppActivityResp> pageList(AppActivityQueryReq query, Integer agentId) {
|
||||
|
||||
@ -11,12 +11,12 @@ import com.seer.teach.mp.app.controller.req.MpGenerateQrCodeReq;
|
||||
import com.seer.teach.mp.app.controller.resp.AgentActivityParticipantResp;
|
||||
import com.seer.teach.mp.app.controller.resp.MpQrCodeResp;
|
||||
import com.seer.teach.mp.app.service.AppOfficialQrCodeService;
|
||||
import com.seer.teach.mp.app.service.IAppAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.app.service.IAppAgentActivityRelationService;
|
||||
import com.seer.teach.mp.app.service.IAppAgentService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -42,9 +43,9 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AppAgentActivityParticipantServiceImpl implements IAppAgentActivityParticipantService {
|
||||
public class AppAgentActivityRelationServiceImpl implements IAppAgentActivityRelationService {
|
||||
|
||||
private final IMpAgentActivityParticipantService agentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService agentActivityRelationService;
|
||||
|
||||
private final IAppAgentService appAgentService;
|
||||
|
||||
@ -63,14 +64,14 @@ public class AppAgentActivityParticipantServiceImpl implements IAppAgentActivity
|
||||
if(!userAgentIds.contains(agentId) ){
|
||||
throw new CommonException(ResultCodeEnum.RELATION_NOT_FOUND);
|
||||
}
|
||||
var participants = agentActivityParticipantService.getListByAgentId(agentId);
|
||||
var participants = agentActivityRelationService.getListByAgentId(agentId);
|
||||
|
||||
if (CollectionUtil.isEmpty(participants)) {
|
||||
return List.of();
|
||||
}
|
||||
Set<Integer> activityIds = participants.stream().map(MpAgentActivityParticipantEntity::getActivityId).collect(Collectors.toSet());
|
||||
|
||||
List<MpActivityEntity> parentInfos = mpActivityService.listByIds(activityIds);
|
||||
List<MpActivityEntity> parentInfos = mpActivityService.getEffectiveActivityListByIds(activityIds);
|
||||
|
||||
var activityInfoMap = parentInfos.stream().collect(Collectors.toMap(MpActivityEntity::getId, activity -> activity));
|
||||
|
||||
@ -80,17 +81,22 @@ public class AppAgentActivityParticipantServiceImpl implements IAppAgentActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQrCode(AppMpAgentActivityQrCodeQueryReq req, Integer userId) {
|
||||
public String getQrCode(AppMpAgentActivityQrCodeQueryReq req) {
|
||||
Integer activityId = req.getActivityId();
|
||||
Integer agentId = req.getAgentId();
|
||||
log.info("getQrCode param activityId:{},agentId:{}", activityId, agentId);
|
||||
MpActivityEntity activity = mpActivityService.getById(activityId);
|
||||
AssertUtils.notNull(activity, ResultCodeEnum.INVALID_ACTIVITY);
|
||||
|
||||
if(activity.getStatus() != 1){
|
||||
throw new CommonException(ResultCodeEnum.INVALID_ACTIVITY);
|
||||
if(Objects.isNull(activity)){
|
||||
return "";
|
||||
}
|
||||
MpAgentActivityParticipantEntity relation = agentActivityParticipantService.getParticipantsByActivityAndAgent(activityId, agentId);
|
||||
|
||||
// 检查活动是否在有效时间内且处于启用状态
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
boolean isWithinTimeRange = !now.isBefore(activity.getStartTime()) && !now.isAfter(activity.getEndTime());
|
||||
if(activity.getStatus() != 1 || !isWithinTimeRange){
|
||||
return "";
|
||||
}
|
||||
MpAgentActivityParticipantEntity relation = agentActivityRelationService.getParticipantsByActivityAndAgent(activityId, agentId);
|
||||
AssertUtils.notNull(relation, ResultCodeEnum.INVALID_ACTIVITY);
|
||||
if(StringUtils.isNotBlank(relation.getQrCodeUrl())){
|
||||
return relation.getQrCodeUrl();
|
||||
@ -111,7 +117,7 @@ public class AppAgentActivityParticipantServiceImpl implements IAppAgentActivity
|
||||
relation.setQrCodeUrl(mpQrCodeResp.getQrCodeUrl());
|
||||
}
|
||||
}
|
||||
agentActivityParticipantService.updateById(relation);
|
||||
agentActivityRelationService.updateById(relation);
|
||||
return mpQrCodeResp.getQrCodeUrl();
|
||||
}
|
||||
|
||||
@ -124,6 +130,19 @@ public class AppAgentActivityParticipantServiceImpl implements IAppAgentActivity
|
||||
MpActivityEntity activity = activityInfoMap.get(entity.getActivityId());
|
||||
if(Objects.nonNull(activity)){
|
||||
resp.setActivityName(activity.getActivityName());
|
||||
resp.setDescription(activity.getDescription());
|
||||
resp.setStartTime(activity.getStartTime());
|
||||
resp.setEndTime(activity.getEndTime());
|
||||
|
||||
// 根据当前时间判断活动状态
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (now.isBefore(activity.getStartTime())) {
|
||||
resp.setStatus(1); // 未开始
|
||||
} else if (now.isAfter(activity.getEndTime())) {
|
||||
resp.setStatus(3); // 已结束
|
||||
} else {
|
||||
resp.setStatus(1); // 进行中
|
||||
}
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class WechatMiniProgramApiImpl implements WechatMiniProgramApi{
|
||||
public class AppMiniProgramApiImpl implements MpMiniProgramApi {
|
||||
|
||||
private final IWechatMiniProgramService wechatMiniProgramService;
|
||||
|
||||
@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class WechatOfficialAccountApiImpl implements WechatOfficialAccountApi{
|
||||
public class AppOfficialAccountApiImpl implements MpOfficialAccountApi {
|
||||
|
||||
@Autowired
|
||||
private MpServiceFactory mpServiceFactory;
|
||||
@ -4,6 +4,7 @@ import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
||||
import com.seer.teach.mp.factory.MpServiceFactory;
|
||||
import com.seer.teach.mp.handler.LocationHandler;
|
||||
import com.seer.teach.mp.handler.MessageReceiveHandler;
|
||||
import com.seer.teach.mp.handler.ScanHandler;
|
||||
import com.seer.teach.mp.handler.SubscribeHandler;
|
||||
import com.seer.teach.mp.handler.UnsubscribeHandler;
|
||||
import com.seer.teach.mp.service.IMpAccountService;
|
||||
@ -30,9 +31,10 @@ public class MpConfiguration {
|
||||
MessageReceiveHandler messageReceiveHandler,
|
||||
SubscribeHandler subscribeHandler,
|
||||
UnsubscribeHandler unsubscribeHandler,
|
||||
LocationHandler locationHandler) {
|
||||
LocationHandler locationHandler,
|
||||
ScanHandler scanHandler) {
|
||||
return new MpServiceFactory(redisTemplateWxRedisOps, mpAccountService,wxMpProperties,
|
||||
messageReceiveHandler, subscribeHandler, unsubscribeHandler, locationHandler);
|
||||
messageReceiveHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler);
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import com.google.common.collect.Maps;
|
||||
import com.seer.teach.mp.entity.MpAccountEntity;
|
||||
import com.seer.teach.mp.handler.LocationHandler;
|
||||
import com.seer.teach.mp.handler.MessageReceiveHandler;
|
||||
import com.seer.teach.mp.handler.ScanHandler;
|
||||
import com.seer.teach.mp.handler.SubscribeHandler;
|
||||
import com.seer.teach.mp.handler.UnsubscribeHandler;
|
||||
import com.seer.teach.mp.service.IMpAccountService;
|
||||
@ -51,6 +52,7 @@ public class MpServiceFactory {
|
||||
private final SubscribeHandler subscribeHandler;
|
||||
private final UnsubscribeHandler unsubscribeHandler;
|
||||
private final LocationHandler locationHandler;
|
||||
private final ScanHandler scanHandler;
|
||||
|
||||
public void init() {
|
||||
List<MpAccountEntity> accounts = mpAccountService.list();
|
||||
@ -130,7 +132,7 @@ public class MpServiceFactory {
|
||||
private WxMpMessageRouter buildMpMessageRouter(WxMpService mpService) {
|
||||
WxMpMessageRouter router = new WxMpMessageRouter(mpService);
|
||||
// 记录所有事件的日志
|
||||
router.rule().handler(messageReceiveHandler).next();
|
||||
router.rule().async(false).handler(messageReceiveHandler).next();
|
||||
|
||||
// 关注事件
|
||||
router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
@ -152,6 +154,10 @@ public class MpServiceFactory {
|
||||
router.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
|
||||
.handler(locationHandler).end();
|
||||
|
||||
// 扫码事件
|
||||
router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.EventType.SCAN).handler(scanHandler)
|
||||
.end();
|
||||
return router;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package com.seer.teach.mp.handler;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AbstractHandler {
|
||||
|
||||
@Autowired
|
||||
private IMpAgentActivityRelationService mpAgentActivityRelationService;
|
||||
|
||||
@Autowired
|
||||
private IMpActivityService mpActivityService;
|
||||
|
||||
|
||||
protected boolean isAgentActivityScanEvent(WxMpXmlMessage wxMessage) {
|
||||
String eventKey = wxMessage.getEventKey();
|
||||
log.info("[handle][用户({})] 获取用户二维码信息:[{}]", wxMessage.getFromUser(), eventKey);
|
||||
if (StringUtils.hasText(eventKey) && eventKey.startsWith("agentId") && eventKey.contains("activityId")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected WxMpXmlOutMessage buildAgentActivityOutMessage(WxMpXmlMessage wxMessage) {
|
||||
String eventKey = wxMessage.getEventKey();
|
||||
Map<String, String> paramMap = HttpUtil.decodeParamMap(eventKey, StandardCharsets.UTF_8);
|
||||
Integer agentId = MapUtil.getInt(paramMap, "agentId", 0);
|
||||
Integer activityId = MapUtil.getInt(paramMap, "activityId", 0);
|
||||
if (agentId > 0 && activityId > 0) {
|
||||
MpAgentActivityParticipantEntity participantsByActivityAndAgent = mpAgentActivityRelationService.getParticipantsByActivityAndAgent(activityId, agentId);
|
||||
MpActivityEntity activity = mpActivityService.getById(activityId);
|
||||
if (Objects.nonNull(participantsByActivityAndAgent)) {
|
||||
WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
|
||||
item.setTitle(activity.getActivityName());
|
||||
item.setDescription(activity.getDescription());
|
||||
item.setPicUrl(participantsByActivityAndAgent.getQrCodeUrl());
|
||||
item.setUrl("https://mp.seerteach.net/login?" + eventKey);
|
||||
WxMpXmlOutNewsMessage build = WxMpXmlOutMessage.NEWS()
|
||||
.addArticle(item)
|
||||
.toUser(wxMessage.getFromUser())
|
||||
.fromUser(wxMessage.getToUser())
|
||||
.build();
|
||||
log.info("[handle][扫码处理,内容:{}]", build);
|
||||
return build;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,9 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@ -37,11 +40,15 @@ public class MessageReceiveHandler implements WxMpMessageHandler {
|
||||
wxMessageEntity.setAppId(wxMpService.getWxMpConfigStorage().getAppId());
|
||||
log.info("[handle][保存消息,内容:{}]", wxMessageEntity);
|
||||
mpMessageService.save(wxMessageEntity);
|
||||
return WxMpXmlOutMessage.TEXT()
|
||||
WxMpXmlOutMessage textMessage = WxMpXmlOutMessage.TEXT()
|
||||
.toUser(wxMessage.getFromUser())
|
||||
.fromUser(wxMessage.getToUser())
|
||||
.content("点击下方菜单进入seerTeach小程序")
|
||||
.content("欢迎使用SeerTeach AI")
|
||||
.build();
|
||||
textMessage.setCreateTime(LocalDateTime.now().atZone(ZoneId.of("Asia/Shanghai"))
|
||||
.toInstant()
|
||||
.toEpochMilli());
|
||||
return textMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.seer.teach.mp.handler;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 用户扫码处理(已关注后的处理)
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ScanHandler extends AbstractHandler implements WxMpMessageHandler {
|
||||
|
||||
@Autowired
|
||||
private IMpAgentActivityRelationService mpAgentActivityRelationService;
|
||||
|
||||
@Autowired
|
||||
private IMpActivityService mpActivityService;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
|
||||
log.info("[handle][扫码处理,内容:{}]", wxMessage);
|
||||
String eventKey = wxMessage.getEventKey();
|
||||
log.info("[handle][用户({})] 获取用户二维码信息:[{}]", wxMessage.getFromUser(), eventKey);
|
||||
if(isAgentActivityScanEvent(wxMessage)){
|
||||
return buildAgentActivityOutMessage(wxMessage);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,11 @@
|
||||
package com.seer.teach.mp.handler;
|
||||
|
||||
import com.seer.teach.common.constants.CommonConstant;
|
||||
import com.seer.teach.common.enums.UserRelationEnum;
|
||||
import com.seer.teach.mp.convert.WxMpUserConvert;
|
||||
import com.seer.teach.mp.entity.MpUserSubscribeEntity;
|
||||
import com.seer.teach.mp.service.IMpUserSubscribeService;
|
||||
import com.seer.teach.user.api.UserInfoServiceApi;
|
||||
import com.seer.teach.user.api.UserRelationServiceApi;
|
||||
import com.seer.teach.user.api.dto.UserInfoDTO;
|
||||
import com.seer.teach.user.api.dto.UserRelationDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
@ -19,9 +16,9 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
@ -31,7 +28,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SubscribeHandler implements WxMpMessageHandler {
|
||||
public class SubscribeHandler extends AbstractHandler implements WxMpMessageHandler {
|
||||
|
||||
@Autowired
|
||||
private UserInfoServiceApi userInfoServiceApi;
|
||||
@ -54,23 +51,17 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
||||
log.info("[handle][用户({})] 转换用户信息成功!", wxMessage.getFromUser());
|
||||
Integer userId = userInfoServiceApi.save(userInfoDTO);
|
||||
log.info("[handle][用户({})] 保存用户信息成功!", wxMessage.getFromUser());
|
||||
String eventKey = wxMessage.getEventKey();
|
||||
if(StringUtils.hasText(eventKey) && eventKey.startsWith(CommonConstant.WX_MP_QR_SCENE_PREFIX)){
|
||||
log.info("[handle][用户({})] 获取用户二维码信息:[{}]", wxMessage.getFromUser(), eventKey);
|
||||
String userIdStr = eventKey.substring(CommonConstant.WX_MP_QR_SCENE_PREFIX.length());
|
||||
UserRelationDTO userRelationDTO = new UserRelationDTO();
|
||||
userRelationDTO.setUserId(userId);
|
||||
userRelationDTO.setRelationId(Integer.parseInt(userIdStr));
|
||||
userRelationDTO.setType(UserRelationEnum.PARENT_CHILD.getDescription());
|
||||
boolean relationResult = userRelationServiceApi.saveUserRelation(userRelationDTO);
|
||||
log.info("[handle][用户({})] 保存用户关系结果:{}!", wxMessage.getFromUser(),relationResult);
|
||||
}
|
||||
String appId = wxMpService.getWxMpConfigStorage().getAppId();
|
||||
MpUserSubscribeEntity mpUserSubscribeEntity = WxMpUserConvert.INSTANCE.convertOne(wxMpUser, userId);
|
||||
mpUserSubscribeEntity.setAppId(appId);
|
||||
boolean saved = mpUserSubscribeService.save(mpUserSubscribeEntity);
|
||||
log.info("[handle][用户({})] 保存用户关注信息结果:{}!", wxMessage.getFromUser(),saved);
|
||||
|
||||
if(isAgentActivityScanEvent(wxMessage)){
|
||||
WxMpXmlOutMessage message = buildAgentActivityOutMessage(wxMessage);
|
||||
if(Objects.nonNull(message)){
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (WxErrorException e) {
|
||||
log.error("[handle][用户({})] 获取用户信息失败!", wxMessage.getFromUser(), e);
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package com.seer.teach.mp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.seer.teach.mp.entity.MpAccountMenuEntity;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公众号菜单表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Lingma
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
public interface IMpAccountMenuService extends IService<MpAccountMenuEntity> {
|
||||
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.seer.teach.mp.service;
|
||||
|
||||
import cn.hutool.db.PageResult;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.seer.teach.mp.entity.MpAccountEntity;
|
||||
|
||||
@ -14,5 +13,11 @@ import com.seer.teach.mp.entity.MpAccountEntity;
|
||||
*/
|
||||
public interface IMpAccountService extends IService<MpAccountEntity> {
|
||||
|
||||
/**
|
||||
* 根据AppId查询公众号账号
|
||||
*
|
||||
* @param appId AppId
|
||||
* @return 公众号账号
|
||||
*/
|
||||
MpAccountEntity getOneByAppId(String appId);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.seer.teach.mp.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -33,8 +34,10 @@ public interface IMpActivityService extends IService<MpActivityEntity> {
|
||||
boolean deleteActivity(Integer id);
|
||||
|
||||
/**
|
||||
* 获取代理商活动名称列表
|
||||
* @return 代理商活动名称列表
|
||||
* 根据ID查询代理商活动
|
||||
*
|
||||
* @param ids 活动ID
|
||||
* @return 活动实体
|
||||
*/
|
||||
List<String> getActivityName();
|
||||
List<MpActivityEntity> getEffectiveActivityListByIds(Collection<Integer> ids);
|
||||
}
|
||||
@ -13,7 +13,7 @@ import java.util.List;
|
||||
* @author Lingma
|
||||
* @since 2025-12-29
|
||||
*/
|
||||
public interface IMpAgentActivityParticipantService extends IService<MpAgentActivityParticipantEntity> {
|
||||
public interface IMpAgentActivityRelationService extends IService<MpAgentActivityParticipantEntity> {
|
||||
|
||||
/**
|
||||
* 根据活动ID和代理商ID获取参与记录
|
||||
@ -0,0 +1,24 @@
|
||||
package com.seer.teach.mp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.seer.teach.mp.entity.MpAccountMenuEntity;
|
||||
import com.seer.teach.mp.mapper.MpAccountMenuMapper;
|
||||
import com.seer.teach.mp.service.IMpAccountMenuService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 公众号菜单表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Lingma
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class MpAccountMenuServiceImpl extends ServiceImpl<MpAccountMenuMapper, MpAccountMenuEntity> implements IMpAccountMenuService {
|
||||
|
||||
}
|
||||
@ -1,21 +1,25 @@
|
||||
package com.seer.teach.mp.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.seer.teach.common.constants.CommonConstant;
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.CommonUtils;
|
||||
import com.seer.teach.mp.entity.MpActivityEntity;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.mapper.MpAgentActivityMapper;
|
||||
import com.seer.teach.mp.service.IMpActivityService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityLogService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -31,7 +35,7 @@ import java.util.List;
|
||||
@RequiredArgsConstructor
|
||||
public class MpActivityServiceImpl extends ServiceImpl<MpAgentActivityMapper, MpActivityEntity> implements IMpActivityService {
|
||||
|
||||
private final IMpAgentActivityParticipantService agentActivityParticipantService;
|
||||
private final IMpAgentActivityRelationService agentActivityParticipantService;
|
||||
private final IMpAgentActivityLogService agentActivityLogService;
|
||||
|
||||
@Override
|
||||
@ -106,14 +110,16 @@ public class MpActivityServiceImpl extends ServiceImpl<MpAgentActivityMapper, Mp
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActivityName() {
|
||||
return this.list().stream()
|
||||
.map(MpActivityEntity::getActivityName).toList();
|
||||
public List<MpActivityEntity> getEffectiveActivityListByIds(Collection<Integer> ids) {
|
||||
if(CollectionUtil.isEmpty(ids)){
|
||||
return List.of();
|
||||
}
|
||||
return super.list(new LambdaQueryWrapper<MpActivityEntity>().in(MpActivityEntity::getId, ids).in(MpActivityEntity::getStatus, CommonConstant.ENABLE));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean saveOrUpdate(MpActivityEntity entity) {
|
||||
boolean result = super.saveOrUpdate(entity);
|
||||
return result;
|
||||
return super.saveOrUpdate(entity);
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.seer.teach.mp.entity.MpAgentActivityParticipantEntity;
|
||||
import com.seer.teach.mp.mapper.MpAgentActivityParticipantMapper;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityLogService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityParticipantService;
|
||||
import com.seer.teach.mp.service.IMpAgentActivityRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -23,7 +23,7 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MpAgentActivityParticipantServiceImpl extends ServiceImpl<MpAgentActivityParticipantMapper, MpAgentActivityParticipantEntity> implements IMpAgentActivityParticipantService {
|
||||
public class MpAgentActivityRelationServiceImpl extends ServiceImpl<MpAgentActivityParticipantMapper, MpAgentActivityParticipantEntity> implements IMpAgentActivityRelationService {
|
||||
|
||||
private final IMpAgentActivityLogService agentActivityLogService;
|
||||
|
||||
@ -140,6 +140,13 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
AssertUtils.notNull(adminUserEntity,ResultCodeEnum.USER_NOT_FOUND);
|
||||
|
||||
UserEntity userEntity = AdminUserConvert.INSTANCE.convertOne(params);
|
||||
// 如果密码不为空,则修改密码
|
||||
if (params.getPassword() != null && !params.getPassword().isEmpty()) {
|
||||
String password = CommonUtils.encryptPassword(params.getPassword());
|
||||
userEntity.setPassword(password);
|
||||
} else {
|
||||
userEntity.setPassword(adminUserEntity.getPassword());
|
||||
}
|
||||
userEntity.setId(id);
|
||||
userService.updateById(userEntity);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import com.seer.teach.common.enums.RoleEnum;
|
||||
import com.seer.teach.common.enums.UserRelationEnum;
|
||||
import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.mp.api.WechatMiniProgramApi;
|
||||
import com.seer.teach.mp.api.MpMiniProgramApi;
|
||||
import com.seer.teach.mp.api.resp.WxMiniProgramSessionDTO;
|
||||
import com.seer.teach.user.app.auth.LoginType;
|
||||
import com.seer.teach.user.app.auth.request.LoginParam;
|
||||
@ -45,7 +45,7 @@ import java.util.Objects;
|
||||
public class MiniProgramLoginStrategy extends AbstractLoginStrategy implements LoginStrategy {
|
||||
|
||||
|
||||
private final WechatMiniProgramApi wechatMiniProgramApi;
|
||||
private final MpMiniProgramApi mpMiniProgramApi;
|
||||
|
||||
private final IUserService userService;
|
||||
|
||||
@ -70,7 +70,7 @@ public class MiniProgramLoginStrategy extends AbstractLoginStrategy implements L
|
||||
|
||||
@Override
|
||||
public LoginUser authenticate(LoginParam request) {
|
||||
WxMiniProgramSessionDTO wxMiniProgramSessionDTO = wechatMiniProgramApi.code2Session(request.getJsCode());
|
||||
WxMiniProgramSessionDTO wxMiniProgramSessionDTO = mpMiniProgramApi.code2Session(request.getJsCode());
|
||||
AssertUtils.isTrue(wxMiniProgramSessionDTO.isSuccess(), ResultCodeEnum.WX_OAUTH_USED_ERROR);
|
||||
UserAuthEntity userAuth = userAuthService.getOneByOpenIdAndUnionId(wxMiniProgramSessionDTO.getOpenid(), wxMiniProgramSessionDTO.getUnionid());
|
||||
boolean isExistsChildren = false;
|
||||
|
||||
@ -2,7 +2,7 @@ package com.seer.teach.user.app.auth.service.strategy;
|
||||
|
||||
import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.mp.api.WechatOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.MpOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
|
||||
import com.seer.teach.user.app.auth.LoginType;
|
||||
import com.seer.teach.user.app.auth.request.LoginParam;
|
||||
@ -26,7 +26,7 @@ import java.util.Objects;
|
||||
public class OfficialAccountLoginStrategy extends AbstractLoginStrategy implements LoginStrategy {
|
||||
|
||||
@Autowired
|
||||
private WechatOfficialAccountApi wechatOfficialAccountApi;
|
||||
private MpOfficialAccountApi mpOfficialAccountApi;
|
||||
|
||||
@Autowired
|
||||
private IUserService userService;
|
||||
@ -42,7 +42,7 @@ public class OfficialAccountLoginStrategy extends AbstractLoginStrategy implemen
|
||||
@Override
|
||||
public LoginUser authenticate(LoginParam request) {
|
||||
log.info("微信公众号登录:{}",request);
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = mpOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
|
||||
log.debug("获取用户信息:{}",wxOAuth2AccessToken);
|
||||
AssertUtils.notNull(wxOAuth2AccessToken, ResultCodeEnum.WX_OAUTH_USED_ERROR);
|
||||
String userOpenId = wxOAuth2AccessToken.getOpenId();
|
||||
|
||||
@ -5,7 +5,7 @@ import com.seer.teach.common.enums.ResultCodeEnum;
|
||||
import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.CommonUtils;
|
||||
import com.seer.teach.mp.api.WechatOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.MpOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
|
||||
import com.seer.teach.user.app.auth.LoginType;
|
||||
import com.seer.teach.user.app.auth.request.LoginParam;
|
||||
@ -33,7 +33,7 @@ public class OfficialOauthWithAccountLoginStrategy extends AbstractLoginStrategy
|
||||
private final IUserService userService;
|
||||
|
||||
@Autowired
|
||||
private WechatOfficialAccountApi wechatOfficialAccountApi;
|
||||
private MpOfficialAccountApi mpOfficialAccountApi;
|
||||
|
||||
@Override
|
||||
public LoginType getType() {
|
||||
@ -54,7 +54,7 @@ public class OfficialOauthWithAccountLoginStrategy extends AbstractLoginStrategy
|
||||
AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
|
||||
String password = CommonUtils.encryptPassword(request.getPassword());
|
||||
if (password.equals(accountUser.getPassword())) {
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = mpOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(), request.getJsCode());
|
||||
log.debug("获取用户信息:{}",wxOAuth2AccessToken);
|
||||
AssertUtils.notNull(wxOAuth2AccessToken, ResultCodeEnum.WX_OAUTH_USED_ERROR);
|
||||
String userOpenId = wxOAuth2AccessToken.getOpenId();
|
||||
|
||||
@ -5,7 +5,7 @@ import com.seer.teach.common.enums.RoleEnum;
|
||||
import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.CommonUtils;
|
||||
import com.seer.teach.mp.api.WechatOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.MpOfficialAccountApi;
|
||||
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
|
||||
import com.seer.teach.user.app.auth.LoginType;
|
||||
import com.seer.teach.user.app.auth.request.LoginParam;
|
||||
@ -38,7 +38,7 @@ public class WarehouseAccountLoginStrategy extends AbstractLoginStrategy impleme
|
||||
|
||||
private final IUserService userService;
|
||||
|
||||
private final WechatOfficialAccountApi wechatOfficialAccountApi;
|
||||
private final MpOfficialAccountApi mpOfficialAccountApi;
|
||||
|
||||
private final IUserAuthService userAuthService;
|
||||
|
||||
@ -68,7 +68,7 @@ public class WarehouseAccountLoginStrategy extends AbstractLoginStrategy impleme
|
||||
.findAny()
|
||||
.orElseThrow(() -> new CommonException(ResultCodeEnum.USER_NOT_HAVE_WAREHOUSE_ROLE));
|
||||
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(),request.getJsCode());
|
||||
WxOAuth2AccessTokenDTO wxOAuth2AccessToken = mpOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(),request.getJsCode());
|
||||
AssertUtils.notNull(wxOAuth2AccessToken, ResultCodeEnum.WX_OAUTH_USED_ERROR);
|
||||
UserAuthEntity userAuthEntity = userAuthService.getOneByOpenId(wxOAuth2AccessToken.getOpenId());
|
||||
if (Objects.isNull(userAuthEntity)) {
|
||||
|
||||
@ -6,7 +6,7 @@ import com.seer.teach.common.exception.CommonException;
|
||||
import com.seer.teach.common.utils.AssertUtils;
|
||||
import com.seer.teach.common.utils.CommonUtils;
|
||||
import com.seer.teach.iot.api.UserDeviceServiceApi;
|
||||
import com.seer.teach.mp.api.WechatMiniProgramApi;
|
||||
import com.seer.teach.mp.api.MpMiniProgramApi;
|
||||
import com.seer.teach.mp.api.resp.WxMiniProgramSessionDTO;
|
||||
import com.seer.teach.user.app.auth.LoginType;
|
||||
import com.seer.teach.user.app.auth.request.LoginParam;
|
||||
@ -35,7 +35,7 @@ public class WechatChildrenAccountLoginStrategy extends AbstractLoginStrategy im
|
||||
|
||||
private final UserDeviceServiceApi userDeviceServiceApi;
|
||||
|
||||
private final WechatMiniProgramApi wechatMiniProgramApi;
|
||||
private final MpMiniProgramApi mpMiniProgramApi;
|
||||
|
||||
private final IUserRelationService userRelationService;
|
||||
|
||||
@ -54,7 +54,7 @@ public class WechatChildrenAccountLoginStrategy extends AbstractLoginStrategy im
|
||||
AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
|
||||
String password = CommonUtils.encryptPassword(request.getPassword());
|
||||
if (password.equals(accountUser.getPassword())) {
|
||||
WxMiniProgramSessionDTO miniProgramSessionDTO = wechatMiniProgramApi.code2Session(request.getJsCode());
|
||||
WxMiniProgramSessionDTO miniProgramSessionDTO = mpMiniProgramApi.code2Session(request.getJsCode());
|
||||
AssertUtils.notNull(miniProgramSessionDTO, ResultCodeEnum.WX_SESSION_CODE_USED_ERROR);
|
||||
// 使用开关控制是否检查设备绑定
|
||||
if (deviceCheckEnabled) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user