Commit d4d7e53e by Wangmin

Merge remote-tracking branch 'origin/dev' into dev

parents e3be8c9b 4599979f
......@@ -246,7 +246,7 @@ xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice,/system/hospital
excludes: /system/notice,/system/hospital,/system/goods
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
......@@ -287,12 +287,15 @@ wechat:
aesKey: #微信小程序消息服务器配置的EncodingAESKey
msgDataFormat: JSON
pay:
mch-id: 1640662528
mch-key: FogyUzGHMnsoUU3exYyDO8DEKEtNjsSx
key-path: classpath:/apiclient_cert.p12
appId: wx6cc2fd1bca9472ae #微信公众号或者小程序等的appid
mchId: 1640662528 #微信支付商户号
mchKey: FogyUzGHMnsoUU3exYyDO8DEKEtNjsSx #微信支付商户密钥
keyPath: classpath:/apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
--- # 文件上传设置
file:
#upload-path: /www/wwwroot/pz/upload
upload-path: D:/www/wwwroot/pz/upload
#注意:响应路径必须加上file后缀
response-path: https://www.pz.com/file
......@@ -52,6 +52,12 @@
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.39</version>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
......@@ -172,7 +178,11 @@
<version>4.5.5.B</version>
</dependency>
<!--微信支付-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>4.5.0</version>
</dependency>
</dependencies>
</project>
......@@ -13,6 +13,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class WechatPayProperties {
/**
* 设置微信公众号或者小程序等的appid
*/
private String appId;
/**
* 微信支付商户号
*/
private String mchId;
......
package com.pz.common.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Binary Wang
*/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WechatPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
private WechatPayProperties properties;
@Bean
@ConditionalOnMissingBean
public WxPayService wxService() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
// 可以指定是否使用沙箱环境
payConfig.setUseSandboxEnv(false);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
}
......@@ -42,6 +42,11 @@ public class SysUser extends BaseEntity {
private String openId;
/**
* 微信公众号openid
*/
private String wxOpenid;
/**
* 部门ID
*/
private Long deptId;
......
package com.pz.common.response;
import lombok.Data;
@Data
public class WxAuthResponse {
private String access_token;
private String openid;
private String expires_in;
private String refresh_token;
private String scope;
}
......@@ -6,20 +6,28 @@ import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSONObject;
import com.pz.common.constant.Constants;
import com.pz.common.core.controller.BaseController;
import com.pz.common.core.domain.R;
import com.pz.common.core.domain.entity.SysUser;
import com.pz.common.exception.ServiceException;
import com.pz.common.response.WxAuthResponse;
import com.pz.common.utils.StringUtils;
import com.pz.common.config.WechatConfiguration;
import com.pz.merchant.domain.WechatUserInfo;
import com.pz.merchant.domain.bo.WechatLoginBo;
import com.pz.system.mapper.SysUserMapper;
import com.pz.system.service.ISysUserService;
import com.pz.system.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
/**
......@@ -38,6 +46,8 @@ public class WechatLoginController extends BaseController {
private final SysLoginService loginService;
private final SysUserMapper sysUserMapper;
/**
* 登录
*
......@@ -71,6 +81,25 @@ public class WechatLoginController extends BaseController {
}
/**
* 解析公众号openid重定向
*/
@SaIgnore
@GetMapping("wxopenid")
public void wxopenid(String userId, String code, String state, HttpServletResponse response) throws IOException {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx6cc2fd1bca9472ae&secret=2edf95828b1a19fc5149f6650cde71f1&code=" + code
+ "&grant_type=authorization_code";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(url, String.class);
WxAuthResponse authResponse = JSONObject.parseObject(result, WxAuthResponse.class);
String mpOpenId = authResponse.getOpenid();
SysUser sysUser = new SysUser();
sysUser.setUserId(Long.valueOf(userId));
sysUser.setWxOpenid(mpOpenId);
sysUserMapper.updateById(sysUser);
response.sendRedirect("https://peizheng.shanpeikj.com/wx/index.html");
}
/**
* 注销
*/
@GetMapping("logout")
......
......@@ -4,7 +4,9 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.pz.common.annotation.ExcelDictFormat;
import com.pz.common.convert.ExcelDictConvert;
import com.pz.common.core.domain.BaseEntity;
import com.pz.system.domain.Carousel;
import com.pz.system.domain.StoreGoodsTag;
import lombok.Data;
import java.util.List;
......@@ -18,7 +20,7 @@ import java.util.List;
*/
@Data
@ExcelIgnoreUnannotated
public class StoreGoodsVo {
public class StoreGoodsVo extends BaseEntity {
private static final long serialVersionUID = 1L;
......@@ -109,4 +111,8 @@ public class StoreGoodsVo {
private List<Carousel> carousel;
private List<Integer> ids;
private List<StoreGoodsTagVo> list;
private String typeName;
}
package com.pz.system.service;
import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.pz.common.core.domain.PageQuery;
import com.pz.common.core.page.TableDataInfo;
import com.pz.system.domain.bo.CityBo;
import com.pz.system.domain.vo.CityVo;
import java.util.Collection;
import java.util.List;
/**
* 城市Service接口
*
* @author ruoyi
* @date 2023-09-07
*/
public interface IPayService {
/**
* <pre>
* 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
* 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
* 需要调用查询接口的情况:
* ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
* ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
* ◆ 调用被扫支付API,返回USERPAYING的状态;
* ◆ 调用关单或撤销接口API之前,需确认支付状态;
* 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
* </pre>
*
* @param transactionId 微信订单号
* @param outTradeNo 商户系统内部的订单号,当没提供transactionId时需要传这个。
*/
WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxPayException;
/**
* 统一下单
* 调用统一下单接口,并组装生成支付所需参数对象.
*
* @param request 统一下单请求参数
* @param <T> 请使用{@link com.github.binarywang.wxpay.bean.order}包下的类
* @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
*/
<T> T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException;
/**
* <pre>
* 微信支付-申请退款
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
* 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
* </pre>
*
* @param request 请求对象
* @return 退款操作结果
*/
WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException;
/**
* <pre>
* 微信支付-查询退款
* 应用场景:
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
* 银行卡支付的退款3个工作日后重新查询退款状态。
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
* 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
* </pre>
* 以下四个参数四选一
*
* @param transactionId 微信订单号
* @param outTradeNo 商户订单号
* @param outRefundNo 商户退款单号
* @param refundId 微信退款单号
* @return 退款信息
*/
WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxPayException;
/**
* 支付回调通知处理
* 微信请求的接口,要求可以公网访问,要放开token校验
* @param xmlData 微信提交的请求参数
*/
String parseOrderNotifyResult(String xmlData) throws WxPayException;
/**
* 退款回调通知处理
* 微信请求的接口,要求可以公网访问,要放开token校验
* @param xmlData 微信提交的请求参数
*/
String parseRefundNotifyResult(String xmlData) throws WxPayException;
}
package com.pz.system.service;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pz.common.constant.CacheConstants;
......@@ -23,10 +25,8 @@ import com.pz.common.exception.user.CaptchaException;
import com.pz.common.exception.user.CaptchaExpireException;
import com.pz.common.exception.user.UserException;
import com.pz.common.helper.LoginHelper;
import com.pz.common.utils.DateUtils;
import com.pz.common.utils.MessageUtils;
import com.pz.common.utils.ServletUtils;
import com.pz.common.utils.StringUtils;
import com.pz.common.response.WxAuthResponse;
import com.pz.common.utils.*;
import com.pz.common.utils.redis.RedisUtils;
import com.pz.common.utils.spring.SpringUtils;
import com.pz.merchant.domain.WechatUserInfo;
......@@ -36,7 +36,11 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.function.Supplier;
......@@ -151,7 +155,7 @@ public class SysLoginService {
public String xccLogin(WechatUserInfo loginBo) {
SysUser user = loadUserByOpenid(loginBo.getOpenId());
if (user == null) {
SysUser userByPhone = userMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhonenumber,loginBo.getMobilePhone()));
SysUser userByPhone = userMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhonenumber, loginBo.getMobilePhone()));
// 若该手机号已经被注册,则直接绑定OpenID
if (userByPhone != null) {
userByPhone.setOpenId(loginBo.getOpenId());
......@@ -189,6 +193,7 @@ public class SysLoginService {
return StpUtil.getTokenValue();
}
/**
* 退出登录
*/
......
package com.pz.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult;
import com.github.binarywang.wxpay.bean.request.*;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.pz.common.core.domain.PageQuery;
import com.pz.common.core.page.TableDataInfo;
import com.pz.system.domain.City;
import com.pz.system.domain.bo.CityBo;
import com.pz.system.domain.vo.CityVo;
import com.pz.system.mapper.CityMapper;
import com.pz.system.service.ICityService;
import com.pz.system.service.IPayService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import java.io.File;
import java.util.Collection;
import java.util.List;
/**
* 城市Service业务层处理
*
* @author ruoyi
* @date 2023-09-07
*/
@RequiredArgsConstructor
@Service
public class PayServiceImpl implements IPayService {
@Autowired
private WxPayService wxService;
/**
* <pre>
* 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
* 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
* 需要调用查询接口的情况:
* ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
* ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
* ◆ 调用被扫支付API,返回USERPAYING的状态;
* ◆ 调用关单或撤销接口API之前,需确认支付状态;
* 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
* </pre>
*
* @param transactionId 微信订单号
* @param outTradeNo 商户系统内部的订单号,当没提供transactionId时需要传这个。
*/
@Override
public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxPayException {
return this.wxService.queryOrder(transactionId, outTradeNo);
}
/**
* 调用统一下单接口,并组装生成支付所需参数对象.
*
* @param request 统一下单请求参数
* @param <T> 请使用{@link com.github.binarywang.wxpay.bean.order}包下的类
* @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
*/
@Override
public <T> T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
return this.wxService.createOrder(request);
}
/**
* <pre>
* 微信支付-申请退款
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
* 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
* </pre>
*
* @param request 请求对象
* @return 退款操作结果
*/
@Override
public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException {
return this.wxService.refund(request);
}
/**
* <pre>
* 微信支付-查询退款
* 应用场景:
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
* 银行卡支付的退款3个工作日后重新查询退款状态。
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
* 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
* </pre>
* 以下四个参数四选一
*
* @param transactionId 微信订单号
* @param outTradeNo 商户订单号
* @param outRefundNo 商户退款单号
* @param refundId 微信退款单号
* @return 退款信息
*/
@Override
public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo,String outRefundNo,String refundId) throws WxPayException {
return this.wxService.refundQuery(transactionId, outTradeNo, outRefundNo, refundId);
}
/**
* 支付回调通知处理
* @param xmlData
* @return
* @throws WxPayException
*/
@Override
public String parseOrderNotifyResult(String xmlData) throws WxPayException {
// 参数解析
final WxPayOrderNotifyResult notifyResult = this.wxService.parseOrderNotifyResult(xmlData);
// TODO 根据自己业务场景需要构造返回对象
return WxPayNotifyResponse.success("成功");
}
/**
* 退款回调通知处理
* @param xmlData
* @return
* @throws WxPayException
*/
@Override
public String parseRefundNotifyResult(String xmlData) throws WxPayException {
// 参数解析
final WxPayRefundNotifyResult result = this.wxService.parseRefundNotifyResult(xmlData);
// TODO 根据自己业务场景需要构造返回对象
return WxPayNotifyResponse.success("成功");
}
}
......@@ -11,8 +11,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pz.common.utils.JsonUtils;
import com.pz.system.domain.StoreApply;
import com.pz.system.domain.StoreGoodsTag;
import com.pz.system.domain.vo.StoreApplyVo;
import com.pz.system.mapper.StoreApplyMapper;
import com.pz.system.mapper.StoreGoodsCategoryMapper;
import com.pz.system.mapper.StoreGoodsTagMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
......@@ -43,12 +45,20 @@ public class StoreGoodsServiceImpl implements IStoreGoodsService {
private final StoreGoodsTagMapper goodsTagMapper;
private final StoreGoodsCategoryMapper storeGoodsCategoryMapper;
/**
* 查询商品
*/
@Override
public StoreGoodsVo queryById(Integer id) {
return baseMapper.selectVoById(id);
StoreGoodsVo storeGoodsVo = baseMapper.selectVoById(id);
if (StringUtils.isNotBlank(storeGoodsVo.getTags())) {
List<Integer> ids = JsonUtils.parseArray(storeGoodsVo.getTags(), Integer.class);
//查询商品标签
storeGoodsVo.setList(goodsTagMapper.selectVoList(new LambdaQueryWrapper<StoreGoodsTag>().in(StoreGoodsTag::getId, ids)));
}
return storeGoodsVo;
}
/**
......@@ -75,8 +85,14 @@ public class StoreGoodsServiceImpl implements IStoreGoodsService {
storeGoodsVos.forEach(storeGoodsVo -> {
if (StringUtils.isNotBlank(storeGoodsVo.getTags())) {
List<Integer> ids = JsonUtils.parseArray(storeGoodsVo.getTags(), Integer.class);
storeGoodsVo.setIds(ids);
//查询商品标签
storeGoodsVo.setList(goodsTagMapper.selectVoList(new LambdaQueryWrapper<StoreGoodsTag>().in(StoreGoodsTag::getId, ids)));
}
if (null != storeGoodsVo.getCategoryId()) {
Optional.ofNullable(storeGoodsCategoryMapper.selectVoById(storeGoodsVo.getCategoryId()))
.ifPresent(storeGoodsCategoryVo -> {
storeGoodsVo.setTypeName(storeGoodsCategoryVo.getTitle());
});
}
});
});
......@@ -162,7 +178,10 @@ public class StoreGoodsServiceImpl implements IStoreGoodsService {
@Override
public Boolean updateByBo(StoreGoodsBo bo) {
StoreGoods update = BeanUtil.toBean(bo, StoreGoods.class);
validEntityBeforeSave(update);
if (CollectionUtils.isNotEmpty(bo.getTagIds())) {
String tags = JsonUtils.toJsonString(bo.getTagIds());
update.setTags(tags);
}
return baseMapper.updateById(update) > 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment