订单管理

pull/2/head
小小张 2023-05-11 18:06:00 +08:00
parent 799c4604b1
commit 693839a486
25 changed files with 2799 additions and 106 deletions

View File

@ -188,6 +188,36 @@ public class DateUtils {
SimpleDateFormat dft = new SimpleDateFormat(DATE_FORMAT);
return dft.format(new Date());
}
/**
* ,
* :<>.
*
* @return
*/
public static Date nowDateTime() {
return strToDate(nowDateTimeStr(), Constants.DATE_FORMAT);
}
/**
* ,
* :<>.
*
* @return
*/
public static String nowDateTimeStr() {
return nowDate(Constants.DATE_FORMAT);
}
/**
* ,
* :<>.
*
* @return
*/
public static String nowDate(String DATE_FORMAT) {
SimpleDateFormat dft = new SimpleDateFormat(DATE_FORMAT);
return dft.format(new Date());
}
/**
*
*
@ -208,6 +238,21 @@ public class DateUtils {
}
}
/**
*
*
* @param num
* @param newDate
* @return
*/
public static final String addDay(Date newDate, int num, String pattern) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
Calendar ca = Calendar.getInstance();
ca.setTime(newDate);
ca.add(Calendar.DATE, num);
return format.format(ca.getTime());
}
/** 获得本周第一天:yyyy-MM-dd HH:mm:ss */
public static String getWeekStartDay() {
Calendar c = Calendar.getInstance();
@ -303,6 +348,31 @@ public class DateUtils {
return null;
}
}
/**
*
* @param starDate
* @param endDate
* @return
*/
public static int daysBetween(Date starDate,Date endDate){
Calendar cal = Calendar.getInstance();
cal.setTime(starDate);
long time1 = cal.getTimeInMillis();
cal.setTime(endDate);
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
/**
*
*

View File

@ -1,9 +1,10 @@
package cn.iocoder.yudao.module.product.service.express;
package cn.iocoder.yudao.module.product.service.express.impl;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.module.product.controller.admin.express.vo.ShippingTemplatesFreeRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.express.ShippingTemplatesFreeDO;
import cn.iocoder.yudao.module.product.dal.mysql.express.ShippingTemplatesFreeMapper;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesFreeService;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.service.ip.AreaService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

View File

@ -1,9 +1,10 @@
package cn.iocoder.yudao.module.product.service.express;
package cn.iocoder.yudao.module.product.service.express.impl;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.module.product.controller.admin.express.vo.ShippingTemplatesNoDeliveryRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.express.ShippingTemplatesNoDeliveryDO;
import cn.iocoder.yudao.module.product.dal.mysql.express.ShippingTemplatesNoDeliveryMapper;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesNoDeliveryService;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.service.ip.AreaService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

View File

@ -1,9 +1,10 @@
package cn.iocoder.yudao.module.product.service.express;
package cn.iocoder.yudao.module.product.service.express.impl;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.module.product.controller.admin.express.vo.ShippingTemplatesRegionRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.express.ShippingTemplatesRegionDO;
import cn.iocoder.yudao.module.product.dal.mysql.express.ShippingTemplatesRegionMapper;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesRegionService;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.service.ip.AreaService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.product.service.express;
package cn.iocoder.yudao.module.product.service.express.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
@ -7,6 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.express.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.express.ShippingTemplatesDO;
import cn.iocoder.yudao.module.product.dal.mysql.express.ShippingTemplatesMapper;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesFreeService;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesNoDeliveryService;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesRegionService;
import cn.iocoder.yudao.module.product.service.express.ShippingTemplatesService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;

View File

@ -29,35 +29,35 @@ public class StoreOrderCountItemResponse implements Serializable {
private static final long serialVersionUID = -8605913636959651047L;
@Schema(description = "总数")
private Integer all;
private Long all;
@Schema(description = "未支付")
private Integer unPaid;
private Long unPaid;
@Schema(description = "未发货")
private Integer notShipped;
private Long notShipped;
@Schema(description = "待收货")
private Integer spike;
private Long spike;
@Schema(description = "待评价")
private Integer bargain;
private Long bargain;
@Schema(description = "交易完成")
private Integer complete;
private Long complete;
@Schema(description = "待核销")
private Integer toBeWrittenOff;
private Long toBeWrittenOff;
@Schema(description = "退款中")
private Integer refunding;
private Long refunding;
@Schema(description = "已退款")
private Integer refunded;
private Long refunded;
@Schema(description = "0 未退款 1 申请中 2 已退款")
private Integer refundStatus;
private Long refundStatus;
@Schema(description = "已删除")
private Integer deleted;
private Long deleted;
}

View File

@ -29,7 +29,7 @@ public class StoreOrderTopItemResponse implements Serializable {
private static final long serialVersionUID = -7583407020447771557L;
@Schema(description = "订单数量")
private Integer count;
private Long count;
@Schema(description = "订单金额")
private BigDecimal amount;

View File

@ -75,5 +75,17 @@
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-member-biz</artifactId>
<version>1.7.2-snapshot</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-biz</artifactId>
<version>1.7.2-snapshot</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.shop.constants;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class PayConstants {
//支付方式
public static final String PAY_TYPE_WE_CHAT = "weixin"; //微信支付
public static final String PAY_TYPE_YUE = "yue"; //余额支付
public static final String PAY_TYPE_OFFLINE = "offline"; //线下支付
public static final String PAY_TYPE_ALI_PAY = "alipay"; //支付宝
public static final String PAY_TYPE_ZERO_PAY = "zeroPay"; // 零元付
//支付渠道
public static final String PAY_CHANNEL_WE_CHAT_H5 = "weixinh5"; //H5唤起微信支付
public static final String PAY_CHANNEL_WE_CHAT_PUBLIC = "public"; //公众号
public static final String PAY_CHANNEL_WE_CHAT_PROGRAM = "routine"; //小程序
public static final String PAY_CHANNEL_WE_CHAT_APP_IOS = "weixinAppIos"; //微信App支付ios
public static final String PAY_CHANNEL_WE_CHAT_APP_ANDROID = "weixinAppAndroid"; //微信App支付android
public static final String PAY_CHANNEL_ALI_PAY = "alipay"; //支付宝支付
public static final String PAY_CHANNEL_ALI_APP_PAY = "appAliPay"; //支付宝App支付
public static final String WX_PAY_TRADE_TYPE_JS = "JSAPI";
public static final String WX_PAY_TRADE_TYPE_H5 = "MWEB";
//微信支付接口请求地址
public static final String WX_PAY_API_URL = "https://api.mch.weixin.qq.com/";
// 微信统一预下单
public static final String WX_PAY_API_URI = "pay/unifiedorder";
// 微信查询订单
public static final String WX_PAY_ORDER_QUERY_API_URI = "pay/orderquery";
// 微信支付回调地址
public static final String WX_PAY_NOTIFY_API_URI = "/api/admin/payment/callback/wechat";
// 微信退款回调地址
public static final String WX_PAY_REFUND_NOTIFY_API_URI = "/api/admin/payment/callback/wechat/refund";
public static final String WX_PAY_SIGN_TYPE_MD5 = "MD5";
public static final String WX_PAY_SIGN_TYPE_SHA256 = "HMAC-SHA256";
public static final String PAY_BODY = "Crmeb支付中心-订单支付";
public static final String FIELD_SIGN = "sign";
// 公共号退款
public static final String WX_PAY_REFUND_API_URI= "secapi/pay/refund";
}

View File

@ -0,0 +1,387 @@
package cn.iocoder.yudao.module.shop.constants;
/**
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class WeChatConstants {
//-------------------------------------------微信系统配置------------------------------------------------------------
/** 公众号appId key */
public static final String WECHAT_PUBLIC_APPID = "wechat_appid";
/** 公众号appSecret key */
public static final String WECHAT_PUBLIC_APPSECRET = "wechat_appsecret";
/** 小程序appId key */
public static final String WECHAT_MINI_APPID = "routine_appid";
// 小程序 名称
public static final String WECHAT_MINI_NAME = "routine_name";
/** 小程序appSecret key */
public static final String WECHAT_MINI_APPSECRET = "routine_appsecret";
//------------------------------------------------微信公众号------------------------------------------------
//微信接口请求地址
public static final String API_URL = "https://api.weixin.qq.com/";
//获取token
public static final String API_TOKEN_URI = "cgi-bin/token?grant_type=client_credential";
// 微信token 过期时间,娶了一个中间值 4000 官方的7200不靠谱
public static final Long API_TOKEN_EXPIRES = 3000L;
//微信公众号菜单创建
public static final String PUBLIC_API_MENU_CREATE_URI = "cgi-bin/menu/create";
//微信公众号菜单获取
public static final String PUBLIC_API_MENU_GET_URI = "cgi-bin/menu/get";
//微信公众号菜单删除
public static final String PUBLIC_API_MENU_DELETE_URI = "cgi-bin/menu/delete";
//微信公众号,获取自定义菜单配置接口
public static final String PUBLIC_API_MENU_SELF_SET_URI = "cgi-bin/get_current_selfmenu_info";
//微信公众号,创建个性化菜单
public static final String PUBLIC_API_MENU_ADD_CONDITIONAL_URI = "cgi-bin/menu/addconditional";
//微信公众号,删除个性化菜单
public static final String PUBLIC_API_MENU_DEL_CONDITIONAL_URI = "cgi-bin/menu/delconditional";
//微信公众号,测试个性化菜单匹配结果
public static final String PUBLIC_API_USER_INFO_URI = "cgi-bin/menu/trymatch";
//获取公众号已创建的标签
public static final String PUBLIC_API_TAG_LIST_URI = "cgi-bin/tags/get";
//创建标签
public static final String PUBLIC_API_TAG_CREATE_URI = "cgi-bin/tags/create";
//编辑标签
public static final String PUBLIC_API_TAG_UPDATE_URI = "cgi-bin/tags/update";
//删除标签
public static final String PUBLIC_API_TAG_DELETE_URI = "cgi-bin/tags/delete";
//获取标签下粉丝列表
public static final String PUBLIC_API_TAG_USER_GET_URI = "cgi-bin/user/tag/get";
//批量为用户打标签
public static final String PUBLIC_API_TAG_MEMBER_BATCH_URI = "cgi-bin/tags/members/batchtagging";
//批量为用户取消标签
public static final String PUBLIC_API_TAG_MEMBER_BATCH_UN_URI = "cgi-bin/tags/members/batchuntagging";
//获取用户身上的标签列表
public static final String PUBLIC_API_TAG_GET_ID_LIST_URI = "cgi-bin/tags/getidlist";
//获取 JsApiTicket
public static final String PUBLIC_API_JS_API_TICKET = "cgi-bin/ticket/getticket";
//发送公众号模板消息
public static final String PUBLIC_API_PUBLIC_TEMPLATE_MESSAGE_SEND = "cgi-bin/message/template/send";
//获取设置的行业信息
public static final String PUBLIC_API_TEMPLATE_MESSAGE_INDUSTRY = "cgi-bin/template/get_industry";
//新增其他类型永久素材
public static final String PUBLIC_API_MEDIA_UPLOAD = "cgi-bin/material/add_material";
//获取永久素材
public static final String PUBLIC_API_MEDIA_GET = "cgi-bin/material/get_material";
//获取微信素材总数
public static final String PUBLIC_API_MEDIA_COUNT = "cgi-bin/material/get_materialcount";
//发送客服消息
public static final String PUBLIC_API_KF_MESSAGE_SEND = "cgi-bin/message/custom/send";
//------------------------------------------------微信小程序------------------------------------------------
//小程序行业消息
public static final String PUBLIC_API_PROGRAM_CATEGORY = "wxaapi/newtmpl/getcategory";
//小程序公共模板库
public static final String PUBLIC_API_PROGRAM_PUBLIC_TEMP = "wxaapi/newtmpl/getpubtemplatetitles";
//小程序模板关键词列表
public static final String PUBLIC_API_PROGRAM_PUBLIC_TEMP_KEYWORDS = "wxaapi/newtmpl/getpubtemplatekeywords";
//添加小程序订阅消息
public static final String PUBLIC_API_ADD_PROGRAM_TEMPLATE = "wxaapi/newtmpl/addtemplate";
//删除小程序订阅消息
public static final String PUBLIC_API_DELETE_PROGRAM_TEMPLATE = "wxaapi/newtmpl/deltemplate";
//发送小程序模板消息
public static final String PUBLIC_API_PROGRAM_TEMPLATE_MESSAGE_SEND = "cgi-bin/message/subscribe/send";
//授权登录
//获取临时code跳转地址
public static final String WE_CHAT_AUTHORIZE_REDIRECT_URI_URL = "/api/front/wechat/authorize/login";
//获取openId
public static final String WE_CHAT_AUTHORIZE_GET_OPEN_ID = "sns/oauth2/access_token";
//获取小程序openId
public static final String WE_CHAT_AUTHORIZE_PROGRAM_GET_OPEN_ID = "sns/jscode2session";
//获取用户信息
public static final String WE_CHAT_AUTHORIZE_GET_USER_INFO = "sns/userinfo";
//生成二维码
public static final String WE_CHAT_CREATE_QRCODE = "wxa/getwxacodeunlimit";
//微信消息存储队列
public static final String WE_CHAT_MESSAGE_SEND_KEY = "we_chat_message_send_list";
//大家注意这里消息类型的定义,以 RESP 开头的表示返回的消息类型,以 REQ 表示微信服务器发来的消息类型
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_TEXT = "text";
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_MUSIC = "music";
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_NEWS = "news";
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_IMAGE = "image";
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_VOICE = "voice";
/**
*
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_VIDEO = "video";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_TEXT = "text";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_IMAGE = "image";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_LINK = "link";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_LOCATION = "location";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_VOICE = "voice";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_VIDEO = "video";
/**
*
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_EVENT = "event";
/**
* subscribe()
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* unsubscribe()
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* CLICK()
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_CLICK = "click";
/**
* VIEW( URl )
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_VIEW = "view";
/**
* LOCATION()
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_LOCATION = "LOCATION";
/**
* LOCATION()
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_SCAN = "SCAN";
//无效关键字key
public static final String WE_CHAT_MESSAGE_DEFAULT_CONTENT_KEY = "default";
//Js sdk api 列表
public static final String PUBLIC_API_JS_API_SDK_LIST = "openAddress,updateTimelineShareData,updateAppMessageShareData,onMenuShareTimeline,onMenuShareAppMessage,onMenuShareQQ,onMenuShareWeibo,onMenuShareQZone,startRecord,stopRecord,onVoiceRecordEnd,playVoice,pauseVoice,stopVoice,onVoicePlayEnd,uploadVoice,downloadVoice,chooseImage,previewImage,uploadImage,downloadImage,translateVoice,getNetworkType,openLocation,getLocation,hideOptionMenu,showOptionMenu,hideMenuItems,showMenuItems,hideAllNonBaseMenuItem,showAllNonBaseMenuItem,closeWindow,scanQRCode,chooseWXPay,openProductSpecificView,addCard,chooseCard,openCard";
//token
public static final String REDIS_TOKEN_KEY = "wechat_token";
public static final String REDIS_PROGRAM_TOKEN_KEY = "wechat_program_token";
//tag
public static final String REDIS_TAGS_LIST_KEY = "wechat_tags_list";
//user tag
public static final String REDIS_TAGS_LIST_USER_KEY = "wechat_tags_user_list";
//微信菜单
public static final String REDIS_PUBLIC_MENU_KEY = "wechat_public_menu_key";
//微信自定义菜单
public static final String REDIS_PUBLIC_MENU_SELF_KEY = "wechat_public_menu_self_key";
//授权请求地址
public static final String WE_CHAT_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appId}&redirect_uri={$redirectUri}&response_type=code&scope=snsapi_base&state=#wechat_redirect";
//-------------------------------------------微信支付------------------------------------------------------------
//微信支付接口请求地址
public static final String PAY_API_URL = "https://api.mch.weixin.qq.com/";
public static final String PAY_API_URI = "pay/unifiedorder";
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_TYPE_JS = "JSAPI";
public static final String PAY_TYPE_H5 = "MWEB";
// --------------------------------------------------------------------------------------------------------
// 微信部分
// --------------------------------------------------------------------------------------------------------
/** 获取accessToken的url */
public static final String WECHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}";
/** 开放平台获取accessToken的url */
public static final String WECHAT_OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code";
/** 开放平台获取用户的url */
public static final String WECHAT_SNS_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token={}&openid={}&lang={}";
/** 公众号js-sdk获取ticket的url */
public static final String WECHAT_PUBLIC_JS_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={}&type=jsapi";
/** 公众号发送模板消息的url */
public static final String WECHAT_PUBLIC_SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}";
/** 公众号获取自定义菜单配置的url */
public static final String WECHAT_PUBLIC_MENU_GET_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token={}";
/** 公众号创建自定义菜单的url */
public static final String WECHAT_PUBLIC_MENU_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={}";
/** 公众号删除自定义菜单的url */
public static final String WECHAT_PUBLIC_MENU_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={}";
/** 企业号上传其他类型永久素材的url */
public static final String WECHAT_PUBLIC_QYAPI_ADD_MATERIAL_URL = "https://qyapi.weixin.qq.com/cgi-bin/material/add_material?type={}&access_token={}";
/** 公众号获取模板列表(自己的) */
public static final String WECHAT_PUBLIC_GET_ALL_PRIVATE_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token={}";
/** 公众号删除模板(自己的) */
public static final String WECHAT_PUBLIC_DEL_PRIVATE_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token={}";
/** 公众号添加模板(自己的) */
public static final String WECHAT_PUBLIC_API_ADD_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={}";
/** 小程序登录凭证校验的url */
public static final String WECHAT_MINI_SNS_AUTH_CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";
/** 小程序生成小程序码的url */
public static final String WECHAT_MINI_QRCODE_UNLIMITED_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}";
/** 小程序发送订阅消息的url */
public static final String WECHAT_MINI_SEND_SUBSCRIBE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={}";
/** 小程序获取订阅列表(自己的) */
public static final String WECHAT_MINI_GET_ALL_PRIVATE_TEMPLATE_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token={}";
/** 小程序删除模板(自己的) */
public static final String WECHAT_MINI_DEL_PRIVATE_TEMPLATE_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token={}";
/** 小程序获取订阅模板(小程序的) */
public static final String WECHAT_MINI_GET_TEMPLATE_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token={}&tid={}";
/** 公众号添加模板(自己的) */
public static final String WECHAT_MINI_API_ADD_TEMPLATE_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token={}";
/** 小程序accessToken redis key */
public static final String REDIS_WECAHT_MINI_ACCESS_TOKEN_KEY = "wechat_mini_accessToken";
/** 公众号accessToken redis key */
public static final String REDIS_WECAHT_PUBLIC_ACCESS_TOKEN_KEY = "wechat_public_accessToken";
/** 公众号JsApiTicket redis key */
public static final String REDIS_PUBLIC_JS_API_TICKET = "wechat_js_api_ticket";
public static final Long REDIS_PUBLIC_JS_API_TICKET_EXPRESS = 7100L;
/**
* --------------------------------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------------------------------
*/
/*------------------------------------------ 申请接入接口 START ---------------------------------------*/
/* 申请接入申请 */
public static final String WECHAT_SHOP_REGISTER_APPLY = "https://api.weixin.qq.com/shop/register/apply?access_token={}";
/* 获取接入状态 */
public static final String WECHAT_SHOP_REGISTER_CHECK = "https://api.weixin.qq.com/shop/register/check?access_token={}";
/*------------------------------------------ 申请接入接口 END ---------------------------------------*/
/*------------------------------------------ 接入商品前必须接口 START ---------------------------------------*/
/** 获取商品类目(自定义交易组件) */
public static final String WECHAT_SHOP_CAT_GET_URL = "https://api.weixin.qq.com/shop/cat/get?access_token={}";
/** 上传图片 **/
public static final String WECHAT_SHOP_IMG_UPLOAD = "https://api.weixin.qq.com/shop/img/upload?&access_token={}";
/** 上传品牌信息 */
public static final String WECHAT_SHOP_AUDIT_AUDIT_BRAND = "https://api.weixin.qq.com/shop/audit/audit_brand?&access_token={}";
/** 上传类目资质 */
public static final String WECHAT_SHOP_AUDIT_AUDIT_CATEGORY = "https://api.weixin.qq.com/shop/audit/audit_category?&access_token={}";
/** 查询类目审核结果 */
public static final String WECHAT_SHOP_AUDIT_RESULT= "https://api.weixin.qq.com/shop/audit/result?access_token={}";
/** 获取小程序提交过的入驻资质信息 */
public static final String WECHAT_SHOP_AUDIT_GET_MINIAPP_CERTIFICATE= "https://api.weixin.qq.com/shop/audit/get_miniapp_certificate?access_token={}";
/*------------------------------------------ 接入商品前必须接口 END ---------------------------------------*/
/*------------------------------------------ 商家入驻接口 START ---------------------------------------*/
/** 获取类目列表 */
public static final String WECHAT_SHOP_ACCOUNT_GET_CATEGORY_LIST = "https://api.weixin.qq.com/shop/account/get_category_list?access_token={}";
/** 获取品牌列表 */
public static final String WECHAT_SHOP_ACCOUNT_GET_BRAND_LIST = "https://api.weixin.qq.com/shop/account/get_brand_list?access_token={}";
/** 更新商家信息 */
public static final String WECHAT_SHOP_ACCOUNT_UPDATE_INFO = "https://api.weixin.qq.com/shop/account/update_info?access_token={}";
/** 获取商家信息 */
public static final String WECHAT_SHOP_ACCOUNT_GET_INFO = "https://api.weixin.qq.com/shop/account/get_info?access_token={}";
/*------------------------------------------ 商家入驻接口 END ---------------------------------------*/
/*------------------------------------------ SPU 接口 START ---------------------------------------*/
// /** 获取品牌列表(自定义交易组件) */
// public static final String WECHAT_SHOP_BRAND_GET_URL = "https://api.weixin.qq.com/shop/account/get_brand_list?access_token={}";
/** 添加商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_ADD_URL = "https://api.weixin.qq.com/shop/spu/add?access_token={}";
/** 删除商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_DEL_URL = "https://api.weixin.qq.com/shop/spu/del?access_token={}";
/** 撤回商品审核(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_DEL_AUDIT_URL = "https://api.weixin.qq.com/shop/spu/del_audit?access_token={}";
/** 获取商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_GET_URL = "https://api.weixin.qq.com/shop/spu/get?access_token={}";
/** 获取商品列表(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_GET_LIST_URL = "https://api.weixin.qq.com/shop/spu/get_list?access_token={}";
/** 更新商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_UPDATE_URL = "https://api.weixin.qq.com/shop/spu/update?access_token={}";
/** 上架商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_LISTING_URL = "https://api.weixin.qq.com/shop/spu/listing?access_token={}";
/** 下架商品(自定义交易组件) */
public static final String WECHAT_SHOP_SPU_DELISTING_URL = "https://api.weixin.qq.com/shop/spu/delisting?access_token={}";
/** 检查场景值是否在支付校验范围内(自定义交易组件) */
public static final String WECHAT_SHOP_SCENE_CHECK_URL = "https://api.weixin.qq.com/shop/scene/check?access_token={}";
/*------------------------------------------ SPU 接口 END ---------------------------------------*/
/*------------------------------------------ 订单 接口 START ---------------------------------------*/
/** 生成订单并获取ticket(自定义交易组件) */
public static final String WECHAT_SHOP_ORDER_ADD_URL = "https://api.weixin.qq.com/shop/order/add?access_token={}";
/** 同步订单支付结果(自定义交易组件) */
public static final String WECHAT_SHOP_ORDER_PAY_URL = "https://api.weixin.qq.com/shop/order/pay?access_token={}";
/** 获取订单(自定义交易组件) */
public static final String WECHAT_SHOP_ORDER_GET_URL = "https://api.weixin.qq.com/shop/order/get?access_token={}";
/*------------------------------------------ 订单 接口 END ---------------------------------------*/
/*------------------------------------------ 物流 接口 START ---------------------------------------*/
/** 获取快递公司列表(自定义交易组件) */
public static final String WECHAT_SHOP_DELIVERY_GET_COMPANY_LIST_URL = "https://api.weixin.qq.com/shop/delivery/get_company_list?access_token={}";
/** 订单发货(自定义交易组件) */
public static final String WECHAT_SHOP_DELIVERY_SEND_URL = "https://api.weixin.qq.com/shop/delivery/send?access_token={}";
/** 订单确认收货(自定义交易组件) */
public static final String WECHAT_SHOP_DELIVERY_RECIEVE_URL = "https://api.weixin.qq.com/shop/delivery/recieve?access_token={}";
/*------------------------------------------ 物流 接口 END ---------------------------------------*/
/*------------------------------------------ 售后 接口 START ---------------------------------------*/
/** 创建售后(自定义交易组件) */
public static final String WECHAT_SHOP_AFTERSALE_ADD_URL = "https://api.weixin.qq.com/shop/aftersale/add?access_token={}";
/** 获取售后(自定义交易组件) */
public static final String WECHAT_SHOP_AFTERSALE_GET_URL = "https://api.weixin.qq.com/shop/aftersale/get?access_token={}";
/** 更新售后(自定义交易组件) */
public static final String WECHAT_SHOP_AFTERSALE_UPDATE_URL = "https://api.weixin.qq.com/shop/aftersale/update?access_token={}";
/*------------------------------------------ 售后 接口 END ---------------------------------------*/
/** 自定义组件,商品类型 redis key */
public static final String REDIS_WECHAT_SHOP_CAT_KEY = "wechat_shop_cat";
/** 微信小程序回调,商品审核回调事件 */
public static final String WECAHT_CALLBACK_EVENT_SPU_AUDIT = "open_product_spu_audit";
/** 微信小程序回调,品牌审核回调事件 */
public static final String WECAHT_CALLBACK_EVENT_BRAND_AUDIT = "open_product_brand_audit";
}

View File

@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.shop.controller.admin.order.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 退
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description="微信退款返回对象")
public class WxRefundResponseVo {
@Schema(description = "SUCCESS/FAIL此字段是通信标识非交易标识交易是否成功需要查看trade_state来判断")
@JsonProperty(value = "return_code")
private String returnCode;
@Schema(description = "当return_code为FAIL时返回信息为错误原因 ,例如 签名失败 参数格式校验错误")
@JsonProperty(value = "return_msg")
private String returnMsg;
@Schema(description = "SUCCESS/FAIL 业务结果")
@JsonProperty(value = "result_code")
private String resultCode;
@Schema(description = "详细参见错误列表")
@JsonProperty(value = "err_code")
private String errCode;
@Schema(description = "错误返回的信息描述")
@JsonProperty(value = "err_code_des")
private String errCodeDes;
@Schema(description = "调用接口提交的公众账号ID")
@JsonProperty(value = "appid")
private String appId;
@Schema(description = "调用接口提交的商户号")
@JsonProperty(value = "mch_id")
private String mchId;
@Schema(description = "微信返回的随机字符串")
@JsonProperty(value = "nonce_str")
private String nonceStr;
@Schema(description = "微信返回的签名")
private String sign;
@Schema(description = "微信支付订单号")
@JsonProperty(value = "transaction_id")
private String transactionId;
@Schema(description = "商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号", required = true)
@JsonProperty(value = "out_trade_no")
private String outTradeNo;
@Schema(description = "商户退款单号,同一退款单号多次请求只退一笔。")
@JsonProperty(value = "out_refund_no")
private String outRefundNo;
@Schema(description = "微信退款单号")
@JsonProperty(value = "refund_id")
private String refundId;
@Schema(description = "退款总金额,单位为分,可以做部分退款")
@JsonProperty(value = "refund_fee")
private Integer refundFee;
@Schema(description = "应结退款金额")
@JsonProperty(value = "settlement_refund_fee")
private Integer settlementRefundFee;
@Schema(description = "标价金额")
@JsonProperty(value = "total_fee")
private Integer totalFee;
@Schema(description = "应结订单金额")
@JsonProperty(value = "settlement_total_fee")
private Integer settlementTotalFee;
@Schema(description = "标价币种订单金额货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型")
@JsonProperty(value = "fee_type")
private String feeType;
@Schema(description = "现金支付金额")
@JsonProperty(value = "cash_fee")
private Integer cashFee;
@Schema(description = "现金支付币种订单金额货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型")
@JsonProperty(value = "cash_fee_type")
private String cashFeeType;
@Schema(description = "现金退款金额")
@JsonProperty(value = "cash_refund_fee")
private Integer cashRefundFee;
}

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.shop.controller.admin.order.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 退
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema(description="调用微信退款所需要的参数")
public class WxRefundVo {
@Schema(description = "appId公众号名称由商户传入", required = true)
private String appid;
@Schema(description = "直连商户的商户号,由微信支付生成并下发", required = true)
private String mch_id;
@Schema(description = "随机字符串不长于32位", required = true)
private String nonce_str;
@Schema(description = "签名", required = true)
private String sign;
@Schema(description = "签名类型目前支持HMAC-SHA256和MD5默认为MD5")
private String sign_type = "MD5";
@Schema(description = "微信支付订单号:微信生成的订单号,在支付通知中有返回")
private String transaction_id;
@Schema(description = "商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号", required = true)
private String out_trade_no;
@Schema(description = "商户退款单号,同一退款单号多次请求只退一笔。")
private String out_refund_no;
@Schema(description = "订单总金额,单位为分", required = true)
private int total_fee;
@Schema(description = "退款金额,单位为分", required = true)
private int refund_fee;
@Schema(description = "退款货币种类:符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型")
private String refund_fee_type = "CNY";
@Schema(description = "退款结果通知url")
private String notify_url;
}

View File

@ -75,7 +75,7 @@ public interface StoreOrderService extends IService<StoreOrder> {
* @param status
* @return
*/
Integer getTopDataUtil(Integer status, Integer userId);
Long getTopDataUtil(Integer status, Integer userId);
List<StoreOrder> getOrderGroupByDate(String dateLimit, int lefTime);
@ -195,7 +195,7 @@ public interface StoreOrderService extends IService<StoreOrder> {
* @param uid uid
* @return Integer
*/
Integer getOrderCountByUid(Integer uid);
Long getOrderCountByUid(Integer uid);
/**
*
@ -209,7 +209,7 @@ public interface StoreOrderService extends IService<StoreOrder> {
* @param uid uid
* @return Integer
*/
Integer getOrderCountByUidAndDate(Integer uid, String date);
Long getOrderCountByUidAndDate(Integer uid, String date);
/**
* ()
@ -267,14 +267,14 @@ public interface StoreOrderService extends IService<StoreOrder> {
* @param date yyyy-MM-dd
* @return Integer
*/
Integer getOrderNumByDate(String date);
Long getOrderNumByDate(String date);
/**
*
* @param date yyyy-MM-dd
* @return Integer
*/
Integer getPayOrderNumByDate(String date);
Long getPayOrderNumByDate(String date);
/**
*
@ -352,17 +352,17 @@ public interface StoreOrderService extends IService<StoreOrder> {
*
* @return Integer
*/
Integer getNotShippingNum();
Long getNotShippingNum();
/**
* 退
*/
Integer getRefundingNum();
Long getRefundingNum();
/**
*
*/
Integer getNotWriteOffNum();
Long getNotWriteOffNum();
/**
*

View File

@ -68,7 +68,7 @@ public interface StoreOrderStatusService extends IService<StoreOrderStatus> {
* @param date yyyy-MM-dd
* @return Integer
*/
Integer getRefundOrderNumByDate(String date);
Long getRefundOrderNumByDate(String date);
/**
* 退

View File

@ -3,12 +3,21 @@ package cn.iocoder.yudao.module.shop.service.order.impl;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderInfo;
import cn.iocoder.yudao.module.shop.dal.mysql.order.StoreOrderInfoMapper;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderInfoService;
import cn.iocoder.yudao.module.shop.service.product.StoreProductReplyService;
import cn.iocoder.yudao.module.shop.vo.order.OrderInfoDetailVo;
import cn.iocoder.yudao.module.shop.vo.order.StoreOrderInfoOldVo;
import cn.iocoder.yudao.module.shop.vo.order.StoreOrderInfoVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -27,15 +36,61 @@ import java.util.List;
@Service
public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper, StoreOrderInfo>
implements StoreOrderInfoService {
@Resource
private StoreOrderInfoMapper mapper;
@Autowired
private StoreProductReplyService storeProductReplyService;
@Override
public HashMap<Integer, List<StoreOrderInfoOldVo>> getMapInId(List<Integer> orderIdList) {
return null;
HashMap<Integer, List<StoreOrderInfoOldVo>> map = new HashMap<>();
if(orderIdList.size() < 1){
return map;
}
LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.in(StoreOrderInfo::getOrderId, orderIdList);
List<StoreOrderInfo> systemStoreStaffList = mapper.selectList(lambdaQueryWrapper);
if(systemStoreStaffList.size() < 1){
return map;
}
for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
//解析商品详情JSON
StoreOrderInfoOldVo StoreOrderInfoVo = new StoreOrderInfoOldVo();
BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
StoreOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), OrderInfoDetailVo.class));
if(map.containsKey(storeOrderInfo.getOrderId())){
map.get(storeOrderInfo.getOrderId()).add(StoreOrderInfoVo);
}else{
List<StoreOrderInfoOldVo> storeOrderInfoVoList = new ArrayList<>();
storeOrderInfoVoList.add(StoreOrderInfoVo);
map.put(storeOrderInfo.getOrderId(), storeOrderInfoVoList);
}
}
return map;
}
@Override
public List<StoreOrderInfoOldVo> getOrderListByOrderId(Integer orderId) {
return null;
LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(StoreOrderInfo::getOrderId, orderId);
List<StoreOrderInfo> systemStoreStaffList = mapper.selectList(lambdaQueryWrapper);
if(systemStoreStaffList.size() < 1){
return null;
}
List<StoreOrderInfoOldVo> storeOrderInfoVoList = new ArrayList<>();
for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
//解析商品详情JSON
StoreOrderInfoOldVo storeOrderInfoVo = new StoreOrderInfoOldVo();
BeanUtils.copyProperties(storeOrderInfo, storeOrderInfoVo, "info");
storeOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), OrderInfoDetailVo.class));
storeOrderInfoVo.getInfo().setIsReply(
storeProductReplyService.isReply(storeOrderInfoVo.getUnique(), storeOrderInfoVo.getOrderId()) ? 1 : 0
);
storeOrderInfoVoList.add(storeOrderInfoVo);
}
return storeOrderInfoVoList;
}
/**
@ -46,7 +101,7 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public boolean saveOrderInfos(List<StoreOrderInfo> storeOrderInfos) {
return false;
return saveBatch(storeOrderInfos);
}
/**
@ -58,7 +113,11 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public StoreOrderInfo getByUniAndOrderId(String uni, Integer orderId) {
return null;
//带 StoreOrderInfo 类的多条件查询
LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(StoreOrderInfo::getOrderId, orderId);
lambdaQueryWrapper.eq(StoreOrderInfo::getUnique, uni);
return mapper.selectOne(lambdaQueryWrapper);
}
/**
@ -69,7 +128,22 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public List<StoreOrderInfoVo> getVoListByOrderId(Integer orderId) {
return null;
LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(StoreOrderInfo::getOrderId, orderId);
List<StoreOrderInfo> systemStoreStaffList = mapper.selectList(lambdaQueryWrapper);
if(systemStoreStaffList.size() < 1){
return null;
}
List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
//解析商品详情JSON
StoreOrderInfoVo storeOrderInfoVo = new StoreOrderInfoVo();
BeanUtils.copyProperties(storeOrderInfo, storeOrderInfoVo, "info");
storeOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), OrderInfoDetailVo.class));
storeOrderInfoVoList.add(storeOrderInfoVo);
}
return storeOrderInfoVoList;
}
/**
@ -80,7 +154,9 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public List<StoreOrderInfo> getListByOrderNo(String orderNo) {
return null;
LambdaQueryWrapper<StoreOrderInfo> lqw = Wrappers.lambdaQuery();
lqw.eq(StoreOrderInfo::getOrderNo, orderNo);
return mapper.selectList(lqw);
}
/**
@ -92,7 +168,7 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public Integer getSalesNumByDateAndProductId(String date, Integer proId) {
return null;
return mapper.getSalesNumByDateAndProductId(date, proId);
}
/**
@ -104,7 +180,7 @@ public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoMapper,
*/
@Override
public BigDecimal getSalesByDateAndProductId(String date, Integer proId) {
return null;
return mapper.getSalesByDateAndProductId(date, proId);
}
}

View File

@ -1,12 +1,21 @@
package cn.iocoder.yudao.module.shop.service.order.impl;
import cn.iocoder.yudao.framework.common.enums.Constants;
import cn.iocoder.yudao.module.infra.api.config.ApiConfigApi;
import cn.iocoder.yudao.module.shop.constants.PayConstants;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundVo;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder;
import cn.iocoder.yudao.module.shop.dal.mysql.order.StoreOrderMapper;
import cn.iocoder.yudao.module.shop.request.order.StoreOrderRefundRequest;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderRefundService;
import cn.iocoder.yudao.module.shop.service.wechat.WechatNewService;
import cn.iocoder.yudao.module.shop.utils.WxPayUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
/**
* StoreOrderServiceImpl
* +----------------------------------------------------------------------
@ -22,10 +31,70 @@ import org.springframework.stereotype.Service;
@Service
public class StoreOrderRefundServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder> implements StoreOrderRefundService {
@Autowired
private ApiConfigApi apiConfigApi;
@Autowired
private WechatNewService wechatNewService;
@Override
public void refund(StoreOrderRefundRequest request, StoreOrder storeOrder) {
refundWx(request, storeOrder);
}
/**
* 退
* @param request
* @param storeOrder
*/
private void refundWx(StoreOrderRefundRequest request, StoreOrder storeOrder) {
// 获取appid、mch_id
// 微信签名key
String appId = "";
String mchId = "";
String signKey = "";
String path = "";
if (storeOrder.getIsChannel() == 0) {// 公众号
appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID).toString();
mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID).toString();
signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY).toString();
// path = systemConfigService.getValueByKeyException("pay_routine_client_p12");
path = apiConfigApi.getConfigKey("pay_weixin_certificate_path").toString();
}
if (storeOrder.getIsChannel() == 1) {// 小程序
appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_APP_ID).toString();
mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_MCH_ID).toString();
signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_ROUTINE_APP_KEY).toString();
// path = systemConfigService.getValueByKeyException("pay_mini_client_p12");
path = apiConfigApi.getConfigKey("pay_routine_certificate_path").toString();
}
if (storeOrder.getIsChannel() == 2) {// H5, 使用公众号的
appId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_ID).toString();
mchId = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_MCH_ID).toString();
signKey = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_PAY_WE_CHAT_APP_KEY).toString();
// path = systemConfigService.getValueByKeyException("pay_mini_client_p12");
path = apiConfigApi.getConfigKey("pay_weixin_certificate_path").toString();
}
String apiDomain = apiConfigApi.getConfigKey(Constants.CONFIG_KEY_API_URL).toString();
//统一下单数据
WxRefundVo wxRefundVo = new WxRefundVo();
wxRefundVo.setAppid(appId);
wxRefundVo.setMch_id(mchId);
wxRefundVo.setNonce_str(WxPayUtil.getNonceStr());
wxRefundVo.setOut_trade_no(storeOrder.getOutTradeNo());
wxRefundVo.setOut_refund_no(storeOrder.getOrderId());
wxRefundVo.setTotal_fee(storeOrder.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
wxRefundVo.setRefund_fee(request.getAmount().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
wxRefundVo.setNotify_url(apiDomain + PayConstants.WX_PAY_REFUND_NOTIFY_API_URI);
String sign = WxPayUtil.getSign(wxRefundVo, signKey);
wxRefundVo.setSign(sign);
wechatNewService.payRefund(wxRefundVo, path);
}
}

View File

@ -1,14 +1,26 @@
package cn.iocoder.yudao.module.shop.service.order.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.Constants;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderStatus;
import cn.iocoder.yudao.module.shop.dal.mysql.order.StoreOrderStatusMapper;
import cn.iocoder.yudao.module.shop.request.order.StoreOrderStatusSearchRequest;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderStatusService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
@ -26,6 +38,13 @@ import java.util.List;
*/
@Service
public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMapper, StoreOrderStatus> implements StoreOrderStatusService {
@Resource
private StoreOrderStatusMapper mapper;
@Autowired
private StoreOrderService storeOrderService;
/**
*
*
@ -35,7 +54,15 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public PageInfo<StoreOrderStatus> getList(StoreOrderStatusSearchRequest request, PageParam pageParamRequest) {
return null;
StoreOrder storeOrder = storeOrderService.getByOderId(request.getOrderNo());
if (ObjectUtil.isNull(storeOrder)) {
return new PageInfo<>(CollUtil.newArrayList());
}
PageHelper.startPage(pageParamRequest.getPageNo(), pageParamRequest.getPageSize());
LambdaQueryWrapper<StoreOrderStatus> lqw = new LambdaQueryWrapper<>();
lqw.eq(StoreOrderStatus::getOid, storeOrder.getId());
lqw.orderByDesc(StoreOrderStatus::getCreateTime);
return new PageInfo<>(mapper.selectList(lqw));
}
/**
@ -48,7 +75,16 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public Boolean saveRefund(Integer orderId, BigDecimal amount, String message) {
return null;
//此处更新订单状态
String changeMessage = Constants.ORDER_LOG_MESSAGE_REFUND_PRICE.replace("{amount}", amount.toString());
if(StringUtils.isNotBlank(message)){
changeMessage += message;
}
StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
storeOrderStatus.setOid(orderId);
storeOrderStatus.setChangeType(Constants.ORDER_LOG_REFUND_PRICE);
storeOrderStatus.setChangeMessage(changeMessage);
return save(storeOrderStatus);
}
/**
@ -61,7 +97,12 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public Boolean createLog(Integer orderId, String type, String message) {
return null;
StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
storeOrderStatus.setOid(orderId);
storeOrderStatus.setChangeType(type);
storeOrderStatus.setChangeMessage(message);
storeOrderStatus.setCreateTime(DateUtils.nowDateTime());
return save(storeOrderStatus);
}
/**
@ -72,7 +113,9 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public List<StoreOrderStatus> getByEntity(StoreOrderStatus storeOrderStatus) {
return null;
LambdaQueryWrapper<StoreOrderStatus> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.setEntity(storeOrderStatus);
return mapper.selectList(lambdaQueryWrapper);
}
/**
@ -83,7 +126,11 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public StoreOrderStatus getLastByOrderId(Integer orderId) {
return null;
QueryWrapper<StoreOrderStatus> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("oid", orderId);
queryWrapper.orderByDesc("create_time");
queryWrapper.last(" limit 1");
return mapper.selectOne(queryWrapper);
}
/**
@ -93,8 +140,12 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
* @return Integer
*/
@Override
public Integer getRefundOrderNumByDate(String date) {
return null;
public Long getRefundOrderNumByDate(String date) {
QueryWrapper<StoreOrderStatus> wrapper = new QueryWrapper<>();
wrapper.select("oid");
wrapper.eq("change_type", "refund_price");
wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
return mapper.selectCount(wrapper);
}
/**
@ -105,7 +156,7 @@ public class StoreOrderStatusServiceImpl extends ServiceImpl<StoreOrderStatusMap
*/
@Override
public BigDecimal getRefundOrderAmountByDate(String date) {
return null;
return mapper.getRefundOrderAmountByDate(date);
}
}

View File

@ -1,8 +1,34 @@
package cn.iocoder.yudao.module.shop.service.order.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.Constants;
import cn.iocoder.yudao.framework.common.exception.ServerException;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.infra.api.config.ApiConfigApi;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderInfo;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderInfoService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderStatusService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderTaskService;
import cn.iocoder.yudao.module.shop.service.product.StoreProductAttrValueService;
import cn.iocoder.yudao.module.shop.service.product.StoreProductService;
import cn.iocoder.yudao.module.system.service.sms.SmsTemplateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.OrderUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
/**
* StoreOrderTaskService
@ -18,28 +44,248 @@ import org.springframework.stereotype.Service;
*/
@Service
public class StoreOrderTaskServiceImpl implements StoreOrderTaskService {
//日志
private static final Logger logger = LoggerFactory.getLogger(StoreOrderTaskServiceImpl.class);
@Autowired
private StoreOrderService storeOrderService;
@Autowired
private StoreOrderInfoService storeOrderInfoService;
@Autowired
private StoreProductService storeProductService;
@Autowired
private StoreOrderStatusService storeOrderStatusService;
@Autowired
private MemberUserMapper memberUserMapper;
@Autowired
private TransactionTemplate transactionTemplate;
private ApiConfigApi apiConfigApi;
@Autowired
private OrderUtils orderUtils;
@Autowired
private StoreProductAttrValueService attrValueService;
@Autowired
private SmsTemplateService smsTemplateService;
@Override
@Transactional(rollbackFor = {RuntimeException.class, Error.class, ServerException.class})
public Boolean cancelByUser(StoreOrder storeOrder) {
return null;
try{
/*
* 1
* 2
* 3
* */
//写订单日志
storeOrderStatusService.createLog(storeOrder.getId(), "cancel_order", "取消订单");
return rollbackStock(storeOrder);
}catch (Exception e){
return false;
}
}
/**
*
* @param storeOrder
*/
private Boolean rollbackStock(StoreOrder storeOrder) {
try{
// 查找出商品详情
List<StoreOrderInfo> orderInfoList = storeOrderInfoService.getListByOrderNo(storeOrder.getOrderId());
if(null == orderInfoList || orderInfoList.size() < 1){
return true;
}
// 正常商品回滚销量库存
for (StoreOrderInfo orderInfoVo : orderInfoList) {
storeProductService.operationStock(orderInfoVo.getProductId(), orderInfoVo.getPayNum(), "add");
attrValueService.operationStock(orderInfoVo.getAttrValueId(), orderInfoVo.getPayNum(), "add", Constants.PRODUCT_TYPE_NORMAL);
}
}catch (Exception e){
// throw new CrmebException(e.getMessage());
logger.error("回滚库存失败error = " + e.getMessage());
return true;
}
return true;
}
@Override
@Transactional(rollbackFor = {RuntimeException.class, Error.class, ServerException.class})
public Boolean complete(StoreOrder storeOrder) {
return null;
/*
* 1
* 2
* */
try{
storeOrderStatusService.createLog(storeOrder.getId(), "check_order_over", "用户评价");
return true;
}catch (Exception e){
return false;
}
}
@Override
public Boolean refundOrder(StoreOrder storeOrder) {
return null;
/**
* 1
* 2
* 3
* 2-5user+userBill
*/
// 获取用户对象
MemberUserDO user = memberUserMapper.selectById(storeOrder.getUid());
if (ObjectUtil.isNull(user)) {
logger.error("订单退款处理,对应的用户不存在,storeOrder===>" + storeOrder);
return Boolean.FALSE;
}
StoreOrder tempOrder = new StoreOrder();
tempOrder.setId(storeOrder.getId());
tempOrder.setRefundStatus(2);
Boolean execute = transactionTemplate.execute(e -> {
//写订单日志
storeOrderStatusService.saveRefund(storeOrder.getId(), storeOrder.getRefundPrice(), "成功");
// 更新用户数据
memberUserMapper.updateById(user);
// 回滚库存
rollbackStock(storeOrder);
storeOrderService.updateById(tempOrder);
return Boolean.TRUE;
});
return execute;
}
@Override
public Boolean autoCancel(StoreOrder storeOrder) {
return null;
// 判断订单是否支付
if (storeOrder.getPaid()) {
return Boolean.TRUE;
}
if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
return Boolean.TRUE;
}
// 获取过期时间
String cancelStr;
DateTime cancelTime;
if (storeOrder.getType().equals(1)) {
cancelStr = "3";
cancelTime = cn.hutool.core.date.DateUtil.offset(storeOrder.getCreateTime(), DateField.MINUTE, Integer.parseInt(cancelStr));
} else {
if (storeOrder.getBargainId() > 0 || storeOrder.getSeckillId() > 0 || storeOrder.getCombinationId() > 0) {
cancelStr = apiConfigApi.getConfigKey("order_activity_time").toString();
} else {
cancelStr = apiConfigApi.getConfigKey("order_cancel_time").toString();
}
if (StrUtil.isBlank(cancelStr)) {
cancelStr = "1";
}
cancelTime = cn.hutool.core.date.DateUtil.offset(storeOrder.getCreateTime(), DateField.HOUR_OF_DAY, Integer.parseInt(cancelStr));
}
long between = cn.hutool.core.date.DateUtil.between(cancelTime, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
if (between < 0) {// 未到过期时间继续循环
return Boolean.FALSE;
}
storeOrder.setIsDel(true).setIsSystemDel(true);
Boolean execute = transactionTemplate.execute(e -> {
storeOrderService.updateById(storeOrder);
//写订单日志
storeOrderStatusService.createLog(storeOrder.getId(), "cancel", "到期未支付系统自动取消");
return Boolean.TRUE;
});
if (execute) {
// 回滚库存
rollbackStock(storeOrder);
}
return execute;
}
@Override
public Boolean orderReceiving(Integer orderId) {
return null;
StoreOrder storeOrder = storeOrderService.getById(orderId);
if (ObjectUtil.isNull(storeOrder)) {
throw new ServiceException(StrUtil.format("订单收货task处理未找到订单id={}", orderId));
}
Boolean execute = transactionTemplate.execute(e -> {
// 日志
storeOrderStatusService.createLog(storeOrder.getId(), "user_take_delivery", Constants.ORDER_STATUS_STR_TAKE);
return Boolean.TRUE;
});
//TODO 发送用户确认收货管理员提醒短信
return execute;
}
/**
*
*
*
*
*/
// private void pushMessageOrder(StoreOrder storeOrder, MemberUserDO user) {
// SystemNotification notification = systemNotificationService.getByMark(NotifyConstants.RECEIPT_GOODS_MARK);
// if (storeOrder.getIsChannel().equals(2)) {
// return;
// }
// if (!storeOrder.getPayType().equals(Constants.PAY_TYPE_WE_CHAT)) {
// return;
// }
// UserToken userToken;
// HashMap<String, String> temMap = new HashMap<>();
// // 公众号
// if (storeOrder.getIsChannel().equals(Constants.ORDER_PAY_CHANNEL_PUBLIC) && notification.getIsWechat().equals(1)) {
// userToken = userTokenService.getTokenByUserId(user.getUid(), UserConstants.USER_TOKEN_TYPE_WECHAT);
// if (ObjectUtil.isNull(userToken)) {
// return ;
// }
// // 发送微信模板消息
// temMap.put(Constants.WE_CHAT_TEMP_KEY_FIRST, "您购买的商品已确认收货!");
// temMap.put("keyword1", storeOrder.getOrderId());
// temMap.put("keyword2", "已收货");
// temMap.put("keyword3", DateUtils.nowDateTimeStr());
// temMap.put("keyword4", "详情请进入订单查看");
// temMap.put(Constants.WE_CHAT_TEMP_KEY_END, "感谢你的使用。");
// templateMessageService.pushTemplateMessage(notification.getWechatId(), temMap, userToken.getToken());
// } else if (notification.getIsRoutine().equals(1)) {
// // 小程序发送订阅消息
// userToken = userTokenService.getTokenByUserId(user.getUid(), UserConstants.USER_TOKEN_TYPE_ROUTINE);
// if (ObjectUtil.isNull(userToken)) {
// return ;
// }
// // 组装数据
// // 获取商品名称
// String storeNameAndCarNumString = orderUtils.getStoreNameAndCarNumString(storeOrder.getId());
// if (StrUtil.isBlank(storeNameAndCarNumString)) {
// return ;
// }
// if (storeNameAndCarNumString.length() > 20) {
// storeNameAndCarNumString = storeNameAndCarNumString.substring(0, 15) + "***";
// }
//// temMap.put("character_string6", storeOrder.getOrderId());
//// temMap.put("phrase4", "已收货");
//// temMap.put("time7", DateUtil.nowDateTimeStr());
//// temMap.put("thing1", storeNameAndCarNumString);
//// temMap.put("thing5", "您购买的商品已确认收货!");
// temMap.put("character_string6", storeOrder.getOrderId());
// temMap.put("date5", DateUtils.nowDateTimeStr());
// temMap.put("thing2", storeNameAndCarNumString);
// templateMessageService.pushMiniTemplateMessage(notification.getRoutineId(), temMap, userToken.getToken());
// }
// }
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.shop.service.wechat;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundResponseVo;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundVo;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public interface WechatNewService {
/**
* 退
* @param wxRefundVo 退
* @param path p12
* @return 退
*/
WxRefundResponseVo payRefund(WxRefundVo wxRefundVo, String path);
}

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.shop.service.wechat.impl;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.shop.constants.WeChatConstants;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundResponseVo;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundVo;
import cn.iocoder.yudao.module.shop.service.wechat.WechatNewService;
import cn.iocoder.yudao.module.shop.utils.CrmebUtil;
import cn.iocoder.yudao.module.shop.utils.RedisUtil;
import cn.iocoder.yudao.module.shop.utils.RestTemplateUtil;
import cn.iocoder.yudao.module.shop.utils.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Service
public class WechatNewServiceImpl implements WechatNewService {
private static final Logger logger = LoggerFactory.getLogger(WechatNewServiceImpl.class);
@Autowired
private RedisUtil redisUtil;
@Autowired
private RestTemplateUtil restTemplateUtil;
/**
* 退
* @param wxRefundVo 退
* @param path p12
* @return 退
*/
@Override
public WxRefundResponseVo payRefund(WxRefundVo wxRefundVo, String path) {
String xmlStr = XmlUtil.objectToXml(wxRefundVo);
String url = WeChatConstants.PAY_API_URL + WeChatConstants.PAY_REFUND_API_URI_WECHAT;
HashMap<String, Object> map = new HashMap<>();
String xml = "";
try {
xml = restTemplateUtil.postWXRefundXml(url, xmlStr, wxRefundVo.getMch_id(), path);
map = XmlUtil.xmlToMap(xml);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException("xmlToMap错误xml = " + xml);
}
if (null == map) {
throw new ServiceException("微信无信息返回,微信申请退款失败!");
}
WxRefundResponseVo responseVo = CrmebUtil.mapToObj(map, WxRefundResponseVo.class);
if (responseVo.getReturnCode().toUpperCase().equals("FAIL")) {
// wxPayExceptionDispose(map, "微信申请退款异常1");
throw new ServiceException("微信申请退款失败1" + responseVo.getReturnMsg());
}
if (responseVo.getResultCode().toUpperCase().equals("FAIL")) {
// wxPayExceptionDispose(map, "微信申请退款业务异常");
throw new ServiceException("微信申请退款失败2" + responseVo.getErrCodeDes());
}
System.out.println("================微信申请退款结束=========================");
return responseVo;
}
/**
*
* @param map
* @param remark
*/
// private void wxPayExceptionDispose(HashMap<String, Object> map, String remark) {
// WechatExceptions wechatExceptions = new WechatExceptions();
// String returnCode = (String) map.get("return_code");
// if (returnCode.toUpperCase().equals("FAIL")) {
// wechatExceptions.setErrcode("-100");
// wechatExceptions.setErrmsg(map.get("return_msg").toString());
// } else {
// wechatExceptions.setErrcode(map.get("err_code").toString());
// wechatExceptions.setErrmsg(map.get("err_code_des").toString());
// }
// wechatExceptions.setData(JSONObject.toJSONString(map));
// wechatExceptions.setRemark(remark);
// wechatExceptions.setCreateTime(DateUtil.date());
// wechatExceptions.setUpdateTime(DateUtil.date());
// wechatExceptionsService.save(wechatExceptions);
// }
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.shop.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.iocoder.yudao.framework.common.enums.Constants;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
@ -51,6 +52,19 @@ public class CrmebUtil {
return new String(result, StandardCharsets.UTF_8);
}
/**
* map
* @param map map
* @param clz
* @author Mr.Zhang
* @since 2020-04-14
* @return Map
*/
public static <T> T mapToObj(HashMap<String,Object> map, Class<T> clz){
if (map == null) return null;
return JSONObject.parseObject(JSONObject.toJSONString(map), clz);
}
/**
* DES
* @param key

View File

@ -0,0 +1,111 @@
package cn.iocoder.yudao.module.shop.utils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
/**
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
* httpClient
*/
@Component
public class RestTemplateUtil {
@Autowired
private RestTemplate restTemplate;
public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9";
public static final String USER_AGENT = WXPAYSDK_VERSION +
" (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") +
") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion();
/**
* POST-JSON(退)
*
* @param url
* @return
*/
public String postWXRefundXml(String url, String xml, String mchId, String path) throws Exception {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
// 读取本机存放的PKCS12证书文件
FileInputStream instream = new FileInputStream(path);
try {
// 指定PKCS12的密码(商户ID)
clientStore.load(instream, mchId.toCharArray());
} finally {
instream.close();
}
// 实例化密钥库 & 初始化密钥工厂
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, mchId.toCharArray());
// 创建 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
// new String[]{"TLSv1"},
// null,
new DefaultHostnameVerifier());
BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build(),
null,
null,
null
);
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.build();
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(8*1000).setConnectTimeout(6*1000).build();
httpPost.setConfig(requestConfig);
StringEntity postEntity = new StringEntity(xml, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.addHeader("User-Agent", USER_AGENT + " " + mchId);
httpPost.setEntity(postEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
org.apache.http.HttpEntity httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity, "UTF-8");
}
}

