Oam插件市场;修复Bug;放心学一次性支付;放心学联合支付

This commit is contained in:
DB 2023-12-29 18:13:19 +08:00
parent 8de9bd498f
commit 6f607d2771
31 changed files with 1124 additions and 57 deletions

View File

@ -0,0 +1,84 @@
package com.cpop.jambox.business.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* @author DB
* @version 1.0.0
* @since 2023-12-28 15:44
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "EasyLearnUnionPayBo对象", description = "统一支付参数")
public class EasyLearnUnionPayBo {
/**
* 品牌或校区id
*/
@NotBlank(message = "云品牌或云校区id不能为空")
@ApiModelProperty(value = "云品牌或云校区id",required = true)
private String brandOrStoreCloudId;
/**
* 联合支付外部订单id
*/
@NotBlank(message = "联合支付外部订单id不能为空")
@ApiModelProperty(value = "联合支付外部订单id",required = true)
private String unionPayOutOrderId;
/**
* 客户名
*/
@NotBlank(message = "客户名不能为空")
@ApiModelProperty(value = "客户名",required = true)
private String customerName;
/**
* 客户电话
*/
@NotBlank(message = "客户电话不能为空")
@ApiModelProperty(value = "客户电话",required = true)
private String customerPhone;
/**
* 总金额
*/
@NotNull(message = "总金额不能为空")
@ApiModelProperty(value = "总金额",required = true)
private BigDecimal totalAmount;
/**
* 总支付金额
*/
@NotNull(message = "总支付金额不能为空")
@ApiModelProperty(value = "总支付金额",required = true)
private BigDecimal totalPayAmount;
/**
* 订单类型
*/
@NotNull(message = "联合支付类型不能为空")
@ApiModelProperty(value = "联合支付类型(PREPAYMENT:预付;REPAYMENT:还款;MEMBER:会员)",required = true)
private String easyLearnUnionPay;
/**
* 分账比率
*/
@ApiModelProperty(value = "分账比率(不传不分帐)")
private Double rate;
/**
* openId
*/
@NotBlank(message = "openId不能为空")
@ApiModelProperty(value = "openId", required = true)
private String openId;
}

View File

@ -3,6 +3,7 @@ package com.cpop.jambox.business.controller.backstage;
import com.alibaba.excel.EasyExcel;
import com.cpop.core.base.R;
import com.cpop.jambox.business.bo.EasyLearnPageBo;
import com.cpop.jambox.business.bo.EasyLearnUnionPayBo;
import com.cpop.jambox.business.bo.OncePlaceOrderBo;
import com.cpop.jambox.business.dto.EasyLearnPageDto;
import com.cpop.jambox.business.service.EasyLearnOrderService;
@ -98,4 +99,17 @@ public class EasyLearnController {
public R<Object> oncePlaceOrder(@RequestBody @Validated @ApiParam("一次性支付") OncePlaceOrderBo bo) {
return R.ok(easyLearnOrderService.oncePlaceOrder(bo));
}
/**
* 放心学统一支付
* @author DB
* @since 2023/12/28
* @param bo 请求参数
* @return R<Object>
*/
@PostMapping("/unionPay")
@ApiOperation("放心学统一支付")
public R<Object> unionPay(@RequestBody @Validated @ApiParam("一次性支付") EasyLearnUnionPayBo bo) {
return R.ok(easyLearnOrderService.unionPay(bo));
}
}

View File

@ -35,4 +35,15 @@ public class EasyLearnCallBackController {
return WxPayNotifyResponse.success("成功");
}
/**
* 微信支付联合支付订单通知
* @param xmlData 数据
* @return java.lang.String
*/
@PostMapping("/notify/unionPay")
public String unionPay(@RequestBody String xmlData){
easyLearnOrderService.unionPayResult(xmlData);
return WxPayNotifyResponse.success("成功");
}
}

View File

