This commit is contained in:
stivepeim
2021-01-19 15:42:51 +08:00
parent be34f57322
commit c12205e535
148 changed files with 4921 additions and 1557 deletions

View File

@@ -195,7 +195,7 @@ public class Constants {
public static final String CONFIG_KEY_STORE_BROKERAGE_USER_EXTRACT_BANK = "user_extract_bank"; //提现银行卡
public static final String CONFIG_KEY_STORE_BROKERAGE_EXTRACT_TIME = "extract_time"; //冻结时间
public static final String CONFIG_KEY_STORE_BROKERAGE_PERSON_PRICE = "store_brokerage_price"; //人人分销满足金额
public static final String CONFIG_KEY_STORE_BROKERAGE_IS_OPEN = "store_brokerage_status"; //分销启用
public static final String CONFIG_KEY_STORE_BROKERAGE_IS_OPEN = "brokerage_func_status"; //分销启用
//积分
public static final String CONFIG_KEY_INTEGRAL_RATE = "integral_ratio"; //积分抵用比例(1积分抵多少金额
@@ -225,15 +225,15 @@ public class Constants {
// 商品类型 活动类型 0=商品1=秒杀2=砍价3=拼团 attrResult表用到
public static final int PRODUCT_TYPE_NORMAL = 0;
public static final Integer PRODUCT_TYPE_NORMAL = 0;
public static final String PRODUCT_TYPE_NORMAL_STR = "默认";
public static final int PRODUCT_TYPE_SECKILL = 1;
public static final Integer PRODUCT_TYPE_SECKILL = 1;
public static final String PRODUCT_TYPE_SECKILL_STR = "秒杀";
public static final int PRODUCT_TYPE_BARGAIN = 2;
public static final Integer PRODUCT_TYPE_BARGAIN = 2;
public static final String PRODUCT_TYPE_BARGAIN_STR = "砍价";
public static final int PRODUCT_TYPE_PINGTUAN= 3;
public static final Integer PRODUCT_TYPE_PINGTUAN= 3;
public static final String PRODUCT_TYPE_PINGTUAN_STR= "拼团";
public static final int PRODUCT_TYPE_GROUP = 0;
public static final Integer PRODUCT_TYPE_GROUP = 0;
@@ -310,7 +310,7 @@ public class Constants {
public static final String USER_BILL_CATEGORY_BROKERAGE_PRICE = "brokerage_price"; //佣金金额
public static final String USER_BILL_CATEGORY_SIGN_NUM = "sign_num"; //签到天数
public static final String USER_BILL_TYPE_BROKERAGE = "brokerage"; //推广
public static final String USER_BILL_TYPE_BROKERAGE = "brokerage"; //推广佣金
public static final String USER_BILL_TYPE_DEDUCTION = "deduction"; //抵扣
public static final String USER_BILL_TYPE_EXTRACT = "extract"; //提现
public static final String USER_BILL_TYPE_TRANSFER_IN = "transferIn"; //佣金转入余额
@@ -330,8 +330,6 @@ public class Constants {
public static final String USER_BILL_TYPE_PAY_MEMBER = "pay_member";// 会员支付
public static final String USER_BILL_TYPE_OFFLINE_SCAN = "offline_scan";// 线下支付
public static final String USER_BILL_TYPE_USER_RECHARGE_REFUND = "user_recharge_refund";// 用户充值退款
public static final String USER_BILL_TYPE_PAY_BROKERAGE = "brokerage";// 佣金
public static final String USER_BILL_TYPE_PAY_EXTRACT = "extract";// 提现
//订单状态
public static final String ORDER_STATUS_ALL = "all"; //所有
@@ -341,6 +339,7 @@ public class Constants {
public static final String ORDER_STATUS_BARGAIN = "bargain"; //已收货待评价
public static final String ORDER_STATUS_COMPLETE = "complete"; //交易完成
public static final String ORDER_STATUS_TOBE_WRITTEN_OFF = "toBeWrittenOff"; //待核销
public static final String ORDER_STATUS_APPLY_REFUNDING = "applyRefund"; //申请退款
public static final String ORDER_STATUS_REFUNDING = "refunding"; //退款中
public static final String ORDER_STATUS_REFUNDED = "refunded"; //已退款
public static final String ORDER_STATUS_DELETED = "deleted"; //已删除
@@ -352,6 +351,7 @@ public class Constants {
public static final String ORDER_STATUS_STR_TAKE = "用户已收货"; //用户已收货
public static final String ORDER_STATUS_STR_COMPLETE = "交易完成"; //交易完成
public static final String ORDER_STATUS_STR_TOBE_WRITTEN_OFF = "待核销"; //待核销
public static final String ORDER_STATUS_STR_APPLY_REFUNDING = "申请退款"; //申请退款
public static final String ORDER_STATUS_STR_REFUNDING = "退款中"; //退款中
public static final String ORDER_STATUS_STR_REFUNDED = "已退款"; //已退款
public static final String ORDER_STATUS_STR_DELETED = "已删除"; //已删除
@@ -379,6 +379,7 @@ public class Constants {
public static final String ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER = "alterOrderCancelByUser"; // 用户取消订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER = "alterOrderRefundByUser"; // 用户订单退款后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER = "alterOrderTakeByUser"; // 用户订单收货后续操作
public static final String ORDER_TASK_PAY_SUCCESS_AFTER = "orderPaySuccessTask"; // 订单支付成功后续操作
public static final String ORDER_STATUS_CACHE_CREATE_ORDER = "cache_key_create_order";

View File

@@ -24,8 +24,8 @@ public class OnePassConstants {
public static final String ONE_PASS_USER_TOKEN_PREFIX = "Bearer-";
// 一号通请求地址
public static final String ONE_PASS_API_URL = "https://sms.crmeb.net/api/";// 正式环境
// public static final String ONE_PASS_API_URL = "http://plat.crmeb.net/api/";// 测试环境
// public static final String ONE_PASS_API_URL = "https://sms.crmeb.net/api/";// 正式环境
public static final String ONE_PASS_API_URL = "http://plat.crmeb.net/api/";// 测试环境
// 验证码地址
public static final String REGISTER_CAPTCHA_URI = "user/code";

View File

@@ -0,0 +1,51 @@
package com.constants;
/**
* 支付相关常量类
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class PayConstants {
//支付方式
public static final String PAY_TYPE_WE_CHAT = "weixin"; //微信支付
public static final String PAY_TYPE_YUE = "yue"; //余额支付
public static final String PAY_TYPE_OFFLINE = "offline"; //线下支付
public static final String PAY_TYPE_ALI_PAY = "alipay"; //支付宝
public static final String PAY_TYPE_ZERO_PAY = "zeroPay"; // 零元付
//支付渠道
public static final String PAY_CHANNEL_WE_CHAT_H5 = "weixinh5"; //H5唤起微信支付
public static final String PAY_CHANNEL_WE_CHAT_PUBLIC = "public"; //公众号
public static final String PAY_CHANNEL_WE_CHAT_PROGRAM = "routine"; //小程序
public static final String WX_PAY_TRADE_TYPE_JS = "JSAPI";
public static final String WX_PAY_TRADE_TYPE_H5 = "MWEB";
//微信支付接口请求地址
public static final String WX_PAY_API_URL = "https://api.mch.weixin.qq.com/";
// 微信统一预下单
public static final String WX_PAY_API_URI = "pay/unifiedorder";
// 微信查询订单
public static final String WX_PAY_ORDER_QUERY_API_URI = "pay/orderquery";
// 微信支付回调地址
public static final String WX_PAY_NOTIFY_API_URI = "/api/admin/payment/callback/wechat";
// 微信退款回调地址
public static final String WX_PAY_REFUND_NOTIFY_API_URI = "/api/admin/payment/callback/wechat/refund";
public static final String WX_PAY_SIGN_TYPE_MD5 = "MD5";
public static final String WX_PAY_SIGN_TYPE_SHA256 = "HMAC-SHA256";
public static final String PAY_BODY = "Crmeb支付中心-订单支付";
public static final String FIELD_SIGN = "sign";
// 公共号退款
public static final String WX_PAY_REFUND_API_URI= "secapi/pay/refund";
}

View File

@@ -587,6 +587,44 @@ public class CrmebUtil {
// setScaler(1,BigDecimal.ROUND_HALF_DOWN);//四舍五入2.35变成2.3如果是5则向下舍
}
/**
* 同比率计算 //同比增长率= ((当前周期 - 上一个周期) ÷ 上一个周期 ) *100%
* @param i1 当前周期
* @param i2 上一个周期
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static BigDecimal getRateBig(Integer i1, Integer i2){
BigDecimal b1 = new BigDecimal(i1);
BigDecimal b2 = new BigDecimal(i2);
return getRateBig(b1, b2);
}
/**
* 同比率计算 //同比增长率= ((当前周期 - 上一个周期) ÷ 上一个周期 ) *100%
* @param b1 当前周期
* @param b2 上一个周期
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static BigDecimal getRateBig(BigDecimal b1, BigDecimal b2){
//计算差值
if(b2.equals(b1)){
//数值一样,说明没有增长
return BigDecimal.ZERO;
}
if(b2.equals(BigDecimal.ZERO)){
//b2是0
return BigDecimal.TEN.multiply(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_UP);
}
return (b1.subtract(b2)).multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).divide(b2, BigDecimal.ROUND_UP);
}
/**
* hash 转换
* @param hash final byte[] hash参数

View File

@@ -507,10 +507,10 @@ public final class DateUtil {
startTime = list.get(0);
endTime = list.get(1);
if (startTime.equals(endTime)) {
// if (startTime.equals(endTime)) {
startTime = DateUtil.appointedDayStrToFormatStr(startTime, Constants.DATE_FORMAT_DATE, Constants.DATE_FORMAT_START);
endTime = DateUtil.appointedDayStrToFormatStr(endTime, Constants.DATE_FORMAT_DATE, Constants.DATE_FORMAT_END);
}
// }
break;
}
}

View File

@@ -0,0 +1,39 @@
package com.utils;
import org.w3c.dom.Document;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
/**
* 微信支付xml工具类
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public final class WXPayXmlUtil {
public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
return documentBuilderFactory.newDocumentBuilder();
}
public static Document newDocument() throws ParserConfigurationException {
return newDocumentBuilder().newDocument();
}
}

View File

@@ -1,9 +1,23 @@
package com.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.constants.Constants;
import com.constants.PayConstants;
import com.exception.CrmebException;
import com.zbkj.crmeb.payment.vo.wechat.CreateOrderRequestVo;
import com.zbkj.crmeb.payment.vo.wechat.WxRefundVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.*;
/**
* 微信支付工具类
@@ -19,10 +33,6 @@ import java.util.HashMap;
*/
public class WxPayUtil {
/**
* TODO 后期微信签名生成、校验等在这里开发
*/
/**
* 处理 HTTPS API返回数据转换成Map对象。return_code为SUCCESS时验证签名。
*
@@ -48,4 +58,141 @@ public class WxPayUtil {
throw new CrmebException(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
}
}
/**
* 获取随机字符串长度要求在32位以内。
*/
public static String getNonceStr() {
return DigestUtils.md5Hex(CrmebUtil.getUuid() + CrmebUtil.randomCount(111111, 666666));
}
/**
* 获取sign
* @param vo 微信公共下单对象
* @param signKey 微信签名key
* @return String
*/
public static String getSign(CreateOrderRequestVo vo, String signKey) {
// 对象转map
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(vo), Map.class);
// map排序
Set<String> keySet = map.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(PayConstants.FIELD_SIGN)) {
continue;
}
if (ObjectUtil.isNotNull(map.get(k))) // 参数值为空,则不参与签名
sb.append(k).append("=").append(map.get(k)).append("&");
}
sb.append("key=").append(signKey);
String sign = SecureUtil.md5(sb.toString()).toUpperCase();
System.out.println("sign ========== " + sign);
return sign;
}
/**
* 获取sign
* @param wxRefundVo 微信退款对象
* @param signKey 微信签名key
* @return String
*/
public static String getSign(WxRefundVo wxRefundVo, String signKey) {
// 对象转map
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(wxRefundVo), Map.class);
// map排序
Set<String> keySet = map.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(PayConstants.FIELD_SIGN)) {
continue;
}
if (ObjectUtil.isNotNull(map.get(k))) // 参数值为空,则不参与签名
sb.append(k).append("=").append(map.get(k)).append("&");
}
sb.append("key=").append(signKey);
String sign = SecureUtil.md5(sb.toString()).toUpperCase();
System.out.println("sign ========== " + sign);
return sign;
}
/**
* 获取sign
* @param map 待签名数据
* @param signKey 微信签名key
* @return String
*/
public static String getSign(Map<String, String> map, String signKey) {
// map排序
Set<String> keySet = map.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(PayConstants.FIELD_SIGN)) {
continue;
}
if (StrUtil.isNotBlank(map.get(k)) && map.get(k).trim().length() > 0) // 参数值为空,则不参与签名
sb.append(k).append("=").append(map.get(k).trim()).append("&");
}
sb.append("key=").append(signKey);
String sign = SecureUtil.md5(sb.toString()).toUpperCase();
System.out.println("sign ========== " + sign);
return sign;
}
/**
* 获取当前时间戳,单位秒
* @return Long
*/
public static Long getCurrentTimestamp() {
return System.currentTimeMillis()/1000;
}
/**
* 获取当前时间戳,单位毫秒
* @return Long
*/
public static Long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
try {
stream.close();
} catch (Exception ex) {
// do nothing
}
return data;
} catch (Exception ex) {
System.out.println(StrUtil.format("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML));
throw ex;
}
}
}

View File

