From ebc3b6e25f82fa99a60d0e3bccbb79a28ad78e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E8=80=98=E7=A8=B7?= <18026623439@163.com> Date: Thu, 10 Dec 2020 12:31:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=95=86=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E9=80=9A=E7=9F=A5(=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/yixiang/constant/ShopConstants.java | 5 + .../customer/domain/YxStoreCustomer.java | 50 ++++++++ .../service/YxStoreCustomerService.java | 48 +++++++ .../service/dto/YxStoreCustomerDto.java | 44 +++++++ .../dto/YxStoreCustomerQueryCriteria.java | 21 ++++ .../impl/YxStoreCustomerServiceImpl.java | 84 +++++++++++++ .../service/mapper/YxStoreCustomerMapper.java | 23 ++++ .../modules/customer/vo/YzCustomerVo.java | 43 +++++++ .../customer/rest/QrCodeController.java | 117 ++++++++++++++++++ .../rest/YxStoreCustomerController.java | 89 +++++++++++++ .../yixiang/tools/rest/UploadController.java | 4 +- .../modules/mp/listener/TemplateListener.java | 28 ++++- .../mp/service/WeixinTemplateService.java | 63 ++++++++++ 13 files changed, 614 insertions(+), 5 deletions(-) create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/domain/YxStoreCustomer.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/service/YxStoreCustomerService.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerDto.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerQueryCriteria.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/service/impl/YxStoreCustomerServiceImpl.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/service/mapper/YxStoreCustomerMapper.java create mode 100644 yshop-mall/src/main/java/co/yixiang/modules/customer/vo/YzCustomerVo.java create mode 100644 yshop-shop/src/main/java/co/yixiang/modules/customer/rest/QrCodeController.java create mode 100644 yshop-shop/src/main/java/co/yixiang/modules/customer/rest/YxStoreCustomerController.java diff --git a/yshop-common/src/main/java/co/yixiang/constant/ShopConstants.java b/yshop-common/src/main/java/co/yixiang/constant/ShopConstants.java index 1e0b5969..8f554a3c 100644 --- a/yshop-common/src/main/java/co/yixiang/constant/ShopConstants.java +++ b/yshop-common/src/main/java/co/yixiang/constant/ShopConstants.java @@ -174,4 +174,9 @@ public interface ShopConstants { String DEFAULT_UNI_H5_URL = "https://h5.yixiang.co"; String YSHOP_MINI_SESSION_KET = "yshop:session_key:"; + + /**公众号二维码*/ + String WECHAT_FOLLOW_IMG="wechat_follow_img"; + /**后台api地址*/ + String ADMIN_API_URL="admin_api_url"; } diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/domain/YxStoreCustomer.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/domain/YxStoreCustomer.java new file mode 100644 index 00000000..540bb05b --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/domain/YxStoreCustomer.java @@ -0,0 +1,50 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.domain; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import com.baomidou.mybatisplus.annotation.TableName; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.validation.constraints.*; +import java.util.Date; +import co.yixiang.domain.BaseDomain; + +/** +* @author Bug +* @date 2020-12-10 +*/ +@Data +@TableName("yx_store_customer") +public class YxStoreCustomer extends BaseDomain { + /** id */ + @TableId + private Long id; + + /** 用户昵称 */ + private String nickName; + + /** openId */ + @NotBlank(message = "请用户扫码后提交") + private String openId; + + /** 备注 */ + private String remark; + + + + + /** 是否启用 */ + private Integer isEnable; + + + public void copy(YxStoreCustomer source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/service/YxStoreCustomerService.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/YxStoreCustomerService.java new file mode 100644 index 00000000..2f153cb4 --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/YxStoreCustomerService.java @@ -0,0 +1,48 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.service; +import co.yixiang.common.service.BaseService; +import co.yixiang.modules.customer.domain.YxStoreCustomer; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerDto; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerQueryCriteria; +import org.springframework.data.domain.Pageable; +import java.util.Map; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import co.yixiang.domain.PageResult; +/** +* @author Bug +* @date 2020-12-10 +*/ +public interface YxStoreCustomerService extends BaseService{ + + /** + * 查询数据分页 + * @param criteria 条件 + * @param pageable 分页参数 + * @return Map + */ + PageResult queryAll(YxStoreCustomerQueryCriteria criteria, Pageable pageable); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List + */ + List queryAll(YxStoreCustomerQueryCriteria criteria); + + /** + * 导出数据 + * @param all 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List all, HttpServletResponse response) throws IOException; +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerDto.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerDto.java new file mode 100644 index 00000000..54dd8cdb --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerDto.java @@ -0,0 +1,44 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.service.dto; + +import lombok.Data; +import java.util.Date; +import java.io.Serializable; + +/** +* @author Bug +* @date 2020-12-10 +*/ +@Data +public class YxStoreCustomerDto implements Serializable { + + /** id */ + private Long id; + + /** 用户昵称 */ + private String nickName; + + /** openId */ + private String openId; + + /** 备注 */ + private String remark; + + /** 添加时间 */ + private Date createTime; + + /** 修改时间 */ + private Date updateTime; + + private Integer isDel; + + /** 是否启用 */ + private Integer isEnable; +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerQueryCriteria.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerQueryCriteria.java new file mode 100644 index 00000000..4bf2bc60 --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/dto/YxStoreCustomerQueryCriteria.java @@ -0,0 +1,21 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.service.dto; + +import lombok.Data; +import java.util.List; +import co.yixiang.annotation.Query; + +/** +* @author Bug +* @date 2020-12-10 +*/ +@Data +public class YxStoreCustomerQueryCriteria{ +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/service/impl/YxStoreCustomerServiceImpl.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/impl/YxStoreCustomerServiceImpl.java new file mode 100644 index 00000000..cdcedd81 --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/impl/YxStoreCustomerServiceImpl.java @@ -0,0 +1,84 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.service.impl; + +import co.yixiang.modules.customer.domain.YxStoreCustomer; +import co.yixiang.common.service.impl.BaseServiceImpl; +import lombok.AllArgsConstructor; +import co.yixiang.dozer.service.IGenerator; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import co.yixiang.common.utils.QueryHelpPlus; +import co.yixiang.utils.ValidationUtil; +import co.yixiang.utils.FileUtil; +import co.yixiang.modules.customer.service.YxStoreCustomerService; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerDto; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerQueryCriteria; +import co.yixiang.modules.customer.service.mapper.YxStoreCustomerMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +// 默认不使用缓存 +//import org.springframework.cache.annotation.CacheConfig; +//import org.springframework.cache.annotation.CacheEvict; +//import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import java.util.List; +import java.util.Map; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import co.yixiang.domain.PageResult; +/** +* @author Bug +* @date 2020-12-10 +*/ +@Service +@AllArgsConstructor +//@CacheConfig(cacheNames = "yxStoreCustomer") +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class YxStoreCustomerServiceImpl extends BaseServiceImpl implements YxStoreCustomerService { + + private final IGenerator generator; + + @Override + //@Cacheable + public PageResult queryAll(YxStoreCustomerQueryCriteria criteria, Pageable pageable) { + getPage(pageable); + PageInfo page = new PageInfo<>(queryAll(criteria)); + return generator.convertPageInfo(page,YxStoreCustomerDto.class); + } + + + @Override + //@Cacheable + public List queryAll(YxStoreCustomerQueryCriteria criteria){ + return baseMapper.selectList(QueryHelpPlus.getPredicate(YxStoreCustomer.class, criteria)); + } + + + @Override + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (YxStoreCustomerDto yxStoreCustomer : all) { + Map map = new LinkedHashMap<>(); + map.put("用户昵称", yxStoreCustomer.getNickName()); + map.put("openId", yxStoreCustomer.getOpenId()); + map.put("备注", yxStoreCustomer.getRemark()); + map.put("添加时间", yxStoreCustomer.getCreateTime()); + map.put("修改时间", yxStoreCustomer.getUpdateTime()); + map.put(" isDel", yxStoreCustomer.getIsDel()); + map.put("是否启用", yxStoreCustomer.getIsEnable()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/service/mapper/YxStoreCustomerMapper.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/mapper/YxStoreCustomerMapper.java new file mode 100644 index 00000000..a2feea1a --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/service/mapper/YxStoreCustomerMapper.java @@ -0,0 +1,23 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.service.mapper; + +import co.yixiang.common.mapper.CoreMapper; +import co.yixiang.modules.customer.domain.YxStoreCustomer; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +/** +* @author Bug +* @date 2020-12-10 +*/ +@Repository +public interface YxStoreCustomerMapper extends CoreMapper { + +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/customer/vo/YzCustomerVo.java b/yshop-mall/src/main/java/co/yixiang/modules/customer/vo/YzCustomerVo.java new file mode 100644 index 00000000..6a254bfc --- /dev/null +++ b/yshop-mall/src/main/java/co/yixiang/modules/customer/vo/YzCustomerVo.java @@ -0,0 +1,43 @@ +package co.yixiang.modules.customer.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 订单通知用户表 接收订单通知的用户 查询结果对象 + *

+ * + * @author LionCity + * @date 2020-04-02 + */ +@Data +@ApiModel(description = "订单通知用户表") +public class YzCustomerVo implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "openId") + private String openId; + + @ApiModelProperty(value = "备注") + private String remark; + + + @ApiModelProperty(value = "创建时间 创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新时间 最后更新时间") + private Date updateTime; + +} \ No newline at end of file diff --git a/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/QrCodeController.java b/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/QrCodeController.java new file mode 100644 index 00000000..6653895f --- /dev/null +++ b/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/QrCodeController.java @@ -0,0 +1,117 @@ +package co.yixiang.modules.customer.rest; + +import cn.hutool.core.util.StrUtil; +import co.yixiang.annotation.AnonymousAccess; +import co.yixiang.constant.ShopConstants; +import co.yixiang.exception.BadRequestException; +import co.yixiang.modules.mp.config.WxMpConfiguration; +import co.yixiang.utils.RecodeUtil; +import co.yixiang.utils.RedisUtil; +import co.yixiang.utils.RedisUtils; +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.Api; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.mp.bean.result.WxMpUser; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; + +/** + * @author lioncity + * @date 2020-03-21 + */ +@Slf4j +@Api(tags = "微信") +@Controller +@RequestMapping("/api/wxmp") +@AllArgsConstructor +public class QrCodeController { + + private final RedisUtils redisUtils; + /** + * 生成微信图片二维码 + * + * @param request + * @param response + * @ + */ + @AnonymousAccess + @GetMapping("/qrcode") + public void qrcode(HttpServletRequest request, HttpServletResponse response, @RequestParam("key") String key) { + String adminApiUrl = redisUtils.getY(ShopConstants.ADMIN_API_URL); + if(StrUtil.isBlank(adminApiUrl)){ + throw new BadRequestException("请配置后台-->商城配置-->商城系统配置-->后台Api地址"); + } + final WxMpService wxService = WxMpConfiguration.getWxMpService(); + if (wxService == null) { + throw new IllegalArgumentException("未找到对应配置的服务,请核实!"); + } + String state = key; + String url = adminApiUrl + "/api/wxmp/userInfo"; + String redirectURL = wxService.getOAuth2Service().buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, URLEncoder.encode(state)); + log.info("【微信网页授权】获取code,redirectURL={}", redirectURL); + //调用工具类,生成二维码 + //180为图片高度和宽度 + RecodeUtil.creatRrCode(redirectURL, 180, 180, response); + } + + @AnonymousAccess + @GetMapping("/wechatCode") + public ResponseEntity wechatCode() { + String wechatFollowImg = redisUtils.getY(ShopConstants.WECHAT_FOLLOW_IMG); + if(StrUtil.isBlank(wechatFollowImg)){ + throw new BadRequestException("请配置后台-->微信管理-->公众号配置->关注二维码"); + } + return ResponseEntity.ok(wechatFollowImg); + } + + @AnonymousAccess + @ResponseBody + @GetMapping("/userInfo") + public void userInfo(HttpServletRequest request, @RequestParam("code") String code, + @RequestParam("state") String key) throws Exception { + log.info("【微信网页授权】code={}", code); + log.info("【微信网页授权】state={}", key); + final WxMpService wxService = WxMpConfiguration.getWxMpService(); + if (wxService == null) { + throw new IllegalArgumentException("未找到对应配置的服务,请核实!"); + } + try { + WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxService.getOAuth2Service().getAccessToken(code); + WxMpUser wxMpUser = wxService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, "zh_CN"); + RedisUtil.set("qrCode:" + key, wxMpOAuth2AccessToken.getOpenId() + ":" + wxMpUser.getNickname()); + log.info("【微信网页授权】wxMpUser={}", wxMpUser); + } catch (WxErrorException e) { + log.info("【微信网页授权】{}", e); + throw new Exception(e.getError().getErrorMsg()); + } + } + + @ResponseBody + @GetMapping("/getOpenId") + public ResponseEntity userInfo(HttpServletRequest request, @RequestParam("key") String key) { + String openId = RedisUtil.get("qrCode:" + key); + if (openId != null) { + String[] str = openId.split(":"); + JSONObject json = new JSONObject(); + json.put("openId", str[0]); + json.put("nickName", str[1]); + return new ResponseEntity(json, HttpStatus.OK); + } + return new ResponseEntity(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/YxStoreCustomerController.java b/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/YxStoreCustomerController.java new file mode 100644 index 00000000..ad169694 --- /dev/null +++ b/yshop-shop/src/main/java/co/yixiang/modules/customer/rest/YxStoreCustomerController.java @@ -0,0 +1,89 @@ +/** +* Copyright (C) 2018-2020 +* All rights reserved, Designed By www.yixiang.co +* 注意: +* 本软件为www.yixiang.co开发研制,未经购买不得使用 +* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台) +* 一经发现盗用、分享等行为,将追究法律责任,后果自负 +*/ +package co.yixiang.modules.customer.rest; +import java.util.Arrays; +import co.yixiang.dozer.service.IGenerator; +import co.yixiang.exception.BadRequestException; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.AllArgsConstructor; +import co.yixiang.logging.aop.log.Log; +import co.yixiang.modules.customer.domain.YxStoreCustomer; +import co.yixiang.modules.customer.service.YxStoreCustomerService; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerQueryCriteria; +import co.yixiang.modules.customer.service.dto.YxStoreCustomerDto; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import co.yixiang.domain.PageResult; +/** +* @author Bug +* @date 2020-12-10 +*/ +@AllArgsConstructor +@Api(tags = "customer管理") +@RestController +@RequestMapping("/api/yxStoreCustomer") +public class YxStoreCustomerController { + + private final YxStoreCustomerService yxStoreCustomerService; + private final IGenerator generator; + + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('admin','yxStoreCustomer:list')") + public void download(HttpServletResponse response, YxStoreCustomerQueryCriteria criteria) throws IOException { + yxStoreCustomerService.download(generator.convert(yxStoreCustomerService.queryAll(criteria), YxStoreCustomerDto.class), response); + } + + @GetMapping + @Log("查询customer") + @ApiOperation("查询customer") + @PreAuthorize("@el.check('admin','yxStoreCustomer:list')") + public ResponseEntity> getYxStoreCustomers(YxStoreCustomerQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(yxStoreCustomerService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @PostMapping + @Log("新增customer") + @ApiOperation("新增customer") + @PreAuthorize("@el.check('admin','yxStoreCustomer:add')") + public ResponseEntity create(@Validated @RequestBody YxStoreCustomer resources){ + int count = yxStoreCustomerService.count(new LambdaQueryWrapper().eq(YxStoreCustomer::getOpenId, resources.getOpenId())); + if (count > 0) throw new BadRequestException("当前用户已存在,请勿重复提交"); + return new ResponseEntity<>(yxStoreCustomerService.save(resources),HttpStatus.CREATED); + } + + @PutMapping + @Log("修改customer") + @ApiOperation("修改customer") + @PreAuthorize("@el.check('admin','yxStoreCustomer:edit')") + public ResponseEntity update(@Validated @RequestBody YxStoreCustomer resources){ + yxStoreCustomerService.updateById(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除customer") + @ApiOperation("删除customer") + @PreAuthorize("@el.check('admin','yxStoreCustomer:del')") + @DeleteMapping + public ResponseEntity deleteAll(@RequestBody Long[] ids) { + Arrays.asList(ids).forEach(id->{ + yxStoreCustomerService.removeById(id); + }); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/yshop-tools/src/main/java/co/yixiang/tools/rest/UploadController.java b/yshop-tools/src/main/java/co/yixiang/tools/rest/UploadController.java index 2c29c6f9..6a4c1977 100644 --- a/yshop-tools/src/main/java/co/yixiang/tools/rest/UploadController.java +++ b/yshop-tools/src/main/java/co/yixiang/tools/rest/UploadController.java @@ -8,6 +8,7 @@ package co.yixiang.tools.rest; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import co.yixiang.api.YshopException; +import co.yixiang.constant.ShopConstants; import co.yixiang.enums.ShopCommonEnum; import co.yixiang.tools.domain.QiniuContent; import co.yixiang.tools.service.LocalStorageService; @@ -56,7 +57,8 @@ public class UploadController { public ResponseEntity create(@RequestParam(defaultValue = "") String name, @RequestParam(defaultValue = "") String type, @RequestParam("file") MultipartFile[] files) { - String localUrl = redisUtils.getY("admin_api_url"); + + String localUrl = redisUtils.getY(ShopConstants.ADMIN_API_URL); if(StrUtil.isBlank(type)){ localUrl = redisUtils.getY("api_url") + "/api"; } diff --git a/yshop-weixin/src/main/java/co/yixiang/modules/mp/listener/TemplateListener.java b/yshop-weixin/src/main/java/co/yixiang/modules/mp/listener/TemplateListener.java index 3cf48d7d..da792275 100644 --- a/yshop-weixin/src/main/java/co/yixiang/modules/mp/listener/TemplateListener.java +++ b/yshop-weixin/src/main/java/co/yixiang/modules/mp/listener/TemplateListener.java @@ -11,6 +11,8 @@ package co.yixiang.modules.mp.listener; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import co.yixiang.constant.ShopConstants; import co.yixiang.enums.BillDetailEnum; import co.yixiang.enums.PayTypeEnum; import co.yixiang.event.TemplateBean; @@ -20,13 +22,17 @@ import co.yixiang.exception.BadRequestException; import co.yixiang.message.rocketmq.MqProducer; import co.yixiang.modules.activity.domain.YxUserExtract; import co.yixiang.modules.activity.service.YxUserExtractService; +import co.yixiang.modules.customer.domain.YxStoreCustomer; +import co.yixiang.modules.customer.service.YxStoreCustomerService; import co.yixiang.modules.mp.service.WeiXinSubscribeService; import co.yixiang.modules.mp.service.WeixinPayService; import co.yixiang.modules.mp.service.WeixinTemplateService; +import co.yixiang.modules.order.vo.YxStoreOrderQueryVo; import co.yixiang.modules.user.domain.YxUser; import co.yixiang.modules.user.service.YxUserBillService; import co.yixiang.modules.user.service.YxUserService; import co.yixiang.modules.user.service.dto.WechatUserDto; +import co.yixiang.utils.DateUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.binarywang.wxpay.exception.WxPayException; import lombok.extern.slf4j.Slf4j; @@ -37,7 +43,9 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.UUID; /** @@ -61,6 +69,8 @@ public class TemplateListener implements SmartApplicationListener { private WeixinPayService payService; @Autowired private YxUserBillService billService; + @Autowired + private YxStoreCustomerService yxStoreCustomerService; //@Autowired //private MqProducer mqProducer; @@ -83,6 +93,18 @@ public class TemplateListener implements SmartApplicationListener { , templateBean.getPrice(), templateBean.getUid()); weiXinSubscribeService.paySuccessNotice(templateBean.getOrderId() , templateBean.getPrice(), templateBean.getUid()); + /**************给客服发送消息**************/ + try { + List yxStoreCustomers = yxStoreCustomerService.list(new LambdaQueryWrapper().eq(YxStoreCustomer::getIsEnable, ShopConstants.YSHOP_ONE_NUM)); + yxStoreCustomers.forEach(msg -> { + if (StrUtil.isNotBlank(msg.getOpenId())) { + weixinTemplateService.paySuccessNoticeToKefu(templateBean.getOrderId() + , templateBean.getPrice(), templateBean.getUid()); + } + }); + } catch (Exception e) { + log.error("消息发送失败:{}", e); + } break; case TYPE_2: //处理退款与消息 @@ -114,7 +136,7 @@ public class TemplateListener implements SmartApplicationListener { YxUser user = userService.getById(resources.getUid()); if (user != null) { WechatUserDto wechatUser = user.getWxProfile(); - if (ObjectUtil.isNotNull(wechatUser)&&ObjectUtil.isNotNull(wechatUser.getRoutineOpenid())) { + if (ObjectUtil.isNotNull(wechatUser) && ObjectUtil.isNotNull(wechatUser.getRoutineOpenid())) { try { String nonce_str = UUID.randomUUID().toString().replace("-", ""); payService.entPay(wechatUser.getRoutineOpenid(), nonce_str, @@ -122,7 +144,7 @@ public class TemplateListener implements SmartApplicationListener { resources.getExtractPrice().multiply(new BigDecimal(100)).intValue()); success = true; } catch (WxPayException e) { - log.error("退款失败,原因:{}",e.getMessage()); + log.error("退款失败,原因:{}", e.getMessage()); } } } @@ -140,8 +162,6 @@ public class TemplateListener implements SmartApplicationListener { } - - break; default: //todo diff --git a/yshop-weixin/src/main/java/co/yixiang/modules/mp/service/WeixinTemplateService.java b/yshop-weixin/src/main/java/co/yixiang/modules/mp/service/WeixinTemplateService.java index d9d778cb..a7a07382 100644 --- a/yshop-weixin/src/main/java/co/yixiang/modules/mp/service/WeixinTemplateService.java +++ b/yshop-weixin/src/main/java/co/yixiang/modules/mp/service/WeixinTemplateService.java @@ -12,14 +12,17 @@ import cn.hutool.core.util.StrUtil; import co.yixiang.api.YshopException; import co.yixiang.constant.ShopConstants; import co.yixiang.enums.ShopCommonEnum; +import co.yixiang.exception.BadRequestException; import co.yixiang.modules.mp.config.WxMpConfiguration; import co.yixiang.modules.mp.domain.YxWechatTemplate; import co.yixiang.modules.user.domain.YxUser; import co.yixiang.modules.user.service.YxUserService; import co.yixiang.modules.user.service.dto.WechatUserDto; import co.yixiang.modules.mp.enums.WechatTempateEnum; +import co.yixiang.utils.RedisUtil; import co.yixiang.utils.RedisUtils; import co.yixiang.utils.ShopKeyUtils; +import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; @@ -35,6 +38,7 @@ import java.util.Map; * @Author hupeng <610796224@qq.com> * @Date 2020/6/27 **/ +@Slf4j @Service public class WeixinTemplateService { @@ -101,6 +105,42 @@ public class WeixinTemplateService { } } + + /** + * 支付成功通知给客服 + * + * @param orderId + * @param price + * @param uid + */ + public void paySuccessNoticeToKefu(String orderId,String price,Long uid) { + Map map = new HashMap<>(); + map.put("first", "尊敬的客服,您有新订单了"); + map.put("keyword1",orderId); + map.put("keyword2",price); + map.put("remark",ShopConstants.YSHOP_WECHAT_PUSH_REMARK); + String tempId = this.getTempId(WechatTempateEnum.PAY_SUCCESS.getValue()); + String appId=RedisUtil.get(ShopKeyUtils.getWxAppAppId()); + if(StrUtil.isNotBlank(tempId)) { + String openid = this.getUserOpenid(uid); + if(StrUtil.isBlank(openid)) { + return; + } + if(StrUtil.isBlank(appId)){ + this.sendWxMpTemplateMessage( openid,tempId, this.getSiteUrl()+"/order/detail/"+orderId,map); + }else{ + WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram(); + miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId())); + miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId); + this.sendWxMpTemplateMessageToWx(openid, tempId, miniProgram, map); + } + } + + + + } + + /** * 退款成功通知 * @param orderId 订单号 @@ -183,6 +223,29 @@ public class WeixinTemplateService { return msgId; } + + + + public String sendWxMpTemplateMessageToWx(String openId, String templateId, WxMpTemplateMessage.MiniProgram miniProgram, Map map) { + WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() + .toUser(openId) + .templateId(templateId) + .miniProgram(miniProgram) + .build(); + map.forEach((k, v) -> { + templateMessage.addData(new WxMpTemplateData(k, v, "#000000")); + }); + String msgId = null; + WxMpService wxService = WxMpConfiguration.getWxMpService(); + try { + msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage); + } catch (WxErrorException e) { + log.error(e.getMessage(), e); + } + return msgId; + } + + /** * 获取模板消息id * @param key 模板key