@ -38,6 +38,11 @@ public class EasyLearnOrder extends BaseEntity implements Serializable {
*/
private Integer orderStatus;
/**
* 联合支付外部订单id
*/
private String unionPayOutOrderId;
/**
* 云id
*/
@ -98,6 +103,11 @@ public class EasyLearnOrder extends BaseEntity implements Serializable {
*/
private Integer orderType;
/**
* 分账比例
*/
private Double rate;
/**
* 逻辑删除0否1是
*/

View File

@ -0,0 +1,61 @@
package com.cpop.jambox.business.entity;
import com.cpop.core.base.entity.BaseEntity;
import com.cpop.core.base.entity.BaseInsertListener;
import com.cpop.core.base.entity.BaseUpdateListener;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 校区-插件记录表 实体类
*
* @author DB
* @since 2023-12-29
*/
@Data
@EqualsAndHashCode(callSuper=false)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Table(value = "cp_j_store_plug", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class StorePlug extends BaseEntity implements Serializable {
/**
* 主键
*/
@Id
private String id;
/**
* 校区id
*/
private String storeId;
/**
* 插件标记
*/
private String plugTag;
/**
* 备注
*/
private String remarks;
/**
* 是否开启
*/
private Boolean isOpen;
/**
* 逻辑删除0否1是
*/
@Column(isLogicDelete = true)
private Boolean isDelete;
}

View File

@ -0,0 +1,14 @@
package com.cpop.jambox.business.mapper;
import com.mybatisflex.core.BaseMapper;
import com.cpop.jambox.business.entity.StorePlug;
/**
* 校区-插件记录表 映射层
*
* @author DB
* @since 2023-12-29
*/
public interface StorePlugMapper extends BaseMapper<StorePlug> {
}

View File

@ -1,6 +1,7 @@
package com.cpop.jambox.business.service;
import com.cpop.jambox.business.bo.EasyLearnPageBo;
import com.cpop.jambox.business.bo.EasyLearnUnionPayBo;
import com.cpop.jambox.business.bo.OncePlaceOrderBo;
import com.cpop.jambox.business.dto.EasyLearnPageDto;
import com.cpop.jambox.business.entity.EasyLearnOrder;
@ -51,4 +52,19 @@ public interface EasyLearnOrderService extends IService<EasyLearnOrder> {
* @param bo 下单请求对象
*/
Object oncePlaceOrder(OncePlaceOrderBo bo);
/**
* 放心学统一支付
* @author DB
* @since 2023/12/28
* @param bo 请求参数
* @return R<Object>
*/
Object unionPay(EasyLearnUnionPayBo bo);
/**
* 微信支付联合支付订单通知
* @param xmlData 数据
*/
void unionPayResult(String xmlData);
}

View File

@ -0,0 +1,26 @@
package com.cpop.jambox.business.service;
import com.cpop.jambox.business.vo.StorePlugListVo;
import com.mybatisflex.core.service.IService;
import com.cpop.jambox.business.entity.StorePlug;
import java.util.List;
/**
* 校区-插件记录表 服务层
*
* @author DB
* @since 2023-12-29
*/
public interface StorePlugService extends IService<StorePlug> {
/**
* 查询校区插件列表
* @author DB
* @since 2023/12/29
* @param brandId 品牌
* @param storeId 校区
* @return List<StorePlugListVo>
*/
List<StorePlugListVo> getStorePlugList(String brandId, String storeId);
}

View File

@ -3,6 +3,7 @@ package com.cpop.jambox.business.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.common.utils.http.HttpUtils;
import com.cpop.common.utils.ip.IpUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.enums.OrderSource;
@ -12,6 +13,7 @@ import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.jambox.business.bo.EasyLearnPageBo;
import com.cpop.jambox.business.bo.EasyLearnUnionPayBo;
import com.cpop.jambox.business.bo.OncePlaceOrderBo;
import com.cpop.jambox.business.dto.EasyLearnPageDto;
import com.cpop.jambox.business.entity.BrandExtend;
@ -24,9 +26,12 @@ import com.cpop.jambox.business.service.StoreExtendService;
import com.cpop.jambox.business.vo.EasyLearnPageVo;
import com.cpop.jambox.framework.constant.JamboxCloudUrl;
import com.cpop.jambox.framework.constant.JamboxRedisConstant;
import com.cpop.jambox.framework.enums.EasyLearnPayPayEnum;
import com.cpop.pay.framewok.config.wxPay.WxPayConfiguration;
import com.cpop.pay.framewok.handler.wxPay.WxPayHandler;
import com.cpop.pay.framewok.task.WxPayAsyncTask;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.service.StoreService;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
@ -45,8 +50,10 @@ import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
@ -374,15 +381,12 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
EasyLearnOrder easyLearnOrder = this.getById(orderId);
//需要分账
String subMchId = wxPayHandler.getSubMchId(easyLearnOrder.getBrandId(), easyLearnOrder.getStoreId());
log.info("支付金额:{}", notifyResult.getTotalFee());
if (notifyResult.getTotalFee() >= Math.ceil(1 / OrderSource.EASY_LEARN.getRate())) {
//设置子商户
WxPayConfig config = wxPayService.getConfig();
config.setSubMchId(subMchId);
wxPayAsyncTask.asyncWxPayProfitSharing(orderId, notifyResult, wxPayService, OrderSource.EASY_LEARN);
}
//更新订单
this.updateChain().set(EASY_LEARN_ORDER.OUT_ORDER_NO, notifyResult.getTransactionId()).where(EASY_LEARN_ORDER.ID.eq(orderId)).update();
//课卡信息
JSONObject jsonBody = new JSONObject();
jsonBody.put("_type", "addPeriod");
@ -407,8 +411,11 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
if (result == null){
throw new ServiceException("放心学一次性支付办卡失败!");
}
easyLearnOrder.setProductId(result.getString("data")).setOrderStatus(1);
this.updateById(easyLearnOrder);
//更新订单
this.updateChain().set(EASY_LEARN_ORDER.OUT_ORDER_NO, notifyResult.getTransactionId())
.set(EASY_LEARN_ORDER.PRODUCT_ID, result.getString("data"))
.set(EASY_LEARN_ORDER.ORDER_STATUS, 1)
.where(EASY_LEARN_ORDER.ID.eq(orderId)).update();
} catch (WxPayException e) {
throw new ServiceException(e.getMessage());
}
@ -445,6 +452,10 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
//创建订单
easyLearnOrder = BeanUtils.mapToClass(bo, EasyLearnOrder.class);
easyLearnOrder.setOrderType(2).setBrandId(brandExtend.getBrandId()).setStoreId(storeExtend.getStoreId());
//需要分账
if (bo.getTotalAmount().scaleByPowerOfTen(2).intValue() >= Math.ceil(1 / OrderSource.EASY_LEARN.getRate())) {
easyLearnOrder.setRate(OrderSource.EASY_LEARN.getRate());
}
this.save(easyLearnOrder);
} else {
if (easyLearnOrder.getOrderStatus() == 1){
@ -453,7 +464,8 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
}
String payNotifyUrl;
if (StringUtils.equals("prod", SpringUtils.getActiveProfile())) {
payNotifyUrl = SpringUtils.getBean(WxPayConfiguration.class).getProperties().getNotifyUrl();
//一次性支付
payNotifyUrl = SpringUtils.getBean(WxPayConfiguration.class).getProperties().getEasyLearnOncePayNotifyUrl();
} else if (StringUtils.equals("test", SpringUtils.getActiveProfile())){
payNotifyUrl = ONCE_PAY_TEST_NOTIFY_URL;
} else {
@ -462,8 +474,7 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
//获取商户信息
WxPayService wxPayService = wxPayHandler.getWxPayService(null, wxPayHandler.getSubMchId(brandExtend.getBrandId(), storeExtend.getStoreId()), payNotifyUrl);
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
//需要分账
if (bo.getTotalAmount().scaleByPowerOfTen(2).intValue() >= Math.ceil(1 / OrderSource.EASY_LEARN.getRate())) {
if (easyLearnOrder.getRate() != null) {
//需要分账
orderRequest.setProfitSharing("Y");
}
@ -487,4 +498,147 @@ public class EasyLearnOrderServiceImpl extends ServiceImpl<EasyLearnOrderMapper,
throw new ServiceException("请勿重复支付");
}
}
/**
* 联合支付回调地址本地内网穿透
*/
private final String UNION_PAY_DEV_NOTIFY_URL = "https://frp-bid.top:60778/Cpop-Oam/easyLearn/callback/notify/unionPay";
/**
* 联合支付回调地址测试地址
*/
private final String UNION_PAY_TEST_NOTIFY_URL = "https://test.cpopsz.com/Cpop-Oam/easyLearn/callback/notify/unionPay";
/**
* 放心学统一支付
* @author DB
* @since 2023/12/28
* @param bo 请求参数
* @return R<Object>
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Object unionPay(EasyLearnUnionPayBo bo) {
//分布式锁进行幂等处理
RedisService redisService = SpringUtils.getBean(RedisService.class);
//分布式锁进行幂等处理
Lock userIdLock = redisService.distributedLock(JamboxRedisConstant.ONCE_PAY_LOCK_USER_PAY + bo.getCustomerPhone());
if (userIdLock.tryLock()) {
try {
//创建订单
EasyLearnOrder easyLearnOrder = BeanUtils.mapToClass(bo, EasyLearnOrder.class);
//获取校区
StoreExtend storeExtend = SpringUtils.getBean(StoreExtendService.class).queryChain().where(STORE_EXTEND.STORE_CLOUD_ID.eq(bo.getBrandOrStoreCloudId())).one();
//获取品牌
BrandExtend brandExtend;
if (storeExtend == null) {
brandExtend = SpringUtils.getBean(BrandExtendService.class).queryChain().where(BRAND_EXTEND.BRAND_CLOUD_ID.eq(bo.getBrandOrStoreCloudId())).one();
easyLearnOrder.setBrandId(brandExtend.getBrandId());
} else {
//获取品牌
Store store = SpringUtils.getBean(StoreService.class).getById(storeExtend.getStoreId());
easyLearnOrder.setBrandId(store.getBrandId());
easyLearnOrder.setStoreId(storeExtend.getStoreId());
}
EasyLearnPayPayEnum easyLearnPayPayEnum = EasyLearnPayPayEnum.valueOf(bo.getEasyLearnUnionPay());
easyLearnOrder.setOrderType(easyLearnPayPayEnum.getOrderType());
this.save(easyLearnOrder);
String payNotifyUrl;
if (StringUtils.equals("prod", SpringUtils.getActiveProfile())) {
//联合支付
payNotifyUrl = SpringUtils.getBean(WxPayConfiguration.class).getProperties().getEasyLearnUnionPayNotifyUrl();
} else if (StringUtils.equals("test", SpringUtils.getActiveProfile())){
payNotifyUrl = UNION_PAY_TEST_NOTIFY_URL;
} else {
payNotifyUrl = UNION_PAY_DEV_NOTIFY_URL;
}
//获取商户信息
WxPayService wxPayService = wxPayHandler.getWxPayService(null, wxPayHandler.getSubMchId(easyLearnOrder.getBrandId(), easyLearnOrder.getStoreId()), payNotifyUrl);
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
//需要分账
if (easyLearnOrder.getRate() != null && easyLearnOrder.getTotalAmount().scaleByPowerOfTen(2).intValue() >= Math.ceil(1 / easyLearnOrder.getRate())) {
//需要分账
orderRequest.setProfitSharing("Y");
}
orderRequest.setSpbillCreateIp(IpUtils.getHostIp())
.setOpenid(bo.getOpenId())
//商品描述
.setBody("一次性支付")
.setOutTradeNo(easyLearnOrder.getId())
//元转分
.setTotalFee(easyLearnOrder.getTotalAmount().scaleByPowerOfTen(2).intValue())
.setTradeType("JSAPI");
return wxPayService.createOrder(orderRequest);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
} finally {
//释放锁
userIdLock.unlock();
}
} else {
//获取锁失败直接返回空
throw new ServiceException("请勿重复支付");
}
}
/**
* 果酱通知地址本地
*/
private final String UNION_PAY_DEV_JAMBOX_NOTIFY_URL = "http://localhost:8078/test/ass/jambox/contract/unionPayNotify";
/**
* 果酱通知地址测试地址
*/
private final String UNION_PAY_TEST_JAMBOX_NOTIFY_URL = "https://test.cpopsz.com/test/ass/jambox/contract/unionPayNotify";
/**
* 果酱通知地址(线上)
*/
private final String UNION_PAY_PROD_JAMBOX_NOTIFY_URL = "https://api.jamboxsys.com/jambox/ass/jambox/contract/unionPayNotify";
/**
* 微信支付联合支付订单通知
* @param xmlData 数据
*/
@Override
public void unionPayResult(String xmlData) {
try {
WxPayService wxPayService = wxPayHandler.getWxPayService();
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
if (!StringUtils.equals(notifyResult.getResultCode(), "SUCCESS")) {
throw new ServiceException(notifyResult.getReturnMsg());
}
String orderId = notifyResult.getOutTradeNo();
//获取订单信息
EasyLearnOrder easyLearnOrder = this.getById(orderId);
if (easyLearnOrder.getRate() != null && easyLearnOrder.getTotalAmount().scaleByPowerOfTen(2).intValue() >= Math.ceil(1 / easyLearnOrder.getRate())) {
//设置子商户
WxPayConfig config = wxPayService.getConfig();
//需要分账
String subMchId = wxPayHandler.getSubMchId(easyLearnOrder.getBrandId(), easyLearnOrder.getStoreId());
config.setSubMchId(subMchId);
wxPayAsyncTask.asyncWxPayProfitSharing(orderId, notifyResult, wxPayService, OrderSource.EASY_LEARN, easyLearnOrder.getRate());
}
JSONObject jsonObject = new JSONObject();
EasyLearnPayPayEnum easyLearnPayPayEnum = EasyLearnPayPayEnum.getEasyLearnPayPayEnum(easyLearnOrder.getOrderType());
jsonObject.put("wxOrderId", easyLearnOrder.getId());
jsonObject.put("unionPayOutOrderId", easyLearnOrder.getUnionPayOutOrderId());
jsonObject.put("easyLearnUnionPay", easyLearnPayPayEnum.toString());
String url;
if (StringUtils.equals("prod", SpringUtils.getActiveProfile())) {
url = UNION_PAY_PROD_JAMBOX_NOTIFY_URL;
} else if (StringUtils.equals("test", SpringUtils.getActiveProfile())) {
url = UNION_PAY_TEST_JAMBOX_NOTIFY_URL;
} else {
url = UNION_PAY_DEV_JAMBOX_NOTIFY_URL;
}
HttpUtils.sendOkHttpPost(url, jsonObject.toJSONString());
//更新订单
this.updateChain().set(EASY_LEARN_ORDER.OUT_ORDER_NO, notifyResult.getTransactionId())
.set(EASY_LEARN_ORDER.ORDER_STATUS, 1)
.where(EASY_LEARN_ORDER.ID.eq(orderId)).update();
} catch (WxPayException | IOException e) {
throw new ServiceException(e.getMessage());
}
}
}

View File

@ -0,0 +1,77 @@
package com.cpop.jambox.business.service.impl;
import com.cpop.common.utils.StringUtils;
import com.cpop.jambox.business.entity.StorePlug;
import com.cpop.jambox.business.mapper.StorePlugMapper;
import com.cpop.jambox.business.service.StorePlugService;
import com.cpop.jambox.business.vo.StorePlugListVo;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.cpop.jambox.business.entity.table.StorePlugTableDef.STORE_PLUG;
/**
* 校区-插件记录表 服务层实现
*
* @author DB
* @since 2023-12-29
*/
@Service("storePlugService")
public class StorePlugServiceImpl extends ServiceImpl<StorePlugMapper, StorePlug> implements StorePlugService {
/**
* 查询校区插件列表
*
* @param brandId 品牌
* @param storeId 校区
* @return List<StorePlugListVo>
* @author DB
* @since 2023/12/29
*/
@Override
public List<StorePlugListVo> getStorePlugList(String brandId, String storeId) {
if (StringUtils.isBlank(brandId) || StringUtils.isBlank(storeId)) {
return new ArrayList<>();
}
List<Row> rows;
try {
DataSourceKey.use("jambox");
rows = Db.selectListByQuery("t_application_info", QueryWrapper.create()
.select("application", "char_tag as plugTag", "pic", "tag", "status","creation_time as listingTime")
.from("t_application_info")
.where("char_tag IS NOT NULL"));
} finally {
DataSourceKey.clear();
}
if (!rows.isEmpty()) {
Map<String, Row> rowsMap = rows.stream().collect(Collectors.toMap(item -> item.getString("plugTag"), item -> item));
List<StorePlugListVo> storePlugListVos = this.listAs(QueryWrapper.create()
.select(STORE_PLUG.PLUG_TAG, STORE_PLUG.ID, STORE_PLUG.CREATE_TIME,STORE_PLUG.IS_OPEN)
.where(STORE_PLUG.STORE_ID.eq(storeId)),
StorePlugListVo.class);
storePlugListVos.forEach(item -> {
if (rowsMap.get(item.getPlugTag()) != null) {
Row row = rowsMap.get(item.getPlugTag());
item.setListingTime(row.getLocalDateTime("listingTime"));
item.setPlugName(row.getString("application"));
item.setPlugType("tag");
}
});
return storePlugListVos;
} else {
return new ArrayList<>();
}
}
}

View File

@ -0,0 +1,70 @@
package com.cpop.jambox.business.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* @author DB
* @version 1.0.0
* @since 2023-12-29 16:36
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "StorePlugListVo对象")
public class StorePlugListVo {
/**
* 主键
*/
@ApiModelProperty("主键")
private String id;
/**
* 插件标记
*/
@ApiModelProperty("插件标记")
private String plugTag;
/**
* 插件名
*/
@ApiModelProperty("插件名")
private String plugName;
/**
* 插件类型
*/
@ApiModelProperty("插件类型")
private String plugType;
/**
* 备注
*/
@ApiModelProperty("备注")
private String remarks;
/**
* 最后修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@ApiModelProperty("上架时间")
private LocalDateTime listingTime;
/**
* 最后修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@ApiModelProperty("开启时间")
private LocalDateTime createTime;
/**
* 是否开启
*/
@ApiModelProperty("是否开启")
private Boolean isOpen;
}

View File

@ -0,0 +1,56 @@
package com.cpop.jambox.framework.enums;
import lombok.Getter;
/**
* @author DB
* @version 1.0.0
* @since 2023-12-28 16:23
*/
@Getter
public enum EasyLearnPayPayEnum {
/**
* 预付
*/
PREPAYMENT("Prepayment",5),
/**
* 还款
*/
REPAYMENT("Repayment",6),
/**
* 会员
*/
MEMBER("MEMBER",7);;
EasyLearnPayPayEnum(String name, Integer orderType) {
this.orderType = orderType;
this.name = name;
}
/**
* 分账比例
*/
private Integer orderType;
private String name;
public void setOrderType(Integer orderType) {
this.orderType = orderType;
}
public void setName(String name) {
this.name = name;
}
public static EasyLearnPayPayEnum getEasyLearnPayPayEnum(int orderType) {
for (EasyLearnPayPayEnum c : EasyLearnPayPayEnum.values()) {
if (c.orderType == orderType) {
return c;
}
}
return null;
}
}

View File

@ -1,4 +1,8 @@
wx:
pay:
#支付通知地址
notify-url: https://oamapi.cpopsz.com/Cpop-Oam/easyLearn/callback/notify/oncePay
notify-url: https://oamapi.cpopsz.com/Cpop-Oam/easyLearn/callback/notify/oncePay
#支付通知地址
easy-learn-once-pay-notify-url: https://oamapi.cpopsz.com/Cpop-Oam/easyLearn/callback/notify/oncePay
#放心学联合支付
easy-learn-union-pay-notify-url: https://oamapi.cpopsz.com/Cpop-Oam/easyLearn/callback/notify/unionPay

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cpop.jambox.business.mapper.StorePlugMapper">
</mapper>