View File

@ -0,0 +1,88 @@
package cn.iocoder.yudao.module.shop.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.iocoder.yudao.module.shop.constants.PayConstants;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.WxRefundVo;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class WxPayUtil {
/**
* sign
* @param wxRefundVo 退
* @param signKey key
* @return String
*/
public static String getSign(WxRefundVo wxRefundVo, String signKey) {
// 对象转map
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(wxRefundVo), Map.class);
// map排序
Set<String> keySet = map.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(PayConstants.FIELD_SIGN)) {
continue;
}
if (ObjectUtil.isNotNull(map.get(k))) // 参数值为空,则不参与签名
sb.append(k).append("=").append(map.get(k)).append("&");
}
sb.append("key=").append(signKey);
String sign = SecureUtil.md5(sb.toString()).toUpperCase();
System.out.println("sign ========== " + sign);
return sign;
}
/**
* sign
* @param map
* @param signKey key
* @return String
*/
public static String getSign(Map<String, String> map, String signKey) {
// map排序
Set<String> keySet = map.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(PayConstants.FIELD_SIGN)) {
continue;
}
if (StrUtil.isNotBlank(map.get(k)) && map.get(k).trim().length() > 0) // 参数值为空,则不参与签名
sb.append(k).append("=").append(map.get(k).trim()).append("&");
}
sb.append("key=").append(signKey);
String sign = SecureUtil.md5(sb.toString()).toUpperCase();
System.out.println("sign ========== " + sign);
return sign;
}
/**
* 32
*/
public static String getNonceStr() {
return DigestUtils.md5Hex(CrmebUtil.getUuid() + CrmebUtil.randomCount(111111, 666666));
}
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.shop.utils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* XML
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public class XmlUtil {
public static Map<String, String> xmlToMap(HttpServletRequest request) {
Map<String, String> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream in = null;
try {
in = request.getInputStream();
Document doc = reader.read(in);
Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
map.put(element.getName(), element.getText());
}
} catch (IOException | DocumentException e) {
e.printStackTrace();
} finally {
try {
assert in != null;
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return map;
}
/**
* xml
*/
public static HashMap<String, Object> xmlToMap(String strxml) throws Exception {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
HashMap<String, Object> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream inputStream = new ByteArrayInputStream(strxml.getBytes(StandardCharsets.UTF_8));
if (StringUtils.isBlank(strxml)) {
return null;
}
Document document = reader.read(inputStream);
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element e : list) {
map.put(e.getName(), e.getText());
}
inputStream.close();
return map;
}
/**
* xml
*/
public static String objectToXml(Object object) {
XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder())); //不需要转义
xstream.alias("xml", object.getClass());
return xstream.toXML(object);
}
}