diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index f9ba8c700..5b4f32258 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -24,7 +24,7 @@ 8.0.27 21.3.0.0 1.5.22 - 3.9.0 + 4.2.0 2.7.6 3.0.3 1.13.1 diff --git a/pigx-visual/pigx-mp-platform/pom.xml b/pigx-visual/pigx-mp-platform/pom.xml index 633276c1b..ebc233475 100755 --- a/pigx-visual/pigx-mp-platform/pom.xml +++ b/pigx-visual/pigx-mp-platform/pom.xml @@ -13,6 +13,9 @@ jar 微信公众号管理模块 + + 1.1.2 + @@ -35,10 +38,16 @@ com.baomidou mybatis-plus-boot-starter + mysql mysql-connector-java + + + com.oracle.database.jdbc + ojdbc8 + com.alibaba @@ -82,6 +91,12 @@ com.github.binarywang weixin-java-mp + + + com.github.binarywang + java-testdata-generator + ${mock.version} + org.springframework.boot diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountTagController.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountTagController.java index 4f2aeb724..bf599b837 100644 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountTagController.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/controller/WxAccountTagController.java @@ -5,10 +5,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.mp.entity.WxAccountTag; -import com.pig4cloud.pigx.mp.entity.WxAutoReply; import com.pig4cloud.pigx.mp.service.WxAccountTagService; import lombok.AllArgsConstructor; -import org.apache.ibatis.annotations.Delete; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -54,6 +53,7 @@ public class WxAccountTagController { * @return 包含保存成功后的账户标签的API调用结果 */ @PostMapping + @PreAuthorize("@pms.hasPermission('mp_wx_account_tag_add')") public R saveAccountTag(@RequestBody @Valid WxAccountTag wxAccountTag) { return R.ok(wxAccountTagService.saveAccountTag(wxAccountTag)); } @@ -64,13 +64,31 @@ public class WxAccountTagController { * @return 包含修改成功后的账户标签的API调用结果 */ @PutMapping + @PreAuthorize("@pms.hasPermission('mp_wx_account_tag_edit')") public R updateAccountTag(@RequestBody @Valid WxAccountTag wxAccountTag) { return R.ok(wxAccountTagService.updateAccountTag(wxAccountTag)); } - @DeleteMapping("/{id:\\d+}") - public R removeAccountTagById(@PathVariable Long id) { - return R.ok(wxAccountTagService.removeAccountTagById(id)); + /** + * 删除 + * @param wxAccountTag 标签 + * @return R + */ + @DeleteMapping + @PreAuthorize("@pms.hasPermission('mp_wx_account_tag_del')") + public R removeAccountTagById(@RequestBody WxAccountTag wxAccountTag) { + return R.ok(wxAccountTagService.removeAccountTagById(wxAccountTag)); + } + + /** + * 同步粉丝 + * @param appId + * @return + */ + @PostMapping("/sync/{appId}") + @PreAuthorize("@pms.hasPermission('mp_wx_account_tag_sync')") + public R sync(@PathVariable String appId) { + return R.ok(wxAccountTagService.syncAccountTags(appId)); } } diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java index 6f8302f5c..7314bd101 100755 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccount.java @@ -16,9 +16,7 @@ */ package com.pig4cloud.pigx.mp.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.pig4cloud.pigx.common.core.sensitive.Sensitive; import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum; @@ -89,17 +87,20 @@ public class WxAccount extends Model { /** * 创建时间 */ + @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; /** * 更新时间 */ + @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** * 是否删除 -1:已删除 0:正常 */ @TableLogic + @TableField(fill = FieldFill.INSERT) private String delFlag; /** diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountTag.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountTag.java index acc42154f..ed2fa60eb 100644 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountTag.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/entity/WxAccountTag.java @@ -1,13 +1,12 @@ package com.pig4cloud.pigx.mp.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; -import com.pig4cloud.pigx.common.data.mybatis.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; /** * 微信公众号账号标签 @@ -17,7 +16,7 @@ import javax.validation.constraints.NotBlank; */ @Data @EqualsAndHashCode(callSuper = true) -public class WxAccountTag extends BaseEntity { +public class WxAccountTag extends Model { private static final long serialVersionUID = 1L; @@ -33,4 +32,55 @@ public class WxAccountTag extends BaseEntity { @NotBlank(message = "标签不能为空") private String tag; + /** + * 标签ID , 微信公众平台返回 + */ + private Long tagId; + + /** + * 微信公众号ID + */ + private Long wxAccountId; + + /** + * 微信公众号appid + */ + private String wxAccountAppid; + + /** + * 微信公众号名 + */ + private String wxAccountName; + + /** + * 创建者 + */ + @TableField(fill = FieldFill.INSERT) + private String createBy; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; + + /** + * 是否删除 1:已删除 0:正常 + */ + @TableLogic + @TableField(fill = FieldFill.INSERT) + private String delFlag; + } diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java index 3b065355c..05fb4487b 100755 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/handler/SubscribeHandler.java @@ -1,5 +1,6 @@ package com.pig4cloud.pigx.mp.handler; +import cn.binarywang.tools.generator.ChineseNameGenerator; import cn.hutool.core.util.BooleanUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.pig4cloud.pigx.mp.builder.TextBuilder; @@ -67,12 +68,11 @@ public class SubscribeHandler extends AbstractHandler { wxAccountFans.setSubscribeStatus(String.valueOf(BooleanUtil.toInt(wxMpUser.getSubscribe()))); wxAccountFans.setSubscribeTime(LocalDateTime .ofInstant(Instant.ofEpochMilli(wxMpUser.getSubscribeTime() * 1000L), ZoneId.systemDefault())); - wxAccountFans.setNickname(wxMpUser.getNickname()); - wxAccountFans.setGender(String.valueOf(wxMpUser.getSex())); + + // 随机生成一个昵称,方便平台内部使用 + String generatedName = ChineseNameGenerator.getInstance().generate(); + wxAccountFans.setNickname(generatedName); wxAccountFans.setLanguage(wxMpUser.getLanguage()); - wxAccountFans.setCountry(wxMpUser.getCountry()); - wxAccountFans.setProvince(wxMpUser.getProvince()); - wxAccountFans.setCity(wxMpUser.getCity()); wxAccountFans.setHeadimgUrl(wxMpUser.getHeadImgUrl()); wxAccountFans.setRemark(wxMpUser.getRemark()); diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountTagService.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountTagService.java index e2669527b..7b6cb2366 100644 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountTagService.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/WxAccountTagService.java @@ -1,7 +1,5 @@ package com.pig4cloud.pigx.mp.service; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.pig4cloud.pigx.mp.entity.WxAccountTag; @@ -29,9 +27,16 @@ public interface WxAccountTagService extends IService { /** * 删除账户标签 - * @param id 待删除的账户标签主键 + * @param wxAccountTag 待删除的账户标签 * @return 删除成功返回true,删除失败返回false */ - Boolean removeAccountTagById(Long id); + Boolean removeAccountTagById(WxAccountTag wxAccountTag); + + /** + * 同步账户标签 + * @param appId appId + * @return Boolean + */ + Boolean syncAccountTags(String appId); } diff --git a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java index b9411d55b..f145ce585 100755 --- a/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java +++ b/pigx-visual/pigx-mp-platform/src/main/java/com/pig4cloud/pigx/mp/service/impl/WxAccountFansServiceImpl.java @@ -16,6 +16,7 @@ */ package com.pig4cloud.pigx.mp.service.impl; +import cn.binarywang.tools.generator.ChineseNameGenerator; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; @@ -137,12 +138,11 @@ public class WxAccountFansServiceImpl extends ServiceImpl implements WxAccountTagService { + private final WxAccountMapper accountMapper; + /** * 保存账户标签 * @param accountTag 账户标签 * @return 保存成功true保存失败false */ @Override + @SneakyThrows + @Transactional(rollbackFor = Exception.class) public WxAccountTag saveAccountTag(WxAccountTag accountTag) { WxAccountTag wxAccountTag = baseMapper .selectOne(Wrappers.lambdaQuery().eq(WxAccountTag::getTag, accountTag.getTag())); Assert.isNull(wxAccountTag, StrUtil.format("名称为[{}]的标签已经存在", accountTag.getTag())); + + // 调用微信公众号接口删除 + WxMpService wxMpService = WxMpInitConfigRunner.getMpServices().get(accountTag.getWxAccountAppid()); + WxUserTag wxUserTag = wxMpService.getUserTagService().tagCreate(accountTag.getTag()); + accountTag.setTagId(wxUserTag.getId()); + + // 查询公众号详细信息 + WxAccount wxAccount = accountMapper + .selectOne(Wrappers.lambdaQuery().eq(WxAccount::getAppid, accountTag.getWxAccountAppid())); + accountTag.setWxAccountId(wxAccount.getId()); + accountTag.setWxAccountAppid(wxAccount.getAppid()); + accountTag.setWxAccountName(wxAccount.getName()); + baseMapper.insert(accountTag); return accountTag; } @@ -39,19 +67,57 @@ public class WxAccountTagServiceImpl extends ServiceImpllambdaQuery() - .eq(WxAccountTag::getTag, accountTag.getTag()).ne(WxAccountTag::getId, accountTag.getId())); - Assert.isNull(wxAccountTag, StrUtil.format("名称为[{}]的标签已经存在", accountTag.getTag())); baseMapper.updateById(accountTag); + + // 调用微信公众号接口更新 + WxMpService wxMpService = WxMpInitConfigRunner.getMpServices().get(accountTag.getWxAccountAppid()); + wxMpService.getUserTagService().tagUpdate(accountTag.getTagId(), accountTag.getTag()); return accountTag; } @Override - public Boolean removeAccountTagById(Long id) { - WxAccountTag wxAccountTag = baseMapper.selectById(id); + @SneakyThrows + @Transactional(rollbackFor = Exception.class) + public Boolean removeAccountTagById(WxAccountTag tag) { + WxAccountTag wxAccountTag = baseMapper.selectById(tag.getId()); Assert.notNull(wxAccountTag, "要删除的标签不存在"); + + // 调用微信公众号接口删除 + WxMpService wxMpService = WxMpInitConfigRunner.getMpServices().get(tag.getWxAccountAppid()); + wxMpService.getUserTagService().tagDelete(wxAccountTag.getTagId()); return removeById(wxAccountTag.getId()); } + /** + * 同步账户标签 + * @param appId appId + * @return Boolean + */ + @Override + @SneakyThrows + @Transactional(rollbackFor = Exception.class) + public Boolean syncAccountTags(String appId) { + WxMpService wxMpService = WxMpInitConfigRunner.getMpServices().get(appId); + List wxUserTags = wxMpService.getUserTagService().tagGet(); + + // 删除旧数据 + baseMapper.delete(Wrappers.lambdaQuery()); + + WxAccount wxAccount = accountMapper.selectOne(Wrappers.lambdaQuery().eq(WxAccount::getAppid, appId)); + for (WxUserTag wxUserTag : wxUserTags) { + WxAccountTag tag = new WxAccountTag(); + tag.setTag(wxUserTag.getName()); + tag.setTagId(wxUserTag.getId()); + tag.setWxAccountId(wxAccount.getId()); + tag.setWxAccountAppid(wxAccount.getAppid()); + tag.setWxAccountName(wxAccount.getName()); + baseMapper.insert(tag); + } + + return Boolean.TRUE; + } + } diff --git a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java index 7b60065f4..185348973 100755 --- a/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java +++ b/pigx-visual/pigx-pay-platform/src/main/java/com/pig4cloud/pigx/pay/controller/PayGoodsOrderController.java @@ -17,11 +17,6 @@ package com.pig4cloud.pigx.pay.controller; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import cn.hutool.core.util.URLUtil; import cn.hutool.http.ContentType; import cn.hutool.json.JSONObject; @@ -43,24 +38,21 @@ import io.swagger.annotations.Api; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; import org.springframework.http.HttpHeaders; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + /** * 商品 * @@ -157,8 +149,8 @@ public class PayGoodsOrderController { storage.setSecret(params.getStr("secret")); wxMpService.setWxMpConfigStorage(storage); - WxMpOAuth2AccessToken mpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code); - goods.setUserId(mpOAuth2AccessToken.getOpenId()); + WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code); + goods.setUserId(accessToken.getOpenId()); goods.setAmount(goods.getAmount()); modelAndView.setViewName("pay"); modelAndView.addAllObjects(payGoodsOrderService.buy(goods, false));