View File

@ -9,6 +9,7 @@ import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingQueryResult;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingReceiverRequest;
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingResult;
import com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingReturnRequest;
import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
@ -50,13 +51,13 @@ public class CpopWxPayTests {
WxPayRefundV3Request.Amount amount = new WxPayRefundV3Request.Amount();
//退款金额(单位分)
//int refund = order.getTotalAmount().scaleByPowerOfTen(2).intValue();
int refund = 500;
int refund = 101;
amount.setRefund(refund)
.setTotal(refund)
.setCurrency("CNY");
request.setSubMchid(wxPayService.getConfig().getSubMchId())
.setTransactionId("4200002091202312282284574621")
.setOutTradeNo("97795855209209856")
.setTransactionId("4200002126202312283733408828")
.setOutTradeNo("97945790336548864")
//.setTransactionId(order.getOutOrderNo())
//.setOutTradeNo(order.getId())
.setNotifyUrl(wxPayProperties.getNotifyRefund())
@ -80,16 +81,28 @@ public class CpopWxPayTests {
//ProfitSharing profitSharing = SpringUtils.getBean(ProfitSharingService.class).getById("77860920238751744");
//profitSharingReturnRequest.setOrderId(profitSharing.getOutProfitSharingId());
//profitSharingReturnRequest.setOutReturnNo(profitSharing.getId());
profitSharingReturnRequest.setOrderId("30000502582023122858656805224");
profitSharingReturnRequest.setOutReturnNo("97795889866743808");
profitSharingReturnRequest.setOrderId("30001002562023122858679309202");
profitSharingReturnRequest.setOutReturnNo("97948799695069184");
profitSharingReturnRequest.setDescription("分账退款");
profitSharingReturnRequest.setSubMchId("1661323640");
profitSharingReturnRequest.setReturnMchid("1618884922");
//profitSharingReturnRequest.setAmount(profitSharing.getAmount());
profitSharingReturnRequest.setAmount(1L);
profitSharingReturnRequest.setAmount(6L);
wxPayService.getProfitSharingV3Service().profitSharingReturn(profitSharingReturnRequest);
}
/**
* 取消订单
* @throws WxPayException
*/
@Test
public void reverse() throws WxPayException {
WxPayOrderReverseRequest wxPayOrderReverseRequest = new WxPayOrderReverseRequest();
wxPayOrderReverseRequest.setOutTradeNo("97945902236385280");
wxPayOrderReverseRequest.setSubMchId("1661323640");
wxPayService.reverseOrder(wxPayOrderReverseRequest);
}
/**
* @descriptions 添加分账接收方
* @author DB
@ -121,8 +134,8 @@ public class CpopWxPayTests {
@Test
public void getOrderInfo() throws WxPayException {
WxPayConfig config = wxPayService.getConfig();
config.setSubMchId("1661807764");
WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder("4200002028202312069539269015", null);
config.setSubMchId("1661323640");
WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(null, "97976926051770368");
System.out.println(wxPayOrderQueryResult);
}
@ -148,8 +161,8 @@ public class CpopWxPayTests {
* @return: void
*/
@Test
public void getRefundResult() throws WxPayException {
ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingV3Service().getProfitSharingResult("84052505520087040", "4200002010202311202693854147", "1659765332");
public void getProfitSharingResult() throws WxPayException {
ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingV3Service().getProfitSharingResult("97976952480079872", "4200002127202312282719627535", "1661323640");
System.out.println(profitSharingResult);
}
@ -160,10 +173,10 @@ public class CpopWxPayTests {
@Test
public void profitSharingFinish() throws WxPayException {
ProfitSharingFinishRequest profitSharingFinishRequest = new ProfitSharingFinishRequest();
profitSharingFinishRequest.setTransactionId("4200002028202312069539269015");
profitSharingFinishRequest.setOutOrderNo("89825115260416000");
profitSharingFinishRequest.setTransactionId("4200002093202312282215936862");
profitSharingFinishRequest.setOutOrderNo("97973671418667008");
profitSharingFinishRequest.setDescription("结束分账");
profitSharingFinishRequest.setSubMchId("1661807764");
profitSharingFinishRequest.setSubMchId("1661323640");
wxPayService.getProfitSharingService().profitSharingFinish(profitSharingFinishRequest);
}

View File

@ -4,7 +4,7 @@ cpop:
profile: E:/Cpop/uploadPath
jwt:
#白名单
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxCp/*,/wxCp/portal/*/registerCode,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/**,/easyLearn/oncePlaceOrder
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxCp/*,/wxCp/portal/*/registerCode,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/*/*,/easyLearn/*
gateway:
rsa-keypair:
# 公钥文件

View File

@ -4,7 +4,7 @@ cpop:
profile: /root/cpop-union/cpop-oam/upload
jwt:
#白名单
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/*,/wxCp/portal/*/registerCode,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/**,/easyLearn/oncePlaceOrder
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/*,/wxCp/portal/*/registerCode,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/*/*,/easyLearn/*
#拦截
gateway:
rsa-keypair:

View File

@ -4,7 +4,7 @@ cpop:
profile: /root/cpop-union/cpop-mall/upload
jwt:
#白名单
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/portal/*/registerCode,/wxCp/*,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/**,/easyLearn/oncePlaceOrder
whiteList: /websocket/*,/login,/getCaptcha,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources,/wxOpen/receiveTicket,/wxOpen/*/callback,/wxOpen/bindOpenAccount/*,/wxCp/portal/*,/wxCp/portal/*/registerCode,/wxCp/*,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/*/*,/easyLearn/*
#拦截
gateway:
rsa-keypair:

View File

@ -0,0 +1,202 @@
package com.cpop.oam.web;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.enums.OrderSource;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SpringUtils;
import com.cpop.jambox.business.entity.EasyLearnOrder;
import com.cpop.jambox.business.entity.StoreExtend;
import com.cpop.jambox.business.service.EasyLearnOrderService;
import com.cpop.jambox.business.service.StoreExtendService;
import com.cpop.jambox.framework.constant.JamboxCloudUrl;
import com.cpop.pay.framewok.config.wxPay.WxPayProperties;
import com.cpop.pay.framewok.handler.wxPay.WxPayHandler;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingRequest;
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowKey;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.client.RestTemplate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.cpop.jambox.business.entity.table.EasyLearnOrderTableDef.EASY_LEARN_ORDER;
import static com.cpop.jambox.business.entity.table.StoreExtendTableDef.STORE_EXTEND;
/**
* @author DB
* @version 1.0.0
* @since 2023-12-29 9:50
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"prod", "core", "jambox"})
public class CpopEasyLearnTest {
@Autowired
private WxPayService wxPayService;
@Autowired
private WxPayProperties wxPayProperties;
@Autowired
private WxPayHandler wxPayHandler;
/**
* 关闭订单一次性支付
* @author DB
* @since 2023/12/29
*/
@Test
public void finishOncePay() throws WxPayException {
String outTradeNo = "97973645262987264";
/*String transactionId = "4200002093202312282215936862";
ProfitSharingFinishRequest profitSharingFinishRequest = new ProfitSharingFinishRequest();
profitSharingFinishRequest.setTransactionId(transactionId);
profitSharingFinishRequest.setOutOrderNo(outTradeNo);
profitSharingFinishRequest.setDescription("结束分账");
profitSharingFinishRequest.setSubMchId("1661323640");
//结束分账
wxPayService.getProfitSharingService().profitSharingFinish(profitSharingFinishRequest);*/
//完结订单
WxPayConfig wxPayConfig = wxPayService.getConfig();
wxPayConfig.setSubMchId("1661323640");
wxPayService.setConfig(wxPayConfig);
wxPayService.closeOrder(outTradeNo);
}
/**
* 放心学一次性支付
* @author DB
* @since 2023/12/29
*/
@Test
public void easyLearnOncePay(){
String orderId = "97976926051770368";
//获取订单信息
EasyLearnOrderService easyLearnOrderService = SpringUtils.getBean(EasyLearnOrderService.class);
EasyLearnOrder easyLearnOrder = easyLearnOrderService.getById(orderId);
//需要分账
String subMchId = wxPayHandler.getSubMchId(easyLearnOrder.getBrandId(), easyLearnOrder.getStoreId());
String transactionId = "4200002127202312282719627535";
//课卡信息
JSONObject jsonBody = new JSONObject();
jsonBody.put("_type", "addPeriod");
//办卡实收金额
jsonBody.put("money", easyLearnOrder.getTotalPayAmount());
//获取云校区id
StoreExtend storeExtend = SpringUtils.getBean(StoreExtendService.class).getOne(QueryWrapper.create().where(STORE_EXTEND.STORE_ID.eq(easyLearnOrder.getStoreId())));
//店铺/校区
jsonBody.put("storeId", storeExtend.getStoreCloudId());
//手机号
jsonBody.put("phone", easyLearnOrder.getCustomerPhone());
//客户名称
jsonBody.put("customerName", easyLearnOrder.getCustomerName());
//模板id
jsonBody.put("templateId", easyLearnOrder.getOrderCloudId());
//订单来源
jsonBody.put("orderSource", OrderSource.EASY_LEARN.toString());
//订单来源
jsonBody.put("subMchId", subMchId);
//获取课卡信息
JSONObject result = SpringUtils.getBean(RestTemplate.class).postForObject(JamboxCloudUrl.COMMON_CARD_URL, jsonBody, JSONObject.class);
if (result == null){
throw new ServiceException("放心学一次性支付办卡失败!");
}
easyLearnOrderService.updateChain().set(EASY_LEARN_ORDER.OUT_ORDER_NO, transactionId)
.set(EASY_LEARN_ORDER.PRODUCT_ID, result.getString("data"))
.set(EASY_LEARN_ORDER.ORDER_STATUS, 1)
.where(EASY_LEARN_ORDER.ID.eq(orderId)).update();
}
/**
* 构建分账请求参数
* @author DB
* @since 2023/12/28
* @param orderId 订单号
* @param orderSource 订单来源
* @return ProfitSharingRequest
*/
private ProfitSharingRequest buildProfitSharingRequest(String orderId, OrderSource orderSource,Integer totalFee,String subMchId,String transactionId) {
LocalDateTime now = LocalDateTime.now();
Double ceil = Math.ceil(totalFee * orderSource.getRate());
Row row = Row.ofKey(RowKey.SNOW_FLAKE_ID)
.set("order_id", orderId)
.set("profit_sharing_status", 0)
.set("amount", ceil.longValue())
.set("pay_account", subMchId)
.set("order_source",orderSource.toString())
.set("create_time", now)
.set("update_time", now)
.set("create_user_id", "1")
.set("update_user_id", "1");
Db.insert("cp_sys_profit_sharing", row);
//固定商户信息
Map<String, Object> mapReceiver = new HashMap<>(4);
mapReceiver.put("type", "MERCHANT_ID");
mapReceiver.put("account", wxPayProperties.getSharingAccount());
mapReceiver.put("amount", ceil.longValue());
mapReceiver.put("description","分账到服务商");
List<Map<String, Object>> receivers = new ArrayList<>();
receivers.add(mapReceiver);
//分账请求参数
ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
profitSharingRequest.setReceivers(JSONObject.toJSONString(receivers));
profitSharingRequest.setOutOrderNo(row.getString("id"));
profitSharingRequest.setTransactionId(transactionId);
profitSharingRequest.setSubMchId(subMchId);
return profitSharingRequest;
}
/**
* 微信支付分账
* @author DB
* @since 2023/11/03 11:09
* @param profitSharingRequest 请求参数
* @param wxPayService 微信服务类
* @param flag 标记
*/
private void wxPayProfitSharing(ProfitSharingRequest profitSharingRequest, WxPayService wxPayService, Integer flag, OrderSource orderSource) {
try {
ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingService().profitSharing(profitSharingRequest);
if (StringUtils.equals(profitSharingResult.getResultCode(), "SUCCESS")) {
//存入系统
DbChain.table("cp_sys_profit_sharing")
.set("out_profit_sharing_id", profitSharingResult.getOrderId())
.set("profit_sharing_status", 1)
.where("id = ?", profitSharingResult.getOutOrderNo())
.update();
} else {
throw new ServiceException(profitSharingResult.getReturnMsg());
}
} catch (WxPayException e) {
if (flag > 5) {
if (OrderSource.MALL == orderSource) {
//关闭商城支付
DbChain.table("cp_sys_brand")
.set("is_open_sharing", false)
.where("wx_mch_id = ?", wxPayService.getConfig().getSubMchId())
.update();
}
throw new ServiceException(e.getMessage());
} else {
//重复调用
flag = flag + 1;
wxPayProfitSharing(profitSharingRequest, wxPayService, flag, orderSource);
}
}
}
}

View File

@ -10,15 +10,23 @@ import com.cpop.core.utils.SpringUtils;
import com.cpop.jambox.business.entity.BrandExtend;
import com.cpop.jambox.business.entity.EasyLearnOrder;
import com.cpop.jambox.business.entity.StoreExtend;
import com.cpop.jambox.business.entity.StorePlug;
import com.cpop.jambox.business.service.BrandExtendService;
import com.cpop.jambox.business.service.EasyLearnOrderService;
import com.cpop.jambox.business.service.StoreExtendService;
import com.cpop.jambox.business.service.StorePlugService;
import com.cpop.oam.business.entity.BrandManager;
import com.cpop.oam.business.entity.BrandManagerStore;
import com.cpop.oam.business.service.BrandManagerService;
import com.cpop.oam.business.service.BrandManagerStoreService;
import com.cpop.system.business.entity.*;
import com.cpop.system.business.service.*;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.entity.StoreLicense;
import com.cpop.system.business.entity.StoreRenew;
import com.cpop.system.business.entity.StoreSign;
import com.cpop.system.business.service.StoreLicenseService;
import com.cpop.system.business.service.StoreRenewService;
import com.cpop.system.business.service.StoreService;
import com.cpop.system.business.service.StoreSignService;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.datasource.FlexDataSource;
@ -32,7 +40,6 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.io.*;
import java.time.LocalDate;
@ -51,7 +58,7 @@ import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
*/
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles(profiles = {"prod", "core"})
//@ActiveProfiles(profiles = {"prod", "core"})
public class CpopImportTests {
/**
@ -495,6 +502,34 @@ public class CpopImportTests {
}*/
}
/**
* 导入校区插件
* @author DB
* @since 2023/12/29
*/
@Test
public void importStorePlug(){
List<Row> rowList;
try {
//数币订单
DataSourceKey.use("jambox");
rowList = DbChain.table("t_application_mechanism")
.select("store_id as storeCloudId", "char_tag as plugTag", "remarks","creation_time as createTime","deleted as isOpen")
.list();
} finally {
DataSourceKey.clear();
}
//获取所有校区
Map<String, String> storeCloudToStore = SpringUtils.getBean(StoreExtendService.class).list().stream().collect(Collectors.toMap(StoreExtend::getStoreCloudId, StoreExtend::getStoreId));
rowList.forEach(item -> {
item.put("storeId", storeCloudToStore.get(item.getString("storeCloudId")));
item.set("isOpen", !item.getBoolean("isOpen"));
});
List<Row> filterRow = rowList.stream().filter(item -> item.getString("storeId") != null).collect(Collectors.toList());
List<StorePlug> entityList = RowUtil.toEntityList(filterRow, StorePlug.class);
SpringUtils.getBean(StorePlugService.class).saveBatch(entityList);
}
private static final String URL = "jdbc:mysql://localhost:3306/cpop_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
/**
* 数据库用户名

View File

@ -12,6 +12,7 @@ import com.cpop.oam.business.service.BusinessService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.business.vo.BusinessInfoPageVo;
import com.cpop.oam.business.vo.BusinessPageVo;
import com.cpop.oam.business.vo.PersonBusinessInfoVo;
import com.cpop.oam.business.vo.StaffVo;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
@ -121,6 +122,20 @@ public class BusinessController {
return R.ok(page);
}
/**
* 获取个人当前事务详情
* @author DB
* @since 2023/12/29
* @param id 事务详情id
* @return R<PersonBusinessInfoVo>
*/
@GetMapping("/getPersonBusinessInfoById/{id}")
@ApiOperation("获取个人当前事务详情")
public R<PersonBusinessInfoVo> getPersonBusinessInfoById(@ApiParam("请求参数") @PathVariable String id) {
PersonBusinessInfoVo vo = businessService.getPersonBusinessInfoById(id);
return R.ok(vo);
}
/**
* 员工事务处理
* @author DB

View File

@ -0,0 +1,55 @@
package com.cpop.oam.business.controller.backstage;
import com.cpop.core.base.R;
import com.cpop.jambox.business.service.StorePlugService;
import com.cpop.jambox.business.vo.StorePlugListVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static com.cpop.jambox.business.entity.table.StorePlugTableDef.STORE_PLUG;
/**
* 校区-插件记录表 控制层
*
* @author DB
* @since 2023-12-29
*/
@RestController
@Api(tags = "校区-插件记录表接口")
@RequestMapping("/storePlug")
public class StorePlugController {
@Autowired
private StorePlugService storePlugService;
/**
* 查询校区插件列表
*
* @param brandId brandId
* @param storeId storeId
*/
@GetMapping("/getStorePlugList")
@ApiOperation("查询校区插件列表")
public R<List<StorePlugListVo>> getStorePlugList(@ApiParam("品牌id") String brandId, @ApiParam("校区id") String storeId) {
List<StorePlugListVo> list = storePlugService.getStorePlugList(brandId,storeId);
return R.ok(list);
}
/**
* 插件开启与关闭
*/
@PutMapping("/changePlugOpen/{id}")
@ApiOperation("插件开启与关闭")
public R<Void> changePlugOpen(@PathVariable String id) {
storePlugService.updateChain().setRaw(STORE_PLUG.IS_OPEN, "if(is_open = 0, 1, 0)")
.where(STORE_PLUG.ID.eq(id))
.update();
return R.ok();
}
}

View File

@ -6,6 +6,7 @@ import com.cpop.oam.business.bo.BusinessInfoPageBo;
import com.cpop.oam.business.bo.BusinessRemoveBo;
import com.cpop.oam.business.vo.BusinessInfoPageVo;
import com.cpop.oam.business.vo.BusinessPageVo;
import com.cpop.oam.business.vo.PersonBusinessInfoVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.cpop.oam.business.entity.Business;
@ -59,4 +60,13 @@ public interface BusinessService extends IService<Business> {
* @param bo 删除参数
*/
void businessRemove(BusinessRemoveBo bo);
/**
* 获取个人当前事务详情
* @author DB
* @since 2023/12/29
* @param id 事务详情id
* @return PersonBusinessInfoVo
*/
PersonBusinessInfoVo getPersonBusinessInfoById(String id);
}

View File

@ -26,6 +26,7 @@ import com.cpop.oam.business.service.BusinessService;
import com.cpop.oam.business.service.BusinessStaffService;
import com.cpop.oam.business.vo.BusinessInfoPageVo;
import com.cpop.oam.business.vo.BusinessPageVo;
import com.cpop.oam.business.vo.PersonBusinessInfoVo;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.service.StoreService;
import com.mybatisflex.core.paginate.Page;
@ -133,7 +134,7 @@ public class BusinessServiceImpl extends ServiceImpl<BusinessMapper, Business> i
List<BusinessStaff> businessStaffs = BeanUtils.mapToList(bo.getSign(), BusinessStaff.class);
businessStaffs.forEach(item -> {
item.setBusinessId(businessId);
flag.set(item.getSurplusQuantity());
flag.updateAndGet(v -> v + item.getSurplusQuantity());
});
//保存负责员工
SpringUtils.getBean(BusinessStaffService.class).saveBatch(businessStaffs);
@ -402,4 +403,25 @@ public class BusinessServiceImpl extends ServiceImpl<BusinessMapper, Business> i
business.setAllSurplusQuantity(business.getAllSurplusQuantity() - 1);
this.updateById(business);
}
/**
* 获取个人当前事务详情
* @author DB
* @since 2023/12/29
* @param id 事务详情id
* @return PersonBusinessInfoVo
*/
@Override
public PersonBusinessInfoVo getPersonBusinessInfoById(String id) {
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
return this.getOneAs(QueryWrapper.create()
.select(BUSINESS.BUSINESS_LEVEL,BUSINESS.BUSINESS_TYPE,BUSINESS.DESC,BUSINESS.START_DATE,BUSINESS.END_DATE,BUSINESS.REMARK)
.select(STAFF.NAME.as(PersonBusinessInfoVo::getInitiatorName))
.select(BUSINESS_STAFF.SURPLUS_QUANTITY.as(PersonBusinessInfoVo::getSurplusQuantity))
.leftJoin(STAFF).on(STAFF.ID.eq(BUSINESS.INITIATOR_ID))
.leftJoin(BUSINESS_STAFF).on(BUSINESS_STAFF.BUSINESS_ID.eq(BUSINESS.ID))
.where(BUSINESS.ID.eq(id))
.and(BUSINESS_STAFF.STAFF_ID.eq(loginUserInfo.getString("id"))),
PersonBusinessInfoVo.class);
}
}

