diff --git a/crmeb-admin/src/main/java/com/zbkj/admin/controller/StoreProductController.java b/crmeb-admin/src/main/java/com/zbkj/admin/controller/StoreProductController.java index 0142513..c71a326 100644 --- a/crmeb-admin/src/main/java/com/zbkj/admin/controller/StoreProductController.java +++ b/crmeb-admin/src/main/java/com/zbkj/admin/controller/StoreProductController.java @@ -9,6 +9,7 @@ import com.zbkj.common.response.StoreProductInfoResponse; import com.zbkj.common.response.StoreProductResponse; import com.zbkj.common.response.StoreProductTabsHeader; import com.zbkj.common.result.CommonResult; +import com.zbkj.service.pojo.XsSkuInfo; import com.zbkj.service.service.StoreCartService; import com.zbkj.service.service.StoreProductService; import io.swagger.annotations.Api; @@ -51,7 +52,16 @@ public class StoreProductController { @Autowired private StoreCartService storeCartService; + /** + * 分页显示商品表 + */ + + @ApiOperation(value = "模糊查询sku") //配合swagger使用 + @RequestMapping(value = "/find", method = RequestMethod.GET) + public CommonResult> findSku(String content ) { + return CommonResult.success( storeProductService.findSku(content, null,null)); + } /** * 分页显示商品表 * @param request 搜索条件 diff --git a/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/ExtendController.java b/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/ExtendController.java new file mode 100644 index 0000000..e5c2d4e --- /dev/null +++ b/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/ExtendController.java @@ -0,0 +1,46 @@ +package com.zbkj.admin.controller.extend; + +import cn.hutool.core.collection.CollUtil; +import com.zbkj.common.model.extend.MallDelivery; +import com.zbkj.service.service.ExtendService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 对外接口 + * @author wyq + */ +@Slf4j +@RestController +@RequestMapping("api/extend") +@Api(tags = "扩展") //配合swagger使用 +public class ExtendController { + + @Resource + private ExtendService extendService; + + /** + * 多包裹发货 + * @param mallDeliverys + * @return + */ + @PostMapping("/delivery/create") + String createDelivery(@RequestBody List mallDeliverys){ + if (CollUtil.isNotEmpty(mallDeliverys)){ + mallDeliverys.forEach(mallDelivery->{ + extendService.createDelivery( mallDelivery); + }); + } + + return ""; + } + + +} diff --git a/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/TestController.java b/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/TestController.java new file mode 100644 index 0000000..12b0b0d --- /dev/null +++ b/crmeb-admin/src/main/java/com/zbkj/admin/controller/extend/TestController.java @@ -0,0 +1,28 @@ +package com.zbkj.admin.controller.extend; + + +import com.zbkj.service.service.OrderTaskService; +import com.zbkj.service.service.RetryService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 测试接口 + * @author wyq + */ +@Slf4j +@RestController +@RequestMapping("api/extend/test") +@Api(tags = "测试接口") +public class TestController { + @Autowired + private OrderTaskService orderTaskService; + + @Autowired + private RetryService retryService; + +} diff --git a/crmeb-admin/src/main/java/com/zbkj/admin/task/order/OrderSyncRuoyiTask.java b/crmeb-admin/src/main/java/com/zbkj/admin/task/order/OrderSyncRuoyiTask.java new file mode 100644 index 0000000..b1dcf09 --- /dev/null +++ b/crmeb-admin/src/main/java/com/zbkj/admin/task/order/OrderSyncRuoyiTask.java @@ -0,0 +1,34 @@ +package com.zbkj.admin.task.order; + +import com.zbkj.common.utils.CrmebDateUtil; +import com.zbkj.service.service.OrderTaskService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 新订单自动同步ruoyi + * @author wyq + */ +@Component("OrderSyncRuoyiTask") +public class OrderSyncRuoyiTask { + @Autowired + private OrderTaskService orderTaskService; + + + private static final Logger logger = LoggerFactory.getLogger(OrderSyncRuoyiTask.class); + public void autoSync() + + { + + logger.info("---OrderSyncRuoyiTask task------produce Data with fixed rate task: Execution Time - {}", CrmebDateUtil.nowDateTime()); + try { + orderTaskService.autoSync(); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("OrderSyncRuoyiTask.task" + " | msg : " + e.getMessage()); + } + } +} diff --git a/crmeb-common/src/main/java/com/zbkj/common/constants/Constants.java b/crmeb-common/src/main/java/com/zbkj/common/constants/Constants.java index ac010b9..5c1a8cd 100644 --- a/crmeb-common/src/main/java/com/zbkj/common/constants/Constants.java +++ b/crmeb-common/src/main/java/com/zbkj/common/constants/Constants.java @@ -25,6 +25,7 @@ public class Constants { public static final int NUM_SEVEN = 7; public static final int NUM_TEN = 10; public static final int NUM_ONE_HUNDRED = 100; + public static final String ORDER_LOCK = "mall:ORDER_LOCK:"; //头部 token令牌key public static final String HEADER_AUTHORIZATION_KEY = "Authori-zation"; diff --git a/crmeb-common/src/main/java/com/zbkj/common/constants/WeChatConstants.java b/crmeb-common/src/main/java/com/zbkj/common/constants/WeChatConstants.java index f3468d1..8f3e952 100644 --- a/crmeb-common/src/main/java/com/zbkj/common/constants/WeChatConstants.java +++ b/crmeb-common/src/main/java/com/zbkj/common/constants/WeChatConstants.java @@ -225,7 +225,7 @@ public class WeChatConstants { public static final String PAY_NOTIFY_API_URI_WECHAT = "/api/admin/payment/callback/wechat"; // 公共号退款 public static final String PAY_REFUND_API_URI_WECHAT = "secapi/pay/refund"; - + public static final String PAY_REFUND_API_URI_WECHAT_QUERY = "pay/refundquery"; public static final String PAY_TYPE_JS = "JSAPI"; public static final String PAY_TYPE_H5 = "MWEB"; diff --git a/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallDelivery.java b/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallDelivery.java new file mode 100644 index 0000000..6ddbb8d --- /dev/null +++ b/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallDelivery.java @@ -0,0 +1,18 @@ +package com.zbkj.common.model.extend; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +/** + * @author wyq + */ +@Data +@AllArgsConstructor +public class MallDelivery { + + private String platformCode; + + private List expressList; +} diff --git a/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallExpressInfoDto.java b/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallExpressInfoDto.java new file mode 100644 index 0000000..d37c247 --- /dev/null +++ b/crmeb-common/src/main/java/com/zbkj/common/model/extend/MallExpressInfoDto.java @@ -0,0 +1,35 @@ +package com.zbkj.common.model.extend; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author wyq + */ +@Data +@AllArgsConstructor +@ApiModel(value = "发货快递信息") +public class MallExpressInfoDto { + + + @ApiModelProperty(value = "快递公司名称") + private String expressName; + + /** + * 快递单号 + */ + private String expressNo; + + @ApiModelProperty(value = "快递公司编码") + private String expressCode; + + @ApiModelProperty(value = "商品编码") + private String skuNo; + @ApiModelProperty(value = "商品名称") + private String skuName; + @ApiModelProperty(value = "商品数量") + private Integer num; + +} diff --git a/crmeb-common/src/main/java/com/zbkj/common/model/parcel/ParcelPO.java b/crmeb-common/src/main/java/com/zbkj/common/model/parcel/ParcelPO.java new file mode 100644 index 0000000..3f19f65 --- /dev/null +++ b/crmeb-common/src/main/java/com/zbkj/common/model/parcel/ParcelPO.java @@ -0,0 +1,85 @@ +package com.zbkj.common.model.parcel; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +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.time.LocalDateTime; + +/** + * @author wyq + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("eb_parcel") +@ApiModel(value="ParcelPO", description="包裹") +public class ParcelPO implements Serializable { + + /** + * 主键ID + */ + @TableId(type = IdType.AUTO) + private Long id; + @ApiModelProperty(value = "订单号") + private String platformCode; + @ApiModelProperty(value = "快递单") + private String expressNo; + @ApiModelProperty(value = "快递公司编码") + private String expressName; + @ApiModelProperty(value = "快递公司名") + private String expressCode; + @ApiModelProperty(value = "sku编码") + private String skuNo; + @ApiModelProperty(value = "sku名称") + private String skuName; + @ApiModelProperty(value = "数量") + private Integer num; + @ApiModelProperty(value = "图片") + private String image; + + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private String createdBy; + + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private String updatedBy; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdTime; + + /** + * 更新时间 + */ + @ApiModelProperty(value = "更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updatedTime; + + /** + * 是否逻辑删除:0未删除,1已删除 + */ + private Integer deleted; + @ApiModelProperty(value = "快递轨迹") + private String expressInfo; + @ApiModelProperty(value = "快递状态") + private String expressStatus; + @ApiModelProperty(value = "签收时间") +@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime signedTime; +} diff --git a/crmeb-common/src/main/java/com/zbkj/common/request/StoreOrderSendRequest.java b/crmeb-common/src/main/java/com/zbkj/common/request/StoreOrderSendRequest.java index 791eb36..a5dd4ce 100644 --- a/crmeb-common/src/main/java/com/zbkj/common/request/StoreOrderSendRequest.java +++ b/crmeb-common/src/main/java/com/zbkj/common/request/StoreOrderSendRequest.java @@ -1,5 +1,6 @@ package com.zbkj.common.request; +import com.zbkj.common.model.extend.MallExpressInfoDto; import com.zbkj.common.request.onepass.OnePassShipmentCreateOrderRequest; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -8,6 +9,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import javax.validation.constraints.NotBlank; +import java.util.List; /** * 订单发货对象 @@ -28,6 +30,7 @@ import javax.validation.constraints.NotBlank; public class StoreOrderSendRequest { private static final long serialVersionUID=1L; + private List ExpressList; @ApiModelProperty(value = "订单id") private Integer id; diff --git a/crmeb-common/src/main/java/com/zbkj/common/vo/WxRefundQuery.java b/crmeb-common/src/main/java/com/zbkj/common/vo/WxRefundQuery.java new file mode 100644 index 0000000..69132db --- /dev/null +++ b/crmeb-common/src/main/java/com/zbkj/common/vo/WxRefundQuery.java @@ -0,0 +1,65 @@ + +package com.zbkj.common.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 调用微信退款所需要的参数 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="WxRefundVo", description="调用微信退款所需要的参数") +public class WxRefundQuery { + + @ApiModelProperty(value = "appId,公众号名称,由商户传入", required = true) + private String appid; + + @ApiModelProperty(value = "直连商户的商户号,由微信支付生成并下发", required = true) + private String mch_id; + + @ApiModelProperty(value = "随机字符串,不长于32位", required = true) + private String nonce_str; + + @ApiModelProperty(value = "签名", required = true) + private String sign; + + @ApiModelProperty(value = "签名类型,目前支持HMAC-SHA256和MD5,默认为MD5") + private String sign_type = "MD5"; + + @ApiModelProperty(value = "微信支付订单号:微信生成的订单号,在支付通知中有返回") + private String transaction_id; + + @ApiModelProperty(value = "商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号", required = true) + private String out_trade_no; + + @ApiModelProperty(value = "商户退款单号,同一退款单号多次请求只退一笔。") + private String out_refund_no; + + @ApiModelProperty(value = "订单总金额,单位为分", required = true) + private int total_fee; + + @ApiModelProperty(value = "退款金额,单位为分", required = true) + private int refund_fee; + + @ApiModelProperty(value = "退款货币种类:符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型") + private String refund_fee_type = "CNY"; + + @ApiModelProperty(value = "退款结果通知url") + private String notify_url; + +} + diff --git a/crmeb-service/src/main/java/com/zbkj/service/dao/ParcelDao.java b/crmeb-service/src/main/java/com/zbkj/service/dao/ParcelDao.java new file mode 100644 index 0000000..fc23d88 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/dao/ParcelDao.java @@ -0,0 +1,21 @@ +package com.zbkj.service.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zbkj.common.model.parcel.ParcelPO; + +/** + * 订单表 Mapper 接口 + * +---------------------------------------------------------------------- + * | CRMEB [ CRMEB赋能开发者,助力企业发展 ] + * +---------------------------------------------------------------------- + * | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 + * +---------------------------------------------------------------------- + * | Author: CRMEB Team + * +---------------------------------------------------------------------- + */ +public interface ParcelDao extends BaseMapper { + + +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/dao/UserAddressDao.java b/crmeb-service/src/main/java/com/zbkj/service/dao/UserAddressDao.java index a73f901..ee2044c 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/dao/UserAddressDao.java +++ b/crmeb-service/src/main/java/com/zbkj/service/dao/UserAddressDao.java @@ -1,7 +1,9 @@ package com.zbkj.service.dao; +import com.zbkj.common.model.order.StoreOrder; import com.zbkj.common.model.user.UserAddress; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; /** * 用户地址表 Mapper 接口 @@ -16,5 +18,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; * +---------------------------------------------------------------------- */ public interface UserAddressDao extends BaseMapper { - + UserAddress selectDistinct(@Param("order") StoreOrder order); } diff --git a/crmeb-service/src/main/java/com/zbkj/service/dao/XsbuyDao.java b/crmeb-service/src/main/java/com/zbkj/service/dao/XsbuyDao.java new file mode 100644 index 0000000..96df245 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/dao/XsbuyDao.java @@ -0,0 +1,18 @@ +package com.zbkj.service.dao; + +import com.zbkj.service.pojo.XsSkuInfo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author wyq + */ +public interface XsbuyDao { + List selectListNew(@Param("content") String content,@Param("pageIndex") long l,@Param("pageSize") Long pageSize); + + + + + +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderCreateReqDTO.java b/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderCreateReqDTO.java new file mode 100644 index 0000000..1427974 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderCreateReqDTO.java @@ -0,0 +1,129 @@ +package com.zbkj.service.pojo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author wyq + */ +@Data +@ApiModel(description = "创建或更新手工订单请求参数") +public class TradeOrderCreateReqDTO { + private Long orderId; + private String platformCode; + + private String erpCode; + + + @ApiModelProperty("渠道 可选值:TO_B,EMPLOYEE_IN_PURCHASE") + @NotNull(message = "渠道不能为空") + private String channel; + @ApiModelProperty("业务归属部门code") + @NotBlank(message = "业务归属部门code不能为空") + private String deptCode; + @ApiModelProperty("业务归属部门name") + @NotBlank(message = "业务归属部门name不能为空") + private String deptName; + @ApiModelProperty("业务员code") + @NotBlank(message = "业务员不能为空") + private String businessMan; + @ApiModelProperty("业务员名称") + private String businessManName; + @ApiModelProperty("业务类型 可选值:JETTISON,REPLACE_SEND,IN_PURCHASE") + @NotNull(message = "业务类型不能为空") + private String businessType; + @ApiModelProperty("下单商户/会员") + @NotBlank(message = "下单商户或购物会员号不能为空") + private String buyVip; + @ApiModelProperty("下单时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime orderTime; + @ApiModelProperty("付款方式 可选值:FIRST_PRODUCT,FIRST_MONEY") + @NotNull(message = "付款方式不可为空") + private String payType; + @ApiModelProperty("预付款时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime perPayTime; + @ApiModelProperty("凭证文件名 同返利活动中附件名称") + private String proofName; + @ApiModelProperty("凭证文件地址 同返利活动中附件地址") + private String proofPath; + @Size(max = 100, message = "买家备注长度不能超过100字") + @ApiModelProperty("买家备注") + private String userRemark; + @Size(max = 100, message = "卖家备注长度不能超过100字") + @ApiModelProperty("卖家备注") + private String salerRemark; + @ApiModelProperty("发货仓库code") + @NotBlank(message = "发货仓库code不能为空") + private String warehouseCode; + @ApiModelProperty("发货仓库name") + @NotBlank(message = "发货仓库name不能为空") + private String warehouseName; + @NotEmpty(message = "订单商品不能为空") + @ApiModelProperty("订单商品") + private List item; + @NotBlank(message = "收货人名称不能为空") + @ApiModelProperty("收货人") + private String receiverName; + @NotBlank(message = "收货人手机号不能为空") + @ApiModelProperty("收货人手机号") + private String receiverPhone; + @NotBlank(message = "收货人地址不能为空") + @ApiModelProperty("收货人地址") + private String receiverAddress; + @ApiModelProperty("收货人城市") + @NotBlank(message = "收货人城市不能为空") + private String receiverCity; + @ApiModelProperty("收货人区县") + @NotBlank(message = "收货人区县不能为空") + private String receiverDistrict; + @ApiModelProperty("收货人省份") + @NotBlank(message = "收货人省份不能为空") + private String receiverProvince; + @ApiModelProperty("发票种类 可选值:NORMAL,VAT") + private String invoiceType; + @ApiModelProperty("发票类型 可选值:ELECTRONIC,PAPER") + private String invoiceCatalogue; + @ApiModelProperty("发票抬头") + private String invoiceTitle; + @ApiModelProperty("发票抬头类型 可选值:PERSONAL,COMPANY") + private String invoiceTitleType; + + @ApiModelProperty("纳税人标识号") + private String ratepayerCode; + @ApiModelProperty("注册地址") + private String registerAddress; + @ApiModelProperty("注册电话") + private String registerPhone; + @ApiModelProperty("开户银行") + private String registerBank; + @ApiModelProperty("银行账号") + private String registerAccount; + @ApiModelProperty("销售总额") + @NotNull(message = "销售总额不能为空") + private BigDecimal totalAmount; + + + @ApiModelProperty("毛利") + @NotNull(message = "毛利不能为空") + private BigDecimal profit; + + @NotNull(message = "是否开票必填") + private Integer needInvoice; + + private String approveCode; + private Integer payState; + private BigDecimal payAmount; + private BigDecimal costAmount; +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderItemCreateReqDTO.java b/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderItemCreateReqDTO.java new file mode 100644 index 0000000..91cd00b --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/pojo/TradeOrderItemCreateReqDTO.java @@ -0,0 +1,56 @@ +package com.zbkj.service.pojo; + + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * @author wyq + */ +@Data +@ApiModel("创建/更新手工订单请求参数") +public class TradeOrderItemCreateReqDTO { + @ApiModelProperty("skuNo") + @NotNull(message = "skuNo不能为空") + private String skuNo; + private String oid; + + private String note; + @ApiModelProperty("品牌 填写中文名称 可选值 非集合,集合") + private String brandType; + @ApiModelProperty("价格说明") + private String priceNote; + private BigDecimal totalPrice; + private BigDecimal payPrice; + private BigDecimal orderPrice; + //返利 + private BigDecimal rebate; + private String activities; + @ApiModelProperty("skuName") + @NotNull(message = "skuName不能为空") + private String skuName; + @ApiModelProperty("销售价格") + @NotNull(message = "销售价格不可为空") + private BigDecimal sellPrice; + @ApiModelProperty("销售数量") + @NotBlank(message = "销售数量不能为空") + private Integer sellQty; + @ApiModelProperty("成本") + private BigDecimal cost; + @ApiModelProperty("毛利") + private BigDecimal profit; + @ApiModelProperty("库存") + private Integer inStock; + @ApiModelProperty("毛利率") + private BigDecimal profitRate; + @ApiModelProperty("市场价") + private String marketPrice; + private String marketPriceStr; + + +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/pojo/WebResponse.java b/crmeb-service/src/main/java/com/zbkj/service/pojo/WebResponse.java new file mode 100644 index 0000000..3132afc --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/pojo/WebResponse.java @@ -0,0 +1,23 @@ +package com.zbkj.service.pojo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * @param + * @author broad + */ +@Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class WebResponse { + +//200正常 + private String status ; + + private String data; + + private String msg ; + + private Boolean success; + +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/pojo/XsSkuInfo.java b/crmeb-service/src/main/java/com/zbkj/service/pojo/XsSkuInfo.java new file mode 100644 index 0000000..c674dd2 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/pojo/XsSkuInfo.java @@ -0,0 +1,40 @@ +package com.zbkj.service.pojo; + +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.experimental.Accessors; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import java.io.Serializable; + +/** + * @author admin2 + */ +@Data +@TableName("m_xsbuy_cn.xs_sku") +@ApiModel(value = "SKU信息对象") +@Accessors(chain = true) +public class XsSkuInfo implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + private Long id; + @ApiModelProperty(value = "SKU编号") + private String skuNo; + @ApiModelProperty(value = "SKU名称") + private String skuName; + @ApiModelProperty(value = "分类名称") + private String categoryName; + @ApiModelProperty(value = "分类编号") + private String categoryCode; + @ApiModelProperty(value = "品牌编号") + private String brandCode; + @ApiModelProperty(value = "品牌名称") + private String brandName; +} + diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/ExpressService.java b/crmeb-service/src/main/java/com/zbkj/service/service/ExpressService.java index 151e437..e6b59cb 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/ExpressService.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/ExpressService.java @@ -31,7 +31,7 @@ public interface ExpressService extends IService { * @return List */ List getList(ExpressSearchRequest request, PageParamRequest pageParamRequest); - + List getByNames(List name); /** * 编辑 */ diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/ExtendService.java b/crmeb-service/src/main/java/com/zbkj/service/service/ExtendService.java new file mode 100644 index 0000000..3e8e63f --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/service/ExtendService.java @@ -0,0 +1,14 @@ +package com.zbkj.service.service; + +import com.zbkj.common.model.extend.MallDelivery; + +import java.util.List; + +/** + * @author wyq + */ +public interface ExtendService { + String createDelivery(MallDelivery mallDelivery); + + void removeProduct(List skuNos); +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/OrderTaskService.java b/crmeb-service/src/main/java/com/zbkj/service/service/OrderTaskService.java index c92f1e1..10189be 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/OrderTaskService.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/OrderTaskService.java @@ -42,4 +42,6 @@ package com.zbkj.service.service; * 订单自动收货 */ void autoTakeDelivery(); + + void autoSync(); } diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/RetryService.java b/crmeb-service/src/main/java/com/zbkj/service/service/RetryService.java new file mode 100644 index 0000000..9635fc8 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/service/RetryService.java @@ -0,0 +1,15 @@ +package com.zbkj.service.service; + +import com.zbkj.common.model.order.StoreOrder; +import com.zbkj.common.model.user.UserAddress; +import com.zbkj.service.pojo.TradeOrderItemCreateReqDTO; + +import java.util.List; + +public interface RetryService { + + public void systemErrNc(String msg); + void createOrder(StoreOrder order, UserAddress userAddress, List detailList); + + +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/StoreOrderService.java b/crmeb-service/src/main/java/com/zbkj/service/service/StoreOrderService.java index fc2a048..fced461 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/StoreOrderService.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/StoreOrderService.java @@ -421,4 +421,6 @@ public interface StoreOrderService extends IService { void expressForOnePassShipmentCancelCallBack(JSONObject jsonObject); Boolean refundRequestPass(RefundPassRequest request); + + String sendNew(StoreOrderSendRequest request); } diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/StoreProductService.java b/crmeb-service/src/main/java/com/zbkj/service/service/StoreProductService.java index 59175df..2b7e0b3 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/StoreProductService.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/StoreProductService.java @@ -9,6 +9,7 @@ import com.zbkj.common.response.StoreProductInfoResponse; import com.zbkj.common.response.StoreProductResponse; import com.zbkj.common.response.StoreProductTabsHeader; import com.zbkj.common.vo.MyRecord; +import com.zbkj.service.pojo.XsSkuInfo; import org.json.JSONException; import java.io.IOException; @@ -239,4 +240,6 @@ public interface StoreProductService extends IService { * @return 商品分类及所有父级分类ID */ List getProductAllCategoryIdByProductIds(List productIdList); + + List findSku(String content, Long pageNum, Long pageSize); } diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/WechatNewService.java b/crmeb-service/src/main/java/com/zbkj/service/service/WechatNewService.java index 829c08b..e097e17 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/WechatNewService.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/WechatNewService.java @@ -1,6 +1,7 @@ package com.zbkj.service.service; import com.alibaba.fastjson.JSONObject; +import com.zbkj.common.model.order.StoreOrder; import com.zbkj.common.request.SaveConfigRequest; import com.zbkj.common.response.WeChatJsSdkConfigResponse; import com.zbkj.common.token.WeChatOauthToken; @@ -142,6 +143,7 @@ public interface WechatNewService { */ WxRefundResponseVo payRefund(WxRefundVo wxRefundVo, String path); + WxRefundResponseVo payRefundQuery(StoreOrder storeOrder); /** * 获取我的公众号模板消息列表 * @return List diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExpressServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExpressServiceImpl.java index 2ce8ad2..fd97027 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExpressServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExpressServiceImpl.java @@ -73,7 +73,13 @@ public class ExpressServiceImpl extends ServiceImpl impleme lambdaQueryWrapper.orderByAsc(Express::getId); return dao.selectList(lambdaQueryWrapper); } + @Override + public List getByNames(List name) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.in(Express::getName, name); + return dao.selectList(lqw); + } /** * 编辑 */ diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExtendServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExtendServiceImpl.java new file mode 100644 index 0000000..ecec529 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/ExtendServiceImpl.java @@ -0,0 +1,94 @@ +package com.zbkj.service.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +import com.zbkj.common.model.extend.MallDelivery; +import com.zbkj.common.model.order.StoreOrder; +import com.zbkj.common.model.product.StoreProduct; +import com.zbkj.common.model.product.StoreProductAttrValue; +import com.zbkj.common.request.StoreOrderSendRequest; +import com.zbkj.service.dao.StoreOrderDao; +import com.zbkj.service.dao.StoreProductAttrValueDao; +import com.zbkj.service.service.ExtendService; +import com.zbkj.service.service.StoreOrderService; +import com.zbkj.service.service.StoreProductService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author wyq + */ +@Service +@Slf4j +public class ExtendServiceImpl implements ExtendService { + + @Resource + private StoreOrderDao storeOrderDao; + @Resource + private StoreProductAttrValueDao storeProductAttrValueDao; + @Resource + private StoreProductService storeProductService; + + @Resource + private StoreOrderService storeOrderService; + @Override + public String createDelivery(MallDelivery mallDelivery) { + StoreOrder order =storeOrderDao.selectOne(new LambdaQueryWrapper().eq(StoreOrder::getOrderId, mallDelivery.getPlatformCode())); + if (order==null){ + if (mallDelivery.getPlatformCode().contains(";" )){ + List list = Arrays.asList(mallDelivery.getPlatformCode().split(";")); + if (CollUtil.isNotEmpty(list)){ + for (String s : list) { + StoreOrder order1 = storeOrderDao.selectOne(new LambdaQueryWrapper().eq(StoreOrder::getOrderId, s)); + if (order1==null){ + throw new RuntimeException("合并发货单订单不存在"); + } + if (order1.getStatus()>0){ + log.info("订单已发货不可再次发货"); + continue; + } + StoreOrderSendRequest request=new StoreOrderSendRequest(); + request.setOrderNo(order1.getOrderId()); + request.setDeliveryType("express"); + request.setExpressList(mallDelivery.getExpressList()); + storeOrderService.sendNew(request); + } + return ""; + } + } + throw new RuntimeException("订单不存在"); + } + if (order.getStatus()>0){ + return "订单已发货不可再次发货"; + } + StoreOrderSendRequest request=new StoreOrderSendRequest(); + request.setOrderNo(order.getOrderId()); + request.setDeliveryType("express"); + request.setExpressList(mallDelivery.getExpressList()); + return storeOrderService.sendNew(request); + + } + + @Override + public void removeProduct(List skuNos) { + List attrValues = storeProductAttrValueDao.selectList(new LambdaQueryWrapper().in(StoreProductAttrValue::getBarCode, skuNos).eq(StoreProductAttrValue::getIsDel,false)); + if (CollUtil.isEmpty(attrValues)){ + return; + } + List productIds = attrValues.stream().map(StoreProductAttrValue::getProductId).distinct().collect(Collectors.toList()); + List list = storeProductService.list(new LambdaQueryWrapper().in(StoreProduct::getId, productIds).eq(StoreProduct::getIsShow, true)); + if (!CollUtil.isEmpty(list)){ + for (StoreProduct storeProduct : list) { + storeProductService.offShelf(storeProduct.getId()); + } + } + + + } +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderTaskServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderTaskServiceImpl.java index f325dbf..04b62e1 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderTaskServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderTaskServiceImpl.java @@ -6,26 +6,41 @@ import cn.hutool.core.date.DateTime; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zbkj.common.constants.Constants; import com.zbkj.common.constants.TaskConstants; import com.zbkj.common.exception.CrmebException; import com.zbkj.common.model.order.StoreOrder; +import com.zbkj.common.model.order.StoreOrderInfo; import com.zbkj.common.model.order.StoreOrderStatus; +import com.zbkj.common.model.product.StoreProductAttrValue; import com.zbkj.common.model.product.StoreProductReply; import com.zbkj.common.model.user.User; +import com.zbkj.common.model.user.UserAddress; import com.zbkj.common.model.wechat.video.PayComponentOrder; import com.zbkj.common.utils.CrmebDateUtil; import com.zbkj.common.utils.RedisUtil; import com.zbkj.common.vo.ShopOrderCommonVo; import com.zbkj.common.vo.StoreOrderInfoOldVo; +import com.zbkj.service.dao.StoreOrderDao; +import com.zbkj.service.dao.StoreProductAttrValueDao; +import com.zbkj.service.dao.UserAddressDao; +import com.zbkj.service.pojo.TradeOrderItemCreateReqDTO; import com.zbkj.service.service.*; +import com.zbkj.service.util.RedisLockUtil; +import org.apache.commons.lang3.StringUtils; 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 javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * StoreOrderServiceImpl 接口实现 @@ -55,10 +70,12 @@ public class OrderTaskServiceImpl implements OrderTaskService { @Autowired private StoreOrderStatusService storeOrderStatusService; - + @Autowired + private RedisLockUtil redisLock; @Autowired private StoreOrderInfoService storeOrderInfoService; - + @Autowired + private StoreProductAttrValueDao storeProductAttrValueDao; @Autowired private UserService userService; @@ -67,10 +84,14 @@ public class OrderTaskServiceImpl implements OrderTaskService { @Autowired private TransactionTemplate transactionTemplate; - + @Resource + private RetryService retryService; @Autowired private OrderPayService orderPayService; - + @Autowired + private StoreOrderDao storeOrderDao; + @Resource + private UserAddressDao userAddressDao; @Autowired private PayComponentOrderService componentOrderService; @@ -413,4 +434,118 @@ public class OrderTaskServiceImpl implements OrderTaskService { }); } + + + @Override + public void autoSync() { +// // 查询未同步的订单; +// List list = storeOrderDao.selectList(new LambdaQueryWrapper() +// .eq(StoreOrder::getIsSystemDel, 0) +// .eq(StoreOrder::getPaid, 1) +// .eq(StoreOrder::getIsDel, 0) +// .eq(StoreOrder::getHasSync, 0) +// .eq(StoreOrder::getRefundStatus, 0)); +// if (CollUtil.isEmpty(list)){ +// return; +// } +// +// for (StoreOrder order : list) { +// boolean lock = +// redisLock.lock(Constants.ORDER_LOCK + order.getOrderId(),5); +// if (!lock) { +// logger.error("订单未获取到锁orderNo = " + order.getOrderId()); +// continue; +// } +// try { +// QueryWrapper queryWrapper=new QueryWrapper<>(); +// queryWrapper.eq("platform_code",order.getOrderId()); +// MdbPayResultPO mdbPayResultPO=mdbPayResultDao.selectOne(queryWrapper); +// List skuList = storeOrderInfoService.getListByOrderNo(order.getOrderId()); +// List skuIds = skuList.stream().map(StoreOrderInfo::getAttrValueId).collect(Collectors.toList()); +// List attrValues = storeProductAttrValueDao.selectList(new LambdaQueryWrapper().in(StoreProductAttrValue::getId, skuIds).eq(StoreProductAttrValue::getIsDel,0)); +// List detailList = new ArrayList<>(); +// BigDecimal hbdkje=BigDecimal.ZERO; +// BigDecimal hdyhje=BigDecimal.ZERO; +// BigDecimal jfdkje=BigDecimal.ZERO; +// if(StringUtils.isNotEmpty(mdbPayResultPO.getRpktRducAmt())){ +// try { +// hbdkje=BigDecimal.valueOf(Double.parseDouble(mdbPayResultPO.getRpktRducAmt())); +// }catch (Exception e){ +// logger.info("红包抵扣金额不是数字格式"); +// } +// } +// if(StringUtils.isNotEmpty(mdbPayResultPO.getActDsctAmt())){ +// try { +// hdyhje=BigDecimal.valueOf(Double.parseDouble(mdbPayResultPO.getActDsctAmt())); +// }catch (Exception e){ +// logger.info("活动优惠金额不是数字格式"); +// } +// } +// if(StringUtils.isNotEmpty(mdbPayResultPO.getPntDsctAmt())){ +// try { +// jfdkje=BigDecimal.valueOf(Double.parseDouble(mdbPayResultPO.getPntDsctAmt())); +// }catch (Exception e){ +// logger.info("积分抵扣金额不是数字格式"); +// } +// } +// +// for (StoreProductAttrValue attrValue : attrValues) { +// TradeOrderItemCreateReqDTO item = new TradeOrderItemCreateReqDTO(); +// item.setSkuNo(attrValue.getBarCode()); +// item.setSkuName(skuList.get(0).getProductName()); +// StoreOrderInfo storeOrderInfo = skuList.stream().filter(o -> o.getAttrValueId().equals(attrValue.getId())).collect(Collectors.toList()).get(0); +// item.setSellQty(storeOrderInfo.getPayNum()); +// item.setSellPrice(attrValue.getPrice()); +// String productName = trim(skuList.get(0).getProductName()); +// String sku = trim(skuList.get(0).getSku()); +// String note = productName+sku; +// if (note.length()>40){ +// productName= productName.length()>20?productName.substring(0,20):productName; +// note= productName+" "+sku; +// } +// item.setNote(note); +// item.setTotalPrice(order.getPayPrice()); +// item.setPayPrice(order.getPayPrice().subtract(hdyhje).subtract(hbdkje).subtract(jfdkje)); +// item.setOrderPrice(order.getPayPrice()); +// item.setOid(order.getOrderId()+"_1"); +// //价格随意全渠道会自动更新 +// item.setCost(BigDecimal.ZERO); +// item.setBrandType(" "); +// item.setRebate(BigDecimal.ZERO); +// item.setPriceNote(" "); +// detailList.add(item); +// } +// UserAddress userAddress = userAddressDao.selectDistinct(order); +// retryService.createOrder(order, userAddress, detailList); +// order.setHasSync(1); +// storeOrderDao.updateById(order); +// }catch (Exception e){ +// logger.error("订单同步失败:订单号:{},异常信息={}", order.getOrderId(), e); +// retryService.systemErrNc("订单同步失败:订单号:"+order.getOrderId()); +// }finally { +// redisLock.unLock(Constants.ORDER_LOCK + order.getOrderId()); +// } +// } + } + /** + * 提取数字字母汉字 + * @param str + * @return + */ + public static String trim (String str) { + StringBuilder result = new StringBuilder(); + + for (char ch : str.toCharArray()) { + // Check if the character is a digit, letter or Chinese character + if (Character.isDigit(ch) || Character.isLetter(ch) || isChineseCharacter(ch)) { + result.append(ch); + } + } + + return result.toString(); + } + private static boolean isChineseCharacter(char ch) { + // Unicode range for CJK Unified Ideographs (common Chinese characters) + return ch >= '\u4e00' && ch <= '\u9fff'; + } } diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/RetryServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/RetryServiceImpl.java new file mode 100644 index 0000000..5432f16 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/RetryServiceImpl.java @@ -0,0 +1,154 @@ +package com.zbkj.service.service.impl; + +import com.alibaba.fastjson.JSON; +import com.zbkj.common.model.order.StoreOrder; +import com.zbkj.common.model.user.UserAddress; +import com.zbkj.common.utils.RestTemplateUtil; +import com.zbkj.service.dao.StoreOrderInfoDao; +import com.zbkj.service.dao.StoreProductAttrValueDao; +import com.zbkj.service.dao.StoreProductDao; +import com.zbkj.service.dao.UserDao; +import com.zbkj.service.pojo.TradeOrderItemCreateReqDTO; +import com.zbkj.service.pojo.WebResponse; +import com.zbkj.service.service.RetryService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author admin2 + */ +@Service +@Slf4j +public class RetryServiceImpl implements RetryService { + + @Resource + private RestTemplateUtil restTemplateUtil; + @Resource + private StoreOrderInfoDao storeOrderInfoDao; + @Value("${ruoyi.createOrderUrl}") + private String createOrderUrl; + @Value("${ruoyi.applyInvoicingUrl}") + private String applyInvoicingUrl; + @Value("${ruoyi.triggerDeliveryCheckUrl}") + private String triggerDeliveryCheckUrl; + @Value("${ruoyi.updateOrderRefundStatusUrl}") + private String updateOrderRefundStatusUrl; + + @Value("${systemErrRobot}") + private String systemErrRobot; + @Resource + private UserDao userDao; + @Resource + private StoreProductAttrValueDao storeProductAttrValueDao; + + @Resource + private StoreProductDao storeProductDao; + + @Override + public void systemErrNc(String msg) { + msg = StringUtils.isBlank(msg) ? msg = "空指针" : msg; + msg = msg.length() > 400 ? msg.substring(0, 400) : msg; + msg = "时间戳:" + System.currentTimeMillis() + "【微信店铺系统】异常:" + msg; + Map param = new HashMap<>(); + Map content = new HashMap<>(); + content.put("text", msg); + param.put("content", content); + param.put("msg_type", "text"); + try { + log.error("发送飞书消息入参:{}", msg); + restTemplateUtil.postMapData(systemErrRobot, param, new HashMap<>()); + } catch (Exception e) { + log.error("发送飞书消息失败", e); + } + } + + + + @Override + public void createOrder(StoreOrder order, UserAddress userAddress, List detailList) { + + Map params = new HashMap<>(); + + BigDecimal hbdkje=BigDecimal.ZERO; + BigDecimal hdyhje=BigDecimal.ZERO; + BigDecimal jfdkje=BigDecimal.ZERO; + + // 填充所有属性名 + params.put("orderId", ""); + params.put("platformCode", order.getOrderId()); + params.put("erpCode", System.currentTimeMillis()); + + params.put("channelCode", "COMM1"); + params.put("channelName", "交通银行"); + params.put("deptCode", ""); + params.put("deptName", ""); + params.put("businessMan", "16638693690"); + params.put("businessManName", "王玉祺"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + params.put("orderTime", sdf.format(order.getPayTime())); + params.put("buyVip", "交通银行用户"); + params.put("payType", "FIRST_MONEY"); + params.put("perPayTime", ""); + params.put("proofName", ""); + params.put("proofPath", ""); + params.put("userRemark", order.getMark()); + params.put("salerRemark", ""); + params.put("warehouseCode", "XS-SH-07"); + params.put("warehouseName", "湘商-湘商-外采主仓"); + params.put("item", detailList); + params.put("receiverName", order.getRealName()); + params.put("receiverPhone", order.getUserPhone()); + params.put("receiverAddress", order.getUserAddress()); + params.put("receiverCity", userAddress.getCity()); + params.put("receiverDistrict", userAddress.getDistrict()); + params.put("receiverProvince", userAddress.getProvince()); + //发票种类 可选值:NORMAL,VAT + params.put("invoiceType", "NORMAL"); + //电子发票 + params.put("invoiceCatalogue", "ELECTRONIC"); + params.put("invoiceTitle", ""); + + //个人发票 + params.put("invoiceTitleType", "PERSONAL"); + params.put("ratepayerCode", ""); + params.put("registerAddress", ""); + params.put("registerPhone", ""); + params.put("registerBank", ""); + params.put("registerAccount", ""); + params.put("totalAmount", order.getPayPrice()); + params.put("profit", ""); + params.put("needInvoice", ""); + params.put("approveCode", ""); + //已付款 + params.put("payState", "1"); + params.put("payAmount", order.getPayPrice().subtract(hdyhje).subtract(hbdkje).subtract(jfdkje)); + params.put("costAmount", "0"); + params.put("installment", "0"); + params.put("payInfo", ""); + params.put("pntDsctAmt", jfdkje); + params.put("platformCouponPrice", hbdkje.add(hdyhje)); + + + params.put("commission", 0); + params.put("totalPrice", order.getPayPrice().subtract(BigDecimal.ZERO)); + params.put("installment", 0); + params.put("payInfo", ""); + log.info("订单同步参数:{}", JSON.toJSONString(params)); + String result = restTemplateUtil.postMapData(createOrderUrl, params, new HashMap<>()); + log.info("订单同步返回:{}", JSON.toJSONString(result)); + WebResponse webResponse = JSON.parseObject(result, WebResponse.class); + if (!"200".equals(webResponse.getStatus())) { + log.info("订单失败"); + throw new RuntimeException(String.format("订单同步失败订单号%s", order.getOrderId())); + } + } +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderServiceImpl.java index 138fd05..bbd241e 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderServiceImpl.java @@ -18,8 +18,11 @@ import com.zbkj.common.constants.*; import com.zbkj.common.exception.CrmebException; import com.zbkj.common.model.combination.StorePink; import com.zbkj.common.model.express.Express; +import com.zbkj.common.model.extend.MallExpressInfoDto; import com.zbkj.common.model.order.StoreOrder; import com.zbkj.common.model.order.StoreOrderInfo; +import com.zbkj.common.model.parcel.ParcelPO; +import com.zbkj.common.model.product.StoreProductAttrValue; import com.zbkj.common.model.sms.SmsTemplate; import com.zbkj.common.model.system.SystemAdmin; import com.zbkj.common.model.system.SystemNotification; @@ -38,7 +41,9 @@ import com.zbkj.common.utils.CrmebUtil; import com.zbkj.common.utils.RedisUtil; import com.zbkj.common.utils.ValidateFormUtil; import com.zbkj.common.vo.*; +import com.zbkj.service.dao.ParcelDao; import com.zbkj.service.dao.StoreOrderDao; +import com.zbkj.service.dao.StoreProductAttrValueDao; import com.zbkj.service.delete.OrderUtils; import com.zbkj.service.service.*; import org.apache.commons.lang3.StringUtils; @@ -52,6 +57,7 @@ import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -76,7 +82,10 @@ public class StoreOrderServiceImpl extends ServiceImpl 0) throw new CrmebException("订单已发货请勿重复操作!"); + request.setId(storeOrder.getId()); + if ("express".equals(request.getDeliveryType())) {// 发货 + mianDanResult = expressMult(request, storeOrder); + } else { + throw new CrmebException("类型错误"); + } + return mianDanResult; + } + private void mappingExpressCode(StoreOrderSendRequest request, StoreOrder storeOrder) { + List expressNames = request.getExpressList().stream().map(MallExpressInfoDto::getExpressName).collect(Collectors.toList()); + Map expressMap = expressService.getByNames(expressNames).stream().collect(Collectors.toMap(Express::getName, Function.identity(), (v1, v2) -> v1)); + for (MallExpressInfoDto item : request.getExpressList()) { + Express express = expressMap.get(item.getExpressName()); + if (express == null) { + throw new RuntimeException(String.format("mall端:订单号:%s 物流公司找不到无法发货 :%s", storeOrder.getOrderId(), item.getExpressName())); + } + item.setExpressCode(express.getCode()); + } + } + /** + * 多包裹发货 + * + * @param request StoreOrderSendRequest 发货参数 + * @param storeOrder StoreOrder 订单信息 + */ + private String expressMult(StoreOrderSendRequest request, StoreOrder storeOrder) { + StoreOrderInfo storeOrderInfo = storeOrderInfoService.getListByOrderNo(storeOrder.getOrderId()).get(0); + String mianDianResult = ""; + //映射快递公司编码 + mappingExpressCode(request, storeOrder); + String expressName = request.getExpressList().stream().map(MallExpressInfoDto::getExpressName).collect(Collectors.joining(",")); + String expressNo = request.getExpressList().stream().map(MallExpressInfoDto::getExpressNo).collect(Collectors.joining(",")); + storeOrder.setStatus(1); + storeOrder.setDeliveryType("express"); + String message = Constants.ORDER_LOG_MESSAGE_EXPRESS.replace("{deliveryName}", expressName).replace("{deliveryCode}", expressNo); + + Boolean execute = transactionTemplate.execute(i -> { + updateById(storeOrder); + List expressList = request.getExpressList(); + //只有一个包裹时包裹中的商品直接取订单的商品,多个包裹时erp上的物流 + if (expressList.size() == 1) { + MallExpressInfoDto item = expressList.get(0); + ParcelPO parcelPO = new ParcelPO(); + parcelPO.setSkuName(storeOrderInfo.getProductName()); + StoreProductAttrValue storeProductAttrValue = storeProductAttrValueDao.selectOne(new LambdaQueryWrapper().eq(StoreProductAttrValue::getId, storeOrderInfo.getAttrValueId())); + parcelPO.setSkuNo(storeProductAttrValue.getBarCode()); + parcelPO.setPlatformCode(storeOrder.getOrderId()); + parcelPO.setExpressNo(item.getExpressNo()); + parcelPO.setExpressName(item.getExpressName()); + parcelPO.setExpressCode(item.getExpressCode()); + parcelPO.setImage(storeOrderInfo.getImage()); + parcelPO.setNum(storeOrder.getTotalNum()); + parcelDao.insert(parcelPO); + } else { + request.getExpressList().forEach(item -> { + ParcelPO parcelPO = new ParcelPO(); + parcelPO.setSkuName(item.getSkuName()); + parcelPO.setSkuNo(item.getSkuNo()); + parcelPO.setNum(item.getNum()); + parcelPO.setImage(storeOrderInfo.getImage()); + parcelPO.setPlatformCode(storeOrder.getOrderId()); + parcelPO.setExpressNo(item.getExpressNo()); + parcelPO.setExpressName(item.getExpressName()); + parcelPO.setExpressCode(item.getExpressCode()); + parcelDao.insert(parcelPO); + }); + } + //订单记录增加 + storeOrderStatusService.createLog(request.getId(), Constants.ORDER_LOG_EXPRESS, message); + return Boolean.TRUE; + }); + + if (!execute) throw new RuntimeException("快递发货失败!"); + + return mianDianResult; + } ///////////////////////////////////////////////////////////////////////////////////////////////////// 以下为自定义方法 /** diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderTaskServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderTaskServiceImpl.java index 47ee3cd..8a4b1c1 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderTaskServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreOrderTaskServiceImpl.java @@ -12,6 +12,7 @@ import com.zbkj.common.model.product.StoreProduct; import com.zbkj.common.model.sms.SmsTemplate; import com.zbkj.common.model.system.SystemNotification; import com.zbkj.common.model.user.*; +import com.zbkj.common.request.StoreOrderRefundRequest; import com.zbkj.common.utils.CrmebDateUtil; import com.zbkj.common.model.bargain.StoreBargain; import com.zbkj.common.model.combination.StoreCombination; @@ -26,6 +27,7 @@ import com.zbkj.common.model.order.StoreOrderInfo; import com.zbkj.common.model.product.StoreProductAttrValue; import com.zbkj.common.model.system.SystemAdmin; import com.zbkj.common.vo.ShopOrderPayVo; +import com.zbkj.common.vo.WxRefundResponseVo; import com.zbkj.service.delete.OrderUtils; import com.zbkj.service.service.*; import org.slf4j.Logger; @@ -87,7 +89,8 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { @Autowired private UserBillService userBillService; - + @Autowired + private WechatNewService wechatNewService; @Autowired private TransactionTemplate transactionTemplate; @@ -111,7 +114,8 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { @Autowired private StorePinkService storePinkService; - + @Autowired + private StoreOrderRefundService storeOrderRefundService; @Autowired private UserIntegralRecordService userIntegralRecordService; @@ -323,7 +327,10 @@ public class StoreOrderTaskServiceImpl implements StoreOrderTaskService { logger.error("订单退款处理,对应的用户不存在,storeOrder===>" + storeOrder); return Boolean.FALSE; } - + // WxRefundResponseVo wxRefundResponseVo = wechatNewService.payRefundQuery(storeOrder); + StoreOrderRefundRequest request = new StoreOrderRefundRequest(); + request.setAmount(storeOrder.getRefundPrice()); + storeOrderRefundService.refund(request, storeOrder); // 回滚经验 UserExperienceRecord userExperienceRecord = userExperienceRecordService.getByOrderNoAndUid(storeOrder.getOrderId(), storeOrder.getUid()); user.setExperience(user.getExperience() - userExperienceRecord.getExperience()); diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreProductServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreProductServiceImpl.java index 2dc30f4..7ffe676 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreProductServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/StoreProductServiceImpl.java @@ -30,7 +30,9 @@ import com.zbkj.common.utils.CrmebDateUtil; import com.zbkj.common.utils.RedisUtil; import com.zbkj.common.vo.MyRecord; import com.zbkj.service.dao.StoreProductDao; +import com.zbkj.service.dao.XsbuyDao; import com.zbkj.service.delete.ProductUtils; +import com.zbkj.service.pojo.XsSkuInfo; import com.zbkj.service.service.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -68,7 +70,8 @@ public class StoreProductServiceImpl extends ServiceImpl findSku(String content, Long pageNum, Long pageSize) { + content = content.trim(); + if (pageNum == null) { + pageNum = 1L; + } + if (pageSize == null || pageSize == 0) { + pageSize = 50L; + } + if (StrUtil.isBlank(content)) { + return new ArrayList<>(); + } + List list = xsbuyDao.selectListNew(content, (pageNum - 1) * pageSize, pageSize); + + return list; + + } ///////////////////////////////////////////自定义方法 diff --git a/crmeb-service/src/main/java/com/zbkj/service/service/impl/WechatNewServiceImpl.java b/crmeb-service/src/main/java/com/zbkj/service/service/impl/WechatNewServiceImpl.java index 62e7ac0..9fbb55c 100644 --- a/crmeb-service/src/main/java/com/zbkj/service/service/impl/WechatNewServiceImpl.java +++ b/crmeb-service/src/main/java/com/zbkj/service/service/impl/WechatNewServiceImpl.java @@ -9,18 +9,17 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.zbkj.common.config.CrmebConfig; +import com.zbkj.common.constants.Constants; import com.zbkj.common.constants.PayConstants; import com.zbkj.common.constants.WeChatConstants; import com.zbkj.common.exception.CrmebException; +import com.zbkj.common.model.order.StoreOrder; import com.zbkj.common.model.wechat.WechatExceptions; import com.zbkj.common.model.wechat.WechatPayInfo; import com.zbkj.common.request.SaveConfigRequest; import com.zbkj.common.response.WeChatJsSdkConfigResponse; import com.zbkj.common.token.WeChatOauthToken; -import com.zbkj.common.utils.CrmebUtil; -import com.zbkj.common.utils.RedisUtil; -import com.zbkj.common.utils.RestTemplateUtil; -import com.zbkj.common.utils.XmlUtil; +import com.zbkj.common.utils.*; import com.zbkj.common.vo.*; import com.zbkj.service.service.SystemConfigService; import com.zbkj.service.service.WechatExceptionsService; @@ -35,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; import java.net.URLDecoder; import java.util.HashMap; import java.util.List; @@ -639,6 +639,47 @@ public class WechatNewServiceImpl implements WechatNewService { return responseVo; } + @Override + public WxRefundResponseVo payRefundQuery(StoreOrder storeOrder) { + String appId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID); + String mchId = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID); + String signKey = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY); + WxRefundVo wxRefundVo = new WxRefundVo(); + wxRefundVo.setAppid(appId); + wxRefundVo.setMch_id(mchId); + wxRefundVo.setNonce_str(WxPayUtil.getNonceStr()); + wxRefundVo.setOut_refund_no(storeOrder.getOrderId()); + String sign = WxPayUtil.getSign(wxRefundVo, signKey); + wxRefundVo.setSign(sign); + String xmlStr = XmlUtil.objectToXml(wxRefundVo); + String url = WeChatConstants.PAY_API_URL + WeChatConstants.PAY_REFUND_API_URI_WECHAT_QUERY; + HashMap map = CollUtil.newHashMap(); + String xml = ""; + try { + xml = restTemplateUtil.postXml(url, xmlStr); + map = XmlUtil.xmlToMap(xml); + } catch (Exception e) { + e.printStackTrace(); + throw new CrmebException("xmlToMap错误,xml = " + xml); + } + if (null == map) { + throw new CrmebException("微信无信息返回,微信申请退款失败!"); + } + + WxRefundResponseVo responseVo = CrmebUtil.mapToObj(map, WxRefundResponseVo.class); + if (responseVo.getReturnCode().toUpperCase().equals("FAIL")) { + wxPayExceptionDispose(map, "微信查询退款异常1"); + throw new CrmebException("微信申请退款失败1!" + responseVo.getReturnMsg()); + } + + if (responseVo.getResultCode().toUpperCase().equals("FAIL")) { + wxPayExceptionDispose(map, "微信查询退款业务异常"); + throw new CrmebException("微信申请退款失败2!" + responseVo.getErrCodeDes()); + } + System.out.println("================微信申请退款结束========================="); + return responseVo; + } + /** * 获取我的公众号模板消息列表 * @return List diff --git a/crmeb-service/src/main/java/com/zbkj/service/util/DateUtils.java b/crmeb-service/src/main/java/com/zbkj/service/util/DateUtils.java new file mode 100644 index 0000000..ed66fbc --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/util/DateUtils.java @@ -0,0 +1,977 @@ +package com.zbkj.service.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 时间工具类 + * + * @author shuai.fan + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils { + public static final String YYYY = "yyyy"; + + public static final String YYYY_MM = "yyyy-MM"; + + public static final String YYYY_MM_DD = "yyyy-MM-dd"; + + public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", + "yyyy.MM.dd HH:mm", "yyyy.MM" }; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) { + try { + return new SimpleDateFormat(format).parse(ts); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) { + if (str == null) { + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } catch (ParseException e) { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算两个时间差 + */ + public static String getDatePoor(Date endDate, Date nowDate) { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 把日期字符串格式化成日期类型 + * + * @param dateStr + * @return + */ + public static Date convert2Date(String dateStr) { + return convert2Date(dateStr, PatternUtils.getTimeFomart(dateStr)); + } + + /** + * 把日期字符串格式化成日期类型 + * + * @param dateStr + * @param format + * @return + */ + public static Date convert2Date(String dateStr, String format) { + SimpleDateFormat simple = new SimpleDateFormat(format); + try { + simple.setLenient(false); + return simple.parse(dateStr); + } catch (Exception e) { + return null; + } + } + + /** + * 把日期类型格式化成字符串 + * + * @param date + * @return + */ + public static String convert2String(Date date) { + return convert2String(date, YYYY_MM_DD_HH_MM_SS); + } + + /** + * 把日期类型格式化成字符串 + * + * @param date + * @param format + * @return + */ + public static String convert2String(Date date, String format) { + SimpleDateFormat formater = new SimpleDateFormat(format); + try { + return formater.format(date); + } catch (Exception e) { + return null; + } + } + + /** + * + * 获取一个时间(当天)的开始时间 + * + * @param date + * @return + */ + public static Date getDateBegin(Date date) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, 0); + todayEnd.set(Calendar.MINUTE, 0); + todayEnd.set(Calendar.SECOND, 0); + todayEnd.set(Calendar.MILLISECOND, 0); + return todayEnd.getTime(); + } + + /** + * + * 获取一个时间(当天)的结束时间 + * + * @param date + * @return + */ + public static Date getDateEnd(Date date) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, 23); + todayEnd.set(Calendar.MINUTE, 59); + todayEnd.set(Calendar.SECOND, 59); + todayEnd.set(Calendar.MILLISECOND, 999); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 转化为具体消耗时间
+	 * 
+ * + * @param mss + * @return + */ + public static String convert2times(Long mss) { + if (null == mss) + return "-"; + StringBuffer s = new StringBuffer(); + + long days = mss / (1000 * 60 * 60 * 24); + long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60); + long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60); + long seconds = (mss % (1000 * 60)) / 1000; + if (days > 0) + s.append(days + "天"); + if (hours > 0) + s.append(hours + "小时"); + if (minutes > 0) + s.append(minutes + "分钟"); + if (seconds > 0) + s.append(seconds + "秒"); + + return s.toString(); + } + + /** + * 获取 2 个时间的自然年历的时间间隔 + * + * @param nextDate 后面的时间,需要大于 previousDate + * @param previousDate 前面的时间 + * @return [年, 月, 日, 小时, 分钟, 秒]的数组 + */ + public static String getTimeSpace(Date beginTime, Date endTime) { + List list = getTimeSpaceForList(beginTime, endTime); + + StringBuffer s = new StringBuffer(); + int year = list.get(0); + int month = list.get(1); + int day = list.get(2); + int hour = list.get(3); + int min = list.get(4); + int second = list.get(5); + + if (year > 0) { + s.append(year + "年"); + } + if (month > 0) { + s.append(month + "月"); + } + if (day > 0) { + s.append(day + "天"); + } + if (hour > 0) { + s.append(hour + "小时"); + } + if (min > 0) { + s.append(min + "分钟"); + } + if (second > 0) { + s.append(second + "秒"); + } + return s.toString(); + } + + public static String getTimeSpaceDayHour(Date beginTime, Date endTime) { + List list = getTimeSpaceForList(beginTime, endTime); + + StringBuffer s = new StringBuffer(); + int year = list.get(0); + int month = list.get(1); + int day = list.get(2); + int hour = list.get(3); + + if (year > 0) { + s.append(year + "年"); + } + if (month > 0) { + s.append(month + "个月"); + } + if (day > 0) { + s.append(day + "天"); + } + if (hour > 0) { + s.append(hour + "小时"); + } + return s.toString(); + } + + public static List getTimeSpaceForList(Date beginTime, Date endTime) { + Calendar bigger = Calendar.getInstance(); + bigger.setTime(beginTime.after(endTime)?beginTime:endTime); + Calendar smaller = Calendar.getInstance(); + smaller.setTime(beginTime.after(endTime)?endTime:beginTime); + + int year = bigger.get(Calendar.YEAR) - smaller.get(Calendar.YEAR); + int month = bigger.get(Calendar.MONTH) - smaller.get(Calendar.MONTH); + int day = bigger.get(Calendar.DAY_OF_MONTH) - smaller.get(Calendar.DAY_OF_MONTH); + int hour = bigger.get(Calendar.HOUR_OF_DAY) - smaller.get(Calendar.HOUR_OF_DAY);// 24小时制 + int min = bigger.get(Calendar.MINUTE) - smaller.get(Calendar.MINUTE); + int second = bigger.get(Calendar.SECOND) - smaller.get(Calendar.SECOND); + + boolean hasBorrowDay = false;// "时"是否向"天"借过一位 + + if (second < 0) { + second += 60; + min--; + } + + if (min < 0) { + min += 60; + hour--; + } + + if (hour < 0) { + hour += 24; + day--; + hasBorrowDay = true; + } + + if (day < 0) { + // 计算截止日期的上一个月有多少天,补上去 + Calendar tempDate = (Calendar) bigger.clone(); + tempDate.add(Calendar.MONTH, -1);// 获取截止日期的上一个月 + day += tempDate.getActualMaximum(Calendar.DAY_OF_MONTH); + + // nextDate是月底最后一天,且day=这个月的天数,即是刚好一整个月,比如20160131~20160229,day=29,实则为1个月 + if (!hasBorrowDay && bigger.get(Calendar.DAY_OF_MONTH) == bigger.getActualMaximum(Calendar.DAY_OF_MONTH)// 日期为月底最后一天 + && day >= bigger.getActualMaximum(Calendar.DAY_OF_MONTH)) {// day刚好是nextDate一个月的天数,或大于nextDate月的天数(比如2月可能只有28天) + day = 0;// 因为这样判断是相当于刚好是整月了,那么不用向 month 借位,只需将 day 置 0 + } else {// 向month借一位 + month--; + } + } + + if (month < 0) { + month += 12; + year--; + } + return Arrays.asList(new Integer[] {year,month,day,hour,min,second}); + } + + + /** + * + *
+	 * 获取某时间当天的最初时刻
+	 * 
+ * + * @param now + * @return + */ + public static Date getTimeBegin(Date date) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, 0); + todayEnd.set(Calendar.MINUTE, 0); + todayEnd.set(Calendar.SECOND, 0); + todayEnd.set(Calendar.MILLISECOND, 0); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 获取当天的最初时刻
+	 * 
+ * + * @param now + * @return + */ + public static Date getTodayBeginTime() { + return getTimeBegin(new Date()); + } + + /** + * + *
+	 * 获取某时间当天的最后时刻
+	 * 
+ * + * @param now + * @return + */ + public static Date getTimeEnd(Date date) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, 23); + todayEnd.set(Calendar.MINUTE, 59); + todayEnd.set(Calendar.SECOND, 59); + todayEnd.set(Calendar.MILLISECOND, 999); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 获取当天的 日信息
+	 * 
+ * + * @return + */ + public static Integer getNowDay() { + return getDay(new Date()); + } + + /** + * + *
+	 * 获取指定日期的 日信息
+	 * 
+ * + * @param now + * @return + */ + public static Integer getDay(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.DATE); + } + + public static Integer getWeek(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.WEEK_OF_YEAR); + } + + /** + * + *
+	 * 获取指定时间的 年信息
+	 * 
+ * + * @param now + * @return + */ + public static Integer getYear(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.YEAR); + } + + /** + * + *
+	 * 获取指定时间的月份
+	 * 
+ * + * @param now + * @return + */ + public static Integer getMonth(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.MONTH); + } + + /** + * + *
+	 * 获取指定时间的 小时信息
+	 * 
+ * + * @param now + * @return + */ + public static Integer getHour(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.HOUR_OF_DAY); + } + + public static Integer getMinute(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.MINUTE); + } + + public static Integer getSecond(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + return cal.get(Calendar.SECOND); + } + + /** + * + *
+	 * 增加指定秒数
+	 * 
+ * + * @param date + * @param second + * @return + */ + public static Date addSecond(Date date, Integer second) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.SECOND, todayEnd.get(Calendar.SECOND) + second); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定分钟
+	 * 
+ * + * @param date + * @param minute + * @return + */ + public static Date addMinute(Date date, Integer minute) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.MINUTE, todayEnd.get(Calendar.MINUTE) + minute); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定小时数
+	 * 
+ * + * @param date + * @param hour + * @return + */ + public static Date addHour(Date date, Integer hour) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, todayEnd.get(Calendar.HOUR_OF_DAY) + hour); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定天数
+	 * 
+ * + * @param date + * @param afterDay + * @return + */ + public static Date addDay(Date date, Integer afterDay) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.DAY_OF_YEAR, todayEnd.get(Calendar.DAY_OF_YEAR) + afterDay); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定月数
+	 * 
+ * + * @param date + * @param afterDay + * @return + */ + public static Date addWeek(Date date, Integer afterWeek) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.WEEK_OF_YEAR, todayEnd.get(Calendar.WEEK_OF_YEAR) + afterWeek); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定月数
+	 * 
+ * + * @param date + * @param afterMonth + * @return + */ + public static Date addMonth(Date date, Integer afterMonth) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.MONTH, todayEnd.get(Calendar.MONTH) + afterMonth); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 增加指定天数
+	 * 
+ * + * @param date + * @param afterDay + * @return + */ + public static Date addYear(Date date, Integer afterYear) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.YEAR, todayEnd.get(Calendar.YEAR) + afterYear); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 减少指定秒
+	 * 
+ * + * @param date + * @param second + * @return + */ + public static Date cutSecond(Date date, Integer second) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.SECOND, todayEnd.get(Calendar.SECOND) - second); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 减少指定分钟数
+	 * 
+ * + * @param date + * @param minute + * @return + */ + public static Date cutMinute(Date date, Integer minute) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.MINUTE, todayEnd.get(Calendar.MINUTE) - minute); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 减少指定小时数
+	 * 
+ * + * @param date + * @param hour + * @return + */ + public static Date cutHour(Date date, Integer hour) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.HOUR_OF_DAY, todayEnd.get(Calendar.HOUR_OF_DAY) - hour); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 减少指定天数
+	 * 
+ * + * @param date + * @param beforeDay + * @return + */ + public static Date cutDay(Date date, Integer beforeDay) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.DAY_OF_YEAR, todayEnd.get(Calendar.DAY_OF_YEAR) - beforeDay); + return todayEnd.getTime(); + } + + public static Date cutMonth(Date date, Integer beforeMonth) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.MONTH, todayEnd.get(Calendar.MONTH) - beforeMonth); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 减少指定年数
+	 * 
+ * + * @param date + * @param beforeYear + * @return + */ + public static Date cutYear(Date date, Integer beforeYear) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.YEAR, todayEnd.get(Calendar.YEAR) - beforeYear); + return todayEnd.getTime(); + } + + /** + * + *
+	 * 获取两个时间相隔天数
+	 * 
+ * + * @param other + * @param now + * @return + */ + public static Integer getDifferenceDays(Date other, Date now) { + if (null == other || null == now) + return null; + + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(other); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(now); + Double between_days = (double) ((cal1.getTimeInMillis() - cal2.getTimeInMillis()) / (1000D * 3600D * 24D)); + return (int) Math.abs(Math.ceil(between_days)); + } + + /** + * + *
+	 * 获取两个时间相隔天数
+	 * 
+ * + * @param other + * @param now + * @return + */ + public static Integer getDifferenceMonths(Date other, Date now) { + int result = 0; + Calendar c1 = Calendar.getInstance(); + Calendar c2 = Calendar.getInstance(); + + c1.setTime(other); + c2.setTime(now); + + result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH); + + return result; + } + + /** + * + *
+	 * 获取两个时间相隔的秒数
+	 * 
+ * + * @param other + * @param now + * @return + */ + public static Integer getDifferenceSecond(Date startTime, Date endTime) { + if (null == startTime || null == endTime) + return null; + + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(startTime); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(endTime); + + Double between_days = (double) ((cal1.getTimeInMillis() - cal2.getTimeInMillis()) / (1000D)); + + return (int) Math.abs(Math.ceil(between_days)); + } + + /** + * + *
+	 * 获取当前时间到当天结束还剩多少秒
+	 * 
+ * + * @return + */ + public static Long getDaySurplusSeconds() { + Date now = new Date(); + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(now); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(getDateEnd(now)); + + Double between_Seconds = (double) ((cal2.getTimeInMillis() - cal1.getTimeInMillis()) / (1000D)); + + return (long) Math.abs(between_Seconds); + } + + /** + * 当前时间到后面2个小时还剩下多少分钟 + * + * @return + */ + public static Long getHourSurplusSeconds() { + Date now = new Date(); + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(now); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(addHour(now, 2)); + + Double between_Seconds = (double) ((cal2.getTimeInMillis() - cal1.getTimeInMillis()) / (1000D)); + + return (long) Math.abs(between_Seconds); + } + + /** + * + *
+	 * 判断2个时间是否为同一天
+	 * 
+ * + * @param date1 + * @param date2 + * @return + * @throws Exception + */ + public static Boolean compareDateIsSameDay(Date date1, Date date2) { + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(date1); + cal1.set(Calendar.HOUR_OF_DAY, 0); + cal1.set(Calendar.MINUTE, 0); + cal1.set(Calendar.SECOND, 0); + cal1.set(Calendar.MILLISECOND, 0); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(date2); + cal2.set(Calendar.HOUR_OF_DAY, 0); + cal2.set(Calendar.MINUTE, 0); + cal2.set(Calendar.SECOND, 0); + cal2.set(Calendar.MILLISECOND, 0); + + return cal1.getTimeInMillis() == cal2.getTimeInMillis(); + } + + /** + * + *
+	 * 获取出生年
+	 * 
+ * + * @param birthday + * @return + */ + public static Date getBirthday(Date birthday) { + Calendar cal = Calendar.getInstance(); + cal.setTime(birthday); + cal.set(Calendar.YEAR, getYear(new Date())); + return cal.getTime(); + } + + /** + * + *
+	 * 获取月日 如2017-8-16 20:45:44 得到 08-16
+	 * 
+ * + * @param now + * @return + */ + public static String getYearMonth(Date now) { + Calendar cal = Calendar.getInstance(); + cal.setTime(now); + int month = cal.get(Calendar.MONTH) + 1; + int day = cal.get(Calendar.DAY_OF_MONTH); + return (month < 10 ? "0" + month : month) + "-" + (day < 10 ? "0" + day : day); + } + + public static Integer getAgeWeek(String birthDay) { + if (StringUtils.isBlank(birthDay)) { + return null; + } + Date tmp = convert2Date(birthDay); + if (tmp == null) { + return null; + } + return getAgeWeek(tmp); + } + + public static Integer getAgeWeek(Date birthDay) { + if (null == birthDay) + return null; + Integer days = getDifferenceDays(new Date(), birthDay); + return days / 7 - (days < 0 ? 1 : 0); + } + + public static Integer getAgeDay(Date birthDay) { + if (null == birthDay) + return null; + Integer days = getDifferenceDays(new Date(), birthDay); + return days; + } + + public static Date get2100year() { + return convert2Date("2100-01-01 00:00:00", YYYY_MM_DD_HH_MM_SS); + } + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearBegin(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, getYear(date)); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 获取某年最后一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearEnd(Date date) { + + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, getYear(date)); + calendar.roll(Calendar.DAY_OF_YEAR, -1); + Date currYearLast = calendar.getTime(); + + return currYearLast; + } + + public static Date getMonthBegin(Date date) { + Calendar todayEnd = Calendar.getInstance(); + todayEnd.setTime(date); + todayEnd.set(Calendar.DAY_OF_MONTH, 1); + todayEnd.set(Calendar.HOUR_OF_DAY, 0); + todayEnd.set(Calendar.MINUTE, 0); + todayEnd.set(Calendar.SECOND, 0); + todayEnd.set(Calendar.MILLISECOND, 0); + return todayEnd.getTime(); + } + + public static Boolean isMonthBeginning(Date date) { + Date monthBegin = getMonthBegin(date); + Date target = getDateBegin(date); + return monthBegin.equals(target); + } + + public static void main(String[] args) { + System.out.println(DateUtils.convert2String(cutMonth(new Date(), 1))); + } +} diff --git a/crmeb-service/src/main/java/com/zbkj/service/util/RedisLockUtil.java b/crmeb-service/src/main/java/com/zbkj/service/util/RedisLockUtil.java new file mode 100644 index 0000000..b75da06 --- /dev/null +++ b/crmeb-service/src/main/java/com/zbkj/service/util/RedisLockUtil.java @@ -0,0 +1,796 @@ +package com.zbkj.service.util; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * redisTemplate封装 + * + * @author shuai.fan + */ +@Slf4j +@Component +public class RedisLockUtil { + + + @Autowired + private RedisTemplate redisTemplate; + + public RedisLockUtil(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + log.error("redisUtil.expire fail", e); + } + return false; + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + try { + if (StringUtils.isBlank(key)) { + return 0; + } + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } catch (Exception e) { + log.error("redisUtil.getExpire fail", e); + } + return 0; + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error("redisUtil.hasKey fail", e); + } + return false; + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + try { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete(CollectionUtils.arrayToList(key)); + } + } + } catch (Exception e) { + log.error("redisUtil.del fail", e); + } + } + + // ============================String============================= + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + try { + return key == null ? null : redisTemplate.opsForValue().get(key); + } catch (Exception e) { + log.error("redisUtil.get fail", e); + } + return null; + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error("redisUtil.set fail", e); + } + return false; + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + log.info("{}缓存{}秒,缓存内容:{}",key,DateUtils.convert2times(time*1000),JSONObject.toJSONString(value)); + return true; + } catch (Exception e) { + log.error("redisUtil.set fail", e); + } + return false; + } + public boolean set(String key, Object value, long time,TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, timeUnit); + } else { + set(key, value); + } + log.info("{}缓存{}秒,缓存内容:{}",key,DateUtils.convert2times(time*1000),JSONObject.toJSONString(value)); + return true; + } catch (Exception e) { + log.error("redisUtil.set fail", e); + } + return false; + } + + /** + * 递增 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递增 + * + * @param key 键 + * @return + */ + public long incr(String key) { + return redisTemplate.opsForValue().increment(key); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + try { + return redisTemplate.opsForHash().get(key, item); + } catch (Exception e) { + log.error("redisUtil.hget fail", e); + } + return null; + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + try { + return redisTemplate.opsForHash().entries(key); + } catch (Exception e) { + log.error("redisUtil.hmget fail", e); + } + return null; + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error("redisUtil.hmset fail", e); + } + return false; + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("redisUtil.hmset fail", e); + } + return false; + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error("redisUtil.hset fail", e); + } + return false; + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("redisUtil.hset fail", e); + } + return false; + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + try { + redisTemplate.opsForHash().delete(key, item); + } catch (Exception e) { + log.error("redisUtil.hdel fail", e); + } + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + try { + return redisTemplate.opsForHash().hasKey(key, item); + } catch (Exception e) { + log.error("redisUtil.hHasKey fail", e); + } + return false; + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error("redisUtil.sGet fail", e); + } + return null; + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error("redisUtil.sHasKey fail", e); + } + return false; + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error("redisUtil.sSet fail", e); + } + return 0; + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error("redisUtil.sSetAndTime fail", e); + } + return 0; + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error("redisUtil.sGetSetSize fail", e); + } + return 0; + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error("redisUtil.setRemove fail", e); + } + return 0; + } + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error("redisUtil.lGet fail", e); + } + return null; + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error("redisUtil.lGetListSize fail", e); + } + return 0; + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error("redisUtil.lGetIndex fail", e); + } + return null; + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + log.error("redisUtil.lSet fail", e); + } + return false; + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("redisUtil.lSet fail", e); + } + return false; + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error("redisUtil.lSet fail", e); + } + return false; + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("redisUtil.lSet fail", e); + } + return false; + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error("redisUtil.lUpdateIndex fail", e); + } + return false; + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + log.error("redisUtil.lRemove fail", e); + } + return 0; + } + + /** + * 模糊查询获取key值 + * + * @param pattern + * @return + */ + public Set keys(String pattern) { + try { + return redisTemplate.keys(pattern); + } catch (Exception e) { + log.error("redisUtil.keys fail", e); + } + return null; + } + + /** + * 使用Redis的消息队列 + * + * @param channel + * @param message 消息内容 + */ + public void convertAndSend(String channel, Object message) { + try { + redisTemplate.convertAndSend(channel, message); + } catch (Exception e) { + log.error("redisUtil.convertAndSend fail", e); + } + } + + public byte[] getBytes(String str) { + if (str == null) { + return null; + } + try { + return str.getBytes("UTF-8"); + } catch (Exception e) { + return str.getBytes(); + } + } + + public GenericJackson2JsonRedisSerializer getRedisSerializer() { + GenericJackson2JsonRedisSerializer redisSerializer = (GenericJackson2JsonRedisSerializer) redisTemplate + .getDefaultSerializer(); + return redisSerializer; + } + + public T get(String key, Class clazz, T defaultValue) { + T data = get(key, clazz); + if (null == data) { + data = defaultValue; + } + return data; + } + + public T get(String key, Class clazz) { + if (StringUtils.isBlank(key)) { + return null; + } + try { + RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); + byte[] source = connection.get(getBytes(key)); + if (source == null) { + return null; + } + + return getRedisSerializer().deserialize(source, clazz); + } catch (Exception e) { + log.error("redisUtil.get fail", e); + } + return null; + } + + + + // 锁前缀 + public static final String LOCK_PREFIX = "redis_lock"; + // 加锁失效时间,毫秒 + public static final int LOCK_EXPIRE = 1; // s + + public boolean lock(String key) { + return lock(key, LOCK_EXPIRE); + } + + /** + * 锁方法 + * + * @param key 锁key + * @param lockExpire 锁自动释放时间 + * @return + * @author yuwenjie + * @date 2020-02-25 03:55:52 + */ + public boolean lock(String key, int lockExpire) { + String lock = LOCK_PREFIX + key; + return (Boolean) redisTemplate.execute((RedisCallback) connection -> { + + long expireAt = System.currentTimeMillis() + lockExpire * 1000 + 1; + Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes()); + + if (acquire) { + return true; + } else { + byte[] value = connection.get(lock.getBytes()); + if (Objects.nonNull(value) && value.length > 0) { + + long expireTime = Long.parseLong(new String(value)); + // 如果锁已经过期 + if (expireTime < System.currentTimeMillis()) { + // 重新加锁,防止死锁 + byte[] oldValue = connection.getSet(lock.getBytes(), + String.valueOf(System.currentTimeMillis() + lockExpire * 1000 + 1).getBytes()); + return Long.parseLong(new String(oldValue)) < System.currentTimeMillis(); + } + } + } + return false; + }); + } + public boolean lock(String key, int lockExpire,int sleepTime,int retryCount) { + boolean lock=false; + for (int i = 0; i < retryCount; i++) { + lock = lock(key, lockExpire); + if (!lock) { + try { + log.info("重试锁次数{}",i+1); + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }else{ + break; + } + } + return lock; + } + /** + * 删除锁 + * + * @param key + */ + public void unLock(String key) { + redisTemplate.delete(LOCK_PREFIX + key); + } + + + + public static void main(String[] args) { + String s = "abc"; + + List list = Arrays.asList(new String[] {"123","abc","435"}); + + list.stream().filter(key -> !key.equals(s)).forEach(key -> { + System.out.println(key); + }); + } +} diff --git a/crmeb-service/src/main/resources/mapper/XsSkuInfoMapper.xml b/crmeb-service/src/main/resources/mapper/XsSkuInfoMapper.xml new file mode 100644 index 0000000..7cf74cd --- /dev/null +++ b/crmeb-service/src/main/resources/mapper/XsSkuInfoMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/crmeb-service/src/main/resources/mapper/user/UserAddressMapper.xml b/crmeb-service/src/main/resources/mapper/user/UserAddressMapper.xml index 3313ed9..f3ab023 100644 --- a/crmeb-service/src/main/resources/mapper/user/UserAddressMapper.xml +++ b/crmeb-service/src/main/resources/mapper/user/UserAddressMapper.xml @@ -1,5 +1,7 @@ - +