@@ -10,30 +10,35 @@ import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* XML 工具类
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
* XML 工具类
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class XmlUtil {
public static Map<String,String> xmlToMap(HttpServletRequest request)
{
Map<String,String> map = new HashMap<>();
public static Map<String, String> xmlToMap(HttpServletRequest request) {
Map<String, String> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream in = null;
@@ -47,7 +52,7 @@ public class XmlUtil {
}
} catch (IOException | DocumentException e) {
e.printStackTrace();
} finally{
} finally {
try {
assert in != null;
in.close();
@@ -61,14 +66,14 @@ public class XmlUtil {
/**
* 将发送消息封装成对应的xml格式
*/
public static HashMap<String,Object> xmlToMap(String strxml)throws Exception{
public static HashMap<String, Object> xmlToMap(String strxml) throws Exception {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
HashMap<String,Object> map = new HashMap<>();
HashMap<String, Object> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream inputStream = new ByteArrayInputStream(strxml.getBytes(StandardCharsets.UTF_8));
if(StringUtils.isBlank(strxml)) {
if (StringUtils.isBlank(strxml)) {
return null;
}
@@ -76,8 +81,8 @@ public class XmlUtil {
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element e : list){
map.put(e.getName(),e.getText());
for (Element e : list) {
map.put(e.getName(), e.getText());
}
inputStream.close();
@@ -88,10 +93,42 @@ public class XmlUtil {
* 将发送消息封装成对应的xml格式
*/
public static String objectToXml(Object object) {
XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder())); //不需要转义
XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder())); //不需要转义
xstream.alias("xml", object.getClass());
return xstream.toXML(object);
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
writer.close();
return output;
}
}

View File

@@ -32,7 +32,7 @@ public class ArticleSearchRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "分类id", required = true)
@ApiModelProperty(value = "分类id", example = "")
private String cid;
@ApiModelProperty(value = "搜索关键字")
@@ -41,16 +41,16 @@ public class ArticleSearchRequest implements Serializable {
@ApiModelProperty(value = "是否有微信素材媒体id")
private Boolean isHaveMediaId = null;
@ApiModelProperty(value = "是否热门(小程序)", example = "null")
@ApiModelProperty(value = "是否热门(小程序)", example = "")
private Boolean isHot = null;
@ApiModelProperty(value = "是否轮播图(小程序)" , example = "null")
@ApiModelProperty(value = "是否轮播图(小程序)" , example = "")
private Boolean isBanner = null;
@ApiModelProperty(value = "是否隐藏", example = "null")
@ApiModelProperty(value = "是否隐藏", example = "")
private Boolean hide = null;
@ApiModelProperty(value = "状态" , example = "null")
@ApiModelProperty(value = "状态" , example = "")
private Boolean status = null;
}

View File

@@ -91,7 +91,7 @@ public class StoreBargain implements Serializable {
private Boolean status;
@ApiModelProperty(value = "反多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "砍价活动简介")
private String info;

View File

@@ -99,7 +99,7 @@ public class StoreBargainRequest implements Serializable {
private Boolean status;
@ApiModelProperty(value = "反多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "砍价活动简介")
@NotBlank(message = "砍价活动简介不能为空")

View File

@@ -78,7 +78,7 @@ public class StoreBargainResponse {
private Boolean status;
@ApiModelProperty(value = "反多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "砍价活动简介")
private String info;

View File

@@ -31,103 +31,82 @@ public interface StoreBargainService extends IService<StoreBargain> {
/**
* 分页显示砍价商品列表
* @param request
* @param pageParamRequest
* @return
*/
PageInfo<StoreBargainResponse> getList(StoreBargainSearchRequest request, PageParamRequest pageParamRequest);
/**
* 新增砍价商品
* @param storeBargainRequest
* @return
*/
boolean saveBargain(StoreBargainRequest storeBargainRequest);
/**
* 删除砍价商品
* @param id
* @return
*/
boolean deleteById(Integer id);
/**
* 修改砍价商品
* @param storeBargainRequest
* @return
*/
boolean updateBarhain(StoreBargainRequest storeBargainRequest);
/**
* 修改砍价商品状态
* @param id
* @param status
* @return
*/
boolean updateBargainStatus(Integer id, boolean status);
/**
* 查询砍价商品详情
* @param id
* @return
*/
StoreProductResponse getAdminDetail(Integer id);
/**
* H5 砍价商品列表
* @param pageParamRequest
* @return
*/
PageInfo<StoreBargainResponse> getH5List(PageParamRequest pageParamRequest);
/**
* H5 获取查看、分享、参与人数
* @param id
* @return
* @param id BargainDetailResponse
*/
Map<String, Object> getH5Share(Integer id);
/**
* H5 获取砍价商品详情信息
* @param id
* @return
* @return BargainDetailResponse
*/
BargainDetailResponse getH5Detail(Integer id);
/**
* 获取当前时间的砍价商品
* @param productId
* @return
* @return List<StoreBargain>
*/
List<StoreBargain> getCurrentBargainByProductId(Integer productId);
/**
* 参与砍价活动
* @param bargainFrontRequest
* @return
* @return Boolean
*/
Boolean start(BargainFrontRequest bargainFrontRequest);
/**
* 砍价商品根据实体查询
* @param storeBargainParam
* @return
* @return Boolean
*/
List<StoreBargain> getByEntity(StoreBargain storeBargainParam);
/**
* 扣减砍价商品库存
* @param bargainId 产品id
* @param num 商品数量
* @param attrValueId
* @param type 是否限购 0=不限购
* @return
* @param bargainId 砍价产品id
* @param num 购买商品数量
* @param attrValueId 砍价产品规格
* @param productId 主商品id
* @param uid 用户uid
* @return Boolean
*/
boolean decProductStock(Integer bargainId, Integer num, Integer attrValueId, Integer type);
Boolean decProductStock(Integer bargainId, Integer num, Integer attrValueId, Integer productId, Integer uid);
/**
* 添加库存
* @param stockRequest
*/
Boolean stockAddRedis(StoreProductStockRequest stockRequest);
@@ -146,4 +125,19 @@ public interface StoreBargainService extends IService<StoreBargain> {
* @param productId 商品编号
*/
Boolean isExistActivity(Integer productId);
/**
* 查询带异常
* @param id 砍价商品id
* @return StoreBargain
*/
StoreBargain getByIdException(Integer id);
/**
* 添加/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
*/
Boolean operationStock(Integer id, Integer num, String type);
}

View File

@@ -8,6 +8,7 @@ import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
@@ -44,6 +45,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -104,6 +106,9 @@ public class StoreBargainServiceImpl extends ServiceImpl<StoreBargainDao, StoreB
@Autowired
private StoreOrderService storeOrderService;
@Autowired
private TransactionTemplate transactionTemplate;
private static final Logger logger = LoggerFactory.getLogger(StoreBargainServiceImpl.class);
/**
@@ -633,43 +638,49 @@ public class StoreBargainServiceImpl extends ServiceImpl<StoreBargainDao, StoreB
/**
* 扣减砍价商品库存
* @param bargainId
* @param num
* @param attrValueId
* @param type
* @return
* 扣除砍价商品表库存
* @param bargainId 砍价产品id
* @param num 购买商品数量
* @param attrValueId 砍价产品规格
* @param productId 主商品id
* @param uid 用户uid
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean decProductStock(Integer bargainId, Integer num, Integer attrValueId, Integer type) {
public Boolean decProductStock(Integer bargainId, Integer num, Integer attrValueId, Integer productId, Integer uid) {
// 因为attrvalue表中unique使用Id代替更新前先查询此表是否存在
StoreProductAttrValue spavParm = new StoreProductAttrValue();
spavParm.setId(attrValueId).setType(type).setProductId(bargainId);
spavParm.setProductId(bargainId);
spavParm.setType(Constants.PRODUCT_TYPE_BARGAIN);
spavParm.setId(attrValueId);
List<StoreProductAttrValue> attrvalues = storeProductAttrValueService.getByEntity(spavParm);
if (CollUtil.isEmpty(attrvalues)) throw new CrmebException("未找到相关商品属性");
// 扣除砍价商品属性值表的suk 砍价商品只会有一条sku
StoreProductAttrValue storeProductAttrValue = attrvalues.get(0);
if (ObjectUtil.isNotNull(storeProductAttrValue)) {
boolean updateAttrValue = storeProductAttrValueService.decProductAttrStock(bargainId, attrValueId, num, type);
if (!updateAttrValue) {
throw new CrmebException("扣减砍价商品sku库存失败");
}
}
StoreProductAttrValue bargaunAttrValue = attrvalues.get(0);
// 对应的主商品sku
List<StoreProductAttrValue> currentProAttrValues = storeProductAttrValueService.getListByProductId(productId);
List<StoreProductAttrValue> existAttrValues = currentProAttrValues.stream().filter(e ->
e.getSuk().equals(bargaunAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL))
.collect(Collectors.toList());
if (CollUtil.isEmpty(existAttrValues)) throw new CrmebException("未找到扣减库存的商品");
// 砍价SKU 库存减,销量、限购总数减
StoreBargain storeBargain = getById(bargainId);
LambdaUpdateWrapper<StoreBargain> luw = new LambdaUpdateWrapper<>();
luw.eq(StoreBargain::getId, bargainId);
luw.set(StoreBargain::getStock, storeBargain.getStock() - num);
luw.set(StoreBargain::getSales, storeBargain.getSales() + num);
luw.set(StoreBargain::getQuota, storeBargain.getQuota() - num);
boolean update = update(luw);
if (!update) {
throw new CrmebException("扣减砍价商品库存失败");
}
return update;
luw.eq(StoreBargain::getId, bargainId);
luw.apply(StrUtil.format(" (stock - {} >= 0) ", num));
// 砍价商品购买成功,改变用户状态
StoreBargainUser storeBargainUser = storeBargainUserService.getByBargainIdAndUid(bargainId, uid);
if (ObjectUtil.isNull(storeBargainUser)) throw new CrmebException("砍价用户信息不存在");
storeBargainUser.setStatus(3);
Boolean execute = transactionTemplate.execute(e -> {
storeProductAttrValueService.decProductAttrStock(bargainId, attrValueId, num, Constants.PRODUCT_TYPE_BARGAIN);
storeProductService.decProductStock(productId, num, existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL);
update(luw);
storeBargainUserService.updateById(storeBargainUser);
return Boolean.TRUE;
});
return execute;
}
/**
@@ -769,6 +780,47 @@ public class StoreBargainServiceImpl extends ServiceImpl<StoreBargainDao, StoreB
return CollUtil.isNotEmpty(list);
}
/**
* 查询带异常
* @param id 砍价商品id
* @return StoreBargain
*/
@Override
public StoreBargain getByIdException(Integer id) {
LambdaQueryWrapper<StoreBargain> lqw = new LambdaQueryWrapper<>();
lqw.eq(StoreBargain::getId, id);
lqw.eq(StoreBargain::getIsDel, false);
lqw.eq(StoreBargain::getStatus, true);
StoreBargain storeBargain = dao.selectOne(lqw);
if (ObjectUtil.isNull(storeBargain)) throw new CrmebException("砍价商品不存在或未开启");
return storeBargain;
}
/**
* 添加/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
*/
@Override
public Boolean operationStock(Integer id, Integer num, String type) {
UpdateWrapper<StoreBargain> updateWrapper = new UpdateWrapper<>();
if (type.equals("add")) {
updateWrapper.setSql(StrUtil.format("stock = stock + {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales - {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota + {}", num));
}
if (type.equals("sub")) {
updateWrapper.setSql(StrUtil.format("stock = stock - {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales + {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota - {}", num));
// 扣减时加乐观锁保证库存不为负
updateWrapper.last(StrUtil.format(" and (stock - {} >= 0)", num));
}
updateWrapper.eq("id", id);
return update(updateWrapper);
}
/**
* 查询活动状态为开启,结束时间小于当前时间的数据
* @return

View File

@@ -52,7 +52,7 @@ public class Category implements Serializable {
@ApiModelProperty(value = "扩展字段")
private String extra;
@ApiModelProperty(value = "状态, 0正常,1失效")
@ApiModelProperty(value = "状态,1正常,0失效")
private Boolean status;
@ApiModelProperty(value = "排序")

View File

@@ -41,7 +41,7 @@ public class CategorySearchRequest implements Serializable {
@ApiModelProperty(value = "类型ID | 类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置")
private Integer type;
@ApiModelProperty(value = "状态, 0正常,1失效")
private Boolean status;
@ApiModelProperty(value = "状态, 1正常,0失效 -1全部")
private Integer status;
}

View File

@@ -1,6 +1,7 @@
package com.zbkj.crmeb.category.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -56,20 +57,18 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, Category> impl
public List<Category> getList(CategorySearchRequest request, PageParamRequest pageParamRequest) {
PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Category category = new Category();
BeanUtils.copyProperties(request,category);
// objectQueryWrapper.setEntity(category);
if(null != category.getPid()){
lambdaQueryWrapper.eq(Category::getPid, category.getPid());
if(null != request.getPid()){
lambdaQueryWrapper.eq(Category::getPid, request.getPid());
}
if(null != category.getType()){
lambdaQueryWrapper.eq(Category::getType, category.getType());
if(null != request.getType()){
lambdaQueryWrapper.eq(Category::getType, request.getType());
}
if(null != category.getStatus()){
lambdaQueryWrapper.eq(Category::getStatus, category.getStatus());
if(ObjectUtil.isNotNull(request.getStatus()) && request.getStatus() >= 0){
lambdaQueryWrapper.eq(Category::getStatus, request.getStatus().equals(1));
}
if(null != category.getName()){
lambdaQueryWrapper.like(Category::getName, category.getName());
if(null != request.getName()){
lambdaQueryWrapper.like(Category::getName, request.getName());
}
lambdaQueryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getId);
return dao.selectList(lambdaQueryWrapper);
@@ -262,6 +261,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, Category> impl
*/
@Override
public List<CategoryTreeVo> getListTree(Integer type, Integer status, List<Integer> categoryIdList) {
System.out.println("菜单列表:getListTree: type:" + type + "| status:" + status + "| categoryIdList:" + JSON.toJSONString(categoryIdList));
return getTree(type, status,null,categoryIdList);
}
@@ -329,6 +329,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, Category> impl
list.add(tree);
}
}
System.out.println("无限极分类 : getTree:" + JSON.toJSONString(list));
return list;
}

View File

@@ -3,13 +3,12 @@ package com.zbkj.crmeb.combination.controller;
import com.common.CommonPage;
import com.common.CommonResult;
import com.common.PageParamRequest;
import com.zbkj.crmeb.combination.model.StorePink;
import com.zbkj.crmeb.combination.request.StoreCombinationRequest;
import com.zbkj.crmeb.combination.request.StoreCombinationSearchRequest;
import com.zbkj.crmeb.combination.request.StorePinkSearchRequest;
import com.zbkj.crmeb.combination.response.StoreCombinationResponse;
import com.zbkj.crmeb.combination.response.StorePinkAdminListResponse;
import com.zbkj.crmeb.combination.response.StorePinkResponse;
import com.zbkj.crmeb.combination.response.StorePinkDetailResponse;
import com.zbkj.crmeb.combination.service.StoreCombinationService;
import com.zbkj.crmeb.combination.service.StorePinkService;
import com.zbkj.crmeb.store.response.StoreProductResponse;
@@ -168,7 +167,7 @@ public class StoreCombinationController {
*/
@ApiOperation(value = "拼团订单列表")
@RequestMapping(value = "/order_pink/{id}", method = RequestMethod.GET)
public CommonResult<List<StorePink>> getPinkList(@PathVariable(value = "id") Integer id) {
public CommonResult<List<StorePinkDetailResponse>> getPinkList(@PathVariable(value = "id") Integer id) {
return CommonResult.success(storePinkService.getAdminList(id));
}
}

View File

@@ -0,0 +1,59 @@
package com.zbkj.crmeb.combination.response;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 拼团表
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="StorePinkDetailResponse对象", description="拼团详情响应对象")
public class StorePinkDetailResponse implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "拼团ID")
private Integer id;
@ApiModelProperty(value = "用户id")
private Integer uid;
@ApiModelProperty(value = "订单id 生成")
private String orderId;
@ApiModelProperty(value = "购买总金额")
private BigDecimal totalPrice;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "订单状态0待发货1待收货2已收货待评价3已完成")
private Integer orderStatus;
@ApiModelProperty(value = "0 未退款 1 申请中 2 已退款 3退款中")
private Integer refundStatus;
}

View File

@@ -10,8 +10,10 @@ import com.zbkj.crmeb.combination.request.StorePinkRequest;
import com.zbkj.crmeb.front.response.CombinationDetailResponse;
import com.zbkj.crmeb.combination.response.StoreCombinationResponse;
import com.zbkj.crmeb.front.response.GoPinkResponse;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.request.StoreProductStockRequest;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import com.zbkj.crmeb.user.model.User;
import java.util.HashMap;
import java.util.List;
@@ -130,13 +132,13 @@ public interface StoreCombinationService extends IService<StoreCombination> {
/**
* 扣减库存加销量
* @param combinationId 产品id
* @param num 商品数量
* @param attrValueId
* @param type 是否限购 0=不限购
* @return 扣减结果
* @param num 商品数量
* @param attrValueId 拼团商品规格
* @param productId 主商品id
* @param user 购买用户
* @return Boolean
*/
Boolean decProductStock(Integer combinationId, Integer num, int attrValueId, int type);
Boolean decProductStock(StoreOrder storeOrder, Integer num, Integer attrValueId, Integer productId, User user);
/**
* 添加库存
@@ -170,4 +172,19 @@ public interface StoreCombinationService extends IService<StoreCombination> {
* @return
*/
Boolean isExistActivity(Integer productId);
/**
* 查询带异常
* @param combinationId 拼团商品id
* @return StoreCombination
*/
StoreCombination getByIdException(Integer combinationId);
/**
* 添加/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
*/
Boolean operationStock(Integer id, Integer num, String type);
}

View File

@@ -6,6 +6,7 @@ import com.zbkj.crmeb.combination.model.StorePink;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zbkj.crmeb.combination.request.StorePinkSearchRequest;
import com.zbkj.crmeb.combination.response.StorePinkAdminListResponse;
import com.zbkj.crmeb.combination.response.StorePinkDetailResponse;
import java.util.List;
@@ -50,7 +51,7 @@ public interface StorePinkService extends IService<StorePink> {
* @param pinkId 团长pinkId
* @return
*/
List<StorePink> getAdminList(Integer pinkId);
List<StorePinkDetailResponse> getAdminList(Integer pinkId);
/**
* 查询拼团列表

View File

@@ -1,12 +1,14 @@
package com.zbkj.crmeb.combination.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
@@ -49,6 +51,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -115,6 +118,9 @@ public class StoreCombinationServiceImpl extends ServiceImpl<StoreCombinationDao
@Autowired
private RedisUtil redisUtil;
@Autowired
private TransactionTemplate transactionTemplate;
private static final Logger logger = LoggerFactory.getLogger(StoreCombinationServiceImpl.class);
/**
@@ -313,8 +319,15 @@ public class StoreCombinationServiceImpl extends ServiceImpl<StoreCombinationDao
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateCombination(StoreCombinationRequest request) {
StoreCombination existCombination = getById(request.getId());
if (ObjectUtil.isNull(existCombination) || existCombination.getIsDel()) throw new CrmebException("拼团商品不存在");
long timeMillis = System.currentTimeMillis();
if (existCombination.getIsShow().equals(true) && existCombination.getStartTime() <= timeMillis && timeMillis <= existCombination.getStopTime()) {
throw new CrmebException("活动开启中,商品不支持修改");
}
// 过滤掉checked=false的数据
System.out.println("updateCombination request = " + request);
clearNotCheckedAndValidationPrice(request);
StoreCombination storeCombination = new StoreCombination();
@@ -911,38 +924,95 @@ public class StoreCombinationServiceImpl extends ServiceImpl<StoreCombinationDao
/**
* 扣减库存加销量
* @param combinationId 产品id
* @param num 商品数量
* @param attrValueId
* @param type 是否限购 0=不限购
* @return
* @param num 商品数量
* @param attrValueId 拼团商品规格
* @param productId 主商品id
* @param user 购买用户
* @return Boolean
*/
@Override
public Boolean decProductStock(Integer combinationId, Integer num, int attrValueId, int type) {
// 因为attrvalue表中unique使用Id代替更新前先查询此表是否存在
// 秒杀SKU 扣减库存加销量
StoreProductAttrValue spavPram = new StoreProductAttrValue();
spavPram.setProductId(combinationId).setType(type).setId(attrValueId);
List<StoreProductAttrValue> existAttrValues = storeProductAttrValueService.getByEntity(spavPram);
if(CollUtil.isEmpty(existAttrValues)) throw new CrmebException("未找到相关商品属性信息");
StoreProductAttrValue productsInAttrValue = existAttrValues.get(0);
StoreCombination storeCombination = getById(combinationId);
boolean result = false;
if(ObjectUtil.isNotNull(productsInAttrValue)){
boolean resultDecProductStock = storeProductAttrValueService.decProductAttrStock(combinationId, attrValueId, num, type);
if(!resultDecProductStock) throw new CrmebException("扣减拼团sku库存失败");
public Boolean decProductStock(StoreOrder storeOrder, Integer num, Integer attrValueId, Integer productId, User user) {
// 判断拼团团长是否存在
StorePink headPink = new StorePink();
if (storeOrder.getPinkId() > 0) {
headPink = storePinkService.getById(storeOrder.getPinkId());
if (ObjectUtil.isNull(headPink) || headPink.getIsRefund().equals(true) || headPink.getStatus() == 3) {
throw new CrmebException("找不到对应的拼团团队信息");
}
}
// 拼团商品本身库存扣减
StoreProductAttrValue spavPram = new StoreProductAttrValue();
spavPram.setProductId(storeOrder.getCombinationId());
spavPram.setType(Constants.PRODUCT_TYPE_PINGTUAN);
spavPram.setId(attrValueId);
List<StoreProductAttrValue> attrvalues = storeProductAttrValueService.getByEntity(spavPram);
if(CollUtil.isEmpty(attrvalues)) throw new CrmebException("未找到相关商品属性信息");
StoreProductAttrValue combinationAttrValue = attrvalues.get(0);
// 对应的主商品sku
List<StoreProductAttrValue> currentProAttrValues = storeProductAttrValueService.getListByProductId(productId);
List<StoreProductAttrValue> existAttrValues = currentProAttrValues.stream().filter(e ->
e.getSuk().equals(combinationAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL))
.collect(Collectors.toList());
if (CollUtil.isEmpty(existAttrValues)) throw new CrmebException("未找到扣减库存的商品");
StoreCombination storeCombination = getById(storeOrder.getCombinationId());
// 拼团商品表扣减库存加销量
LambdaUpdateWrapper<StoreCombination> lqwuper = new LambdaUpdateWrapper<>();
lqwuper.eq(StoreCombination::getId, combinationId);
lqwuper.set(StoreCombination::getStock, storeCombination.getStock()-num);
lqwuper.set(StoreCombination::getSales, storeCombination.getSales()+num);
lqwuper.set(StoreCombination::getQuota, storeCombination.getQuota()-num);
result = update(lqwuper);
return result;
lqwuper.eq(StoreCombination::getId, storeOrder.getCombinationId());
lqwuper.apply(StrUtil.format(" (stock - {} >= 0) ", num));
// 生成拼团表数据
StorePink storePink = new StorePink();
storePink.setUid(user.getUid());
storePink.setAvatar(user.getAvatar());
storePink.setNickname(user.getNickname());
storePink.setOrderId(storeOrder.getOrderId());
storePink.setOrderIdKey(storeOrder.getId());
storePink.setTotalNum(storeOrder.getTotalNum());
storePink.setTotalPrice(storeOrder.getTotalPrice());
storePink.setCid(storeCombination.getId());
storePink.setPid(storeCombination.getProductId());
storePink.setPeople(storeCombination.getPeople());
storePink.setPrice(storeCombination.getPrice());
Integer effectiveTime = storeCombination.getEffectiveTime();// 有效小时数
DateTime dateTime = cn.hutool.core.date.DateUtil.date();
storePink.setAddTime(dateTime.getTime());
if (ObjectUtil.isNotNull(storeOrder.getPinkId()) && storeOrder.getPinkId() > 0) {
storePink.setStopTime(headPink.getStopTime());
} else {
DateTime hourTime = cn.hutool.core.date.DateUtil.offsetHour(dateTime, effectiveTime);
long stopTime = hourTime.getTime();
if (stopTime > storeCombination.getStopTime()) {
stopTime = storeCombination.getStopTime();
}
storePink.setStopTime(stopTime);
}
storePink.setKId(Optional.ofNullable(storeOrder.getPinkId()).orElse(0));
storePink.setIsTpl(false);
storePink.setIsRefund(false);
storePink.setStatus(1);
Boolean execute = transactionTemplate.execute(e -> {
// 拼团规格扣减
storeProductAttrValueService.decProductAttrStock(storeOrder.getCombinationId(), attrValueId, num, Constants.PRODUCT_TYPE_PINGTUAN);
// 主商品扣减
storeProductService.decProductStock(productId, num, existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL);
// 拼团商品扣减
update(lqwuper);
storePinkService.save(storePink);
// 如果是开团,需要更新订单数据
if (storePink.getKId() == 0) {
storeOrder.setPinkId(storePink.getId());
storeOrderService.updateById(storeOrder);
}
return Boolean.TRUE;
});
return execute;
}
/**
@@ -1031,6 +1101,47 @@ public class StoreCombinationServiceImpl extends ServiceImpl<StoreCombinationDao
return CollUtil.isNotEmpty(list);
}
/**
* 查询带异常
* @param combinationId 拼团商品id
* @return StoreCombination
*/
@Override
public StoreCombination getByIdException(Integer combinationId) {
LambdaQueryWrapper<StoreCombination> lqw = new LambdaQueryWrapper<>();
lqw.eq(StoreCombination::getId, combinationId);
lqw.eq(StoreCombination::getIsDel, false);
lqw.eq(StoreCombination::getIsShow, true);
StoreCombination storeCombination = dao.selectOne(lqw);
if (ObjectUtil.isNull(storeCombination)) throw new CrmebException("拼团商品不存在或未开启");
return storeCombination;
}
/**
* 添加/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
*/
@Override
public Boolean operationStock(Integer id, Integer num, String type) {
UpdateWrapper<StoreCombination> updateWrapper = new UpdateWrapper<>();
if (type.equals("add")) {
updateWrapper.setSql(StrUtil.format("stock = stock + {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales - {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota + {}", num));
}
if (type.equals("sub")) {
updateWrapper.setSql(StrUtil.format("stock = stock - {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales + {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota - {}", num));
// 扣减时加乐观锁保证库存不为负
updateWrapper.last(StrUtil.format(" and (stock - {} >= 0)", num));
}
updateWrapper.eq("id", id);
return update(updateWrapper);
}
/**
* 拼团操作库存
* @param storeProductStockRequest

View File

@@ -20,6 +20,7 @@ import com.zbkj.crmeb.combination.model.StoreCombination;
import com.zbkj.crmeb.combination.model.StorePink;
import com.zbkj.crmeb.combination.request.StorePinkSearchRequest;
import com.zbkj.crmeb.combination.response.StorePinkAdminListResponse;
import com.zbkj.crmeb.combination.response.StorePinkDetailResponse;
import com.zbkj.crmeb.combination.service.StoreCombinationService;
import com.zbkj.crmeb.combination.service.StorePinkService;
import com.zbkj.crmeb.front.request.OrderRefundApplyRequest;
@@ -142,19 +143,23 @@ public class StorePinkServiceImpl extends ServiceImpl<StorePinkDao, StorePink> i
* @return
*/
@Override
public List<StorePink> getAdminList(Integer pinkId) {
public List<StorePinkDetailResponse> getAdminList(Integer pinkId) {
LambdaQueryWrapper<StorePink> lqw = Wrappers.lambdaQuery();
lqw.eq(StorePink::getId, pinkId).or().eq(StorePink::getKId, pinkId);
lqw.orderByDesc(StorePink::getId);
List<StorePink> pinkList = dao.selectList(lqw);
// 将拼团状态提换为订单状态
pinkList.forEach(i -> {
StoreOrder storeOrder = storeOrderService.getByOderId(i.getOrderId());
List<StorePinkDetailResponse> responseList = pinkList.stream().map(pink -> {
StorePinkDetailResponse response = new StorePinkDetailResponse();
BeanUtils.copyProperties(pink, response);
StoreOrder storeOrder = storeOrderService.getByOderId(pink.getOrderId());
if (ObjectUtil.isNotNull(storeOrder)) {
i.setStatus(storeOrder.getStatus());
response.setOrderStatus(storeOrder.getStatus());
response.setRefundStatus(storeOrder.getRefundStatus());
}
});
return pinkList;
return response;
}).collect(Collectors.toList());
return responseList;
}
@Override

View File

@@ -78,6 +78,8 @@ public class WebConfig implements WebMvcConfigurer {
excludePathPatterns("/api/admin/wechat/config").
excludePathPatterns("/api/admin/authorize/login").
excludePathPatterns("/api/admin/payment/callback/**").
excludePathPatterns("/api/admin/system/role/menu").
excludePathPatterns("/api/admin/system/role/info").
excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
//后台权限规则
@@ -110,6 +112,7 @@ public class WebConfig implements WebMvcConfigurer {
excludePathPatterns("/api/front/logistics").
excludePathPatterns("/api/front/groom/list/**").
excludePathPatterns("/api/front/index").
excludePathPatterns("/api/front/config").
excludePathPatterns("/api/front/category").
excludePathPatterns("/api/front/seckill/*").
excludePathPatterns("/api/front/seckill/list/*").

View File

@@ -105,7 +105,7 @@ public class ExcelServiceImpl implements ExcelService {
aliasMap.put("startTime", "砍价开启时间");
aliasMap.put("stopTime", "砍价结束时间");
aliasMap.put("sales", "销量");
aliasMap.put("stock", "库存");
aliasMap.put("quotaShow", "库存");
aliasMap.put("giveIntegral", "返多少积分");
aliasMap.put("addTime", "添加时间");
@@ -146,7 +146,7 @@ public class ExcelServiceImpl implements ExcelService {
aliasMap.put("title", "拼团名称");
aliasMap.put("otPrice", "原价");
aliasMap.put("price", "拼团价");
aliasMap.put("stock", "库存");
aliasMap.put("quotaShow", "库存");
aliasMap.put("countPeople", "拼团人数");
aliasMap.put("countPeopleAll", "参与人数");
aliasMap.put("countPeoplePink", "成团数量");

View File

@@ -44,8 +44,8 @@ public class BargainProductExcelVo {
@ApiModelProperty(value = "销量")
private Integer sales;
@ApiModelProperty(value = "库存")
private Integer stock;
@ApiModelProperty(value = "库存剩余")
private Integer quotaShow;
@ApiModelProperty(value = "反多少积分")
private BigDecimal giveIntegral;

View File

@@ -32,8 +32,8 @@ public class CombinationProductExcelVo {
@ApiModelProperty(value = "拼团价")
private BigDecimal price;
@ApiModelProperty(value = "库存")
private Integer stock;
@ApiModelProperty(value = "库存剩余")
private Integer quotaShow;
@ApiModelProperty(value = "拼团人数")
private Integer countPeople;

View File

@@ -107,7 +107,7 @@ public class ExpressController {
public CommonResult<Express> info(@RequestParam(value = "id") Integer id){
Express express = expressService.getById(id);
return CommonResult.success(express);
}
}
/**
* 查询全部物流公司
@@ -130,3 +130,6 @@ public class ExpressController {
return CommonResult.success(expressService.template(com));
}
}

View File

@@ -11,8 +11,8 @@ import com.zbkj.crmeb.express.request.ExpressUpdateShowRequest;
import java.util.List;
/**
* ExpressService 接口
* +----------------------------------------------------------------------
* ExpressService 接口
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
@@ -21,17 +21,17 @@ import java.util.List;
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
*/
public interface ExpressService extends IService<Express> {
/**
* 列表
* @param request 搜索条件
* @param pageParamRequest 分页类参数
* @author Mr.Zhang
* @since 2020-04-17
* @return List<Express>
*/
* 列表
* @param request 搜索条件
* @param pageParamRequest 分页类参数
* @author Mr.Zhang
* @since 2020-04-17
* @return List<Express>
*/
List<Express> getList(ExpressSearchRequest request, PageParamRequest pageParamRequest);
Express info(Integer id);

View File

@@ -45,7 +45,7 @@ import java.util.stream.Collectors;
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
*/
@Service
public class ExpressServiceImpl extends ServiceImpl<ExpressDao, Express> implements ExpressService {
@@ -271,3 +271,4 @@ public class ExpressServiceImpl extends ServiceImpl<ExpressDao, Express> impleme
public static String st = "mnc7Yay0RsvF70LWX7i6k";
public static String sk = "¥bugJEjOmF01hxGr~qj5";
}

View File

@@ -26,8 +26,8 @@ import java.util.concurrent.TimeUnit;
/**
* ExpressServiceImpl 接口实现
* +----------------------------------------------------------------------
* ExpressServiceImpl 接口实现
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
@@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
*/
@Data
@Service
public class LogisticsServiceImpl implements LogisticService {
@@ -142,7 +142,7 @@ public class LogisticsServiceImpl implements LogisticService {
private JSONObject getCache() {
Object data = redisUtil.get(getRedisKey() + getExpressNo());
if(null != data){
return JSONObject.parseObject(data.toString());
return JSONObject.parseObject(data.toString());
}
return null;
}
@@ -167,3 +167,4 @@ public class LogisticsServiceImpl implements LogisticService {
}
}
}

View File

@@ -36,7 +36,7 @@ public class LogisticsResultVo {
@ApiModelProperty(value = "快递运送轨迹")
private List<LogisticsResultListVo> list;
@ApiModelProperty(value = "快递收件(揽件)1.在途中 2.正在派件 3.已签收 4.派送失败 5.疑难件 6.退件签收 10待清关11清关中12已清关13清关异常14收件人拒签 */")
@ApiModelProperty(value = "快递收件(揽件)1.在途中 2.正在派件 3.已签收 4.派送失败 5.疑难件 6.退件签收 */")
@JsonProperty("deliverystatus")
private String deliveryStatus;

View File

@@ -118,10 +118,6 @@ public class UserExtractServiceImpl extends ServiceImpl<UserExtractDao, UserExtr
//时间范围
if(StringUtils.isNotBlank(request.getDateLimit())){
dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit());
if (dateLimit.getStartTime().length() == 10) {
dateLimit.setStartTime(dateLimit.getStartTime().concat(" 00:00:00"));
dateLimit.setEndTime(dateLimit.getEndTime().concat(" 23:59:59"));
}
lambdaQueryWrapper.between(UserExtract::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
}

View File

@@ -46,3 +46,4 @@ public class ExpressController {
}

View File

@@ -85,6 +85,16 @@ public class IndexController {
public CommonResult<HashMap<String, String>> share(){
return CommonResult.success(indexService.getShareConfig());
}
/**
* 公共配置 云智服
* @return 公共配置
*/
@ApiOperation(value = "公共配置")
@RequestMapping(value = "/config", method = RequestMethod.GET)
public CommonResult<HashMap<String,String>> getConfig(){
return CommonResult.success(indexService.getCommConfig());
}
}

View File

@@ -0,0 +1,64 @@
package com.zbkj.crmeb.front.controller;
import com.common.CommonResult;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.front.request.OrderPayRequest;
import com.zbkj.crmeb.front.response.OrderPayResultResponse;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.payment.wechat.WeChatPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* 微信缓存表 前端控制器
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/front/pay")
@Api(tags = "支付管理")
public class PayController {
@Autowired
private WeChatPayService weChatPayService;
@Autowired
private OrderPayService orderPayService;
/**
* 订单支付
* @return
*/
@ApiOperation(value = "订单支付")
@RequestMapping(value = "/payment", method = RequestMethod.POST)
public CommonResult<OrderPayResultResponse> payment(@RequestBody @Validated OrderPayRequest orderPayRequest, HttpServletRequest request) {
String ip = CrmebUtil.getClientIp(request);
return CommonResult.success(orderPayService.payment(orderPayRequest, ip));
}
/**
* 查询支付结果
*
* @param orderNo |订单编号|String|必填
* @return
*/
@ApiOperation(value = "查询支付结果")
@RequestMapping(value = "/queryPayResult", method = RequestMethod.GET)
public CommonResult<Boolean> queryPayResult(@RequestParam String orderNo) {
return CommonResult.success(weChatPayService.queryPayResult(orderNo));
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
/**
* H5端订单操作
@@ -43,19 +44,13 @@ public class StoreOrderController {
/**
* 根据购物车id确认订单
* @param cartIds 购物车id集合
* @param request 购物车id集合
* @return 订单确认结果
*/
@ApiOperation(value = "确认订单")
@RequestMapping(value = "/confirm", method = RequestMethod.POST)
public CommonResult<ConfirmOrderResponse> OrderConForm(@RequestParam String cartIds,
@RequestParam(value = "isNew", defaultValue = "false") boolean isNew,
@RequestParam(value = "addAgain", defaultValue = "false") boolean addAgain,
@RequestParam(value = "secKill", defaultValue = "false") boolean secKill,
@RequestParam(value = "bargain", defaultValue = "false") boolean bargain,
@RequestParam(value = "combination", defaultValue = "false") boolean combination,
@RequestParam(value = "addressId", defaultValue = "0") Integer addressId){
return CommonResult.success(orderService.confirmOrder(CrmebUtil.stringToArrayStr(cartIds),isNew,addAgain,secKill,bargain, combination, addressId));
public CommonResult<ConfirmOrderResponse> OrderConForm(@RequestBody @Validated ConfirmOrderRequest request){
return CommonResult.success(orderService.confirmOrder(request));
}
/**
@@ -66,9 +61,8 @@ public class StoreOrderController {
*/
@ApiOperation(value = "生成订单")
@RequestMapping(value = "/create/{key}", method = RequestMethod.POST)
public CommonResult<Object> createOrder(@PathVariable String key,@Validated @RequestBody OrderCreateRequest orderRequest,HttpServletRequest request){
String ip = CrmebUtil.getClientIp(request);
return CommonResult.success(orderService.createOrder(orderRequest,key, ip));
public CommonResult<Map<String, Object>> createOrder(@PathVariable String key, @Validated @RequestBody OrderCreateRequest orderRequest, HttpServletRequest request){
return CommonResult.success(orderService.createOrder_1_3_1(orderRequest, key));
}
/**
@@ -205,16 +199,6 @@ public class StoreOrderController {
}
}
/**
* 订单退款前验证
* @return 验证结果
*/
@ApiOperation(value = "退款订单验证")
@RequestMapping(value = "/refund/verify", method = RequestMethod.POST)
public CommonResult<Object> refundVerify(@RequestBody @Validated OrderRefundVerifyRequest request){
return CommonResult.success(orderService.refundVerify(request));
}
/**
* 订单退款申请
* @param request OrderRefundApplyRequest 订单id

View File

@@ -322,7 +322,7 @@ public class UserController {
*/
@ApiOperation(value = "推广人排行")
@RequestMapping(value = "rank", method = RequestMethod.GET)
public CommonResult<List<User>> getTopSpreadPeopleListByDate(@RequestParam String type, @Validated PageParamRequest pageParamRequest){
public CommonResult<List<User>> getTopSpreadPeopleListByDate(@RequestParam(required = false) String type, @Validated PageParamRequest pageParamRequest){
return CommonResult.success(userCenterService.getTopSpreadPeopleListByDate(type, pageParamRequest));
}

View File

@@ -0,0 +1,52 @@
package com.zbkj.crmeb.front.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 确认订单请求对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
public class ConfirmOrderRequest {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "购物车id集合")
@NotNull(message = "购物车编号集合 不能为空")
private String cartIds;
@ApiModelProperty(value = "是否立即购买")
@NotNull(message = "是否立即购买 不能为空")
private Boolean isNew;
@ApiModelProperty(value = "是否再一下单")
@NotNull(message = "是否再一下单 不能为空")
private Boolean addAgain;
@ApiModelProperty(value = "是否秒杀商品")
@NotNull(message = "是否秒杀商品 不能为空")
private Boolean secKill;
@ApiModelProperty(value = "是否砍价商品")
@NotNull(message = "是否砍价商品 不能为空")
private Boolean bargain;
@ApiModelProperty(value = "是否拼团商品")
@NotNull(message = "是否拼团商品 不能为空")
private Boolean combination;
@ApiModelProperty(value = "地址id")
// @NotNull(message = "地址编号 不能为空")
private Integer addressId;
}

View File

@@ -20,7 +20,7 @@ import javax.validation.constraints.NotNull;
@Data
public class OrderAgainRequest {
@ApiModelProperty(value = "订单id")
@NotNull(message = "uni参数不能为空")
private String nui;
@ApiModelProperty(value = "订单编号")
@NotNull(message = "订单编号不能为空")
private String orderNo;
}

View File

@@ -28,7 +28,6 @@ import java.net.Inet4Address;
public class OrderCreateRequest {
@ApiModelProperty(value = "真实名称")
// @NotNull(message = "商品id不能为空")
private String realName;
@ApiModelProperty(value = "手机号码")
@@ -37,15 +36,18 @@ public class OrderCreateRequest {
@ApiModelProperty(value = "收货地址id")
private Integer addressId;
@ApiModelProperty(value = "")
private Integer formId;
// @ApiModelProperty(value = "")
// private Integer formId;
@ApiModelProperty(value = "优惠券编号")
private Integer couponId;
@ApiModelProperty(value = "支付类型")
@ApiModelProperty(value = "支付类型:weixin-微信支付yue-余额支付offline-线下支付alipay-支付包支付")
private String payType;
@ApiModelProperty(value = "支付渠道:weixinh5-微信H5支付public-公众号支付routine-小程序支付")
private String payChannel;
@ApiModelProperty(value = "是否使用积分")
private Boolean useIntegral;
@@ -61,14 +63,14 @@ public class OrderCreateRequest {
@ApiModelProperty(value = "秒杀商品id")
private Integer seckillId;
@ApiModelProperty(value = "")
@ApiModelProperty(value = "订单备注")
private String mark;
@ApiModelProperty(value = "")
@ApiModelProperty(value = "自提点id")
private Integer storeId;
@ApiModelProperty(value = "")
private String from;
// @ApiModelProperty(value = "")
// private String from;
@ApiModelProperty(value = "快递类型")
private Integer shippingType;

View File

@@ -27,11 +27,20 @@ import javax.validation.constraints.NotNull;
public class OrderPayRequest {
@ApiModelProperty(value = "订单id")
@NotNull(message = "订单id不能为空")
// @NotNull(message = "订单id不能为空")
private String uni;
@ApiModelProperty(value = "支付类型")
private String paytype;
@ApiModelProperty(value = "订单编号")
@NotNull(message = "订单编号不能为空")
private String orderNo;
@ApiModelProperty(value = "支付类型weixin-微信支付yue-余额支付offline-线下支付alipay-支付包支付")
@NotNull(message = "支付类型不能为空")
private String payType;
@ApiModelProperty(value = "支付渠道:weixinh5-微信H5支付public-公众号支付routine-小程序支付")
@NotNull(message = "支付渠道不能为空")
private String payChannel;
@ApiModelProperty(value = "支付平台")
private String from;

View File

@@ -36,14 +36,17 @@ public class OrderRefundApplyRequest {
private String text;
@ApiModelProperty(value = "订单id", required = true)
@NotBlank(message = "请选择订单")
private Integer id;
@ApiModelProperty(value = "退款凭证(多个图片请用,(英文逗号)隔开)")
@ApiModelProperty(value = "退款凭证图片(多个图片请用,(英文逗号)隔开)")
@JsonProperty("refund_reason_wap_img")
private String reasonImage;
@ApiModelProperty(value = "备注说明")
@JsonProperty("refund_reason_wap_explain")
private String explain;
@ApiModelProperty(value = "待退款订单")
@NotNull(message = "待退款订单 不能为空")
private String uni;
}

View File

@@ -4,7 +4,11 @@ import com.zbkj.crmeb.marketing.response.StoreCouponUserResponse;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserAddress;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.HashMap;
import java.util.List;
@@ -22,51 +26,65 @@ import java.util.List;
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ConfirmOrderResponse对象", description="订单确认相应对象")
public class ConfirmOrderResponse {
// 收否扣减
@ApiModelProperty(value = "收否扣减")
private Boolean deduction;
// 可用优惠券
@ApiModelProperty(value = "可用优惠券")
private StoreCouponUserResponse usableCoupon;
// 用户地址
@ApiModelProperty(value = "用户地址")
private UserAddress addressInfo;
// 购物车信息
@ApiModelProperty(value = "购物车信息")
private List<StoreCartResponse> cartInfo;
// 价格集合
// private HashMap<String, Object> priceGroup;
@ApiModelProperty(value = "价格集合")
private PriceGroupResponse priceGroup;
@ApiModelProperty(value = "其他")
private HashMap<String, Object> other;
@ApiModelProperty(value = "订单key")
private String orderKey;
@ApiModelProperty(value = "线下邮费")
private String offlinePostage;
@ApiModelProperty(value = "用户信息")
private User userInfo;
@ApiModelProperty(value = "积分抵扣比例")
private String integralRatio;
@ApiModelProperty(value = "线下支付状态")
private String offlinePayStatus;
// 余额支付 1 开启 2 关闭
@ApiModelProperty(value = "余额支付 1 开启 2 关闭")
private String yuePayStatus;
// 门店自提是否开启
@ApiModelProperty(value = "门店自提是否开启")
private String storeSelfMention;
// 门店信息
@ApiModelProperty(value = "门店信息")
private String systemStore;
// 微信支付 1 开启 0 关闭
@ApiModelProperty(value = "微信支付 1 开启 0 关闭")
private String payWeixinOpen;
// 秒杀id
@ApiModelProperty(value = "秒杀id")
private Integer secKillId;
// 砍价id
@ApiModelProperty(value = "砍价id")
private Integer bargainId;
// 拼团id
@ApiModelProperty(value = "拼团id")
private Integer combinationId;
@ApiModelProperty(value = "团长id")
private Integer pinkId;
}

View File

@@ -0,0 +1,41 @@
package com.zbkj.crmeb.front.response;
import com.zbkj.crmeb.front.vo.WxPayJsResultVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 订单支付结果 Response
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="OrderPayResultResponse对象", description="订单支付结果响应对象")
public class OrderPayResultResponse {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "支付状态")
private Boolean status;
@ApiModelProperty(value = "微信调起支付参数对象")
private WxPayJsResultVo jsConfig;
@ApiModelProperty(value = "支付类型")
private String payType;
@ApiModelProperty(value = "订单编号")
private String orderNo;
}

View File

@@ -1,6 +1,10 @@
package com.zbkj.crmeb.front.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
@@ -17,15 +21,38 @@ import java.math.BigDecimal;
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="PriceGroupResponse对象", description="价格计算集合对象")
public class PriceGroupResponse {
@ApiModelProperty(value = "运费")
private BigDecimal storePostage;
@ApiModelProperty(value = "满额包邮")
private BigDecimal storeFreePostage;
@ApiModelProperty(value = "总金额")
private BigDecimal totalPrice;
@ApiModelProperty(value = "原价")
private BigDecimal costPrice;
@ApiModelProperty(value = "会员金额")
private BigDecimal vipPrice;
@ApiModelProperty(value = "优惠券金额")
private BigDecimal couponPrice;
@ApiModelProperty(value = "支付金额")
private BigDecimal payPrice;
@ApiModelProperty(value = "邮费金额")
private BigDecimal payPostage;
@ApiModelProperty(value = "抵扣金额")
private BigDecimal deductionPrice;
@ApiModelProperty(value = "使用积分")
private Integer usedIntegral;
}

View File

@@ -127,13 +127,13 @@ public class StoreOrderDetailResponse {
private String deliveryId;
@ApiModelProperty(value = "消费赚取积分")
private BigDecimal gainIntegral;
private Integer gainIntegral;
@ApiModelProperty(value = "使用积分")
private Integer useIntegral;
@ApiModelProperty(value = "给用户退了多少积分")
private BigDecimal backIntegral;
private Integer backIntegral;
@ApiModelProperty(value = "备注")
private String mark;

View File

@@ -42,7 +42,7 @@ public class UserSignInfoResponse implements Serializable {
private BigDecimal nowMoney;
@ApiModelProperty(value = "用户剩余积分")
private BigDecimal integral;
private Integer integral;
@ApiModelProperty(value = "连续签到天数")
private Integer signNum;

View File

@@ -27,4 +27,10 @@ public interface IndexService{
List<HashMap<String, Object>> hotKeywords();
HashMap<String, String> getShareConfig();
/**
* 获取公共配置
* @return 公共配置
*/
HashMap<String,String> getCommConfig();
}

View File

@@ -1,5 +1,6 @@
package com.zbkj.crmeb.front.service;
import com.common.MyRecord;
import com.common.PageParamRequest;
import com.zbkj.crmeb.front.request.*;
import com.zbkj.crmeb.front.response.ConfirmOrderResponse;
@@ -32,16 +33,9 @@ import java.util.List;
public interface OrderService {
/**
* 订单确认
* @param cartIds 购物车id集合
* @param isNew 立即购买
* @param addAgain 重复下单
* @param seckill 秒杀
* @param bargain 砍价
* @param combination 拼团
* @param addressId 用户地址Id
* @return 确认订单信息
*/
ConfirmOrderResponse confirmOrder(List<String> cartIds, boolean isNew, boolean addAgain,boolean seckill, boolean bargain, boolean combination, Integer addressId);
ConfirmOrderResponse confirmOrder(ConfirmOrderRequest request);
/**
@@ -52,6 +46,13 @@ public interface OrderService {
*/
OrderPayResponse createOrder(OrderCreateRequest request, String key, String ip);
/**
* 创建订单
* @param request 创建订单参数
* @param key 订单key
* @return MyRecord
*/
MyRecord createOrder_1_3_1(OrderCreateRequest request, String key);
/**
* 再次下单
@@ -116,13 +117,7 @@ public interface OrderService {
* @param request
* @return
*/
boolean refundApplyTask(List<OrderRefundApplyRequest> applyList);
/**
* 订单退款前验证
* @param request 退款参数
*/
boolean refundVerify(OrderRefundVerifyRequest request);
Boolean refundApplyTask(List<OrderRefundApplyRequest> applyList);
/**
* 订单物流查看

View File

@@ -213,5 +213,17 @@ public class IndexServiceImpl implements IndexService {
map.put("synopsis", info.get("wechat_share_synopsis"));
return map;
}
/**
* 获取公共配置
*
* @return 公共配置
*/
@Override
public HashMap<String, String> getCommConfig() {
HashMap<String,String> result = new HashMap<>();
result.put("yzfUrl", systemConfigService.getValueByKey(Constants.CONFIG_KEY_YZF_H5_URL));
return result;
}
}

View File

@@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.common.MyRecord;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.constants.PayConstants;
import com.exception.CrmebException;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
@@ -49,12 +51,12 @@ import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.wechat.service.impl.WechatSendMessageForMinService;
import com.zbkj.crmeb.wechat.vo.WechatSendMessageForCreateOrder;
import com.zbkj.crmeb.wechat.vo.WechatSendMessageForReFundNotify;
import org.apache.catalina.Store;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import java.math.BigDecimal;
import java.util.*;
@@ -115,9 +117,6 @@ public class OrderServiceImpl implements OrderService {
@Autowired
private OrderUtils orderUtils;
@Autowired
private SmsService smsService;
@Autowired
private SystemAttachmentService systemAttachmentService;
@@ -136,45 +135,48 @@ public class OrderServiceImpl implements OrderService {
@Autowired
private StoreBargainService storeBargainService;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 确认订单
* @param cartIds 购物车id集合
* @param isNew 是否再次下单=从缓存中获取数据
* @return 确认订单response
* isNew 是否再次下单=从缓存中获取数据
*/
@Override
public ConfirmOrderResponse confirmOrder(List<String> cartIds, boolean isNew, boolean addAgain,boolean seckill, boolean bargain, boolean combination, Integer addressId) {
ConfirmOrderResponse response = new ConfirmOrderResponse();
public ConfirmOrderResponse confirmOrder(ConfirmOrderRequest request) {
List<String> cartIds = CrmebUtil.stringToArrayStr(request.getCartIds());
User currentUserInfo = userService.getInfoException();
// 获取运费默认模版
// ShippingTemplates template = shippingTemplatesService.getById(69);
// if (null == template)
ShippingTemplates template = shippingTemplatesService.getById(1);
if (null == template) throw new CrmebException("默认模板未配置,无法下单");
User currentUserInfo = userService.getInfoException();
List<StoreCartResponse> storeCartResponse;
// 再次下单、秒杀、砍价、拼团
if (addAgain || seckill || bargain || combination) { // 从redis缓存中获取重新下单和秒杀订单数据、砍价订单数据、拼团订单数据
if (request.getAddAgain() || request.getSecKill() || request.getBargain() || request.getCombination()) { // 从redis缓存中获取重新下单和秒杀订单数据、砍价订单数据、拼团订单数据
String cacheOrderData = orderUtils.getCacheOrderData(cartIds.get(0) + "");
if (StrUtil.isBlank(cacheOrderData)) throw new CrmebException("未找到订单数据");
storeCartResponse = JSONObject.parseArray(cacheOrderData, StoreCartResponse.class);
if (seckill) {
if (request.getSecKill()) {
// 秒杀商品数据验证
StoreCart storeCartPram = new StoreCart()
.setSeckillId(storeCartResponse.get(0).getSeckillId())
.setUid(currentUserInfo.getUid())
.setProductAttrUnique(storeCartResponse.get(0).getProductAttrUnique());
storeCartPram.setCartNum(1);
orderUtils.validSecKill(storeCartPram, currentUserInfo);
}
if (bargain) {
if (request.getBargain()) {
// 砍价商品数据验证
StoreCart storeCartPram = new StoreCart()
.setBargainId(storeCartResponse.get(0).getBargainId())
.setUid(currentUserInfo.getUid())
.setProductAttrUnique(storeCartResponse.get(0).getProductAttrUnique());
storeCartPram.setCartNum(1);
orderUtils.validBargain(storeCartPram, currentUserInfo);
}
if (combination) {
if (request.getCombination()) {
// 拼团商品数据验证
StoreCart storeCartPram = new StoreCart()
.setCombinationId(storeCartResponse.get(0).getCombinationId())
@@ -186,16 +188,16 @@ public class OrderServiceImpl implements OrderService {
}
orderUtils.validCombination(storeCartPram, currentUserInfo);
}
}else if(isNew){// 获取立即购买数据
storeCartResponse = storeCartService.getListByUserIdAndCartIds(currentUserInfo.getUid(),cartIds,1);
}else{ // 获取购物车数据
storeCartResponse = storeCartService.getListByUserIdAndCartIds(currentUserInfo.getUid(),cartIds,null);
}else{
// 获取购物车数据
// 获取立即购买数据 根据isNew判断
storeCartResponse = storeCartService.getListByUserIdAndCartIds(currentUserInfo.getUid(),cartIds,request.getIsNew());
}
// 这里需要根据参数判定,不能一直使用默认收货地址
UserAddress defaultAddress;
if (addressId > 0) {// 获取选择的地址
defaultAddress = userAddressService.getById(addressId);
if (ObjectUtil.isNotNull(request.getAddressId()) && request.getAddressId() > 0) {// 获取选择的地址
defaultAddress = userAddressService.getById(request.getAddressId());
} else {// 获取默认地址
defaultAddress = userAddressService.getDefault();
}
@@ -216,6 +218,9 @@ public class OrderServiceImpl implements OrderService {
if(null != canUseUseCouponList && canUseUseCouponList.size() > 0){
canUserCoupon = canUseUseCouponList.get(0);
}
// 确认订单响应对象
ConfirmOrderResponse response = new ConfirmOrderResponse();
response.setUsableCoupon(canUserCoupon);
response.setAddressInfo(defaultAddress);
response.setCartInfo(storeCartResponse);
@@ -264,7 +269,7 @@ public class OrderServiceImpl implements OrderService {
ConfirmOrderResponse cor = JSONObject.parseObject(existCacheOrder,ConfirmOrderResponse.class);
// 缓存订单并做计算
orderUtils.computedOrder(request, cor, orderKey);
orderUtils.computedOrder(request, cor, orderKey, currentUser);
// 检查订单状态
StoreOrder orderCreated = orderUtils.createOrder(request, cor, 0, request.getStoreId(), orderKey);
@@ -275,8 +280,8 @@ public class OrderServiceImpl implements OrderService {
if(request.getIsNew()){
HashMap<String, Object> resultMap = new HashMap<>();
OrderPayRequest orderPayRequest = new OrderPayRequest();
orderPayRequest.setFrom(request.getFrom());
orderPayRequest.setPaytype(request.getPayType());
// orderPayRequest.setFrom(request.getFrom());
orderPayRequest.setPayType(request.getPayType());
orderPayRequest.setUni(orderCreated.getOrderId());
boolean b = doPayOrder(orderPayRequest, ip, resultMap, orderCreated);
OrderPayItemResponse itemResponse = new OrderPayItemResponse();
@@ -297,8 +302,7 @@ public class OrderServiceImpl implements OrderService {
orderPayResponse.setStatus("SUCCESS");
break;
}
orderPayResponse.setMessage(payType);
itemResponse.setKey(orderCreated.getOrderId());
itemResponse.setKey(orderCreated.getOrderId());
itemResponse.setOrderId(orderKey);
orderPayResponse.setResult(itemResponse);
}else{
@@ -333,6 +337,59 @@ public class OrderServiceImpl implements OrderService {
return orderPayResponse;
}
/**
* 订单创建
* 订单创建只生成订单返回订单编号
* 前端在之后需调用查询支付结果接口
* @param request 创建订单参数
* @param orderKey orderKey
* @return 创建订单结果
*/
@Override
public MyRecord createOrder_1_3_1(OrderCreateRequest request, String orderKey) {
User currentUser = userService.getInfo();
if (ObjectUtil.isNull(currentUser)) throw new CrmebException("当前用户不存在!");
// 检查订单是否存在
if(orderUtils.checkOrderExist(orderKey, currentUser.getUid())) throw new CrmebException(orderKey + "订单已存在");
// 检测支付方式
if(!orderUtils.checkPayType(request.getPayType())) throw new CrmebException("暂不支持该支付方式,请刷新页面或者联系管理员");
if (request.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
// 检测支付渠道
if (StrUtil.isBlank(request.getPayChannel())) throw new CrmebException("支付渠道不能为空!");
if (!OrderUtils.checkPayChannel(request.getPayChannel())) throw new CrmebException("支付渠道不存在!");
}
// 判断订单是否过期
String existCacheOrder = orderUtils.cacheGetOrderInfo(currentUser.getUid(), orderKey);
if(StrUtil.isBlank(existCacheOrder)) throw new CrmebException("订单已过期,请刷新当前页面!");
ConfirmOrderResponse cor = JSONObject.parseObject(existCacheOrder, ConfirmOrderResponse.class);
// 缓存订单并做计算
orderUtils.computedOrder(request, cor, orderKey, currentUser);
// 生成订单
StoreOrder orderCreated = orderUtils.createOrder_v131(request, cor, orderKey, currentUser);
if(ObjectUtil.isNull(orderCreated)) {
throw new CrmebException("订单生成失败");
}
// 清除购物车数据
List<StoreCartResponse> cartInfo = cor.getCartInfo();
List<StoreCartResponse> cartList = cartInfo.stream().filter(i -> ObjectUtil.isNotNull(i.getId())).collect(Collectors.toList());
if (CollUtil.isNotEmpty(cartList)) {
List<Integer> cartIdList = cartList.stream().map(temp -> temp.getId().intValue()).collect(Collectors.toList());
storeCartService.deleteCartByIds(cartIdList);
}
MyRecord record = new MyRecord();
record.set("orderNo", orderCreated.getOrderId());
return record;
}
/**
* 删除已完成订单
* @param id Integer 订单id
@@ -436,77 +493,72 @@ public class OrderServiceImpl implements OrderService {
}
/**
* 订单退款前验证
* @param request 退款参数
* 订单退款申请
* @param request OrderRefundApplyRequest 退款参数
*/
@Override
public boolean refundVerify(OrderRefundVerifyRequest request) {
User currentUser = userService.getInfo();
public boolean refundApply(OrderRefundApplyRequest request) {
User currentUser = userService.getInfoException();
StoreOrder storeOrderPram = new StoreOrder();
storeOrderPram.setOrderId(request.getUni());
storeOrderPram.setIsDel(false);
storeOrderPram.setPaid(true);
StoreOrder existStoreOrder = storeOrderService.getByEntityOne(storeOrderPram);
if(null == existStoreOrder) throw new CrmebException("支付订单不存在");
if(existStoreOrder.getRefundStatus() == 2) throw new CrmebException("订单已退款");
if(existStoreOrder.getRefundStatus() == 1) throw new CrmebException("正在申请退款中");
if(existStoreOrder.getStatus() == 1) throw new CrmebException("当前订单无法退款");
storeOrderStatusService.createLog(existStoreOrder.getId(), Constants.ORDER_LOG_REFUND_APPLY,"用户申请退款原因:" + request.getRefund_reason_wap_explain());
existStoreOrder.setRefundStatus(1);
existStoreOrder.setStatus(-1);
existStoreOrder.setRefundReasonTime(DateUtil.nowDateTime());
existStoreOrder.setRefundReasonWap(request.getText());
existStoreOrder.setRefundReasonWapExplain(request.getRefund_reason_wap_explain());
existStoreOrder.setRefundReasonWapImg(systemAttachmentService.clearPrefix(request.getRefund_reason_wap_img()));
boolean updateOrderResult = storeOrderService.updateById(existStoreOrder);
if(!updateOrderResult) throw new CrmebException("申请退款失败");
HashMap<String, Object> smsInfo = new HashMap<>();
smsInfo.put("orderId", existStoreOrder.getOrderId());
smsInfo.put("adminName", currentUser.getNickname());
boolean codeResult = smsService.pushCodeToList(currentUser.getPhone(),1, smsInfo);
if(!codeResult) throw new CrmebException("短信加入发送队列失败");
return true;
}
/**
* 订单退款申请
* @param request OrderRefundApplyRequest 退款参数
*/
@Override
public boolean refundApply(OrderRefundApplyRequest request) {
StoreOrder storeOrder = orderUtils.getInfoById(request.getId());
if(storeOrder.getRefundStatus() == 1){
if(existStoreOrder.getRefundStatus() == 1){
throw new CrmebException("正在申请退款中");
}
if(storeOrder.getRefundStatus() == 2){
if(existStoreOrder.getRefundStatus() == 2){
throw new CrmebException("订单已退款");
}
if(storeOrder.getStatus() == 1){
throw new CrmebException("订单当前无法退款");
if(existStoreOrder.getRefundStatus() == 3){
throw new CrmebException("订单退款");
}
storeOrder.setRefundReasonWapImg(systemAttachmentService.clearPrefix(request.getReasonImage()));
storeOrder.setRefundStatus(1);
storeOrder.setRefundReasonWapExplain(request.getExplain());
storeOrder.setRefundReason(request.getText());
storeOrder.setRefundPrice(storeOrder.getPayPrice());
storeOrder.setRefundReasonTime(DateUtil.nowDateTime());
// 发送微信小程序订阅消息
String storeNameAndCarNumString = orderUtils.getStoreNameAndCarNumString(storeOrder.getId());
if(StringUtils.isNotBlank(storeNameAndCarNumString)){
WechatSendMessageForReFundNotify notify = new WechatSendMessageForReFundNotify(
storeNameAndCarNumString,storeOrder.getPayPrice().toString(),
storeOrder.getCreateTime().toString(),storeOrder.getOrderId()+"",DateUtil.nowDateTimeStr(),
"CRMEB","发起申请",request.getExplain(),storeOrder.getPayPrice()+"",
request.getText(),storeOrder.getUserPhone(),"CRMEB");
wechatSendMessageForMinService.sendReFundNotifyMessage(notify, userService.getUserId());
}
return storeOrderService.updateById(storeOrder);
// if(existStoreOrder.getStatus() == 1){
// throw new CrmebException("订单当前状态无法申请退款");
// }
// if (StrUtil.isBlank(existStoreOrder.getRefundReason())) {
// throw new CrmebException("订单退款已被拒绝");
// }
existStoreOrder.setRefundStatus(1);
existStoreOrder.setRefundReasonTime(DateUtil.nowDateTime());
existStoreOrder.setRefundReasonWap(request.getText());
existStoreOrder.setRefundReasonWapExplain(request.getExplain());
existStoreOrder.setRefundReasonWapImg(systemAttachmentService.clearPrefix(request.getReasonImage()));
existStoreOrder.setRefundPrice(BigDecimal.ZERO);
Boolean execute = transactionTemplate.execute(e -> {
storeOrderService.updateById(existStoreOrder);
storeOrderStatusService.createLog(existStoreOrder.getId(), Constants.ORDER_LOG_REFUND_APPLY, "用户申请退款原因:" + request.getExplain());
return Boolean.TRUE;
});
if(!execute) throw new CrmebException("申请退款失败");
// HashMap<String, Object> smsInfo = new HashMap<>();
// smsInfo.put("orderId", existStoreOrder.getOrderId());
// smsInfo.put("adminName", currentUser.getNickname());
// if (execute) {
// // 发送微信小程序订阅消息
// String storeNameAndCarNumString = orderUtils.getStoreNameAndCarNumString(storeOrder.getId());
// if(StringUtils.isNotBlank(storeNameAndCarNumString)){
// WechatSendMessageForReFundNotify notify = new WechatSendMessageForReFundNotify(
// storeNameAndCarNumString,storeOrder.getPayPrice().toString(),
// storeOrder.getCreateTime().toString(),storeOrder.getOrderId()+"",DateUtil.nowDateTimeStr(),
// "CRMEB","发起申请",request.getExplain(),storeOrder.getPayPrice()+"",
// request.getText(),storeOrder.getUserPhone(),"CRMEB");
// wechatSendMessageForMinService.sendReFundNotifyMessage(notify, userService.getUserId());
// }
// boolean codeResult = smsService.pushCodeToList(currentUser.getPhone(),1, smsInfo);
// if(!codeResult) throw new CrmebException("短信加入发送队列失败");
// }
return execute;
}
/**
@@ -515,7 +567,7 @@ public class OrderServiceImpl implements OrderService {
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean refundApplyTask(List<OrderRefundApplyRequest> applyList) {
public Boolean refundApplyTask(List<OrderRefundApplyRequest> applyList) {
if (CollUtil.isEmpty(applyList)) {
return false;
}
@@ -535,9 +587,13 @@ public class OrderServiceImpl implements OrderService {
throw new CrmebException("订单已退款");
}
if(storeOrder.getStatus() == 1){
throw new CrmebException("订单当前无法退款");
if(storeOrder.getRefundStatus() == 3){
throw new CrmebException("订单退款");
}
// if(storeOrder.getStatus() == 1){
// throw new CrmebException("订单状态当前无法退款");
// }
storeOrder.setRefundReasonWapImg(systemAttachmentService.clearPrefix(request.getReasonImage()));
storeOrder.setRefundStatus(1);
storeOrder.setRefundReasonWapExplain(request.getExplain());
@@ -582,17 +638,27 @@ public class OrderServiceImpl implements OrderService {
*/
@Override
public HashMap<String, Object> againOrder(OrderAgainRequest request) {
// 检查是否已经有相同的商品再次下单
// StoreCartResponse cacheOrderAgain = orderUtils.getCacheOrderAgain(request.getNui());
// if(null != cacheOrderAgain) throw new CrmebException("已经有相同的订单存在");
User currentUser = userService.getInfoException();
HashMap<String, Object> resultMap = new HashMap<>();
User currentUser = userService.getInfo();
// 查询订单是否存在
StoreOrder storeOrder = new StoreOrder();
storeOrder.setUid(currentUser.getUid());
storeOrder.setUnique(request.getNui());
storeOrder.setOrderId(request.getOrderNo());
StoreOrder storeOrderExist = storeOrderService.getInfoByEntity(storeOrder);
if(null == storeOrderExist) throw new CrmebException("订单不存在");
// 申请退款订单不能再次下单
if (!storeOrderExist.getRefundStatus().equals(0)) {
throw new CrmebException("申请退款订单不支持再次下单");
}
// 订单收货后才能再次下单
if (storeOrderExist.getStatus() < 2) {
throw new CrmebException("订单收货后才能再次下单");
}
// 活动商品不支持再次下单
if (storeOrderExist.getCombinationId() > 0 || storeOrderExist.getSeckillId() > 0 || storeOrderExist.getBargainId() > 0) {
throw new CrmebException("活动商品不支持再次下单");
}
OrderAgainVo orderAgainVo = orderUtils.tidyOrder(storeOrderExist, true, false);
// List<StoreCart> storeCartResultList = new ArrayList<>();
for (StoreOrderInfoVo oldCartInfo : orderAgainVo.getCartInfo()) { // todo 确实是否仅仅一条数据
@@ -626,8 +692,8 @@ public class OrderServiceImpl implements OrderService {
if(null == existStoreOrder) throw new CrmebException("订单不存在");
if(existStoreOrder.getPaid()) throw new CrmebException("该订单已支付");
// 判断支付类型是否更改
if(!existStoreOrder.getPayType().equals(request.getPaytype())){
boolean changePayTypeResult = changePayType(request.getPaytype(), existStoreOrder.getOrderId());
if(!existStoreOrder.getPayType().equals(request.getPayType())){
boolean changePayTypeResult = changePayType(request.getPayType(), existStoreOrder.getOrderId());
if(!changePayTypeResult) throw new CrmebException("更新订单支付状态失败");
}
// 支付
@@ -713,8 +779,6 @@ public class OrderServiceImpl implements OrderService {
// todo 二维码前端生成
}
storeOrderDetailResponse.setMapKey(systemConfigService.getValueByKey("tengxun_map_key"));
// StoreOrder storeOrder = new StoreOrder();
// BeanUtils.copyProperties(storeOrderDetailResponse,storeOrder);
OrderAgainVo orderAgainVo = orderUtils.tidyOrder(storeOrderResult, true, true);
BeanUtils.copyProperties(orderAgainVo.getStoreOrder(), storeOrderDetailResponse);
storeOrderDetailResponse.setCartInfo(orderAgainVo.getCartInfo());
@@ -788,7 +852,7 @@ public class OrderServiceImpl implements OrderService {
}
// 立即购买或者秒杀或者砍价
String existCacheOrder = orderUtils.cacheGetOrderInfo(userService.getUserIdException(), orderKey);
String existCacheOrder = orderUtils.cacheGetOrderInfo(currentUser.getUid(), orderKey);
if(null == existCacheOrder) throw new CrmebException("订单已过期,请刷新当前页面!");
ConfirmOrderResponse cor = JSONObject.parseObject(existCacheOrder,ConfirmOrderResponse.class);
@@ -798,6 +862,7 @@ public class OrderServiceImpl implements OrderService {
.setSeckillId(cor.getCartInfo().get(0).getSeckillId())
.setUid(currentUser.getUid())
.setProductAttrUnique(cor.getCartInfo().get(0).getProductAttrUnique());
storeCartPram.setCartNum(1);
orderUtils.validSecKill(storeCartPram, currentUser);
}
@@ -807,6 +872,7 @@ public class OrderServiceImpl implements OrderService {
.setBargainId(cor.getCartInfo().get(0).getBargainId())
.setUid(currentUser.getUid())
.setProductAttrUnique(cor.getCartInfo().get(0).getProductAttrUnique());
storeCartPram.setCartNum(1);
orderUtils.validBargain(storeCartPram, currentUser);
}
@@ -822,7 +888,7 @@ public class OrderServiceImpl implements OrderService {
OrderCreateRequest orderCreateRequest = new OrderCreateRequest();
BeanUtils.copyProperties(request,orderCreateRequest);
ComputeOrderResponse priceGroup = orderUtils.computedOrder(orderCreateRequest, cor, orderKey);
ComputeOrderResponse priceGroup = orderUtils.computedOrder(orderCreateRequest, cor, orderKey, currentUser);
if(null == priceGroup){
throw new CrmebException("计算失败");
}else{
@@ -934,7 +1000,7 @@ public class OrderServiceImpl implements OrderService {
*/
@Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
public boolean doPayOrder(OrderPayRequest request, String ip, HashMap<String, Object> resultMap, StoreOrder existStoreOrder) {
existStoreOrder.setPayType(request.getPaytype());
existStoreOrder.setPayType(request.getPayType());
CreateOrderResponseVo orderPayResult = orderPayService.payOrder(existStoreOrder.getId(), request.getFrom(), ip);
// 下面组装前端所需数据
switch (existStoreOrder.getPayType()){

View File

@@ -140,7 +140,16 @@ public class ProductServiceImpl implements ProductService {
*/
@Override
public List<CategoryTreeVo> getCategory() {
return categoryService.getListTree(Constants.CATEGORY_TYPE_PRODUCT, 1,"");
List<CategoryTreeVo> listTree = categoryService.getListTree(Constants.CATEGORY_TYPE_PRODUCT, 1, "");
for (int i = 0; i < listTree.size();) {
CategoryTreeVo categoryTreeVo = listTree.get(i);
if (!categoryTreeVo.getPid().equals(0)) {
listTree.remove(i);
continue;
}
i++;
}
return listTree;
}
/**

View File

@@ -533,6 +533,8 @@ public class UserCenterServiceImpl extends ServiceImpl<UserDao, User> implements
userService.bindSpread(user, spreadUid);
loginResponse.setUser(user);
user.setLastLoginTime(DateUtil.nowDateTime());
updateById(user);
return loginResponse;
}catch (Exception e){
throw new CrmebException(e.getMessage());
@@ -626,6 +628,8 @@ public class UserCenterServiceImpl extends ServiceImpl<UserDao, User> implements
userService.bindSpread(user, request.getSpreadPid());
loginResponse.setUser(user);
user.setLastLoginTime(DateUtil.nowDateTime());
updateById(user);
return loginResponse;
}catch (Exception e){
throw new CrmebException(e.getMessage());

View File

@@ -0,0 +1,44 @@
package com.zbkj.crmeb.front.vo;
import com.utils.WxPayUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 微信调起支付参数对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@ApiModel(value="WxPayJsResultVo对象", description="微信调起支付参数对象")
public class WxPayJsResultVo {
@ApiModelProperty(value = "微信分配的小程序ID")
private String appId;
@ApiModelProperty(value = "随机字符串不长于32位")
private String nonceStr;
@ApiModelProperty(value = "统一下单接口返回的 prepay_id 参数值")
private String packages;
@ApiModelProperty(value = "签名类型默认为MD5支持HMAC-SHA256和MD5。")
private String signType;
@ApiModelProperty(value = "时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间")
private String timeStamp;
@ApiModelProperty(value = "支付签名")
private String paySign;
@ApiModelProperty(value = "H5支付跳转链接")
private String mwebUrl;
}

View File

@@ -54,7 +54,7 @@ public class StoreProductLogServiceImpl extends ServiceImpl<StoreProductLogDao,
dateLimitUtilVo dateLimit = DateUtil.getDateLimit(time);
//时间范围
if(dateLimit.getStartTime() != null && dateLimit.getEndTime() != null){
lqw.between(StoreProductLog::getAddTime, cn.hutool.core.date.DateUtil.parse(dateLimit.getStartTime()).getTime(), cn.hutool.core.date.DateUtil.parse(dateLimit.getEndTime()).getTime());
lqw.between(StoreProductLog::getAddTime, dateLimit.getStartTime(), dateLimit.getEndTime());
}
return dao.selectCount(lqw);
}

View File

@@ -29,8 +29,7 @@ import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_store_coupon")
@ApiModel(value="StoreCoupon对象", description="优惠券表")
@ApiModel(value="StoreCouponFrontResponse对象", description="web优惠券相应对象")
public class StoreCouponFrontResponse implements Serializable {
private static final long serialVersionUID=1L;
@@ -61,11 +60,9 @@ public class StoreCouponFrontResponse implements Serializable {
private BigDecimal minPrice;
@ApiModelProperty(value = "可领取开始时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date receiveStartTime;
@ApiModelProperty(value = "可领取结束时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date receiveEndTime;
@ApiModelProperty(value = "是否固定使用时间, 默认0 否, 1是")
@@ -80,7 +77,7 @@ public class StoreCouponFrontResponse implements Serializable {
@ApiModelProperty(value = "天数")
private Integer day;
@ApiModelProperty(value = "优惠券类型 0-通用 1 普通券, 2 新人券, 3 购买商品赠送券, 4 付费会员")
@ApiModelProperty(value = "优惠券类型 1 手动领取, 2 新人券, 3 赠送")
private Integer type;
@ApiModelProperty(value = "排序")
@@ -100,4 +97,13 @@ public class StoreCouponFrontResponse implements Serializable {
@ApiModelProperty(value = "是否已领取未使用")
private Boolean isUse = false;
@ApiModelProperty(value = "使用类型 1 全场通用, 2 商品券, 3 品类券")
private Integer useType;
@ApiModelProperty(value = "可使用时间范围 开始时间字符串")
private String useStartTimeStr;
@ApiModelProperty(value = "可使用时间范围 结束时间字符串")
private String useEndTimeStr;
}

View File

@@ -70,12 +70,12 @@ public class StoreCouponUserOrder implements Serializable {
@ApiModelProperty(value = "开始使用时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
@JsonProperty("receiveStartTime")
@JsonProperty("useStartTimeStr")
private Date startTime;
@ApiModelProperty(value = "过期时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
@JsonProperty("receiveEndTime")
@JsonProperty("useEndTimeStr")
private Date endTime;
@ApiModelProperty(value = "使用时间")

View File

@@ -68,11 +68,9 @@ public class StoreCouponUserResponse implements Serializable {
private Date updateTime;
@ApiModelProperty(value = "开始使用时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date startTime;
@ApiModelProperty(value = "过期时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date endTime;
@ApiModelProperty(value = "使用时间")
@@ -92,4 +90,13 @@ public class StoreCouponUserResponse implements Serializable {
@ApiModelProperty(value = "主键id 商品id/分类id", required = true)
private String primaryKey;
@ApiModelProperty(value = "有效状态usable-可用unusable-已用overdue-过期notStart-未开始")
private String validStr;
@ApiModelProperty(value = "开始使用时间字符串")
private String useStartTimeStr;
@ApiModelProperty(value = "过期时间字符串")
private String useEndTimeStr;
}

View File

@@ -38,7 +38,7 @@ public interface StoreCouponUserService extends IService<StoreCouponUser> {
*/
List<StoreCouponUser> getList(StoreCouponUser storeCouponUser);
boolean receive(StoreCouponUserRequest storeCouponUserRequest);
Boolean receive(StoreCouponUserRequest storeCouponUserRequest);
boolean use(Integer id, List<Integer> productIdList, BigDecimal price);
@@ -65,4 +65,9 @@ public interface StoreCouponUserService extends IService<StoreCouponUser> {
List<StoreCouponUserOrder> getListByCartIds(List<Integer> cartIds);
List<StoreCouponUserResponse> getListFront(Integer userId, PageParamRequest pageParamRequest);
/**
* 优惠券过期定时任务
*/
void overdueTask();
}

View File

@@ -298,6 +298,9 @@ public class StoreCouponServiceImpl extends ServiceImpl<StoreCouponDao, StoreCou
response.setReceiveStartTime(null);
}
// 更改使用时间格式,去掉时分秒
response.setUseStartTimeStr(DateUtil.dateToStr(response.getUseStartTime(), Constants.DATE_FORMAT_DATE));
response.setUseEndTimeStr(DateUtil.dateToStr(response.getUseEndTime(), Constants.DATE_FORMAT_DATE));
storeCouponFrontResponseArrayList.add(response);
}
@@ -334,6 +337,7 @@ public class StoreCouponServiceImpl extends ServiceImpl<StoreCouponDao, StoreCou
.and(i -> i.gt(StoreCoupon::getLastTotal, 0).or().eq(StoreCoupon::getIsLimited, false))
//领取时间范围, 结束时间为null则是不限时
.and(i -> i.isNull(StoreCoupon::getReceiveEndTime).or( p -> p.lt(StoreCoupon::getReceiveStartTime, date).gt(StoreCoupon::getReceiveEndTime, date)));
lambdaQueryWrapper.eq(StoreCoupon::getType, 1);
if(productId > 0){
//有商品id 通用券可以领取,商品券可以领取,分类券可以领取
getPrimaryKeySql(lambdaQueryWrapper, productId.toString());

View File

@@ -1,5 +1,7 @@
package com.zbkj.crmeb.marketing.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -28,10 +30,12 @@ import com.zbkj.crmeb.store.service.StoreCartService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.wechat.vo.WechatSendMessageForOrderCancel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -68,6 +72,9 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
@Autowired
private StoreCartService storeCartService;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 列表
* @param request 请求参数
@@ -102,13 +109,14 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
// lambdaQueryWrapper.le(StoreCouponUser::getMinPrice, request.getMinPrice());
// }
// lambdaQueryWrapper.orderByDesc(StoreCouponUser::getId);
ArrayList<StoreCouponUserResponse> storeCouponUserResponseList = new ArrayList<>();
lambdaQueryWrapper.last(StrUtil.format(" order by case `status` when {} then {} when {} then {} when {} then {} end", 0, 1, 1, 2, 2, 3));
List<StoreCouponUser> storeCouponUserList = dao.selectList(lambdaQueryWrapper);
if(storeCouponUserList.size() < 1){
return new PageInfo<>();
}
ArrayList<StoreCouponUserResponse> storeCouponUserResponseList = new ArrayList<>();
List<Integer> uidList = storeCouponUserList.stream().map(StoreCouponUser::getUid).distinct().collect(Collectors.toList());
HashMap<Integer, User> userList = userService.getMapListInUid(uidList);
@@ -145,7 +153,7 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
* @return boolean
*/
@Override
public boolean receive(StoreCouponUserRequest request) {
public Boolean receive(StoreCouponUserRequest request) {
//获取优惠券信息
StoreCoupon storeCoupon = storeCouponService.getInfoException(request.getCouponId());
@@ -172,9 +180,9 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
//是否有固定的使用时间
if(!storeCoupon.getIsFixedTime()){
String endTime = DateUtil.addDay(DateUtil.nowDate(Constants.DATE_FORMAT_START), storeCoupon.getDay() + 1, Constants.DATE_FORMAT_START);
storeCoupon.setUseEndTime(DateUtil.strToDate(endTime, Constants.DATE_FORMAT_START));
storeCoupon.setUseStartTime(DateUtil.nowDateTimeReturnDate(Constants.DATE_FORMAT_DATE));
String endTime = DateUtil.addDay(DateUtil.nowDate(Constants.DATE_FORMAT), storeCoupon.getDay(), Constants.DATE_FORMAT);
storeCoupon.setUseEndTime(DateUtil.strToDate(endTime, Constants.DATE_FORMAT));
storeCoupon.setUseStartTime(DateUtil.nowDateTimeReturnDate(Constants.DATE_FORMAT));
}
ArrayList<StoreCouponUser> storeCouponUserList = new ArrayList<>();
@@ -189,10 +197,22 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
storeCouponUser.setStartTime(storeCoupon.getUseStartTime());
storeCouponUser.setEndTime(storeCoupon.getUseEndTime());
storeCouponUser.setUseType(storeCoupon.getUseType());
storeCouponUser.setType("receive");
if (storeCoupon.getUseType() > 1) {
storeCouponUser.setPrimaryKey(storeCoupon.getPrimaryKey());
}
storeCouponUserList.add(storeCouponUser);
}
return saveBatch(storeCouponUserList);
storeCoupon.setLastTotal(storeCoupon.getLastTotal() - uidList.size());
Boolean execute = transactionTemplate.execute(e -> {
saveBatch(storeCouponUserList);
storeCouponService.updateById(storeCoupon);
return Boolean.TRUE;
});
return execute;
}
/**
@@ -466,13 +486,13 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
List<String> carIdsStr = cartIds.stream().map(e -> e.toString()).collect(Collectors.toList());
//购物车产品集合
List<StoreCartResponse> storeCartResponseList =
storeCartService.getListByUserIdAndCartIds(userService.getUserIdException(), carIdsStr,1);
storeCartService.getListByUserIdAndCartIds(userService.getUserIdException(), carIdsStr,true);
//产品id集合
List<Integer> productIds = storeCartResponseList.stream().map(StoreCartResponse::getProductId).distinct().collect(Collectors.toList());
//计算购物车价格
BigDecimal maxPrice = storeCartResponseList.stream().map(StoreCartResponse::getTruePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal maxPrice = storeCartResponseList.stream().map(cart -> cart.getTruePrice().multiply(new BigDecimal(cart.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
LambdaQueryWrapper<StoreCouponUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Date date = DateUtil.nowDateTime();
@@ -480,6 +500,7 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
.le(StoreCouponUser::getMinPrice, maxPrice)
.lt(StoreCouponUser::getStartTime, date)
.gt(StoreCouponUser::getEndTime, date);
lambdaQueryWrapper.eq(StoreCouponUser::getUid, userService.getUserIdException());
getPrimaryKeySql(lambdaQueryWrapper, StringUtils.join(productIds, ","));
//前端组件统一 转化数据
@@ -514,39 +535,81 @@ public class StoreCouponUserServiceImpl extends ServiceImpl<StoreCouponUserDao,
}
Date date = DateUtil.nowDateTime();
for (StoreCouponUserResponse storeCouponUserResponse : list.getList()) {
boolean type = true;
if(storeCouponUserResponse.getStatus() > 0){
type = false;
String validStr = "usable";// 可用
if (storeCouponUserResponse.getStatus() == 1) {
validStr = "unusable";// 已用
}
if (storeCouponUserResponse.getStatus() == 2) {
validStr = "overdue";// 过期
}
//判断是否在使用时间内
if(null != storeCouponUserResponse.getStartTime() && null != storeCouponUserResponse.getEndTime()){
if(storeCouponUserResponse.getStartTime().compareTo(date) > 0){
type = false;
validStr = "notStart";// 未开始
}
if(date.compareTo(storeCouponUserResponse.getEndTime()) >= 0){
type = false;
validStr = "overdue";// 过期
}
}
storeCouponUserResponse.setIsValid(type);
storeCouponUserResponse.setValidStr(validStr);
// 更改使用时间格式,去掉时分秒
storeCouponUserResponse.setUseStartTimeStr(DateUtil.dateToStr(storeCouponUserResponse.getStartTime(), Constants.DATE_FORMAT_DATE));
storeCouponUserResponse.setUseEndTimeStr(DateUtil.dateToStr(storeCouponUserResponse.getEndTime(), Constants.DATE_FORMAT_DATE));
}
return list.getList();
}
/**
* 优惠券过期定时任务
*/
@Override
public void overdueTask() {
// 查询所有状态——可用的优惠券
LambdaQueryWrapper<StoreCouponUser> lqw = new LambdaQueryWrapper<>();
lqw.eq(StoreCouponUser::getStatus, 0);
List<StoreCouponUser> couponList = dao.selectList(lqw);
if (CollUtil.isEmpty(couponList)) {
return;
}
// 判断优惠券是否过期
List<StoreCouponUser> updateList = CollUtil.newArrayList();
String nowDateStr = DateUtil.nowDate(Constants.DATE_FORMAT);
couponList.forEach(coupon -> {
String endDateStr = DateUtil.dateToStr(coupon.getEndTime(), Constants.DATE_FORMAT);
if (DateUtil.compareDate(nowDateStr, endDateStr, Constants.DATE_FORMAT) >= 0) {
coupon.setStatus(2);
updateList.add(coupon);
}
});
if (CollUtil.isEmpty(updateList)) {
return;
}
boolean update = updateBatchById(updateList);
if (!update) throw new CrmebException("批量更新优惠券过期动作失败");
}
private void getPrimaryKeySql(LambdaQueryWrapper<StoreCouponUser> lambdaQueryWrapper, String productIdStr){
if(StringUtils.isBlank(productIdStr)){
return;
}
List<Integer> categoryIdList = storeProductService.getSecondaryCategoryByProductId(productIdStr);
String categoryIdStr = categoryIdList.stream().map(Object::toString).collect(Collectors.joining(","));
lambdaQueryWrapper.and(i -> i.and(
//通用券 商品券 品类券
// t -> t.eq(StoreCouponUser::getUseType, 1)
// .or(p -> p.eq(StoreCouponUser::getUseType , 2).apply(CrmebUtil.getFindInSetSql("primary_key", productIdStr)))
// .or(c -> c.eq(StoreCouponUser::getUseType , 3).apply(CrmebUtil.getFindInSetSql("primary_key", (ArrayList<Integer>) categoryIdList)))
t -> t.eq(StoreCouponUser::getUseType, 1)
.or(p -> p.eq(StoreCouponUser::getUseType , 2).apply(CrmebUtil.getFindInSetSql("primary_key", productIdStr)))
.or(c -> c.eq(StoreCouponUser::getUseType , 3).apply(CrmebUtil.getFindInSetSql("primary_key", (ArrayList<Integer>) categoryIdList)))
.or(p -> p.eq(StoreCouponUser::getUseType , 2).apply(StrUtil.format(" primary_key in ({})", productIdStr)))
.or(c -> c.eq(StoreCouponUser::getUseType , 3).apply(StrUtil.format(" primary_key in ({})", categoryIdStr)))
));
}
}

View File

@@ -334,11 +334,10 @@ public class OnePassServiceImpl implements OnePassService {
params.add("page", request.getPage());
params.add("limit", request.getLimit());
if (OnePassConstants.ONE_PASS_MEAL_TYPE_SMS.equals(request.getType())) {
int status = 3;// 查询全部状态
if (ObjectUtil.isNotNull(request.getStatus())) {
status = request.getStatus();
// int status = 3;// 查询全部状态
if (ObjectUtil.isNotNull(request.getStatus()) && request.getStatus() != 3) {
params.add("status", request.getStatus());
}
params.add("status", status);
}
String token = onePassUtil.getToken();
HashMap<String, String> header = onePassUtil.getCommonHeader(token);

View File

@@ -58,6 +58,18 @@ public class CallbackController {
//支付宝支付回调
callbackService.aliPay(request);
}
/**
* 微信退款回调
*/
@ApiOperation(value = "微信退款回调")
@RequestMapping(value = "/wechat/refund", method = RequestMethod.POST)
public String weChatRefund(@RequestBody String request) {
System.out.println("微信退款回调 request ===> " + request);
String response = callbackService.weChatRefund(request);
System.out.println("微信退款回调 response ===> " + response);
return response;
}
}

View File

@@ -15,7 +15,7 @@ package com.zbkj.crmeb.payment.service;
public interface CallbackService {
/**
* 微信支付回调
* @param xmlInfo 微信会到json
* @param xmlInfo 微信回调json
* @return String
*/
String weChat(String xmlInfo);
@@ -26,4 +26,11 @@ public interface CallbackService {
* @return
*/
boolean aliPay(String request);
/**
* 微信退款回调
* @param request 微信回调json
* @return String
*/
String weChatRefund(String request);
}

View File

@@ -1,9 +1,9 @@
package com.zbkj.crmeb.payment.service;
import com.zbkj.crmeb.front.request.OrderPayRequest;
import com.zbkj.crmeb.front.response.OrderPayResultResponse;
import com.zbkj.crmeb.payment.vo.wechat.CreateOrderResponseVo;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserToken;
/**
* 订单支付
@@ -27,8 +27,21 @@ public interface OrderPayService{
/**
* 支付成功处理
* @param storeOrder 订单
* @param user 用户
* @param userToken 用户Token
*/
Boolean paySuccess(StoreOrder storeOrder, User user, UserToken userToken);
Boolean paySuccess(StoreOrder storeOrder);
/**
* 余额支付
* @param StoreOrder 订单
* @return
*/
Boolean yuePay(StoreOrder storeOrder);
/**
* 订单支付
* @param orderPayRequest 支付参数
* @param ip ip
* @return
*/
OrderPayResultResponse payment(OrderPayRequest orderPayRequest, String ip);
}

View File

@@ -1,12 +1,14 @@
package com.zbkj.crmeb.payment.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.common.MyRecord;
import com.constants.Constants;
import com.exception.CrmebException;
import com.utils.CrmebUtil;
import com.utils.WxPayUtil;
import com.utils.*;
import com.zbkj.crmeb.finance.model.UserRecharge;
import com.zbkj.crmeb.finance.service.UserRechargeService;
import com.zbkj.crmeb.payment.service.CallbackService;
@@ -16,6 +18,7 @@ import com.zbkj.crmeb.payment.vo.wechat.AttachVo;
import com.zbkj.crmeb.payment.vo.wechat.CallbackVo;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.service.StoreOrderService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserToken;
import com.zbkj.crmeb.user.service.UserService;
@@ -25,8 +28,15 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -65,6 +75,15 @@ public class CallbackServiceImpl implements CallbackService {
@Autowired
private UserRechargeService userRechargeService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 微信支付回调
* @author Mr.Zhang
@@ -74,7 +93,7 @@ public class CallbackServiceImpl implements CallbackService {
public String weChat(String xmlInfo) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
if(StrUtil.isBlank("xmlInfo")){
if(StrUtil.isBlank(xmlInfo)){
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[xmlInfo is blank]]></return_msg>");
sb.append("</xml>");
@@ -127,11 +146,11 @@ public class CallbackServiceImpl implements CallbackService {
}
// 订单
if (Constants.SERVICE_PAY_TYPE_ORDER.equals(attachVo.getType())) {
StoreOrder storeOrder = new StoreOrder();
storeOrder.setOrderId(callbackVo.getOutTradeNo());
storeOrder.setUid(attachVo.getUserId());
StoreOrder orderParam = new StoreOrder();
orderParam.setOrderId(callbackVo.getOutTradeNo());
orderParam.setUid(attachVo.getUserId());
storeOrder = storeOrderService.getInfoByEntity(storeOrder);
StoreOrder storeOrder = storeOrderService.getInfoByEntity(orderParam);
if (ObjectUtil.isNull(storeOrder)) {
logger.error("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
throw new CrmebException("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
@@ -143,12 +162,22 @@ public class CallbackServiceImpl implements CallbackService {
sb.append("</xml>");
return sb.toString();
}
// 支付成功处理
Boolean payAfter = orderPayService.paySuccess(storeOrder, user, userToken);
if (!payAfter) {
logger.error("wechat pay error : 数据保存失败==》" + callbackVo.getOutTradeNo());
throw new CrmebException("wechat pay error : 数据保存失败==》" + callbackVo.getOutTradeNo());
// 添加支付成功redis队列
Boolean execute = transactionTemplate.execute(e -> {
storeOrderService.updatePaid(storeOrder.getOrderId());
if (storeOrder.getUseIntegral() > 0) {
userService.updateIntegral(user, storeOrder.getUseIntegral(), "sub");
}
return Boolean.TRUE;
});
if (!execute) {
logger.error("wechat pay error : 订单更新失败==》" + callbackVo.getOutTradeNo());
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
return sb.toString();
}
redisUtil.lPush(Constants.ORDER_TASK_PAY_SUCCESS_AFTER, storeOrder.getOrderId());
}
// 充值
if (Constants.SERVICE_PAY_TYPE_RECHARGE.equals(attachVo.getType())) {
@@ -194,4 +223,155 @@ public class CallbackServiceImpl implements CallbackService {
//根据类型判断是订单或者充值
return false;
}
/**
* 微信退款回调
* @param xmlInfo 微信回调json
* @return MyRecord
*/
@Override
public String weChatRefund(String xmlInfo) {
MyRecord notifyRecord = new MyRecord();
MyRecord refundRecord = refundNotify(xmlInfo, notifyRecord);
if (refundRecord.getStr("status").equals("fail")) {
logger.error("微信退款回调失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
if (!refundRecord.getBoolean("isRefund")) {
logger.error("微信退款回调失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
String outRefundNo = notifyRecord.getStr("out_refund_no");
StoreOrder storeOrder = storeOrderService.getByOderId(outRefundNo);
if (ObjectUtil.isNull(storeOrder)) {
logger.error("微信退款订单查询失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
if (storeOrder.getRefundStatus() == 2) {
logger.warn("微信退款订单已确认成功==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
storeOrder.setRefundStatus(2);
boolean update = storeOrderService.updateById(storeOrder);
if (update) {
// 退款task
redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, storeOrder.getId());
} else {
logger.warn("微信退款订单更新失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
}
return refundRecord.getStr("returnXml");
}
/**
* 支付订单回调通知
* @return MyRecord
*/
private MyRecord refundNotify(String xmlInfo, MyRecord notifyRecord) {
MyRecord refundRecord = new MyRecord();
refundRecord.set("status", "fail");
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
if(StrUtil.isBlank(xmlInfo)){
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[xmlInfo is blank]]></return_msg>");
sb.append("</xml>");
logger.error("wechat refund callback error : " + sb.toString());
return refundRecord.set("returnXml", sb.toString()).set("errMsg", "xmlInfo is blank");
}
Map<String, String> respMap;
try {
respMap = WxPayUtil.xmlToMap(xmlInfo);
} catch (Exception e) {
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[").append(e.getMessage()).append("]]></return_msg>");
sb.append("</xml>");
logger.error("wechat refund callback error : " + e.getMessage());
return refundRecord.set("returnXml", sb.toString()).set("errMsg", e.getMessage());
}
notifyRecord.setColums(_strMap2ObjMap(respMap));
// 这里的可以应该根据小程序还是公众号区分
String return_code = respMap.get("return_code");
if (return_code.equals(Constants.SUCCESS)) {
String appid = respMap.get("appid");
String signKey = getSignKey(appid);
// 解码加密信息
String reqInfo = respMap.get("req_info");
System.out.println("encodeReqInfo==>" + reqInfo);
try {
String decodeInfo = decryptToStr(reqInfo, signKey);
Map<String, String> infoMap = WxPayUtil.xmlToMap(decodeInfo);
notifyRecord.setColums(_strMap2ObjMap(infoMap));
String refund_status = infoMap.get("refund_status");
refundRecord.set("isRefund", refund_status.equals(Constants.SUCCESS));
} catch (Exception e) {
refundRecord.set("isRefund", false);
logger.error("微信退款回调异常e==》" + e.getMessage());
}
} else {
notifyRecord.set("return_msg", respMap.get("return_msg"));
refundRecord.set("isRefund", false);
}
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
return refundRecord.set("returnXml", sb.toString()).set("status", "ok");
}
private String getSignKey(String appid) {
String publicAppid = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID);
String miniAppid = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID);
String signKey = "";
if (appid.equals(publicAppid)) {
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY);
}
if (appid.equals(miniAppid)) {
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY);
}
return signKey;
}
public String decryptToStr(String reqInfo, String signKey) throws Exception {
byte[] decodeReqInfo = Base64.decode(reqInfo);
SecretKeySpec key = new SecretKeySpec(SecureUtil.md5(signKey).toLowerCase().getBytes(), "AES");
Cipher cipher;
cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(decodeReqInfo), StandardCharsets.UTF_8);
}
private static final List<String> list = new ArrayList<>();
static {
list.add("total_fee");
list.add("cash_fee");
list.add("coupon_fee");
list.add("coupon_count");
list.add("refund_fee");
list.add("settlement_refund_fee");
list.add("settlement_total_fee");
list.add("cash_refund_fee");
list.add("coupon_refund_fee");
list.add("coupon_refund_count");
}
private Map<String, Object> _strMap2ObjMap(Map<String, String> params) {
Map<String, Object> map = new HashMap<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (list.contains(entry.getKey())) {
try {
map.put(entry.getKey(), Integer.parseInt(entry.getValue()));
} catch (NumberFormatException e) {
map.put(entry.getKey(), 0);
logger.error("字段格式错误key==》" + entry.getKey() + ", value==》" + entry.getValue());
}
continue;
}
map.put(entry.getKey(), entry.getValue());
}
return map;
}
}

View File

@@ -1,9 +1,26 @@
package com.zbkj.crmeb.payment.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.common.MyRecord;
import com.constants.Constants;
import com.constants.PayConstants;
import com.exception.CrmebException;
import com.utils.DateUtil;
import com.utils.RedisUtil;
import com.zbkj.crmeb.bargain.model.StoreBargainUser;
import com.zbkj.crmeb.bargain.service.StoreBargainService;
import com.zbkj.crmeb.bargain.service.StoreBargainUserService;
import com.zbkj.crmeb.combination.model.StoreCombination;
import com.zbkj.crmeb.combination.model.StorePink;
import com.zbkj.crmeb.combination.service.StoreCombinationService;
import com.zbkj.crmeb.combination.service.StorePinkService;
import com.zbkj.crmeb.front.request.OrderPayRequest;
import com.zbkj.crmeb.front.response.OrderPayResultResponse;
import com.zbkj.crmeb.front.response.UserRechargePaymentResponse;
import com.zbkj.crmeb.front.vo.WxPayJsResultVo;
import com.zbkj.crmeb.marketing.request.StoreCouponUserRequest;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.payment.service.OrderPayService;
@@ -14,17 +31,16 @@ import com.zbkj.crmeb.payment.vo.wechat.PayParamsVo;
import com.zbkj.crmeb.payment.wechat.WeChatPayService;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.model.StoreProductCoupon;
import com.zbkj.crmeb.store.service.StoreOrderInfoService;
import com.zbkj.crmeb.store.service.StoreOrderService;
import com.zbkj.crmeb.store.service.StoreOrderStatusService;
import com.zbkj.crmeb.store.service.StoreProductCouponService;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserBill;
import com.zbkj.crmeb.user.model.UserToken;
import com.zbkj.crmeb.user.service.UserBillService;
import com.zbkj.crmeb.user.service.UserLevelService;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.wechat.service.TemplateMessageService;
import com.zbkj.crmeb.wechat.service.WeChatService;
@@ -40,7 +56,11 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -108,6 +128,29 @@ public class OrderPayServiceImpl extends PayService implements OrderPayService {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private RedisUtil redisUtil;
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private StoreProductService storeProductService;
@Autowired
private UserLevelService userLevelService;
@Autowired
private StoreBargainService storeBargainService;
@Autowired
private StoreBargainUserService storeBargainUserService;
@Autowired
private StoreCombinationService storeCombinationService;
@Autowired
private StorePinkService storePinkService;
/**
* 订单支付
@@ -242,43 +285,140 @@ public class OrderPayServiceImpl extends PayService implements OrderPayService {
/**
* 支付成功处理
* @param storeOrder 订单
* @param user 用户
* @param userToken 用户Token
*/
@Override
public Boolean paySuccess(StoreOrder storeOrder, User user, UserToken userToken) {
storeOrder.setPaid(true);
storeOrder.setPayTime(DateUtil.nowDateTime());
public Boolean paySuccess(StoreOrder storeOrder) {
if (storeOrder.getPayType().equals(Constants.PAY_TYPE_YUE)) {
user.setNowMoney(user.getNowMoney().subtract(storeOrder.getPayPrice()));
User user = userService.getById(storeOrder.getUid());
List<UserBill> billList = CollUtil.newArrayList();
// 订单支付记录
UserBill userBill = userBillInit(storeOrder, user);
billList.add(userBill);
// 积分抵扣记录
if (storeOrder.getUseIntegral() > 0) {
UserBill userBillSub = userBillSubInit(storeOrder, user);
billList.add(userBillSub);
}
UserBill userBill = userBillInit(storeOrder, user);
// 经验处理1.经验添加2.等级计算
Integer experience = 0;
experience = storeOrder.getPayPrice().setScale(0, BigDecimal.ROUND_DOWN).intValue();
user.setExperience(user.getExperience() + experience);
// 经验添加记录
UserBill experienceBill = experienceBillInit(storeOrder, user.getExperience(), experience);
billList.add(experienceBill);
// 积分处理1.下单赠送积分2.商品赠送积分
Integer integral = 0;
// 下单赠送积分
//赠送积分比例
String integralStr = systemConfigService.getValueByKey(Constants.CONFIG_KEY_INTEGRAL_RATE);
if (StrUtil.isNotBlank(integralStr)) {
BigDecimal integralBig = new BigDecimal(integralStr);
integral = integralBig.multiply(storeOrder.getPayPrice()).setScale(0, BigDecimal.ROUND_DOWN).intValue();
if (integral > 0) {
// 添加积分
user.setIntegral(user.getIntegral() + integral);
}
// 生成积分记录
UserBill integralBill = integralBillInit(storeOrder, user.getIntegral(), integral, "order");
billList.add(integralBill);
}
// 商品赠送积分
// 查询订单详情
// 获取商品额外赠送积分
List<StoreOrderInfoVo> orderInfoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
List<Integer> productIds = orderInfoList.stream().map(StoreOrderInfoVo::getProductId).collect(Collectors.toList());
if(productIds.size() > 0){
List<StoreProduct> products = storeProductService.getListInIds(productIds);
int sumIntegral = products.stream().mapToInt(e -> e.getGiveIntegral().intValue()).sum();
if (sumIntegral > 0) {
// 添加积分
user.setIntegral(user.getIntegral() + sumIntegral);
}
// 生成积分记录
UserBill integralBill = integralBillInit(storeOrder, user.getIntegral(), sumIntegral, "product");
billList.add(integralBill);
}
// 更新用户下单数量
user.setPayCount(user.getPayCount() + 1);
Boolean execute = transactionTemplate.execute(e -> {
//更新订单状态
storeOrderService.updateById(storeOrder);
//订单日志
storeOrderStatusService.addLog(storeOrder.getId(), Constants.ORDER_LOG_PAY_SUCCESS, Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS);
// 余额支付——用户余额更新,余额资金变动记录添加
if (storeOrder.getPayType().equals(Constants.PAY_TYPE_YUE)) {
userService.updateNowMoney(user.getUid(), user.getNowMoney());
UserBill userBillYueInit = userBillYueInit(storeOrder, user);
userBillService.save(userBillYueInit);
}
// 用户信息变更
userService.updateById(user);
//资金变动
userBillService.save(userBill);
userBillService.saveBatch(billList);
// 更新用户下单数量
userService.userPayCountPlus(user);
//经验升级
userLevelService.upLevel(user);
//增加经验、积分
userService.consumeAfterUpdateUserFounds(storeOrder.getUid(), storeOrder.getPayPrice(), Constants.USER_BILL_TYPE_PAY_ORDER);
// 如果是砍价商品,修改砍价状态
if (storeOrder.getBargainId() > 0) {
StoreBargainUser storeBargainUser = storeBargainUserService.getByBargainIdAndUid(storeOrder.getBargainId(), user.getUid());
storeBargainUser.setStatus(3);
storeBargainUserService.updateById(storeBargainUser);
}
// 如果是拼团商品,拼团处理
// TODO 拼团整体逻辑需调整
// TODO 将拼团生成放到订单生成,如果取消订单,则删除生成的拼团的数据
// TODO 在这里只负责将拼团状态改为已完成用消息列队发送拼团task形式处理
if (storeOrder.getCombinationId() > 0) {
// 判断拼团团长是否存在
StorePink headPink = new StorePink();
Integer pinkId = storeOrder.getPinkId();
if (pinkId > 0) {
headPink = storePinkService.getById(pinkId);
if (ObjectUtil.isNull(headPink) || headPink.getIsRefund().equals(true) || headPink.getStatus() == 3) {
pinkId = 0;
}
}
StoreCombination storeCombination = storeCombinationService.getById(storeOrder.getCombinationId());
// 生成拼团表数据
StorePink storePink = new StorePink();
storePink.setUid(user.getUid());
storePink.setAvatar(user.getAvatar());
storePink.setNickname(user.getNickname());
storePink.setOrderId(storeOrder.getOrderId());
storePink.setOrderIdKey(storeOrder.getId());
storePink.setTotalNum(storeOrder.getTotalNum());
storePink.setTotalPrice(storeOrder.getTotalPrice());
storePink.setCid(storeCombination.getId());
storePink.setPid(storeCombination.getProductId());
storePink.setPeople(storeCombination.getPeople());
storePink.setPrice(storeCombination.getPrice());
Integer effectiveTime = storeCombination.getEffectiveTime();// 有效小时数
DateTime dateTime = cn.hutool.core.date.DateUtil.date();
storePink.setAddTime(dateTime.getTime());
if (pinkId > 0) {
storePink.setStopTime(headPink.getStopTime());
} else {
DateTime hourTime = cn.hutool.core.date.DateUtil.offsetHour(dateTime, effectiveTime);
long stopTime = hourTime.getTime();
if (stopTime > storeCombination.getStopTime()) {
stopTime = storeCombination.getStopTime();
}
storePink.setStopTime(stopTime);
}
storePink.setKId(pinkId);
storePink.setIsTpl(false);
storePink.setIsRefund(false);
storePink.setStatus(1);
storePinkService.save(storePink);
// 如果是开团,需要更新订单数据
if (storePink.getKId() == 0) {
storeOrder.setPinkId(storePink.getId());
storeOrderService.updateById(storeOrder);
}
}
return Boolean.TRUE;
});
@@ -297,16 +437,159 @@ public class OrderPayServiceImpl extends PayService implements OrderPayService {
return execute;
}
private UserBill userBillYueInit(StoreOrder storeOrder, User user) {
/**
* 余额支付
* @param storeOrder 订单
* @return Boolean
*/
@Override
public Boolean yuePay(StoreOrder storeOrder) {
// 用户余额扣除
User user = userService.getById(storeOrder.getUid());
if (ObjectUtil.isNull(user)) throw new CrmebException("用户不存在");
if (user.getNowMoney().compareTo(storeOrder.getPayPrice()) < 0) {
throw new CrmebException("用户余额不足");
}
if (user.getIntegral() < storeOrder.getUseIntegral()) {
throw new CrmebException("用户积分不足");
}
storeOrder.setPaid(true);
storeOrder.setPayTime(DateUtil.nowDateTime());
Boolean execute = transactionTemplate.execute(e -> {
// 订单修改
storeOrderService.updateById(storeOrder);
// 这里只扣除金额账单记录在task中处理
userService.updateNowMoney(user, storeOrder.getPayPrice(), "sub");
// 扣除积分
if (storeOrder.getUseIntegral() > 0) {
userService.updateIntegral(user, storeOrder.getUseIntegral(), "sub");
}
// 添加支付成功redis队列
redisUtil.lPush(Constants.ORDER_TASK_PAY_SUCCESS_AFTER, storeOrder.getOrderId());
return Boolean.TRUE;
});
if (!execute) throw new CrmebException("余额支付订单失败");
return execute;
}
/**
* 订单支付
* @param orderPayRequest 支付参数
* @param ip ip
* @return
* 1.微信支付拉起微信预支付,返回前端调用微信支付参数,在之后需要调用微信支付查询接口
* 2.余额支付更改对应信息后加入支付成功处理task
*/
@Override
public OrderPayResultResponse payment(OrderPayRequest orderPayRequest, String ip) {
StoreOrder storeOrder = storeOrderService.getByOderId(orderPayRequest.getOrderNo());
if (ObjectUtil.isNull(storeOrder)) {
throw new CrmebException("订单不存在");
}
if (storeOrder.getIsDel()) {
throw new CrmebException("订单已被删除");
}
if (storeOrder.getPaid()) {
throw new CrmebException("订单已支付");
}
User user = userService.getById(storeOrder.getUid());
if (ObjectUtil.isNull(user)) throw new CrmebException("用户不存在");
// 判断订单是否还是之前的支付类型
if (!storeOrder.getPayType().equals(orderPayRequest.getPayType())) {
// 根据支付类型进行校验,更换支付类型
storeOrder.setPayType(orderPayRequest.getPayType());
// 余额支付
if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
if (user.getNowMoney().compareTo(storeOrder.getPayPrice()) < 0) {
throw new CrmebException("用户余额不足");
}
storeOrder.setIsChannel(3);
}
if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
switch (orderPayRequest.getPayChannel()){
case PayConstants.PAY_CHANNEL_WE_CHAT_H5:// H5
storeOrder.setIsChannel(2);
break;
case PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC:// 公众号
storeOrder.setIsChannel(0);
break;
case PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM:// 小程序
storeOrder.setIsChannel(1);
break;
}
}
boolean changePayType = storeOrderService.updateById(storeOrder);
if (!changePayType) {
throw new CrmebException("变更订单支付类型失败!");
}
}
if (user.getIntegral() < storeOrder.getUseIntegral()) {
throw new CrmebException("用户积分不足");
}
OrderPayResultResponse response = new OrderPayResultResponse();
MyRecord record = new MyRecord();
response.setOrderNo(storeOrder.getOrderId());
response.setPayType(storeOrder.getPayType());
// 0元付
if (storeOrder.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
Boolean aBoolean = yuePay(storeOrder);
// response.setPayType(PayConstants.PAY_TYPE_ZERO_PAY);
response.setPayType(PayConstants.PAY_TYPE_YUE);
response.setStatus(aBoolean);
return response;
}
// 微信支付,调用微信预下单,返回拉起微信支付需要的信息
if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
Map<String, String> unifiedorder = weChatPayService.unifiedorder(storeOrder, ip);
record.set("status", true);
response.setStatus(true);
WxPayJsResultVo vo = new WxPayJsResultVo();
vo.setAppId(unifiedorder.get("appId"));
vo.setNonceStr(unifiedorder.get("nonceStr"));
vo.setPackages(unifiedorder.get("package"));
vo.setSignType(unifiedorder.get("signType"));
vo.setTimeStamp(unifiedorder.get("timeStamp"));
vo.setPaySign(unifiedorder.get("paySign"));
if (storeOrder.getIsChannel() == 2) {
vo.setMwebUrl(unifiedorder.get("mweb_url"));
response.setPayType(PayConstants.PAY_CHANNEL_WE_CHAT_H5);
}
response.setJsConfig(vo);
return response;
}
// 余额支付
if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
Boolean yueBoolean = yuePay(storeOrder);
response.setStatus(yueBoolean);
return response;
}
if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY)) {
throw new CrmebException("暂时不支持支付宝支付");
}
if (storeOrder.getPayType().equals(PayConstants.PAY_TYPE_OFFLINE)) {
throw new CrmebException("暂时不支持线下支付");
}
response.setStatus(false);
return response;
}
private UserBill userBillSubInit(StoreOrder storeOrder, User user) {
UserBill userBill = new UserBill();
userBill.setTitle("购买商品");
userBill.setTitle("订单支付抵扣");
userBill.setUid(user.getUid());
userBill.setCategory(Constants.USER_BILL_CATEGORY_MONEY);
userBill.setCategory(Constants.USER_BILL_CATEGORY_INTEGRAL);
userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT);
userBill.setNumber(storeOrder.getPayPrice());
userBill.setNumber(new BigDecimal(storeOrder.getUseIntegral()));
userBill.setLinkId(storeOrder.getId()+"");
userBill.setBalance(user.getNowMoney());
userBill.setMark("余额支付" + storeOrder.getPayPrice() + "购买商品");
userBill.setBalance(new BigDecimal(user.getIntegral()));
userBill.setMark("订单支付抵扣" + storeOrder.getUseIntegral() + "积分购买商品");
userBill.setPm(0);
return userBill;
}
@@ -317,13 +600,52 @@ public class OrderPayServiceImpl extends PayService implements OrderPayService {
userBill.setLinkId(order.getId().toString());
userBill.setTitle("购买商品");
userBill.setCategory(Constants.USER_BILL_CATEGORY_MONEY);
userBill.setType(Constants.USER_BILL_TYPE_PAY_MONEY);
userBill.setType(Constants.USER_BILL_TYPE_PAY_ORDER);
userBill.setNumber(order.getPayPrice());
userBill.setBalance(user.getNowMoney());
userBill.setMark("支付" + order.getPayPrice() + "元购买商品");
return userBill;
}
/**
* 经验添加记录
*/
private UserBill experienceBillInit(StoreOrder storeOrder, Integer balance, Integer experience) {
UserBill userBill = new UserBill();
userBill.setPm(1);
userBill.setUid(storeOrder.getUid());
userBill.setLinkId(storeOrder.getId().toString());
userBill.setTitle(Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS);
userBill.setCategory(Constants.USER_BILL_CATEGORY_EXPERIENCE);
userBill.setType(Constants.USER_BILL_TYPE_PAY_ORDER);
userBill.setNumber(new BigDecimal(experience));
userBill.setBalance(new BigDecimal(balance));
userBill.setMark("用户付款成功增加" + experience + "经验");
return userBill;
}
/**
* 积分添加记录
*/
private UserBill integralBillInit(StoreOrder storeOrder, Integer balance, Integer integral, String type) {
UserBill userBill = new UserBill();
userBill.setPm(1);
userBill.setUid(storeOrder.getUid());
userBill.setLinkId(storeOrder.getId().toString());
userBill.setTitle(Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS);
userBill.setCategory(Constants.USER_BILL_CATEGORY_INTEGRAL);
userBill.setType(Constants.USER_BILL_TYPE_PAY_ORDER);
userBill.setNumber(new BigDecimal(integral));
userBill.setBalance(new BigDecimal(balance));
if (type.equals("order")){
userBill.setMark("用户付款成功,订单增加" + integral + "积分");
}
if (type.equals("product")) {
userBill.setMark("用户付款成功,商品增加" + integral + "积分");
}
return userBill;
}
/**
* 发送模板消息通知
*/

View File

@@ -22,7 +22,7 @@ import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="CreateOrderVo对象", description="微信统一下单对象")
@ApiModel(value="CreateOrderRequestVo对象", description="微信统一下单对象")
public class CreateOrderRequestVo {
@ApiModelProperty(value = "appId公众号名称由商户传入", required = true)
private String appid;
@@ -39,13 +39,13 @@ public class CreateOrderRequestVo {
@ApiModelProperty(value = "签名", required = true)
private String sign;
@ApiModelProperty(value = "随机字符串不长于32位")
@ApiModelProperty(value = "签名类型默认为MD5支持HMAC-SHA256和MD5。")
private String sign_type;
@ApiModelProperty(value = "商品简单描述,该字段须严格按照规范传递", required = true)
private String body;
@ApiModelProperty(value = "单品优惠字段(暂未上线)")
@ApiModelProperty(value = "商品简单描述")
private String detail;
@ApiModelProperty(value = "附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据, String(127)")
@@ -75,8 +75,8 @@ public class CreateOrderRequestVo {
@ApiModelProperty(value = "接收微信支付异步通知回调地址通知url必须为直接可访问的url不能携带参数。")
private String notify_url;
@ApiModelProperty(value = "H5支付的交易类型为MWEB")
private String trade_type = WeChatConstants.PAY_TYPE_H5;
@ApiModelProperty(value = "JSAPI -JSAPI支付或小程序支付 NATIVE -Native支付 APP -APP支付MWEB--H5支付", required = true)
private String trade_type;
@ApiModelProperty(value = "trade_type=NATIVE此参数必传。此id为二维码中包含的商品ID商户自行定义。")
private String product_id;

View File

@@ -61,5 +61,8 @@ public class WxRefundVo {
@ApiModelProperty(value = "退款货币种类:符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型")
private String refund_fee_type = "CNY";
@ApiModelProperty(value = "退款结果通知url")
private String notify_url;
}

View File

@@ -2,6 +2,9 @@ package com.zbkj.crmeb.payment.wechat;
import com.zbkj.crmeb.payment.vo.wechat.CreateOrderResponseVo;
import com.zbkj.crmeb.payment.vo.wechat.PayParamsVo;
import com.zbkj.crmeb.store.model.StoreOrder;
import java.util.Map;
/**
* 微信支付
@@ -17,4 +20,19 @@ import com.zbkj.crmeb.payment.vo.wechat.PayParamsVo;
*/
public interface WeChatPayService {
CreateOrderResponseVo create(PayParamsVo payParamsVo);
/**
* 微信预下单接口
* @param storeOrder 订单
* @param ip ip
* @return 获取wechat.requestPayment()参数
*/
Map<String, String> unifiedorder(StoreOrder storeOrder, String ip);
/**
* 查询支付结果
* @param orderNo 订单编号
* @return
*/
Boolean queryPayResult(String orderNo);
}

View File

@@ -1,18 +1,24 @@
package com.zbkj.crmeb.payment.wechat.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.common.MyRecord;
import com.constants.Constants;
import com.constants.PayConstants;
import com.constants.WeChatConstants;
import com.exception.CrmebException;
import com.utils.CrmebUtil;
import com.utils.RestTemplateUtil;
import com.utils.XmlUtil;
import com.utils.*;
import com.zbkj.crmeb.payment.vo.wechat.*;
import com.zbkj.crmeb.payment.wechat.WeChatPayService;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.service.StoreOrderInfoService;
import com.zbkj.crmeb.store.service.StoreOrderService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserToken;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.user.service.UserTokenService;
import com.zbkj.crmeb.wechat.service.WeChatService;
import lombok.Data;
@@ -21,9 +27,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
@@ -69,6 +78,15 @@ public class WeChatPayServiceImpl implements WeChatPayService {
private CreateOrderResponseVo createOrderResponseVo = null;
@Autowired
private RedisUtil redisUtil;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private UserService userService;
/**
* 统一下单
* @param payParamsVo PayParamsVo 支付参数
@@ -235,4 +253,271 @@ public class WeChatPayServiceImpl implements WeChatPayService {
UserToken userToken = userTokenService.getTokenByUserId(getPayParamsVo().getUserId(), type);
return userToken.getToken();
}
/**
* 微信预下单
* @param storeOrder 订单
* @param ip ip
* @return
*/
@Override
public Map<String, String> unifiedorder(StoreOrder storeOrder, String ip) {
if (ObjectUtil.isNull(storeOrder)) {
throw new CrmebException("订单不存在");
}
if (storeOrder.getIsDel()) {
throw new CrmebException("订单已被删除");
}
if (storeOrder.getPaid()) {
throw new CrmebException("订单已支付");
}
if (!storeOrder.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
throw new CrmebException("不是微信支付类型订单,请重新选择支付方式");
}
// 获取用户openId
// 根据订单支付类型来判断获取公众号openId还是小程序openId
UserToken userToken = new UserToken();
if (storeOrder.getIsChannel() == 0) {// 公众号
userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), 1);
}
if (storeOrder.getIsChannel() == 1) {// 小程序
userToken = userTokenService.getTokenByUserId(storeOrder.getUid(), 2);
}
if (storeOrder.getIsChannel() == 2) {// H5
// userTokenService.getByUid(storeOrder.getUid());
userToken.setToken("");
}
if (ObjectUtil.isNull(userToken)) {
throw new CrmebException("该用户没有openId");
}
// 获取appid、mch_id
// 微信签名key
String appId = "";
String mchId = "";
String signKey = "";
if (storeOrder.getIsChannel() == 0) {// 公众号
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY);
}
if (storeOrder.getIsChannel() == 1) {// 小程序
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY);
}
if (storeOrder.getIsChannel() == 2) {// H5,使用公众号的
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY);
}
// 获取微信预下单对象
CreateOrderRequestVo unifiedorderVo = getUnifiedorderVo(storeOrder, userToken.getToken(), ip, appId, mchId, signKey);
// 预下单
CreateOrderResponseVo responseVo = unifiedOrder(unifiedorderVo);
// 组装前端预下单参数
Map<String, String> map = new HashMap<>();
map.put("appId", unifiedorderVo.getAppid());
map.put("nonceStr", WxPayUtil.getNonceStr());
map.put("package", "prepay_id=".concat(responseVo.getPrepayId()));
map.put("signType", unifiedorderVo.getSign_type());
map.put("timeStamp", Long.toString(WxPayUtil.getCurrentTimestamp()));
String paySign = WxPayUtil.getSign(map, signKey);
map.put("paySign", paySign);
if (storeOrder.getIsChannel() == 2) {
map.put("mweb_url", responseVo.getMWebUrl());
}
return map;
}
/**
* 查询支付结果
* @param orderNo 订单编号
* @return
*/
@Override
public Boolean queryPayResult(String orderNo) {
if (StrUtil.isBlank(orderNo)) {
throw new CrmebException("订单编号不能为空");
}
StoreOrder storeOrder = storeOrderService.getByOderId(orderNo);
if (ObjectUtil.isNull(storeOrder)) {
throw new CrmebException("订单不存在");
}
if (storeOrder.getIsDel()) {
throw new CrmebException("订单已被删除");
}
if (!storeOrder.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
throw new CrmebException("不是微信支付类型订单,请重新选择支付方式");
}
if (storeOrder.getPaid()) {
// throw new CrmebException("订单已支付");
return Boolean.TRUE;
}
User user = userService.getById(storeOrder.getUid());
if (ObjectUtil.isNull(user)) throw new CrmebException("用户不存在");
// 获取appid、mch_id
// 微信签名key
String appId = "";
String mchId = "";
String signKey = "";
if (storeOrder.getIsChannel() == 0) {// 公众号
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY);
}
if (storeOrder.getIsChannel() == 1) {// 小程序
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY);
}
if (storeOrder.getIsChannel() == 2) {// H5
appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID);
mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_MCH_ID);
signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY);
}
// 生成查询订单对象
Map<String, String> payVo = getWxChantQueryPayVo(orderNo, appId, mchId, signKey);
// 查询订单信息
MyRecord record = orderPayQuery(payVo);
Boolean updatePaid = transactionTemplate.execute(e -> {
storeOrderService.updatePaid(orderNo);
if (storeOrder.getUseIntegral() > 0) {
userService.updateIntegral(user, storeOrder.getUseIntegral(), "sub");
}
return Boolean.TRUE;
});
if (!updatePaid) {
throw new CrmebException("支付成功更新订单失败");
}
// 添加支付成功task
redisUtil.lPush(Constants.ORDER_TASK_PAY_SUCCESS_AFTER, orderNo);
return Boolean.TRUE;
}
private MyRecord orderPayQuery(Map<String, String> payVo) {
String url = PayConstants.WX_PAY_API_URL + PayConstants.WX_PAY_ORDER_QUERY_API_URI;
try {
String request = XmlUtil.mapToXml(payVo);
String xml = restTemplateUtil.postXml(url, request);
HashMap<String, Object> map = XmlUtil.xmlToMap(xml);
MyRecord record = new MyRecord();
if(null == map){
throw new CrmebException("微信订单查询失败!");
}
record.setColums(map);
if(record.getStr("return_code").toUpperCase().equals("FAIL")){
throw new CrmebException("微信下单失败1" + record.getStr("return_msg"));
}
if(record.getStr("result_code").toUpperCase().equals("FAIL")){
throw new CrmebException("微信下单失败2" + record.getStr("err_code_des"));
}
return record;
} catch (Exception e) {
e.printStackTrace();
throw new CrmebException("查询微信订单mapToXml异常===》" + e.getMessage());
}
}
/**
* 生成微信查询订单对象
* @return
*/
private Map<String, String> getWxChantQueryPayVo(String no, String appId, String mchId, String orderNo) {
Map<String, String> map = CollUtil.newHashMap();
map.put("appid", appId);
map.put("mch_id", mchId);
map.put("out_trade_no", orderNo);
map.put("nonce_str", WxPayUtil.getNonceStr());
map.put("sign_type", PayConstants.WX_PAY_SIGN_TYPE_MD5);
map.put("sign", WxPayUtil.getSign(map, signKey));
return map;
}
/**
* 获取微信预下单对象
* @return
*/
private CreateOrderRequestVo getUnifiedorderVo(StoreOrder storeOrder, String openid, String ip, String appId, String mchId, String signKey) {
// 获取域名
String domain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_SITE_URL);
String apiDomain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
AttachVo attachVo = new AttachVo(Constants.SERVICE_PAY_TYPE_ORDER, storeOrder.getUid());
CreateOrderRequestVo vo = new CreateOrderRequestVo();
vo.setAppid(appId);
vo.setMch_id(mchId);
vo.setNonce_str(WxPayUtil.getNonceStr());
vo.setSign_type(PayConstants.WX_PAY_SIGN_TYPE_MD5);
vo.setBody(PayConstants.PAY_BODY);
vo.setAttach(JSONObject.toJSONString(attachVo));
vo.setOut_trade_no(storeOrder.getOrderId());
// 订单中使用的是BigDecimal,这里要转为Integer类型
vo.setTotal_fee(storeOrder.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
vo.setSpbill_create_ip(ip);
vo.setNotify_url(apiDomain + PayConstants.WX_PAY_NOTIFY_API_URI);
vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_JS);
vo.setOpenid(openid);
if (storeOrder.getIsChannel() == 2){// H5
vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_H5);
vo.setOpenid(null);
}
CreateOrderH5SceneInfoVo createOrderH5SceneInfoVo = new CreateOrderH5SceneInfoVo(
new CreateOrderH5SceneInfoDetailVo(
domain,
systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_SITE_NAME)
)
);
vo.setScene_info(JSONObject.toJSONString(createOrderH5SceneInfoVo));
String sign = WxPayUtil.getSign(vo, signKey);
vo.setSign(sign);
return vo;
}
/**
* 作用:统一下单<br>
* 场景公共号支付、扫码支付、APP支付
*
* @param vo 向wxpay post的请求数据
* @return API返回数据
*/
private CreateOrderResponseVo unifiedOrder(CreateOrderRequestVo vo) {
try {
String url = PayConstants.WX_PAY_API_URL + PayConstants.WX_PAY_API_URI;
String request = XmlUtil.objectToXml(vo);
String xml = restTemplateUtil.postXml(url, request);
HashMap<String, Object> map = XmlUtil.xmlToMap(xml);
if(null == map){
throw new CrmebException("微信下单失败!");
}
CreateOrderResponseVo responseVo = CrmebUtil.mapToObj(map, CreateOrderResponseVo.class);
if(responseVo.getReturnCode().toUpperCase().equals("FAIL")){
throw new CrmebException("微信下单失败1" + responseVo.getReturnMsg());
}
if(responseVo.getResultCode().toUpperCase().equals("FAIL")){
throw new CrmebException("微信下单失败2" + responseVo.getErrCodeDes());
}
responseVo.setExtra(vo.getScene_info());
return responseVo;
} catch (Exception e) {
e.printStackTrace();
throw new CrmebException(e.getMessage());
}
}
}

View File

@@ -63,7 +63,7 @@ public class StoreSeckill implements Serializable {
private BigDecimal otPrice;
@ApiModelProperty(value = "返多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "排序")
private Integer sort;

View File

@@ -60,7 +60,7 @@ public class StoreSeckillRequest {
private BigDecimal otPrice;
@ApiModelProperty(value = "返多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "排序")
private Integer sort;

View File

@@ -117,7 +117,7 @@ public class StoreSeckillResponse {
private BigDecimal otPrice;
@ApiModelProperty(value = "返多少积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "排序")
private Integer sort;

View File

@@ -137,7 +137,7 @@ public class StoreSeckillStoreInfoResponse {
private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;

View File

@@ -3,19 +3,14 @@ package com.zbkj.crmeb.seckill.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.common.PageParamRequest;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.front.response.SecKillResponse;
import com.zbkj.crmeb.seckill.model.StoreSeckill;
import com.zbkj.crmeb.seckill.request.StoreSeckillAttrRequest;
import com.zbkj.crmeb.seckill.request.StoreSeckillRequest;
import com.zbkj.crmeb.seckill.request.StoreSeckillSearchRequest;
import com.zbkj.crmeb.seckill.response.StoreSeckillDetailResponse;
import com.zbkj.crmeb.seckill.response.StoreSeckillResponse;
import com.zbkj.crmeb.store.request.StoreProductRequest;
import com.zbkj.crmeb.store.request.StoreProductStockRequest;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import org.json.JSONException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -101,12 +96,13 @@ public interface StoreSeckillService extends IService<StoreSeckill> {
/**
* 扣减库存加销量
* @param seckillId 产品id
* @param num 商品数量
* @param type 是否限购 0=不限购
* @param seckillId 秒杀产品id
* @param num 购买商品数量
* @param attrValueId 秒杀商品规格
* @param productId 主商品id
* @return 扣减结果
*/
boolean decProductStock(Integer seckillId, Integer num, Integer attrValueId, Integer type);
Boolean decProductStock(Integer seckillId, Integer num, Integer attrValueId, Integer productId);
/**
* 根据商品id查询正在秒杀的商品信息
@@ -132,4 +128,19 @@ public interface StoreSeckillService extends IService<StoreSeckill> {
* @param productId 商品编号
*/
Boolean isExistActivity(Integer productId);
/**
* 查询带异常
* @param id 秒杀商品id
* @return StoreSeckill
*/
StoreSeckill getByIdException(Integer id);
/**
* 添加/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
*/
Boolean operationStock(Integer id, Integer num, String type);
}

View File

@@ -99,7 +99,7 @@ public class StoreSeckillMangerServiceImpl extends ServiceImpl<StoreSeckillMange
public List<StoreSeckillManger> checkTimeRangeUnique(StoreSeckillManger storeSeckillManger) {
LambdaQueryWrapper<StoreSeckillManger> lqTimeUnique = Wrappers.lambdaQuery();
lqTimeUnique.ge(StoreSeckillManger::getStartTime, storeSeckillManger.getStartTime());
lqTimeUnique.gt(StoreSeckillManger::getStartTime, storeSeckillManger.getEndTime());
lqTimeUnique.lt(StoreSeckillManger::getStartTime, storeSeckillManger.getEndTime());
lqTimeUnique.or();
lqTimeUnique.le(StoreSeckillManger::getStartTime, storeSeckillManger.getStartTime());
lqTimeUnique.ge(StoreSeckillManger::getEndTime, storeSeckillManger.getEndTime());

View File

@@ -2,10 +2,12 @@ package com.zbkj.crmeb.seckill.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
@@ -18,7 +20,6 @@ import com.github.pagehelper.PageInfo;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.utils.RedisUtil;
import com.zbkj.crmeb.combination.model.StoreCombination;
import com.zbkj.crmeb.front.response.SecKillResponse;
import com.zbkj.crmeb.seckill.dao.StoreSeckillDao;
import com.zbkj.crmeb.seckill.model.StoreSeckill;
@@ -35,12 +36,11 @@ import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.StoreProductAttrValueRequest;
import com.zbkj.crmeb.store.request.StoreProductStockRequest;
import com.zbkj.crmeb.store.response.StoreProductAttrValueResponse;
import com.zbkj.crmeb.store.response.StoreProductRecommendResponse;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.utilService.ProductUtils;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import com.zbkj.crmeb.task.order.OrderRefundByUser;
import com.zbkj.crmeb.task.order.OrderRefundTask;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.service.UserService;
import org.apache.commons.lang3.StringUtils;
@@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -107,7 +108,10 @@ public class StoreSeckillServiceImpl extends ServiceImpl<StoreSeckillDao, StoreS
@Autowired
private RedisUtil redisUtil;
private static final Logger logger = LoggerFactory.getLogger(OrderRefundByUser.class);
@Autowired
private TransactionTemplate transactionTemplate;
private static final Logger logger = LoggerFactory.getLogger(OrderRefundTask.class);
/**
* 列表
@@ -649,7 +653,7 @@ public class StoreSeckillServiceImpl extends ServiceImpl<StoreSeckillDao, StoreS
}
lqw.orderByDesc(StoreSeckill::getId);
List<StoreSeckill> storeSeckills = dao.selectList(lqw);
storeSeckills.stream().map(e->{
storeSeckills.forEach(e->{
StoreSeckillResponse r = new StoreSeckillResponse();
BeanUtils.copyProperties(e,r);
r.setImages(CrmebUtil.stringToArrayStr(e.getImages()));
@@ -657,8 +661,7 @@ public class StoreSeckillServiceImpl extends ServiceImpl<StoreSeckillDao, StoreS
r.setTimeSwap(currentTimeSwap+"");
r.setPercent(CrmebUtil.percentInstanceIntVal(e.getQuotaShow() - e.getQuota(), e.getQuotaShow()));
responses.add(r);
return e;
}).collect(Collectors.toList());
});
return responses;
}
@@ -678,46 +681,46 @@ public class StoreSeckillServiceImpl extends ServiceImpl<StoreSeckillDao, StoreS
/**
* 扣减库存加销量
*
* @param seckillId 产品id
* @param num 商品数量
* @param attrValueId
* @param type
* @param seckillId 秒杀产品id
* @param num 购买商品数量
* @param attrValueId 秒杀商品规格
* @param productId 主商品id
* @return 扣减结果
*/
@Override
public boolean decProductStock(Integer seckillId, Integer num, Integer attrValueId, Integer type) {
public Boolean decProductStock(Integer seckillId, Integer num, Integer attrValueId, Integer productId) {
// 因为attrvalue表中unique使用Id代替更新前先查询此表是否存在
// 秒杀SKU 扣减库存加销量
// 秒杀商品sku
StoreProductAttrValue spavPram = new StoreProductAttrValue();
spavPram.setProductId(seckillId).setType(type).setId(attrValueId);
List<StoreProductAttrValue> existAttrValues = storeProductAttrValueService.getByEntity(spavPram);
if(null == existAttrValues && existAttrValues.size() == 0) throw new CrmebException("未找到相关商品属性信息");
StoreProductAttrValue productsInAttrValue = existAttrValues.get(0); // 现在默认只能秒杀一件
StoreSeckill storeSeckill = getById(seckillId);
boolean result = false;
if(null != productsInAttrValue){
boolean resultDecProductStock = storeProductAttrValueService.decProductAttrStock(seckillId,attrValueId,num,type);
if(!resultDecProductStock) throw new CrmebException("扣减秒杀sku库存失败");
}
spavPram.setProductId(seckillId);
spavPram.setType(Constants.PRODUCT_TYPE_SECKILL);
spavPram.setId(attrValueId);
List<StoreProductAttrValue> existSeckillAttrValues = storeProductAttrValueService.getByEntity(spavPram);
if (CollUtil.isEmpty(existSeckillAttrValues)) throw new CrmebException("未找到扣减库存的秒杀商品");
StoreProductAttrValue currentSeckillAttrValue = existSeckillAttrValues.get(0);
// 对应的主商品sku
List<StoreProductAttrValue> currentProAttrValues = storeProductAttrValueService.getListByProductId(productId);
List<StoreProductAttrValue> existAttrValues = currentProAttrValues.stream().filter(e ->
e.getSuk().equals(currentSeckillAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL))
.collect(Collectors.toList());
if (CollUtil.isEmpty(existAttrValues)) throw new CrmebException("未找到扣减库存的商品");
// 秒杀商品表扣减库存加销量
StoreSeckill storeSeckill = getById(seckillId);
if (ObjectUtil.isNull(storeSeckill)) throw new CrmebException("未找到对应的秒杀商品");
LambdaUpdateWrapper<StoreSeckill> lqwuper = new LambdaUpdateWrapper<>();
lqwuper.eq(StoreSeckill::getId, seckillId);
lqwuper.set(StoreSeckill::getStock, storeSeckill.getStock()-num);
lqwuper.set(StoreSeckill::getSales, storeSeckill.getSales()+num);
lqwuper.set(StoreSeckill::getQuota, storeSeckill.getQuota()-num);
result = update(lqwuper);
// if(result){ //判断库存警戒值
// Integer alterNumI=0;
// String alterNum = systemConfigService.getValueByKey("store_stock");
// if(StringUtils.isNotBlank(alterNum)) alterNumI = Integer.parseInt(alterNum);
// if(alterNumI >= productsInAttrValue.getStock()){
// // todo socket 发送库存警告
// }
// }
return result;
lqwuper.eq(StoreSeckill::getId, seckillId);
lqwuper.apply(StrUtil.format(" (stock - {} >= 0) ", num));
Boolean execute = transactionTemplate.execute(e -> {
storeProductAttrValueService.decProductAttrStock(seckillId, attrValueId, num, Constants.PRODUCT_TYPE_SECKILL);
storeProductService.decProductStock(productId, num, existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL);
update(lqwuper);
return Boolean.TRUE;
});
return execute;
}
/**
@@ -813,6 +816,48 @@ public class StoreSeckillServiceImpl extends ServiceImpl<StoreSeckillDao, StoreS
List<StoreSeckill> list = seckillList.stream().filter(i -> i.getStatus().equals(1)).collect(Collectors.toList());
return CollUtil.isNotEmpty(list);
}
/**
* 查询带异常
* @param id 秒杀商品id
* @return StoreSeckill
*/
@Override
public StoreSeckill getByIdException(Integer id) {
LambdaQueryWrapper<StoreSeckill> lqw = Wrappers.lambdaQuery();
lqw.eq(StoreSeckill::getId, id);
lqw.eq(StoreSeckill::getIsDel, false);
lqw.eq(StoreSeckill::getIsShow, true);
StoreSeckill storeSeckill = dao.selectOne(lqw);
if (ObjectUtil.isNull(storeSeckill)) throw new CrmebException("秒杀商品不存在或以删除");
return storeSeckill;
}
/**
* 添加(退货)/扣减库存
* @param id 秒杀商品id
* @param num 数量
* @param type 类型add—添加sub—扣减
* @return Boolean
*/
@Override
public Boolean operationStock(Integer id, Integer num, String type) {
UpdateWrapper<StoreSeckill> updateWrapper = new UpdateWrapper<>();
if (type.equals("add")) {
updateWrapper.setSql(StrUtil.format("stock = stock + {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales - {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota + {}", num));
}
if (type.equals("sub")) {
updateWrapper.setSql(StrUtil.format("stock = stock - {}", num));
updateWrapper.setSql(StrUtil.format("sales = sales + {}", num));
updateWrapper.setSql(StrUtil.format("quota = quota - {}", num));
// 扣减时加乐观锁保证库存不为负
updateWrapper.last(StrUtil.format(" and (stock - {} >= 0)", num));
}
updateWrapper.eq("id", id);
return update(updateWrapper);
}
/////////////////////////////////////////////////////////////////// 自定义方法
// 秒杀操作库存

View File

@@ -68,10 +68,10 @@ public class HomeServiceImpl implements HomeService {
//日同比
int dayRate = CrmebUtil.getRate(today, yesterday);
BigDecimal dayRate = CrmebUtil.getRateBig(today, yesterday);
//周同比
int weekRate = CrmebUtil.getRate(week, preWeek);
BigDecimal weekRate = CrmebUtil.getRateBig(week, preWeek);
return new HomeRateResponse(yesterday, dayRate, weekRate, all);
@@ -104,10 +104,10 @@ public class HomeServiceImpl implements HomeService {
//日同比
int dayRate = CrmebUtil.getRate(today, yesterday);
BigDecimal dayRate = CrmebUtil.getRateBig(today, yesterday);
//周同比
int weekRate = CrmebUtil.getRate(week, preWeek);
BigDecimal weekRate = CrmebUtil.getRateBig(week, preWeek);
return new HomeRateResponse(yesterday, dayRate, weekRate, all);
@@ -140,10 +140,10 @@ public class HomeServiceImpl implements HomeService {
//日同比
int dayRate = CrmebUtil.getRate(today, yesterday);
BigDecimal dayRate = CrmebUtil.getRateBig(today, yesterday);
//周同比
int weekRate = CrmebUtil.getRate(week, preWeek);
BigDecimal weekRate = CrmebUtil.getRateBig(week, preWeek);
return new HomeRateResponse(yesterday, dayRate, weekRate, all);
@@ -170,10 +170,10 @@ public class HomeServiceImpl implements HomeService {
Integer preWeek = storeProductLogService.getCountByTimeAndType(Constants.SEARCH_DATE_PRE_WEEK, "visit");
//日同比
Integer dayRate = CrmebUtil.getRate(today, yesterday);
BigDecimal dayRate = CrmebUtil.getRateBig(today, yesterday);
//周同比
Integer weekRate = CrmebUtil.getRate(week, preWeek);
BigDecimal weekRate = CrmebUtil.getRateBig(week, preWeek);
//总访问量
Integer all = storeProductLogService.getCountByTimeAndType(Constants.SEARCH_DATE_MONTH, "visit");

View File

@@ -75,77 +75,25 @@ public class RetailShopController {
public CommonResult<CommonPage<RetailShopUserResponse>> getList(@RequestParam(required = false) String keywords,
@RequestParam(required = false) String dateLimit,
@ModelAttribute PageParamRequest pageParamRequest){
PageInfo<RetailShopUserResponse> rsup = retailShopService.getList(keywords,dateLimit,pageParamRequest);
return CommonResult.success(CommonPage.restPage(rsup));
return CommonResult.success(retailShopService.getList(keywords,dateLimit,pageParamRequest));
}
/**
* 分销头部信息
* @param nickName
* @param dateLimit
* @param keywords 搜索参数
* @param dateLimit 时间参数
* @return
*/
@ApiOperation(value = "分销头部数据")
@RequestMapping(value = "/statistics", method = RequestMethod.GET)
@ApiImplicitParams({
@ApiImplicitParam(name = "nickName", value = "昵称"),
@ApiImplicitParam(name = "keywords", value = "搜索参数"),
@ApiImplicitParam(name = "dateLimit", value = "today,yesterday,lately7,lately30,month,year,/yyyy-MM-dd hh:mm:ss,yyyy-MM-dd hh:mm:ss/")
})
public CommonResult<Object> getStatistics(@RequestParam(required = false) String nickName,
public CommonResult<RetailShopStatisticsResponse> getStatistics(@RequestParam(required = false) String keywords,
@RequestParam(required = false) String dateLimit){
List<RetailShopStatisticsResponse> resultList = new ArrayList<>();
// 获取分销人数
List<UserResponse> userResponseList = retailShopService.getStatisticsData(nickName, dateLimit);
// 发展会员人数
RetailShopStatisticsResponse spreadCount = new RetailShopStatisticsResponse("发展会员人数",0);
// 订单总数
RetailShopStatisticsResponse orderCount = new RetailShopStatisticsResponse("订单总数",0);
// 订单金额
RetailShopStatisticsResponse orderPrice = new RetailShopStatisticsResponse("订单金额",0);
// 可提现金额
RetailShopStatisticsResponse cashMoney = new RetailShopStatisticsResponse("可提现金额",0);
// 提现次数
RetailShopStatisticsResponse cashCount = new RetailShopStatisticsResponse("提现次数",0);
// 未提现金额
RetailShopStatisticsResponse maxCashCount = new RetailShopStatisticsResponse("未提现金额",0);
List<Integer> ids = userResponseList.stream().map(UserResponse::getUid).distinct().collect(Collectors.toList());
if(userResponseList.size() > 0){
spreadCount.setCount(userService.getSpreadPeopleIdList(ids).size());
List<StoreOrder> storeOrders = storeOrderService.getOrderByUserIdsForRetailShop(ids);
orderCount.setCount(storeOrders.size());
BigDecimal payPrice = new BigDecimal("0");
for (StoreOrder so: storeOrders) {
payPrice.add(so.getPayPrice());
}
orderPrice.setCount(payPrice.intValue());
List<User> userList = userService.getSpreadPeopleList(ids);
BigDecimal cashTotalPrice = new BigDecimal("0");
BigDecimal canCashTotalPrice = new BigDecimal("0");
for(User user: userList){
cashTotalPrice.add(user.getBrokeragePrice());
canCashTotalPrice.add(user.getBrokeragePrice());//todo 待统一
}
cashMoney.setCount(cashTotalPrice.intValue());
cashCount.setCount(userExtractService.getListByUserIds(ids).size());
maxCashCount.setCount(canCashTotalPrice.intValue());
}
// 组装结果数据
resultList.add(new RetailShopStatisticsResponse("分销人员人数(人)",userResponseList.size()));
resultList.add(spreadCount);
resultList.add(orderCount);
resultList.add(orderPrice);
resultList.add(cashMoney);
resultList.add(cashCount);
resultList.add(maxCashCount);
return CommonResult.success(resultList);
return CommonResult.success(retailShopService.getAdminStatistics(keywords, dateLimit));
}
/**

View File

@@ -13,7 +13,10 @@ import com.zbkj.crmeb.store.response.StoreStaffDetail;
import com.zbkj.crmeb.store.response.StoreStaffTopDetail;
import com.zbkj.crmeb.store.service.StoreOrderService;
import com.zbkj.crmeb.store.service.StoreOrderVerification;
import io.swagger.annotations.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -163,19 +166,20 @@ public class StoreOrderController {
}
/**
* 退款
* 拒绝退款
* @param id Integer 订单id
* @param reason String 原因
* @author Mr.Zhang
* @since 2020-05-28
*/
@ApiOperation(value = "拒绝退款")
@RequestMapping(value = "/refund/refuse", method = RequestMethod.GET)
public CommonResult<Boolean> refundRefuse(@RequestParam Integer id, @RequestParam String reason){
public CommonResult<Object> refundRefuse(@RequestParam Integer id, @RequestParam String reason){
if(StringUtils.isBlank(reason)){
CommonResult.validateFailed("请填写退款原因");
}
return CommonResult.success(storeOrderService.refundRefuse(id, reason));
if (storeOrderService.refundRefuse(id, reason)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
@@ -202,7 +206,7 @@ public class StoreOrderController {
}
/**
* 核销订单头部数据
* 核销订单 月列表数据
* @author stivepeim
* @since 2020-08-29
*/
@@ -226,7 +230,7 @@ public class StoreOrderController {
}
/**
* 核销码核销订单
* 核销码查询待核销订单
* @author stivepeim
* @since 2020-09-01
*/

View File

@@ -93,13 +93,10 @@ public class StoreOrder implements Serializable {
@ApiModelProperty(value = "创建时间")
private Date createTime;
// @ApiModelProperty(value = "创建时间") todo ZL
// private String day;
@ApiModelProperty(value = "订单状态(-1 : 申请退款 -2 : 退货成功 0待发货1待收货2已收货待评价3已完成")
@ApiModelProperty(value = "订单状态0待发货1待收货2已收货待评价3已完成")
private Integer status;
@ApiModelProperty(value = "0 未退款 1 申请中 2 已退款")
@ApiModelProperty(value = "0 未退款 1 申请中 2 已退款 3 退款中")
private Integer refundStatus;
@ApiModelProperty(value = "退款图片")
@@ -108,15 +105,15 @@ public class StoreOrder implements Serializable {
@ApiModelProperty(value = "退款用户说明")
private String refundReasonWapExplain;
@ApiModelProperty(value = "退款时间")
private Date refundReasonTime;
@ApiModelProperty(value = "前台退款原因")
private String refundReasonWap;
@ApiModelProperty(value = "不退款的理由")
private String refundReason;
@ApiModelProperty(value = "退款时间")
private Date refundReasonTime;
@ApiModelProperty(value = "退款金额")
private BigDecimal refundPrice;
@@ -183,8 +180,8 @@ public class StoreOrder implements Serializable {
@ApiModelProperty(value = "店员id")
private Integer clerkId;
@ApiModelProperty(value = "支付渠道(0微信公众号1微信小程序)")
private int isChannel;
@ApiModelProperty(value = "支付渠道(0-微信公众号,1-微信小程序,2-H5,3-余额)")
private Integer isChannel;
@ApiModelProperty(value = "消息提醒")
private Boolean isRemind;
@@ -192,6 +189,9 @@ public class StoreOrder implements Serializable {
@ApiModelProperty(value = "后台是否删除")
private Boolean isSystemDel;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
@ApiModelProperty(value = "快递公司简称")
private String deliveryCode;
}

View File

@@ -119,7 +119,7 @@ public class StoreProduct implements Serializable {
private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;

View File

@@ -89,4 +89,7 @@ public class StoreProductReply implements Serializable {
@ApiModelProperty(value = "更新时间")
private Date updateTime;
@ApiModelProperty(value = "商品规格属性值")
private String sku;
}

View File

@@ -6,6 +6,7 @@ import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* 推广列表参数
@@ -31,6 +32,7 @@ public class RetailShopStairUserRequest {
// 类型 0 = 全部 1=一级推广人 2=二级推广人
@ApiModelProperty(value = "类型 0 = 全部 1=一级推广人 2=二级推广人")
@NotNull(message = "推广人类型不能为空")
@Range(min = 0, max = 3, message = "请选择正确的用户类型")
private Integer type;

View File

@@ -38,8 +38,4 @@ public class StoreOrderRefundRequest {
@DecimalMin(value = "0.00", message = "退款金额不能少于0.00")
private BigDecimal amount;
@ApiModelProperty(value = "status 1 = 直接退款, 2 = 退款后,返回原状态", allowableValues = "range[1,2]")
@Range(min = 1, max = 2, message = "请选择退款状态 1 = 直接退款, 2 = 退款后,返回原状态")
private int type;
}

View File

@@ -31,18 +31,18 @@ import java.util.Date;
public class StoreOrderRequest {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "订单总价")
private BigDecimal totalPrice;
@ApiModelProperty(value = "邮费")
private BigDecimal totalPostage;
// @ApiModelProperty(value = "订单总价")
// private BigDecimal totalPrice;
//
// @ApiModelProperty(value = "邮费")
// private BigDecimal totalPostage;
@ApiModelProperty(value = "实际支付金额")
private BigDecimal payPrice;
@ApiModelProperty(value = "支付邮费")
private BigDecimal payPostage;
// @ApiModelProperty(value = "支付邮费")
// private BigDecimal payPostage;
@ApiModelProperty(value = "消费赚取积分")
private BigDecimal gainIntegral;
private Integer gainIntegral;
}

View File

@@ -65,4 +65,7 @@ public class StoreProductReplyAddRequest implements Serializable {
@ApiModelProperty(value = "评论人昵称 [虚拟评论参数]")
private String nickname;
@ApiModelProperty(value = "商品规格属性值,多规格时用英文逗号拼接")
private String sku;
}

View File

@@ -126,7 +126,7 @@ public class StoreProductRequest implements Serializable {
private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;

View File

@@ -1,9 +1,15 @@
package com.zbkj.crmeb.store.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 分销头部数据Response
* 分销统计响应对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
@@ -15,16 +21,39 @@ import lombok.Data;
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="RetailShopStatisticsResponse", description="分销统计响应对象")
public class RetailShopStatisticsResponse {
public RetailShopStatisticsResponse() {
}
public RetailShopStatisticsResponse(String name, Integer count) {
this.name = name;
this.count = count;
}
@ApiModelProperty(value = "分销人员人数")
private Integer distributionNum;
private String name;
private Integer count;
// private String className;
@ApiModelProperty(value = "发展会员人数")
private Integer developNum;
@ApiModelProperty(value = "订单总数")
private Integer orderNum;
@ApiModelProperty(value = "订单金额(元)")
private BigDecimal orderPriceCount;
@ApiModelProperty(value = "提现次数")
private Integer withdrawCount;
@ApiModelProperty(value = "未提现金额(元)")
private BigDecimal noWithdrawPrice;
public RetailShopStatisticsResponse() {}
public RetailShopStatisticsResponse(Integer distributionNum, Integer developNum,
Integer orderNum, BigDecimal orderPriceCount,
Integer withdrawCount, BigDecimal noWithdrawPrice) {
this.distributionNum = distributionNum;
this.developNum = developNum;
this.orderNum = orderNum;
this.orderPriceCount = orderPriceCount;
this.withdrawCount = withdrawCount;
this.noWithdrawPrice = noWithdrawPrice;
}
}

View File

@@ -29,7 +29,7 @@ public class RetailShopUserResponse {
public RetailShopUserResponse() {
}
public RetailShopUserResponse(Integer uid, String account, String pwd, String realName, String birthday, String cardId, String mark, Integer partnerId, Integer groupId, String groupName, String tagName, String nickname, String avatar, String phone, String addIp, String lastIp, BigDecimal nowMoney, BigDecimal brokeragePrice, BigDecimal integral, Integer experience, Integer signNum, Boolean status, Integer level, Integer spreadUid, Date spreadTime, String spreadNickname, String userType, Boolean isPromoter, Integer payCount, Integer spreadCount, String addres, Integer adminid, String loginType, Date updateTime, Date createTime, Date lastLoginTime, Date cleanTime, UserExtractResponse userExtractResponse, RetailShopOrderDataResponse retailShopOrderDataResponse) {
public RetailShopUserResponse(Integer uid, String account, String pwd, String realName, String birthday, String cardId, String mark, Integer partnerId, Integer groupId, String groupName, String tagName, String nickname, String avatar, String phone, String addIp, String lastIp, BigDecimal nowMoney, BigDecimal brokeragePrice, Integer integral, Integer experience, Integer signNum, Boolean status, Integer level, Integer spreadUid, Date spreadTime, String spreadNickname, String userType, Boolean isPromoter, Integer payCount, Integer spreadCount, String addres, Integer adminid, String loginType, Date updateTime, Date createTime, Date lastLoginTime, Date cleanTime, UserExtractResponse userExtractResponse, RetailShopOrderDataResponse retailShopOrderDataResponse) {
this.uid = uid;
this.account = account;
this.pwd = pwd;
@@ -128,7 +128,7 @@ public class RetailShopUserResponse {
private BigDecimal brokeragePrice;
@ApiModelProperty(value = "用户剩余积分")
private BigDecimal integral;
private Integer integral;
@ApiModelProperty(value = "用户剩余经验")
private Integer experience;

View File

@@ -81,10 +81,15 @@ public class StoreCartResponse implements Serializable {
private Boolean attrStatus;
// todo 价格计算有问题
// 真实价格
private BigDecimal truePrice;
// 会员价格
private BigDecimal vipTruePrice;
// 真实库存
private Integer trueStock;
// 原价
private BigDecimal costPrice;
private Integer isReply;
private String addTime;

View File

@@ -125,13 +125,13 @@ public class StoreOrderCreateResponse {
private String deliveryId;
@ApiModelProperty(value = "消费赚取积分")
private BigDecimal gainIntegral;
private Integer gainIntegral;
@ApiModelProperty(value = "使用积分")
private BigDecimal useIntegral;
private Integer useIntegral;
@ApiModelProperty(value = "给用户退了多少积分")
private BigDecimal backIntegral;
private Integer backIntegral;
@ApiModelProperty(value = "备注")
private String mark;

View File

@@ -133,13 +133,13 @@ public class StoreOrderInfoResponse implements Serializable {
private String deliveryId;
@ApiModelProperty(value = "消费赚取积分")
private BigDecimal gainIntegral;
private Integer gainIntegral;
@ApiModelProperty(value = "使用积分")
private BigDecimal useIntegral;
private Integer useIntegral;
@ApiModelProperty(value = "给用户退了多少积分")
private BigDecimal backIntegral;
private Integer backIntegral;
@ApiModelProperty(value = "备注")
private String mark;

View File

@@ -128,13 +128,13 @@ public class StoreOrderListResponse implements Serializable {
private String deliveryId;
@ApiModelProperty(value = "消费赚取积分")
private BigDecimal gainIntegral;
private Integer gainIntegral;
@ApiModelProperty(value = "使用积分")
private BigDecimal useIntegral;
private Integer useIntegral;
@ApiModelProperty(value = "给用户退了多少积分")
private BigDecimal backIntegral;
private Integer backIntegral;
@ApiModelProperty(value = "备注")
private String mark;

View File

@@ -84,76 +84,22 @@ public class StoreProductCartProductInfoResponse implements Serializable {
@ApiModelProperty(value = "库存")
private Integer stock;
//
// @ApiModelProperty(value = "状态0未上架1上架")
// private Boolean isShow;
//
// @ApiModelProperty(value = "是否热卖")
// private Boolean isHot;
//
// @ApiModelProperty(value = "是否优惠")
// private Boolean isBenefit;
//
// @ApiModelProperty(value = "是否精品")
// private Boolean isBest;
//
// @ApiModelProperty(value = "是否新品")
// private Boolean isNew;
//
// @ApiModelProperty(value = "添加时间")
// private Integer addTime;
@ApiModelProperty(value = "是否包邮")
private Boolean isPostage;
// @ApiModelProperty(value = "是否删除")
// private Boolean isDel;
//
// @ApiModelProperty(value = "商户是否代理 0不可代理1可代理")
// private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;
// @ApiModelProperty(value = "秒杀状态 0 未开启 1已开启")
// private Boolean isSeckill;
//
// @ApiModelProperty(value = "砍价状态 0未开启 1开启")
// private Boolean isBargain;
//
// @ApiModelProperty(value = "是否优品推荐")
// private Boolean isGood;
@ApiModelProperty(value = "是否单独分佣")
private Boolean isSub;
// @ApiModelProperty(value = "虚拟销量")˚
// private Integer ficti;
//
// @ApiModelProperty(value = "浏览量")
// private Integer browse;
//
// @ApiModelProperty(value = "商品二维码地址(用户小程序海报)")
// private String codePath;
//
// @ApiModelProperty(value = "淘宝京东1688类型")
// private String soureLink;
//
// @ApiModelProperty(value = "主图视频链接")
// private String videoLink;
@ApiModelProperty(value = "运费模板ID")
private Integer tempId;
// @ApiModelProperty(value = "规格 0单 1多")
// private Boolean specType;
//
// @ApiModelProperty(value = "活动显示排序1=秒杀2=砍价3=拼团")
// private String activity;
@ApiModelProperty(value = "sku详情")
private StoreProductAttrValue attrInfo;
}

View File

@@ -77,5 +77,8 @@ public class StoreProductReplyResponse {
@ApiModelProperty(value = "更新时间")
private Date updateTime;
@ApiModelProperty(value = "商品规格属性值")
private String sku;
private StoreProduct storeProduct;
}

View File

@@ -50,23 +50,20 @@ public class StoreProductResponse implements Serializable {
return activity;
}else{
List<Integer> activityValue = CrmebUtil.stringToArrayInt(activity);
activityValue.stream().map(e->{
switch (e){
case Constants.PRODUCT_TYPE_NORMAL:
_activity.add(Constants.PRODUCT_TYPE_NORMAL_STR);
break;
case Constants.PRODUCT_TYPE_SECKILL:
_activity.add(Constants.PRODUCT_TYPE_SECKILL_STR);
break;
case Constants.PRODUCT_TYPE_BARGAIN:
_activity.add(Constants.PRODUCT_TYPE_BARGAIN_STR);
break;
case Constants.PRODUCT_TYPE_PINGTUAN:
_activity.add(Constants.PRODUCT_TYPE_PINGTUAN_STR);
break;
activityValue.forEach(e->{
if (e.equals(Constants.PRODUCT_TYPE_NORMAL)) {
_activity.add(Constants.PRODUCT_TYPE_NORMAL_STR);
}
return e;
}).collect(Collectors.toList());
if (e.equals(Constants.PRODUCT_TYPE_SECKILL)) {
_activity.add(Constants.PRODUCT_TYPE_SECKILL_STR);
}
if (e.equals(Constants.PRODUCT_TYPE_BARGAIN)) {
_activity.add(Constants.PRODUCT_TYPE_BARGAIN_STR);
}
if (e.equals(Constants.PRODUCT_TYPE_PINGTUAN)) {
_activity.add(Constants.PRODUCT_TYPE_PINGTUAN_STR);
}
});
}
this.setActivityStr(String.join(",",_activity));
return activity;
@@ -155,7 +152,7 @@ public class StoreProductResponse implements Serializable {
private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;

View File

@@ -107,7 +107,7 @@ public class StoreProductStoreInfoResponse implements Serializable {
private Boolean merUse;
@ApiModelProperty(value = "获得积分")
private BigDecimal giveIntegral;
private Integer giveIntegral;
@ApiModelProperty(value = "成本价")
private BigDecimal cost;

Some files were not shown because too many files have changed in this diff Show More