View File

@ -22,6 +22,7 @@ import com.cpop.oam.business.bo.TaskDemandUrgentBo;
import com.cpop.oam.business.entity.Task;
import com.cpop.oam.business.entity.TaskDemand;
import com.cpop.oam.business.mapper.TaskDemandMapper;
import com.cpop.oam.business.service.CommonService;
import com.cpop.oam.business.service.TaskDemandService;
import com.cpop.oam.business.service.TaskService;
import com.cpop.oam.business.vo.TaskDemandPageVo;
@ -183,12 +184,12 @@ public class TaskDemandServiceImpl extends ServiceImpl<TaskDemandMapper, TaskDem
this.save(entity);
// 获取审核管理员手机号
RedisService redisService = SpringUtils.getBean(RedisService.class);
String auditStaffPhone = redisService.getCacheObject(OamConfigEnum.AUDIT_STAFF_PHONE.getKey());
CommonService commonService = SpringUtils.getBean(CommonService.class);
String auditStaffPhone = redisService.getCacheObject(commonService.getCacheKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey()));
if (StringUtils.isBlank(auditStaffPhone)) {
SysConfig sysConfig =
SpringUtils.getBean(CoreService.class).selectConfigByKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey());
SysConfig sysConfig = SpringUtils.getBean(CoreService.class).selectConfigByKey(commonService.getCacheKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey()));
auditStaffPhone = sysConfig.getConfigValue();
redisService.setCacheObject(OamConfigEnum.AUDIT_STAFF_PHONE.getKey(), auditStaffPhone);
redisService.setCacheObject(commonService.getCacheKey(OamConfigEnum.AUDIT_STAFF_PHONE.getKey()), auditStaffPhone);
}
// 企微通知审核管理员
List<String> phoneList = new ArrayList<String>();

