发布通告功能
This commit is contained in:
parent
79a2286006
commit
4d25ae90c8
@ -16,7 +16,17 @@
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--微信支付SDK-->
|
||||
<dependency>
|
||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||
<artifactId>wechatpay-apache-httpclient</artifactId>
|
||||
<version>0.4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||
<artifactId>wechatpay-java</artifactId>
|
||||
<version>0.2.12</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-devtools -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
147
ruoyi-admin/src/main/java/com/ruoyi/api/PayApi.java
Normal file
147
ruoyi-admin/src/main/java/com/ruoyi/api/PayApi.java
Normal file
@ -0,0 +1,147 @@
|
||||
package com.ruoyi.api;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.payConfig.WechatPayConfig;
|
||||
import com.ruoyi.payConfig.WechatPayRequest;
|
||||
import com.ruoyi.payConfig.WechatPayUrlEnum;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.*;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/payApi")
|
||||
public class PayApi {
|
||||
@Resource
|
||||
private WechatPayConfig wechatPayConfig;
|
||||
@Resource
|
||||
private WechatPayRequest wechatPayRequest;
|
||||
/**
|
||||
* type:h5、jsapi、app、native、sub_jsapi
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value = "统一下单-统一接口", notes = "统一下单-统一接口")
|
||||
@GetMapping("/prepayment")
|
||||
public Map<String,Object> transactions(String type, Long orderNo, String payType) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException {
|
||||
SysUser user = SecurityUtils.getLoginUser().getUser();
|
||||
// 统一参数封装
|
||||
Map<String, Object> params = new HashMap<>(8);
|
||||
params.put("appid", wechatPayConfig.getAppId());
|
||||
params.put("mchid", wechatPayConfig.getMchId());
|
||||
params.put("description", driveSchoolCourse.getName());
|
||||
params.put("out_trade_no", orderNo.toString());
|
||||
params.put("notify_url", wechatPayConfig.getNotifyUrl());
|
||||
Map<String, Object> amountMap = new HashMap<>(4);
|
||||
|
||||
// 金额单位为分
|
||||
amountMap.put("total", amount.intValue());
|
||||
//人民币
|
||||
amountMap.put("currency", "CNY");
|
||||
params.put("amount", amountMap);
|
||||
|
||||
// 场景信息
|
||||
Map<String, Object> sceneInfoMap = new HashMap<>(4);
|
||||
// 客户端IP
|
||||
sceneInfoMap.put("payer_client_ip", "127.0.0.1");
|
||||
// 商户端设备号(门店号或收银设备ID)
|
||||
sceneInfoMap.put("device_id", "127.0.0.1");
|
||||
// 除H5与JSAPI有特殊参数外,其他的支付方式都一样
|
||||
if (type.equals(WechatPayUrlEnum.H5.getType())) {
|
||||
Map<String, Object> h5InfoMap = new HashMap<>(4);
|
||||
// 场景类型:iOS, Android, Wap
|
||||
h5InfoMap.put("type", "IOS");
|
||||
sceneInfoMap.put("h5_info", h5InfoMap);
|
||||
} else if (type.equals(WechatPayUrlEnum.JSAPI.getType()) || type.equals(WechatPayUrlEnum.SUB_JSAPI.getType())) {
|
||||
Map<String, Object> payerMap = new HashMap<>(4);
|
||||
payerMap.put("openid", user.getWxOpenId());
|
||||
params.put("payer", payerMap);
|
||||
}
|
||||
params.put("scene_info", sceneInfoMap);
|
||||
String paramsStr = JSON.toJSONString(params);
|
||||
String resStr = wechatPayRequest.wechatHttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",paramsStr);
|
||||
Map<String, Object> resMap = JSONObject.parseObject(resStr, new TypeReference<Map<String, Object>>(){});
|
||||
return paySignMsg(resMap.get("prepay_id").toString(), wechatPayConfig.getAppId(),null);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "支付回调", notes = "支付回调")
|
||||
@PostMapping("/payNotify")
|
||||
public Map<String, String> payNotify(@RequestBody JSONObject jsonObject) throws GeneralSecurityException, IOException {
|
||||
String key = wechatPayConfig.getApiV3Key();
|
||||
String json = jsonObject.toString();
|
||||
String associated_data = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.associated_data");
|
||||
String ciphertext = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.ciphertext");
|
||||
String nonce = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.nonce");
|
||||
String decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString(associated_data.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
|
||||
//验签成功
|
||||
JSONObject decryptDataObj = JSONObject.parseObject(decryptData, JSONObject.class);
|
||||
String orderNo = decryptDataObj.get("out_trade_no").toString();
|
||||
//调用业务系统
|
||||
Map<String, String> res = new HashMap<>();
|
||||
res.put("code", "SUCCESS");
|
||||
res.put("message", "成功");
|
||||
return res;
|
||||
}
|
||||
|
||||
String buildMessage(String appId, String timestamp,String nonceStr,String prepay_id) {
|
||||
|
||||
return appId + "\n"
|
||||
+ timestamp + "\n"
|
||||
+ nonceStr + "\n"
|
||||
+ prepay_id + "\n";
|
||||
}
|
||||
|
||||
String sign(byte[] message,String privateKeyStr) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {
|
||||
//签名方式
|
||||
Signature sign = Signature.getInstance("SHA256withRSA");
|
||||
//私钥,通过MyPrivateKey来获取,这是个静态类可以接调用方法 ,需要的是_key.pem文件的绝对路径配上文件名
|
||||
PrivateKey privateKey =null;
|
||||
if (StringUtils.isNotEmpty(privateKeyStr)){
|
||||
privateKey = PemUtil.loadPrivateKey(privateKeyStr);
|
||||
}else {
|
||||
privateKey = wechatPayConfig.getPrivateKey(wechatPayConfig.getKeyPemPath());
|
||||
}
|
||||
|
||||
sign.initSign(privateKey);
|
||||
sign.update(message);
|
||||
return Base64.getEncoder().encodeToString(sign.sign());
|
||||
}
|
||||
|
||||
private Map<String, Object> paySignMsg(String prepayId,String appId,String privateKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
String timeStamp = timeMillis/1000+"";
|
||||
String nonceStr = timeMillis+"";
|
||||
String packageStr = "prepay_id="+prepayId;
|
||||
// 公共参数
|
||||
Map<String, Object> resMap = new HashMap<>();
|
||||
resMap.put("nonceStr",nonceStr);
|
||||
resMap.put("timeStamp",timeStamp);
|
||||
resMap.put("appId",appId);
|
||||
resMap.put("package", packageStr);
|
||||
// 使用字段appId、timeStamp、nonceStr、package进行签名
|
||||
//从下往上依次生成
|
||||
String message = buildMessage(appId, timeStamp, nonceStr, packageStr);
|
||||
//签名
|
||||
String paySign = sign(message.getBytes("utf-8"), privateKeyStr);
|
||||
resMap.put("paySign", paySign);
|
||||
resMap.put("signType", "RSA");
|
||||
return resMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -11,6 +11,7 @@ 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.ruoyi.busi.domain.BusiNoticeForm;
|
||||
import com.ruoyi.busi.domain.BusiNoticeSign;
|
||||
import com.ruoyi.busi.query.AppNoticeQuery;
|
||||
import com.ruoyi.busi.query.BusiNoticeQuery;
|
||||
import com.ruoyi.busi.service.IBusiNoticeFormService;
|
||||
@ -309,4 +310,41 @@ public class BusiNoticeController extends BaseController
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查看通告报名列表
|
||||
* @author zcy
|
||||
* @date 15:39 2025/3/29
|
||||
* @param query 查询条件
|
||||
* @param pageNum 1
|
||||
* @param pageSize 10
|
||||
* @return com.ruoyi.common.core.domain.AjaxResult
|
||||
**/
|
||||
@GetMapping("/reportList")
|
||||
public AjaxResult reportList(AppNoticeQuery query,
|
||||
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize)
|
||||
{
|
||||
Page<BusiNoticeSign> page = new Page<>(pageNum, pageSize);
|
||||
IPage<BusiNoticeSign> list = busiNoticeService.reportList(query,page);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查看通告报名数量
|
||||
* @author zcy
|
||||
* @date 15:39 2025/3/29
|
||||
* @param query 查询条件
|
||||
* @return com.ruoyi.common.core.domain.AjaxResult
|
||||
**/
|
||||
@GetMapping("/reportNum")
|
||||
public AjaxResult reportNum(AppNoticeQuery query)
|
||||
{
|
||||
JSONObject res = busiNoticeService.reportNum(query);
|
||||
return success(res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,11 @@ import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.busi.domain.BusiNotice;
|
||||
import com.ruoyi.busi.query.AppNoticeQuery;
|
||||
import com.ruoyi.busi.query.AppNoticeSign;
|
||||
import com.ruoyi.busi.service.IBusiNoticeService;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -39,6 +43,8 @@ public class BusiNoticeSignController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IBusiNoticeSignService busiNoticeSignService;
|
||||
@Autowired
|
||||
private IBusiNoticeService noticeService;
|
||||
|
||||
/**
|
||||
* 查询通告报名列表
|
||||
@ -57,14 +63,20 @@ public class BusiNoticeSignController extends BaseController
|
||||
/**
|
||||
* 导出通告报名列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('busi:sign:export')")
|
||||
|
||||
@Log(title = "通告报名", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, BusiNoticeSign busiNoticeSign)
|
||||
@GetMapping("/export")
|
||||
@Anonymous
|
||||
public void export(HttpServletResponse response, @RequestParam(name = "noticeId") String noticeId)
|
||||
{
|
||||
List<BusiNoticeSign> list = busiNoticeSignService.list();
|
||||
BusiNotice notice = noticeService.getById(noticeId);
|
||||
AppNoticeQuery query =new AppNoticeQuery();
|
||||
query.setNoticeId(noticeId);
|
||||
query.setStatus("02");
|
||||
Page<BusiNoticeSign> page = new Page<>(1, 5000);
|
||||
List<BusiNoticeSign> records = noticeService.reportList(query, page).getRecords();
|
||||
ExcelUtil<BusiNoticeSign> util = new ExcelUtil<BusiNoticeSign>(BusiNoticeSign.class);
|
||||
util.exportExcel(response, list, "通告报名数据");
|
||||
util.exportExcel(response, records, "通告:"+notice.getTitle()+"报名名称");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,4 +133,14 @@ public class BusiNoticeSignController extends BaseController
|
||||
busiNoticeSignService.userSign(appNoticeSign);
|
||||
return success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户通告报名
|
||||
*/
|
||||
@PostMapping("/chooseSign")
|
||||
public AjaxResult chooseSign(String signIds) throws Exception {
|
||||
busiNoticeSignService.chooseSign(signIds.split(","));
|
||||
return success();
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +133,7 @@ public class BusiNotice extends DlBaseEntity
|
||||
@Excel(name = "微信号")
|
||||
private String wechat;
|
||||
|
||||
|
||||
/** 电话 */
|
||||
@Excel(name = "电话")
|
||||
private String tel;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.ruoyi.busi.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@ -87,5 +88,20 @@ public class BusiNoticeSign extends DlBaseEntity
|
||||
* 报价
|
||||
*/
|
||||
private BigDecimal price;
|
||||
@TableField(exist = false)
|
||||
private String[] choosed={};
|
||||
@TableField(exist = false)
|
||||
private String platformCode;
|
||||
@TableField(exist = false)
|
||||
private String platformName;
|
||||
@TableField(exist = false)
|
||||
private String accountName;
|
||||
@TableField(exist = false)
|
||||
private Long fansNum;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.busi.domain.BusiNoticeSign;
|
||||
import com.ruoyi.busi.query.AppNoticeQuery;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@ -21,6 +22,10 @@ public interface BusiNoticeSignMapper extends BaseMapper<BusiNoticeSign>
|
||||
{
|
||||
IPage<BusiNoticeSign> queryListPage(@Param("entity") BusiNoticeSign entity, Page<BusiNoticeSign> page);
|
||||
|
||||
IPage<BusiNoticeSign> reportList( Page<BusiNoticeSign> page,@Param("entity") AppNoticeQuery entity);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查某些公告的报名数量
|
||||
* @author vinjor-M
|
||||
|
@ -36,5 +36,6 @@ public class AppNoticeQuery {
|
||||
|
||||
//'进行中', '已关闭'
|
||||
private String status;
|
||||
private String noticeId;
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.busi.domain.BusiNotice;
|
||||
import com.ruoyi.busi.domain.BusiNoticeSign;
|
||||
import com.ruoyi.busi.query.AppNoticeQuery;
|
||||
import com.ruoyi.busi.query.BusiNoticeQuery;
|
||||
import com.ruoyi.busi.vo.BusiNoticeVo;
|
||||
@ -97,6 +98,8 @@ public interface IBusiNoticeService extends IService<BusiNotice>
|
||||
IPage<BusiNoticeVo> myNoticeList(AppNoticeQuery query, Page<BusiNotice> page);
|
||||
|
||||
IPage<BusiNoticeVo> myPublishNoticeList(AppNoticeQuery query, Page<BusiNotice> page);
|
||||
IPage<BusiNoticeSign> reportList(AppNoticeQuery query, Page<BusiNoticeSign> page);
|
||||
JSONObject reportNum(AppNoticeQuery query);
|
||||
|
||||
|
||||
|
||||
|
@ -17,4 +17,5 @@ public interface IBusiNoticeSignService extends IService<BusiNoticeSign>
|
||||
{
|
||||
IPage<BusiNoticeSign> queryListPage(BusiNoticeSign pageReqVO, Page<BusiNoticeSign> page);
|
||||
void userSign(AppNoticeSign appNoticeSign) throws Exception;
|
||||
void chooseSign(String[] signIds);
|
||||
}
|
||||
|
@ -589,5 +589,29 @@ public class BusiNoticeServiceImpl extends ServiceImpl<BusiNoticeMapper,BusiNoti
|
||||
return pageList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<BusiNoticeSign> reportList(AppNoticeQuery query, Page<BusiNoticeSign> page) {
|
||||
return busiNoticeSignMapper.reportList(page,query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取报名数量
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public JSONObject reportNum(AppNoticeQuery query) {
|
||||
JSONObject result = new JSONObject();
|
||||
LambdaQueryWrapper<BusiNoticeSign> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(BusiNoticeSign::getNoticeId,query.getNoticeId()).eq(BusiNoticeSign::getStatus,"01");
|
||||
Integer i = busiNoticeSignMapper.selectCount(queryWrapper);
|
||||
result.put("waitNum",i);
|
||||
queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(BusiNoticeSign::getNoticeId,query.getNoticeId()).eq(BusiNoticeSign::getStatus,"02");
|
||||
Integer i2 = busiNoticeSignMapper.selectCount(queryWrapper);
|
||||
result.put("checkedNum",i2);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,11 +6,13 @@ import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.ruoyi.busi.query.AppNoticeSign;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@ -29,6 +31,8 @@ public class BusiNoticeSignServiceImpl extends ServiceImpl<BusiNoticeSignMapper,
|
||||
{
|
||||
@Autowired
|
||||
private BusiNoticeSignMapper busiNoticeSignMapper;
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Override
|
||||
public IPage<BusiNoticeSign> queryListPage(BusiNoticeSign pageReqVO, Page<BusiNoticeSign> page) {
|
||||
@ -46,13 +50,14 @@ public class BusiNoticeSignServiceImpl extends ServiceImpl<BusiNoticeSignMapper,
|
||||
if(busiNoticeSignMapper.selectOne(new LambdaQueryWrapper<BusiNoticeSign>().eq(BusiNoticeSign::getNoticeId, appNoticeSign.getNoticeId()).eq(BusiNoticeSign::getUserId, loginUser.getUserId()).last("limit 1"))!=null){
|
||||
throw new Exception("请勿重复报名!");
|
||||
}
|
||||
SysUser sysUser = userService.selectUserById(loginUser.getUserId());
|
||||
for (JSONObject cardInfo : appNoticeSign.getCardList()) {
|
||||
|
||||
BusiNoticeSign busiNoticeSign =new BusiNoticeSign();
|
||||
busiNoticeSign.setNoticeId(appNoticeSign.getNoticeId());
|
||||
busiNoticeSign.setUserId(loginUser.getUserId());
|
||||
busiNoticeSign.setNickname(loginUser.getUser().getNickName());
|
||||
busiNoticeSign.setAvatar(loginUser.getUser().getAvatar());
|
||||
busiNoticeSign.setNickname(sysUser.getNickName());
|
||||
busiNoticeSign.setAvatar(sysUser.getAvatar());
|
||||
busiNoticeSign.setStatus("0");
|
||||
busiNoticeSign.setFormData(JSONArray.toJSONString(appNoticeSign.getCustomForm()));
|
||||
busiNoticeSign.setCardId(cardInfo.getString("id"));
|
||||
@ -64,4 +69,17 @@ public class BusiNoticeSignServiceImpl extends ServiceImpl<BusiNoticeSignMapper,
|
||||
busiNoticeSignMapper.insert(busiNoticeSign);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中报名通过
|
||||
* @param signIds
|
||||
*/
|
||||
@Override
|
||||
public void chooseSign(String[] signIds) {
|
||||
for (String signId : signIds) {
|
||||
BusiNoticeSign noticeSign = this.getById(signId);
|
||||
noticeSign.setStatus("02");
|
||||
this.updateById(noticeSign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,162 @@
|
||||
package com.ruoyi.payConfig;
|
||||
|
||||
|
||||
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
|
||||
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
|
||||
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
|
||||
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.PrivateKey;
|
||||
|
||||
/**
|
||||
* @Author:
|
||||
* @Description:
|
||||
**/
|
||||
@Component
|
||||
@Data
|
||||
@Slf4j
|
||||
@ConfigurationProperties(prefix = "wxpay")
|
||||
public class WechatPayConfig {
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
private String appId;
|
||||
/**
|
||||
* 商户号
|
||||
*/
|
||||
private String mchId;
|
||||
/**
|
||||
* 服务商商户号
|
||||
*/
|
||||
private String slMchId;
|
||||
/**
|
||||
* APIv2密钥
|
||||
*/
|
||||
private String apiKey;
|
||||
/**
|
||||
* APIv3密钥
|
||||
*/
|
||||
private String apiV3Key;
|
||||
/**
|
||||
* 支付通知回调地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
/**
|
||||
* 退款回调地址
|
||||
*/
|
||||
private String refundNotifyUrl;
|
||||
|
||||
/**
|
||||
* API 证书中的 key.pem
|
||||
*/
|
||||
private String keyPemPath;
|
||||
|
||||
/**
|
||||
* 商户序列号
|
||||
*/
|
||||
private String serialNo;
|
||||
private String appSecret;
|
||||
/**
|
||||
* 微信支付V3-url前缀
|
||||
*/
|
||||
private String baseUrl;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取商户的私钥文件
|
||||
* @param keyPemPath
|
||||
* @return
|
||||
*/
|
||||
public PrivateKey getPrivateKey(String keyPemPath){
|
||||
log.info("进入获取");
|
||||
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(keyPemPath);
|
||||
if(inputStream==null){
|
||||
log.info("私钥文件不存在");
|
||||
throw new RuntimeException("私钥文件不存在");
|
||||
}
|
||||
log.info("存在");
|
||||
return PemUtil.loadPrivateKey(inputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取证书管理器实例
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Verifier getVerifier() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {
|
||||
|
||||
log.info("获取证书管理器实例");
|
||||
|
||||
//获取商户私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
//私钥签名对象
|
||||
PrivateKeySigner privateKeySigner = new PrivateKeySigner(serialNo, privateKey);
|
||||
|
||||
//身份认证对象
|
||||
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
|
||||
|
||||
// 使用定时更新的签名验证器,不需要传入证书
|
||||
CertificatesManager certificatesManager = CertificatesManager.getInstance();
|
||||
certificatesManager.putMerchant(mchId,wechatPay2Credentials,apiV3Key.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return certificatesManager.getVerifier(mchId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取支付http请求对象
|
||||
* @param verifier
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "wxPayClient")
|
||||
public CloseableHttpClient getWxPayClient(Verifier verifier) {
|
||||
|
||||
//获取商户私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
|
||||
.withMerchant(mchId, serialNo, privateKey)
|
||||
.withValidator(new WechatPay2Validator(verifier));
|
||||
|
||||
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HttpClient,无需进行应答签名验证,跳过验签的流程
|
||||
*/
|
||||
@Bean(name = "wxPayNoSignClient")
|
||||
public CloseableHttpClient getWxPayNoSignClient(){
|
||||
|
||||
//获取商户私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
//用于构造HttpClient
|
||||
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
|
||||
//设置商户信息
|
||||
.withMerchant(mchId, serialNo, privateKey)
|
||||
//无需进行签名验证、通过withValidator((response) -> true)实现
|
||||
.withValidator((response) -> true);
|
||||
|
||||
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
package com.ruoyi.payConfig;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @Author:
|
||||
* @Description:
|
||||
**/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WechatPayRequest {
|
||||
@Resource
|
||||
private CloseableHttpClient wxPayClient;
|
||||
public String wechatHttpGet(String url) {
|
||||
try {
|
||||
// 拼接请求参数
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setHeader("Accept", "application/json");
|
||||
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpGet);
|
||||
|
||||
return getResponseBody(response);
|
||||
}catch (Exception e){
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String wechatHttpPost(String url,String paramsStr) {
|
||||
try {
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
StringEntity entity = new StringEntity(paramsStr, "utf-8");
|
||||
entity.setContentType("application/json");
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Accept", "application/json");
|
||||
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||
return getResponseBody(response);
|
||||
}catch (Exception e){
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getResponseBody(CloseableHttpResponse response) throws IOException {
|
||||
|
||||
//响应体
|
||||
HttpEntity entity = response.getEntity();
|
||||
String body = entity==null?"":EntityUtils.toString(entity);
|
||||
//响应状态码
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
//处理成功,204是,关闭订单时微信返回的正常状态码
|
||||
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NO_CONTENT) {
|
||||
log.info("成功, 返回结果 = " + body);
|
||||
} else {
|
||||
String msg = "微信支付请求失败,响应码 = " + statusCode + ",返回结果 = " + body;
|
||||
log.error(msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.ruoyi.payConfig;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WechatPayUrlEnum {
|
||||
|
||||
|
||||
/**
|
||||
* native
|
||||
*/
|
||||
NATIVE("native"),
|
||||
/**
|
||||
* app
|
||||
*/
|
||||
APP("app"),
|
||||
/**
|
||||
* h5
|
||||
*/
|
||||
H5("h5"),
|
||||
/**
|
||||
* jsapi
|
||||
*/
|
||||
JSAPI("jsapi"),
|
||||
|
||||
/**
|
||||
* 小程序jsapi
|
||||
*/
|
||||
SUB_JSAPI("sub_jsapi"),
|
||||
|
||||
/**
|
||||
* Native下单
|
||||
*/
|
||||
PAY_TRANSACTIONS("/pay/transactions/"),
|
||||
|
||||
/**
|
||||
* Native下单
|
||||
*/
|
||||
NATIVE_PAY_V2("/pay/unifiedorder"),
|
||||
|
||||
/**
|
||||
* 查询订单
|
||||
*/
|
||||
ORDER_QUERY_BY_NO("/pay/transactions/out-trade-no/"),
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
*/
|
||||
CLOSE_ORDER_BY_NO("/pay/transactions/out-trade-no/%s/close"),
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
*/
|
||||
DOMESTIC_REFUNDS("/refund/domestic/refunds"),
|
||||
|
||||
/**
|
||||
* 查询单笔退款
|
||||
*/
|
||||
DOMESTIC_REFUNDS_QUERY("/refund/domestic/refunds/"),
|
||||
|
||||
/**
|
||||
* 申请交易账单
|
||||
*/
|
||||
TRADE_BILLS("/bill/tradebill"),
|
||||
|
||||
/**
|
||||
* 申请资金账单
|
||||
*/
|
||||
FUND_FLOW_BILLS("/bill/fundflowbill");
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final String type;
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package com.ruoyi.payConfig;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.*;
|
||||
|
||||
/**
|
||||
* @Author:
|
||||
* @Description:
|
||||
**/
|
||||
@Slf4j
|
||||
public class WechatPayValidator {
|
||||
/**
|
||||
* 应答超时时间,单位为分钟
|
||||
*/
|
||||
private static final long RESPONSE_EXPIRED_MINUTES = 5;
|
||||
private final Verifier verifier;
|
||||
private final String requestId;
|
||||
private final String body;
|
||||
|
||||
|
||||
public WechatPayValidator(Verifier verifier, String requestId, String body) {
|
||||
this.verifier = verifier;
|
||||
this.requestId = requestId;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
protected static IllegalArgumentException parameterError(String message, Object... args) {
|
||||
message = String.format(message, args);
|
||||
return new IllegalArgumentException("parameter error: " + message);
|
||||
}
|
||||
|
||||
protected static IllegalArgumentException verifyFail(String message, Object... args) {
|
||||
message = String.format(message, args);
|
||||
return new IllegalArgumentException("signature verify fail: " + message);
|
||||
}
|
||||
|
||||
public final boolean validate(HttpServletRequest request) {
|
||||
try {
|
||||
//处理请求参数
|
||||
validateParameters(request);
|
||||
|
||||
//构造验签名串
|
||||
String message = buildMessage(request);
|
||||
|
||||
String serial = request.getHeader(WECHAT_PAY_SERIAL);
|
||||
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
|
||||
|
||||
//验签
|
||||
if (!verifier.verify(serial, message.getBytes(StandardCharsets.UTF_8), signature)) {
|
||||
throw verifyFail("serial=[%s] message=[%s] sign=[%s], request-id=[%s]",
|
||||
serial, message, signature, requestId);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void validateParameters(HttpServletRequest request) {
|
||||
|
||||
// NOTE: ensure HEADER_WECHAT_PAY_TIMESTAMP at last
|
||||
String[] headers = {WECHAT_PAY_SERIAL, WECHAT_PAY_SIGNATURE, WECHAT_PAY_NONCE, WECHAT_PAY_TIMESTAMP};
|
||||
|
||||
String header = null;
|
||||
for (String headerName : headers) {
|
||||
header = request.getHeader(headerName);
|
||||
if (header == null) {
|
||||
throw parameterError("empty [%s], request-id=[%s]", headerName, requestId);
|
||||
}
|
||||
}
|
||||
|
||||
//判断请求是否过期
|
||||
String timestampStr = header;
|
||||
try {
|
||||
Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestampStr));
|
||||
// 拒绝过期请求
|
||||
if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= RESPONSE_EXPIRED_MINUTES) {
|
||||
throw parameterError("timestamp=[%s] expires, request-id=[%s]", timestampStr, requestId);
|
||||
}
|
||||
} catch (DateTimeException | NumberFormatException e) {
|
||||
throw parameterError("invalid timestamp=[%s], request-id=[%s]", timestampStr, requestId);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildMessage(HttpServletRequest request) {
|
||||
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
||||
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
||||
return timestamp + "\n"
|
||||
+ nonce + "\n"
|
||||
+ body + "\n";
|
||||
}
|
||||
|
||||
private String getResponseBody(CloseableHttpResponse response) throws IOException {
|
||||
HttpEntity entity = response.getEntity();
|
||||
return (entity != null && entity.isRepeatable()) ? EntityUtils.toString(entity) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 对称解密,异步通知的加密数据
|
||||
* @param resource 加密数据
|
||||
* @param apiV3Key apiV3密钥
|
||||
* @param type 1-支付,2-退款
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> decryptFromResource(String resource,String apiV3Key,Integer type) {
|
||||
|
||||
String msg = type==1?"支付成功":"退款成功";
|
||||
log.info(msg+",回调通知,密文解密");
|
||||
try {
|
||||
//通知数据
|
||||
Map<String, String> resourceMap = JSONObject.parseObject(resource, new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
//数据密文
|
||||
String ciphertext = resourceMap.get("ciphertext");
|
||||
//随机串
|
||||
String nonce = resourceMap.get("nonce");
|
||||
//附加数据
|
||||
String associatedData = resourceMap.get("associated_data");
|
||||
|
||||
log.info("密文: {}", ciphertext);
|
||||
AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
|
||||
String resourceStr = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
|
||||
nonce.getBytes(StandardCharsets.UTF_8),
|
||||
ciphertext);
|
||||
|
||||
log.info(msg+",回调通知,解密结果 : {}", resourceStr);
|
||||
return JSONObject.parseObject(resourceStr, new TypeReference<Map<String, Object>>(){});
|
||||
}catch (Exception e){
|
||||
throw new RuntimeException("回调参数,解密失败!");
|
||||
}
|
||||
}
|
||||
}
|
28
ruoyi-admin/src/main/resources/apiclient_key.pem
Normal file
28
ruoyi-admin/src/main/resources/apiclient_key.pem
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC7FUOpvxLTMFcf
|
||||
UaA2g8/B86GhGXXAEn1hSMQMpKAp+oXVvw1H1aW/mJfjiFlhlodVXBQwVsCaVENd
|
||||
bcwoCsQjYHWgUtkcFv4j8vryMbb13bcTyYrcYEERhpneYDKv6tPNc8tGZZu55ExX
|
||||
bRrQ+9TloO43rAXkUgabxgRecYEg05WyZBjpJVqFntmyCM394nBmr9wC8H65aDJc
|
||||
60N2h8v+ZiYBzn4aOatJTUdQAAV+0kzSq7kRn/jG19HDLESLmkgXwFNpSm21hDTw
|
||||
TbplLXUfI92Jhdx/lQ3aDoj8lVIjbEW7SQnk0wbU4nfDfo2mlgXItRDPNCHiAnYR
|
||||
cdZCm48vAgMBAAECggEBAIo57eJvYNNVNinXv45H2ast/U/wZcXiY20LvH6y6/vY
|
||||
NCZ3oLJgsrRbZG4jAhdOhvOUsv38OxZMB/Hx/BPh0IVq8b3hOLS+cEvTbYKhJNOI
|
||||
W4ptMQIexDTUxL8/SHQeBxwX4CtFS8gPXDCEVnnud6CqRRgxK7FEwck6h2PYbVX4
|
||||
e4575fqrPEQHA4raKQB/boUBLK2KxyXbomT1vU2Xehzlu/1Lcc3PMuKcXtTWNg0K
|
||||
tvUcVdfI36BVde79TIiauultEIai0ZXVj1NUG/9CA2iHyzSGmVtTyWqQQQDEz5Ph
|
||||
RdRhYCvPARoTEfw7AX0ShCM6trLkZjcTIM68gkuJdWECgYEA3CagoLXpUM08cySW
|
||||
GzswCP/p06Pe/4NBGLronKj6+k2x32zFVEfZnv++CfdPAXd9d8iXqElRvLFceAsu
|
||||
NbcxsbtPYKG5eBsc2qS7f5hVSjubiycJATqfR6JlFv+hHYG42snY10qfdzsJpJ8T
|
||||
SKh7SJeZ54o9wlKqbkaV3ucUpIcCgYEA2Ywlp46INLzsn1LOzn3sV6pcwII33YEl
|
||||
3JZz3OQWzrpGMuC/HCH9aazh3ZLyc6NXpRFAR5329mLgKKTOIT0yp0c4S3EQ8/M/
|
||||
nwUEDye/GrVJjsT7mqoXbSylVZpVfg/4M4SAZ3xbL7aANMtMcCS67J3ByulmHEAh
|
||||
DvDiyplKEhkCgYEAjQZ5kzm00jwG40OmnJ8XsEwvf5HUAh4Uj0D8TY6556nprdRB
|
||||
vDGiqIXvOPchtzDSQO9Qp08Aez2qnIOdAG/v94ij2qT+6H+FxlIMgjoVOM5iX4uL
|
||||
6yugaQUQeOEcVoiI4C65J4D4EirRjJESi1LSVrg2sOoPkfHel3HEA9xHjvUCgYEA
|
||||
nCCinYADbKXxw94wIa3pwni3nElYQpX/UDKB8JOZcr/oxXbacRxLvF2gs95UNn2R
|
||||
1xtsYHmT1fvcGA8/CEfdZIQOeMYqfomirUNySFYkJszYf6gLUlKkAWw7NBZRKOnZ
|
||||
HVAIvzxWTQXTORB2ST1zEYGepTugVsIHd6uVeAVPTXECgYEA2sgzcVHf38EFf16V
|
||||
x8OfYalGBazfnTXxZUMji4DBaiaA0luH+cmEm21bEVnJkINs8pySrSP8IiGr01r3
|
||||
ieMkVZVdA8PulxPTKTGnnIuLEsQzdulD01A2i0f3mNxjyLUltBUX56SO7Sc8/Zoq
|
||||
lENhDpQlP41ahoLE8X9Ti0uxpsw=
|
||||
-----END PRIVATE KEY-----
|
@ -38,6 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="entity.tel != null and entity.tel != ''"> and tel like concat('%', #{entity.tel}, '%')</if>
|
||||
<if test="entity.status != null and entity.status != ''"> and status = #{entity.status}</if>
|
||||
</where>
|
||||
order by isSuper desc, create_time asc
|
||||
</select>
|
||||
<select id="selectReportNumByIdList" resultType="java.util.Map">
|
||||
SELECT
|
||||
@ -54,4 +55,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
GROUP BY
|
||||
dbns.id
|
||||
</select>
|
||||
<select id="reportList" resultType="com.ruoyi.busi.domain.BusiNoticeSign">
|
||||
select sign.*,card.platform_name as platformName,
|
||||
card.account_name as accountName,card.fans_num as fansNum
|
||||
,card.platform_code as platformCode
|
||||
from dl_busi_notice_sign sign
|
||||
inner join dl_member_busi_card card on sign.card_id = card.id
|
||||
<where>
|
||||
<if test="entity.noticeId != null and entity.noticeId != ''"> and sign.notice_id like concat('%', #{entity.noticeId}, '%')</if>
|
||||
|
||||
<if test="entity.status != null and entity.status != ''"> and sign.status = #{entity.status}</if>
|
||||
</where>
|
||||
order by sign.is_super desc, sign.create_time asc
|
||||
</select>
|
||||
</mapper>
|
@ -73,6 +73,14 @@ public class SysUser extends BaseEntity
|
||||
/** openId */
|
||||
private String openId;
|
||||
|
||||
|
||||
/** 微信公众号openId */
|
||||
private String wxOpenId;
|
||||
|
||||
|
||||
/** 微信公众平台id */
|
||||
private String unionId;
|
||||
|
||||
/** 部门对象 */
|
||||
@Excels({
|
||||
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
|
||||
@ -331,4 +339,20 @@ public class SysUser extends BaseEntity
|
||||
.append("dept", getDept())
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getWxOpenId() {
|
||||
return wxOpenId;
|
||||
}
|
||||
|
||||
public void setWxOpenId(String wxOpenId) {
|
||||
this.wxOpenId = wxOpenId;
|
||||
}
|
||||
|
||||
public String getUnionId() {
|
||||
return unionId;
|
||||
}
|
||||
|
||||
public void setUnionId(String unionId) {
|
||||
this.unionId = unionId;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="password" column="password" />
|
||||
<result property="status" column="status" />
|
||||
<result property="openId" column="open_id" />
|
||||
<result property="wxOpenId" column="wx_open_id" />
|
||||
<result property="unionId" column="union_id" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="loginIp" column="login_ip" />
|
||||
<result property="loginDate" column="login_date" />
|
||||
@ -48,7 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUserVo">
|
||||
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status,u.open_id, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
|
||||
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status,u.open_id,u.wx_open_id,u.union_id, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
|
||||
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
|
||||
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
|
||||
from sys_user u
|
||||
@ -58,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</sql>
|
||||
|
||||
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
|
||||
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status,u.open_id, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
|
||||
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status,u.open_id,u.wx_open_id,u.union_id, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
where u.del_flag = '0'
|
||||
<if test="userId != null and userId != 0">
|
||||
@ -87,7 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectAllocatedList" parameterType="SysUser" resultMap="SysUserResult">
|
||||
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,u.open_id, u.create_time
|
||||
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,u.open_id,u.wx_open_id,u.union_id, u.create_time
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
left join sys_user_role ur on u.user_id = ur.user_id
|
||||
@ -104,7 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectUnallocatedList" parameterType="SysUser" resultMap="SysUserResult">
|
||||
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,u.open_id, u.create_time
|
||||
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,u.open_id,u.wx_open_id,u.union_id, u.create_time
|
||||
from sys_user u
|
||||
left join sys_dept d on u.dept_id = d.dept_id
|
||||
left join sys_user_role ur on u.user_id = ur.user_id
|
||||
@ -156,6 +158,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="password != null and password != ''">password,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="openId != null and openId != ''">open_id,</if>
|
||||
<if test="wxOpenId != null and wxOpenId != ''">wx_open_id,</if>
|
||||
<if test="unionId != null and unionId != ''">union_id,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="remark != null and remark != ''">remark,</if>
|
||||
create_time
|
||||
@ -171,6 +175,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="password != null and password != ''">#{password},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="openId != null and openId != ''">#{openId},</if>
|
||||
<if test="wxOpenId != null and wxOpenId != ''">#{wxOpenId},</if>
|
||||
<if test="unionId != null and unionId != ''">#{unionId},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="remark != null and remark != ''">#{remark},</if>
|
||||
sysdate()
|
||||
@ -189,6 +195,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="password != null and password != ''">password = #{password},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="openId != null and openId != ''">open_id = #{openId},</if>
|
||||
<if test="wxOpenId != null and wxOpenId != ''">wx_open_id = #{wxOpenId},</if>
|
||||
<if test="unionId != null and unionId != ''">union_id =#{unionId},</if>
|
||||
|
||||
<if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
|
||||
<if test="loginDate != null">login_date = #{loginDate},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
@ -226,6 +235,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="openId!=null and openId!=''">
|
||||
and u.open_id = #{openId}
|
||||
</if>
|
||||
<if test="wxOpenId!=null and wxOpenId!=''">
|
||||
and u.wx_open_id = #{wxOpenId}
|
||||
</if>
|
||||
<if test="unionId!=null and unionId!=''">
|
||||
and u.union_id = #{unionId}
|
||||
</if>
|
||||
<if test="phone!=null and phone!=''">
|
||||
and u.user_name = #{phone}
|
||||
</if>
|
||||
|
Loading…
Reference in New Issue
Block a user