Commit 56313839 by 郑云飞

定时任务 拼团失败退款 完成

parent 151019ec
......@@ -81,12 +81,23 @@ public class WxController {
}
/**
* 微信退款回调
*
* @param request
* @return
*/
@RequestMapping(value = "/wxRefundNotify", method = RequestMethod.POST)
public void wxRefundNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
wxService.wxRefundNotify(request, response);
}
/**
* 微信退款
*
* @param request
* @return
*/
@RequestMapping(value = "/wxPay", method = RequestMethod.POST)
@RequestMapping(value = "/wxRefund", method = RequestMethod.POST)
public Result wxRefund(Integer userId, Integer orderId, HttpServletRequest request) {
try {
return wxService.wxRefund(userId, orderId, request);
......
......@@ -112,6 +112,13 @@ public class GroupBuyController {
return Result.success(rmap);
}
@RequestMapping(value = "/{id}/deleteById",method = RequestMethod.GET)
@ResponseBody
public Result deleteById(@PathVariable Long id){
return Result.success(groupBuyService.delById(id));
}
/**
* 新增团购活动
* @param item
......
package com.yunniu.farming.webadmin.controller;
import cn.hutool.core.lang.WeightRandom;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yunniu.farming.util.DateTools;
import com.yunniu.farming.webadmin.dao.CustomerDao;
import com.yunniu.farming.webadmin.dao.GroupBuyDao;
import com.yunniu.farming.webadmin.dao.GroupOrderDao;
import com.yunniu.farming.webadmin.dao.OrderMainDao;
import com.yunniu.farming.webadmin.model.Customer;
......@@ -34,6 +33,8 @@ public class TaskJob {
private OrderMainDao orderMainDao;
@Autowired
private WxService wxService;
@Autowired
private GroupBuyDao groupBuyDao;
//定时任务
@Scheduled(cron = "0 0 0 * * ? ") // 每天凌晨零点零分零秒
......@@ -48,11 +49,11 @@ public class TaskJob {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String nowDay = DateTools.getDate("yyyy-MM-dd");
Date now = sdf.parse(nowDay);
if(customers != null && customers.size() > 0){
if (customers != null && customers.size() > 0) {
for (Customer task : customers) {
//会员过期日期与当前日期进行比较 当前日期大于会员到期日期
Date svip = sdf.parse(task.getSenddate());
if(now.getTime() > svip.getTime()){
if (now.getTime() > svip.getTime()) {
//改变会员用户状态
this.updateUserVipStatus(task);
}
......@@ -66,14 +67,14 @@ public class TaskJob {
*/
@Scheduled(cron = "59 59 23 * * ? ")
@Transactional(rollbackFor = Exception.class)
public void successGroup() throws Exception{
public void successGroup() throws Exception {
// 查询待成团并到期的团购订单
List<GroupOrder> orders = groupOrderDao.getList();
orders.forEach(order -> {
// 查询已支付成功订单
List<OrderMain> orderMains = orderMainDao.selectByGroupOrderId(order.getId());
// 订单数小于成团数 拼团失败 进行退款
if (order.getGroupSize() < orderMains.size()){
if (order.getGroupSize() < orderMains.size()) {
order.setGroupStatus("4");
// 循环退款
orderMains.forEach(orderMain -> {
......@@ -87,11 +88,20 @@ public class TaskJob {
});
}
/**
* 定时失效团购活动
*/
@Scheduled(cron = "59 59 23 * * ? ")
public void activityFailure() {
groupBuyDao.activityFailure();
}
//改变会员用户状态
public void updateUserVipStatus(Customer user){
public void updateUserVipStatus(Customer user) {
if(user == null){
return ;
if (user == null) {
return;
}
user.setIroleid(Customer.ROLE_NORMAL);//普通用户
......
......@@ -17,4 +17,8 @@ public interface GroupBuyDao extends BaseMapper<GroupBuy> {
List<GroupBuy> findPageList(GroupBuy item);
int updateEndTime(GroupBuy item);
int activityFailure();
int updateStatus(Long id);
}
......@@ -17,5 +17,7 @@ import java.util.List;
public interface GroupBuyProductDao extends BaseMapper<GroupBuyProduct> {
int insertBath(@Param("products") List<GroupBuyProduct> products, @Param("id") Long id);
List<Product> getList(Long id);
List<Product> getProductList(Long id);
List<GroupBuyProduct> getList(Long id);
}
......@@ -3,6 +3,7 @@ package com.yunniu.farming.webadmin.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yunniu.farming.webadmin.model.GroupBuy;
import com.yunniu.farming.webadmin.model.GroupOrder;
import com.yunniu.farming.webadmin.model.OrderMain;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
......@@ -24,4 +25,6 @@ public interface GroupOrderDao extends BaseMapper<GroupOrder> {
GroupBuy getGroupBuy(Long groupOrderId);
int updateStatus(Long groupOrderId);
OrderMain getBySdef1(String outRefundNo);
}
......@@ -34,4 +34,6 @@ public interface GroupBuyService {
* @return
*/
List<Product> productList(Product item);
int delById(Long id);
}
......@@ -26,4 +26,6 @@ public interface GroupOrderService {
* @return
*/
List<OrderSub> productList(OrderSub item);
boolean updateRefundStatus(String outRefundNo);
}
......@@ -16,4 +16,6 @@ public interface WxService {
void notify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException;
Result wxRefund(Integer userId, Integer orderId, HttpServletRequest request) throws Exception;
void wxRefundNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException;
}
......@@ -83,6 +83,13 @@ public class GroupBuyServiceimpl implements GroupBuyService {
}
return Result.success();
} else {
Calendar cal = Calendar.getInstance();
cal.setTime(item.getEndTime());
cal.set(Calendar.HOUR_OF_DAY, 23); //时
cal.set(Calendar.MINUTE, 59); //分
cal.set(Calendar.SECOND, 59); //秒
cal.set(Calendar.MILLISECOND, 0); //毫秒
item.setEndTime(cal.getTime());
this.mapper.updateEndTime(item);
return Result.success();
}
......@@ -103,8 +110,10 @@ public class GroupBuyServiceimpl implements GroupBuyService {
groupBuy.setStartDate(formatter.format(groupBuy.getStartTime()));
groupBuy.setEndDate(formatter.format(groupBuy.getEndTime()));
// 团购商品
List<Product> products = groupBuyProductDao.getList(id);
groupBuy.setProductList(JSON.toJSONString(products));
List<Product> productList = groupBuyProductDao.getProductList(id);
List<GroupBuyProduct> products = groupBuyProductDao.selectList(Wrappers.<GroupBuyProduct>lambdaQuery().eq(GroupBuyProduct::getGroupBuyId, id));
groupBuy.setProductList(JSON.toJSONString(productList));
groupBuy.setProducts(products);
// 团购小区
String areaIds = groupBuy.getAreaIds();
if (StringUtils.isNotEmpty(areaIds)) {
......@@ -130,4 +139,14 @@ public class GroupBuyServiceimpl implements GroupBuyService {
public List<Product> productList(Product item) {
return productDao.selectByParamPageList(item);
}
/**
* 根据id删除
* @param id
* @return
*/
@Override
public int delById(Long id) {
return mapper.updateStatus(id);
}
}
......@@ -129,6 +129,22 @@ public class GroupOrderServiceImpl implements GroupOrderService {
}
/**
* 退款回调修改退款状态
* @param outRefundNo
* @return
*/
@Override
public boolean updateRefundStatus(String outRefundNo) {
OrderMain order = orderDao.getBySdef1(outRefundNo);
order.setIrefundstatus(1);
int update = orderMainDao.updateById(order);
if (update > 0) {
return true;
}
return false;
}
/**
* 支付成功后判断团购订单是否成团
* @param curOrder
*/
......
......@@ -2,23 +2,23 @@ package com.yunniu.farming.webadmin.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yunniu.farming.util.DateTools;
import com.yunniu.farming.util.StringHelper;
import com.yunniu.farming.util.UrlUtil;
import com.yunniu.farming.util.*;
import com.yunniu.farming.webadmin.dao.*;
import com.yunniu.farming.webadmin.model.*;
import com.yunniu.farming.webadmin.service.GroupOrderService;
import com.yunniu.farming.webadmin.service.WxService;
import com.yunniu.farming.util.UUIDUtils;
import com.yunniu.farming.wx.WxConfigUtil;
import com.yunniu.farming.wx.WxUtil;
import com.yunniu.farming.wx.XMLUtil;
import lombok.extern.slf4j.Slf4j;
import org.jdom.JDOMException;
import org.osgi.framework.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
......@@ -26,6 +26,7 @@ import java.text.DecimalFormat;
import java.util.*;
@Service
@Slf4j
public class WxServiceImpl implements WxService {
@Autowired
......@@ -122,8 +123,7 @@ public class WxServiceImpl implements WxService {
* 获取微信小程序 session_key 和 openid
*
* @author zhy
* @param code 调用微信登陆返回的Code
* @param token
* @param wxcode 调用微信登陆返回的Code
* @return
*/
public JSONObject getSessionKeyOropenid(String wxcode){
......@@ -244,7 +244,7 @@ public class WxServiceImpl implements WxService {
parameters.put("refund_fee", decimalFormat.format(tradeMoney * 100)); // 订单总金额
//parameters.put("profit_sharing", "Y");
// 用户端实际ip
parameters.put("notify_url", WxConfigUtil.notify_url); // 接收微信支付异步通知回调地址
parameters.put("notify_url", WxConfigUtil.refund_notify_url); // 接收微信支付异步通知回调地址
System.out.println("sign=====" + parameters);
// 设置签名
String sign = WxUtil.createSignMD5(parameters);
......@@ -263,6 +263,146 @@ public class WxServiceImpl implements WxService {
return new Result();
}
/**
* 退款成功回调
* @param request
* @param response
*/
@Override
public void wxRefundNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
// 解析xml成map
Map<String, String> m = new HashMap<String, String>();
m = XMLUtil.doXMLParse(sb.toString());
for (Object keyValue : m.keySet()) {
System.out.println(keyValue + "=" + m.get(keyValue));
}
// 过滤空 设置 TreeMap
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
Iterator it = m.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = m.get(parameter);
String v = "";
if (null != parameterValue) {
v = parameterValue.trim();
}
packageParams.put(parameter, v);
}
// 判断签名是否正确
String resXml = "";
if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
System.out.println("退款成功!");
// 这里是退款成功
// ////////执行自己的业务逻辑////////////////
String req_info = (String) packageParams.get("req_info"); // 商户号
resXml = this.wechatRefund(req_info);
} else {
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
// ------------------------------
// 处理业务完毕
// ------------------------------
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
public String wechatRefund(String xmlStr) {
String xmlBack = "";
Map<String, String> notifyMap = null;
try {
//解密
String reqInfo = decryptData(xmlStr);
// 解析xml成map
Map<String, String> m = new HashMap<String, String>();
m = XMLUtil.doXMLParse(reqInfo);
for (Object keyValue : m.keySet()) {
System.out.println(keyValue + "=" + m.get(keyValue));
}
// 过滤空 设置 TreeMap
SortedMap<String, String> map = new TreeMap<String, String>();
Iterator it = m.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = m.get(parameter);
String v = "";
if (null != parameterValue) {
v = parameterValue.trim();
}
map.put(parameter, v);
}
if (null == map || map.size() == 0) {
log.info("解密异常");
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
}
//支付交易号
String transactionId = map.get("transaction_id");
//订单号sys/sysDepart/batchSyncSysDepart
String outTradeNo = map.get("out_trade_no");
//退款交易号
String refundId = map.get("refund_id");
//退款单号
String outRefundNo = map.get("out_refund_no");
//订单金额
String totalFee = map.get("total_fee");
String settlementTotalFee = map.get("settlement_total_fee");
//申请金额
String refundFee = map.get("refund_fee");
//退款金额
String settlementRefundFee = map.get("settlement_refund_fee");
//退款状态
String refundStatus = map.get("refund_status");
//成功时间
String successTime = map.get("success_time");
String refundRecvAccout = map.get("refund_recv_accout");
String refundAccount = map.get("refund_account");
String refundRequestSource = map.get("refund_request_source");
groupOrderService.updateRefundStatus(outRefundNo);
if (null == settlementRefundFee) {
log.info("退款金额为空");
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
}
if (null == outRefundNo) {
log.info("商户退款单号为空");
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
}
if (null == refundId) {
log.info("微信退款单号为空");
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
}
log.info("\n\t----------------------------------------------------------\n\t" +
"订单退款成功" +
"\n\t----------------------------------------------------------");
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
} catch (Exception e) {
e.printStackTrace();
log.info("退款回调失败");
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
}
}
public String decryptData(String decryptData) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(MD5Util.MD5Encode(WxConfigUtil.API_KEY, "UTF-8").toLowerCase().getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] buffer = Base64.getDecoder().decode(decryptData);
return new String(cipher.doFinal(buffer), "UTF-8");
}
/**
* @支付成功回调处理
......
......@@ -16,6 +16,7 @@ public class WxConfigUtil {
public final static String PROFIT_SHARING_URL = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing";
public final static String PROFIT_SHARING_ADDRECEIVER = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver";
public final static String notify_url = "http://1.15.43.240:8330/wx/notify"; // 订单回调接口
public final static String refund_notify_url = "http://1.15.43.240:8330/wx/wxRefundNotify"; // 订单回调接口
public final static String REFUND_ORDER_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
public static String GET_MINICODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
......
......@@ -10,13 +10,14 @@
(select max(product_price) from group_buy_product where group_buy_id = a.id) maxPrice
from group_buy a
<where>
group_status &lt;&gt; 5
<if test="groupBuyCode != null and groupBuyCode != ''">
and group_buy_code = #{groupBuyCode,jdbcType=VARCHAR}
</if>
<if test="groupBuyTitle != null and groupBuyTitle != ''">
and group_buy_title like concat('%', #{groupBuyTitle,jdbcType=VARCHAR},'%')
</if>
<if test="appFlag != null and appFlag = ''">
<if test="appFlag != null and appFlag != ''">
and group_status = 3
</if>
</where>
......@@ -28,4 +29,12 @@
set end_time = #{endTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=BIGINT}
</update>
<update id="activityFailure">
update group_buy set group_status = 4 where end_time &lt;= now();
</update>
<update id="updateStatus">
update group_buy set group_status =5 where id = #{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
......@@ -12,7 +12,7 @@
</foreach>
</insert>
<select id="getList" resultType="com.yunniu.farming.webadmin.model.Product">
<select id="getProductList" resultType="com.yunniu.farming.webadmin.model.Product">
select gbp.product_price,
p.id,
p.sshortpic,
......@@ -28,4 +28,5 @@
where gbp.group_buy_id = #{id,jdbcType=BIGINT}
and gbp.status = 0
</select>
</mapper>
\ No newline at end of file
......@@ -64,4 +64,8 @@
<update id="updateStatus">
update group_order set group_status = 1 where id = #{groupOrderId,jdbcType=BIGINT}
</update>
<select id="getBySdef1" resultType="com.yunniu.farming.webadmin.model.OrderMain">
select * from order_main where sdef1 = #{outRefundNo,jdbcType=VARCHAR}
</select>
</mapper>
\ No newline at end of file
......@@ -50,20 +50,21 @@
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red">*</span>团购活动有效期</label>
<div class="layui-input-inline">
<input type="date" class="layui-input" name="startDate" id="startDate" th:value="${obj.startDate}" required="required">
<input type="date" class="layui-input" name="startDate" id="startDate" th:value="${obj.startDate}"
required="required">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="date" class="layui-input" name="endDate" id="endDate" th:value="${obj.endDate}" required="required">
<input type="date" class="layui-input" name="endDate" id="endDate" th:value="${obj.endDate}"
required="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red">*</span>配送小区</label>
<div class="layui-input-inline">
<select name="areaIdList" id="areaIdList" lay-filter="areaIdList" multiple>
<select name="areaIdList" id="areaIdList" lay-filter="areaIdList" >
<option th:each="list:${areaList}" th:value="${list.id}"
th:text="${list.areaName }"
th:selected="${list.id}==${obj.id}"></option>
th:text="${list.areaName }"></option>
</select>
</div>
<label class="layui-form-label">简介</label>
......@@ -141,7 +142,7 @@
UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
UE.Editor.prototype.getActionUrl = function (action) {
if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
return "http://1.15.43.240:8330/product/uploads";
return "https://farming.nyinhong.com/product/uploads";
// return "https://127.0.0.1/goods/uploads";
} else if (action == 'listimage') {
return this._bkGetActionUrl.call(this, action);
......@@ -149,6 +150,35 @@
return this._bkGetActionUrl.call(this, action);
}
}
// 设置默认选中项
var selectedValues = [];
if (id) {
selectedValues = JSON.parse('[[${obj.areaIdList}]]');
// 获取下拉框元素
var select = document.getElementById('areaIdList');
// 遍历下拉框选项,设置选中状态
for (var i = 0; i < select.options.length; i++) {
if (selectedValues.includes(parseInt(select.options[i].value))) {
select.options[i].selected = true;
}
}
}
layui.use('form', function() {
var form = layui.form;
form.render('select');
// 监听 select 元素的 change 事件
form.on('select(areaIdList)', function(data) {
if (selectedValues.includes(parseInt(data.value))){
var index = selectedValues.indexOf(parseInt(data.value));
selectedValues.splice(index, 1);
}else {
selectedValues.push(parseInt(data.value));
}
console.log(selectedValues); // 打印选中的值
});
});
var groupBuyPic;
layui.use('upload', function () {
var upload = layui.upload;
......@@ -190,10 +220,10 @@
$(function () {
if (id) {
console.log("===========================",'[[${obj}]]')
console.log("===========================", '[[${obj}]]')
showPic('[[${obj.groupBuyPic}]]');
showTable('[[${obj.productList}]]');
console.log(111111111,selectedData)
console.log(111111111, selectedData)
renderTable();
}
});
......@@ -201,6 +231,9 @@
window.addEventListener('message', function (event) {
console.log(event);
selectedData = event.data;
for (var i = 0; i < selectedData.length; i++) {
selectedData[i].productPrice = selectedData[i].productPrice || selectedData[i].dsaleprice;
}
renderTable();
}, false);
......@@ -281,7 +314,6 @@
}
function save() {
console.log(11111111111, groupBuyPic);
if ($("#formId input[name='groupBuyTitle']").val() == '') {
layer.msg("活动标题不能为空!");
return false;
......@@ -368,7 +400,7 @@
processData: false,
contentType: "application/json",
success: function (result) {
if (result.code == 100) {
if (result.code === 100) {
layer.msg(result.msg, {icon: 6, time: 1000}, function () {
closeLayer();
parent.layui.table.reload('tableId');
......@@ -400,15 +432,17 @@
}
function showPic(groupPic) {
groupBuyPic = groupPic;
$('#previewImg').attr('src', groupPic);
}
function showTable(products) {
console.log(44444444444, products)
const newStr = products.replace(/&quot;/g, '"');
console.log(3333333333, newStr)
selectedData = JSON.parse(newStr)
for (var i = 0; i < selectedData.length; i++) {
selectedData[i].productPrice = selectedData[i].productPrice || '';
}
console.log(222222222, selectedData)
}
layui.use('form', function () {
......
......@@ -262,7 +262,7 @@
if (obj.event === 'del') {
layer.confirm('删除后无法撤销,确定继续吗?', function (index) {
$.ajax({
url: "/product/"+obj.data.id+"/deleteById",
url: ""+obj.data.id+"/deleteById",
type: "GET",
dataType: "json",
success: function (result) {
......
......@@ -25,11 +25,11 @@
<div class="layadmin-user-login-box layadmin-user-login-body layui-form">
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-username"></label>
<input type="text" name="username" id="account" placeholder="账号" value="123456" class="layui-input" >
<input type="text" name="username" id="account" placeholder="账号" class="layui-input" >
</div>
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-password"></label>
<input type="password" name="password" id="password" placeholder="密码" value="123456" class="layui-input"
<input type="password" name="password" id="password" placeholder="密码" class="layui-input"
>
</div>
<div class="layui-form-item">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment