diff --git a/crmeb/src/main/java/com/constants/Constants.java b/crmeb/src/main/java/com/constants/Constants.java index 0172fa3e..49393c1a 100644 --- a/crmeb/src/main/java/com/constants/Constants.java +++ b/crmeb/src/main/java/com/constants/Constants.java @@ -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"; diff --git a/crmeb/src/main/java/com/constants/OnePassConstants.java b/crmeb/src/main/java/com/constants/OnePassConstants.java index fbbd90de..ae55ea77 100644 --- a/crmeb/src/main/java/com/constants/OnePassConstants.java +++ b/crmeb/src/main/java/com/constants/OnePassConstants.java @@ -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"; diff --git a/crmeb/src/main/java/com/constants/PayConstants.java b/crmeb/src/main/java/com/constants/PayConstants.java new file mode 100644 index 00000000..d843b6da --- /dev/null +++ b/crmeb/src/main/java/com/constants/PayConstants.java @@ -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 + * +---------------------------------------------------------------------- + */ +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"; +} diff --git a/crmeb/src/main/java/com/utils/CrmebUtil.java b/crmeb/src/main/java/com/utils/CrmebUtil.java index bbad6991..e7f153e3 100644 --- a/crmeb/src/main/java/com/utils/CrmebUtil.java +++ b/crmeb/src/main/java/com/utils/CrmebUtil.java @@ -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参数 diff --git a/crmeb/src/main/java/com/utils/DateUtil.java b/crmeb/src/main/java/com/utils/DateUtil.java index ac4f4a42..dd88c402 100644 --- a/crmeb/src/main/java/com/utils/DateUtil.java +++ b/crmeb/src/main/java/com/utils/DateUtil.java @@ -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; } } diff --git a/crmeb/src/main/java/com/utils/WXPayXmlUtil.java b/crmeb/src/main/java/com/utils/WXPayXmlUtil.java new file mode 100644 index 00000000..24796737 --- /dev/null +++ b/crmeb/src/main/java/com/utils/WXPayXmlUtil.java @@ -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 + * +---------------------------------------------------------------------- + */ +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(); + } +} diff --git a/crmeb/src/main/java/com/utils/WxPayUtil.java b/crmeb/src/main/java/com/utils/WxPayUtil.java index 6d956bba..4756f00e 100644 --- a/crmeb/src/main/java/com/utils/WxPayUtil.java +++ b/crmeb/src/main/java/com/utils/WxPayUtil.java @@ -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 map = JSONObject.parseObject(JSONObject.toJSONString(vo), Map.class); + // map排序 + Set 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 map = JSONObject.parseObject(JSONObject.toJSONString(wxRefundVo), Map.class); + // map排序 + Set 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 map, String signKey) { + // map排序 + Set 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 xmlToMap(String strXML) throws Exception { + try { + Map data = new HashMap(); + 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; + } + + } } diff --git a/crmeb/src/main/java/com/utils/XmlUtil.java b/crmeb/src/main/java/com/utils/XmlUtil.java index 24a4bbf0..2b1797c4 100644 --- a/crmeb/src/main/java/com/utils/XmlUtil.java +++ b/crmeb/src/main/java/com/utils/XmlUtil.java @@ -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 - * +---------------------------------------------------------------------- + * XML 工具类 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- */ public class XmlUtil { - public static Map xmlToMap(HttpServletRequest request) - { - Map map = new HashMap<>(); + public static Map xmlToMap(HttpServletRequest request) { + Map 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 xmlToMap(String strxml)throws Exception{ + public static HashMap xmlToMap(String strxml) throws Exception { strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); - HashMap map = new HashMap<>(); + HashMap 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 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 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; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/article/request/ArticleSearchRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/article/request/ArticleSearchRequest.java index 5a21ef51..c17b189e 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/article/request/ArticleSearchRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/article/request/ArticleSearchRequest.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/bargain/model/StoreBargain.java b/crmeb/src/main/java/com/zbkj/crmeb/bargain/model/StoreBargain.java index 67a3bb49..1e2ad892 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/bargain/model/StoreBargain.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/bargain/model/StoreBargain.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/bargain/request/StoreBargainRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/bargain/request/StoreBargainRequest.java index 5a61e73e..6707994f 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/bargain/request/StoreBargainRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/bargain/request/StoreBargainRequest.java @@ -99,7 +99,7 @@ public class StoreBargainRequest implements Serializable { private Boolean status; @ApiModelProperty(value = "反多少积分") - private BigDecimal giveIntegral; + private Integer giveIntegral; @ApiModelProperty(value = "砍价活动简介") @NotBlank(message = "砍价活动简介不能为空") diff --git a/crmeb/src/main/java/com/zbkj/crmeb/bargain/response/StoreBargainResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/bargain/response/StoreBargainResponse.java index 94489c2c..43406d69 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/bargain/response/StoreBargainResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/bargain/response/StoreBargainResponse.java @@ -78,7 +78,7 @@ public class StoreBargainResponse { private Boolean status; @ApiModelProperty(value = "反多少积分") - private BigDecimal giveIntegral; + private Integer giveIntegral; @ApiModelProperty(value = "砍价活动简介") private String info; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/StoreBargainService.java b/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/StoreBargainService.java index 70d876fe..5b40a2ff 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/StoreBargainService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/StoreBargainService.java @@ -31,103 +31,82 @@ public interface StoreBargainService extends IService { /** * 分页显示砍价商品列表 - * @param request - * @param pageParamRequest - * @return */ PageInfo 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 getH5List(PageParamRequest pageParamRequest); /** * H5 获取查看、分享、参与人数 - * @param id - * @return + * @param id BargainDetailResponse */ Map getH5Share(Integer id); /** * H5 获取砍价商品详情信息 - * @param id - * @return + * @return BargainDetailResponse */ BargainDetailResponse getH5Detail(Integer id); /** * 获取当前时间的砍价商品 - * @param productId - * @return + * @return List */ List getCurrentBargainByProductId(Integer productId); /** * 参与砍价活动 - * @param bargainFrontRequest - * @return + * @return Boolean */ Boolean start(BargainFrontRequest bargainFrontRequest); /** * 砍价商品根据实体查询 - * @param storeBargainParam - * @return + * @return Boolean */ List 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 { * @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); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/impl/StoreBargainServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/impl/StoreBargainServiceImpl.java index 6aa016fd..c24b3e0c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/impl/StoreBargainServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/bargain/service/impl/StoreBargainServiceImpl.java @@ -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 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 currentProAttrValues = storeProductAttrValueService.getListByProductId(productId); + List 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 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 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 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 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/category/model/Category.java b/crmeb/src/main/java/com/zbkj/crmeb/category/model/Category.java index 1b3c2b22..80c36aa5 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/category/model/Category.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/category/model/Category.java @@ -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 = "排序") diff --git a/crmeb/src/main/java/com/zbkj/crmeb/category/request/CategorySearchRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/category/request/CategorySearchRequest.java index 3220eed9..2f3a8289 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/category/request/CategorySearchRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/category/request/CategorySearchRequest.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/category/service/impl/CategoryServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/category/service/impl/CategoryServiceImpl.java index 8a6cc79f..b5383a3b 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/category/service/impl/CategoryServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/category/service/impl/CategoryServiceImpl.java @@ -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 impl public List getList(CategorySearchRequest request, PageParamRequest pageParamRequest) { PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()); LambdaQueryWrapper 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 impl */ @Override public List getListTree(Integer type, Integer status, List 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 impl list.add(tree); } } + System.out.println("无限极分类 : getTree:" + JSON.toJSONString(list)); return list; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/controller/StoreCombinationController.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/controller/StoreCombinationController.java index a0c2e6f2..cfd6c24c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/combination/controller/StoreCombinationController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/controller/StoreCombinationController.java @@ -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> getPinkList(@PathVariable(value = "id") Integer id) { + public CommonResult> getPinkList(@PathVariable(value = "id") Integer id) { return CommonResult.success(storePinkService.getAdminList(id)); } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/response/StorePinkDetailResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/response/StorePinkDetailResponse.java new file mode 100644 index 00000000..9bd809c6 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/response/StorePinkDetailResponse.java @@ -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 + * +---------------------------------------------------------------------- + */ +@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; + +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StoreCombinationService.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StoreCombinationService.java index 3dbe38f3..e333ef67 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StoreCombinationService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StoreCombinationService.java @@ -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 { /** * 扣减库存加销量 - * @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 { * @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); } \ No newline at end of file diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StorePinkService.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StorePinkService.java index 5ffff392..4b66f207 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StorePinkService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/StorePinkService.java @@ -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 { * @param pinkId 团长pinkId * @return */ - List getAdminList(Integer pinkId); + List getAdminList(Integer pinkId); /** * 查询拼团列表 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StoreCombinationServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StoreCombinationServiceImpl.java index 29b3ebb0..e57c7f04 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StoreCombinationServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StoreCombinationServiceImpl.java @@ -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 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 attrvalues = storeProductAttrValueService.getByEntity(spavPram); + if(CollUtil.isEmpty(attrvalues)) throw new CrmebException("未找到相关商品属性信息"); + StoreProductAttrValue combinationAttrValue = attrvalues.get(0); + // 对应的主商品sku + List currentProAttrValues = storeProductAttrValueService.getListByProductId(productId); + List 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 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 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 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 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StorePinkServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StorePinkServiceImpl.java index 3a46c493..09a920e1 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StorePinkServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/combination/service/impl/StorePinkServiceImpl.java @@ -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 i * @return */ @Override - public List getAdminList(Integer pinkId) { + public List getAdminList(Integer pinkId) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(StorePink::getId, pinkId).or().eq(StorePink::getKId, pinkId); lqw.orderByDesc(StorePink::getId); List pinkList = dao.selectList(lqw); // 将拼团状态提换为订单状态 - pinkList.forEach(i -> { - StoreOrder storeOrder = storeOrderService.getByOderId(i.getOrderId()); + List 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 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/config/WebConfig.java b/crmeb/src/main/java/com/zbkj/crmeb/config/WebConfig.java index 7d3fe59d..dac20b34 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/config/WebConfig.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/config/WebConfig.java @@ -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/*"). diff --git a/crmeb/src/main/java/com/zbkj/crmeb/export/service/impl/ExcelServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/export/service/impl/ExcelServiceImpl.java index 598e393e..cc96b930 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/export/service/impl/ExcelServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/export/service/impl/ExcelServiceImpl.java @@ -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", "成团数量"); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/export/vo/BargainProductExcelVo.java b/crmeb/src/main/java/com/zbkj/crmeb/export/vo/BargainProductExcelVo.java index 3f27f154..d90ca372 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/export/vo/BargainProductExcelVo.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/export/vo/BargainProductExcelVo.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/export/vo/CombinationProductExcelVo.java b/crmeb/src/main/java/com/zbkj/crmeb/export/vo/CombinationProductExcelVo.java index 2a486250..53d8a0bb 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/export/vo/CombinationProductExcelVo.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/export/vo/CombinationProductExcelVo.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/express/controller/ExpressController.java b/crmeb/src/main/java/com/zbkj/crmeb/express/controller/ExpressController.java index a8ccd7b2..cce049a1 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/express/controller/ExpressController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/express/controller/ExpressController.java @@ -107,7 +107,7 @@ public class ExpressController { public CommonResult 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)); } } + + + diff --git a/crmeb/src/main/java/com/zbkj/crmeb/express/service/ExpressService.java b/crmeb/src/main/java/com/zbkj/crmeb/express/service/ExpressService.java index bc2cdb2b..f15e0307 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/express/service/ExpressService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/express/service/ExpressService.java @@ -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 * +---------------------------------------------------------------------- - */ +*/ public interface ExpressService extends IService { /** - * 列表 - * @param request 搜索条件 - * @param pageParamRequest 分页类参数 - * @author Mr.Zhang - * @since 2020-04-17 - * @return List - */ + * 列表 + * @param request 搜索条件 + * @param pageParamRequest 分页类参数 + * @author Mr.Zhang + * @since 2020-04-17 + * @return List + */ List getList(ExpressSearchRequest request, PageParamRequest pageParamRequest); Express info(Integer id); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/ExpressServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/ExpressServiceImpl.java index e11763a4..188ee46d 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/ExpressServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/ExpressServiceImpl.java @@ -45,7 +45,7 @@ import java.util.stream.Collectors; * +---------------------------------------------------------------------- * | Author: CRMEB Team * +---------------------------------------------------------------------- - */ +*/ @Service public class ExpressServiceImpl extends ServiceImpl implements ExpressService { @@ -271,3 +271,4 @@ public class ExpressServiceImpl extends ServiceImpl impleme public static String st = "mnc7Yay0RsvF70LWX7i6k"; public static String sk = "¥bugJEjOmF01hxGr~qj5"; } + diff --git a/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/LogisticsServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/LogisticsServiceImpl.java index c71fc33e..7041c5d4 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/LogisticsServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/express/service/impl/LogisticsServiceImpl.java @@ -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 * +---------------------------------------------------------------------- - */ +*/ @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 { } } } + diff --git a/crmeb/src/main/java/com/zbkj/crmeb/express/vo/LogisticsResultVo.java b/crmeb/src/main/java/com/zbkj/crmeb/express/vo/LogisticsResultVo.java index 35daad71..cf753eec 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/express/vo/LogisticsResultVo.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/express/vo/LogisticsResultVo.java @@ -36,7 +36,7 @@ public class LogisticsResultVo { @ApiModelProperty(value = "快递运送轨迹") private List 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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/finance/service/impl/UserExtractServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/finance/service/impl/UserExtractServiceImpl.java index 5bafab19..0546d029 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/finance/service/impl/UserExtractServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/finance/service/impl/UserExtractServiceImpl.java @@ -118,10 +118,6 @@ public class UserExtractServiceImpl extends ServiceImpl> share(){ return CommonResult.success(indexService.getShareConfig()); } + + /** + * 公共配置 云智服 + * @return 公共配置 + */ + @ApiOperation(value = "公共配置") + @RequestMapping(value = "/config", method = RequestMethod.GET) + public CommonResult> getConfig(){ + return CommonResult.success(indexService.getCommConfig()); + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/controller/PayController.java b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/PayController.java new file mode 100644 index 00000000..aeb43016 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/PayController.java @@ -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 + * +---------------------------------------------------------------------- + */ +@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 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 queryPayResult(@RequestParam String orderNo) { + return CommonResult.success(weChatPayService.queryPayResult(orderNo)); + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/controller/StoreOrderController.java b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/StoreOrderController.java index 5587a245..cdce04f8 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/controller/StoreOrderController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/StoreOrderController.java @@ -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 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 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 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> 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 refundVerify(@RequestBody @Validated OrderRefundVerifyRequest request){ - return CommonResult.success(orderService.refundVerify(request)); - } - /** * 订单退款申请 * @param request OrderRefundApplyRequest 订单id diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/controller/UserController.java b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/UserController.java index deef33e1..9104e431 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/controller/UserController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/controller/UserController.java @@ -322,7 +322,7 @@ public class UserController { */ @ApiOperation(value = "推广人排行") @RequestMapping(value = "rank", method = RequestMethod.GET) - public CommonResult> getTopSpreadPeopleListByDate(@RequestParam String type, @Validated PageParamRequest pageParamRequest){ + public CommonResult> getTopSpreadPeopleListByDate(@RequestParam(required = false) String type, @Validated PageParamRequest pageParamRequest){ return CommonResult.success(userCenterService.getTopSpreadPeopleListByDate(type, pageParamRequest)); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/request/ConfirmOrderRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/front/request/ConfirmOrderRequest.java new file mode 100644 index 00000000..7ffe1754 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/request/ConfirmOrderRequest.java @@ -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 + * +---------------------------------------------------------------------- + */ +@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; +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderAgainRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderAgainRequest.java index 55408a85..dc8a3f6d 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderAgainRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderAgainRequest.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderCreateRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderCreateRequest.java index 68c3efa2..e29021ff 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderCreateRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderCreateRequest.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderPayRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderPayRequest.java index 8915b21a..b8e99467 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderPayRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderPayRequest.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderRefundApplyRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderRefundApplyRequest.java index 08777198..f7be7489 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderRefundApplyRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/request/OrderRefundApplyRequest.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/response/ConfirmOrderResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/front/response/ConfirmOrderResponse.java index 1dfb5dc1..ab4db27c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/response/ConfirmOrderResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/response/ConfirmOrderResponse.java @@ -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 cartInfo; - // 价格集合 -// private HashMap priceGroup; + + @ApiModelProperty(value = "价格集合") private PriceGroupResponse priceGroup; + @ApiModelProperty(value = "其他") private HashMap 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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/response/OrderPayResultResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/front/response/OrderPayResultResponse.java new file mode 100644 index 00000000..3621c15d --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/response/OrderPayResultResponse.java @@ -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 + * +---------------------------------------------------------------------- + */ +@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; +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/response/PriceGroupResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/front/response/PriceGroupResponse.java index 0916677d..53f01f0a 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/response/PriceGroupResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/response/PriceGroupResponse.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/response/StoreOrderDetailResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/front/response/StoreOrderDetailResponse.java index 29b69e82..931473da 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/response/StoreOrderDetailResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/response/StoreOrderDetailResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/response/UserSignInfoResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/front/response/UserSignInfoResponse.java index b70145ba..d3067430 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/response/UserSignInfoResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/response/UserSignInfoResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/IndexService.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/IndexService.java index 51f3c440..c408454c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/IndexService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/IndexService.java @@ -27,4 +27,10 @@ public interface IndexService{ List> hotKeywords(); HashMap getShareConfig(); + + /** + * 获取公共配置 + * @return 公共配置 + */ + HashMap getCommConfig(); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/OrderService.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/OrderService.java index 226f9140..937c08fd 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/OrderService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/OrderService.java @@ -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 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 applyList); - - /** - * 订单退款前验证 - * @param request 退款参数 - */ - boolean refundVerify(OrderRefundVerifyRequest request); + Boolean refundApplyTask(List applyList); /** * 订单物流查看 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/IndexServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/IndexServiceImpl.java index 40a3f6d0..f006b46e 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/IndexServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/IndexServiceImpl.java @@ -213,5 +213,17 @@ public class IndexServiceImpl implements IndexService { map.put("synopsis", info.get("wechat_share_synopsis")); return map; } + + /** + * 获取公共配置 + * + * @return 公共配置 + */ + @Override + public HashMap getCommConfig() { + HashMap result = new HashMap<>(); + result.put("yzfUrl", systemConfigService.getValueByKey(Constants.CONFIG_KEY_YZF_H5_URL)); + return result; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/OrderServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/OrderServiceImpl.java index 8893f066..c5fad540 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/OrderServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/OrderServiceImpl.java @@ -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 cartIds, boolean isNew, boolean addAgain,boolean seckill, boolean bargain, boolean combination, Integer addressId) { - ConfirmOrderResponse response = new ConfirmOrderResponse(); + public ConfirmOrderResponse confirmOrder(ConfirmOrderRequest request) { + List 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; // 再次下单、秒杀、砍价、拼团 - 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 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 cartInfo = cor.getCartInfo(); + List cartList = cartInfo.stream().filter(i -> ObjectUtil.isNotNull(i.getId())).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(cartList)) { + List 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 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 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 applyList) { + public Boolean refundApplyTask(List 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 againOrder(OrderAgainRequest request) { - // 检查是否已经有相同的商品再次下单 -// StoreCartResponse cacheOrderAgain = orderUtils.getCacheOrderAgain(request.getNui()); -// if(null != cacheOrderAgain) throw new CrmebException("已经有相同的订单存在"); - + User currentUser = userService.getInfoException(); HashMap 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 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 resultMap, StoreOrder existStoreOrder) { - existStoreOrder.setPayType(request.getPaytype()); + existStoreOrder.setPayType(request.getPayType()); CreateOrderResponseVo orderPayResult = orderPayService.payOrder(existStoreOrder.getId(), request.getFrom(), ip); // 下面组装前端所需数据 switch (existStoreOrder.getPayType()){ diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/ProductServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/ProductServiceImpl.java index 32d069cb..f5ee798f 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/ProductServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/ProductServiceImpl.java @@ -140,7 +140,16 @@ public class ProductServiceImpl implements ProductService { */ @Override public List getCategory() { - return categoryService.getListTree(Constants.CATEGORY_TYPE_PRODUCT, 1,""); + List 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; } /** diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/UserCenterServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/UserCenterServiceImpl.java index 72387196..44e6e2e4 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/UserCenterServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/service/impl/UserCenterServiceImpl.java @@ -533,6 +533,8 @@ public class UserCenterServiceImpl extends ServiceImpl 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 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()); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/front/vo/WxPayJsResultVo.java b/crmeb/src/main/java/com/zbkj/crmeb/front/vo/WxPayJsResultVo.java new file mode 100644 index 00000000..052ec2f7 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/front/vo/WxPayJsResultVo.java @@ -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 + * +---------------------------------------------------------------------- + */ +@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; +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/log/service/impl/StoreProductLogServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/log/service/impl/StoreProductLogServiceImpl.java index 025880e5..3cc8e16d 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/log/service/impl/StoreProductLogServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/log/service/impl/StoreProductLogServiceImpl.java @@ -54,7 +54,7 @@ public class StoreProductLogServiceImpl extends ServiceImpl { */ List getList(StoreCouponUser storeCouponUser); - boolean receive(StoreCouponUserRequest storeCouponUserRequest); + Boolean receive(StoreCouponUserRequest storeCouponUserRequest); boolean use(Integer id, List productIdList, BigDecimal price); @@ -65,4 +65,9 @@ public interface StoreCouponUserService extends IService { List getListByCartIds(List cartIds); List getListFront(Integer userId, PageParamRequest pageParamRequest); + + /** + * 优惠券过期定时任务 + */ + void overdueTask(); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponServiceImpl.java index 3326c50f..7ae89e59 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponServiceImpl.java @@ -298,6 +298,9 @@ public class StoreCouponServiceImpl extends ServiceImpl 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()); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponUserServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponUserServiceImpl.java index c45ed7a8..c22c6e94 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponUserServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/marketing/service/impl/StoreCouponUserServiceImpl.java @@ -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 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 storeCouponUserList = dao.selectList(lambdaQueryWrapper); if(storeCouponUserList.size() < 1){ return new PageInfo<>(); } + ArrayList storeCouponUserResponseList = new ArrayList<>(); List uidList = storeCouponUserList.stream().map(StoreCouponUser::getUid).distinct().collect(Collectors.toList()); HashMap userList = userService.getMapListInUid(uidList); @@ -145,7 +153,7 @@ public class StoreCouponUserServiceImpl extends ServiceImpl storeCouponUserList = new ArrayList<>(); @@ -189,10 +197,22 @@ public class StoreCouponUserServiceImpl extends ServiceImpl 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 carIdsStr = cartIds.stream().map(e -> e.toString()).collect(Collectors.toList()); //购物车产品集合 List storeCartResponseList = - storeCartService.getListByUserIdAndCartIds(userService.getUserIdException(), carIdsStr,1); + storeCartService.getListByUserIdAndCartIds(userService.getUserIdException(), carIdsStr,true); //产品id集合 List 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 lambdaQueryWrapper = new LambdaQueryWrapper<>(); Date date = DateUtil.nowDateTime(); @@ -480,6 +500,7 @@ public class StoreCouponUserServiceImpl extends ServiceImpl 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 lqw = new LambdaQueryWrapper<>(); + lqw.eq(StoreCouponUser::getStatus, 0); + List couponList = dao.selectList(lqw); + if (CollUtil.isEmpty(couponList)) { + return; + } + // 判断优惠券是否过期 + List 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 lambdaQueryWrapper, String productIdStr){ if(StringUtils.isBlank(productIdStr)){ return; } List 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) 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) 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))) + )); } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/pass/service/impl/OnePassServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/pass/service/impl/OnePassServiceImpl.java index 310c43b3..f43b34c7 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/pass/service/impl/OnePassServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/pass/service/impl/OnePassServiceImpl.java @@ -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 header = onePassUtil.getCommonHeader(token); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/controller/CallbackController.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/controller/CallbackController.java index 04d68c30..e4cd5715 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/controller/CallbackController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/controller/CallbackController.java @@ -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; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/CallbackService.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/CallbackService.java index aa10e2d0..646ff081 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/CallbackService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/CallbackService.java @@ -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); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/OrderPayService.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/OrderPayService.java index 5f124e1b..98b61f83 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/OrderPayService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/OrderPayService.java @@ -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); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/CallbackServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/CallbackServiceImpl.java index f8e254d6..b6276245 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/CallbackServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/CallbackServiceImpl.java @@ -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(""); - if(StrUtil.isBlank("xmlInfo")){ + if(StrUtil.isBlank(xmlInfo)){ sb.append(""); sb.append(""); sb.append(""); @@ -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(""); 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(""); + sb.append(""); + sb.append(""); + 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(""); + if(StrUtil.isBlank(xmlInfo)){ + sb.append(""); + sb.append(""); + sb.append(""); + logger.error("wechat refund callback error : " + sb.toString()); + return refundRecord.set("returnXml", sb.toString()).set("errMsg", "xmlInfo is blank"); + } + + Map respMap; + try { + respMap = WxPayUtil.xmlToMap(xmlInfo); + } catch (Exception e) { + sb.append(""); + sb.append(""); + sb.append(""); + 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 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(""); + sb.append(""); + sb.append(""); + 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 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 _strMap2ObjMap(Map params) { + Map map = new HashMap<>(); + for (Map.Entry 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; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/OrderPayServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/OrderPayServiceImpl.java index 8f04e6d9..9f2554a4 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/OrderPayServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/service/impl/OrderPayServiceImpl.java @@ -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 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 orderInfoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId()); + List productIds = orderInfoList.stream().map(StoreOrderInfoVo::getProductId).collect(Collectors.toList()); + if(productIds.size() > 0){ + List 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 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; + } + /** * 发送模板消息通知 */ diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/CreateOrderRequestVo.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/CreateOrderRequestVo.java index f8dcb493..fc51e43f 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/CreateOrderRequestVo.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/CreateOrderRequestVo.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/WxRefundVo.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/WxRefundVo.java index 943912eb..bcc97858 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/WxRefundVo.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/vo/wechat/WxRefundVo.java @@ -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; + } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/WeChatPayService.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/WeChatPayService.java index 0335d310..18ba30fd 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/WeChatPayService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/WeChatPayService.java @@ -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 unifiedorder(StoreOrder storeOrder, String ip); + + /** + * 查询支付结果 + * @param orderNo 订单编号 + * @return + */ + Boolean queryPayResult(String orderNo); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/impl/WeChatPayServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/impl/WeChatPayServiceImpl.java index 6ab88b2f..2e657ac3 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/impl/WeChatPayServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/payment/wechat/impl/WeChatPayServiceImpl.java @@ -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 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 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 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 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 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 getWxChantQueryPayVo(String no, String appId, String mchId, String orderNo) { + Map 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; + } + + /** + * 作用:统一下单
+ * 场景:公共号支付、扫码支付、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 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()); + } + } + } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/model/StoreSeckill.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/model/StoreSeckill.java index 7925be00..5d3a9abb 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/model/StoreSeckill.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/model/StoreSeckill.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/request/StoreSeckillRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/request/StoreSeckillRequest.java index 07b20a89..9d6c7026 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/request/StoreSeckillRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/request/StoreSeckillRequest.java @@ -60,7 +60,7 @@ public class StoreSeckillRequest { private BigDecimal otPrice; @ApiModelProperty(value = "返多少积分") - private BigDecimal giveIntegral; + private Integer giveIntegral; @ApiModelProperty(value = "排序") private Integer sort; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillResponse.java index 8557ef41..32170db6 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillResponse.java @@ -117,7 +117,7 @@ public class StoreSeckillResponse { private BigDecimal otPrice; @ApiModelProperty(value = "返多少积分") - private BigDecimal giveIntegral; + private Integer giveIntegral; @ApiModelProperty(value = "排序") private Integer sort; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillStoreInfoResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillStoreInfoResponse.java index cfe4b4ad..2bf0314a 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillStoreInfoResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/response/StoreSeckillStoreInfoResponse.java @@ -137,7 +137,7 @@ public class StoreSeckillStoreInfoResponse { private Boolean merUse; @ApiModelProperty(value = "获得积分") - private BigDecimal giveIntegral; + private Integer giveIntegral; @ApiModelProperty(value = "成本价") private BigDecimal cost; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/StoreSeckillService.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/StoreSeckillService.java index dc44cd27..7595dae3 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/StoreSeckillService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/StoreSeckillService.java @@ -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 { /** * 扣减库存加销量 - * @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 { * @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); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillMangerServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillMangerServiceImpl.java index eb65cdd9..0ce41f1e 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillMangerServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillMangerServiceImpl.java @@ -99,7 +99,7 @@ public class StoreSeckillMangerServiceImpl extends ServiceImpl checkTimeRangeUnique(StoreSeckillManger storeSeckillManger) { LambdaQueryWrapper 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()); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillServiceImpl.java index fc4537a0..d32b6fde 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/seckill/service/impl/StoreSeckillServiceImpl.java @@ -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 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 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 existSeckillAttrValues = storeProductAttrValueService.getByEntity(spavPram); + if (CollUtil.isEmpty(existSeckillAttrValues)) throw new CrmebException("未找到扣减库存的秒杀商品"); + StoreProductAttrValue currentSeckillAttrValue = existSeckillAttrValues.get(0); + // 对应的主商品sku + List currentProAttrValues = storeProductAttrValueService.getListByProductId(productId); + List 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 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 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 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 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); + } /////////////////////////////////////////////////////////////////// 自定义方法 // 秒杀操作库存 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/statistics/service/impl/HomeServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/statistics/service/impl/HomeServiceImpl.java index 551d4f03..c64eb011 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/statistics/service/impl/HomeServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/statistics/service/impl/HomeServiceImpl.java @@ -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"); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/controller/RetailShopController.java b/crmeb/src/main/java/com/zbkj/crmeb/store/controller/RetailShopController.java index a2375133..291ec9fd 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/controller/RetailShopController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/controller/RetailShopController.java @@ -75,77 +75,25 @@ public class RetailShopController { public CommonResult> getList(@RequestParam(required = false) String keywords, @RequestParam(required = false) String dateLimit, @ModelAttribute PageParamRequest pageParamRequest){ - PageInfo 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 getStatistics(@RequestParam(required = false) String nickName, + public CommonResult getStatistics(@RequestParam(required = false) String keywords, @RequestParam(required = false) String dateLimit){ - List resultList = new ArrayList<>(); - // 获取分销人数 - List 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 ids = userResponseList.stream().map(UserResponse::getUid).distinct().collect(Collectors.toList()); - - if(userResponseList.size() > 0){ - spreadCount.setCount(userService.getSpreadPeopleIdList(ids).size()); - List 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 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)); } /** diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/controller/StoreOrderController.java b/crmeb/src/main/java/com/zbkj/crmeb/store/controller/StoreOrderController.java index 952a1287..78116a6c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/controller/StoreOrderController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/controller/StoreOrderController.java @@ -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 refundRefuse(@RequestParam Integer id, @RequestParam String reason){ + public CommonResult 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 */ diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreOrder.java b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreOrder.java index b839cc1c..5f77e04c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreOrder.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreOrder.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProduct.java b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProduct.java index 8aa02447..d4dc1fce 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProduct.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProduct.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProductReply.java b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProductReply.java index 91909bb2..9ebb3b51 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProductReply.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/model/StoreProductReply.java @@ -89,4 +89,7 @@ public class StoreProductReply implements Serializable { @ApiModelProperty(value = "更新时间") private Date updateTime; + + @ApiModelProperty(value = "商品规格属性值") + private String sku; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/request/RetailShopStairUserRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/store/request/RetailShopStairUserRequest.java index 00296b90..c2b8a689 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/request/RetailShopStairUserRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/request/RetailShopStairUserRequest.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRefundRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRefundRequest.java index c5c9af59..d8bfa001 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRefundRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRefundRequest.java @@ -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; - } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRequest.java index a4cc3399..989bdca2 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreOrderRequest.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductReplyAddRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductReplyAddRequest.java index 4a50ef60..ae12aaf2 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductReplyAddRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductReplyAddRequest.java @@ -65,4 +65,7 @@ public class StoreProductReplyAddRequest implements Serializable { @ApiModelProperty(value = "评论人昵称 [虚拟评论参数]") private String nickname; + + @ApiModelProperty(value = "商品规格属性值,多规格时用英文逗号拼接") + private String sku; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductRequest.java index 01d2b45f..a49f1560 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/request/StoreProductRequest.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopStatisticsResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopStatisticsResponse.java index 0cbaadb6..652c9172 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopStatisticsResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopStatisticsResponse.java @@ -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; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopUserResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopUserResponse.java index 0c3fc212..c7dbb24e 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopUserResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/RetailShopUserResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreCartResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreCartResponse.java index 28f72046..caf63a54 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreCartResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreCartResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderCreateResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderCreateResponse.java index 7b56c1d0..fb142ed2 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderCreateResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderCreateResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderInfoResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderInfoResponse.java index ab29cf37..277ed6b4 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderInfoResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderInfoResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderListResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderListResponse.java index 1ecb8deb..dd2f593c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderListResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreOrderListResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductCartProductInfoResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductCartProductInfoResponse.java index 0468dc3c..f69dd58a 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductCartProductInfoResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductCartProductInfoResponse.java @@ -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; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductReplyResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductReplyResponse.java index 2b57c1fa..8368fa23 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductReplyResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductReplyResponse.java @@ -77,5 +77,8 @@ public class StoreProductReplyResponse { @ApiModelProperty(value = "更新时间") private Date updateTime; + @ApiModelProperty(value = "商品规格属性值") + private String sku; + private StoreProduct storeProduct; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductResponse.java index eb653401..ef47bcc8 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductResponse.java @@ -50,23 +50,20 @@ public class StoreProductResponse implements Serializable { return activity; }else{ List 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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductStoreInfoResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductStoreInfoResponse.java index 2c8086b2..431b93d8 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductStoreInfoResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/response/StoreProductStoreInfoResponse.java @@ -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; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/OrderTaskService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/OrderTaskService.java index db13d5e2..38546823 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/OrderTaskService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/OrderTaskService.java @@ -24,4 +24,6 @@ package com.zbkj.crmeb.store.service; void takeByUser(); void deleteByUser(); - } + + void orderPaySuccessAfter(); +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/RetailShopService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/RetailShopService.java index 3ea2f9f3..f4d5b4d8 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/RetailShopService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/RetailShopService.java @@ -1,10 +1,12 @@ package com.zbkj.crmeb.store.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.common.CommonPage; import com.common.PageParamRequest; import com.github.pagehelper.PageInfo; import com.zbkj.crmeb.store.request.RetailShopRequest; import com.zbkj.crmeb.store.request.RetailShopStairUserRequest; +import com.zbkj.crmeb.store.response.RetailShopStatisticsResponse; import com.zbkj.crmeb.store.response.RetailShopUserResponse; import com.zbkj.crmeb.user.model.User; import com.zbkj.crmeb.user.response.UserResponse; @@ -32,7 +34,7 @@ public interface RetailShopService extends IService { * @param pageRequest * @return */ - PageInfo getList(String keywords, String dateLimit, PageParamRequest pageRequest); + CommonPage getList(String keywords, String dateLimit, PageParamRequest pageRequest); /** * 获取分销头部数据 @@ -60,4 +62,12 @@ public interface RetailShopService extends IService { * @return 保存结果 */ boolean setManageInfo(RetailShopRequest retailShopRequest); + + /** + * 获取分销统计数据 + * @param keywords 模糊搜索参数 + * @param dateLimit 时间参数 + * @return + */ + RetailShopStatisticsResponse getAdminStatistics(String keywords, String dateLimit); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreCartService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreCartService.java index ba1292d8..1a5cbf57 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreCartService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreCartService.java @@ -38,7 +38,7 @@ public interface StoreCartService extends IService { * @param cartIds 购物车id集合 * @return 购物车列表 */ - List getListByUserIdAndCartIds(Integer userId, List cartIds,Integer isNew); + List getListByUserIdAndCartIds(Integer userId, List cartIds,Boolean isNew); /** * 根据用户id和购物车id集合获取列表 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderService.java index 999b4adb..98577ffe 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderService.java @@ -122,7 +122,7 @@ public interface StoreOrderService extends IService { boolean mark(Integer id, String mark); - boolean refundRefuse(Integer id, String reason); + Boolean refundRefuse(Integer id, String reason); RetailShopOrderDataResponse getOrderDataByUserId(Integer userId); @@ -208,4 +208,10 @@ public interface StoreOrderService extends IService { ExpressSheetVo getDeliveryInfo(); PageInfo findListByUserIdsForRetailShop(List userIds, RetailShopStairUserRequest request, PageParamRequest pageParamRequest); + + /** + * 更新支付结果 + * @param orderNo 订单编号 + */ + Boolean updatePaid(String orderNo); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderStatusService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderStatusService.java index d732c557..95ae2c55 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderStatusService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderStatusService.java @@ -1,7 +1,6 @@ package com.zbkj.crmeb.store.service; import com.common.PageParamRequest; -import com.zbkj.crmeb.store.model.StoreOrder; import com.zbkj.crmeb.store.model.StoreOrderStatus; import com.baomidou.mybatisplus.extension.service.IService; import com.zbkj.crmeb.store.request.StoreOrderStatusSearchRequest; @@ -25,9 +24,9 @@ public interface StoreOrderStatusService extends IService { List getList(StoreOrderStatusSearchRequest request, PageParamRequest pageParamRequest); - void saveRefund(Integer orderId, BigDecimal amount, String message); + Boolean saveRefund(Integer orderId, BigDecimal amount, String message); - void createLog(Integer orderId, String type, String message); + Boolean createLog(Integer orderId, String type, String message); Boolean addLog(Integer orderId, String type, String message); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderTaskService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderTaskService.java index 758729ff..650f0d79 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderTaskService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreOrderTaskService.java @@ -26,4 +26,8 @@ import com.zbkj.crmeb.store.model.StoreOrder; Boolean takeByUser(StoreOrder storeOrder); Boolean deleteByUser(StoreOrder storeOrder); + + Boolean refundOrder(StoreOrder storeOrder); + + Boolean paySuccessAfter(StoreOrder storeOrder); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreProductAttrValueService.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreProductAttrValueService.java index 82dbecba..8b22d68f 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreProductAttrValueService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/StoreProductAttrValueService.java @@ -69,4 +69,30 @@ public interface StoreProductAttrValueService extends IService { * @return */ MyRecord copyProduct(String url); + + /** + * 添加/扣减库存 + * @param id 商品id + * @param num 数量 + * @param type 类型:add—添加,sub—扣减 + */ + Boolean operationStock(Integer id, Integer num, String type); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/OrderTaskServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/OrderTaskServiceImpl.java index d03c14fe..0337ba18 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/OrderTaskServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/OrderTaskServiceImpl.java @@ -1,8 +1,10 @@ package com.zbkj.crmeb.store.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; import com.constants.Constants; +import com.exception.CrmebException; import com.utils.DateUtil; import com.utils.RedisUtil; import com.zbkj.crmeb.store.model.StoreOrder; @@ -10,7 +12,7 @@ import com.zbkj.crmeb.store.service.OrderTaskService; import com.zbkj.crmeb.store.service.StoreOrderService; import com.zbkj.crmeb.store.service.StoreOrderTaskService; import com.zbkj.crmeb.store.utilService.OrderUtils; -import com.zbkj.crmeb.task.order.OrderRefundByUser; +import com.zbkj.crmeb.task.order.OrderRefundTask; import com.zbkj.crmeb.wechat.service.impl.WechatSendMessageForMinService; import com.zbkj.crmeb.wechat.vo.WechatSendMessageForGetPackage; import com.zbkj.crmeb.wechat.vo.WechatSendMessageForOrderCancel; @@ -34,7 +36,7 @@ import org.springframework.stereotype.Service; @Service public class OrderTaskServiceImpl implements OrderTaskService { //日志 - private static final Logger logger = LoggerFactory.getLogger(OrderRefundByUser.class); + private static final Logger logger = LoggerFactory.getLogger(OrderTaskServiceImpl.class); @Autowired private RedisUtil redisUtil; @@ -116,7 +118,11 @@ public class OrderTaskServiceImpl implements OrderTaskService { } try{ StoreOrder storeOrder = storeOrderService.getById(Integer.valueOf(orderId.toString())); - boolean result = storeOrderTaskService.refundApply(storeOrder); + if (ObjectUtil.isNull(storeOrder)) { + throw new CrmebException("订单不存在,orderNo = " + orderId); + } +// boolean result = storeOrderTaskService.refundApply(storeOrder); + boolean result = storeOrderTaskService.refundOrder(storeOrder); if(!result){ redisUtil.lPush(redisKey, orderId); } @@ -225,4 +231,38 @@ public class OrderTaskServiceImpl implements OrderTaskService { } } } + + /** + * 订单支付成功后置处理 + */ + @Override + public void orderPaySuccessAfter() { + String redisKey = Constants.ORDER_TASK_PAY_SUCCESS_AFTER; + Long size = redisUtil.getListSize(redisKey); + logger.info("OrderTaskServiceImpl.orderPaySuccessAfter | size:" + size); + if(size < 1){ + return; + } + for (int i = 0; i < size; i++) { + //如果10秒钟拿不到一个数据,那么退出循环 + Object data = redisUtil.getRightPop(redisKey, 10L); + if(null == data){ + continue; + } + try{ + StoreOrder storeOrder = storeOrderService.getByOderId(String.valueOf(data)); + if (ObjectUtil.isNull(storeOrder)) { + logger.error("OrderTaskServiceImpl.orderPaySuccessAfter | 订单不存在,orderNo: " + data); + throw new CrmebException("订单不存在,orderNo: " + data); + } + boolean result = storeOrderTaskService.paySuccessAfter(storeOrder); + if(!result){ + redisUtil.lPush(redisKey, data); + } + }catch (Exception e){ + e.printStackTrace(); + redisUtil.lPush(redisKey, data); + } + } + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/RetailShopServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/RetailShopServiceImpl.java index 9f8cb306..8259dab6 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/RetailShopServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/RetailShopServiceImpl.java @@ -1,14 +1,18 @@ package com.zbkj.crmeb.store.service.impl; +import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.common.CommonPage; import com.common.PageParamRequest; +import com.exception.CrmebException; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.zbkj.crmeb.finance.service.UserExtractService; +import com.zbkj.crmeb.store.model.StoreOrder; import com.zbkj.crmeb.store.request.RetailShopRequest; import com.zbkj.crmeb.store.request.RetailShopStairUserRequest; +import com.zbkj.crmeb.store.response.RetailShopStatisticsResponse; import com.zbkj.crmeb.store.response.RetailShopUserResponse; import com.zbkj.crmeb.store.service.RetailShopService; import com.zbkj.crmeb.store.service.StoreOrderService; @@ -65,7 +69,7 @@ public class RetailShopServiceImpl extends ServiceImpl implements * @return */ @Override - public PageInfo getList(String keywords, String dateLimit, PageParamRequest pageRequest) { + public CommonPage getList(String keywords, String dateLimit, PageParamRequest pageRequest) { Page pageUserPage = PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit()); // User currentUser = userService.getUserByEntity(); @@ -103,7 +107,10 @@ public class RetailShopServiceImpl extends ServiceImpl implements // 佣金数据 rShopUser.setBrokerageMoney(userBillService.getDataByUserId(rShopUser.getUid())); } - return CommonPage.copyPageInfo(pageUserPage, retailShopUserResponses); + PageInfo responsePageInfo = CommonPage.copyPageInfo(pageUserPage, retailShopUserResponses); + responsePageInfo.setTotal(userResponses.getTotal()); + responsePageInfo.setPages(userResponses.getPages()); + return CommonPage.restPage(responsePageInfo); } /** @@ -162,6 +169,10 @@ public class RetailShopServiceImpl extends ServiceImpl implements */ @Override public boolean setManageInfo(RetailShopRequest retailShopRequest) { + // 返佣比例之和+起来不能超过100% + int ration = retailShopRequest.getStoreBrokerageTwo() + retailShopRequest.getStoreBrokerageRatio(); + if (ration > 100 || ration < 0) throw new CrmebException("返佣比例加起来不能超过100%"); + List keys = initKeys(); systemConfigService.updateOrSaveValueByName(keys.get(0), retailShopRequest.getBrokerageFuncStatus()); systemConfigService.updateOrSaveValueByName(keys.get(1), retailShopRequest.getStoreBrokerageStatus()); @@ -175,6 +186,40 @@ public class RetailShopServiceImpl extends ServiceImpl implements return true; } + /** + * 获取分销统计数据 + * @param keywords 模糊搜索参数 + * @param dateLimit 时间参数 + * @return RetailShopStatisticsResponse + */ + @Override + public RetailShopStatisticsResponse getAdminStatistics(String keywords, String dateLimit) { + + // 获取分销人数 + List userDisList = userService.findDistributionList(keywords, dateLimit); + if (CollUtil.isEmpty(userDisList)) { + return new RetailShopStatisticsResponse(0, 0, 0, BigDecimal.ZERO, 0, BigDecimal.ZERO); + } + // 分销人员人数 + Integer distributionNum = userDisList.size(); + + // 发展会员人数 + List ids = userDisList.stream().map(User::getUid).collect(Collectors.toList()); + Integer developNum = userService.getDevelopDistributionPeopleNum(ids, dateLimit); + + List storeOrders = storeOrderService.getOrderByUserIdsForRetailShop(ids); + // 订单总数 + Integer orderNum = storeOrders.size(); + // 订单金额 + BigDecimal orderPriceCount = storeOrders.stream().map(StoreOrder::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add); + // 提现次数 + Integer withdrawCount = userExtractService.getListByUserIds(ids).size(); + // 未提现金额 + BigDecimal noWithdrawPrice = userDisList.stream().map(User::getBrokeragePrice).reduce(BigDecimal.ZERO, BigDecimal::add); + + return new RetailShopStatisticsResponse(distributionNum, developNum, orderNum, orderPriceCount, withdrawCount, noWithdrawPrice); + } + ///////////////////////////////////////////////////// 自定义 public List initKeys(){ diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreCartServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreCartServiceImpl.java index e92f3e5c..e1a9efff 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreCartServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreCartServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.common.MyRecord; import com.common.PageParamRequest; import com.constants.Constants; import com.exception.CrmebException; @@ -13,15 +14,15 @@ import com.zbkj.crmeb.bargain.model.StoreBargain; import com.zbkj.crmeb.combination.model.StoreCombination; import com.zbkj.crmeb.front.request.CartResetRequest; import com.zbkj.crmeb.seckill.model.StoreSeckill; -import com.zbkj.crmeb.seckill.service.StoreSeckillMangerService; -import com.zbkj.crmeb.seckill.service.StoreSeckillService; import com.zbkj.crmeb.store.dao.StoreCartDao; import com.zbkj.crmeb.store.model.StoreCart; import com.zbkj.crmeb.store.model.StoreProductAttrValue; import com.zbkj.crmeb.store.response.StoreCartResponse; import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse; import com.zbkj.crmeb.store.response.StoreProductResponse; -import com.zbkj.crmeb.store.service.*; +import com.zbkj.crmeb.store.service.StoreCartService; +import com.zbkj.crmeb.store.service.StoreProductAttrValueService; +import com.zbkj.crmeb.store.service.StoreProductService; import com.zbkj.crmeb.store.utilService.OrderUtils; import com.zbkj.crmeb.system.service.SystemConfigService; import com.zbkj.crmeb.user.model.User; @@ -35,6 +36,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -76,18 +78,6 @@ public class StoreCartServiceImpl extends ServiceImpl i @Autowired private OrderUtils orderUtils; - @Autowired - private StoreSeckillService storeSeckillService; - - @Autowired - private StoreSeckillMangerService storeSeckillMangerService; - - @Autowired - private StoreOrderService storeOrderService; - - @Autowired - private StoreOrderInfoService storeOrderInfoService; - /** * 列表 * @param pageParamRequest 分页类参数 @@ -132,7 +122,7 @@ public class StoreCartServiceImpl extends ServiceImpl i p.setAttrInfo(productAttrValue); } storeCartResponse.setAttrStatus(productAttrValue.getStock() > 0); - storeCartResponse.setTruePrice(setVipPrice(productAttrValue.getPrice(),userService.getUserIdException(),true)); + storeCartResponse.setTruePrice(productAttrValue.getPrice()); storeCartResponse.setVipTruePrice(setVipPrice(productAttrValue.getPrice(),userService.getUserIdException(),false)); storeCartResponse.setTrueStock(product.getStock()); storeCartResponse.setCostPrice(product.getCost()); @@ -150,13 +140,17 @@ public class StoreCartServiceImpl extends ServiceImpl i * @return 购物车列表 */ @Override - public List getListByUserIdAndCartIds(Integer userId, List cartIds,Integer isNew) { + public List getListByUserIdAndCartIds(Integer userId, List cartIds,Boolean isNew) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.in(StoreCart::getId,cartIds); lambdaQueryWrapper.eq(StoreCart::getUid, userId); - if(null != isNew) lambdaQueryWrapper.eq(StoreCart::getIsNew, isNew); +// lambdaQueryWrapper.eq(StoreCart::getIsNew, isNew); lambdaQueryWrapper.orderByDesc(StoreCart::getCreateTime); List storeCarts = dao.selectList(lambdaQueryWrapper); + if (CollUtil.isEmpty(storeCarts)) { + throw new CrmebException("购物车信息不存在"); + } + List response = new ArrayList<>(); for (StoreCart storeCart : storeCarts) { @@ -167,14 +161,14 @@ public class StoreCartServiceImpl extends ServiceImpl i Constants.PRODUCT_TYPE_NORMAL); for (StoreProductAttrValue productAttrValue : productAttrValues) { StoreCartResponse storeCartResponse = new StoreCartResponse(); - BeanUtils.copyProperties(storeCart,storeCartResponse); + BeanUtils.copyProperties(storeCart, storeCartResponse); StoreProductResponse product = storeProductService.getByProductId(productAttrValue.getProductId()); StoreProductCartProductInfoResponse p = new StoreProductCartProductInfoResponse(); - BeanUtils.copyProperties(product,p); + BeanUtils.copyProperties(product, p); p.setAttrInfo(productAttrValue); storeCartResponse.setProductInfo(p); - storeCartResponse.setTruePrice(setVipPrice(productAttrValue.getPrice(),userService.getUserIdException(),true)); - storeCartResponse.setVipTruePrice(setVipPrice(productAttrValue.getPrice(),userService.getUserIdException(),false)); + storeCartResponse.setTruePrice(productAttrValue.getPrice()); + storeCartResponse.setVipTruePrice(setVipPrice(productAttrValue.getPrice(), userId,false)); storeCartResponse.setTrueStock(product.getStock()); storeCartResponse.setCostPrice(product.getCost()); response.add(storeCartResponse); @@ -227,7 +221,8 @@ public class StoreCartServiceImpl extends ServiceImpl i public String saveCate(StoreCart storeCart) { // 判断商品正常 StoreProductResponse existProduct = storeProductService.getByProductId(storeCart.getProductId()); - if(null == existProduct) throw new CrmebException("商品不存在"); + if (ObjectUtil.isNull(existProduct) || existProduct.getIsDel()) throw new CrmebException("商品不存在"); + if (!existProduct.getIsShow()) throw new CrmebException("商品已下架"); /** * ================================ @@ -236,28 +231,33 @@ public class StoreCartServiceImpl extends ServiceImpl i */ // 活动校验 - if (!storeCart.getIsNew() && (ObjectUtil.isNotNull(storeCart.getSeckillId()) || ObjectUtil.isNotNull(storeCart.getBargainId()) || ObjectUtil.isNotNull(storeCart.getCombinationId()))) { - throw new CrmebException("活动商品不能加入购物车"); + if (!storeCart.getIsNew()) { + if (ObjectUtil.isNotNull(storeCart.getSeckillId()) && storeCart.getSeckillId() > 0) { + throw new CrmebException("秒杀商品不能加入购物车"); + } + if (ObjectUtil.isNotNull(storeCart.getBargainId()) && storeCart.getBargainId() > 0) { + throw new CrmebException("砍价商品不能加入购物车"); + } + if (ObjectUtil.isNotNull(storeCart.getCombinationId()) && storeCart.getCombinationId() > 0) { + throw new CrmebException("拼团商品不能加入购物车"); + } } - // 秒杀商品业务处理 - if(ObjectUtil.isNotNull(storeCart.getSeckillId()) && storeCart.getIsNew()){ + if(ObjectUtil.isNotNull(storeCart.getSeckillId()) && storeCart.getSeckillId() > 0 && storeCart.getIsNew()){ storeCart.setCartNum(1); // 秒杀仅仅只能购买一件商品 List cacheSecKillIds = buildCartInfoForSeckill(storeCart); return cacheSecKillIds.get(0); } // 砍价商品业务处理 - if (ObjectUtil.isNotNull(storeCart.getBargainId()) && storeCart.getIsNew()) { + if (ObjectUtil.isNotNull(storeCart.getBargainId()) && storeCart.getBargainId() > 0 && storeCart.getIsNew()) { storeCart.setCartNum(1); // 砍价一次仅仅只能购买一件商品 - List cacheBargainIds = buildCartInfoForBargain(storeCart); - return cacheBargainIds.get(0); + return buildCartInfoForBargain(storeCart); } // 拼团商品业务处理 - if (ObjectUtil.isNotNull(storeCart.getCombinationId()) && storeCart.getIsNew()) { - List cacheBargainIds = buildCartInfoForCombination(storeCart); - return cacheBargainIds.get(0); + if (ObjectUtil.isNotNull(storeCart.getCombinationId()) && storeCart.getCombinationId() > 0 && storeCart.getIsNew()) { + return buildCartInfoForCombination(storeCart); } /** @@ -281,10 +281,6 @@ public class StoreCartServiceImpl extends ServiceImpl i User currentUser = userService.getInfo(); storeCart.setUid(currentUser.getUid()); storeCart.setType("product"); -// storeCart.setIsNew(false); -// if (storeCart.getIsNew()) {// 立即购买才为true -// storeCart.setIsNew(true); -// } if(dao.insert(storeCart) <= 0) throw new CrmebException("添加购物车失败"); return storeCart.getId()+""; } @@ -295,25 +291,26 @@ public class StoreCartServiceImpl extends ServiceImpl i * 设置会员价格 * @param price 原来价格 * @param userId 会员id - * @param isSingle + * @param isSingle 是否普通用户,true普通用户,false会员 * @return */ @Override public BigDecimal setVipPrice(BigDecimal price, Integer userId, boolean isSingle) { // 判断会员功能是否开启 - Integer memberFuncStatus = Integer.valueOf(systemConfigService.getValueByKey("member_func_status")); - Integer memberPriceStatus = Integer.valueOf(systemConfigService.getValueByKey("member_price_status")); - if(memberFuncStatus <= 0 || memberPriceStatus <= 0){ - return isSingle ? price : BigDecimal.ZERO; +// Integer memberFuncStatus = Integer.valueOf(systemConfigService.getValueByKey("member_func_status")); + Integer memberFuncStatus = Integer.valueOf(systemConfigService.getValueByKey("vip_open")); + if(memberFuncStatus <= 0){ + return price; } -// User userInfo = userService.getById(userId); + // 会员等级 UserLevel userLevelInfo = userLevelService.getUserLevelByUserId(userId); + if (ObjectUtil.isNull(userLevelInfo)) return price; if(userLevelInfo.getDiscount().compareTo(BigDecimal.ZERO) == 0){ // 不是会员原价返回 - return isSingle ? price : BigDecimal.ZERO; + return price; } BigDecimal discount = userLevelInfo.getDiscount().divide(BigDecimal.valueOf(100)); - return isSingle ? discount.divide(price) : discount.multiply(price); + return isSingle ? price : discount.multiply(price).setScale(2, RoundingMode.UP); } /** @@ -491,7 +488,7 @@ public class StoreCartServiceImpl extends ServiceImpl i * @param storeCartPram 砍价参数 * @return 组装好的下单前砍价数据 */ - private List buildCartInfoForBargain(StoreCart storeCartPram) { + private String buildCartInfoForBargain(StoreCart storeCartPram) { User currentUser = userService.getInfoException(); List cacheIdsResult = new ArrayList<>(); List storeCartResponses = new ArrayList<>(); @@ -499,21 +496,11 @@ public class StoreCartServiceImpl extends ServiceImpl i StoreProductCartProductInfoResponse spcpInfo = new StoreProductCartProductInfoResponse(); // 砍价商品数据验证 - StoreBargain storeBargain = orderUtils.validBargain(storeCartPram, currentUser); + MyRecord record = orderUtils.validBargain(storeCartPram, currentUser); + StoreBargain storeBargain = record.get("product"); BeanUtils.copyProperties(storeBargain, spcpInfo); - // 判断商品对应属性是否有效 - StoreProductAttrValue apAttrValuePram = new StoreProductAttrValue(); - apAttrValuePram.setProductId(storeCartPram.getSeckillId()); - apAttrValuePram.setId(Integer.valueOf(storeCartPram.getProductAttrUnique())); - apAttrValuePram.setType(Constants.PRODUCT_TYPE_BARGAIN); - List bargainAttrValues = storeProductAttrValueService.getByEntity(apAttrValuePram); - StoreProductAttrValue existSPAttrValue = new StoreProductAttrValue(); - if(CollUtil.isNotEmpty(bargainAttrValues)) existSPAttrValue = bargainAttrValues.get(0); - if(ObjectUtil.isEmpty(existSPAttrValue)) throw new CrmebException("请选择有效的商品属性"); - if(existSPAttrValue.getStock() <= 0) throw new CrmebException("该商品库存不足"); - - spcpInfo.setAttrInfo(existSPAttrValue); + spcpInfo.setAttrInfo(record.get("attrInfo")); spcpInfo.setStoreInfo(storeBargain.getInfo()); spcpInfo.setStoreName(storeBargain.getTitle()); @@ -522,16 +509,15 @@ public class StoreCartServiceImpl extends ServiceImpl i storeCartResponse.setTrueStock(storeCartResponse.getProductInfo().getAttrInfo().getStock()); storeCartResponse.setCostPrice(storeCartResponse.getProductInfo().getAttrInfo().getCost()); storeCartResponse.setTruePrice(storeBargain.getMinPrice()); - storeCartResponse.setVipTruePrice(BigDecimal.ZERO); + storeCartResponse.setVipTruePrice(storeBargain.getMinPrice()); - storeCartResponse.setType(Constants.PRODUCT_TYPE_BARGAIN +"");// 砍价=2 + storeCartResponse.setType(Constants.PRODUCT_TYPE_BARGAIN.toString());// 砍价=2 storeCartResponse.setProductId(storeCartPram.getProductId()); storeCartResponse.setProductAttrUnique(storeCartPram.getProductAttrUnique()); storeCartResponse.setCartNum(1); storeCartResponses.add(storeCartResponse); - cacheIdsResult.add(orderUtils.setCacheOrderData(currentUser, storeCartResponses)); - return cacheIdsResult; + return orderUtils.setCacheOrderData(currentUser, storeCartResponses); } /** @@ -539,15 +525,15 @@ public class StoreCartServiceImpl extends ServiceImpl i * @param storeCartPram 砍价参数 * @return 组装好的下单前砍价数据 */ - private List buildCartInfoForCombination(StoreCart storeCartPram) { + private String buildCartInfoForCombination(StoreCart storeCartPram) { User currentUser = userService.getInfoException(); - List cacheIdsResult = new ArrayList<>(); List storeCartResponses = new ArrayList<>(); StoreCartResponse storeCartResponse = new StoreCartResponse(); StoreProductCartProductInfoResponse spcpInfo = new StoreProductCartProductInfoResponse(); // 拼团商品数据验证 - StoreCombination storeCombination = orderUtils.validCombination(storeCartPram, currentUser); + MyRecord record = orderUtils.validCombination(storeCartPram, currentUser); + StoreCombination storeCombination = record.get("product"); BeanUtils.copyProperties(storeCombination, spcpInfo); // 判断商品对应属性是否有效 @@ -556,12 +542,12 @@ public class StoreCartServiceImpl extends ServiceImpl i apAttrValuePram.setId(Integer.valueOf(storeCartPram.getProductAttrUnique())); apAttrValuePram.setType(Constants.PRODUCT_TYPE_PINGTUAN); List combinationAttrValues = storeProductAttrValueService.getByEntity(apAttrValuePram); - StoreProductAttrValue existSPAttrValue = new StoreProductAttrValue(); + StoreProductAttrValue existSPAttrValue = null; if(CollUtil.isNotEmpty(combinationAttrValues)) existSPAttrValue = combinationAttrValues.get(0); - if(ObjectUtil.isEmpty(existSPAttrValue)) throw new CrmebException("请选择有效的商品属性"); + if(ObjectUtil.isNull(existSPAttrValue)) throw new CrmebException("请选择有效的商品属性"); if(existSPAttrValue.getStock() <= 0) throw new CrmebException("该商品库存不足"); - spcpInfo.setAttrInfo(existSPAttrValue); + spcpInfo.setAttrInfo(record.get("attrInfo")); spcpInfo.setStoreInfo(storeCombination.getInfo()); spcpInfo.setStoreName(storeCombination.getTitle()); @@ -571,16 +557,15 @@ public class StoreCartServiceImpl extends ServiceImpl i storeCartResponse.setTrueStock(storeCartResponse.getProductInfo().getAttrInfo().getStock()); storeCartResponse.setCostPrice(storeCartResponse.getProductInfo().getAttrInfo().getCost()); storeCartResponse.setTruePrice(storeCombination.getPrice()); - storeCartResponse.setVipTruePrice(BigDecimal.ZERO); + storeCartResponse.setVipTruePrice(storeCombination.getPrice()); - storeCartResponse.setType(Constants.PRODUCT_TYPE_PINGTUAN+"");// 砍价=3 + storeCartResponse.setType(Constants.PRODUCT_TYPE_PINGTUAN.toString());// 砍价=3 storeCartResponse.setProductId(storeCartPram.getProductId()); storeCartResponse.setProductAttrUnique(storeCartPram.getProductAttrUnique()); storeCartResponse.setCartNum(storeCartPram.getCartNum()); storeCartResponses.add(storeCartResponse); - cacheIdsResult.add(orderUtils.setCacheOrderData(currentUser, storeCartResponses)); - return cacheIdsResult; + return orderUtils.setCacheOrderData(currentUser, storeCartResponses); } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderRefundServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderRefundServiceImpl.java index 3f278d54..14cce286 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderRefundServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderRefundServiceImpl.java @@ -3,10 +3,12 @@ package com.zbkj.crmeb.store.service.impl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.WxPayUtil; import com.utils.XmlUtil; import com.zbkj.crmeb.payment.vo.wechat.WxRefundResponseVo; import com.zbkj.crmeb.payment.vo.wechat.WxRefundVo; @@ -49,18 +51,9 @@ public class StoreOrderRefundServiceImpl extends ServiceImpl 0){throw new CrmebException("退款金额大于支付金额,请修改退款金额");} - + if(storeOrder.getRefundPrice().add(request.getAmount()).compareTo(storeOrder.getPayPrice()) > 0) { + throw new CrmebException("退款金额大于支付金额,请修改退款金额"); + } //用户 User user = userService.getById(storeOrder.getUid()); @@ -785,61 +785,45 @@ public class StoreOrderServiceImpl extends ServiceImpl { + updateById(storeOrder); + if (storeOrder.getPayType().equals(Constants.PAY_TYPE_YUE)) { + // 更新用户金额 TODO 后期要调整 + UserOperateFundsRequest userOperateFundsRequest = new UserOperateFundsRequest(); + userOperateFundsRequest.setUid(storeOrder.getUid()); + userOperateFundsRequest.setValue(request.getAmount()); + userOperateFundsRequest.setFoundsCategory(Constants.USER_BILL_CATEGORY_MONEY); + userOperateFundsRequest.setFoundsType(Constants.ORDER_STATUS_REFUNDED); + userOperateFundsRequest.setType(1); + userOperateFundsRequest.setTitle(Constants.ORDER_STATUS_STR_REFUNDED); + userService.updateFounds(userOperateFundsRequest, false); //更新余额 + //新增日志 + userBillService.saveRefundBill(request, user); + // 退款task + redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, storeOrder.getId()); + } + return Boolean.TRUE; + }); + if(!execute){ storeOrderStatusService.saveRefund(request.getOrderId(), request.getAmount(), "失败"); throw new CrmebException("订单更新失败"); } - //退款成功 - storeOrderStatusService.saveRefund(request.getOrderId(), request.getAmount(), null); +// // 小程序订阅消息 退款成功 +// String storeNameAndCarNumString = orderUtils.getStoreNameAndCarNumString(storeOrder.getId()); +// WechatSendMessageForReFundEd forReFundEd = new WechatSendMessageForReFundEd( +// "退款成功",storeNameAndCarNumString,request.getAmount()+"",DateUtil.nowDateTimeStr(),"退款金额已到余额中", +// storeOrder.getOrderId(),storeOrder.getId()+"",storeOrder.getCreateTime()+"",storeOrder.getRefundPrice()+"", +// storeNameAndCarNumString,storeOrder.getRefundReason(),"CRMEB",storeOrder.getRefundReasonWapExplain(), +// "暂无" +// ); +// wechatSendMessageForMinService.sendReFundEdMessage(forReFundEd, userService.getUserIdException()); - //佣金 - subtractBill(request, Constants.USER_BILL_CATEGORY_MONEY, - Constants.USER_BILL_TYPE_BROKERAGE, Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE); - - //积分 - subtractBill(request, Constants.USER_BILL_CATEGORY_INTEGRAL, - Constants.USER_BILL_TYPE_GAIN, Constants.USER_BILL_CATEGORY_INTEGRAL); - - // 回滚库存 后续操作放入redis - redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, storeOrder.getId()); - - // 小程序订阅消息 退款成功 - String storeNameAndCarNumString = orderUtils.getStoreNameAndCarNumString(storeOrder.getId()); - WechatSendMessageForReFundEd forReFundEd = new WechatSendMessageForReFundEd( - "退款成功",storeNameAndCarNumString,request.getAmount()+"",DateUtil.nowDateTimeStr(),"退款金额已到余额中", - storeOrder.getOrderId(),storeOrder.getId()+"",storeOrder.getCreateTime()+"",storeOrder.getRefundPrice()+"", - storeNameAndCarNumString,storeOrder.getRefundReason(),"CRMEB",storeOrder.getRefundReasonWapExplain(), - "暂无" - ); - wechatSendMessageForMinService.sendReFundEdMessage(forReFundEd, userService.getUserIdException()); - - return true; + return execute; } /** 订单详情 @@ -933,18 +917,21 @@ public class StoreOrderServiceImpl extends ServiceImpl { + updateById(storeOrder); + storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_REFUND_REFUSE, Constants.ORDER_LOG_MESSAGE_REFUND_REFUSE.replace("{reason}", reason)); + return Boolean.TRUE; + }); + if (execute) { - //TODO 模板消息通知 - - return true; + //TODO 模板消息通知 + } + return execute; } /** @@ -1025,8 +1012,9 @@ public class StoreOrderServiceImpl extends ServiceImpl getOrderByUserIdsForRetailShop(List ids) { LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); lqw.in(StoreOrder::getUid,ids); - lqw.ge(StoreOrder::getPaid, 1); - lqw.ge(StoreOrder::getRefundStatus, 0); + lqw.eq(StoreOrder::getPaid, 1); + lqw.eq(StoreOrder::getRefundStatus, 0); + lqw.eq(StoreOrder::getIsDel, false); return dao.selectList(lqw); } @@ -1182,6 +1170,7 @@ public class StoreOrderServiceImpl extends ServiceImpl lqw = Wrappers.lambdaQuery(); lqw.eq(StoreOrder::getUid,storeOrder.getUid()).eq(StoreOrder::getSeckillId,storeOrder.getSeckillId()) .between(StoreOrder::getCreateTime,dayStart,dayEnd); + lqw.eq(StoreOrder::getIsDel, false); return dao.selectList(lqw); } @@ -1262,6 +1251,20 @@ public class StoreOrderServiceImpl extends ServiceImpl lqw = new LambdaUpdateWrapper<>(); + lqw.set(StoreOrder::getPaid, true); + lqw.eq(StoreOrder::getOrderId, orderNo); + lqw.eq(StoreOrder::getPaid,false); + return update(lqw); + } + ///////////////////////////////////////////////////////////////////////////////////////////////////// 以下为自定义方法 /** @@ -1303,7 +1306,7 @@ public class StoreOrderServiceImpl extends ServiceImpl 0){ - BigDecimal useIntegral = BigDecimal.valueOf(storeOrder.getUseIntegral(),0); - currentUser.setIntegral(currentUser.getIntegral().subtract(useIntegral)); + Integer useIntegral = storeOrder.getUseIntegral(); + currentUser.setIntegral(currentUser.getIntegral() - useIntegral); userService.updateBase(currentUser); } userService.userPayCountPlus(currentUser); @@ -1684,111 +1687,61 @@ public class StoreOrderServiceImpl extends ServiceImpl i.or().eq("is_del", 1).or().eq("is_system_del", 1)); -// }else{ -// queryWrapper.eq("is_del", deleteStatus); -// } -// } - - - - } /** @@ -1868,11 +1821,21 @@ public class StoreOrderServiceImpl extends ServiceImpl spreadList = getSpreadList(user.getPath()); +// List spreadList = getSpread List(user.getPath()); List spreadList = getSpreadList(user.getSpreadUid()); if(null == spreadList || spreadList.size() < 1){ return; @@ -380,7 +376,6 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { return brokeragePrice; } - //查询对应等级的分销比例 String key = Constants.CONFIG_KEY_STORE_BROKERAGE_LEVEL.replace("num", i.toString()); if (i == 1) { @@ -426,68 +421,31 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { /** * 通过分佣等级关系计算需要拿到分佣的用户数据 * @param spreadId String 推广人ID - * @author Mr.Zhang - * @since 2020-07-09 - * @return BigDecimal */ - // * @param path String 推广人关系 /0/1/2/3/4/ private List getSpreadList(Integer spreadId) { - try{ + List spreadList = CollUtil.newArrayList(); + User spreadUser = userService.getById(spreadId); + if (ObjectUtil.isEmpty(spreadUser)) { + return spreadList; + } + if (!spreadUser.getIsPromoter()) { + spreadList.add(0); + } else { + spreadList.add(spreadId); + } + if (ObjectUtil.isNull(spreadUser.getSpreadUid()) || spreadUser.getSpreadUid() == 0) { + return spreadList; + } -// List spreadList = CrmebUtil.stringToArrayByRegex(path, "/"); -// if(spreadList.size() < 1){ -// return null; -// } -// //去拿所有是分销员的信息 -// HashMap mapListInUidList = userService.getMapListInUid(spreadList); -// if(null == mapListInUidList){ -// return null; -// } -// -// Collections.reverse(spreadList); // 倒序 -// -// //分佣级别 -// int level = 2; -// int i = 0; -// -// //超过返佣等级去除掉 -// for (Integer spreadId : spreadList) { -// if(level <= i){ -// spreadList.remove(i); -// } -// -// //不是推广员,没有找到用户数据去,把推广人id设置为0 -// if(!mapListInUidList.containsKey(spreadId) || !mapListInUidList.get(spreadId).getIsPromoter()){ -// spreadList.set(i, 0); -// } -// i++; -// } - List spreadList = CollUtil.newArrayList(); - User spreadUser = userService.getById(spreadId); - if (ObjectUtil.isEmpty(spreadUser)) { - return null; - } - if (!spreadUser.getIsPromoter()) { + User spreadSpreadUser = userService.getById(spreadUser.getSpreadUid()); + if (ObjectUtil.isNotNull(spreadSpreadUser)) { + if (!spreadSpreadUser.getIsPromoter()) { spreadList.add(0); } else { - spreadList.add(spreadId); + spreadList.add(spreadSpreadUser.getUid()); } - if (ObjectUtil.isNull(spreadUser.getSpreadUid()) || spreadUser.getSpreadUid() == 0) { - return spreadList; - } - - User spreadSpreadUser = userService.getById(spreadUser.getSpreadUid()); - if (ObjectUtil.isNotEmpty(spreadSpreadUser)) { - if (!spreadSpreadUser.getIsPromoter()) { - spreadList.add(0); - } else { - spreadList.add(spreadSpreadUser.getUid()); - } - } - return spreadList; - }catch (Exception e){ - return null; } + return spreadList; } @@ -564,7 +522,7 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { * 回滚库存 * @param storeOrder 订单信息 */ - private Boolean rollbackStock(StoreOrder storeOrder) { + private Boolean rollbackStock(StoreOrder storeOrder) { try{ // 查找出商品详情 List orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId()); @@ -655,7 +613,6 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { //回滚使用积分 if(storeOrder.getUseIntegral() > 0){ //有退积分操作, 那么用户使用的积分会减少 -// storeOrder.setUseIntegral(storeOrder.getUseIntegral()- (storeOrder.getBackIntegral())); storeOrder.setBackIntegral(storeOrder.getUseIntegral()); } setIntegral(storeOrder, 1); @@ -675,4 +632,325 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { //回滚用户已使用的优惠券 couponUserService.rollbackByCancelOrder(storeOrder); } + + /** + * 订单退款处理 + * 退款得时候根据userBill 来进行回滚 + */ + @Override + public Boolean refundOrder(StoreOrder storeOrder) { + /** + * 1、写订单日志 + * 2、回滚消耗积分 + * 3、回滚获得积分 + * 4、回滚冻结期佣金 + * 5、回滚经验 + * 6、回滚库存 + * 7、发送通知 + * 实际上2-5就是user数据的处理+userBill的记录 + */ + // 获取用户对象 + User user = userService.getById(storeOrder.getUid()); + if (ObjectUtil.isNull(user)) { + logger.error("订单退款处理,对应的用户不存在,storeOrder===>" + storeOrder); + return Boolean.FALSE; + } + + List userBillList = CollUtil.newArrayList(); + + //回滚积分 消耗和获得 + // 通过userBill记录获取订单之前处理的记录 + List userBills = userBillService.findListByOrderIdAndUid(storeOrder.getId(), storeOrder.getUid()); + + // 回滚经验 + List experienceList = userBills.stream().filter(e -> e.getCategory().equals(Constants.USER_BILL_CATEGORY_EXPERIENCE)).collect(Collectors.toList()); + experienceList.forEach(bill -> { + user.setExperience(user.getExperience() - bill.getNumber().intValue()); + + UserBill userBill = new UserBill(); + BeanUtils.copyProperties(bill, userBill); + userBill.setId(null); + userBill.setTitle(Constants.ORDER_STATUS_STR_REFUNDED); + userBill.setPm(0); + userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_REFUND); + userBill.setBalance(new BigDecimal(user.getExperience())); + userBill.setMark(StrUtil.format("订单退款,扣除{}赠送经验", bill.getNumber().intValue())); + userBill.setStatus(1); + userBillList.add(userBill); + }); + + // 回滚积分 + List integralList = userBills.stream().filter(e -> e.getCategory().equals(Constants.USER_BILL_CATEGORY_INTEGRAL)).collect(Collectors.toList()); + integralList.forEach(bill -> { + UserBill userBill = new UserBill(); + BeanUtils.copyProperties(bill, userBill); + if (bill.getPm() == 0) {// 返还用户使用的积分 + user.setIntegral(user.getIntegral() + bill.getNumber().intValue()); + userBill.setId(null); + userBill.setTitle(Constants.ORDER_STATUS_STR_REFUNDED); + userBill.setPm(1); + userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_REFUND); + userBill.setBalance(new BigDecimal(user.getIntegral())); + userBill.setMark(StrUtil.format("订单退款,返还{}支付扣除积分", bill.getNumber().intValue())); + userBill.setStatus(1); + userBillList.add(userBill); + } + if (bill.getPm() == 1) {// 回滚之前获得的积分 + user.setIntegral(user.getIntegral() - bill.getNumber().intValue()); + userBill.setId(null); + userBill.setTitle(Constants.ORDER_STATUS_STR_REFUNDED); + userBill.setPm(0); + userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_REFUND); + userBill.setBalance(new BigDecimal(user.getIntegral())); + userBill.setMark(StrUtil.format("订单退款,扣除{}订单赠送积分", bill.getNumber().intValue())); + userBill.setStatus(1); + userBillList.add(userBill); + } + }); + + StoreOrder tempOrder = new StoreOrder(); + tempOrder.setId(storeOrder.getId()); + tempOrder.setRefundStatus(2); + // 回滚佣金 TODO 这里之后处理 + + Boolean execute = transactionTemplate.execute(e -> { + //写订单日志 + storeOrderStatusService.saveRefund(storeOrder.getId(), storeOrder.getRefundPrice(), "成功"); + + // 更新用户数据 + userService.updateById(user); + + // 用户账单记录处理 + userBillService.saveBatch(userBillList); + + //回滚冻结期佣金 + rollbackBrokeragePrice(storeOrder); + + // 回滚库存 + rollbackStock(storeOrder); + + storeOrderService.updateById(tempOrder); + return Boolean.TRUE; + }); + + if (execute) { + // 发送通知 + } + + return execute; + } + + /** + * 订单支付成功后置处理 + * @param storeOrder + * @return + */ + @Override + public Boolean paySuccessAfter(StoreOrder storeOrder) { + return orderPayService.paySuccess(storeOrder); + } + + /** + * 回滚佣金 + * @param storeOrder 订单信息 + * @param user 订单用户 + */ + private void rollbackBrokeragePrice(StoreOrder storeOrder, User user) { + //计算分销人 + List spreadList = getSpreadList(user.getSpreadUid()); + if(null == spreadList || spreadList.size() < 1){ + return; + } + //资金明细加一条数据 + UserOperateFundsRequest userOperateFundsRequest = new UserOperateFundsRequest(); + userOperateFundsRequest.setLinkId(storeOrder.getId().toString()); + userOperateFundsRequest.setTitle("推广佣金"); + userOperateFundsRequest.setFoundsCategory(Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE); + userOperateFundsRequest.setFoundsType(Constants.USER_BILL_TYPE_BROKERAGE); + userOperateFundsRequest.setType(0); + + + //计算每个人的佣金 + int i = 1; + for (Integer spreadId: spreadList) { + if(spreadId < 1){ + continue; + } + //大于0的用户开始计算佣金, 并更新数据库 + BigDecimal brokeragePrice = getBrokeragePriceByOrder(i, storeOrder.getId()); + User userInfo = userService.getById(spreadId); + userInfo.setBrokeragePrice(userInfo.getBrokeragePrice().add(brokeragePrice)); + + //获得推广佣金 + userOperateFundsRequest.setUid(spreadId); + userOperateFundsRequest.setValue(brokeragePrice); + userService.updateFounds(userOperateFundsRequest, true); + i++; + } + } + + /** + * 检查是否需要回滚佣金 + * @param storeOrder 订单 + * @param user + */ + private Boolean checkRollbackBrokeragePrice(StoreOrder storeOrder, User user) { + //营销产品不参与 + if(storeOrder.getCombinationId() > 0 || storeOrder.getSeckillId() > 0 || storeOrder.getBargainId() > 0){ + return Boolean.FALSE; + } + + //当前用户不存在 没有上级 或者 当用用户上级时自己 直接返回 + if(user.getSpreadUid() < 1 || null == user.getSpreadUid() || 0 == user.getSpreadUid() || user.getSpreadUid().equals(storeOrder.getUid())){ + return Boolean.FALSE; + } + + //检测商城是否开启分销功能 + String isOpen = systemConfigService.getValueByKey(Constants.CONFIG_KEY_STORE_BROKERAGE_IS_OPEN); + if(StringUtils.isBlank(isOpen) || isOpen.equals("0")){ + return Boolean.FALSE; + } + + // 查看是否在冻结期之内, 如果在是需要回滚的,如果不在则不需要回滚 + String time = systemConfigService.getValueByKey(Constants.CONFIG_KEY_STORE_BROKERAGE_EXTRACT_TIME); + if(StringUtils.isBlank(time)){ + return Boolean.FALSE; + } + DateTime patTime = cn.hutool.core.date.DateUtil.offsetDay(storeOrder.getPayTime(), Integer.parseInt(time)); + long between = cn.hutool.core.date.DateUtil.between(patTime, DateUtil.nowDateTime(), DateUnit.MS, false); + if (between < 0) { + return Boolean.FALSE; + } + return Boolean.TRUE; + } + + /** + * 创建退款UserBill对象(包含积分、佣金、经验) + * @param storeOrder 订单 + * @param user 用户 + * @param category 分类 + * @param pm 1 = 增加, 0 = 减少 + * + */ + private UserBill createRefundUserBill(StoreOrder storeOrder, User user, String category, Integer pm) { + UserBill userBill = new UserBill(); + BigDecimal balance = getUserBalance(user, category); + userBill.setTitle(Constants.ORDER_STATUS_STR_REFUNDED); + userBill.setUid(storeOrder.getUid()); + userBill.setCategory(category); + userBill.setLinkId(storeOrder.getOrderId()); //链接id + userBill.setPm(pm); + userBill.setBalance(balance); + switch (category) { + case Constants.USER_BILL_CATEGORY_INTEGRAL:// 积分 + userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_INTEGRAL_BACK); + if (pm.equals(1)) {// 返还积分 + userBill.setNumber(new BigDecimal(storeOrder.getUseIntegral())); + } else {// 扣除奖励积分 + userBill.setNumber(new BigDecimal(storeOrder.getGainIntegral())); + } + userBill.setMark(getMark(userBill)); + break; + case Constants.USER_BILL_CATEGORY_EXPERIENCE:// 经验 + break; + case Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE:// 佣金 + break; + case Constants.USER_BILL_CATEGORY_MONEY:// 余额 + break; + } + return userBill; + } + + /** + * 获取用户剩余 + * @param user 用户 + * @param category 分类 + * @return BigDecimal + */ + private BigDecimal getUserBalance(User user, String category) { + BigDecimal value = BigDecimal.ZERO; + switch (category) { + case Constants.USER_BILL_CATEGORY_INTEGRAL:// 积分 + value = new BigDecimal(user.getIntegral()); + break; + case Constants.USER_BILL_CATEGORY_EXPERIENCE:// 经验 + value = new BigDecimal(user.getExperience()); + break; + case Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE:// 佣金 + value = user.getBrokeragePrice(); + break; + case Constants.USER_BILL_CATEGORY_MONEY:// 余额 + value = user.getNowMoney(); + break; + } + return value; + } + + private String getMark(UserBill userBill) { + String operate = (userBill.getPm() == 1) ? "增加" : "减少"; + String founds = ""; + switch (userBill.getCategory()){ + case Constants.USER_BILL_CATEGORY_INTEGRAL: + founds = "积分"; + break; + case Constants.USER_BILL_CATEGORY_MONEY: + founds = "余额"; + break; + case Constants.USER_BILL_CATEGORY_EXPERIENCE: + founds = "经验"; + break; + case Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE: + founds = "佣金"; + break; + } + + return Constants.USER_BILL_OPERATE_LOG_TITLE.replace("{$title}", userBill.getTitle()).replace("{$operate}", operate).replace("{$founds}", founds); + } + + /** + * 计算佣金 + * @param i Integer 分销员等级 + * @param id Integer 订单id + */ + private BigDecimal getBrokeragePrice(Integer i, Integer id) { + BigDecimal brokeragePrice = BigDecimal.ZERO; + + //先看商品是否有固定分佣 + List orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(id); + if(null == orderInfoVoList || orderInfoVoList.size() < 1){ + return brokeragePrice; + } + + //查询对应等级的分销比例 + String key = ""; + if (i == 1) { + key = Constants.CONFIG_KEY_STORE_BROKERAGE_RATE_ONE; + } + if (i == 2) { + key = Constants.CONFIG_KEY_STORE_BROKERAGE_RATE_TWO; + } + String rate = systemConfigService.getValueByKey(key); + if(StrUtil.isBlank(rate)){ + return brokeragePrice; + } + //佣金比例整数存储, 例如80, 所以计算的时候要除以 10*10 + BigDecimal rateBigDecimal = new BigDecimal(rate).divide(new BigDecimal(100)); + + BigDecimal totalBrokerPrice = BigDecimal.ZERO; + for (StoreOrderInfoVo orderInfoVo : orderInfoVoList) { + if(i == 1){ + brokeragePrice = orderInfoVo.getInfo().getProductInfo().getAttrInfo().getBrokerage(); + }else if(i == 2){ + brokeragePrice = orderInfoVo.getInfo().getProductInfo().getAttrInfo().getBrokerageTwo(); + } + + if(brokeragePrice.compareTo(BigDecimal.ZERO) == 0 && !rateBigDecimal.equals(BigDecimal.ZERO)){ + //商品没有分销金额, 并且有设置对应等级的分佣比例 + brokeragePrice = orderInfoVo.getInfo().getTruePrice().multiply(rateBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP); + } + + totalBrokerPrice = totalBrokerPrice.add(brokeragePrice); + } + return totalBrokerPrice; + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderVerificationImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderVerificationImpl.java index f479e681..f8bfbdec 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderVerificationImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreOrderVerificationImpl.java @@ -188,21 +188,13 @@ public class StoreOrderVerificationImpl implements StoreOrderVerification { @Override public boolean verificationOrderByCode(String vCode) { StoreOrderVerificationConfirmResponse existOrder = getVerificationOrderByCode(vCode); - if(existOrder.getCombinationId() >0 && existOrder.getPinkId() > 0){ - // todo 营销业务待处理 - } // 判断当前用户是否有权限核销 SystemAdmin currentAdmin = systemAdminService.getInfo(); -// List currentIds = new ArrayList<>(); -// currentIds.add(currentAdmin.getId()); -// List currentStaffs = systemStoreStaffService.getByAdminUserIds(currentIds); -// if(currentStaffs.size() == 0) throw new CrmebException(Constants.RESULT_VERIFICATION_NOTAUTH); // 添加核销人员后执行核销操作 StoreOrder storeOrder = new StoreOrder(); BeanUtils.copyProperties(existOrder,storeOrder); storeOrder.setStatus(Constants.ORDER_STATUS_INT_BARGAIN); -// storeOrder.setClerkId(currentStaffs.get(0).getId()); -// storeOrder.setStoreId(currentStaffs.get(0).getStoreId()); + storeOrder.setClerkId(currentAdmin.getId()); boolean saveStatus = dao.updateById(storeOrder) > 0; // 小程序订阅消息发送 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductAttrValueServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductAttrValueServiceImpl.java index fd99b0ee..d9f758e3 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductAttrValueServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductAttrValueServiceImpl.java @@ -1,7 +1,9 @@ package com.zbkj.crmeb.store.service.impl; +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.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.common.PageParamRequest; @@ -9,6 +11,7 @@ import com.constants.Constants; import com.exception.CrmebException; import com.github.pagehelper.Constant; import com.github.pagehelper.PageHelper; +import com.zbkj.crmeb.seckill.model.StoreSeckill; import com.zbkj.crmeb.store.dao.StoreProductAttrValueDao; import com.zbkj.crmeb.store.model.StoreProductAttrValue; import com.zbkj.crmeb.store.request.StoreProductAttrValueSearchRequest; @@ -170,5 +173,68 @@ public class StoreProductAttrValueServiceImpl extends ServiceImpl 0; } + + /** + * 根据id、类型查询 + * @param id ID + * @param type 类型 + * @return StoreProductAttrValue + */ + @Override + public StoreProductAttrValue getByIdAndProductIdAndType(Integer id, Integer productId, Integer type) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StoreProductAttrValue::getId, id); + lqw.eq(StoreProductAttrValue::getProductId, productId); + lqw.eq(StoreProductAttrValue::getType, type); + return dao.selectOne(lqw); + } + + /** + * 根据sku查询 + * @param productId 商品id + * @param suk sku + * @param type 规格类型 + * @return StoreProductAttrValue + */ + @Override + public StoreProductAttrValue getByProductIdAndSkuAndType(Integer productId, String suk, Integer type) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StoreProductAttrValue::getProductId, productId); + lqw.eq(StoreProductAttrValue::getSuk, suk); + lqw.eq(StoreProductAttrValue::getType, type); + return dao.selectOne(lqw); + } + + /** + * 添加(退货)/扣减库存 + * @param id 秒杀商品id + * @param num 数量 + * @param operationType 类型:add—添加,sub—扣减 + * @param type 活动类型 0=商品,1=秒杀,2=砍价,3=拼团 + * @return Boolean + */ + @Override + public Boolean operationStock(Integer id, Integer num, String operationType, Integer type) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + if (operationType.equals("add")) { + updateWrapper.setSql(StrUtil.format("stock = stock + {}", num)); + updateWrapper.setSql(StrUtil.format("sales = sales - {}", num)); + if (type > 0) { + updateWrapper.setSql(StrUtil.format("quota = quota + {}", num)); + } + } + if (operationType.equals("sub")) { + updateWrapper.setSql(StrUtil.format("stock = stock - {}", num)); + updateWrapper.setSql(StrUtil.format("sales = sales + {}", num)); + if (type > 0) { + updateWrapper.setSql(StrUtil.format("quota = quota - {}", num)); + } + // 扣减时加乐观锁保证库存不为负 + updateWrapper.last(StrUtil.format("and (stock - {} >= 0)", num)); + } + updateWrapper.eq("id", id); + updateWrapper.eq("type", type); + return update(updateWrapper); + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductReplyServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductReplyServiceImpl.java index 7c1d418f..50d3cfed 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductReplyServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductReplyServiceImpl.java @@ -149,9 +149,7 @@ public class StoreProductReplyServiceImpl extends ServiceImpl dataList = dao.selectList(lambdaQueryWrapper); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductServiceImpl.java index 0aae0681..c710ff21 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/service/impl/StoreProductServiceImpl.java @@ -1,5 +1,6 @@ package com.zbkj.crmeb.store.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; @@ -7,6 +8,7 @@ import com.alibaba.fastjson.JSONObject; 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; @@ -42,7 +44,7 @@ import com.zbkj.crmeb.store.service.*; import com.zbkj.crmeb.store.utilService.ProductUtils; import com.zbkj.crmeb.system.service.SystemAttachmentService; import com.zbkj.crmeb.system.service.SystemConfigService; -import com.zbkj.crmeb.task.order.OrderRefundByUser; +import com.zbkj.crmeb.task.order.OrderRefundTask; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -124,7 +126,7 @@ public class StoreProductServiceImpl extends ServiceImpl cg = categoryService.getByIds(CrmebUtil.stringToArray(product.getCateId())); - StringBuilder sb = new StringBuilder(); - for (Category category : cg) { - sb.append(sb.length() == 0 ? category.getName(): category.getName()+","); +// StringBuilder sb = new StringBuilder(); +// for (Category category : cg) { +// sb.append(sb.length() == 0 ? category.getName(): category.getName()+","); +// } + if (CollUtil.isEmpty(cg)) { + storeProductResponse.setCateValues(""); + } else { + storeProductResponse.setCateValues(cg.stream().map(Category::getName).collect(Collectors.joining(","))); } - storeProductResponse.setCateValues(sb.toString()); storeProductResponse.setCollectCount( storeProductRelationService.getList(product.getId(),"collect").size()); @@ -823,23 +829,15 @@ public class StoreProductServiceImpl extends ServiceImpl existAttrValues = storeProductAttrValueService.getByEntity(spavPram); -// if(null == existAttrValues && existAttrValues.size() == 0) throw new CrmebException("未找到相关商品属性信息"); - -// StoreProductAttrValue productsInAttrValue = existAttrValues.get(0); + StoreProductAttrValue productsInAttrValue = storeProductAttrValueService.getById(attrValueId); StoreProduct storeProduct = getById(productId); - boolean result = false; - if(null != productsInAttrValue){ - result = storeProductAttrValueService.decProductAttrStock(productId,attrValueId,num,type); - } + boolean result = storeProductAttrValueService.decProductAttrStock(productId,attrValueId,num,type); + if (!result) return result; LambdaUpdateWrapper lqwuper = new LambdaUpdateWrapper<>(); - lqwuper.eq(StoreProduct::getId, productId); lqwuper.set(StoreProduct::getStock, storeProduct.getStock()-num); lqwuper.set(StoreProduct::getSales, storeProduct.getSales()+num); + lqwuper.eq(StoreProduct::getId, productId); + lqwuper.apply(StrUtil.format(" (stock - {} >= 0) ", num)); result = update(lqwuper); if(result){ //判断库存警戒值 Integer alterNumI=0; @@ -1091,5 +1089,28 @@ public class StoreProductServiceImpl extends ServiceImpl updateWrapper = new UpdateWrapper<>(); + if (type.equals("add")) { + updateWrapper.setSql(StrUtil.format("stock = stock + {}", num)); + updateWrapper.setSql(StrUtil.format("sales = sales - {}", num)); + } + if (type.equals("sub")) { + updateWrapper.setSql(StrUtil.format("stock = stock - {}", num)); + updateWrapper.setSql(StrUtil.format("sales = sales + {}", num)); + // 扣减时加乐观锁保证库存不为负 + updateWrapper.last(StrUtil.format(" and (stock - {} >= 0)", num)); + } + updateWrapper.eq("id", id); + return update(updateWrapper); + } + } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/OrderUtils.java b/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/OrderUtils.java index 21d6aefc..3063e0e0 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/OrderUtils.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/OrderUtils.java @@ -1,13 +1,15 @@ package com.zbkj.crmeb.store.utilService; 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.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +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; @@ -18,7 +20,6 @@ import com.zbkj.crmeb.bargain.service.StoreBargainService; import com.zbkj.crmeb.bargain.service.StoreBargainUserHelpService; 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.express.model.ShippingTemplates; @@ -55,7 +56,6 @@ import com.zbkj.crmeb.system.service.SystemGroupDataService; import com.zbkj.crmeb.system.service.SystemStoreService; import com.zbkj.crmeb.user.model.User; import com.zbkj.crmeb.user.model.UserAddress; -import com.zbkj.crmeb.user.model.UserBill; import com.zbkj.crmeb.user.service.UserAddressService; import com.zbkj.crmeb.user.service.UserBillService; import com.zbkj.crmeb.user.service.UserService; @@ -69,6 +69,7 @@ import org.apache.commons.lang3.StringUtils; 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.*; @@ -167,6 +168,22 @@ public class OrderUtils { @Autowired private StorePinkService storePinkService; + @Autowired + private TransactionTemplate transactionTemplate; + + /** + * 检测支付渠道 + * @param payChannel 支付渠道 + */ + public static boolean checkPayChannel(String payChannel) { + if (!payChannel.equals(PayConstants.PAY_CHANNEL_WE_CHAT_H5) && + !payChannel.equals(PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM) && + !payChannel.equals(PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC)) { + return false; + } + return true; + } + // 组装数据给前端使用 public OrderAgainVo tidyOrder(StoreOrder storeOrder, boolean detail, boolean isPic){ OrderAgainVo orderAgainVoResult = new OrderAgainVo(); @@ -288,32 +305,30 @@ public class OrderUtils { * 缓存订单并做计算 * @param request */ - public ComputeOrderResponse computedOrder(OrderCreateRequest request, ConfirmOrderResponse cor, String orderKey){ + public ComputeOrderResponse computedOrder(OrderCreateRequest request, ConfirmOrderResponse cor, String orderKey, User currentUser){ // 检查订单是否存在 - User current = userService.getInfo(); - if(checkOrderExist(orderKey, current.getUid())) throw new CrmebException(orderKey + "订单已存在"); + if(checkOrderExist(orderKey, currentUser.getUid())) throw new CrmebException(orderKey + "订单已存在"); // 需要return的自定义变量 - BigDecimal couponPrice = BigDecimal.ZERO; - Integer surPlusIntegral = 0; - BigDecimal deductionPrice = BigDecimal.ZERO; - Integer usedIntegral = 0; - BigDecimal payPrice = cor.getPriceGroup().getTotalPrice(); - - User currentUser = userService.getInfo(); - if(null == currentUser) throw new CrmebException("用户不存在"); + BigDecimal couponPrice = BigDecimal.ZERO;// 优惠券金额 + Integer surPlusIntegral = 0;// 剩余积分 + BigDecimal deductionPrice;// 抵扣金额 + Integer usedIntegral = 0;// 使用积分 + BigDecimal payPrice = cor.getPriceGroup().getTotalPrice();// 支付金额 + // 线下支付状态 Integer offliePayStatus = Integer.valueOf(systemConfigService.getValueByKey("offline_pay_status")); - PriceGroupResponse currentOrderPriceGroup = getOrderPriceGroup(cor.getCartInfo(), null); + PriceGroupResponse currentOrderPriceGroup; - List exsitPayType = getPayType().stream().filter(e->{ - if(offliePayStatus == 2 && e == Constants.PAY_TYPE_OFFLINE){ + // TODO 订单支付类型判断应该在外层 + List existPayType = getPayType().stream().filter(e->{ + if(offliePayStatus == 2 && e.equals(Constants.PAY_TYPE_OFFLINE)){ return false; } return true; }).distinct().collect(Collectors.toList()); - if(exsitPayType.size() == 0) throw new CrmebException("选择支付方式有误"); + if(CollUtil.isEmpty(existPayType)) throw new CrmebException("选择支付方式有误"); // 检测订单是否重复提交 if(checkOrderSubmitAgain(orderKey)) throw new CrmebException("请勿重复提交订单"); @@ -368,8 +383,8 @@ public class OrderUtils { } // 积分 - if(null != request.getUseIntegral() && currentUser.getIntegral().compareTo(BigDecimal.ZERO) > 0){ - deductionPrice = currentUser.getIntegral().multiply(BigDecimal.valueOf(Double.valueOf(cor.getOther().get("integralRatio").toString()))); + if(null != request.getUseIntegral() && currentUser.getIntegral() > 0){ + deductionPrice = new BigDecimal(currentUser.getIntegral()).multiply(BigDecimal.valueOf(Double.valueOf(cor.getOther().get("integralRatio").toString()))); if(request.getUseIntegral()){ // 积分兑换金额小于实际支付金额 if(deductionPrice.compareTo(payPrice) < 0){ @@ -378,7 +393,7 @@ public class OrderUtils { }else{ deductionPrice = payPrice; if(payPrice.compareTo(BigDecimal.ZERO) > 0){ - usedIntegral = payPrice.multiply(BigDecimal.valueOf(Double.valueOf(cor.getOther().get("integralRatio").toString()))).setScale(0, BigDecimal.ROUND_UP).intValue(); + usedIntegral = payPrice.divide(BigDecimal.valueOf(Double.parseDouble(cor.getOther().get("integralRatio").toString()))).setScale(0, BigDecimal.ROUND_UP).intValue(); surPlusIntegral = currentUser.getIntegral().intValue() - usedIntegral; } payPrice = BigDecimal.ZERO; @@ -420,78 +435,470 @@ public class OrderUtils { */ @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class}) public StoreOrder createOrder(OrderCreateRequest request,ConfirmOrderResponse cor, Integer isChannel,Integer orderId, String orderKey){ - UserAddress currentUserAddress = new UserAddress(); - List cartIds = new ArrayList<>(); - Integer totalNum = 0; - Integer gainIntegral = 0; +// UserAddress currentUserAddress = new UserAddress(); +// List cartIds = new ArrayList<>(); +// Integer totalNum = 0; +// Integer gainIntegral = 0; +// +// if(request.getShippingType() == 1){ // 是否包邮 +// if(request.getAddressId() <= 0) throw new CrmebException("请选择收货地址"); +// UserAddress userAddress = new UserAddress(); +// userAddress.setId(request.getAddressId()); +// userAddress.setIsDel(false); +// currentUserAddress = userAddressService.getUserAddress(userAddress); +// if(null == currentUserAddress){ +// throw new CrmebException("收货地址有误"); +// } +// }else if(request.getShippingType() == 2){ // 到店自提 +// if(StringUtils.isBlank(request.getRealName()) || StringUtils.isBlank(request.getPhone())) +// throw new CrmebException("请填写姓名和电话"); +// +// currentUserAddress.setRealName(request.getRealName()); +// currentUserAddress.setPhone(request.getPhone()); +// } +// for (StoreCartResponse cartResponse : cor.getCartInfo()) { +// cartIds.add(cartResponse.getSeckillId()); +// totalNum += cartResponse.getCartNum(); +// +// Integer cartInfoGainIntegral = +// (cartResponse.getProductInfo().getGiveIntegral() != null && cartResponse.getProductInfo().getGiveIntegral() > 0 )? +// cartResponse.getProductInfo().getGiveIntegral() * cartResponse.getCartNum() +// : 0; +// gainIntegral = gainIntegral + cartInfoGainIntegral; +// } +// // todo 检测营销产品状态 +// // 发快递还是门店自提 +// String storeSelfMention = systemConfigService.getValueByKey("store_self_mention"); +// if(!Boolean.valueOf(storeSelfMention)) request.setShippingType(1); +// +// StoreOrder storeOrder = new StoreOrder(); +// storeOrder.setUid(cor.getUserInfo().getUid()); +// storeOrder.setOrderId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT)); +// +// // 后置选择收货地址信息 +// if(null == cor.getAddressInfo() && request.getAddressId() > 0){ +// UserAddress selectUserAddress = userAddressService.getById(request.getAddressId()); +// cor.setAddressInfo(selectUserAddress); +// } +// +// storeOrder.setRealName(currentUserAddress.getRealName()); +// storeOrder.setUserPhone(currentUserAddress.getPhone()); +// storeOrder.setUserAddress(cor.getAddressInfo().getProvince() +// + cor.getAddressInfo().getCity() +// + cor.getAddressInfo().getDistrict() +// + cor.getAddressInfo().getDetail()); +//// storeOrder.setCarId(cartIds); +// storeOrder.setTotalNum(totalNum); +// BigDecimal mapTotalPrice = cor.getPriceGroup().getTotalPrice(); +// BigDecimal mapStorePostage = cor.getPriceGroup().getStorePostage(); +// BigDecimal mapCouponPrice = cor.getPriceGroup().getCouponPrice(); +// BigDecimal mapPayPrice = cor.getPriceGroup().getPayPrice(); +// BigDecimal mapPayPostage = cor.getPriceGroup().getPayPostage(); +// BigDecimal mapDeductionPrice = cor.getPriceGroup().getDeductionPrice(); +// Integer mapUsedIntegral = cor.getPriceGroup().getUsedIntegral(); +// BigDecimal mapCostPrice = cor.getPriceGroup().getCostPrice(); +// +// int couponId = null == cor.getUsableCoupon() ? 0: cor.getUsableCoupon().getId(); +// storeOrder.setTotalPrice(mapTotalPrice); +// storeOrder.setTotalPostage(mapStorePostage); +// storeOrder.setCouponId(couponId); +// storeOrder.setCouponPrice(mapCouponPrice); +// storeOrder.setPayPrice(mapPayPrice); +// storeOrder.setPayPostage(mapPayPostage); +// storeOrder.setDeductionPrice(mapDeductionPrice); +//// storeOrder.setPaid(false); +// storeOrder.setPayType(request.getPayType()); +// storeOrder.setUseIntegral(mapUsedIntegral); +// storeOrder.setGainIntegral(gainIntegral); +// storeOrder.setMark(StringEscapeUtils.escapeHtml4(request.getMark())); +// storeOrder.setCombinationId(request.getCombinationId()); +// storeOrder.setPinkId(request.getPinkId()); +// storeOrder.setSeckillId(request.getSeckillId()); +// storeOrder.setBargainId(request.getBargainId()); +// storeOrder.setCost(mapCostPrice); +// storeOrder.setIsChannel(isChannel); +// storeOrder.setCreateTime(DateUtil.nowDateTime()); +// storeOrder.setUnique(orderKey); +// storeOrder.setShippingType(request.getShippingType()); +// storeOrder.setPinkId(request.getPinkId()); +// +// // 如果是自提 +// if(request.getShippingType() == 2){ +// storeOrder.setVerifyCode(CrmebUtil.randomCount(1111111111,999999999)+""); +// SystemStore systemStore = new SystemStore(); +// systemStore.setId(request.getStoreId()); +// systemStore.setIsShow(true); +// systemStore.setIsDel(false); +// SystemStore existSystemStore = systemStoreService.getByCondition(systemStore); +// if(null == existSystemStore) throw new CrmebException("暂无门店无法选择门店自提"); +// storeOrder.setStoreId(existSystemStore.getId()); +// } +// boolean createdResult = storeOrderService.create(storeOrder); +// if(!createdResult) throw new CrmebException("订单生成失败"); +// +// // 积分抵扣 +// boolean disIntegle = true; +// User currentUser = userService.getInfo(); +// if(request.getUseIntegral() && currentUser.getIntegral() > 0){ +// BigDecimal deductionPrice = BigDecimal.ZERO; +// if(null != cor.getPriceGroup().getUsedIntegral()){ +// deductionPrice = BigDecimal.valueOf(cor.getPriceGroup().getUsedIntegral(),2); +// if(cor.getPriceGroup().getUsedIntegral() > 0){ +// currentUser.setIntegral(0); +// disIntegle = userService.updateBase(currentUser); +// }else{ +// if(currentUser.getIntegral() < deductionPrice.intValue()){ +// currentUser.setIntegral(currentUser.getIntegral() - deductionPrice.intValue()); +// disIntegle = userService.updateBase(currentUser); +// } +// } +// } +// UserBill userBill = new UserBill(); +// userBill.setTitle("积分抵扣"); +// userBill.setUid(currentUser.getUid()); +// userBill.setCategory("integral"); +// userBill.setType("deduction"); +// userBill.setNumber(deductionPrice); +// userBill.setLinkId(orderId+""); +// userBill.setBalance(new BigDecimal(currentUser.getIntegral())); +// +// userBill.setMark("购买商品使用"+userBill.getNumber()+"积分抵扣"+deductionPrice+"元"); +// boolean userBillSaveResult = userBillService.save(userBill); +// disIntegle = disIntegle && userBillSaveResult; +// } +// if(!disIntegle) throw new CrmebException("使用积分抵扣失败"); +// +// Integer secKillId = null; +// List storeOrderInfos = new ArrayList<>(); +// boolean deCountResult = true; +// for (StoreCartResponse cartResponse : cor.getCartInfo()) { +// StoreOrderInfo soInfo = new StoreOrderInfo(); +// // 秒杀商品扣减库存 +// if(null != cartResponse.getSeckillId() && cartResponse.getSeckillId() > 0){ +// secKillId = cartResponse.getSeckillId(); +// // 秒杀商品本身库存扣减 +// deCountResult = storeSeckillService.decProductStock( +// cartResponse.getSeckillId(), +// cartResponse.getCartNum(), +// Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_SECKILL); +// // 商品本身扣减库存 更新商品本身库存步骤 1=根据秒杀uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 +// // 秒杀对应商品库存扣减 +// StoreProductAttrValue currentSeckillAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); +// List currentSeckillAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); +// List existAttrValues = currentSeckillAttrValues.stream().filter(e -> +// e.getSuk().equals(currentSeckillAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) +// .collect(Collectors.toList()); +// if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); +// deCountResult = storeProductService.decProductStock( +// existAttrValues.get(0).getProductId(), +// cartResponse.getCartNum(), +// existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); +// +// }else if (ObjectUtil.isNotNull(cartResponse.getBargainId()) && cartResponse.getBargainId() > 0) { +// // 砍价扣减库存 +// Integer bargainId = cartResponse.getBargainId(); +// // 砍价商品扣减库存 +// deCountResult = storeBargainService.decProductStock( +// cartResponse.getBargainId(), +// cartResponse.getCartNum(), +// Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_BARGAIN); +// // 商品本身扣减库存 更新商品本身库存步骤 1=根据秒杀uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 +// // 砍价对应商品库存扣减 +// StoreProductAttrValue currentSeckillAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); +// List currentBargainAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); +// List existAttrValues = currentBargainAttrValues.stream().filter(e -> +// e.getSuk().equals(currentSeckillAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) +// .collect(Collectors.toList()); +// if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); +// deCountResult = storeProductService.decProductStock( +// existAttrValues.get(0).getProductId(), +// cartResponse.getCartNum(), +// existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); +// +// // 砍价商品购买成功,改变用户状态 +// StoreBargainUser storeBargainUser = storeBargainUserService.getByBargainIdAndUid(cartResponse.getBargainId(), cor.getUserInfo().getUid()); +// storeBargainUser.setStatus(3); +// storeBargainUserService.updateById(storeBargainUser); +// }else if (ObjectUtil.isNotNull(cartResponse.getCombinationId()) && cartResponse.getCombinationId() > 0) { +// // 判断拼团团长是否存在 +// StorePink headPink = null; +// if (ObjectUtil.isNotNull(cartResponse.getPinkId()) && cartResponse.getPinkId() > 0) { +// headPink = storePinkService.getById(cartResponse.getPinkId()); +// if (ObjectUtil.isNull(headPink) || headPink.getIsRefund().equals(true) || headPink.getStatus() == 3) { +// throw new CrmebException("找不到对应的拼团团队信息"); +// } +// } +// // 拼团扣减库存 +// // 拼团商品本身库存扣减 +// deCountResult = storeCombinationService.decProductStock( +// cartResponse.getCombinationId(), +// cartResponse.getCartNum(), +// Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_PINGTUAN); +// // 商品本身扣减库存 更新商品本身库存步骤 1=根据拼团uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 +// // 拼团对应商品库存扣减 +// StoreProductAttrValue currentCombinationAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); +// List currentCombinationAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); +// List existAttrValues = currentCombinationAttrValues.stream().filter(e -> +// e.getSuk().equals(currentCombinationAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) +// .collect(Collectors.toList()); +// if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); +// deCountResult = storeProductService.decProductStock( +// existAttrValues.get(0).getProductId(), +// cartResponse.getCartNum(), +// existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); +// // 生成拼团表数据 +// StoreCombination storeCombination = storeCombinationService.getById(cartResponse.getCombinationId()); +// StorePink storePink = new StorePink(); +// storePink.setUid(cor.getUserInfo().getUid()); +// storePink.setAvatar(cor.getUserInfo().getAvatar()); +// storePink.setNickname(cor.getUserInfo().getNickname()); +// storePink.setOrderId(storeOrder.getOrderId()); +// storePink.setOrderIdKey(storeOrder.getId()); +// storePink.setTotalNum(storeOrder.getTotalNum()); +// storePink.setTotalPrice(storeOrder.getTotalPrice()); +// storePink.setCid(cartResponse.getCombinationId()); +// storePink.setPid(cartResponse.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(cartResponse.getPinkId()) && cartResponse.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(cartResponse.getPinkId()).orElse(0)); +// storePink.setIsTpl(false); +// storePink.setIsRefund(false); +// storePink.setStatus(1); +// storePinkService.save(storePink); +// +// // 如果是开团,需要更新订单数据 +// if (storePink.getKId() == 0) { +// storeOrder.setPinkId(storePink.getId()); +// storeOrderService.updateById(storeOrder); +// } +// }else { +// // 普通购买扣减库存 +// deCountResult = storeProductService.decProductStock( +// cartResponse.getProductId(), +// cartResponse.getCartNum(), +// Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_NORMAL); +// } +// soInfo.setOrderId(storeOrder.getId()); +// soInfo.setProductId(cartResponse.getProductId()); +// soInfo.setInfo(JSON.toJSON(cartResponse).toString()); +// soInfo.setUnique(cartResponse.getProductAttrUnique()); +// storeOrderInfos.add(soInfo); +// +// } +// // 保存购物车商品详情 +// boolean saveBatchOrderInfosResult = storeOrderInfoService.saveOrderInfos(storeOrderInfos); +// if(!saveBatchOrderInfosResult && !deCountResult){ +// throw new CrmebException("订单生成失败"); +// } +// +// // 删除缓存订单 +// cacheDeleteOrderInfo(currentUser.getUid(), orderKey); +// // 检查缺省的默认地址设置 +// UserAddress defaultAddress = userAddressService.getDefault(); +// if(null != defaultAddress){ +// userAddressService.def(cor.getAddressInfo().getId()); +// } +// storeOrderStatusService.createLog(storeOrder.getId(), +// Constants.ORDER_STATUS_CACHE_CREATE_ORDER,"订单生成"); +// return storeOrder; + return null; + } - if(request.getShippingType() == 1){ // 是否包邮 + /** + * 创建订单 + * @param request 订单创建参数 + * @param cor 缓存的购物车,价钱等信息集合 + * @param user 用户 + * @return 订单信息 + * 先扣减库存,需要使用乐观锁 + * 扣减库存成功后生成订单 + 保存其他数据 + */ + public StoreOrder createOrder_v131(OrderCreateRequest request, ConfirmOrderResponse cor, String orderKey, User user){ + // 收货信息 + UserAddress currentUserAddress = new UserAddress(); + // 购买总数量 + Integer totalNum = 0; + // 购买赠送的积分 + Integer gainIntegral = 0; + // 核销码 + String verifyCode = ""; + // 自提门店id + Integer storeId = 0; + + // 校验收货信息 + if(request.getShippingType() == 1){ // 发货 if(request.getAddressId() <= 0) throw new CrmebException("请选择收货地址"); UserAddress userAddress = new UserAddress(); userAddress.setId(request.getAddressId()); userAddress.setIsDel(false); currentUserAddress = userAddressService.getUserAddress(userAddress); - if(null == currentUserAddress){ + if(ObjectUtil.isNull(currentUserAddress)){ throw new CrmebException("收货地址有误"); } }else if(request.getShippingType() == 2){ // 到店自提 - if(StringUtils.isBlank(request.getRealName()) || StringUtils.isBlank(request.getPhone())) + if(StringUtils.isBlank(request.getRealName()) || StringUtils.isBlank(request.getPhone())) { throw new CrmebException("请填写姓名和电话"); - + } currentUserAddress.setRealName(request.getRealName()); currentUserAddress.setPhone(request.getPhone()); + // 自提开关是否打开 + String storeSelfMention = systemConfigService.getValueByKey("store_self_mention"); + if (storeSelfMention.equals("false")) { + throw new CrmebException("请先联系管理员开启门店自提"); + } + SystemStore systemStore = new SystemStore(); + systemStore.setId(request.getStoreId()); + systemStore.setIsShow(true); + systemStore.setIsDel(false); + SystemStore existSystemStore = systemStoreService.getByCondition(systemStore); + if(null == existSystemStore) throw new CrmebException("暂无门店无法选择门店自提"); + storeId = existSystemStore.getId(); + verifyCode = CrmebUtil.randomCount(1111111111,999999999)+""; + currentUserAddress.setDetail(existSystemStore.getName()); } - for (StoreCartResponse cartResponse : cor.getCartInfo()) { - cartIds.add(cartResponse.getSeckillId()); - totalNum += cartResponse.getCartNum(); - Integer cartInfoGainIntegral = - (cartResponse.getProductInfo().getGiveIntegral() != null && cartResponse.getProductInfo().getGiveIntegral() > 0 )? - cartResponse.getProductInfo().getGiveIntegral() * cartResponse.getCartNum() - : 0; - gainIntegral = gainIntegral + cartInfoGainIntegral; + // 校验积分抵扣 + if(request.getUseIntegral() && user.getIntegral() >= 0 && cor.getPriceGroup().getUsedIntegral() >= 0) { + if (user.getIntegral() < cor.getPriceGroup().getUsedIntegral()) { + throw new CrmebException("用户的积分不够抵扣,请刷新页面重新计算价格"); + } } - // todo 检测营销产品状态 - // 发快递还是门店自提 - String storeSelfMention = systemConfigService.getValueByKey("store_self_mention"); - if(!Boolean.valueOf(storeSelfMention)) request.setShippingType(1); + + if (request.getBargainId() > 0) { + StoreBargainUser storeBargainUser = storeBargainUserService.getByBargainIdAndUid(request.getBargainId(), user.getUid()); + if (ObjectUtil.isNull(storeBargainUser)) throw new CrmebException("砍价用户信息不存在"); + if (!storeBargainUser.getStatus().equals(1)) { + throw new CrmebException("活动已结束或订单已支付"); + } + } + + // 库存扣减 + List cartInfoList = cor.getCartInfo(); + if (CollUtil.isEmpty(cartInfoList)) throw new CrmebException("购物详情信息不存在"); + + /** + * 活动商品校验 + * skuRecord 扣减库存对象 + * ——activityId 活动商品id + * ——activityAttrValueId 活动商品skuid + * ——productId 普通(主)商品id + * ——attrValueId 普通(主)商品skuid + * ——num 购买数量 + */ + List skuRecordList = productSkuDispose(request, cartInfoList); + + List storeOrderInfos = new ArrayList<>(); + // 获取购买数量+赠送积分 + // 购物车商品详情 + for (StoreCartResponse cartResponse : cartInfoList) { + // 购买数量 + totalNum += cartResponse.getCartNum(); + // 赠送积分 + if (ObjectUtil.isNotNull(cartResponse.getProductInfo().getGiveIntegral()) && cartResponse.getProductInfo().getGiveIntegral() > 0) { + gainIntegral += cartResponse.getProductInfo().getGiveIntegral() * cartResponse.getCartNum(); + } + + // 订单详情 + StoreOrderInfo soInfo = new StoreOrderInfo(); + soInfo.setProductId(cartResponse.getProductId()); + soInfo.setInfo(JSON.toJSON(cartResponse).toString()); + soInfo.setUnique(cartResponse.getProductAttrUnique()); + storeOrderInfos.add(soInfo); + } + + // 下单赠送积分 + // 赠送积分比例 + if (cor.getPriceGroup().getPayPrice().compareTo(BigDecimal.ZERO) > 0) { + String integralStr = systemConfigService.getValueByKey(Constants.CONFIG_KEY_INTEGRAL_RATE); + if (StrUtil.isNotBlank(integralStr)) { + BigDecimal integralBig = new BigDecimal(integralStr); + Integer integral = integralBig.multiply(cor.getPriceGroup().getPayPrice()).setScale(0, BigDecimal.ROUND_DOWN).intValue(); + if (integral > 0) { + // 添加积分 + gainIntegral += integral; + } + } + } + + String orderNo = ""; + int isChannel = 3; // 支付渠道 + if (request.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) { + orderNo = CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT); + switch (request.getPayChannel()){ + case PayConstants.PAY_CHANNEL_WE_CHAT_H5:// H5 + isChannel = 2; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC:// 公众号 + isChannel = 0; + break; + case PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM:// 小程序 + isChannel = 1; + break; + } + } else {// 目前只有余额支付 + orderNo = CrmebUtil.getOrderNo(Constants.PAY_TYPE_YUE); + } + StoreOrder storeOrder = new StoreOrder(); storeOrder.setUid(cor.getUserInfo().getUid()); - storeOrder.setOrderId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT)); - - // 后置选择收货地址信息 - if(null == cor.getAddressInfo() && request.getAddressId() > 0){ - UserAddress selectUserAddress = userAddressService.getById(request.getAddressId()); - cor.setAddressInfo(selectUserAddress); - } - + storeOrder.setOrderId(orderNo); storeOrder.setRealName(currentUserAddress.getRealName()); storeOrder.setUserPhone(currentUserAddress.getPhone()); - storeOrder.setUserAddress(cor.getAddressInfo().getProvince() - + cor.getAddressInfo().getCity() - + cor.getAddressInfo().getDistrict() - + cor.getAddressInfo().getDetail()); -// storeOrder.setCarId(cartIds); + // 发货才有详细地址 + if(request.getShippingType() == 1){ // 发货 + storeOrder.setUserAddress(currentUserAddress.getProvince() + + currentUserAddress.getCity() + + currentUserAddress.getDistrict() + + currentUserAddress.getDetail()); + } + // 如果是自提 + if(request.getShippingType() == 2){ + storeOrder.setVerifyCode(verifyCode); + storeOrder.setStoreId(storeId); + storeOrder.setUserAddress(currentUserAddress.getDetail()); + } storeOrder.setTotalNum(totalNum); +// int couponId = ObjectUtil.isNull(cor.getUsableCoupon()) ? 0: cor.getUsableCoupon().getId(); + storeOrder.setCouponId(Optional.ofNullable(request.getCouponId()).orElse(0)); + + + // 订单总价 BigDecimal mapTotalPrice = cor.getPriceGroup().getTotalPrice(); + // 邮费 BigDecimal mapStorePostage = cor.getPriceGroup().getStorePostage(); + // 优惠券金额 BigDecimal mapCouponPrice = cor.getPriceGroup().getCouponPrice(); + // 实际支付金额 BigDecimal mapPayPrice = cor.getPriceGroup().getPayPrice(); + // 支付邮费 BigDecimal mapPayPostage = cor.getPriceGroup().getPayPostage(); + // 抵扣金额 BigDecimal mapDeductionPrice = cor.getPriceGroup().getDeductionPrice(); + // 使用积分 Integer mapUsedIntegral = cor.getPriceGroup().getUsedIntegral(); + // 成本价 BigDecimal mapCostPrice = cor.getPriceGroup().getCostPrice(); - int couponId = null == cor.getUsableCoupon() ? 0: cor.getUsableCoupon().getId(); storeOrder.setTotalPrice(mapTotalPrice); storeOrder.setTotalPostage(mapStorePostage); - storeOrder.setCouponId(couponId); storeOrder.setCouponPrice(mapCouponPrice); storeOrder.setPayPrice(mapPayPrice); storeOrder.setPayPostage(mapPayPostage); storeOrder.setDeductionPrice(mapDeductionPrice); -// storeOrder.setPaid(false); storeOrder.setPayType(request.getPayType()); storeOrder.setUseIntegral(mapUsedIntegral); storeOrder.setGainIntegral(gainIntegral); @@ -501,204 +908,309 @@ public class OrderUtils { storeOrder.setSeckillId(request.getSeckillId()); storeOrder.setBargainId(request.getBargainId()); storeOrder.setCost(mapCostPrice); - storeOrder.setIsChannel(isChannel); storeOrder.setCreateTime(DateUtil.nowDateTime()); storeOrder.setUnique(orderKey); storeOrder.setShippingType(request.getShippingType()); storeOrder.setPinkId(request.getPinkId()); + storeOrder.setIsChannel(isChannel); + storeOrder.setPaid(false); + // 0表示是团长开团,在支付成功后需要更换为,拼团团长pinkid + Integer pinkId = Optional.ofNullable(cartInfoList.get(0).getPinkId()).orElse(0); + storeOrder.setPinkId(pinkId); - // 如果是自提 - if(request.getShippingType() == 2){ - storeOrder.setVerifyCode(CrmebUtil.randomCount(1111111111,999999999)+""); - SystemStore systemStore = new SystemStore(); - systemStore.setId(request.getStoreId()); - systemStore.setIsShow(true); - systemStore.setIsDel(false); - SystemStore existSystemStore = systemStoreService.getByCondition(systemStore); - if(null == existSystemStore) throw new CrmebException("暂无门店无法选择门店自提"); - storeOrder.setStoreId(existSystemStore.getId()); + StoreCouponUser storeCouponUser = new StoreCouponUser(); + // 优惠券修改 + if (storeOrder.getCouponId() > 0) { + storeCouponUser = storeCouponUserService.getById(storeOrder.getCouponId()); + storeCouponUser.setStatus(1); } - boolean createdResult = storeOrderService.create(storeOrder); - if(!createdResult) throw new CrmebException("订单生成失败"); + StoreCouponUser finalStoreCouponUser = storeCouponUser; - // 积分抵扣 - boolean disIntegle = true; - User currentUser = userService.getInfo(); - if(request.getUseIntegral() && currentUser.getIntegral().compareTo(BigDecimal.ZERO) > 0){ - BigDecimal deductionPrice = BigDecimal.ZERO; - if(null != cor.getPriceGroup().getUsedIntegral()){ - deductionPrice = BigDecimal.valueOf(cor.getPriceGroup().getUsedIntegral(),2); - if(cor.getPriceGroup().getUsedIntegral() > 0){ - currentUser.setIntegral(BigDecimal.ZERO); - disIntegle = userService.updateBase(currentUser); - }else{ - if(currentUser.getIntegral().compareTo(deductionPrice) < 0){ - currentUser.setIntegral(currentUser.getIntegral().subtract(deductionPrice)); - disIntegle = userService.updateBase(currentUser); - } + Boolean execute = transactionTemplate.execute(e -> { + // 扣减库存 + // 需要根据是否活动商品,扣减不同的库存 + if (storeOrder.getSeckillId() > 0) {// 秒杀扣库存 + MyRecord skuRecord = skuRecordList.get(0); + // 秒杀商品扣库存 + storeSeckillService.operationStock(skuRecord.getInt("activityId"), skuRecord.getInt("num"), "sub"); + // 秒杀商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("activityAttrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_SECKILL); + // 普通商品口库存 + storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub"); + // 普通商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL); + } else + if (storeOrder.getBargainId() > 0) {// 砍价扣库存 + MyRecord skuRecord = skuRecordList.get(0); + // 砍价商品扣库存 + storeBargainService.operationStock(skuRecord.getInt("activityId"), skuRecord.getInt("num"), "sub"); + // 砍价商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("activityAttrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_BARGAIN); + // 普通商品口库存 + storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub"); + // 普通商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL); + } else + if (storeOrder.getCombinationId() > 0) {// 拼团扣库存 + MyRecord skuRecord = skuRecordList.get(0); + // 秒杀商品扣库存 + storeCombinationService.operationStock(skuRecord.getInt("activityId"), skuRecord.getInt("num"), "sub"); + // 秒杀商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("activityAttrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_PINGTUAN); + // 普通商品口库存 + storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub"); + // 普通商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL); + } else { // 普通商品 + for (MyRecord skuRecord : skuRecordList) { + // 普通商品口库存 + storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub"); + // 普通商品规格扣库存 + storeProductAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL); } } - UserBill userBill = new UserBill(); - userBill.setTitle("积分抵扣"); - userBill.setUid(currentUser.getUid()); - userBill.setCategory("integral"); - userBill.setType("deduction"); - userBill.setNumber(deductionPrice); - userBill.setLinkId(orderId+""); - userBill.setBalance(currentUser.getIntegral()); - userBill.setMark("购买商品使用"+userBill.getNumber()+"积分抵扣"+deductionPrice+"元"); - boolean userBillSaveResult = userBillService.save(userBill); - disIntegle = disIntegle && userBillSaveResult; + storeOrderService.create(storeOrder); + storeOrderInfos.forEach(info -> { + info.setOrderId(storeOrder.getId()); + }); + // 优惠券修改 + if (storeOrder.getCouponId() > 0) { + storeCouponUserService.updateById(finalStoreCouponUser); + } + // 保存购物车商品详情 + storeOrderInfoService.saveOrderInfos(storeOrderInfos); + // 生成订单日志 + storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_CACHE_CREATE_ORDER, "订单生成"); + + // 扣减库存 +// deductionsStock(cartInfoList, storeOrder, user); + return Boolean.TRUE; + }); + if (!execute) { + throw new CrmebException("订单生成失败"); } - if(!disIntegle) throw new CrmebException("使用积分抵扣失败"); + // 删除缓存订单 + cacheDeleteOrderInfo(user.getUid(), orderKey); + return storeOrder; + } - Integer secKillId = null; - List storeOrderInfos = new ArrayList<>(); - boolean deCountResult = true; - for (StoreCartResponse cartResponse : cor.getCartInfo()) { - StoreOrderInfo soInfo = new StoreOrderInfo(); + /** + * 商品sku处理 + * @param request + * @param cartInfoList + * @return List + * skuRecord 扣减库存对象 + * ——activityId 活动商品id + * ——activityAttrValueId 活动商品skuid + * ——productId 普通(主)商品id + * ——attrValueId 普通(主)商品skuid + * ——num 购买数量 + */ + private List productSkuDispose(OrderCreateRequest request, List cartInfoList) { + List recordList = CollUtil.newArrayList(); + Integer productId; + Integer cartNum; + Integer attrValueId; + // 活动商品处理 + if (request.getSeckillId() > 0 || request.getBargainId() > 0 || request.getCombinationId() > 0) { + StoreCartResponse storeCartResponse = cartInfoList.get(0); + productId = storeCartResponse.getProductId(); + cartNum = storeCartResponse.getCartNum(); + attrValueId = Integer.parseInt(storeCartResponse.getProductAttrUnique()); + if (request.getSeckillId() > 0) { + // 秒杀部分判断 + Integer seckillId = request.getSeckillId(); + StoreSeckill storeSeckill = storeSeckillService.getByIdException(seckillId); + if (storeSeckill.getStock().equals(0) || cartNum > storeSeckill.getStock()) { + throw new CrmebException("秒杀商品库存不足"); + } + StoreProductAttrValue seckillAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(attrValueId, seckillId, Constants.PRODUCT_TYPE_SECKILL); + if (ObjectUtil.isNull(seckillAttrValue)) { + throw new CrmebException("秒杀商品规格不存在"); + } + if (seckillAttrValue.getStock() <= 0 || seckillAttrValue.getQuota() <= 0 || cartNum > seckillAttrValue.getStock()) { + throw new CrmebException("秒杀商品规格库存不足"); + } + // 普通商品部分判断 + StoreProduct product = storeProductService.getById(productId); + if (ObjectUtil.isNull(product) || product.getIsDel()) { + throw new CrmebException("秒杀主商品不存在"); + } + if (product.getStock().equals(0) || cartNum > product.getStock()) { + throw new CrmebException("秒杀主商品库存不足"); + } + // 主商品sku + StoreProductAttrValue productAttrValue = storeProductAttrValueService.getByProductIdAndSkuAndType(productId, seckillAttrValue.getSuk(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(productAttrValue)) { + throw new CrmebException("秒杀主商品规格不存在"); + } + if (productAttrValue.getStock() <= 0 || cartNum > productAttrValue.getStock()) { + throw new CrmebException("秒杀主商品规格库存不足"); + } + + MyRecord record = new MyRecord(); + record.set("activityId", seckillId); + record.set("activityAttrValueId", attrValueId); + record.set("productId", productId); + record.set("attrValueId", productAttrValue.getId()); + record.set("num", cartNum); + recordList.add(record); + } + if ( request.getBargainId() > 0) { + // 砍价部分判断 + Integer bargainId = request.getBargainId(); + StoreBargain storeBargain = storeBargainService.getByIdException(bargainId); + if (storeBargain.getStock().equals(0) || cartNum > storeBargain.getStock()) { + throw new CrmebException("砍价商品库存不足"); + } + StoreProductAttrValue bargainAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(attrValueId, bargainId, Constants.PRODUCT_TYPE_BARGAIN); + if (ObjectUtil.isNull(bargainAttrValue)) { + throw new CrmebException("砍价商品规格不存在"); + } + if (bargainAttrValue.getStock() <= 0 || bargainAttrValue.getQuota() <= 0 || cartNum > bargainAttrValue.getStock()) { + throw new CrmebException("砍价商品规格库存不足"); + } + // 普通商品部分判断 + StoreProduct product = storeProductService.getById(productId); + if (ObjectUtil.isNull(product) || product.getIsDel()) { + throw new CrmebException("砍价主商品不存在"); + } + if (product.getStock().equals(0) || cartNum > product.getStock()) { + throw new CrmebException("砍价主商品库存不足"); + } + // 主商品sku + StoreProductAttrValue productAttrValue = storeProductAttrValueService.getByProductIdAndSkuAndType(productId, bargainAttrValue.getSuk(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(productAttrValue)) { + throw new CrmebException("砍价主商品规格不存在"); + } + if (productAttrValue.getStock() <= 0 || cartNum > productAttrValue.getStock()) { + throw new CrmebException("砍价主商品规格库存不足"); + } + + MyRecord record = new MyRecord(); + record.set("activityId", bargainId); + record.set("activityAttrValueId", attrValueId); + record.set("productId", productId); + record.set("attrValueId", productAttrValue.getId()); + record.set("num", cartNum); + recordList.add(record); + } + if (request.getCombinationId() > 0) { + // 拼团部分判断 + Integer combinationId = request.getCombinationId(); + StoreCombination storeCombination = storeCombinationService.getByIdException(combinationId); + if (storeCombination.getStock().equals(0) || cartNum > storeCombination.getStock()) { + throw new CrmebException("拼团商品库存不足"); + } + StoreProductAttrValue combinationAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(attrValueId, combinationId, Constants.PRODUCT_TYPE_PINGTUAN); + if (ObjectUtil.isNull(combinationAttrValue)) { + throw new CrmebException("拼团商品规格不存在"); + } + if (combinationAttrValue.getStock() <= 0 || combinationAttrValue.getQuota() <= 0 || cartNum > combinationAttrValue.getStock()) { + throw new CrmebException("拼团商品规格库存不足"); + } + // 普通商品部分判断 + StoreProduct product = storeProductService.getById(productId); + if (ObjectUtil.isNull(product) || product.getIsDel()) { + throw new CrmebException("拼团主商品不存在"); + } + if (product.getStock().equals(0) || cartNum > product.getStock()) { + throw new CrmebException("拼团主商品库存不足"); + } + // 主商品sku + StoreProductAttrValue productAttrValue = storeProductAttrValueService.getByProductIdAndSkuAndType(productId, combinationAttrValue.getSuk(), Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(productAttrValue)) { + throw new CrmebException("砍价主商品规格不存在"); + } + if (productAttrValue.getStock() <= 0 || cartNum > productAttrValue.getStock()) { + throw new CrmebException("砍价主商品规格库存不足"); + } + + MyRecord record = new MyRecord(); + record.set("activityId", combinationId); + record.set("activityAttrValueId", attrValueId); + record.set("productId", productId); + record.set("attrValueId", productAttrValue.getId()); + record.set("num", cartNum); + record.set("pinkId", storeCartResponse.getPinkId()); + recordList.add(record); + } + } else {// 普通商品处理 + /** + * 1.判断商品有效 + * 2.判断商品库存 + * 3.判断商品规格库存 + */ + for (StoreCartResponse cartResponse : cartInfoList) { + productId = cartResponse.getProductId(); + cartNum = cartResponse.getCartNum(); + attrValueId = Integer.parseInt(cartResponse.getProductAttrUnique()); + StoreProduct product = storeProductService.getById(productId); + if (ObjectUtil.isNull(product) || product.getIsDel() || !product.getIsShow()) { + throw new CrmebException("购买的商品不存在或已下架"); + } + if (product.getStock().equals(0) || cartNum > product.getStock()) { + throw new CrmebException("购买的商品库存不足"); + } + StoreProductAttrValue productAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(attrValueId, productId, Constants.PRODUCT_TYPE_NORMAL); + if (ObjectUtil.isNull(productAttrValue)) { + throw new CrmebException("购买的商品规格不存在"); + } + if (productAttrValue.getStock() <= 0 || cartNum > productAttrValue.getStock()) { + throw new CrmebException("购买的商品规格库存不足"); + } + + MyRecord record = new MyRecord(); + record.set("productId", productId); + record.set("num", cartNum); + record.set("attrValueId", attrValueId); + recordList.add(record); + } + } + return recordList; + } + + + /** + * 扣减库存 + */ + private Boolean deductionsStock(List cartInfoList, StoreOrder storeOrder, User user) { + // 活动商品处理,只会有一条数据 + if (cartInfoList.size() == 1) { + StoreCartResponse cartResponse = cartInfoList.get(0); + Integer num = cartResponse.getCartNum(); + Integer attrValueId = Integer.parseInt(cartResponse.getProductAttrUnique()); + Integer productId = cartResponse.getProductId(); // 秒杀商品扣减库存 - if(null != cartResponse.getSeckillId() && cartResponse.getSeckillId() > 0){ - secKillId = cartResponse.getSeckillId(); - // 秒杀商品本身库存扣减 - deCountResult = storeSeckillService.decProductStock( - cartResponse.getSeckillId(), - cartResponse.getCartNum(), - Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_SECKILL); - // 商品本身扣减库存 更新商品本身库存步骤 1=根据秒杀uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 - // 秒杀对应商品库存扣减 - StoreProductAttrValue currentSeckillAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); - List currentSeckillAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); - List existAttrValues = currentSeckillAttrValues.stream().filter(e -> - e.getSuk().equals(currentSeckillAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) - .collect(Collectors.toList()); - if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); - deCountResult = storeProductService.decProductStock( - existAttrValues.get(0).getProductId(), - cartResponse.getCartNum(), - existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); - - }else if (ObjectUtil.isNotNull(cartResponse.getBargainId()) && cartResponse.getBargainId() > 0) { + if (ObjectUtil.isNotNull(cartResponse.getSeckillId()) && cartResponse.getSeckillId() > 0) { + Integer seckillId = cartResponse.getSeckillId(); + return storeSeckillService.decProductStock(seckillId, num, attrValueId, productId); + } + // 砍价扣减库存 + if (ObjectUtil.isNotNull(cartResponse.getBargainId()) && cartResponse.getBargainId() > 0) { // 砍价扣减库存 Integer bargainId = cartResponse.getBargainId(); - // 砍价商品扣减库存 - deCountResult = storeBargainService.decProductStock( - cartResponse.getBargainId(), - cartResponse.getCartNum(), - Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_BARGAIN); - // 商品本身扣减库存 更新商品本身库存步骤 1=根据秒杀uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 - // 砍价对应商品库存扣减 - StoreProductAttrValue currentSeckillAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); - List currentBargainAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); - List existAttrValues = currentBargainAttrValues.stream().filter(e -> - e.getSuk().equals(currentSeckillAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) - .collect(Collectors.toList()); - if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); - deCountResult = storeProductService.decProductStock( - existAttrValues.get(0).getProductId(), - cartResponse.getCartNum(), - existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); - - // 砍价商品购买成功,改变用户状态 - StoreBargainUser storeBargainUser = storeBargainUserService.getByBargainIdAndUid(cartResponse.getBargainId(), cor.getUserInfo().getUid()); - storeBargainUser.setStatus(3); - storeBargainUserService.updateById(storeBargainUser); - }else if (ObjectUtil.isNotNull(cartResponse.getCombinationId()) && cartResponse.getCombinationId() > 0) { - // 判断拼团团长是否存在 - StorePink headPink = null; - if (ObjectUtil.isNotNull(cartResponse.getPinkId()) && cartResponse.getPinkId() > 0) { - headPink = storePinkService.getById(cartResponse.getPinkId()); - if (ObjectUtil.isNull(headPink) || headPink.getIsRefund().equals(true) || headPink.getStatus() == 3) { - throw new CrmebException("找不到对应的拼团团队信息"); - } - } - // 拼团扣减库存 - // 拼团商品本身库存扣减 - deCountResult = storeCombinationService.decProductStock( - cartResponse.getCombinationId(), - cartResponse.getCartNum(), - Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_PINGTUAN); - // 商品本身扣减库存 更新商品本身库存步骤 1=根据拼团uniuqeId 获取对应sku 2=根据商品ID获取商品sku信息后 对比相等的sku 更新其对应数量 - // 拼团对应商品库存扣减 - StoreProductAttrValue currentCombinationAttrValue = storeProductAttrValueService.getById(cartResponse.getProductAttrUnique()); - List currentCombinationAttrValues = storeProductAttrValueService.getListByProductId(cartResponse.getProductId()); - List existAttrValues = currentCombinationAttrValues.stream().filter(e -> - e.getSuk().equals(currentCombinationAttrValue.getSuk()) && e.getType().equals(Constants.PRODUCT_TYPE_NORMAL)) - .collect(Collectors.toList()); - if(existAttrValues.size() != 1) throw new CrmebException("未找到扣减库存的商品"); - deCountResult = storeProductService.decProductStock( - existAttrValues.get(0).getProductId(), - cartResponse.getCartNum(), - existAttrValues.get(0).getId(), Constants.PRODUCT_TYPE_NORMAL); - // 生成拼团表数据 - StoreCombination storeCombination = storeCombinationService.getById(cartResponse.getCombinationId()); - StorePink storePink = new StorePink(); - storePink.setUid(cor.getUserInfo().getUid()); - storePink.setAvatar(cor.getUserInfo().getAvatar()); - storePink.setNickname(cor.getUserInfo().getNickname()); - storePink.setOrderId(storeOrder.getOrderId()); - storePink.setOrderIdKey(storeOrder.getId()); - storePink.setTotalNum(storeOrder.getTotalNum()); - storePink.setTotalPrice(storeOrder.getTotalPrice()); - storePink.setCid(cartResponse.getCombinationId()); - storePink.setPid(cartResponse.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(cartResponse.getPinkId()) && cartResponse.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(cartResponse.getPinkId()).orElse(0)); - storePink.setIsTpl(false); - storePink.setIsRefund(false); - storePink.setStatus(1); - storePinkService.save(storePink); - - // 如果是开团,需要更新订单数据 - if (storePink.getKId() == 0) { - storeOrder.setPinkId(storePink.getId()); - storeOrderService.updateById(storeOrder); - } - }else { - // 普通购买扣减库存 - deCountResult = storeProductService.decProductStock( + return storeBargainService.decProductStock(bargainId, num, attrValueId, productId, user.getUid()); + } + // 拼团商品扣减库存 + if (ObjectUtil.isNotNull(cartResponse.getCombinationId()) && cartResponse.getCombinationId() > 0) { + Integer combinationId = cartResponse.getCombinationId(); + Integer pinkId = cartResponse.getPinkId(); + return storeCombinationService.decProductStock(storeOrder, num, attrValueId, productId, user); + } + } + // 处理普通商品 + Boolean execute = transactionTemplate.execute(e -> { + for (StoreCartResponse cartResponse : cartInfoList) { + storeProductService.decProductStock( cartResponse.getProductId(), cartResponse.getCartNum(), Integer.parseInt(cartResponse.getProductAttrUnique()), Constants.PRODUCT_TYPE_NORMAL); } - soInfo.setOrderId(storeOrder.getId()); - soInfo.setProductId(cartResponse.getProductId()); - soInfo.setInfo(JSON.toJSON(cartResponse).toString()); - soInfo.setUnique(cartResponse.getProductAttrUnique()); - storeOrderInfos.add(soInfo); - - } - // 保存购物车商品详情 - boolean saveBatchOrderInfosResult = storeOrderInfoService.saveOrderInfos(storeOrderInfos); - if(!saveBatchOrderInfosResult && !deCountResult){ - throw new CrmebException("订单生成失败"); - } - - // 删除缓存订单 - cacheDeleteOrderInfo(currentUser.getUid(), orderKey); - // 检查缺省的默认地址设置 - UserAddress defaultAddress = userAddressService.getDefault(); - if(null != defaultAddress){ - userAddressService.def(cor.getAddressInfo().getId()); - } - storeOrderStatusService.createLog(storeOrder.getId(), - Constants.ORDER_STATUS_CACHE_CREATE_ORDER,"订单生成"); - return storeOrder; + return Boolean.TRUE; + }); + return execute; } /** @@ -776,13 +1288,13 @@ public class OrderUtils { boolean result = false; payType = payType.toLowerCase(); switch (payType){ - case Constants.PAY_TYPE_WE_CHAT: + case PayConstants.PAY_TYPE_WE_CHAT: result = systemConfigService.getValueByKey("pay_weixin_open").equals("1"); break; - case Constants.PAY_TYPE_YUE: + case PayConstants.PAY_TYPE_YUE: result = (systemConfigService.getValueByKey("balance_func_status").equals("1") && systemConfigService.getValueByKey("yue_pay_status").equals("1")); break; - case Constants.PAY_TYPE_OFFLINE: + case PayConstants.PAY_TYPE_OFFLINE: result = systemConfigService.getValueByKey("offline_pay_status").equals("1"); break; } @@ -806,19 +1318,19 @@ public class OrderUtils { vipPrice = BigDecimal.ZERO; // 订单会员优惠价 for (StoreCartResponse cartResponse : storeCartResponse) { - totalPrice = (totalPrice.add(cartResponse.getTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum())))); - costPrice = (costPrice.add(cartResponse.getCostPrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum())))); - vipPrice = (vipPrice.add(cartResponse.getVipTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum())))); + totalPrice = totalPrice.add(cartResponse.getTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))); + costPrice = costPrice.add(cartResponse.getCostPrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))); + vipPrice = vipPrice.add(cartResponse.getVipTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))); } // 判断是否满额包邮 type=1按件数 2按重量 3按体积 Integer storeFreePostageString = Integer.valueOf(systemConfigService.getValueByKey("store_free_postage")); if(storeFreePostageString <= 0){ // 包邮 storeFreePostage = BigDecimal.ZERO; }else{ - if(null != userAddress && userAddress.getCityId() > 0){ - int cityId = userAddress.getCityId() > 0 ? userAddress.getCityId():0; + if(null != userAddress && userAddress.getCityId() > 0){// 有用户地址的情况下 + int cityId = userAddress.getCityId(); List spcpInfo = - storeCartResponse.stream().map(StoreCartResponse::getProductInfo).distinct().collect(Collectors.toList()); + storeCartResponse.stream().map(StoreCartResponse::getProductInfo).collect(Collectors.toList()); List tempIds = spcpInfo.stream().map(StoreProductCartProductInfoResponse::getTempId).distinct().collect(Collectors.toList()); // 查询运费模版 List shippingTemplates = shippingTemplatesService.getListInIds(tempIds); @@ -828,7 +1340,7 @@ public class OrderUtils { // 指定区域包邮费用 List shippingTemplateRegions = shippingTemplatesRegionService.listByIds(tempIds); - BigDecimal postPrice = BigDecimal.ZERO; + BigDecimal postPrice; if(!shippingTemplates.get(0).getAppoint() && shippingTemplateRegions.size() > 0){ postPrice = shippingTemplateRegions.get(0).getFirstPrice(); }else if(shippingTemplates.get(0).getAppoint()){ // 正常配送和运费 @@ -1042,10 +1554,6 @@ public class OrderUtils { queryWrapper.eq(StoreOrder::getPaid, true); queryWrapper.eq(StoreOrder::getStatus, 2); queryWrapper.eq(StoreOrder::getRefundStatus, 0); -// queryWrapper.eq(StoreOrder::getPaid, true); 待核销 -// queryWrapper.eq(StoreOrder::getStatus, 0); -// queryWrapper.eq(StoreOrder::getRefundStatus, 0); -// queryWrapper.eq(StoreOrder::getShippingType, 2); break; case Constants.ORDER_STATUS_H5_COMPLETE: // 已完成 queryWrapper.eq(StoreOrder::getPaid, true); @@ -1054,16 +1562,15 @@ public class OrderUtils { break; case Constants.ORDER_STATUS_H5_REFUNDING: // 退款中 queryWrapper.eq(StoreOrder::getPaid, true); - queryWrapper.eq(StoreOrder::getRefundStatus, 1); + queryWrapper.in(StoreOrder::getRefundStatus, 1, 3); break; case Constants.ORDER_STATUS_H5_REFUNDED: // 已退款 queryWrapper.eq(StoreOrder::getPaid, true); - queryWrapper.eq(StoreOrder::getStatus, 2); + queryWrapper.eq(StoreOrder::getRefundStatus, 2); break; case Constants.ORDER_STATUS_H5_REFUND: // 包含已退款和退款中 queryWrapper.eq(StoreOrder::getPaid, true); - queryWrapper.in(StoreOrder::getStatus,0,-1,-2); - queryWrapper.in(StoreOrder::getRefundStatus, 1,2); + queryWrapper.in(StoreOrder::getRefundStatus, 1,2,3); break; } queryWrapper.eq(StoreOrder::getIsDel, false); @@ -1198,16 +1705,18 @@ public class OrderUtils { * 下单前砍价验证 * @param storeCartPram 砍价参数 * @param currentUser 当前购买人 + * @return */ - public StoreBargain validBargain(StoreCart storeCartPram, User currentUser) { + public MyRecord validBargain(StoreCart storeCartPram, User currentUser) { // 判断砍价商品是否有效 - StoreBargain storeBargainParam = new StoreBargain(); - storeBargainParam.setId(storeCartPram.getBargainId()); - storeBargainParam.setIsDel(false); - storeBargainParam.setStatus(true); - List existBargains = storeBargainService.getByEntity(storeBargainParam); - if (CollUtil.isEmpty(existBargains)) throw new CrmebException("该商品已下架或删除"); - StoreBargain existBargain = existBargains.get(0); + StoreBargain existBargain = storeBargainService.getByIdException(storeCartPram.getBargainId()); + // 判断购买数量 + if (storeCartPram.getCartNum() > existBargain.getQuota()) { + throw new CrmebException("砍价商品库存不足"); + } + if (existBargain.getQuota() <= 0 || existBargain.getStock() <= 0) {// 销量等于限量 + throw new CrmebException("当前拼团商品已售罄"); + } // 判断砍价活动时间段 long timeMillis = System.currentTimeMillis(); @@ -1225,15 +1734,14 @@ public class OrderUtils { } // 判断砍价商品库存和砍价限量 - StoreProductAttrValue spavPram = new StoreProductAttrValue() - .setId(Integer.valueOf(storeCartPram.getProductAttrUnique())) - .setType(Constants.PRODUCT_TYPE_BARGAIN); - List currentBargainAttrValues = storeProductAttrValueService.getByEntity(spavPram); - if(null == currentBargainAttrValues || currentBargainAttrValues.size() == 0){ - throw new CrmebException("未找到该商品信息"); + StoreProductAttrValue storeProductAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(Integer.valueOf(storeCartPram.getProductAttrUnique()), storeCartPram.getBargainId(), Constants.PRODUCT_TYPE_BARGAIN); + if(ObjectUtil.isNull(storeProductAttrValue)){ + throw new CrmebException("未找到该商品规格信息"); + } + if (storeProductAttrValue.getQuota() <= 0 || storeProductAttrValue.getStock() <= 0){// sku销量等于限量 + throw new CrmebException("当前砍价商品已售罄"); } - StoreProductAttrValue storeProductAttrValue = currentBargainAttrValues.get(0); // 仅仅会获取一条数据 // 参与活动次数 -根据用户和秒杀信息查询当天订单判断订单数量 StoreOrder soPram = new StoreOrder().setUid(currentUser.getUid()).setBargainId(storeCartPram.getBargainId()); List userCurrentBargainOrders = storeOrderService.getUserCurrentBargainOrders(soPram); @@ -1243,45 +1751,44 @@ public class OrderUtils { if(unPayOrders.size() > 0) throw new CrmebException("您有砍价待支付订单,请支付后再购买"); // 判断是否达到上限 - if(CollUtil.isNotEmpty(userCurrentBargainOrders) && userCurrentBargainOrders.size() >= existBargain.getNum()){ + List noRefundOrders = userCurrentBargainOrders.stream().filter(i -> i.getRefundStatus() != 2).collect(Collectors.toList()); + if(CollUtil.isNotEmpty(userCurrentBargainOrders) && noRefundOrders.size() >= existBargain.getNum()){ throw new CrmebException("您已经达到当前砍价活动上限"); } - - // 达到商品限量 sku quota - Integer orderCount = storeOrderService.getCountByBargainId(existBargain.getId()); - if (orderCount >= existBargain.getQuotaShow()) { - throw new CrmebException("当前砍价活动商品已达购买上限"); - } - return existBargain; + MyRecord record = new MyRecord(); + record.set("product", existBargain); + record.set("attrInfo", storeProductAttrValue); + return record; } /** * 下单前拼团验证 * @param storeCartPram 拼团参数 * @param currentUser 当前购买人 + * @return */ - public StoreCombination validCombination(StoreCart storeCartPram, User currentUser) { + public MyRecord validCombination(StoreCart storeCartPram, User currentUser) { // 判断拼团商品是否有效 - StoreCombination storeProductPram = new StoreCombination(); - storeProductPram.setId(storeCartPram.getCombinationId()); - storeProductPram.setIsDel(false); - storeProductPram.setIsShow(true); - List existCombinations = storeCombinationService.getByEntity(storeProductPram); - if(CollUtil.isEmpty(existCombinations)) throw new CrmebException("该商品已下架或者删除"); - StoreCombination existCombination = existCombinations.get(0); + StoreCombination existCombination = storeCombinationService.getByIdException(storeCartPram.getCombinationId()); // 判断拼团时间段 long timeMillis = System.currentTimeMillis(); if (timeMillis < existCombination.getStartTime()) { throw new CrmebException("拼团商品活动未开始"); } - if (timeMillis > existCombination.getStopTime()) { + if (timeMillis >= existCombination.getStopTime()) { throw new CrmebException("拼团商品已过期"); } // 判断购买数量 if (storeCartPram.getCartNum() > existCombination.getOnceNum()) { throw new CrmebException("购买数量超过单次拼团购买上限"); } + if (storeCartPram.getCartNum() > existCombination.getQuota()) { + throw new CrmebException("拼团商品库存不足"); + } + if (existCombination.getQuota() <= 0 || existCombination.getStock() <= 0) {// 销量等于限量 + throw new CrmebException("当前拼团商品已售罄"); + } // 如果时参团,判断团队是否已满员 if (ObjectUtil.isNotNull(storeCartPram.getPinkId()) && storeCartPram.getPinkId() > 0) { @@ -1291,15 +1798,19 @@ public class OrderUtils { } } - // 判断拼团商品库存和拼团限量 - StoreProductAttrValue spavPram = new StoreProductAttrValue() - .setId(Integer.valueOf(storeCartPram.getProductAttrUnique())) - .setType(Constants.PRODUCT_TYPE_PINGTUAN); - List currentCombinationAttrValues = storeProductAttrValueService.getByEntity(spavPram); - if(CollUtil.isEmpty(currentCombinationAttrValues)){ + // 判断拼团商品规格库存和拼团限量 + // 判断商品对应属性是否有效 + StoreProductAttrValue storeProductAttrValue = storeProductAttrValueService.getByIdAndProductIdAndType(Integer.valueOf(storeCartPram.getProductAttrUnique()), storeCartPram.getCombinationId(), Constants.PRODUCT_TYPE_PINGTUAN); + if(ObjectUtil.isNull(storeProductAttrValue)){ throw new CrmebException("未找到该商品信息"); } - StoreProductAttrValue storeProductAttrValue = currentCombinationAttrValues.get(0); // 仅仅会获取一条数据 + if (storeProductAttrValue.getQuota() <= 0 || storeProductAttrValue.getStock() <= 0){// sku销量等于限量 + throw new CrmebException("当前拼团商品已售罄"); + } + if (storeCartPram.getCartNum() > storeProductAttrValue.getQuota()) { + throw new CrmebException("数量超过拼团商品库存上限"); + } + // 用户参与活动的次数 StoreOrder soPram = new StoreOrder().setUid(currentUser.getUid()).setCombinationId(storeCartPram.getCombinationId()); List userCombinationOrders = storeOrderService.getByEntity(soPram); @@ -1324,22 +1835,9 @@ public class OrderUtils { } } - // 判断是否达到上限 - // 达到商品限量 sku quota - if (existCombination.getSales() >= existCombination.getQuotaShow()) {// 销量等于限量 - throw new CrmebException("当前拼团商品已售完"); - } - if (storeProductAttrValue.getSales() >= storeProductAttrValue.getQuotaShow()){// sku销量等于限量 - throw new CrmebException("当前拼团商品已售完"); - } - - if (existCombination.getSales() + storeCartPram.getCartNum() > existCombination.getQuotaShow()) { - throw new CrmebException("数量超过拼团商品上限"); - } - if (storeProductAttrValue.getSales() + storeCartPram.getCartNum() > storeProductAttrValue.getQuotaShow()) { - throw new CrmebException("数量超过拼团商品上限"); - } - - return existCombination; + MyRecord record = new MyRecord(); + record.set("product", existCombination); + record.set("attrInfo", storeProductAttrValue); + return record; } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/ProductUtils.java b/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/ProductUtils.java index 2b263a4a..03dfa832 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/ProductUtils.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/store/utilService/ProductUtils.java @@ -413,14 +413,16 @@ public class ProductUtils { baseUrl = systemConfigService.getValueByKey("importProductTM"); break; } - String token = systemConfigService.getValueByKey("importProductToken"); +// String token = systemConfigService.getValueByKey("importProductToken"); + String token = systemConfigService.getValueByKey("copy_product_apikey"); if(StringUtils.isBlank(token)){ throw new CrmebException("请配置复制产品平台的Token -- www.99api.com"); } if(StringUtils.isBlank(baseUrl)){ throw new CrmebException("请配置复制产品平台的Url-- www.99api.com"); } - rightUrl = "?apikey="+systemConfigService.getValueByKey("importProductToken")+rightEndUrl; +// rightUrl = "?apikey="+systemConfigService.getValueByKey("importProductToken")+rightEndUrl; + rightUrl = "?apikey="+systemConfigService.getValueByKey("copy_product_apikey")+rightEndUrl; } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/system/service/SystemAdminService.java b/crmeb/src/main/java/com/zbkj/crmeb/system/service/SystemAdminService.java index 6ce6d7b1..f68533b6 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/system/service/SystemAdminService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/system/service/SystemAdminService.java @@ -7,6 +7,7 @@ import com.zbkj.crmeb.system.request.SystemAdminAddRequest; import com.zbkj.crmeb.system.request.SystemAdminRequest; import com.zbkj.crmeb.system.response.SystemAdminResponse; +import java.util.HashMap; import java.util.List; /** @@ -75,4 +76,6 @@ public interface SystemAdminService extends IService { void bind(String wxCode, Integer adminId); Boolean updateStatus(Integer id, Boolean status); + + HashMap getMapInId(List adminIdList); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemAdminServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemAdminServiceImpl.java index 4f8594d1..7fbd7965 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemAdminServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemAdminServiceImpl.java @@ -3,6 +3,7 @@ package com.zbkj.crmeb.system.service.impl; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.common.PageParamRequest; import com.constants.Constants; @@ -14,6 +15,7 @@ import com.zbkj.crmeb.authorization.model.TokenModel; import com.zbkj.crmeb.system.dao.SystemAdminDao; import com.zbkj.crmeb.system.model.SystemAdmin; import com.zbkj.crmeb.system.model.SystemRole; +import com.zbkj.crmeb.system.model.SystemStoreStaff; import com.zbkj.crmeb.system.request.SystemAdminAddRequest; import com.zbkj.crmeb.system.request.SystemAdminRequest; import com.zbkj.crmeb.system.request.SystemRoleSearchRequest; @@ -31,6 +33,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -378,6 +381,24 @@ public class SystemAdminServiceImpl extends ServiceImpl getMapInId(List adminIdList) { + HashMap map = new HashMap<>(); + if(adminIdList.size() < 1){ + return map; + } + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.in(SystemAdmin::getId, adminIdList); + List systemAdminList = dao.selectList(lambdaQueryWrapper); + if(systemAdminList.size() < 1){ + return map; + } + for (SystemAdmin systemAdmin : systemAdminList) { + map.put(systemAdmin.getId(), systemAdmin); + } + return map; + } + /** * 解绑微信 * @author Mr.Zhang diff --git a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemRoleServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemRoleServiceImpl.java index 906174d3..8e2b8750 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemRoleServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemRoleServiceImpl.java @@ -2,6 +2,7 @@ package com.zbkj.crmeb.system.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.common.PageParamRequest; @@ -115,6 +116,7 @@ public class SystemRoleServiceImpl extends ServiceImpl menu() { List categoryIdList = getRoleListInRoleId(); + System.out.println("权限列表:categoryIdList:"+ JSON.toJSONString(categoryIdList)); return categoryService.getListTree(Constants.CATEGORY_TYPE_MENU, 1, categoryIdList); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemStoreServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemStoreServiceImpl.java index a11c1008..e5b44ec5 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemStoreServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/system/service/impl/SystemStoreServiceImpl.java @@ -271,7 +271,7 @@ public class SystemStoreServiceImpl extends ServiceImpl + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class CouponOverdueTask { + + //日志 + private static final Logger logger = LoggerFactory.getLogger(CouponOverdueTask.class); + + @Autowired + private StoreCouponUserService couponUserService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---CouponOverdueTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + couponUserService.overdueTask(); + }catch (Exception e){ + e.printStackTrace(); + logger.error("CouponOverdueTask.task" + " | msg : " + e.getMessage()); + } + + } + +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCancelTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCancelTask.java new file mode 100644 index 00000000..d90ff2a3 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCancelTask.java @@ -0,0 +1,47 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 用户取消订单task任务 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderCancelTask { + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderCancelTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderCancelTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.cancelByUser(); + + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderCancelTask.task" + " | msg : " + e.getMessage()); + } + + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCompleteTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCompleteTask.java new file mode 100644 index 00000000..9ef059da --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderCompleteTask.java @@ -0,0 +1,47 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 用户订单完成task任务 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderCompleteTask { + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderCompleteTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderCompleteTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.complete(); + + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderCompleteTask.task" + " | msg : " + e.getMessage()); + } + + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderDeleteTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderDeleteTask.java new file mode 100644 index 00000000..ca625291 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderDeleteTask.java @@ -0,0 +1,47 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 用户订单删除task任务 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderDeleteTask { + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderDeleteTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderDeleteTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.deleteByUser(); + + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderDeleteTask.task" + " | msg : " + e.getMessage()); + } + + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderPaySuccessTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderPaySuccessTask.java new file mode 100644 index 00000000..00584504 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderPaySuccessTask.java @@ -0,0 +1,48 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 订单支付成功后置task任务 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderPaySuccessTask { + + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderPaySuccessTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderPaySuccessTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.orderPaySuccessAfter(); + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderPaySuccessTask.task" + " | msg : " + e.getMessage()); + } + + } + +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderReceiptTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderReceiptTask.java new file mode 100644 index 00000000..c867964a --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderReceiptTask.java @@ -0,0 +1,46 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** 用户确认收货Task + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderReceiptTask { + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderReceiptTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderReceiptTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.takeByUser(); + + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderReceiptTask.task" + " | msg : " + e.getMessage()); + } + + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderRefundTask.java b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderRefundTask.java new file mode 100644 index 00000000..aa2f8472 --- /dev/null +++ b/crmeb/src/main/java/com/zbkj/crmeb/task/order/OrderRefundTask.java @@ -0,0 +1,47 @@ +package com.zbkj.crmeb.task.order; + +import com.utils.DateUtil; +import com.zbkj.crmeb.store.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 账单退款操作 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Component +@Configuration //读取配置 +@EnableScheduling // 2.开启定时任务 +public class OrderRefundTask { + //日志 + private static final Logger logger = LoggerFactory.getLogger(OrderRefundTask.class); + + @Autowired + private OrderTaskService orderTaskService; + + @Scheduled(fixedDelay = 1000 * 60L) //1分钟同步一次数据 + public void init(){ + logger.info("---OrderRefundTask task------produce Data with fixed rate task: Execution Time - {}", DateUtil.nowDateTime()); + try { + orderTaskService.refundApply(); + + }catch (Exception e){ + e.printStackTrace(); + logger.error("OrderRefundTask.task" + " | msg : " + e.getMessage()); + } + + } +} diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/controller/UserController.java b/crmeb/src/main/java/com/zbkj/crmeb/user/controller/UserController.java index 3b162bd8..c67aed1b 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/controller/UserController.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/controller/UserController.java @@ -180,11 +180,9 @@ public class UserController { } /** - * 会员分组 + * 会员标签 * @param id String id * @param tagId Integer 标签id - * @author Mr.Zhang - * @since 2020-04-28 */ @ApiOperation(value = "标签") @RequestMapping(value = "/tag", method = RequestMethod.POST) diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/model/User.java b/crmeb/src/main/java/com/zbkj/crmeb/user/model/User.java index d9ac9e91..bec143a6 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/model/User.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/model/User.java @@ -95,7 +95,7 @@ public class User implements Serializable { private BigDecimal brokeragePrice; @ApiModelProperty(value = "用户剩余积分") - private BigDecimal integral; + private Integer integral; @ApiModelProperty(value = "用户剩余经验") private Integer experience; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/request/UserOperateIntegralMoneyRequest.java b/crmeb/src/main/java/com/zbkj/crmeb/user/request/UserOperateIntegralMoneyRequest.java index 4d3c29e1..53fd7ebc 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/request/UserOperateIntegralMoneyRequest.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/request/UserOperateIntegralMoneyRequest.java @@ -7,10 +7,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.hibernate.validator.constraints.Range; -import javax.validation.constraints.DecimalMax; -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.*; import java.io.Serializable; import java.math.BigDecimal; @@ -45,9 +42,9 @@ public class UserOperateIntegralMoneyRequest implements Serializable { private int integralType; @ApiModelProperty(value = "积分") - @DecimalMin(value = "0") - @DecimalMax(value = "999999") - private BigDecimal integralValue; + @Min(value = 0) + @Max(value = 999999) + private Integer integralValue; @ApiModelProperty(value = "余额类型, 1 = 增加, 2 = 减少") @NotNull diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/response/TopDetail.java b/crmeb/src/main/java/com/zbkj/crmeb/user/response/TopDetail.java index 462dae25..7f3563de 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/response/TopDetail.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/response/TopDetail.java @@ -24,7 +24,7 @@ public class TopDetail { // 余额 private BigDecimal balance; // 积分 - private BigDecimal integralCount; + private Integer integralCount; // 总计订单 private Integer allOrderCount; // 本月订单 diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/response/UserResponse.java b/crmeb/src/main/java/com/zbkj/crmeb/user/response/UserResponse.java index 3b0d6a47..78201617 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/response/UserResponse.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/response/UserResponse.java @@ -86,7 +86,7 @@ public class UserResponse { private BigDecimal brokeragePrice; @ApiModelProperty(value = "用户剩余积分") - private BigDecimal integral; + private Integer integral; @ApiModelProperty(value = "用户剩余经验") private Integer experience; diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserBillService.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserBillService.java index 7d6de67e..c1e1ec95 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserBillService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserBillService.java @@ -181,4 +181,11 @@ public interface UserBillService extends IService { * @return 明细类型集合 */ List getSearchOption(); + + /** + * 获取订单历史处理记录(退款使用) + * @param orderId 订单id + * @param uid 用户id + */ + List findListByOrderIdAndUid(Integer orderId, Integer uid); } \ No newline at end of file diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserLevelService.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserLevelService.java index 7e134beb..1c6de47c 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserLevelService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserLevelService.java @@ -1,6 +1,7 @@ package com.zbkj.crmeb.user.service; import com.common.PageParamRequest; +import com.zbkj.crmeb.user.model.User; import com.zbkj.crmeb.user.model.UserLevel; import com.baomidou.mybatisplus.extension.service.IService; import com.zbkj.crmeb.user.request.UserLevelSearchRequest; @@ -32,4 +33,11 @@ public interface UserLevelService extends IService { * @return 用户等级 */ UserLevel getUserLevelByUserId(Integer userId); + + /** + * 经验升级 + * @param user + * @return + */ + Boolean upLevel(User user); } \ No newline at end of file diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserService.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserService.java index 293b4056..1fc2fc3a 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserService.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/UserService.java @@ -53,11 +53,12 @@ public interface UserService extends IService { /** * 更新余额 - * @param userId 用户id - * @param price 余额 + * @param user 用户 + * @param price 金额 + * @param type 增加add、扣减sub * @return 更新后的用户数据 */ - boolean updateNowMoney(int userId, BigDecimal price); + Boolean updateNowMoney(User user, BigDecimal price, String type); boolean group(String id, String groupId); @@ -149,4 +150,28 @@ public interface UserService extends IService { * @return */ Boolean editSpread(UserUpdateSpreadRequest request); + + /** + * 更新用户积分 + * @param user 用户 + * @param integral 积分 + * @param type 增加add、扣减sub + * @return 更新后的用户对象 + */ + Boolean updateIntegral(User user, Integer integral, String type); + + /** + * 获取分销人员列表 + * @param keywords 搜索参数 + * @param dateLimit 时间参数 + */ + List findDistributionList(String keywords, String dateLimit); + + /** + * 获取发展会员人数 + * @param ids 推广人id集合 + * @param dateLimit 时间参数 + * @return + */ + Integer getDevelopDistributionPeopleNum(List ids, String dateLimit); } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserBillServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserBillServiceImpl.java index 1d975e85..8d38bcc1 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserBillServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserBillServiceImpl.java @@ -140,7 +140,9 @@ public class UserBillServiceImpl extends ServiceImpl impl QueryWrapper queryWrapper = new QueryWrapper<>(); dateLimitUtilVo dateLimit = DateUtil.getDateLimit(type); - queryWrapper.select("uid", "sum(IF((pm=0), -number, number))AS number").eq("status", true); + queryWrapper.select("uid", "sum(IF((pm=0), -number, number))AS number"); + queryWrapper.eq("status", true); + queryWrapper.eq("category", Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE); if(!StringUtils.isBlank(dateLimit.getStartTime())){ queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime()); } @@ -218,25 +220,6 @@ public class UserBillServiceImpl extends ServiceImpl impl */ @Override public PageInfo getListAdmin(FundsMonitorSearchRequest request, PageParamRequest pageParamRequest) { -// List userBillList = getList(request, pageParamRequest); -// if(userBillList.size() < 1){ -// return new PageInfo<>(); -// } -// -// List responses = new ArrayList<>(); -// -// //用户信息 -// List userIdList = userBillList.stream().map(UserBill::getUid).distinct().collect(Collectors.toList()); -// HashMap mapListInUid = userService.getMapListInUid(userIdList); -// -// for (UserBill userBill : userBillList) { -// UserBillResponse userBillResponse = new UserBillResponse(); -// BeanUtils.copyProperties(userBill, userBillResponse); -// userBillResponse.setNickName(mapListInUid.get(userBill.getUid()).getNickname()); -// responses.add(userBillResponse); -// } - -// return CommonPage.copyPageInfo(userBillPage, responses); userBillPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()); Map map = new HashMap<>(); if (StrUtil.isNotBlank(request.getKeywords())) { @@ -257,6 +240,9 @@ public class UserBillServiceImpl extends ServiceImpl impl map.put("startTime", dateLimit.getStartTime()); map.put("endTime", dateLimit.getEndTime()); } + if (CollUtil.isNotEmpty(request.getUserIdList())) { + map.put("userIdList", request.getUserIdList()); + } List responses = dao.getListAdminAndIntegeal(map); return CommonPage.copyPageInfo(userBillPage, responses); @@ -315,8 +301,7 @@ public class UserBillServiceImpl extends ServiceImpl impl QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.select("sum(number) as number"). - eq("category", category). + queryWrapper.eq("category", category). eq("status", 1); if (ObjectUtil.isNotNull(userId)) { queryWrapper.eq("uid", userId); @@ -331,11 +316,16 @@ public class UserBillServiceImpl extends ServiceImpl impl dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date); queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime()); } - UserBill userBill = dao.selectOne(queryWrapper); - if(null == userBill || null == userBill.getNumber()){ +// UserBill userBill = dao.selectOne(queryWrapper); +// if(null == userBill || null == userBill.getNumber()){ +// return BigDecimal.ZERO; +// } +// return userBill.getNumber(); + List userBills = dao.selectList(queryWrapper); + if (CollUtil.isEmpty(userBills)) { return BigDecimal.ZERO; } - return userBill.getNumber(); + return userBills.stream().map(UserBill::getNumber).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2); } /** @@ -377,20 +367,17 @@ public class UserBillServiceImpl extends ServiceImpl impl */ @Override public boolean saveRefundBill(StoreOrderRefundRequest request, User user) { - try{ - UserBill userBill = new UserBill(); - userBill.setTitle("商品退款"); - userBill.setUid(user.getUid()); - userBill.setCategory(Constants.USER_BILL_CATEGORY_MONEY); - userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_REFUND); - userBill.setNumber(request.getAmount()); - userBill.setLinkId(request.getOrderId().toString()); - userBill.setBalance(user.getNowMoney().add(request.getAmount())); - userBill.setMark("订单退款到余额" + request.getAmount() + "元"); - return save(userBill); - }catch (Exception e){ - throw new CrmebException(e.getMessage()); - } + UserBill userBill = new UserBill(); + userBill.setTitle("商品退款"); + userBill.setUid(user.getUid()); + userBill.setCategory(Constants.USER_BILL_CATEGORY_MONEY); + userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT_REFUND); + userBill.setNumber(request.getAmount()); + userBill.setLinkId(request.getOrderId().toString()); + userBill.setBalance(user.getNowMoney().add(request.getAmount())); + userBill.setMark("订单退款到余额" + request.getAmount() + "元"); + userBill.setPm(1); + return save(userBill); } /** @@ -608,6 +595,21 @@ public class UserBillServiceImpl extends ServiceImpl impl return dao.selectList(qw); } + /** + * 获取订单历史处理记录(退款使用) + * @param orderId 订单id + * @param uid 用户id + * @return + */ + @Override + public List findListByOrderIdAndUid(Integer orderId, Integer uid) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(UserBill::getUid, uid); + lqw.eq(UserBill::getLinkId, String.valueOf(orderId)); + lqw.eq(UserBill::getStatus, 1); + return dao.selectList(lqw); + } + /////////////////////////////////////////////////////////////////////// 自定义方法 private BigDecimal getIntegerByEntity(UserBill userBill) { diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserLevelServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserLevelServiceImpl.java index ad18e395..de825131 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserLevelServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserLevelServiceImpl.java @@ -1,5 +1,6 @@ package com.zbkj.crmeb.user.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.common.PageParamRequest; import com.constants.Constants; @@ -8,6 +9,7 @@ import com.github.pagehelper.PageHelper; import com.utils.DateUtil; import com.zbkj.crmeb.system.model.SystemUserLevel; +import com.zbkj.crmeb.system.request.SystemUserLevelSearchRequest; import com.zbkj.crmeb.system.service.SystemUserLevelService; import com.zbkj.crmeb.user.model.User; import com.zbkj.crmeb.user.model.UserLevel; @@ -18,6 +20,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zbkj.crmeb.user.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import java.util.Date; @@ -47,6 +50,9 @@ public class UserLevelServiceImpl extends ServiceImpl i @Autowired private UserService userService; + @Autowired + private TransactionTemplate transactionTemplate; + /** * 列表 @@ -155,5 +161,80 @@ public class UserLevelServiceImpl extends ServiceImpl i levelLambdaQueryWrapper.eq(UserLevel::getIsDel, 0); return dao.selectOne(levelLambdaQueryWrapper); } + + /** + * 用户升级 + * @param user + * @return + */ + @Override + public Boolean upLevel(User user) { + //确定当前经验所达到的等级 + SystemUserLevelSearchRequest systemUserLevelSearchRequest = new SystemUserLevelSearchRequest(); + systemUserLevelSearchRequest.setIsDel(false); + systemUserLevelSearchRequest.setIsShow(true); + List list = systemUserLevelService.getList(systemUserLevelSearchRequest, new PageParamRequest()); + + SystemUserLevel userLevelConfig = new SystemUserLevel(); + for (SystemUserLevel systemUserLevel : list) { + if(user.getExperience() > systemUserLevel.getExperience()){ + userLevelConfig = systemUserLevel; + continue; + } + break; + } + + if(userLevelConfig.getId() == null){ + System.out.println("未找到用户对应的等级"); + return Boolean.TRUE; + } + + // 判断用户是否还在原等级 + UserLevel userLevel = getByUid(user.getUid()); + if (ObjectUtil.isNotNull(userLevel) && userLevelConfig.getId().equals(userLevel.getLevelId())) { + // 之前有记录,并且等级不需要变化 + return Boolean.TRUE; + } + + + UserLevel newLevel = new UserLevel(); + newLevel.setStatus(true); + newLevel.setIsDel(false); + newLevel.setGrade(userLevelConfig.getGrade()); + newLevel.setUid(user.getUid()); + newLevel.setLevelId(userLevelConfig.getId()); + newLevel.setDiscount(userLevelConfig.getDiscount()); + + Date date = DateUtil.nowDateTimeReturnDate(Constants.DATE_FORMAT); + String mark = Constants.USER_LEVEL_OPERATE_LOG_MARK.replace("【{$userName}】", user.getNickname()). + replace("{$date}", DateUtil.dateToStr(date, Constants.DATE_FORMAT)). + replace("{$levelName}", userLevelConfig.getName()); + newLevel.setMark(mark); + + //更新会员等级 + user.setLevel(userLevelConfig.getGrade()); + Boolean execute = transactionTemplate.execute(e -> { + if (userLevel == null) { + //创建新的会员等级信息 + save(userLevel); + } else { + //有数据,更新即可 + newLevel.setId(userLevel.getId()); + updateById(newLevel); + } + + userService.updateById(user); + return Boolean.TRUE; + }); + return execute; + } + + private UserLevel getByUid(Integer uid) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(UserLevel::getUid, uid); + lqw.eq(UserLevel::getStatus, true); + lqw.eq(UserLevel::getIsDel, false); + return dao.selectOne(lqw); + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserServiceImpl.java index df78d356..142bb6da 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserServiceImpl.java @@ -31,7 +31,6 @@ import com.zbkj.crmeb.front.request.UserBindingRequest; import com.zbkj.crmeb.front.response.*; import com.zbkj.crmeb.marketing.request.StoreCouponUserSearchRequest; import com.zbkj.crmeb.marketing.response.StoreCouponUserResponse; -import com.zbkj.crmeb.marketing.service.StoreCouponService; import com.zbkj.crmeb.marketing.service.StoreCouponUserService; import com.zbkj.crmeb.store.model.StoreOrder; import com.zbkj.crmeb.store.request.RetailShopStairUserRequest; @@ -113,9 +112,6 @@ public class UserServiceImpl extends ServiceImpl implements UserS @Autowired private StoreCouponUserService storeCouponUserService; - @Autowired - private StoreCouponService storeCouponService; - /** * 分页显示用户表 * @param request 搜索条件 @@ -268,7 +264,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS throw new CrmebException("至少输入一个金额"); } - if(request.getMoneyValue().compareTo(BigDecimal.ZERO) < 1 && request.getIntegralValue().compareTo(BigDecimal.ZERO) < 1){ + if(request.getMoneyValue().compareTo(BigDecimal.ZERO) < 1 && request.getIntegralValue() <= 0){ throw new CrmebException("最小值为0.01"); } @@ -294,7 +290,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS } // 处理积分 - if(request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0){ + if(request.getIntegralValue() > 0){ if(request.getIntegralType() == 1){ userOperateFundsRequest.setFoundsType(Constants.USER_BILL_TYPE_SYSTEM_ADD); userOperateFundsRequest.setType(request.getIntegralType()); @@ -303,7 +299,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS userOperateFundsRequest.setType(0); } userOperateFundsRequest.setFoundsCategory(Constants.USER_BILL_CATEGORY_INTEGRAL); - userOperateFundsRequest.setValue(request.getIntegralValue()); + userOperateFundsRequest.setValue(new BigDecimal(request.getIntegralValue())); updateFounds(userOperateFundsRequest, true); } @@ -400,7 +396,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS if(null != user.getBrokeragePrice() && user.getBrokeragePrice().compareTo(BigDecimal.ZERO) > 0){ lambdaUpdateWrapper.set(User::getBrokeragePrice, user.getBrokeragePrice()); } - if(null != user.getIntegral() && user.getIntegral().compareTo(BigDecimal.ZERO) >= 0){ + if(null != user.getIntegral() && user.getIntegral() >= 0){ lambdaUpdateWrapper.set(User::getIntegral, user.getIntegral()); } if(null != user.getExperience() && user.getExperience() > 0){ @@ -449,15 +445,23 @@ public class UserServiceImpl extends ServiceImpl implements UserS /** * 更新用户金额 - * @param userId 用户id - * @param price 余额 + * @param user 用户 + * @param price 金额 + * @param type 增加add、扣减sub * @return 更新后的用户对象 */ @Override - public boolean updateNowMoney(int userId, BigDecimal price) { + public Boolean updateNowMoney(User user, BigDecimal price, String type) { LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); - lambdaUpdateWrapper.eq(User::getUid, userId); - lambdaUpdateWrapper.set(User::getNowMoney, price); + if (type.equals("add")) { + lambdaUpdateWrapper.set(User::getNowMoney, user.getNowMoney().add(price)); + } else { + lambdaUpdateWrapper.set(User::getNowMoney, user.getNowMoney().subtract(price)); + } + lambdaUpdateWrapper.eq(User::getUid, user.getUid()); + if (type.equals("sub")) { + lambdaUpdateWrapper.apply(StrUtil.format(" now_money - {} >= 0", price)); + } return update(lambdaUpdateWrapper); } @@ -470,30 +474,21 @@ public class UserServiceImpl extends ServiceImpl implements UserS */ @Override public boolean group(String id, String groupIdValue) { - ArrayList userList = new ArrayList<>(); + if (StrUtil.isBlank(id)) throw new CrmebException("会员编号不能为空"); + if (StrUtil.isBlank(groupIdValue)) throw new CrmebException("分组id不能为空"); + //循环id处理 - List list = getListInUid(CrmebUtil.stringToArray(id)); - if(list.size() < 1){ + List idList = CrmebUtil.stringToArray(id); + idList = idList.stream().distinct().collect(Collectors.toList()); + List list = getListInUid(idList); + if (CollUtil.isEmpty(list)) throw new CrmebException("没有找到用户信息"); + if(list.size() < idList.size()){ throw new CrmebException("没有找到用户信息"); } for (User user : list) { - if(!StringUtils.isBlank(user.getGroupId())){ - groupIdValue = user.getGroupId() + groupIdValue; - } - //清除已经删除或者去掉的id - groupIdValue = userGroupService.clean(groupIdValue); - if(StringUtils.isBlank(groupIdValue)){ - continue; - } - - List groupIdList = CrmebUtil.stringToArray(groupIdValue); - user.setGroupId("," + StringUtils.join(groupIdList, ",") + ","); - userList.add(user); + user.setGroupId(groupIdValue); } - if(userList.size() < 1){ - throw new CrmebException("没有可供设置的分组"); - } - return updateBatchById(userList); + return updateBatchById(list); } /** @@ -558,6 +553,8 @@ public class UserServiceImpl extends ServiceImpl implements UserS loginResponse.setExpiresTime(DateUtil.addSecond(DateUtil.nowDateTime(), (int)time)); + user.setLastLoginTime(DateUtil.nowDateTime()); + updateById(user); return loginResponse; } @@ -584,6 +581,9 @@ public class UserServiceImpl extends ServiceImpl implements UserS LoginResponse loginResponse = new LoginResponse(); loginResponse.setToken(token(user)); + + user.setLastLoginTime(DateUtil.nowDateTime()); + updateById(user); user.setPwd(null); //绑定推广关系 @@ -829,7 +829,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS userCenterResponse.setLevel(currentUser.getLevel()); // 判断是否开启会员功能 - Integer memberFuncStatus = Integer.valueOf(systemConfigService.getValueByKey("member_func_status")); + Integer memberFuncStatus = Integer.valueOf(systemConfigService.getValueByKey("vip_open")); if(memberFuncStatus == 0){ userCenterResponse.setVip(false); }else{ @@ -918,31 +918,21 @@ public class UserServiceImpl extends ServiceImpl implements UserS */ @Override public boolean tag(String id, String tagIdValue) { + if (StrUtil.isBlank(id)) throw new CrmebException("会员编号不能为空"); + if (StrUtil.isBlank(tagIdValue)) throw new CrmebException("标签id不能为空"); + //循环id处理 - ArrayList userList = new ArrayList<>(); - //循环id处理 - List list = getListInUid(CrmebUtil.stringToArray(id)); + List idList = CrmebUtil.stringToArray(id); + idList = idList.stream().distinct().collect(Collectors.toList()); + List list = getListInUid(idList); + if (CollUtil.isEmpty(list)) throw new CrmebException("没有找到用户信息"); if(list.size() < 1){ throw new CrmebException("没有找到用户信息"); } for (User user : list) { - if(!StringUtils.isBlank(user.getTagId())){ - tagIdValue = user.getTagId() + tagIdValue; - } - //清除已经删除或者去掉的id - tagIdValue = userTagService.clean(tagIdValue); - if(StringUtils.isBlank(tagIdValue)){ - continue; - } - - List tagIdList = CrmebUtil.stringToArray(tagIdValue); - user.setTagId("," + StringUtils.join(tagIdList, ",") + ","); - userList.add(user); + user.setTagId(tagIdValue); } - if(userList.size() < 1){ - throw new CrmebException("没有可供设置的标签"); - } - return updateBatchById(userList); + return updateBatchById(list); } /** @@ -1165,6 +1155,9 @@ public class UserServiceImpl extends ServiceImpl implements UserS int result = value.subtract(request.getValue()).compareTo(BigDecimal.ZERO); if(result < 0){ + if (request.getFoundsCategory().equals("integral")) { + throw new CrmebException("此用户当前积分为 " + value + ", 需要减少的积分不能大于 " + value); + } throw new CrmebException("此用户当前资金为 " + value + ", 需要减少的资金不能大于 " + value); } } @@ -1180,7 +1173,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS BigDecimal value = null; if(request.getFoundsCategory().equals(Constants.USER_BILL_CATEGORY_INTEGRAL)){ - value = user.getIntegral(); + value = new BigDecimal(user.getIntegral()); } if(request.getFoundsCategory().equals(Constants.USER_BILL_CATEGORY_MONEY)){ @@ -1363,30 +1356,81 @@ public class UserServiceImpl extends ServiceImpl implements UserS */ @Override public PageInfo getUserListBySpreadLevel(RetailShopStairUserRequest request, PageParamRequest pageParamRequest) { - Page userPage = PageHelper.startPage(pageParamRequest.getPage(),pageParamRequest.getLimit()); - List users = getUsersBySpreadLevel(request); - return CommonPage.copyPageInfo(userPage, users); +// Page userPage = PageHelper.startPage(pageParamRequest.getPage(),pageParamRequest.getLimit()); +// List users = getUsersBySpreadLevel(request); +// return CommonPage.copyPageInfo(userPage, users); + if (request.getType().equals(1)) { + return getFirstSpreadUserListPage(request, pageParamRequest); + } + if (request.getType().equals(2)) { + return getSecondSpreadUserListPage(request, pageParamRequest); + } + return getAllSpreadUserListPage(request, pageParamRequest); } // 分页获取一级推广员 - private List getFirstSpreadUserListPage(RetailShopStairUserRequest request, PageParamRequest pageParamRequest) { + private PageInfo getFirstSpreadUserListPage(RetailShopStairUserRequest request, PageParamRequest pageParamRequest) { Page userPage = PageHelper.startPage(pageParamRequest.getPage(),pageParamRequest.getLimit()); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getSpreadUid, request.getUid()); if (StrUtil.isNotBlank(request.getNickName())) { queryWrapper.and(e -> e.like(User::getNickname, request.getNickName()).or().eq(User::getUid, request.getNickName()) .or().eq(User::getPhone, request.getNickName())); - } - queryWrapper.eq(User::getSpreadUid, request.getUid()); + if (StrUtil.isNotBlank(request.getDateLimit())) { + dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit()); + queryWrapper.between(User::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime()); + } + List userList = userDao.selectList(queryWrapper); + return CommonPage.copyPageInfo(userPage, userList); + } - return null; - }; // 分页获取二级推广员 - private List getSecondSpreadUserListPage() {return null;}; - // 分页获取所有推广员 - private List getAllSpreadUserListPage() {return null;}; + private PageInfo getSecondSpreadUserListPage(RetailShopStairUserRequest request, PageParamRequest pageParamRequest) { + // 先获取一级推广员 + List firstUserList = getSpreadListBySpreadIdAndType(request.getUid(), 1); + if (CollUtil.isEmpty(firstUserList)) { + return new PageInfo(CollUtil.newArrayList()); + } + List userIds = firstUserList.stream().map(User::getUid).distinct().collect(Collectors.toList()); + Page userPage = PageHelper.startPage(pageParamRequest.getPage(),pageParamRequest.getLimit()); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(User::getSpreadUid, userIds); + if (StrUtil.isNotBlank(request.getNickName())) { + queryWrapper.and(e -> e.like(User::getNickname, request.getNickName()).or().eq(User::getUid, request.getNickName()) + .or().eq(User::getPhone, request.getNickName())); + } + if (StrUtil.isNotBlank(request.getDateLimit())) { + dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit()); + queryWrapper.between(User::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime()); + } + List userList = userDao.selectList(queryWrapper); + return CommonPage.copyPageInfo(userPage, userList); + } + // 分页获取所有推广员 + private PageInfo getAllSpreadUserListPage(RetailShopStairUserRequest request, PageParamRequest pageParamRequest) { + // 先所有一级推广员 + List firstUserList = getSpreadListBySpreadIdAndType(request.getUid(), 1); + if (CollUtil.isEmpty(firstUserList)) { + return new PageInfo(CollUtil.newArrayList()); + } + List userIds = firstUserList.stream().map(User::getUid).distinct().collect(Collectors.toList()); + userIds.add(request.getUid()); + Page userPage = PageHelper.startPage(pageParamRequest.getPage(),pageParamRequest.getLimit()); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(User::getSpreadUid, userIds); + if (StrUtil.isNotBlank(request.getNickName())) { + queryWrapper.and(e -> e.like(User::getNickname, request.getNickName()).or().eq(User::getUid, request.getNickName()) + .or().eq(User::getPhone, request.getNickName())); + } + if (StrUtil.isNotBlank(request.getDateLimit())) { + dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit()); + queryWrapper.between(User::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime()); + } + List userList = userDao.selectList(queryWrapper); + return CommonPage.copyPageInfo(userPage, userList); + } /** * 根据推广级别和其他参数获取推广列表 @@ -1549,12 +1593,12 @@ public class UserServiceImpl extends ServiceImpl implements UserS @Override public List getTopSpreadPeopleListByDate(String type, PageParamRequest pageParamRequest) { PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()); - dateLimitUtilVo dateLimit = DateUtil.getDateLimit(type); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select("count(spread_count) as spread_count, spread_uid") .gt("spread_uid", 0) .eq("status", true); - if(!StringUtils.isBlank(dateLimit.getStartTime())){ + if(StrUtil.isNotBlank(type)){ + dateLimitUtilVo dateLimit = DateUtil.getDateLimit(type); queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime()); } queryWrapper.groupBy("spread_uid").orderByDesc("spread_count"); @@ -1578,7 +1622,7 @@ public class UserServiceImpl extends ServiceImpl implements UserS User userVo = userVoList.get(spreadVo.getSpreadUid()); user.setUid(spreadVo.getSpreadUid()); user.setAvatar(userVo.getAvatar()); - user.setSpreadCount(userVo.getSpreadCount()); + user.setSpreadCount(spreadVo.getSpreadCount()); if(StringUtils.isBlank(userVo.getNickname())){ user.setNickname(userVo.getPhone().substring(0, 2) + "****" + userVo.getPhone().substring(7)); }else{ @@ -1725,4 +1769,66 @@ public class UserServiceImpl extends ServiceImpl implements UserS tempUser.setSpreadTime(DateUtil.nowDateTime()); return updateById(tempUser); } + + /** + * 更新用户积分 + * @param user 用户 + * @param integral 积分 + * @param type 增加add、扣减sub + * @return 更新后的用户对象 + */ + @Override + public Boolean updateIntegral(User user, Integer integral, String type) { + LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); + if (type.equals("add")) { + lambdaUpdateWrapper.set(User::getIntegral, user.getIntegral() + integral); + } else { + lambdaUpdateWrapper.set(User::getIntegral, user.getIntegral() - integral); + } + lambdaUpdateWrapper.eq(User::getUid, user.getUid()); + if (type.equals("sub")) { + lambdaUpdateWrapper.apply(StrUtil.format(" integral - {} >= 0", integral)); + } + return update(lambdaUpdateWrapper); + } + + /** + * 获取分销人员列表 + * @param keywords 搜索参数 + * @param dateLimit 时间参数 + * @return List + */ + @Override + public List findDistributionList(String keywords, String dateLimit) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(User::getIsPromoter, true); + if (StrUtil.isNotBlank(dateLimit)) { + dateLimitUtilVo dateLimitVo = DateUtil.getDateLimit(dateLimit); + lqw.between(User::getCreateTime, dateLimitVo.getStartTime(), dateLimitVo.getEndTime()); + } + if (StrUtil.isNotBlank(keywords)) { + lqw.and(i -> i.like(User::getRealName, keywords) //真实姓名 + .or().like(User::getPhone, keywords) //手机号码 + .or().like(User::getNickname, keywords) //用户昵称 + .or().like(User::getUid, keywords)); //uid + } + return userDao.selectList(lqw); + } + + /** + * 获取发展会员人数 + * @param ids 推广人id集合 + * @param dateLimit 时间参数 + * @return Integer + */ + @Override + public Integer getDevelopDistributionPeopleNum(List ids, String dateLimit) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.in(User::getSpreadUid, ids); + if (StrUtil.isNotBlank(dateLimit)) { + dateLimitUtilVo dateLimitVo = DateUtil.getDateLimit(dateLimit); + lqw.between(User::getCreateTime, dateLimitVo.getStartTime(), dateLimitVo.getEndTime()); + } + return userDao.selectCount(lqw); + } } diff --git a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserSignServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserSignServiceImpl.java index 7ff84254..8980c266 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserSignServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/user/service/impl/UserSignServiceImpl.java @@ -139,7 +139,7 @@ public class UserSignServiceImpl extends ServiceImpl impl //更新用户签到天数 user.setSignNum(user.getSignNum()+1); //更新用户积分 - user.setIntegral(user.getIntegral().add(integralFundsRequest.getValue())); + user.setIntegral(user.getIntegral() + integralFundsRequest.getValue().intValue()); // 更新用户经验 user.setExperience(user.getExperience() + experienceFundsRequest.getValue().intValue()); @@ -161,7 +161,7 @@ public class UserSignServiceImpl extends ServiceImpl impl // 小程序消息积分变动通知 WechatSendMessageForIntegral integralPram = new WechatSendMessageForIntegral( "您的积分变动如下","签到获得积分","签到","0",configVo.getIntegral()+"", - (user.getIntegral().add(BigDecimal.valueOf(configVo.getIntegral())))+"", + (user.getIntegral() + configVo.getIntegral())+"", DateUtil.nowDateTimeStr(),"暂无","暂无","签到赠送积分" ); wechatSendMessageForMinService.sendIntegralMessage(integralPram,user.getUid()); diff --git a/crmeb/src/main/java/com/zbkj/crmeb/wechat/service/impl/WeChatServiceImpl.java b/crmeb/src/main/java/com/zbkj/crmeb/wechat/service/impl/WeChatServiceImpl.java index e0125f58..3bd3bf12 100644 --- a/crmeb/src/main/java/com/zbkj/crmeb/wechat/service/impl/WeChatServiceImpl.java +++ b/crmeb/src/main/java/com/zbkj/crmeb/wechat/service/impl/WeChatServiceImpl.java @@ -826,7 +826,6 @@ public class WeChatServiceImpl implements WeChatService { map.put("jsApiList", getJsApiList()); map.put("debug", debug); map.put("beta", beta); - map.put("yzfUrl", systemConfigService.getValueByKey(Constants.CONFIG_KEY_YZF_H5_URL)); return map; } diff --git a/crmeb/src/main/resources/mapper/user/UserBillMapper.xml b/crmeb/src/main/resources/mapper/user/UserBillMapper.xml index e9b88c12..9721236e 100644 --- a/crmeb/src/main/resources/mapper/user/UserBillMapper.xml +++ b/crmeb/src/main/resources/mapper/user/UserBillMapper.xml @@ -35,6 +35,12 @@ and ub.category = #{category, jdbcType=VARCHAR} + + and ub.uid in + + #{userIdList} + + and (ub.create_time between #{startTime} and #{endTime}) diff --git a/crmeb/start.sh b/crmeb/start.sh index 6236ed39..d1a15c31 100755 --- a/crmeb/start.sh +++ b/crmeb/start.sh @@ -48,7 +48,7 @@ if test -e $APP_NAME;then #通过检测日志来判断 while [ -f $LOG_FILE ] do - success=`grep "CRMEB Started!" $LOG_FILE` + success=`grep "Started CrmebApplication in " $LOG_FILE` if [[ "$success" != "" ]] then # echo "Crmeb start ........."