View File

@ -361,7 +361,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
.on(TASK_STAFF_GROUP.TASK_ID.eq(TASK.ID))
// 员工表
.leftJoin(STAFF)
.on(STAFF.ID.eq(TASK_STAFF_GROUP.STAFF_ID))
.on(STAFF.ID.eq(TASK.RESPONSIBLE_STAFF_ID))
.where(TASK.TASK_TYPE.in(0, 1))
.orderBy(TASK.EXPECTED_COMPLETION_DATE.asc()),
PersonTaskPageVo.class);
@ -484,16 +484,16 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
taskStaffGroups.forEach(item -> {
//向下取整
Integer oldGradePoint = item.getGradePoint();
double deductGradePoint = Math.floor(item.getGradePoint() * 0.8);
item.setGradePoint(oldGradePoint - (int) deductGradePoint).setRemark("任务完成超时扣除绩点:" + deductGradePoint);
Double deductGradePoint = Math.floor(item.getGradePoint() * 0.2);
item.setGradePoint(oldGradePoint - deductGradePoint.intValue()).setRemark("任务完成超时扣除绩点:" + deductGradePoint);
});
} else {
//3天以上50%
taskStaffGroups.forEach(item -> {
//向下取整
Integer oldGradePoint = item.getGradePoint();
double deductGradePoint = Math.floor(item.getGradePoint() * 0.5);
item.setGradePoint(oldGradePoint - (int) deductGradePoint).setRemark("任务完成超时扣除绩点:" + deductGradePoint);
Double deductGradePoint = Math.floor(item.getGradePoint() * 0.5);
item.setGradePoint(oldGradePoint - deductGradePoint.intValue()).setRemark("任务完成超时扣除绩点:" + deductGradePoint);
});
}
taskStaffGroupService.updateBatch(taskStaffGroups);

