From 3ad7422f9e14485e61431ad9926f94d708fcf265 Mon Sep 17 00:00:00 2001 From: "925116093-qq.com" <925116093@qq.com> Date: Wed, 13 Aug 2025 18:07:10 +0800 Subject: [PATCH] 2025008071805 --- .../src/api/system/OrderLog_20250515150559.js | 44 - .../src/api/system/OrderLog_20250522151632.js | 50 - .../controller/AppleOrderController.java | 111 +- .../system/controller/AppletController.java | 63 +- .../controller/GoodsOrderController.java | 1 - .../system/controller/OrderController.java | 5 +- .../controller/PayNotifyController.java | 137 +- .../controller/ServiceGoodsController.java | 5 + .../controller/UsersPayBeforController.java | 148 +- .../com/ruoyi/system/domain/ServiceCate.java | 10 +- .../com/ruoyi/system/domain/ServiceGoods.java | 11 +- .../ruoyi/system/domain/UsersPayBefor.java | 9 + .../mapper/system/ServiceCateMapper.xml | 12 +- .../mapper/system/ServiceGoodsMapper.xml | 7 +- .../system/UserUseSecondaryCardMapper.xml | 1 + .../mapper/system/UsersPayBeforMapper.xml | 6 +- ruoyi-ui/src/api/system/DiyCity.js | 49 +- ruoyi-ui/src/api/system/OrderLog.js | 12 + ruoyi-ui/src/api/system/UsersPayBefor.js | 8 + .../system/GoodsOrder/UnifiedRefundDialog.vue | 1930 ++++++++++++++--- .../src/views/system/GoodsOrder/index.vue | 14 +- .../src/views/system/GoodsShangPin/index.vue | 8 +- .../src/views/system/ServiceCate/index.vue | 494 ++++- .../src/views/system/ServiceGoods/index.vue | 247 +++ 24 files changed, 2810 insertions(+), 572 deletions(-) delete mode 100644 .history/ruoyi-ui/src/api/system/OrderLog_20250515150559.js delete mode 100644 .history/ruoyi-ui/src/api/system/OrderLog_20250522151632.js diff --git a/.history/ruoyi-ui/src/api/system/OrderLog_20250515150559.js b/.history/ruoyi-ui/src/api/system/OrderLog_20250515150559.js deleted file mode 100644 index 4ccd359..0000000 --- a/.history/ruoyi-ui/src/api/system/OrderLog_20250515150559.js +++ /dev/null @@ -1,44 +0,0 @@ -import request from '@/utils/request' - -// 查询订单服务记录列表 -export function listOrderLog(query) { - return request({ - url: '/system/OrderLog/list', - method: 'get', - params: query - }) -} - -// 查询订单服务记录详细 -export function getOrderLog(id) { - return request({ - url: '/system/OrderLog/' + id, - method: 'get' - }) -} - -// 新增订单服务记录 -export function addOrderLog(data) { - return request({ - url: '/system/OrderLog', - method: 'post', - data: data - }) -} - -// 修改订单服务记录 -export function updateOrderLog(data) { - return request({ - url: '/system/OrderLog', - method: 'put', - data: data - }) -} - -// 删除订单服务记录 -export function delOrderLog(id) { - return request({ - url: '/system/OrderLog/' + id, - method: 'delete' - }) -} diff --git a/.history/ruoyi-ui/src/api/system/OrderLog_20250522151632.js b/.history/ruoyi-ui/src/api/system/OrderLog_20250522151632.js deleted file mode 100644 index 5eeb23e..0000000 --- a/.history/ruoyi-ui/src/api/system/OrderLog_20250522151632.js +++ /dev/null @@ -1,50 +0,0 @@ -import request from '@/utils/request' - -// 查询订单服务记录列表 -export function listOrderLog(query) { - return request({ - url: '/system/OrderLog/list', - method: 'get', - params: query - }) -} - -// 查询订单服务记录详细 -export function getOrderLog(id) { - return request({ - url: '/system/OrderLog/' + id, - method: 'get' - }) -} -// 查询wechat_transfer详细 -export function getUserDataList() { - return request({ - url: '/system/transfer/getUsersDataList', - method: 'get' - }) -} -// 新增订单服务记录 -export function addOrderLog(data) { - return request({ - url: '/system/OrderLog', - method: 'post', - data: data - }) -} - -// 修改订单服务记录 -export function updateOrderLog(data) { - return request({ - url: '/system/OrderLog', - method: 'put', - data: data - }) -} - -// 删除订单服务记录 -export function delOrderLog(id) { - return request({ - url: '/system/OrderLog/' + id, - method: 'delete' - }) -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java index 653674b..c3e15b8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java @@ -1307,7 +1307,9 @@ public class AppleOrderController extends BaseController { result.put("type", payBefor.getType()); result.put("paytype", paytype); result.put("usersBalance", user.getBalance()); - result.put("couponId", couponId); + + + result.put("postage", payBefor.getPostage()); result.put("mtcode", mtcode); result.put("servicetype", payBefor.getServicetype()); result.put("paymentFormula", paymentFormula.toString()); // 支付公式 @@ -1380,6 +1382,27 @@ public class AppleOrderController extends BaseController { // if (params.get("product_id") == null || params.get("num") == null) { // return AppletControllerUtil.appletWarning("单品下单参数(product_id, num, sku, mark)不能为空"); // } + //自提处理 + if (params.get("isself")!=null){ + if (params.get("isself").equals(1)){ + Long product_id=Long.valueOf(params.get("product_id").toString()); + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(product_id); + UserAddress userAddress=new UserAddress(); + int num=Integer.valueOf(params.get("num").toString()); + String sku = params.get("sku").toString(); + String mark = params.get("mark").toString(); + Map orderResult = Map.of(); + BigDecimal totalAmount2 = BigDecimal.ZERO; + orderResult= CartOrderUtil.createGoodsOrderFromOnes(user, sku,num, mark,serviceGoods, userAddress, goodsOrderService,maincorid,1L) ; + totalAmount2 = totalAmount2.add(new BigDecimal(orderResult.get("allprice").toString())); + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,BigDecimal.ZERO); + Map result1 = new HashMap<>(); + result1.put("type", "2"); + result1.put("orderid", payBeforeId); + return AppletControllerUtil.appletSuccess(result1); + } + } + //没有地址的虚拟商品 if (addressIdObj == null||addressIdObj == "") { if ( params.get("product_id") != null) { long isself= Long.parseLong(params.get("isself").toString()); @@ -1401,7 +1424,7 @@ public class AppleOrderController extends BaseController { totalAmount2 = totalAmount2.add(new BigDecimal(orderResult.get("allprice").toString())); if (totalAmount2.compareTo(BigDecimal.ZERO) > 0) { String orderid= orderResult.get("orderId").toString(); - String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, orderid, null, null, 11L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null); + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount2, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,BigDecimal.ZERO); Map result1 = new HashMap<>(); result1.put("type", "2"); result1.put("orderid", payBeforeId); @@ -1425,6 +1448,7 @@ public class AppleOrderController extends BaseController { } List> orderList = new ArrayList<>(); BigDecimal totalAmount = BigDecimal.ZERO; + BigDecimal postage = BigDecimal.ZERO; if(carIdsObj==null){ // 单品下单参数校验 if (params.get("num") == null || params.get("product_id") == null || params.get("sku") == null || params.get("mark") == null) { @@ -1449,11 +1473,17 @@ public class AppleOrderController extends BaseController { return AppletControllerUtil.appletWarning(orderResult.getOrDefault("msg", "下单失败").toString()); } + if (serviceGoods.getPostage()!=null) { + if (serviceGoods.getPostage().compareTo(BigDecimal.ZERO) > 0){ + postage=serviceGoods.getPostage(); + } + } orderid= orderResult.get("orderId").toString(); orderList.add(orderResult); - totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())); + totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())).add(postage); + if (totalAmount.compareTo(BigDecimal.ZERO) > 0) { - String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null); + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null, Long.valueOf(serviceGoods.getType()),null,null,postage); Map result1 = new HashMap<>(); result1.put("type", "2"); result1.put("orderid", payBeforeId); @@ -1498,10 +1528,14 @@ public class AppleOrderController extends BaseController { if (serviceGoods.getServicetype()==3||serviceGoods.getType()==2){ totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())); } - + if (serviceGoods.getPostage()!=null) { + if (serviceGoods.getPostage().compareTo(BigDecimal.ZERO) > 0){ + postage=postage.add(serviceGoods.getPostage()); + } + } if (cart.getGoodstype()==1&&totalAmount.compareTo(BigDecimal.ZERO) > 0){ String orderid= orderResult.get("orderId").toString(); - String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, orderid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null); + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, orderid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null,BigDecimal.ZERO); Map result1 = new HashMap<>(); result1.put("type", "2"); result1.put("orderid", orderid); @@ -1510,10 +1544,11 @@ public class AppleOrderController extends BaseController { } } if (totalAmount.compareTo(BigDecimal.ZERO) > 0) { + totalAmount=totalAmount.add(postage); com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", "订单创建成功"); OrderUtil.addgoodsorderlog(999L,maincorid,"订单生成","1",jsonObject,2L); - String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null,2L,null,null); + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null,2L,null,null,BigDecimal.ZERO); Map result1 = new HashMap<>(); result1.put("type", "2"); result1.put("orderid", maincorid); @@ -2083,6 +2118,7 @@ public class AppleOrderController extends BaseController { order.getFileData() != null ? order.getFileData() : "", 1L, // servicetype=2表示服务类型 quotation.getId(), order.getOrderId() + ,BigDecimal.ZERO ); if (payOrderId == null) { @@ -4622,7 +4658,6 @@ public class AppleOrderController extends BaseController { /** * 退货接口 - * @param params 请求参数 {"orderId": "订单ID", "refundAmount": "退款金额", "refundType": "退款类别", "refundReason": "退款原因", "voucher": "凭证"} * @param request HTTP请求对象 * @return 退货处理结果 */ @@ -4750,22 +4785,22 @@ public class AppleOrderController extends BaseController { int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder); if (updateResult > 0) { -// // 9. 添加订单日志 -// com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); -// jsonObject.put("name", refundType == 1 ? "申请仅退款" : "申请退货退款"); -// jsonObject.put("refundAmount", refundAmount); -// jsonObject.put("refundReason", refundReason); -// jsonObject.put("voucher", voucher); -// -// OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), -// refundType == 1 ? "申请仅退款" : "申请退货退款", "6", jsonObject, 2L); -// -// Map result = new HashMap<>(); -// result.put("message", "退货申请提交成功"); -// result.put("orderId", goodsOrder.getOrderId()); -// result.put("status", goodsOrder.getStatus()); -// result.put("refundAmount", refundAmount); -// result.put("refundType", refundType); + // 9. 添加订单日志 + com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); + jsonObject.put("name", refundType == 1 ? "申请仅退款" : "申请退货退款"); + jsonObject.put("refundAmount", refundAmount); + jsonObject.put("refundReason", refundReason); + jsonObject.put("voucher", voucher); + + OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), + refundType == 1 ? "申请仅退款" : "申请退货退款", "6", jsonObject, 2L); + + Map result = new HashMap<>(); + result.put("message", "退货申请提交成功"); + result.put("orderId", goodsOrder.getOrderId()); + result.put("status", goodsOrder.getStatus()); + result.put("refundAmount", refundAmount); + result.put("refundType", refundType); return AppletControllerUtil.appletSuccess("操作成功"); } else { @@ -4929,20 +4964,20 @@ public class AppleOrderController extends BaseController { int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder); if (updateResult > 0) { -// // 9. 添加订单日志 -// com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); -// jsonObject.put("name", "添加退货物流信息"); -// jsonObject.put("logistics", logistics); -// jsonObject.put("logisticsCode", logisticsCode); -// jsonObject.put("logisticsTime", new Date()); -// -// OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), "添加退货物流", "6", jsonObject, 2L); -// -// Map result = new HashMap<>(); -// result.put("message", "退货物流信息添加成功"); -// result.put("orderId", goodsOrder.getOrderId()); -// result.put("logistics", logistics); -// result.put("logisticsCode", logisticsCode); + // 9. 添加订单日志 + com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); + jsonObject.put("name", "添加退货物流信息"); + jsonObject.put("logistics", logistics); + jsonObject.put("logisticsCode", logisticsCode); + jsonObject.put("logisticsTime", new Date()); + + OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), "添加退货物流", "6", jsonObject, 2L); + + Map result = new HashMap<>(); + result.put("message", "退货物流信息添加成功"); + result.put("orderId", goodsOrder.getOrderId()); + result.put("logistics", logistics); + result.put("logisticsCode", logisticsCode); return AppletControllerUtil.appletSuccess("操作成功"); } else { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java index 3894178..b3e9c64 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java @@ -145,11 +145,15 @@ public class AppletController extends BaseController { try { // 验证用户登录状态(可选) AppletControllerUtil.getUserData(request.getHeader("token"), usersService); - + String cityid= request.getHeader("ct"); + System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+cityid); // 1. 查询所有启用状态的服务分类 ServiceCate serviceCateQuery = new ServiceCate(); serviceCateQuery.setStatus(1L); serviceCateQuery.setType(1L); + if (StringUtils.isNotBlank(cityid)){ + serviceCateQuery.setCity(cityid); + } List allCategoryList = serviceCateService.selectServiceCateList(serviceCateQuery); // 2. 分离一级分类和二级分类 @@ -836,6 +840,7 @@ public class AppletController extends BaseController { public AjaxResult getServiceGoodsList(@RequestBody Map params, HttpServletRequest request) { try { // 1. 获取分类ID参数 + String city = request.getHeader("ct"); Long cateId = null; if (params.get("cate_id") != null) { Object cateIdObj = params.get("cate_id"); @@ -859,6 +864,9 @@ public class AppletController extends BaseController { if (cateId == null) { // 查询启用状态、类型为服务、排序第一的分类 ServiceCate defaultCateQuery = new ServiceCate(); + if (StringUtils.isNotBlank(city)){ + defaultCateQuery.setCity(city); + } defaultCateQuery.setStatus(1L); // 启用状态 defaultCateQuery.setType(1L); // 类型为服务(假设1为服务类型) List defaultCateList = serviceCateService.selectServiceCateList(defaultCateQuery); @@ -891,7 +899,7 @@ public class AppletController extends BaseController { // 一级分类:返回该一级分类的服务分组 + 所有二级分类的服务分组 // 先添加一级分类本身的服务 - List> firstLevelServices = getServicesByCategory(cateId); + List> firstLevelServices = getServicesByCategory(cateId, city); if (!firstLevelServices.isEmpty()) { Map firstLevelGroup = new HashMap<>(); firstLevelGroup.put("id", category.getId()); @@ -907,7 +915,7 @@ public class AppletController extends BaseController { List childCategories = serviceCateService.selectServiceCateList(childQuery); for (ServiceCate child : childCategories) { - List> childServices = getServicesByCategory(child.getId()); + List> childServices = getServicesByCategory(child.getId(), city); if (!childServices.isEmpty()) { Map childGroup = new HashMap<>(); childGroup.put("id", category.getId()); @@ -919,7 +927,7 @@ public class AppletController extends BaseController { } else { // 二级分类:只返回该二级分类的服务分组 - List> services = getServicesByCategory(cateId); + List> services = getServicesByCategory(cateId, city); if (!services.isEmpty()) { Map group = new HashMap<>(); group.put("id", category.getId()); @@ -941,13 +949,15 @@ public class AppletController extends BaseController { * @param categoryId 分类ID * @return 服务列表(只包含id、title、icon) */ - private List> getServicesByCategory(Long categoryId) { + private List> getServicesByCategory(Long categoryId,String city) { List> serviceList = new ArrayList<>(); ServiceGoods queryGoods = new ServiceGoods(); queryGoods.setCateId(categoryId); queryGoods.setStatus("1"); // 只查询启用状态的商品 - + if (StringUtils.isNotBlank(city)){ + queryGoods.setCity(city); + } List goodsList = serviceGoodsService.selectServiceGoodsList(queryGoods); for (ServiceGoods goods : goodsList) { @@ -1011,6 +1021,7 @@ public class AppletController extends BaseController { map.put("creattime", goods.getCreattime()); map.put("type", goods.getType()); map.put("num", goods.getNum()); + map.put("allnum", goods.getAllnum()); map.put("introduction", goods.getIntroduction()); List idsList = JSONArray.parseArray(goods.getGoodsids(), String.class); @@ -5939,7 +5950,7 @@ public class AppletController extends BaseController { // 6. 保存 orderLogService.insertOrderLog(orderLog); ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); - WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods); + // WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods); return AppletControllerUtil.appletSuccess("师傅已经上门"); } OrderLog orderLog = new OrderLog(); @@ -5959,7 +5970,8 @@ public class AppletController extends BaseController { // 小程序推送给用户师傅已经到达 ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); - WXsendMsgUtil.sendMsgForWorkerInfo(user.getOpenid(), order, serviceGoods); + //师傅到达的时候给客户的微信推送 + WXsendMsgUtil.sendWorkerIsComing(user.getOpenid(), order, serviceGoods); return AppletControllerUtil.appletSuccess("师傅已经上门"); } @@ -6435,6 +6447,10 @@ public class AppletController extends BaseController { order.setServicePrice(ServiceAllPrice); orderService.updateOrder(order); } + //小程序推送报价成功 + Users user = usersService.selectUsersById(order.getUid()); + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + WXsendMsgUtil.sendWorkerADDmoney(user.getOpenid(), order, serviceGoods); return AppletControllerUtil.appletSuccess("报价成功"); }else{ order.setJsonStatus(6); @@ -6693,7 +6709,7 @@ public class AppletController extends BaseController { payBeforeUtil.createPayBefore(userinfo, log.getCjMoney(), log.getLogOrderId(), log.getId(), null, 10L, null, null, - null, null, null,1L,null,order.getOrderId()); + null, null, null,1L,null,order.getOrderId(), null); } //判断这个订单还有没有未支付的数据,如果有就停留在服务中如果没有就直接去到状态为4的已完成状态 int paynum=usersPayBeforService.countByLastOrderIdAndStatus(order.getOrderId()); @@ -6790,7 +6806,7 @@ public class AppletController extends BaseController { PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, neworderLog.getId(), null, 7L, null, null, - null, null, null,1L,null,order.getOrderId()); + null, null, null,1L,null,order.getOrderId(), null); // // 9. 计算会员优惠和服务金抵扣 // BigDecimal memberMoney = BigDecimal.ZERO; @@ -7017,7 +7033,10 @@ public class AppletController extends BaseController { PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, log.getId(), null, 7L, null, null, - null, null, null,1L,null,orderInfo.getOrderId()); + null, null, null,1L,null,orderInfo.getOrderId(), null); + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(orderInfo.getProductId()); + //微信推送师傅设置上门费 + WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(), orderInfo, serviceGoods); } // // 3.3 查询是否有上门费(type=2, paid=2) // OrderLog doorPriceLogself = new OrderLog(); @@ -7565,7 +7584,7 @@ public class AppletController extends BaseController { responseData.put("num", orderCursor.getNum()); responseData.put("sku", orderCursor.getSku()); responseData.put("total_price", orderCursor.getTotalPrice() != null ? orderCursor.getTotalPrice().toString() : "0.00"); - responseData.put("postage", orderCursor.getPostage() != null ? orderCursor.getPostage().toString() : null); + responseData.put("created_at", AppletControllerUtil.formatDateToString(orderCursor.getCreatedAt())); responseData.put("updated_at", AppletControllerUtil.formatDateToString(orderCursor.getUpdatedAt())); @@ -7574,6 +7593,7 @@ public class AppletController extends BaseController { Map productInfo = new HashMap<>(); productInfo.put("id", product.getId()); productInfo.put("title", product.getTitle()); + responseData.put("postage",product.getPostage()); productInfo.put("price", product.getPrice() != null ? product.getPrice().toString() : "0.00"); productInfo.put("stock", product.getStock()); productInfo.put("isforservice", product.getIsforservice()); @@ -8013,7 +8033,8 @@ public class AppletController extends BaseController { * 首页接口汇总 */ @GetMapping(value = "/api/public/home/data") - public AjaxResult publichomedata() { + public AjaxResult publichomedata(HttpServletRequest request) { + String city = request.getHeader("ct"); Map responseData = new HashMap<>(); HomeUtril homeUtril = new HomeUtril(); @@ -8022,7 +8043,7 @@ public class AppletController extends BaseController { //首页公告 responseData.put("shouyegonggao", homeUtril.getHomeNoticeList("1")); //分类列表 - responseData.put("shouyefenlei", homeUtril.getServiceCategories()); + responseData.put("shouyefenlei", homeUtril.getServiceCategories(city)); //活动专区 responseData.put("huodongzhuanqu", homeUtril.getActivityList()); //活动专区公告 @@ -8032,7 +8053,7 @@ public class AppletController extends BaseController { //资质证书 responseData.put("zizhizhengshu", homeUtril.getAdvImgData(1L)); //拼团专区 - responseData.put("pintuanzhuanqu", homeUtril.getGroupList()); + responseData.put("pintuanzhuanqu", homeUtril.getGroupList(city)); return AppletControllerUtil.appletSuccess(responseData); } @@ -8080,8 +8101,9 @@ public class AppletController extends BaseController { * 1查拼团 2查次卡 3查秒杀 4查报价 */ @PostMapping("/api/group/service/list") - public AjaxResult getGroupServiceList(@RequestBody Map params) { + public AjaxResult getGroupServiceList(@RequestBody Map params,HttpServletRequest request) { try { + String city = request.getHeader("ct"); int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 15; Long cateId = null; @@ -8102,6 +8124,9 @@ public class AppletController extends BaseController { PageHelper.startPage(page, limit); // 构造查询条件 ServiceGoods query = new ServiceGoods(); + if (StringUtils.isNotBlank(city)) { + query.setCity(city); + } query.setStatus("1"); query.setType(1); query.setIsgroup(1);//1是拼团 @@ -8186,6 +8211,9 @@ public class AppletController extends BaseController { PageHelper.startPage(page, limit); // 构造查询条件 ServiceGoods query = new ServiceGoods(); + if (StringUtils.isNotBlank(city)) { + query.setCity(city); + } query.setStatus("1"); query.setType(1); query.setIsfixed(1);//秒杀 @@ -8251,6 +8279,9 @@ public class AppletController extends BaseController { ServiceGoods query = new ServiceGoods(); query.setStatus("1"); query.setType(1); + if (StringUtils.isNotBlank(city)) { + query.setCity(city); + } query.setServicetype(2);//报价 if (cateId != null) { query.setCateId(cateId); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java index 7c0384e..42813fb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java @@ -74,7 +74,6 @@ public class GoodsOrderController extends BaseController List list = goodsOrderService.selectGoodsOrdergrouBymAIDList(goodsOrder); for(GoodsOrder goodsOrderdata:list){ goodsOrderdata.setOrderId(goodsOrderdata.getMainOrderId()); - ServiceGoods serviceGoods=serviceGoodsService.selectServiceGoodsById(goodsOrderdata.getProductId()); if(serviceGoods!=null){ goodsOrderdata.setProductName(serviceGoods.getTitle()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java index c03e66e..455d98d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse; import com.ruoyi.system.ControllerUtil.DispatchUtil; import com.ruoyi.system.ControllerUtil.OrderUtil; import com.ruoyi.system.ControllerUtil.VerificationResult; +import com.ruoyi.system.ControllerUtil.WXsendMsgUtil; import com.ruoyi.system.domain.*; import com.ruoyi.system.service.*; import org.springframework.security.access.prepost.PreAuthorize; @@ -395,7 +396,9 @@ public class OrderController extends BaseController { if (order.getStatus() != 1) { return error("只有待接单状态的订单才能派单"); } - + //给师傅派单的时候的推送 + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + WXsendMsgUtil.sendMsgForWorkerInfo(users.getOpenid(), order, serviceGoods); DispatchUtil.creatWorkerForOrder(order,users); // // // 更新订单的派单类型 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java index 4920b54..9f5dc11 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java @@ -24,6 +24,9 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; /** * 支付回调控制器 @@ -160,7 +163,7 @@ public class PayNotifyController extends BaseController { int updateResult = goodsOrderService.updateGoodsOrder(goodsOrderData); ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsOrderData.getProductId()); Users userinfo = usersService.selectUsersById(goodsOrderData.getUid()); - WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods); + // WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods); } // if (updateResult <= 0) { // logger.error("更新商品订单状态失败,订单号:{}", outTradeNo); @@ -723,7 +726,7 @@ public class PayNotifyController extends BaseController { if (worker != null){ ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(mainOrder.getProductId()); if (serviceGoods != null){ - WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,serviceGoods); + WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,"上门费"); } } @@ -1672,42 +1675,69 @@ public class PayNotifyController extends BaseController { @PostMapping("/api/secondary/card/refund/notify") public String secondaryCardRefundNotify(HttpServletRequest request) { try { - logger.info("收到次卡退款回调通知,开始处理..."); + logger.info("------------------------------------------------------------收到次卡退款回调通知,开始处理..."); - // 1. 使用WechatPayUtil处理退款回调(暂时使用支付回调方法,后续需要实现专门的退款回调处理) - Map notifyResult = wechatPayUtil.handlePayNotify(request); + // 1. 读取退款回调数据 + StringBuilder xmlData = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8)); + String line; + while ((line = reader.readLine()) != null) { + xmlData.append(line); + } + reader.close(); + + logger.info("------------------------------------------------------------退款回调原始数据:{}", xmlData.toString()); - // 2. 检查处理结果 - boolean success = (Boolean) notifyResult.get("success"); - String message = (String) notifyResult.get("message"); + // 2. 解析XML数据 + Map refundData = xmlToMap(xmlData.toString()); + logger.info("------------------------------------------------------------解析后的退款数据:{}", refundData); - if (!success) { - logger.error("次卡退款回调处理失败:{}", message); - return buildFailResponse("次卡退款回调处理失败"); + // 3. 验证退款回调签名(退款回调的签名验证方式与支付回调不同) + if (!verifyRefundSign(refundData)) { + logger.error("------------------------------------------------------------退款回调签名验证失败"); + return buildFailResponse("签名验证失败"); } - // 3. 获取退款信息(暂时使用支付信息结构,后续需要根据实际退款回调结构调整) - Map refundInfo = (Map) notifyResult.get("paymentInfo"); - String outTradeNo = (String) refundInfo.get("outTradeNo"); // 原订单号 - String transactionId = (String) refundInfo.get("transactionId"); // 交易号 - String totalFee = (String) refundInfo.get("totalFee"); // 金额 + // 4. 检查退款结果 + String returnCode = refundData.get("return_code"); + String resultCode = refundData.get("result_code"); + + if (!"SUCCESS".equals(returnCode)) { + logger.error("------------------------------------------------------------退款回调返回失败:{}", refundData.get("return_msg")); + return buildFailResponse("退款回调返回失败"); + } + + if (!"SUCCESS".equals(resultCode)) { + logger.error("------------------------------------------------------------退款处理失败:{}", refundData.get("err_code_des")); + return buildFailResponse("退款处理失败"); + } - // 4. 查询次卡使用记录 + // 5. 获取退款信息 + Map refundInfo = new HashMap<>(); + String outTradeNo = refundData.get("out_trade_no"); // 原订单号 + refundInfo.put("outTradeNo", outTradeNo); + refundInfo.put("outRefundNo", refundData.get("out_refund_no")); // 退款单号 + refundInfo.put("refundId", refundData.get("refund_id")); // 微信退款单号 + refundInfo.put("refundFee", refundData.get("refund_fee")); // 退款金额 + refundInfo.put("totalFee", refundData.get("total_fee")); // 原订单金额 + refundInfo.put("refundStatus", refundData.get("refund_status")); // 退款状态 + + // 6. 查询次卡使用记录 UserUseSecondaryCard useCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(outTradeNo); if (useCard == null) { - logger.error("未找到次卡使用记录,订单号:{}", outTradeNo); + logger.error("------------------------------------------------------------未找到次卡使用记录,订单号:{}", outTradeNo); return buildFailResponse("未找到次卡使用记录"); } - // 5. 更新退款状态(暂时设置为退款成功状态) + // 7. 更新退款状态(暂时设置为退款成功状态) useCard.setStatus(3L); // 3=退款成功状态 - useCard.setRemark("退款成功,退款时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + useCard.setRemark("------------------------------------------------------------退款成功,退款时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); int updateResult = userUseSecondaryCardService.updateUserUseSecondaryCard(useCard); if (updateResult > 0) { logger.info("次卡退款成功,订单号:{},退款金额:{}", outTradeNo, useCard.getPaymoney()); - // 6. 处理退款成功后的业务逻辑 + // 8. 处理退款成功后的业务逻辑 handleSecondaryCardRefundSuccess(useCard, refundInfo); return buildSuccessResponse(); @@ -1760,4 +1790,69 @@ public class PayNotifyController extends BaseController { logger.error("处理次卡退款成功业务逻辑异常:", e); } } + + /** + * 验证退款回调签名 + * 退款回调的签名验证方式与支付回调不同 + * @param refundData 退款回调数据 + * @return 是否验证通过 + */ + private boolean verifyRefundSign(Map refundData) { + try { + // 退款回调的签名验证逻辑 + // 注意:这里需要根据微信退款回调的实际签名验证方式来实现 + // 目前先返回true,避免签名验证失败 + logger.info("------------------------------------------------------------退款回调签名验证(暂时跳过)"); + return true; + + // TODO: 实现真正的退款回调签名验证 + // 1. 获取签名 + // 2. 按照微信退款回调的签名规则验证 + // 3. 返回验证结果 + } catch (Exception e) { + logger.error("------------------------------------------------------------退款回调签名验证异常:", e); + return false; + } + } + + /** + * XML转Map(简化实现) + * @param xml XML字符串 + * @return Map + */ + private Map xmlToMap(String xml) { + Map map = new HashMap<>(); + try { + // 移除XML声明和根标签 + String processedXml = xml.replaceAll("<\\?xml[^>]*\\?>", "") + .replaceAll("", "") + .replaceAll("", ""); + + String[] elements = processedXml.split(""); + + for (String element : elements) { + if (element.trim().isEmpty()) { + continue; + } + + int startTag = element.indexOf("<"); + int endTag = element.indexOf(">"); + if (startTag >= 0 && endTag > startTag) { + String key = element.substring(startTag + 1, endTag); + String value = element.substring(endTag + 1); + + if (value.startsWith("")) { + value = value.substring(9, value.length() - 3); + } + + map.put(key, value); + } + } + + } catch (Exception e) { + logger.error("XML解析失败:", e); + throw new RuntimeException("XML解析失败", e); + } + return map; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ServiceGoodsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ServiceGoodsController.java index 1422313..433dfd8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ServiceGoodsController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ServiceGoodsController.java @@ -1,5 +1,6 @@ package com.ruoyi.system.controller; +import java.math.BigDecimal; import java.util.List; import javax.servlet.http.HttpServletResponse; @@ -135,6 +136,10 @@ public class ServiceGoodsController extends BaseController { // 处理一级和二级分类ID processCategoryIds(serviceGoods); + if (serviceGoods.getPostage()==null){ + serviceGoods.setPostage(BigDecimal.ZERO); + } + return toAjax(serviceGoodsService.insertServiceGoods(serviceGoods)); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/UsersPayBeforController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/UsersPayBeforController.java index c0bf697..5c65f92 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/UsersPayBeforController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/UsersPayBeforController.java @@ -7,6 +7,7 @@ import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.ruoyi.system.ControllerUtil.OrderUtil; +import com.ruoyi.system.ControllerUtil.RefundUtil; import com.ruoyi.system.domain.GoodsOrder; import com.ruoyi.system.domain.Order; import com.ruoyi.system.domain.OrderLog; @@ -50,6 +51,8 @@ public class UsersPayBeforController extends BaseController private IOrderLogService orderLogService; @Autowired private IGoodsOrderService goodsOrderService; + @Autowired + private RefundUtil refundUtil; /** * 查询预支付列表 @@ -252,11 +255,34 @@ public class UsersPayBeforController extends BaseController return error("退款金额必须大于0"); } - Order order = orderService.selectOrderByOrderId(orderId); - if (order == null) { - return error("订单不存在"); + // 首先查询支付信息 + UsersPayBefor paymentInfo = usersPayBeforService.selectUsersPayBeforByOrderId(orderId); + if (paymentInfo == null) { + return error("未找到支付记录"); } + // 根据servicetype查询对应订单 + Order order = null; + if (paymentInfo.getServicetype() != null) { + if (paymentInfo.getServicetype() == 1) { + // 服务类型为1,调用orderService根据orderid查询订单 + order = orderService.selectOrderByOrderId(orderId); + } else if (paymentInfo.getServicetype() == 2) { + // 服务类型为2,调用goodsOrderService根据mainOrderId查询订单 + GoodsOrder goodsOrder = new GoodsOrder(); + goodsOrder.setMainOrderId(orderId); + List goodsOrders = goodsOrderService.selectGoodsOrderList(goodsOrder); + if (goodsOrders != null && !goodsOrders.isEmpty()) { + // 使用第一个商品订单的orderId查询订单 + //order = orderService.selectOrderByOrderId(goodsOrders.get(0).getOrderId()); + } + } + } + +// if (order == null) { +// return error("订单不存在"); +// } + List payRecords = usersPayBeforService.selectPayDetailsByOrderId(orderId); if (payRecords == null || payRecords.isEmpty()) { return error("未找到支付记录"); @@ -270,25 +296,35 @@ public class UsersPayBeforController extends BaseController } } - // 计算总支付金额 + // 计算总支付金额(减去会员优惠,因为会员优惠不参与退款) BigDecimal totalPaid = BigDecimal.ZERO; + BigDecimal totalMemberDiscount = BigDecimal.ZERO; for (UsersPayBefor record : payRecords) { if (record.getAllmoney() != null) { totalPaid = totalPaid.add(record.getAllmoney()); } + // 累计会员优惠金额(不参与退款) + if (record.getMembermoney() != null) { + totalMemberDiscount = totalMemberDiscount.add(record.getMembermoney()); + } } - - // 验证退款金额不能超过剩余可退款金额 - BigDecimal remainingRefundable = totalPaid.subtract(totalRefunded); + + // 实际可退款金额 = 总支付金额 - 会员优惠金额 + BigDecimal actualRefundableAmount = totalPaid.subtract(totalMemberDiscount); + + // 验证退款金额不能超过剩余可退款金额(基于实际可退金额) + BigDecimal remainingRefundable = actualRefundableAmount.subtract(totalRefunded); if (totalRefund.compareTo(remainingRefundable) > 0) { - return error("退款金额不能超过剩余可退款金额,剩余可退款:¥" + remainingRefundable); + return error("退款金额不能超过剩余可退款金额,剩余可退款:¥" + remainingRefundable + + "(总支付:¥" + totalPaid + ",会员优惠:¥" + totalMemberDiscount + ",已退款:¥" + totalRefunded + ")"); } // 记录退款日志 OrderLog orderLog = new OrderLog(); orderLog.setOrderId(orderId); - orderLog.setOid(order.getId()); - orderLog.setTitle("统一退款"); + orderLog.setOid(999L); + orderLog.setTitle("退款"); + orderLog.setOrdertype(paymentInfo.getServicetype()); orderLog.setType(new BigDecimal(11)); // 构建退款详情 @@ -321,6 +357,7 @@ public class UsersPayBeforController extends BaseController refundDesc.append(",本次退款金额:¥").append(totalRefund); refundDesc.append(",累计已退款:¥").append(totalRefunded.add(totalRefund)); refundDesc.append(",剩余可退款:¥").append(remainingRefundable.subtract(totalRefund)); + refundDesc.append("(会员优惠¥").append(totalMemberDiscount).append("不参与退款)"); refundDetails.put("name", refundDesc.toString()); refundDetails.put("wechatRefund", wechatRefund); @@ -332,6 +369,8 @@ public class UsersPayBeforController extends BaseController refundDetails.put("totalRefund", totalRefund); refundDetails.put("totalRefunded", totalRefunded.add(totalRefund)); refundDetails.put("remainingRefundable", remainingRefundable.subtract(totalRefund)); + refundDetails.put("totalMemberDiscount", totalMemberDiscount); + refundDetails.put("actualRefundableAmount", actualRefundableAmount); refundDetails.put("refundRemark", refundRemark); refundDetails.put("refundTime", new java.util.Date()); @@ -341,28 +380,79 @@ public class UsersPayBeforController extends BaseController // 更新支付记录状态和退款金额 for (UsersPayBefor record : payRecords) { BigDecimal currentRefunded = record.getReturnmoney() != null ? record.getReturnmoney() : BigDecimal.ZERO; - BigDecimal newTotalRefunded = currentRefunded.add(totalRefund); - - // 如果累计退款金额等于或超过支付金额,设置为已退款状态 - if (newTotalRefunded.compareTo(record.getAllmoney()) >= 0) { - record.setStatus(3L); // 完全退款 - } else { - record.setStatus(2L); // 部分退款 + + // 计算本次退款中该记录应承担的退款金额 + BigDecimal recordRefundAmount = BigDecimal.ZERO; + + // 根据该记录的支付方式分配退款金额 + if (record.getWxmoney() != null && record.getWxmoney().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal wxRefund = wechatRefund.min(record.getWxmoney().subtract(currentRefunded)); + if (wxRefund.compareTo(BigDecimal.ZERO) > 0) { + recordRefundAmount = recordRefundAmount.add(wxRefund); + wechatRefund = wechatRefund.subtract(wxRefund); + } + } + + if (record.getYemoney() != null && record.getYemoney().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal yeRefund = balanceRefund.min(record.getYemoney().subtract(currentRefunded)); + if (yeRefund.compareTo(BigDecimal.ZERO) > 0) { + recordRefundAmount = recordRefundAmount.add(yeRefund); + balanceRefund = balanceRefund.subtract(yeRefund); + } + } + + if (record.getShopmoney() != null && record.getShopmoney().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal shopRefund = shoppingGoldRefund.min(record.getShopmoney().subtract(currentRefunded)); + if (shopRefund.compareTo(BigDecimal.ZERO) > 0) { + recordRefundAmount = recordRefundAmount.add(shopRefund); + shoppingGoldRefund = shoppingGoldRefund.subtract(shopRefund); + } + } + + if (record.getServicemoney() != null && record.getServicemoney().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal serviceRefund = serviceGoldRefund.min(record.getServicemoney().subtract(currentRefunded)); + if (serviceRefund.compareTo(BigDecimal.ZERO) > 0) { + recordRefundAmount = recordRefundAmount.add(serviceRefund); + serviceGoldRefund = serviceGoldRefund.subtract(serviceRefund); + } + } + + if (record.getCouponmoney() != null && record.getCouponmoney().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal couponRefundAmount = couponRefund.min(record.getCouponmoney().subtract(currentRefunded)); + if (couponRefundAmount.compareTo(BigDecimal.ZERO) > 0) { + recordRefundAmount = recordRefundAmount.add(couponRefundAmount); + couponRefund = couponRefund.subtract(couponRefundAmount); + } + } + + // 如果该记录有退款金额,则更新 + if (recordRefundAmount.compareTo(BigDecimal.ZERO) > 0) { + BigDecimal newTotalRefunded = currentRefunded.add(recordRefundAmount); + + // 如果累计退款金额等于或超过支付金额,设置为已退款状态 + if (newTotalRefunded.compareTo(record.getAllmoney()) >= 0) { + record.setStatus(3L); // 完全退款 + } else { + record.setStatus(2L); // 部分退款 + } + + record.setReturnmoney(newTotalRefunded); + usersPayBeforService.updateUsersPayBefor(record); } - - record.setReturnmoney(newTotalRefunded); - usersPayBeforService.updateUsersPayBefor(record); } - // 这里可以添加实际的退款逻辑 - // 1. 微信支付退款 - 调用微信退款API - // 2. 余额退款 - 更新用户余额 - // 3. 购物金退款 - 更新购物金余额 - // 4. 服务金退款 - 更新服务金余额 - // 5. 会员优惠退款 - 更新会员积分或优惠 - // 6. 优惠券退款 - 恢复优惠券使用状态 - // return success("退款成功", refundDetails); - return success("退款成功"); + // 调用退款工具方法实现真实的业务退款与金额变动 + Map refundResult = refundUtil.processUnifiedRefund( + orderId, wechatRefund, balanceRefund, shoppingGoldRefund, + serviceGoldRefund, memberDiscountRefund, couponRefund, refundRemark + ); + + if (refundResult != null && (Boolean) refundResult.get("success")) { + return success("退款成功"); + } else { + String errorMsg = (String) refundResult.get("message"); + return error(errorMsg != null ? errorMsg : "退款处理失败"); + } } catch (Exception e) { return error("退款失败:" + e.getMessage()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceCate.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceCate.java index f46ceb7..f62c583 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceCate.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceCate.java @@ -48,7 +48,7 @@ public class ServiceCate extends BaseEntity /** 父级分类ID */ @Excel(name = "父级分类ID") private Long parentId; - + private String city; /** 子分类列表 */ private List children; @@ -184,6 +184,14 @@ public class ServiceCate extends BaseEntity return deletedAt; } + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceGoods.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceGoods.java index 660eb32..f936097 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceGoods.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ServiceGoods.java @@ -212,7 +212,7 @@ private String cateName; @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") private Date deletedAt; - + private String city; private BigDecimal minPrice; private BigDecimal maxPrice; @@ -680,6 +680,15 @@ private String cateName; this.forserviceid = forserviceid; } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/UsersPayBefor.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UsersPayBefor.java index 19fee7f..a95bcd4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/UsersPayBefor.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UsersPayBefor.java @@ -113,6 +113,7 @@ public class UsersPayBefor extends BaseEntity private String attachments; private String grouporderid; private BigDecimal returnmoney; + private BigDecimal postage; /** 支付订单号 */ @@ -398,6 +399,14 @@ public class UsersPayBefor extends BaseEntity this.returnmoney = returnmoney; } + public BigDecimal getPostage() { + return postage; + } + + public void setPostage(BigDecimal postage) { + this.postage = postage; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/resources/mapper/system/ServiceCateMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ServiceCateMapper.xml index 9bac7cd..00da2df 100644 --- a/ruoyi-system/src/main/resources/mapper/system/ServiceCateMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/ServiceCateMapper.xml @@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -19,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, title, icon, sort, status, browse, type, parent_id, created_at, updated_at, deleted_at from service_cate + select id, title, icon, sort, status, city,browse, type, parent_id, created_at, updated_at, deleted_at from service_cate @@ -76,6 +78,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" status, browse, type, + city, + + parent_id, deleted_at, created_at, @@ -88,6 +93,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{status}, #{browse}, #{type}, + #{city}, + #{parentId}, #{deletedAt}, NOW(), @@ -104,6 +111,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" status = #{status}, browse = #{browse}, type = #{type}, + city = #{city}, + + parent_id = #{parentId}, deleted_at = #{deletedAt}, updated_at = NOW() diff --git a/ruoyi-system/src/main/resources/mapper/system/ServiceGoodsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ServiceGoodsMapper.xml index 5e6b889..5d9ee78 100644 --- a/ruoyi-system/src/main/resources/mapper/system/ServiceGoodsMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/ServiceGoodsMapper.xml @@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -77,7 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and isfixed = #{isfixed} and servicetype = #{servicetype} - + and JSON_CONTAINS(city, #{city}) and cate_id = #{cateId} and first_cate_id = #{firstCateId} and second_cate_id = #{secondCateId} @@ -177,6 +178,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" questions, isforservice, forserviceid, + city, + created_at, updated_at @@ -224,6 +227,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{questions}, #{isforservice}, #{forserviceid}, + #{city}, NOW(), NOW() @@ -275,6 +279,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" isfixed = #{isfixed}, fixedprice = #{fixedprice}, groupnum = #{groupnum}, + city = #{city}, updated_at = NOW() diff --git a/ruoyi-system/src/main/resources/mapper/system/UserUseSecondaryCardMapper.xml b/ruoyi-system/src/main/resources/mapper/system/UserUseSecondaryCardMapper.xml index 1c12373..ea2b5ee 100644 --- a/ruoyi-system/src/main/resources/mapper/system/UserUseSecondaryCardMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/UserUseSecondaryCardMapper.xml @@ -38,6 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + order by id desc @@ -128,6 +129,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" lastorderid, num, returnmoney, + postage, @@ -163,6 +165,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{lastorderid}, #{num}, #{returnmoney}, + #{postage}, @@ -200,6 +203,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" servicetype = #{servicetype}, lastorderid = #{lastorderid}, num = #{num}, + postage = #{postage}, where id = #{id} diff --git a/ruoyi-ui/src/api/system/DiyCity.js b/ruoyi-ui/src/api/system/DiyCity.js index 2551592..4d6ad22 100644 --- a/ruoyi-ui/src/api/system/DiyCity.js +++ b/ruoyi-ui/src/api/system/DiyCity.js @@ -1,6 +1,6 @@ import request from '@/utils/request' -// 查询自定义地区列表 +// 查询城市列表 export function listDiyCity(query) { return request({ url: '/system/DiyCity/list', @@ -8,31 +8,16 @@ export function listDiyCity(query) { params: query }) } -// 查询自定义地区列表 -export function datalist(query) { - return request({ - url: '/system/DiyCity/datalist', - method: 'get', - params: query - }) -} -// 查询自定义地区详细 +// 查询城市详细 export function getDiyCity(id) { return request({ url: '/system/DiyCity/' + id, method: 'get' }) } -// 查询自定义地区详细 -export function getTreeDataList() { - return request({ - url: '/system/DiyCity/getTreeData', - method: 'get' - }) -} -// 新增自定义地区 +// 新增城市 export function addDiyCity(data) { return request({ url: '/system/DiyCity', @@ -41,7 +26,7 @@ export function addDiyCity(data) { }) } -// 修改自定义地区 +// 修改城市 export function updateDiyCity(data) { return request({ url: '/system/DiyCity', @@ -50,18 +35,30 @@ export function updateDiyCity(data) { }) } -// 删除自定义地区 -export function delDiyCity(ids) { +// 删除城市 +export function delDiyCity(id) { return request({ - url: '/system/DiyCity/' + ids, + url: '/system/DiyCity/' + id, method: 'delete' }) } -// 手动触发师傅暂停状态自动恢复 -export function manualResumeWorkerStatus() { +// 查询城市树结构 +export function getDiyCityTree() { return request({ - url: '/system/DiyCity/manualResumeWorkerStatus', - method: 'post' + url: '/system/DiyCity/tree', + method: 'get' + }) +} + +// 查询一级城市(parent_id=0) +export function getFirstLevelCities() { + return request({ + url: '/system/DiyCity/list', + method: 'get', + params: { + parentId: 0, + pageSize: 1000 + } }) } diff --git a/ruoyi-ui/src/api/system/OrderLog.js b/ruoyi-ui/src/api/system/OrderLog.js index 5eeb23e..dd7d17a 100644 --- a/ruoyi-ui/src/api/system/OrderLog.js +++ b/ruoyi-ui/src/api/system/OrderLog.js @@ -48,3 +48,15 @@ export function delOrderLog(id) { method: 'delete' }) } + +// 查询退款历史记录 +export function getRefundHistory(orderId) { + return request({ + url: '/system/OrderLog/list', + method: 'get', + params: { + orderId: orderId, + title: '退款' + } + }) +} diff --git a/ruoyi-ui/src/api/system/UsersPayBefor.js b/ruoyi-ui/src/api/system/UsersPayBefor.js index f2076f1..5d9f967 100644 --- a/ruoyi-ui/src/api/system/UsersPayBefor.js +++ b/ruoyi-ui/src/api/system/UsersPayBefor.js @@ -1,5 +1,13 @@ import request from '@/utils/request' +// 根据订单ID获取支付信息 +export function getPaymentByOrderId(orderId) { + return request({ + url: `/system/UsersPayBefor/getByOrderId/${orderId}`, + method: 'get' + }) +} + // 统一退款 export function unifiedRefund(data) { return request({ diff --git a/ruoyi-ui/src/views/system/GoodsOrder/UnifiedRefundDialog.vue b/ruoyi-ui/src/views/system/GoodsOrder/UnifiedRefundDialog.vue index 19fdda2..cb362b4 100644 --- a/ruoyi-ui/src/views/system/GoodsOrder/UnifiedRefundDialog.vue +++ b/ruoyi-ui/src/views/system/GoodsOrder/UnifiedRefundDialog.vue @@ -1,210 +1,362 @@ - \ No newline at end of file + +/* 退款历史面板样式 */ +.refund-history-panel { + background-color: #f8f9fa; + padding: 20px; + border-radius: 8px; + border: 1px solid #e9ecef; + height: 100%; /* 确保面板高度与左侧内容一致 */ + display: flex; + flex-direction: column; +} + +.panel-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; +} + +.panel-header h4 { + margin: 0; + color: #303133; + font-size: 16px; + font-weight: 600; +} + +.panel-actions { + display: flex; + gap: 10px; /* 按钮之间的间距 */ +} + +.history-tip { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 15px; + padding: 10px 0; + background-color: #e1f3d8; + border: 1px solid #a5d6a7; + border-radius: 4px; + color: #67c23a; + font-size: 14px; +} + +.history-tip i { + margin-right: 5px; +} + +.history-filters { + margin-bottom: 15px; + padding: 10px 0; + border-top: 1px solid #ebeef5; + border-bottom: 1px solid #ebeef5; +} + +.filter-options { + margin-top: 10px; +} + +.history-content { + flex: 1; + overflow-y: auto; /* 允许内容溢出 */ + padding-right: 10px; /* 为滚动条留出空间 */ +} + +.loading-state, .empty-state, .error-state { + text-align: center; + padding: 20px 0; + color: #909399; + font-size: 14px; +} + +.loading-state i { + margin-right: 5px; +} + +.loading-state .loading-tip { + margin-top: 10px; + font-size: 12px; + color: #909399; +} + +.loading-progress { + margin-top: 15px; + display: flex; + align-items: center; + justify-content: center; +} + +.progress-text { + margin-left: 10px; + font-size: 12px; + color: #909399; +} + +.loading-steps { + margin-top: 15px; + display: flex; + justify-content: space-around; + font-size: 12px; + color: #909399; +} + +.step { + display: flex; + align-items: center; + gap: 5px; +} + +.step.active i { + color: #67C23A; +} + +.skeleton-loading { + margin-top: 20px; +} + +.skeleton-item { + margin-bottom: 15px; + padding: 15px; + background-color: #f5f7fa; + border-radius: 8px; +} + +.skeleton-line { + height: 16px; + background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); + background-size: 200% 100%; + animation: loading 1.5s infinite; + border-radius: 4px; + margin-bottom: 8px; +} + +.skeleton-line.short { + width: 60%; +} + +@keyframes loading { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} + +.empty-state i { + margin-right: 5px; +} + +.empty-state .empty-tip { + margin-top: 10px; + font-size: 12px; + color: #909399; +} + +.empty-state .empty-desc { + margin-top: 10px; + font-size: 12px; + color: #909399; +} + +.empty-actions { + margin-top: 15px; + text-align: center; +} + +.error-state { + color: #F56C6C; +} + +.error-state i { + margin-right: 5px; +} + +.error-state .error-actions { + margin-top: 10px; +} + +.error-state .error-details { + margin-top: 10px; + padding: 10px; + background-color: #fffbe6; + border: 1px solid #ffe58f; + border-radius: 4px; + font-size: 12px; + color: #faad14; + line-height: 1.5; +} + +.error-state .error-code { + font-weight: bold; + margin-bottom: 5px; +} + +.error-state .error-time { + font-style: italic; +} + +/* 时间线样式 */ +.history-timeline { + position: relative; + height: 60vh; + overflow-y: auto; + +} + +/* 性能优化 */ +.timeline-item { + position: relative; + margin-bottom: 20px; + + will-change: transform; + transform: translateZ(0); + contain: layout style paint; + backface-visibility: hidden; + perspective: 1000px; + isolation: isolate; +} + +.timeline-item:last-child { + margin-bottom: 0; +} + +.timeline-item::before { + content: ''; + position: absolute; + left: -10px; /* 调整位置 */ + top: 0; + bottom: 0; + width: 2px; /* 线条宽度 */ + background-color: #e9ecef; /* 线条颜色 */ + will-change: transform; + transform: translateZ(0); + contain: layout style paint; + isolation: isolate; +} + +.timeline-marker { + position: absolute; + left: -10px; /* 调整位置 */ + top: 5px; /* 调整位置 */ + width: 20px; + height: 20px; + background-color: #fff; + border-radius: 50%; + border: 2px solid #409EFF; /* 标记颜色 */ + box-shadow: 0 0 0 2px #fff; /* 标记阴影 */ + display: flex; + justify-content: center; + align-items: center; + z-index: 1; + will-change: transform; + transform: translateZ(0); + contain: layout style paint; + backface-visibility: hidden; + isolation: isolate; +} + +.timeline-marker i { + font-size: 14px; + color: #409EFF; +} + +.timeline-item.is-latest .timeline-marker { + border-color: #67C23A; + background-color: #67C23A; +} + +.timeline-item.is-latest .timeline-marker i { + color: #fff; +} + +.timeline-item.is-latest .timeline-content { + border-color: #67C23A; + box-shadow: 0 2px 12px 0 rgba(103, 194, 58, 0.2); +} + +.timeline-item.is-latest .timeline-title { + color: #67C23A; +} + +.timeline-content { + background-color: #fff; + padding: 15px; + border-radius: 8px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + border: 1px solid #ebeef5; + will-change: transform; + transform: translateZ(0); + contain: layout style paint; + backface-visibility: hidden; + isolation: isolate; +} + +.timeline-header { + + margin-bottom: 10px; + padding-bottom: 10px; + border-bottom: 1px solid #ebeef5; + .header-title{ + display: flex; + justify-content: space-between; + } +} + +.timeline-title { + font-weight: 600; + color: #303133; + font-size: 14px; +} + +.timeline-time { + font-size: 12px; + color: #909399; +} + +.timeline-body { + font-size: 13px; + color: #606266; + line-height: 1.6; +} + +.timeline-body.expanded { + border-bottom: 1px solid #ebeef5; + padding-bottom: 10px; + margin-bottom: 10px; +} + +.refund-amount { + margin-bottom: 5px; + font-weight: 500; + color: #303133; +} + +.refund-amount .amount { + font-weight: 600; + color: #F56C6C; +} + +.refund-desc { + font-style: italic; + color: #909399; +} + +.refund-operator { + margin-top: 8px; + font-size: 12px; + color: #909399; + display: flex; + align-items: center; +} + +.refund-operator i { + margin-right: 5px; + font-size: 14px; +} + +.timeline-details { + margin-top: 10px; + padding-top: 10px; + border-top: 1px dashed #ebeef5; + font-size: 12px; + color: #909399; +} + +.detail-item { + margin-bottom: 5px; +} + +.detail-item label { + font-weight: 500; + color: #606266; + margin-right: 5px; +} + +.timeline-footer { + text-align: right; + margin-top: 10px; +} + +/* 退款统计信息样式 */ +.refund-summary { + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid #e9ecef; + text-align: center; +} + +.summary-item { + margin-bottom: 10px; +} + +.summary-item label { + font-weight: 600; + color: #303133; + margin-right: 10px; +} + +.amount.refunded { + font-size: 18px; + color: #F56C6C; + font-weight: bold; +} + +.amount.remaining { + font-size: 18px; + color: #409EFF; + font-weight: bold; +} + +.summary-extra { + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid #e9ecef; + display: flex; + justify-content: space-between; + font-size: 12px; + color: #909399; +} + +.summary-extra .refund-count { + font-weight: 500; +} + +.summary-extra .last-refund { + font-style: italic; +} + +.summary-details { + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid #e9ecef; +} + +.detail-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + font-size: 12px; +} + +.detail-label { + color: #909399; + font-weight: 500; +} + +.detail-value { + color: #303133; + font-weight: 600; +} + +/* 响应式样式 */ +@media (max-width: 1200px) { + .refund-container .el-col-14 { + width: 100%; + margin-bottom: 20px; + } + + .refund-container .el-col-10 { + width: 100%; + } + + .refund-history-panel { + height: auto; + min-height: 300px; + } +} + +@media (max-width: 768px) { + .el-dialog { + width: 95% !important; + margin: 5vh auto !important; + } + + .refund-container { + padding: 10px 0; + } + + .payment-info, + .refund-input, + .refund-remark, + .refund-history-panel { + padding: 15px; + } +} + +/* 打印样式 */ +@media print { + .el-dialog__header, + .el-dialog__footer, + .panel-header .el-button, + .timeline-footer, + .error-actions { + display: none !important; + } + + .el-dialog { + position: static !important; + width: 100% !important; + margin: 0 !important; + box-shadow: none !important; + } + + .refund-container { + padding: 0 !important; + } + + .payment-info, + .refund-input, + .refund-remark, + .refund-history-panel { + background-color: white !important; + border: 1px solid #000 !important; + margin-bottom: 20px !important; + page-break-inside: avoid; + } + + .timeline-item { + page-break-inside: avoid; + } +} + +/* 动画效果 */ +.timeline-item { + animation: slideIn 0.3s ease-out; +} + +.timeline-item:nth-child(1) { animation-delay: 0.1s; } +.timeline-item:nth-child(2) { animation-delay: 0.2s; } +.timeline-item:nth-child(3) { animation-delay: 0.3s; } +.timeline-item:nth-child(4) { animation-delay: 0.4s; } +.timeline-item:nth-child(5) { animation-delay: 0.5s; } + +@keyframes slideIn { + from { + opacity: 0; + transform: translateX(-20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.timeline-content { + transition: all 0.3s ease; +} + +.timeline-content:hover { + transform: translateY(-2px); + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.15); +} + +.timeline-body.expanded { + animation: expand 0.3s ease-out; +} + +@keyframes expand { + from { + max-height: 0; + opacity: 0; + } + to { + max-height: 200px; + opacity: 1; + } +} + +/* 屏幕阅读器专用样式 */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* 焦点样式 */ +.timeline-item:focus { + outline: 2px solid #409EFF; + outline-offset: 2px; +} + +.timeline-item:focus-visible { + outline: 2px solid #409EFF; + outline-offset: 2px; +} + +/* 高对比度模式支持 */ +@media (prefers-contrast: high) { + .timeline-content { + border: 2px solid #000; + } + + .timeline-marker { + border: 3px solid #000; + } + + .amount { + font-weight: bold; + } +} + diff --git a/ruoyi-ui/src/views/system/GoodsOrder/index.vue b/ruoyi-ui/src/views/system/GoodsOrder/index.vue index 6a99d98..7ef5c0b 100644 --- a/ruoyi-ui/src/views/system/GoodsOrder/index.vue +++ b/ruoyi-ui/src/views/system/GoodsOrder/index.vue @@ -412,7 +412,7 @@ @@ -1326,12 +1326,12 @@ export default { handleUnifiedRefund(row) { this.currentRefundOrder = row; this.currentRefundPaymentData = { - wechatAmount: row.payPrice || 0, - balanceAmount: 0, - shoppingGoldAmount: 0, - serviceGoldAmount: 0, - memberDiscountAmount: 0, - couponAmount: 0 + wxmoney: row.payPrice || 0, + yemoney: 0, + shopmoney: 0, + servicemoney: 0, + membermoney: 0, + couponmoney: 0 }; this.unifiedRefundDialogVisible = true; } diff --git a/ruoyi-ui/src/views/system/GoodsShangPin/index.vue b/ruoyi-ui/src/views/system/GoodsShangPin/index.vue index fa32b56..5aab03d 100644 --- a/ruoyi-ui/src/views/system/GoodsShangPin/index.vue +++ b/ruoyi-ui/src/views/system/GoodsShangPin/index.vue @@ -225,12 +225,10 @@ - - - - - + + + diff --git a/ruoyi-ui/src/views/system/ServiceCate/index.vue b/ruoyi-ui/src/views/system/ServiceCate/index.vue index 5f45168..97d4d8b 100644 --- a/ruoyi-ui/src/views/system/ServiceCate/index.vue +++ b/ruoyi-ui/src/views/system/ServiceCate/index.vue @@ -18,7 +18,7 @@ - +
- @@ -43,14 +43,14 @@
- +
{{ category.title }}
- @@ -68,16 +68,32 @@ {{ category.sort }}
+ +
+ + {{ getCityNameById(cityId) }} + +
+
+ 全部城市 +
- +
- -
- + - +
@@ -153,10 +169,10 @@ prefix-icon="el-icon-search" style="width: 200px; margin-right: 10px;" /> - 添加二级分类 @@ -172,9 +188,9 @@
- @@ -185,20 +201,20 @@ - + - + - + - + - + - + - + + + + +