View File

@ -0,0 +1,63 @@
package com.cpop.oam.business.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDate;
/**
* @author DB
* @version 1.0.0
* @since 2023-12-29 15:16
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "PersonBusinessInfoVo对象")
public class PersonBusinessInfoVo {
/**
* 剩余数量
*/
@ApiModelProperty(value = "剩余数量")
private Integer surplusQuantity;
/**
* 业务等级业务等级(0123)
*/
@ApiModelProperty(value = "业务等级(0123急)")
private Integer businessLevel;
/**
* 业务类型业务类型(0:机构对接1机构签约)
*/
@ApiModelProperty(value = "业务类型(0:机构对接1机构签约)")
private Integer businessType;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
private String desc;
/**
* 结束时间
*/
@ApiModelProperty(value = "结束时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate endDate;
/**
* 分发人
*/
@ApiModelProperty(value = "分发人")
private String initiatorName;
/**
* 备注
*/
@ApiModelProperty(value = "备注")
private String remark;
/**
* 开始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "开始时间")
private LocalDate startDate;
}

View File

@ -76,7 +76,7 @@ public class OamScheduledTasks {
log.info("==============开始检查进行中任务===========");
TaskService taskService = SpringUtils.getBean(TaskService.class);
List<Task> taskList = taskService.queryChain().where(TASK.TASK_STATUS.in(2, 3)).and(TASK.TASK_TYPE.in(0, 1)).list();
List<Task> filterList = taskList.stream().filter(item -> item.getExpectedCompletionDate().isBefore(LocalDate.now().plusDays(1))).collect(Collectors.toList());
List<Task> filterList = taskList.stream().filter(item -> item.getExpectedCompletionDate().plusDays(1).isBefore(LocalDate.now())).collect(Collectors.toList());
if (!filterList.isEmpty()) {
//任务项逾期
taskService.updateChain().set(TASK.TASK_ITEM, -1).where(TASK.ID.in(filterList.stream().map(Task::getId).collect(Collectors.toSet()))).update();

View File

@ -71,4 +71,14 @@ public class WxPayProperties {
*/
private String sharingAccountName;
/**
* 一次性支付
*/
private String easyLearnOncePayNotifyUrl;
/**
* 放心学联合支付通知地址
*/
private String easyLearnUnionPayNotifyUrl;
}

View File

@ -103,16 +103,28 @@ public class WxPayHandler {
* @return String
*/
public String getSubMchId(String brandId, String storeId) {
//先查校区
Row store = Db.selectOneByQuery("cp_sys_store", QueryWrapper.create().where("id = ?", storeId));
String wxMchId = store.getString("wxMchId");
if (StringUtils.isBlank(wxMchId)){
String wxMchId;
if (StringUtils.isNotEmpty(storeId)){
//先查校区
Row store = Db.selectOneByQuery("cp_sys_store", QueryWrapper.create().where("id = ?", storeId));
if (store != null && StringUtils.isNotBlank(store.getString("wxMchId"))){
wxMchId = store.getString("wxMchId");
} else {
//查询品牌
Row brand = Db.selectOneByQuery("cp_sys_brand", QueryWrapper.create().where("id = ?", brandId));
if (brand != null && StringUtils.isNotBlank(brand.getString("wxMchId"))){
wxMchId = brand.getString("wxMchId");
}else {
wxMchId = "1661323640";
}
}
} else {
//查询品牌
Row brand = Db.selectOneByQuery("cp_sys_brand", QueryWrapper.create().where("id = ?", brandId));
wxMchId = brand.getString("wxMchId");
if (StringUtils.isBlank(wxMchId)){
//果酱默认商户
wxMchId = "1618925571";
if (brand != null && StringUtils.isNotBlank(brand.getString("wxMchId"))){
wxMchId = brand.getString("wxMchId");
}else {
wxMchId = "1661323640";
}
}
return wxMchId;

View File

@ -45,7 +45,7 @@ public class WxPayAsyncTask {
* @return: void
*/
@Async("customAsyncThreadPool")
public void asyncWxPayProfitSharing(String orderId, WxPayOrderNotifyResult notifyResult, WxPayService wxPayService,OrderSource orderSource) {
public void asyncWxPayProfitSharing(String orderId, WxPayOrderNotifyResult notifyResult, WxPayService wxPayService, OrderSource orderSource) {
ProfitSharingRequest profitSharingRequest = buildProfitSharingRequest(orderId, notifyResult, orderSource);
try {
Thread.sleep(5000);
@ -55,17 +55,43 @@ public class WxPayAsyncTask {
}
}
@Async("customAsyncThreadPool")
public void asyncWxPayProfitSharing(String orderId, WxPayOrderNotifyResult notifyResult, WxPayService wxPayService, OrderSource orderSource, Double rate) {
ProfitSharingRequest profitSharingRequest = buildProfitSharingRequest(orderId, notifyResult, orderSource, rate);
try {
Thread.sleep(5000);
wxPayProfitSharing(profitSharingRequest, wxPayService, 0, orderSource);
} catch (InterruptedException e) {
throw new ServiceException(e.getMessage());
}
}
/**
* @descriptions 构建分账请求参数
* 构建分账请求参数
* @author DB
* @date 2023/11/03 11:12
* @since 2023/12/28
* @param orderId 订单号
* @param notifyResult 通知结果
* @return: com.github.binarywang.wxpay.bean.profitsharingV3.ProfitSharingRequest
* @param orderSource 订单来源
* @return ProfitSharingRequest
*/
private ProfitSharingRequest buildProfitSharingRequest(String orderId, WxPayOrderNotifyResult notifyResult,OrderSource orderSource) {
private ProfitSharingRequest buildProfitSharingRequest(String orderId, WxPayOrderNotifyResult notifyResult, OrderSource orderSource) {
return buildProfitSharingRequest(orderId, notifyResult, orderSource, orderSource.getRate());
}
/**
* 构建分账请求参数
* @author DB
* @since 2023/12/28
* @param orderId 订单号
* @param notifyResult 通知结果
* @param orderSource 订单来源
* @param rate 分账比例
* @return ProfitSharingRequest
*/
private ProfitSharingRequest buildProfitSharingRequest(String orderId, WxPayOrderNotifyResult notifyResult, OrderSource orderSource, Double rate) {
LocalDateTime now = LocalDateTime.now();
Double ceil = Math.ceil(notifyResult.getTotalFee() * OrderSource.MALL.getRate());
Double ceil = Math.ceil(notifyResult.getTotalFee() * rate);
Row row = Row.ofKey(RowKey.SNOW_FLAKE_ID)
.set("order_id", orderId)
.set("profit_sharing_status", 0)
@ -95,13 +121,12 @@ public class WxPayAsyncTask {
}
/**
* @descriptions 微信支付分账
* 微信支付分账
* @author DB
* @date 2023/11/03 11:09
* @since 2023/11/03 11:09
* @param profitSharingRequest 请求参数
* @param wxPayService 微信服务类
* @param flag 标记
* @return: void
*/
private void wxPayProfitSharing(ProfitSharingRequest profitSharingRequest, WxPayService wxPayService, Integer flag, OrderSource orderSource) {
try {