diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java index fd59c31..297448c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java @@ -99,8 +99,8 @@ public class CommonController // 使用七牛云上传 String fileUrl = QiniuUploadUtil.uploadFile(file); AjaxResult ajax = AjaxResult.success(); - ajax.put("url", fileUrl); - ajax.put("EditorURL", "https://" + getQiniuConfig().getDomain() + "/" +fileUrl); + ajax.put("url", fileUrl); + ajax.put("EditorURL",fileUrl); ajax.put("fileName", fileUrl); ajax.put("newFileName", FileUtils.getName(file.getOriginalFilename())); ajax.put("originalFilename", file.getOriginalFilename()); 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 4ca236e..bac3500 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 @@ -29,6 +29,7 @@ import com.ruoyi.system.domain.GoodsCart; import com.ruoyi.system.service.IGoodsCartService; import com.ruoyi.system.domain.OrderTypeCount; import com.ruoyi.system.service.IQuoteMaterialTypeService; +import com.ruoyi.system.service.IQuoteMaterialService; /** * 苹果订单控制器 @@ -114,6 +115,13 @@ public class AppleOrderController extends BaseController { @Autowired private IQuoteMaterialTypeService quoteMaterialTypeService; + @Autowired + private IQuoteMaterialService quoteMaterialService; + + // 1. 注入IWorkerMoneyLogService + @Autowired + private IWorkerMoneyLogService workerMoneyLogService; + /** @@ -1832,72 +1840,112 @@ public class AppleOrderController extends BaseController { @PostMapping("/api/service/create/order") public AjaxResult submitCartOrder(@RequestBody Map params, HttpServletRequest request) { try { - + // 兼容前端传 {"0":{...}} 的情况 +// if (!params.containsKey("carid") && params.size() == 1 && params.containsKey("0") && params.get("0") instanceof Map) { +// params = (Map) params.get("0"); +// } + // 打印前端传递的参数 + System.out.println("submitCartOrder params: " + params); PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); } - String maincorid=GenerateCustomCode.generCreateOrder("MC"); + String maincorid=GenerateCustomCode.generCreateOrder("ALL"); Users user = (Users) userValidation.get("user"); if (user == null) { return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); } - if (params == null || params.get("carid") == null || params.get("address_id") == null) { - return AppletControllerUtil.appletWarning("carid和address_id不能为空"); + // 检查carid和address_id参数 + Object carIdsObj = params.get("carid"); + Object addressIdObj = params.get("address_id"); +// if (params.get("product_id") == null || params.get("num") == null) { +// return AppletControllerUtil.appletWarning("单品下单参数(product_id, num, sku, mark)不能为空"); +// } + if (addressIdObj == null) { + return AppletControllerUtil.appletWarning("address_id不能为空"); } - List carIds; + Long addressId; try { - carIds = (List) params.get("carid"); + addressId = Long.valueOf(addressIdObj.toString()); } catch (Exception e) { - return AppletControllerUtil.appletWarning("carid参数格式错误,必须为整型数组"); + return AppletControllerUtil.appletWarning("address_id格式错误"); } - Long addressId = Long.valueOf(params.get("address_id").toString()); - String makeTime = params.get("make_time") != null ? params.get("make_time").toString() : ""; - UserAddress userAddress = userAddressService.selectUserAddressById(addressId); if (userAddress == null) { return AppletControllerUtil.appletWarning("地址不存在"); } - List> orderList = new ArrayList<>(); BigDecimal totalAmount = BigDecimal.ZERO; - for (Integer carId : carIds) { - GoodsCart cart = goodsCartService.selectGoodsCartById(carId); - if (cart == null || !user.getId().equals(cart.getUid())) { - return AppletControllerUtil.appletWarning("购物车ID " + carId + " 不存在或无权操作"); + if(carIdsObj==null){ + // 单品下单参数校验 + if (params.get("num") == null || params.get("product_id") == null || params.get("sku") == null || params.get("mark") == null) { + return AppletControllerUtil.appletWarning("num、product_id、sku、mark参数不能为空"); } - ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(cart.getGoodId()); + int num; + try { num = Integer.parseInt(params.get("num").toString()); } catch (Exception e) { return AppletControllerUtil.appletWarning("num格式错误"); } + Long product_id; + try { product_id = Long.valueOf(params.get("product_id").toString()); } catch (Exception e) { return AppletControllerUtil.appletWarning("product_id格式错误"); } + String sku = params.get("sku").toString(); + String mark = params.get("mark").toString(); + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(product_id); if (serviceGoods == null) { - return AppletControllerUtil.appletWarning("商品ID " + cart.getGoodId() + " 不存在"); + return AppletControllerUtil.appletWarning("商品ID " + product_id + " 不存在"); } - Map orderResult; - if (cart.getGoodstype() != null && cart.getGoodstype() == 2) { - // 商品类下单 - orderResult = CartOrderUtil.createGoodsOrderFromCart(user, cart, serviceGoods, userAddress, goodsOrderService,maincorid); - } else { - // 服务类下单 - orderResult = CartOrderUtil.createServiceOrderFromCart(user, cart, serviceGoods, userAddress, makeTime, orderService, orderLogService,maincorid); + Map orderResult = Map.of(); + if (serviceGoods.getType() == 2) { + orderResult= CartOrderUtil.createGoodsOrderFromOnes(user, sku,num, mark,serviceGoods, userAddress, goodsOrderService,maincorid) ; } if (!(Boolean) orderResult.getOrDefault("success", false)) { return AppletControllerUtil.appletWarning(orderResult.getOrDefault("msg", "下单失败").toString()); } - orderList.add(orderResult); totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())); - //一口价 - if (cart.getGoodstype()==1&&cart.getOrdertype()==2){ - String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null); - Map result1 = new HashMap<>(); - result1.put("type", "2"); - result1.put("orderid", maincorid); - return AppletControllerUtil.appletSuccess(result1); + }else{ + List carIds; + try { + carIds = (List) carIdsObj; + } catch (Exception e) { + return AppletControllerUtil.appletWarning("carid参数格式错误,必须为整型数组"); + } + String makeTime = params.get("make_time") != null ? params.get("make_time").toString() : ""; + for (Integer carId : carIds) { + GoodsCart cart = goodsCartService.selectGoodsCartById(carId); + if (cart == null || !user.getId().equals(cart.getUid())) { + return AppletControllerUtil.appletWarning("购物车ID " + carId + " 不存在或无权操作"); + } + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(cart.getGoodId()); + if (serviceGoods == null) { + return AppletControllerUtil.appletWarning("商品ID " + cart.getGoodId() + " 不存在"); + } + Map orderResult; + if (cart.getGoodstype() != null && cart.getGoodstype() == 2) { + orderResult = CartOrderUtil.createGoodsOrderFromCart(user, cart, serviceGoods, userAddress, goodsOrderService,maincorid); + // String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null); + + } else { + orderResult = CartOrderUtil.createServiceOrderFromCart(user, cart, serviceGoods, userAddress, makeTime, orderService, orderLogService,maincorid); + //String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null); + + } + if (!(Boolean) orderResult.getOrDefault("success", false)) { + //删除购物车记录 + goodsCartService.deleteGoodsCartById(cart.getId()); + return AppletControllerUtil.appletWarning(orderResult.getOrDefault("msg", "下单失败").toString()); + } + orderList.add(orderResult); + totalAmount = totalAmount.add(new BigDecimal(orderResult.get("allprice").toString())); + if (cart.getGoodstype()==1&&cart.getOrdertype()==2){ + String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, cart.getGoodId(), 6L, cart.getSku(), null, null, null, null,1L, null, null); + Map result1 = new HashMap<>(); + result1.put("type", "2"); + result1.put("orderid", maincorid); + return AppletControllerUtil.appletSuccess(result1); + } } } - if (totalAmount.compareTo(BigDecimal.ZERO) > 0) { - //插入预支付订单,随后进行支付 String payBeforeId = payBeforeUtil.createPayBefore(user, totalAmount, maincorid, null, null, 5L, null, null, null, null, null,2L,null,null); Map result1 = new HashMap<>(); result1.put("type", "2"); @@ -1908,10 +1956,7 @@ public class AppleOrderController extends BaseController { result1.put("type", "1"); result1.put("orderid", maincorid); return AppletControllerUtil.appletSuccess(result1); - } - - } catch (Exception e) { logger.error("购物车下单失败:", e); return AppletControllerUtil.appletError("购物车下单失败:" + e.getMessage()); @@ -2489,9 +2534,9 @@ public class AppleOrderController extends BaseController { List orderList = new ArrayList<>(); Order queryOrder = new Order(); // 直接用dayDate字符串查 - if (org.apache.commons.lang3.StringUtils.isNotBlank(dayDate)) { + if (StringUtils.isNotBlank(dayDate)) { queryOrder.setDayDate(dayDate); - } else if (org.apache.commons.lang3.StringUtils.isNotBlank(day)) { + } else if (StringUtils.isNotBlank(day)) { Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); @@ -2717,7 +2762,7 @@ public class AppleOrderController extends BaseController { } for (String cityId : cityIds) { if (cityId != null && !cityId.trim().isEmpty()) { - DiyCity city = diyCityService.selectDiyCityById(Math.toIntExact(Long.parseLong(cityId.replaceAll("\"", "").trim()))); + DiyCity city = diyCityService.selectDiyCityById(Long.valueOf(cityId.replaceAll("\"", "").trim()).intValue()); if (city != null) { Map cityMap = new HashMap<>(); cityMap.put("id", city.getId()); @@ -3452,8 +3497,8 @@ public class AppleOrderController extends BaseController { String hourStr = arr[1]; Long makeTimeStamp = null; try { - java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); - java.util.Date date = sdf.parse(dateStr); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date date = sdf.parse(dateStr); makeTimeStamp = date.getTime() / 1000; } catch (Exception e) { return AjaxResult.error("日期格式错误"); @@ -3497,7 +3542,7 @@ public class AppleOrderController extends BaseController { return AppletControllerUtil.appletWarning("订单不存在"); } // 3. 查询最新一条日志,获取type - java.math.BigDecimal logType = null; + BigDecimal logType = null; try { OrderLog latestLog = orderLogService.selectDataTheFirstNew(oid); if (latestLog != null && latestLog.getType() != null) { @@ -3515,7 +3560,7 @@ public class AppleOrderController extends BaseController { orderLog.setTitle("师傅跟单"); orderLog.setType(logType); // 跟单type与最新日志一致 // content格式为{"name":内容} - com.alibaba.fastjson2.JSONObject json = new com.alibaba.fastjson2.JSONObject(); + JSONObject json = new JSONObject(); json.put("name", content); orderLog.setContent(json.toJSONString()); // 5. 插入日志 @@ -3544,9 +3589,9 @@ public class AppleOrderController extends BaseController { int total = allList.size(); int fromIndex = Math.max(0, (pageNum - 1) * pageSize); int toIndex = Math.min(fromIndex + pageSize, total); - List pageList = fromIndex < toIndex ? allList.subList(fromIndex, toIndex) : new java.util.ArrayList<>(); + List pageList = fromIndex < toIndex ? allList.subList(fromIndex, toIndex) : new ArrayList<>(); // 只返回title和id - List> simpleList = new java.util.ArrayList<>(); + List> simpleList = new ArrayList<>(); for (DiyCity city : pageList) { Map map = new HashMap<>(); map.put("id", city.getId()); @@ -3579,9 +3624,9 @@ public class AppleOrderController extends BaseController { int total = allList.size(); int fromIndex = Math.max(0, (pageNum - 1) * pageSize); int toIndex = Math.min(fromIndex + pageSize, total); - List pageList = fromIndex < toIndex ? allList.subList(fromIndex, toIndex) : new java.util.ArrayList<>(); + List pageList = fromIndex < toIndex ? allList.subList(fromIndex, toIndex) : new ArrayList<>(); // 只返回title和id - List> simpleList = new java.util.ArrayList<>(); + List> simpleList = new ArrayList<>(); for (SiteSkill skill : pageList) { Map map = new HashMap<>(); map.put("id", skill.getId()); @@ -3665,8 +3710,8 @@ public class AppleOrderController extends BaseController { String[] arr = makeTimeStr.split(" "); if (arr.length == 2) { try { - java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); - java.util.Date date = sdf.parse(arr[0]); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date date = sdf.parse(arr[0]); makeTime = date.getTime() / 1000; makeHour = arr[1]; } catch (Exception e) { @@ -3696,8 +3741,8 @@ public class AppleOrderController extends BaseController { orderLog.setOid(order.getId()); orderLog.setOrderId(order.getOrderId()); orderLog.setTitle("拼团预约"); - orderLog.setType(java.math.BigDecimal.valueOf(1.0)); - com.alibaba.fastjson2.JSONObject json = new com.alibaba.fastjson2.JSONObject(); + orderLog.setType(BigDecimal.valueOf(1.0)); + JSONObject json = new JSONObject(); json.put("name", "拼团预约成功,待接单"); orderLog.setContent(json.toJSONString()); orderLogService.insertOrderLog(orderLog); @@ -3829,6 +3874,18 @@ public class AppleOrderController extends BaseController { return AjaxResult.success(data); } + + + /** + * 协议类型接口,返回写死的数据 + */ + @GetMapping("/api/public/getusertest/{id}") + public AjaxResult getusertest(@PathVariable("id") Long id) { + + List data = OrderUtil.getDispatchWorkerList(id); + return AjaxResult.success(data); + } + /** * 查询内容详情接口 * @param id 内容ID @@ -3880,21 +3937,35 @@ public class AppleOrderController extends BaseController { @GetMapping("/api/material/detail") public AjaxResult getMaterialDetail(@RequestParam("id") Long id) { try { - QuoteMaterialType material = quoteMaterialTypeService.selectQuoteMaterialTypeById(id); + QuoteMaterial material = quoteMaterialService.selectQuoteMaterialById(id); if (material == null) { return AjaxResult.error("物料不存在"); } - // 构建返回数据(可根据实际字段调整) Map result = new HashMap<>(); result.put("id", material.getId()); - result.put("name", material.getName()); - result.put("type", material.getType()); + result.put("title", material.getTitle()); + result.put("typeId", material.getTypeId()); + result.put("typeName", material.getTypeName()); + result.put("goodId", material.getGoodId()); + result.put("serviceName", material.getServiceName()); result.put("price", material.getPrice()); result.put("unit", material.getUnit()); - result.put("desc", material.getDesc()); - result.put("status", material.getStatus()); - result.put("createdAt", material.getCreatedAt()); - result.put("updatedAt", material.getUpdatedAt()); + result.put("image", material.getImage()); + // 格式化manyimages为数组 + if (material.getManyimages() != null && !material.getManyimages().trim().isEmpty()) { + result.put("manyimages", JSONArray.parseArray(material.getManyimages())); + } else { + result.put("manyimages", new JSONArray()); + } + if (StringUtils.isNotBlank(material.getContent())&&StringUtils.isNotBlank(material.getManyimages())){ + result.put("showtype", 1); + }else{ + result.put("showtype", 2); + } + result.put("content", material.getContent()); + result.put("profit", material.getProfit()); + result.put("commissions", material.getCommissions()); + result.put("iscommissions", material.getIscommissions()); // 可根据需要添加更多字段 return AjaxResult.success(result); } catch (Exception e) { @@ -3903,4 +3974,221 @@ public class AppleOrderController extends BaseController { } } + @GetMapping("/api/worker/stat") + public AjaxResult getWorkerStat(HttpServletRequest request) { + try { + // 1. 校验用户登录 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + Long workerId = user.getId(); + + // 2. 今日单量 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String todayStr = sdf.format(new Date()); + Date todayStart = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(todayStr + " 00:00:00"); + Date todayEnd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(todayStr + " 23:59:59"); + Order dayOrder = new Order(); + dayOrder.setWorkerId(workerId); + dayOrder.setReceiveTimeStart(todayStart); + dayOrder.setReceiveTimeEnd(todayEnd); + int dayCount = orderService.selectOrderList(dayOrder).size(); + + // 3. 本月单量 + String monthStartStr = todayStr.substring(0, 8) + "01 00:00:00"; + Date monthStart = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(monthStartStr); + Order monthOrder = new Order(); + monthOrder.setWorkerId(workerId); + monthOrder.setType(1); + monthOrder.setReceiveTimeStart(monthStart); + monthOrder.setReceiveTimeEnd(todayEnd); + int monthCount = orderService.selectOrderList(monthOrder).size(); + + // 4. 本月收入 + BigDecimal monthIncome = workerMoneyLogService.selectWorkerMoneySumPrice(workerId.intValue()); + if (monthIncome == null) monthIncome = BigDecimal.ZERO; + + // 5. 配置信息 + SiteConfig config = new SiteConfig(); + config.setName("config_one"); + List configList = siteConfigService.selectSiteConfigList(config); + Map configValue = new HashMap<>(); + if (configList != null && !configList.isEmpty()) { + String value = configList.get(0).getValue(); + if (value != null && !value.trim().isEmpty()) { + configValue = com.alibaba.fastjson.JSONObject.parseObject(value, Map.class); + } + } + + // 6. 是否需要签到 + boolean sign = true; + if (user.getWorkerTime() != null) { + if (sdf.format(user.getWorkerTime()).equals(todayStr)) { + sign = false; + } + } + + // 7. 返回数据 + Map data = new HashMap<>(); + data.put("day_count", dayCount); + data.put("mouth_count", monthCount); + data.put("income", monthIncome); + data.put("user", user); + data.put("sign", sign); + data.put("config", configValue); + + return AppletControllerUtil.appletSuccess(data); + } catch (Exception e) { + return AppletControllerUtil.appletError("首页统计异常:" + e.getMessage()); + } + } + + @PostMapping("/api/workerdata/index") + public AjaxResult workerdataIndex(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 校验用户登录 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + + int limit = 10; + if (params.get("limit") != null) { + try { limit = Integer.parseInt(params.get("limit").toString()); } catch (Exception ignore) {} + } + int pageNum = params.get("pageNum") != null ? Integer.parseInt(params.get("pageNum").toString()) : 1; + int offset = (pageNum - 1) * limit; + + // 2. 师傅等级图片 + if (user.getLevel() != null) { + WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(user.getLevel())); + if (levelInfo != null) { + user.setLevelInfo(levelInfo); + user.setLevelImg(levelInfo.getImage()); + } + } + + // 3. 质保金、累计佣金、佣金为0处理 + if (user.getMargin() == null) user.setMargin(BigDecimal.ZERO); + if (user.getTotalComm() == null) user.setTotalComm(BigDecimal.ZERO); + if (user.getCommission() == null) user.setCommission(BigDecimal.ZERO); + + // 4. 师傅技能 + if (user.getSkillIds() != null && !user.getSkillIds().trim().isEmpty()) { + List skillArr = new ArrayList<>(); + List skillIds = parseJsonIdList(user.getSkillIds()); + for (String sid : skillIds) { + SiteSkill skill = siteSkillService.selectSiteSkillById(Long.valueOf(sid)); + if (skill != null) { + Map skillMap = new HashMap<>(); + skillMap.put("id", skill.getId()); + skillMap.put("title", skill.getTitle()); + skillArr.add(skillMap.toString()); + } + } + user.setSkillArr(skillArr); + } + + // 5. 师傅服务地区 + if (user.getServiceCityIds() != null && !user.getServiceCityIds().trim().isEmpty()) { + List cityArr = new ArrayList<>(); + List cityIds = parseJsonIdList(user.getServiceCityIds()); + for (String cid : cityIds) { + DiyCity city = diyCityService.selectDiyCityById(Long.valueOf(cid).intValue()); + if (city != null) { + Map cityMap = new HashMap<>(); + cityMap.put("id", city.getId()); + cityMap.put("title", city.getTitle()); + cityArr.add(cityMap); + } + } + user.setServiceCityArr(cityArr); + } + + // 6. 禁止接单剩余时间 + if (user.getProhibitTime() != null && user.getProhibitTimeNum() != null) { + long now = System.currentTimeMillis() / 1000; + long prohibitStart = user.getProhibitTime().getTime() / 1000; + long prohibitEnd = prohibitStart + user.getProhibitTimeNum() * 3600; + if (prohibitStart < now && prohibitEnd > now) { + long residue = prohibitEnd - now; + long hours = residue / 3600; + long minutes = (residue % 3600) / 60; + long seconds = residue % 60; + StringBuilder str = new StringBuilder(); + if (hours > 0) str.append(hours).append("小时"); + if (minutes > 0) str.append(minutes).append("分钟"); + if (seconds > 0) str.append(seconds).append("秒"); + user.setProhibit("因违反平台规定," + user.getProhibitTimeNum() + "小时内禁止接单,剩余" + str); + } + } + + // 7. 查询师傅所有服务订单ID(Log表,worker_id=当前师傅,取oid) + List oids = orderLogService.selectOidListByWorkerId(user.getId()); + + // 8. 查询评价(Comment表,oid in oids,支持type筛选,分页) + List> dataList = new ArrayList<>(); + Map commentStat = new HashMap<>(); + double totalNum = 0; + int totalCount = 0; + Long type = params.get("type") != null ? Long.valueOf(params.get("type").toString()) : null; + if (!oids.isEmpty()) { + List comments = orderCommentService.selectOrderCommentListByOidsAndType(oids, type, offset, limit); + for (OrderComment c : comments) { + Map cMap = new HashMap<>(); + Users u = usersService.selectUsersById(c.getUid()); + cMap.put("id", c.getId()); + cMap.put("uid", c.getUid()); + cMap.put("images", c.getImages()); + cMap.put("content", c.getContent()); + cMap.put("num", c.getNum()); + cMap.put("time", c.getCreatedAt()); + cMap.put("user", u != null ? Map.of("id", u.getId(), "name", u.getName(), "avatar", u.getAvatar()) : null); + dataList.add(cMap); + totalNum += c.getNum() != null ? c.getNum() : 0; + totalCount++; + } + // 统计好评/中评/差评数量 + commentStat.put("one", orderCommentService.countByOidsAndType(oids, 1L)); + commentStat.put("two", orderCommentService.countByOidsAndType(oids, 2L)); + commentStat.put("three", orderCommentService.countByOidsAndType(oids, 3L)); + commentStat.put("total", totalCount > 0 ? Math.round(totalNum / totalCount * 10.0) / 10.0 : 0); + } else { + commentStat.put("one", 0); + commentStat.put("two", 0); + commentStat.put("three", 0); + commentStat.put("total", 0); + } + + Map result = new HashMap<>(); + result.put("user", user); + result.put("data", dataList); + result.put("comment", commentStat); + + return AppletControllerUtil.appletSuccess(result); + } catch (Exception e) { + return AppletControllerUtil.appletError("获取个人中心信息失败:" + e.getMessage()); + } + } + + // 辅助方法:解析JSON数组字符串为List + private List parseJsonIdList(String json) { + try { + return com.alibaba.fastjson.JSONArray.parseArray(json, String.class); + } catch (Exception e) { + return new ArrayList<>(); + } + } + } 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 23648a5..545910c 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 @@ -4327,15 +4327,13 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletError("查询师傅订单列表失败:" + e.getMessage()); } } - /** - * 获取师傅工作台统计数据 - * 返回格式见json.txt + * 师傅签到 */ - @GetMapping("/api/worker/stat") - public AjaxResult getWorkerStat(HttpServletRequest request) { + @GetMapping("/api/worker/sign/") + public AjaxResult workerSign(HttpServletRequest request) { try { - // 1. 校验token并获取用户 + // 1. 校验用户登录 String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { @@ -4345,47 +4343,225 @@ public class AppletController extends BaseController { if (user == null) { return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); } - // 2. 查询config_one配置 - SiteConfig configQuery = new SiteConfig(); - configQuery.setName("config_one"); - List configList = siteConfigService.selectSiteConfigList(configQuery); - Object configObj = null; - if (configList != null && !configList.isEmpty()) { - String configValue = configList.get(0).getValue(); - if (configValue != null && !configValue.trim().isEmpty()) { - configObj = JSONObject.parse(configValue); - } + // 2. 判断是否为师傅 + if (user.getType() == null || user.getType().equals(2)) { + return AppletControllerUtil.appletWarning("您还不是师傅"); } - // 3. 判断今日是否签到 + // 3. 更新worker_time + user.setWorkerTime(new Date()); + int updateResult = usersService.updateUsers(user); + // 4. 插入签到记录 + WorkerSign workerSign = new WorkerSign(); + + workerSign.setUid(String.valueOf(user.getId())); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - String todayStr = sdf.format(new Date()); - WorkerSign signQuery = new WorkerSign(); - signQuery.setUid(String.valueOf(user.getId())); - signQuery.setTime(sdf.parse(todayStr)); - boolean signed = false; - List signList = workerSignService.selectWorkerSignList(signQuery); - if (signList != null && !signList.isEmpty()) { - signed = true; + workerSign.setTime(new Date()); + workerSign.setCreatedAt(new Date()); + workerSign.setUpdatedAt(new Date()); + workerSignService.insertWorkerSign(workerSign); + // 5. 返回 + if (updateResult > 0) { + return AppletControllerUtil.appletSuccess("签到成功"); + } else { + return AppletControllerUtil.appletWarning("签到失败"); } - // 4. 构建user数据 - Map userMap = buildUserInfoResponse(user); - // 5. 构建返回结构 - Map data = new HashMap<>(); - data.put("day_count", 0); - data.put("mouth_count", 0); - data.put("income", 0); - data.put("user", userMap); - data.put("sign", signed); - data.put("config", configObj); - Map result = new HashMap<>(); - result.put("code", 200); - result.put("msg", "OK"); - result.put("data", data); - return AjaxResult.success(result); } catch (Exception e) { - return AppletControllerUtil.appletError("获取师傅统计数据失败:" + e.getMessage()); + return AppletControllerUtil.appletError("签到异常:" + e.getMessage()); } } + @PostMapping("/api/worker/stop") + public AjaxResult stopWorker(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 校验用户登录 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + + // 2. 获取参数 is_stop + Object isStopObj = params.get("is_stop"); + int isStop = (isStopObj != null && ("1".equals(isStopObj.toString()) || "true".equalsIgnoreCase(isStopObj.toString()))) ? 1 : 0; + + // 3. 更新用户 is_stop 字段 + user.setIsStop(isStop); + int result = usersService.updateUsers(user); + + // 4. 返回 + if (result > 0) { + return AppletControllerUtil.appletSuccess("成功"); + } else { + return AppletControllerUtil.appletError("失败"); + } + } catch (Exception e) { + return AppletControllerUtil.appletError("操作异常:" + e.getMessage()); + } + } + + +// /** +// * 师傅签到 +// */ +// @GetMapping("/api/worker/stop") +// public AjaxResult workerSignstop(HttpServletRequest request) { +// try { +// // 1. 校验用户登录 +// String token = request.getHeader("token"); +// Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); +// if (!(Boolean) userValidation.get("valid")) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// Users user = (Users) userValidation.get("user"); +// if (user == null) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// // 2. 判断是否为师傅 +// if (user.getType() == null || user.getType().equals(2)) { +// return AppletControllerUtil.appletWarning("您还不是师傅"); +// } +// // 3. 更新worker_time +// user.setIsStop(1); +// int updateResult = usersService.updateUsers(user); +// +// // 5. 返回 +// if (updateResult > 0) { +// return AppletControllerUtil.appletSuccess("关闭成功"); +// } else { +// return AppletControllerUtil.appletWarning("关闭失败"); +// } +// } catch (Exception e) { +// return AppletControllerUtil.appletError("关闭异常:" + e.getMessage()); +// } +// } +// +// @GetMapping("/api/worker/stat") +// public AjaxResult getWorkerStat(HttpServletRequest request) { +// try { +// // 1. 校验用户登录 +// String token = request.getHeader("token"); +// Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); +// if (!(Boolean) userValidation.get("valid")) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// Users user = (Users) userValidation.get("user"); +// if (user == null) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// Long workerId = user.getId(); +// +// // 2. 今日单量 +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); +// String todayStr = sdf.format(new Date()); +// String todayStart = todayStr + " 00:00:00"; +// String todayEnd = todayStr + " 23:59:59"; +// +// int dayCount = orderService.countByWorkerIdAndReceiveTime(workerId, todayStart, todayEnd, null); +// +// // 3. 本月单量 +// String monthStart = todayStr.substring(0, 8) + "01 00:00:00"; +// int monthCount = orderService.countByWorkerIdAndReceiveTime(workerId, monthStart, todayEnd, 1); +// +// // 4. 本月收入 +// BigDecimal monthIncome = moneyLogService.sumPriceByWorkerIdAndCreatedAt(workerId, monthStart, todayEnd, 1); +// +// // 5. 配置信息 +// SiteConfig config = new SiteConfig(); +// config.setName("config_one"); +// List configList = siteConfigService.selectSiteConfigList(config); +// Map configValue = new HashMap<>(); +// if (configList != null && !configList.isEmpty()) { +// String value = configList.get(0).getValue(); +// if (value != null && !value.trim().isEmpty()) { +// configValue = JSONObject.parseObject(value, Map.class); +// } +// } +// +// // 6. 是否需要签到 +// boolean sign = true; +// if (user.getWorkerTime() != null) { +// String workerTimeStr = sdf.format(user.getWorkerTime()); +// if (workerTimeStr.equals(todayStr)) { +// sign = false; +// } +// } +// +// // 7. 返回数据 +// Map data = new HashMap<>(); +// data.put("day_count", dayCount); +// data.put("mouth_count", monthCount); +// data.put("income", monthIncome); +// data.put("user", user); +// data.put("sign", sign); +// data.put("config", configValue); +// +// return AppletControllerUtil.appletSuccess(data); +// } catch (Exception e) { +// return AppletControllerUtil.appletError("首页统计异常:" + e.getMessage()); +// } +// } + +// /** +// * 获取师傅工作台统计数据 +// * 返回格式见json.txt +// */ +// @GetMapping("/api/worker/stat") +// public AjaxResult getWorkerStat(HttpServletRequest request) { +// try { +// // 1. 校验token并获取用户 +// String token = request.getHeader("token"); +// Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); +// if (!(Boolean) userValidation.get("valid")) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// Users user = (Users) userValidation.get("user"); +// if (user == null) { +// return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); +// } +// // 2. 查询config_one配置 +// SiteConfig configQuery = new SiteConfig(); +// configQuery.setName("config_one"); +// List configList = siteConfigService.selectSiteConfigList(configQuery); +// Object configObj = null; +// if (configList != null && !configList.isEmpty()) { +// String configValue = configList.get(0).getValue(); +// if (configValue != null && !configValue.trim().isEmpty()) { +// configObj = JSONObject.parse(configValue); +// } +// } +// // 3. 判断今日是否签到 +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); +// String todayStr = sdf.format(new Date()); +// WorkerSign signQuery = new WorkerSign(); +// signQuery.setUid(String.valueOf(user.getId())); +// signQuery.setTime(sdf.parse(todayStr)); +// boolean signed = false; +// List signList = workerSignService.selectWorkerSignList(signQuery); +// if (signList != null && !signList.isEmpty()) { +// signed = true; +// } +// // 4. 构建user数据 +// Map userMap = buildUserInfoResponse(user); +// // 5. 构建返回结构 +// Map data = new HashMap<>(); +// data.put("day_count", 0); +// data.put("mouth_count", 0); +// data.put("income", 0); +// data.put("user", userMap); +// data.put("sign", signed); +// data.put("config", configObj); +// Map result = new HashMap<>(); +// result.put("code", 200); +// result.put("msg", "OK"); +// result.put("data", data); +// return AjaxResult.success(result); +// } catch (Exception e) { +// return AppletControllerUtil.appletError("获取师傅统计数据失败:" + e.getMessage()); +// } +// } // /** // * 师傅端订单详情接口 @@ -4557,8 +4733,9 @@ public class AppletController extends BaseController { jsonObject.put("status",0); contentObj=jsonObject; } - - + }else if (log.getTitle().equals("已检查评估报价")){ + JSONObject jsonObject = JSONObject.from(OrderUtil.getbaojiajson(log.getContent())); + contentObj = jsonObject; }else{ try { if (log.getContent() != null) { @@ -4980,6 +5157,52 @@ public class AppletController extends BaseController { // } // // } +// logMap.put("content", contentObj); +// Object contentObj = null; +// // content字段为json字符串,需转为对象 +// if (log.getTitle().equals("订单评价")) { +// OrderComment comment = new OrderComment(); +// comment.setOid(log.getOid()); +// List commentList = orderCommentService.selectOrderCommentList(comment); +// if(!commentList.isEmpty()){ +// OrderComment commentDATA = commentList.getFirst(); +// JSONObject jsonObject = new JSONObject(); +// jsonObject.put("num",commentDATA.getNum()); +// jsonObject.put("status",commentDATA.getStatus()); +// jsonObject.put("text",commentDATA.getContent()); +// if (commentDATA.getImages()!=null){ +// jsonObject.put("image",JSONArray.parseArray(commentDATA.getImages())); +// } +// if (commentDATA.getLabels()!=null){ +// jsonObject.put("labels",JSONArray.parseArray(commentDATA.getLabels())); +// } +// +// contentObj=jsonObject; +// }else{ +// JSONObject jsonObject = new JSONObject(); +// +// jsonObject.put("status",0); +// contentObj=jsonObject; +// } +// +// +// }else{ +// try { +// if (log.getContent() != null) { +// contentObj = JSONObject.parse(log.getContent()); +// } +// } catch (Exception e) { +// +// if (AppletControllerUtil.canParseToJSONArray(log.getContent())) { +// contentObj = JSONArray.parseArray(log.getContent()); +// } else { +// contentObj = log.getContent(); +// } +// +// } +// } +// +// // logMap.put("content", contentObj); Object contentObj = null; // content字段为json字符串,需转为对象 @@ -5007,8 +5230,9 @@ public class AppletController extends BaseController { jsonObject.put("status",0); contentObj=jsonObject; } - - + }else if (log.getTitle().equals("已检查评估报价")){ + JSONObject jsonObject = JSONObject.from(OrderUtil.getbaojiajson(log.getContent())); + contentObj = jsonObject; }else{ try { if (log.getContent() != null) { @@ -5524,7 +5748,7 @@ public class AppletController extends BaseController { * 返回结构见json.txt */ @PostMapping("/api/worker/index") - public AjaxResult getWorkerIndex(@RequestBody Map params, HttpServletRequest request) { + public AjaxResult getWorkerdataIndex(@RequestBody Map params, HttpServletRequest request) { try { // 1. 校验token并获取师傅信息 String token = request.getHeader("token"); @@ -5536,6 +5760,23 @@ public class AppletController extends BaseController { if (user == null) { return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); } + // 6. 禁止接单剩余时间 + if (user.getProhibitTime() != null && user.getProhibitTimeNum() != null) { + long now = System.currentTimeMillis() / 1000; + long prohibitStart = user.getProhibitTime().getTime() / 1000; + long prohibitEnd = prohibitStart + user.getProhibitTimeNum() * 3600; + if (prohibitStart < now && prohibitEnd > now) { + long residue = prohibitEnd - now; + long hours = residue / 3600; + long minutes = (residue % 3600) / 60; + long seconds = residue % 60; + StringBuilder str = new StringBuilder(); + if (hours > 0) str.append(hours).append("小时"); + if (minutes > 0) str.append(minutes).append("分钟"); + if (seconds > 0) str.append(seconds).append("秒"); + user.setProhibit("因违反平台规定," + user.getProhibitTimeNum() + "小时内禁止接单,剩余" + str); + } + } // 2. 查询等级信息 Object levelInfo = null; String levelImg = null; @@ -6063,166 +6304,7 @@ public class AppletController extends BaseController { // return AppletControllerUtil.appletError("设置上门费失败:" + e.getMessage()); // } // } - /** - * 师傅设置上门费接口 - * 参数:{"id":订单id,"price":金额} - * 逻辑:查找订单最新日志,设置workerCost和price,并设置paid=1 - */ - @PostMapping("/api/worker/set/price") - public AjaxResult setWorkerPrice(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 校验token并获取用户 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); - } - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); - } - Long orderId = params.get("id") != null ? Long.parseLong(params.get("id").toString()) : null; - String priceStr = params.get("price") != null ? params.get("price").toString() : null; - if (orderId == null || StringUtils.isEmpty(priceStr)) { - return AppletControllerUtil.appletWarning("参数错误"); - } - BigDecimal price = new BigDecimal(priceStr); - // 查询订单 - Order order = orderService.selectOrderById(orderId); - if (order == null) { - return AppletControllerUtil.appletWarning("订单不存在"); - } - // 查询最新订单日志 - OrderLog neworderLogdata =orderLogService.selectDataTheFirstNew(order.getId()); -// neworderLogdata.setType(new BigDecimal(2.0)); -// neworderLogdata.setOid(order.getId()); -// List orderLogslist = orderLogService.selectOrderLogList(neworderLogdata); -// OrderLog neworderLog = orderLogslist.getFirst(); - if (neworderLogdata != null) { - - String logOrderId = GenerateCustomCode.generCreateOrder("DSB"); - OrderLog neworderLog =new OrderLog(); - neworderLog.setOid(order.getId()); - neworderLog.setOrderId(order.getOrderId()); - neworderLog.setLogOrderId(logOrderId); - neworderLog.setTitle("上门费"); - neworderLog.setType(neworderLogdata.getType()); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("name", "师傅"+user.getName()+"设置上门费"+ price+"元"); - neworderLog.setContent(jsonObject.toJSONString()); - neworderLog.setPaid(1L); - neworderLog.setPrice( price); - neworderLog.setLogId(GenerateCustomCode.generCreateOrder("FEE")); - - neworderLog.setWorkerId(user.getId()); - neworderLog.setWorkerCost( price); - neworderLog.setWorkerLogId(user.getId()); - int insert =orderLogService.insertOrderLog(neworderLog); - if (insert > 0) { - //上门费创建支付单 - BigDecimal totalAmount=neworderLog.getPrice(); - Users userinfo = usersService.selectUsersById(order.getUid()); - PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); - payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, neworderLog.getId(), - null, 7L, null, null, - null, null, null,1L,null,order.getOrderId()); - -// // 9. 计算会员优惠和服务金抵扣 -// BigDecimal memberMoney = BigDecimal.ZERO; -// BigDecimal serviceMoney = BigDecimal.ZERO; -// -// try { -// // 查询config_one配置 -// SiteConfig configQuery = new SiteConfig(); -// configQuery.setName("config_one"); -// List configList = siteConfigService.selectSiteConfigList(configQuery); -// -// if (configList != null && !configList.isEmpty()) { -// String configValue = configList.get(0).getValue(); -// if (configValue != null && !configValue.trim().isEmpty()) { -// JSONObject configJson = JSONObject.parseObject(configValue); -// -// // 计算会员优惠金额 -// if (user.getIsmember() != null && user.getIsmember() == 1) { -// // 用户是包年会员,计算会员优惠 -// Integer memberDiscount = configJson.getInteger("member_discount"); -// if (memberDiscount != null && memberDiscount > 0) { -// // 会员优惠金额 = 订单金额 * (100 - 会员折扣) / 100 -// BigDecimal discountRate = BigDecimal.valueOf(memberDiscount).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); -// if (totalAmount != null) { -// memberMoney = totalAmount.multiply(discountRate); -// } -// } -// } -// -// // 计算服务金抵扣金额 -// Integer serviceFee = configJson.getInteger("servicefee"); -// if (serviceFee != null && serviceFee > 0) { -// // 查询数据库最新用户数据 -// Users userDb = usersService.selectUsersById(user.getId()); -// if (userDb != null && userDb.getServicefee() != null && userDb.getServicefee().compareTo(BigDecimal.ZERO) > 0) { -// // 服务金抵扣金额 = 用户服务金 * 服务金比例 / 100 -// BigDecimal serviceRate = BigDecimal.valueOf(serviceFee).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); -// serviceMoney = userDb.getServicefee().multiply(serviceRate); -// } -// } -// } -// } -// } catch (Exception e) { -// logger.warn("计算会员优惠和服务金抵扣失败: " + e.getMessage()); -// memberMoney = BigDecimal.ZERO; -// serviceMoney = BigDecimal.ZERO; -// } -// -// // 10. 创建预支付记录 -// UsersPayBefor usersPayBefor = new UsersPayBefor(); -// usersPayBefor.setUid(userinfo.getId()); -// usersPayBefor.setOrderid(logOrderId); -// usersPayBefor.setOid(neworderLog.getId()); -// usersPayBefor.setPaycode(GenerateCustomCode.generCreateOrder("PAY")); -// usersPayBefor.setAllmoney(totalAmount); -// usersPayBefor.setWxmoney(totalAmount); -// usersPayBefor.setShopmoney(BigDecimal.ZERO); -// usersPayBefor.setServicemoney(serviceMoney); -// usersPayBefor.setMtmoney(BigDecimal.ZERO); -// usersPayBefor.setYemoney(BigDecimal.ZERO); -// usersPayBefor.setCouponmoney(BigDecimal.ZERO); -// usersPayBefor.setServicetype(1L); -// usersPayBefor.setMembermoney(memberMoney); -// usersPayBefor.setType(7L); -// usersPayBefor.setSku(""); -// usersPayBefor.setStatus(1L); // 1=待支付 -// usersPayBefor.setPaytype(1L); // 默认微信支付 -// -// int payBeforResult = usersPayBeforService.insertUsersPayBefor(usersPayBefor); -// if (payBeforResult <= 0) { -// return AppletControllerUtil.appletWarning("预支付记录创建失败"); -// } - } - -// //修改订单日志添加费用 -// neworderLog.setPrice(price); -// neworderLog.setPaid(1L); -// neworderLog.setWorkerCost(price); -// neworderLog.setLogId(GenerateCustomCode.generCreateOrder("FEE")); -// //修改订单状态 -// order.setJsonStatus(3); -// JSONObject jsonObject3 = new JSONObject(); -// jsonObject3.put("type", 2); -// order.setLogJson(jsonObject3.toJSONString()); -// orderLogService.updateOrderLog(neworderLog); -// orderService.updateOrder(order); -// Users userinfo = usersService.selectUsersById(order.getUid()); -// ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); -// //给用户发送微信推送消息 -// WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(), order, serviceGoods); - } - return AjaxResult.success("设置上门费成功"); - } catch (Exception e) { - return AppletControllerUtil.appletError("设置上门费失败:" + e.getMessage()); - } - } /** * 师傅设置出发上门 @@ -6573,6 +6655,18 @@ public class AppletController extends BaseController { materialMap.put("image",AppletControllerUtil.buildImageUrl(material.getImage())); materialMap.put("price", material.getPrice() != null ? material.getPrice().toString() : "0.00"); materialMap.put("unit", material.getUnit()); + // 格式化manyimages为数组 + if (material.getManyimages() != null && !material.getManyimages().trim().isEmpty()) { + materialMap.put("manyimages", JSONArray.parseArray(material.getManyimages())); + } else { + materialMap.put("manyimages", new JSONArray()); + } + if (org.apache.commons.lang3.StringUtils.isNotBlank(material.getContent())&& org.apache.commons.lang3.StringUtils.isNotBlank(material.getManyimages())){ + materialMap.put("showtype", 1); + }else{ + materialMap.put("showtype", 2); + } + materialMap.put("content", material.getContent()); // type_id为数组,需解析 List typeIdList = new ArrayList<>(); String typeIdStr = material.getTypeId(); @@ -7147,6 +7241,171 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletSuccess("服务已完成"); } + + + + /** + * 师傅设置上门费接口 + * 参数:{"id":订单id,"price":金额} + * 逻辑:查找订单最新日志,设置workerCost和price,并设置paid=1 + */ + @PostMapping("/api/worker/set/price") + public AjaxResult setWorkerPrice(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 校验token并获取用户 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletdengluWarning("用户信息获取失败"); + } + + Long orderId = params.get("id") != null ? Long.parseLong(params.get("id").toString()) : null; + String priceStr = params.get("price") != null ? params.get("price").toString() : null; + if (orderId == null || StringUtils.isEmpty(priceStr)) { + return AppletControllerUtil.appletWarning("参数错误"); + } + BigDecimal price = new BigDecimal(priceStr); + // 查询订单 + Order order = orderService.selectOrderById(orderId); + if (order == null) { + return AppletControllerUtil.appletWarning("订单不存在"); + } + // 查询最新订单日志 + OrderLog neworderLogdata =orderLogService.selectDataTheFirstNew(order.getId()); +// neworderLogdata.setType(new BigDecimal(2.0)); +// neworderLogdata.setOid(order.getId()); +// List orderLogslist = orderLogService.selectOrderLogList(neworderLogdata); +// OrderLog neworderLog = orderLogslist.getFirst(); + if (neworderLogdata != null) { + + String logOrderId = GenerateCustomCode.generCreateOrder("DSB"); + OrderLog neworderLog =new OrderLog(); + neworderLog.setOid(order.getId()); + neworderLog.setOrderId(order.getOrderId()); + neworderLog.setLogOrderId(logOrderId); + neworderLog.setTitle("上门费"); + neworderLog.setType(neworderLogdata.getType()); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", "师傅"+user.getName()+"设置上门费"+ price+"元"); + neworderLog.setContent(jsonObject.toJSONString()); + neworderLog.setPaid(1L); + neworderLog.setPrice( price); + neworderLog.setLogId(GenerateCustomCode.generCreateOrder("FEE")); + + neworderLog.setWorkerId(user.getId()); + neworderLog.setWorkerCost( price); + neworderLog.setWorkerLogId(user.getId()); + int insert =orderLogService.insertOrderLog(neworderLog); + if (insert > 0) { + //上门费创建支付单 + BigDecimal totalAmount=neworderLog.getPrice(); + Users userinfo = usersService.selectUsersById(order.getUid()); + PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); + payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, neworderLog.getId(), + null, 7L, null, null, + null, null, null,1L,null,order.getOrderId()); + +// // 9. 计算会员优惠和服务金抵扣 +// BigDecimal memberMoney = BigDecimal.ZERO; +// BigDecimal serviceMoney = BigDecimal.ZERO; +// +// try { +// // 查询config_one配置 +// SiteConfig configQuery = new SiteConfig(); +// configQuery.setName("config_one"); +// List configList = siteConfigService.selectSiteConfigList(configQuery); +// +// if (configList != null && !configList.isEmpty()) { +// String configValue = configList.get(0).getValue(); +// if (configValue != null && !configValue.trim().isEmpty()) { +// JSONObject configJson = JSONObject.parseObject(configValue); +// +// // 计算会员优惠金额 +// if (user.getIsmember() != null && user.getIsmember() == 1) { +// // 用户是包年会员,计算会员优惠 +// Integer memberDiscount = configJson.getInteger("member_discount"); +// if (memberDiscount != null && memberDiscount > 0) { +// // 会员优惠金额 = 订单金额 * (100 - 会员折扣) / 100 +// BigDecimal discountRate = BigDecimal.valueOf(memberDiscount).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); +// if (totalAmount != null) { +// memberMoney = totalAmount.multiply(discountRate); +// } +// } +// } +// +// // 计算服务金抵扣金额 +// Integer serviceFee = configJson.getInteger("servicefee"); +// if (serviceFee != null && serviceFee > 0) { +// // 查询数据库最新用户数据 +// Users userDb = usersService.selectUsersById(user.getId()); +// if (userDb != null && userDb.getServicefee() != null && userDb.getServicefee().compareTo(BigDecimal.ZERO) > 0) { +// // 服务金抵扣金额 = 用户服务金 * 服务金比例 / 100 +// BigDecimal serviceRate = BigDecimal.valueOf(serviceFee).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); +// serviceMoney = userDb.getServicefee().multiply(serviceRate); +// } +// } +// } +// } +// } catch (Exception e) { +// logger.warn("计算会员优惠和服务金抵扣失败: " + e.getMessage()); +// memberMoney = BigDecimal.ZERO; +// serviceMoney = BigDecimal.ZERO; +// } +// +// // 10. 创建预支付记录 +// UsersPayBefor usersPayBefor = new UsersPayBefor(); +// usersPayBefor.setUid(userinfo.getId()); +// usersPayBefor.setOrderid(logOrderId); +// usersPayBefor.setOid(neworderLog.getId()); +// usersPayBefor.setPaycode(GenerateCustomCode.generCreateOrder("PAY")); +// usersPayBefor.setAllmoney(totalAmount); +// usersPayBefor.setWxmoney(totalAmount); +// usersPayBefor.setShopmoney(BigDecimal.ZERO); +// usersPayBefor.setServicemoney(serviceMoney); +// usersPayBefor.setMtmoney(BigDecimal.ZERO); +// usersPayBefor.setYemoney(BigDecimal.ZERO); +// usersPayBefor.setCouponmoney(BigDecimal.ZERO); +// usersPayBefor.setServicetype(1L); +// usersPayBefor.setMembermoney(memberMoney); +// usersPayBefor.setType(7L); +// usersPayBefor.setSku(""); +// usersPayBefor.setStatus(1L); // 1=待支付 +// usersPayBefor.setPaytype(1L); // 默认微信支付 +// +// int payBeforResult = usersPayBeforService.insertUsersPayBefor(usersPayBefor); +// if (payBeforResult <= 0) { +// return AppletControllerUtil.appletWarning("预支付记录创建失败"); +// } + } + +// //修改订单日志添加费用 +// neworderLog.setPrice(price); +// neworderLog.setPaid(1L); +// neworderLog.setWorkerCost(price); +// neworderLog.setLogId(GenerateCustomCode.generCreateOrder("FEE")); +// //修改订单状态 +// order.setJsonStatus(3); +// JSONObject jsonObject3 = new JSONObject(); +// jsonObject3.put("type", 2); +// order.setLogJson(jsonObject3.toJSONString()); +// orderLogService.updateOrderLog(neworderLog); +// orderService.updateOrder(order); +// Users userinfo = usersService.selectUsersById(order.getUid()); +// ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); +// //给用户发送微信推送消息 +// WXsendMsgUtil.sendMsgForUserDoorMoney(userinfo.getOpenid(), order, serviceGoods); + } + return AjaxResult.success("设置上门费成功"); + } catch (Exception e) { + return AppletControllerUtil.appletError("设置上门费失败:" + e.getMessage()); + } + } + + /** * 结束订单 * POST @@ -7163,6 +7422,11 @@ public class AppletController extends BaseController { if (orderInfo == null) { return AjaxResult.error("订单不存在"); } + String shangmenprice = params.get("price").toString(); +// Order orderInfo = orderService.selectOrderById(id); +// if (orderInfo == null) { +// return AjaxResult.error("订单不存在"); +// } Users workerInfo = usersService.selectUsersById(orderInfo.getWorkerId()); if (workerInfo == null) { return AjaxResult.error("师傅记录不存在"); @@ -7196,20 +7460,44 @@ public class AppletController extends BaseController { updateOrder.setId(id); updateOrder.setStatus(7L); orderService.updateOrder(updateOrder); - + String logOrderId = GenerateCustomCode.generCreateOrder("DSB"); // 3.2 插入订单日志 OrderLog log = new OrderLog(); + JSONObject jsonObject = new JSONObject(); + if (StringUtils.isNotBlank(shangmenprice)){ + log.setPaid(1L); + log.setPrice(new BigDecimal(shangmenprice)); + jsonObject.put("name","师傅提前结束订单,上门费"+shangmenprice+"元"); +// BigDecimal totalAmount=log.getPrice(); +// +// Users userinfo = usersService.selectUsersById(orderInfo.getUid()); +// PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); +// payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, log.getId(), +// null, 7L, null, null, +// null, null, null,1L,null,order.getOrderId()); + }else{ + jsonObject.put("name","师傅提前结束订单,无其他费用"); + } + + log.setLogOrderId(logOrderId); log.setOid(orderInfo.getId()); log.setOrderId(orderInfo.getOrderId()); log.setTitle("结束订单"); log.setType(BigDecimal.valueOf(10)); - log.setContent("{\"name\":\"师傅提前结束订单\"}"); + log.setContent(jsonObject.toJSONString()); //Long workerId = getCurrentWorkerId(request); // 需实现 log.setWorkerId(workerInfo.getId()); log.setCreatedAt(new Date()); log.setUpdatedAt(new Date()); orderLogService.insertOrderLog(log); - + if (StringUtils.isNotBlank(shangmenprice)){ + BigDecimal totalAmount=log.getPrice(); + Users userinfo = usersService.selectUsersById(orderInfo.getUid()); + PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); + payBeforeUtil.createPayBefore(userinfo, totalAmount, logOrderId, log.getId(), + null, 7L, null, null, + null, null, null,1L,null,orderInfo.getOrderId()); + } // 3.3 查询是否有上门费(type=2, paid=2) OrderLog doorPriceLogself = new OrderLog(); doorPriceLogself.setOid(orderInfo.getId()); @@ -7251,6 +7539,7 @@ public class AppletController extends BaseController { moneyLog.setLookday(7); moneyLog.setLookMoney(price); workerMoneyLogService.insertWorkerMoneyLog(moneyLog); + } // 3.4 解绑虚拟号 if (orderInfo.getMiddlePhone() != null) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/json.txt b/ruoyi-system/src/main/java/com/ruoyi/system/controller/json.txt index 3e204f7..b8230d6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/json.txt +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/json.txt @@ -1,53 +1,92 @@ -// 评价订单 - public function comment(Request $request) + // 个人中心 + public function index(Request $request) { - - $validator = Validator::make($request->all(),$this->comment_rule()['rules'],$this->comment_rule()['messages']); - if($validator->fails()){ - return $this->error($validator->errors()->all()[0]); - } $param = $request->post(); - // 是否已经评价过 - $info = Comment::where(['uid'=>$this->user_info['id'],'order_id'=>$param['order_id']])->first(); - if($info){ - return $this->error('请勿重复提交'); + $limit = isset($param['limit']) && $param['limit'] ? $param['limit'] : env('PAGE_LIMIT'); + + if($this->user_info['level']) + { + $this->user_info['level_info'] = WorkerLevel::select('id','image')->find($this->user_info['level']); } - $num_type = $param['num'] == 1 ? 3 : (in_array($param['num'],[2,3]) ? 2 : 1); - // 商品id - $order_info = Order::select('product_id','id','worker_id')->where(['order_id'=>$param['order_id']])->first(); - $data = [ - 'oid' => $order_info['id'], - 'order_id' => $param['order_id'], - 'product_id' => $order_info['product_id'], - 'content' => $param['content'], - 'num' => $param['num'], - 'uid' => $this->user_info['id'], - 'images' => $param['images'] ? json_encode($param['images']) : null, - 'num_type' => $num_type, - 'worker_id' => $order_info['worker_id'], - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s'), - ]; - DB::beginTransaction(); - try{ - Comment::insert($data); - // 订单评价记录 - $log_data = [ - 'oid' => $order_info['id'], - 'order_id' => $param['order_id'], - 'title' => '订单评价', - 'type' => 8, - 'content' => json_encode(['text'=>$param['content'],'image'=>$param['images'],'num'=>$data['num']]), - 'created_at'=> date('Y-m-d H:i:s'), - 'updated_at'=> date('Y-m-d H:i:s'), - ]; - Log::insert($log_data); - // 更改订单状态为完成--评价状态改为已评价 - Order::where(['order_id'=>$param['order_id']])->update(['status'=>4,'is_comment'=>1]); - DB::commit(); - return $this->success(); - }catch(\Exception $e){ - DB::rollBack(); - return $this->error('操作失败'.$e->getMessage()); + // 个人基本信息 + $data['user'] = $this->user_info; + // 质保金 + if(!$this->user_info['margin']){ + $data['user']['margin'] = 0; } + // 累计佣金 + if(!$this->user_info['total_comm']) + { + $data['user']['total_comm'] = 0; + } + // 佣金 + if(!$this->user_info['commission']) + { + $data['user']['commission'] = 0; + } + // 师傅技能 + if($this->user_info['skill_ids']) + { + $skill_ids = array_filter(json_decode($this->user_info['skill_ids'],true)); + $this->user_info['skill_arr'] = skill::whereIn('id',$skill_ids)->select('id','title')->get(); + } + // 师傅服务地区 + if($this->user_info['service_city_ids']) + { + $this->user_info['service_city_arr'] = DiyCity::whereIn('id',json_decode($this->user_info['service_city_ids'],true))->select('id','title')->get(); + } + // 等级信息 + if($this->user_info['level']) + { + $level = WorkerLevel::select('image')->find($this->user_info['level']); + if($level) $data['user']['level_img'] = $level['image']; + } + // 是否禁止接单 + if(strtotime($this->user_info['prohibit_time']) < time() && strtotime($this->user_info['prohibit_time']) + $this->user_info['prohibit_time_num']*3600 > time()){ + // 禁止剩余是啊金 + $residue_time = strtotime($this->user_info['prohibit_time']) + $this->user_info['prohibit_time_num']*3600 - time(); + $hours = intval($residue_time / 3600); + $minutes = intval(($residue_time % 3600) / 60); + $seconds = $residue_time % 60; + $str = ''; + if($hours > 0) $str .= $hours.'小时'; + if($minutes > 0) $str .= $minutes.'分钟'; + if($seconds > 0) $str .= $seconds.'秒'; + + $this->user_info['prohibit'] = '因违反平台规定,'.$this->user_info['prohibit_time_num'].'小时内禁止接单,剩余'.$str; + } + + // 我的服务订单 + // $oids = Log::where(['worker_id'=>$this->user_info['id'],'type'=>8])->pluck('oid')->toArray(); + $oids = Log::where(['worker_id'=>$this->user_info['id']])->pluck('oid')->toArray(); + + // 我的评价 + if($oids){ + $model = new Comment(); + if(isset($param['type']) && $param['type']) + { + $model = $model->where(['num_type'=>$param['type']]); + } + $data['data'] = $model->whereIn('oid',$oids) + ->with(['user'=>function($query){ + $query->select('id','name','avatar'); + }]) + ->select('id','uid','images','content','num','created_at') + ->paginate($limit); + // 总评分 + $total_num = 0; + foreach($data['data'] as &$val) + { + // 时间转换 + $val['time'] = $this->mdate($val['created_at']); + $total_num += $val['num']; + } + // 评价数量 + $data['comment']['one'] = Comment::where(['num_type'=>1])->whereIn('oid',$oids)->count(); + $data['comment']['two'] = Comment::where(['num_type'=>2])->whereIn('oid',$oids)->count(); + $data['comment']['three'] = Comment::where(['num_type'=>3])->whereIn('oid',$oids)->count(); + if(count($data['data']) < 1) $data['comment']['total'] = 0; + else $data['comment']['total'] = round($total_num/count($data['data']),1); + } + return $this->success($data); } \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletControllerUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletControllerUtil.java index 5ec7139..cdec440 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletControllerUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletControllerUtil.java @@ -42,8 +42,12 @@ public class AppletControllerUtil { private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class); + private static final IOrderService orderService = SpringUtils.getBean(IOrderService.class); private static final IUserAddressService userAddressService = SpringUtils.getBean(IUserAddressService.class); private static final IOrderCommentService orderCommentService = SpringUtils.getBean(IOrderCommentService.class); + private static final IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class); + + // ============================== 统一响应处理方法 ============================== @@ -94,7 +98,19 @@ public class AppletControllerUtil { return result; } - + /** + * 业务提示响应 - code: 422 + * + * @param message 提示消息 + * @return AjaxResult + */ + public static AjaxResult appletdengluWarning(String message) { + AjaxResult result = new AjaxResult(); + result.put("code", 422); + result.put("msg", message); + result.put("data", new ArrayList<>()); + return result; + } /** * 业务提示响应 - code:500 @@ -126,28 +142,28 @@ public class AppletControllerUtil { return result; } - /** - * Token验证失败响应 - code: 332 - * - * @return AjaxResult - */ - public static AjaxResult appletUnauthorized() { - return appletUnauthorized("用户未登录或token无效,请重新登录"); - } +// /** +// * Token验证失败响应 - code: 332 +// * +// * @return AjaxResult +// */ +// public static AjaxResult appletUnauthorized() { +// return appletUnauthorized("用户未登录或token无效,请重新登录"); +// } - /** - * Token验证失败响应 - code: 332,自定义消息 - * - * @param message 提示消息 - * @return AjaxResult - */ - public static AjaxResult appletUnauthorized(String message) { - AjaxResult result = new AjaxResult(); - result.put("code", 332); - result.put("msg", message); - result.put("data", new ArrayList<>()); - return result; - } +// /** +// * Token验证失败响应 - code: 332,自定义消息 +// * +// * @param message 提示消息 +// * @return AjaxResult +// */ +// public static AjaxResult appletUnauthorized(String message) { +// AjaxResult result = new AjaxResult(); +// result.put("code", 422); +// result.put("msg", message); +// result.put("data", new ArrayList<>()); +// return result; +// } /** * 系统错误响应 - code: 500 @@ -2625,22 +2641,74 @@ public class AppletControllerUtil { * @param order 订单主键 * @return 是否可用 */ - public static Users creatWorkerForOrder(Order order) { - GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil(); + public static Users creatWorkerForOrder(Order order,Users worker) { + + order.setWorkerId(worker.getId()); + order.setStatus(1L); + order.setIsPause(1); + order.setReceiveTime(new Date()); + order.setWorkerPhone(worker.getPhone()); UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId()); -// if (userAddress != null){ -// String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude()); -// if (city != null){ -// -// }else{ -// -// } -// } - Users worker = usersService.selectUsersById(2l); + if (userAddress != null){ + order.setUserPhone(userAddress.getPhone()); + } + order.setMiddlePhone("18339212639"); + order.setReceiveType(3l); + order.setLogStatus(9); + JSONObject jSONObject = new JSONObject(); + jSONObject.put("type", 9); + order.setLogJson(jSONObject.toJSONString()); + orderService.updateOrder(order); + + + OrderLog orderLognew = new OrderLog(); + orderLognew.setOid(order.getId()); + orderLognew.setOrderId(order.getOrderId()); + orderLognew.setTitle("系统派单"); + orderLognew.setType(new BigDecimal(1.1)); + JSONObject jSONObject1 = new JSONObject(); + jSONObject1.put("name", "师傅收到派单信息"); + orderLognew.setContent(jSONObject1.toJSONString()); + orderLognew.setWorkerId(worker.getId()); + orderLognew.setWorkerLogId(worker.getId()); + orderLogService.insertOrderLog(orderLognew); + +// GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil(); +// UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId()); +//// if (userAddress != null){ +//// String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude()); +//// if (city != null){ +//// +//// }else{ +//// +//// } +//// } +// // Users worker = usersService.selectUsersById(2l); return worker; } + + + + + + + + // Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData); +// +// if (worker != null) { +// // 更新订单状态为已派单 + +// // 添加派单日志 + +// // 发送通知 +// WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods); +// YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone()); +// } + + + /** * 判断时间段是否可用 * @@ -4492,7 +4560,7 @@ public class AppletControllerUtil { // 1. 验证用户token Map tokenValidation = validateUserToken(token, usersService); if (!(Boolean) tokenValidation.get("valid")) { - return appletUnauthorized((String) tokenValidation.get("message")); + return appletdengluWarning((String) tokenValidation.get("message")); } // 从tokenValidation中获取用户信息Map,然后提取userId diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/OrderUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/OrderUtil.java index e901033..0563b10 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/OrderUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/OrderUtil.java @@ -6,6 +6,7 @@ import com.ruoyi.common.utils.AmapUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.*; import com.ruoyi.system.service.*; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Controller; import java.math.BigDecimal; @@ -25,6 +26,8 @@ public class OrderUtil { private static IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class); private static IGoodsOrderService goodsOrderService = SpringUtils.getBean(IGoodsOrderService.class); private static IUserDemandQuotationService userDemandQuotationService = SpringUtils.getBean(IUserDemandQuotationService.class); + private static IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class); + private static IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class); private static OrderLogHandler orderLogHandler = SpringUtils.getBean(OrderLogHandler.class); @@ -32,6 +35,43 @@ public class OrderUtil { private static final String PREFIX = "C"; private static final int FIXED_LENGTH = 15; // 总长度为15 + + /** + * 创建新用户对象 + * + * @return 新用户对象 + */ + public static JSONObject getbaojiajson(String json) { + if (StringUtils.isNotBlank(json)) { + JSONObject jsonObject = JSONObject.parseObject(json); + JSONArray material = jsonObject.getJSONArray("material"); + if (material != null) { + for (int i = 0; i < material.size(); i++) { + JSONObject jsonObjectmaterial = material.getJSONObject(i); + String id = jsonObjectmaterial.getString("id"); + if (StringUtils.isNotBlank(id)) { + QuoteMaterial quoteMaterial = quoteMaterialService.selectQuoteMaterialById(Long.parseLong(id)); + if (quoteMaterial != null) { + jsonObjectmaterial.put("manyimages", JSONArray.parseArray(quoteMaterial.getManyimages())); + jsonObjectmaterial.put("image", AppletControllerUtil.buildImageUrl(quoteMaterial.getImage())); + if (StringUtils.isNotBlank(quoteMaterial.getContent()) && StringUtils.isNotBlank(quoteMaterial.getManyimages())) { + jsonObjectmaterial.put("showtype", 1); + } else { + jsonObjectmaterial.put("showtype", 2); + } + jsonObjectmaterial.put("content", quoteMaterial.getContent()); + } + } + } + } + // 直接返回原始jsonObject,其他字段都保留 + return jsonObject; + } + return new JSONObject(); + } + + + /** * 生成订单编码的工具 * @@ -601,8 +641,7 @@ public class OrderUtil { IOrderService orderService = SpringUtils.getBean(IOrderService.class); // 拼团 - if (payBefor.getServicetype()==2){ - System.out.println("=== 处理拼团商品订单 ==="); + if (type == 6){ GoodsOrder gorder = new GoodsOrder(); gorder.setMainOrderId(payBefor.getOrderid()); System.out.println("查询拼团商品订单 - orderid: " + payBefor.getOrderid()); @@ -626,6 +665,15 @@ public class OrderUtil { return payBefor.getOrderid(); } // 7上门费 8定金 9尾款 10差价 + if (type == 11) { + GoodsOrder order = goodsOrderService.selectGoodsOrderByorderId(payBefor.getOrderid()); + if (order != null) { + order.setStatus(2L); + order.setTransactionId(payBefor.getPaycode()); + int updateResult = goodsOrderService.updateGoodsOrder(order); + } + return null; + } if (type == 7) { // 4. 查询对应的订单日志(上门费记录) OrderLog orderLog = orderLogService.selectOrderLogById(payBefor.getOid()); @@ -639,7 +687,7 @@ public class OrderUtil { if (updateResult > 0){ ISTOPAYSIZE(payBefor.getLastorderid()); } - +// int paynum=usersPayBeforService.countByLastOrderIdAndStatus(order.getOrderId(), 1); // Order order = orderService.selectOrderByOrderId(payBefor.getLastorderid()); // if (order != null) { // if (order.getStatus() == 6){ @@ -672,17 +720,17 @@ public class OrderUtil { OrderLog orderLog = orderLogService.selectDataTheFirstNew(order.getId()); orderLog.setPayTime(System.currentTimeMillis()/1000); orderLog.setPaid(2L); - orderLogService.updateOrderLog(orderLog); - OrderLog orderLog1 = orderLogService.selectOrderLogById(payBefor.getOid()); + int updateResult = orderLogService.updateOrderLog(orderLog); + // OrderLog orderLog1 = orderLogService.selectOrderLogById(payBefor.getOid()); // 6. 更新订单支付状态 - order.setStatus(4L); // 2:已支付 - // order.setTransactionId(transactionId); - order.setPayTime(new Date()); - //order.setUpdateTime(new Date()); - // 计算实际支付金额(分转换为元) - BigDecimal paidAmount = orderLog1.getPrice(); - order.setPayPrice(paidAmount); - int updateResult = orderService.updateOrder(order); +// order.setStatus(4L); // 2:已支付 +// // order.setTransactionId(transactionId); +// order.setPayTime(new Date()); +// //order.setUpdateTime(new Date()); +// // 计算实际支付金额(分转换为元) +// BigDecimal paidAmount = orderLog1.getPrice(); +// order.setPayPrice(paidAmount); + // int updateResult = orderService.updateOrder(order); if (updateResult > 0){ ISTOPAYSIZE(payBefor.getLastorderid()); } @@ -768,6 +816,21 @@ public class OrderUtil { System.out.println("需求报价订单处理失败,返回null"); return null; } + if (type == 2) { + System.out.println("处理次卡订单"); + IUserUseSecondaryCardService userUseSecondaryCardService = SpringUtils.getBean(IUserUseSecondaryCardService.class); + UserUseSecondaryCard userUseSecondaryCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(payBefor.getOrderid()); + System.out.println("查询到的次卡记录: " + (userUseSecondaryCard != null ? userUseSecondaryCard.toString() : "null")); + + if (userUseSecondaryCard != null) { + System.out.println("更新次卡状态"); + userUseSecondaryCard.setStatus(1L); + int cardUpdateResult = userUseSecondaryCardService.updateUserUseSecondaryCard(userUseSecondaryCard); + System.out.println("次卡状态更新结果: " + cardUpdateResult); + } + return null; + } + if (type == 1) { System.out.println("=== 处理拼团订单 ==="); String ptorderid= payBefor.getOrderid(); @@ -875,22 +938,22 @@ public class OrderUtil { UserGroupBuying userGroupBuyingData = new UserGroupBuying(); userGroupBuyingData.setOrderid(payBefor.getGrouporderid()); userGroupBuyingData.setPaystatus(1L); - userGroupBuyingData.setStatus(2L); + userGroupBuyingData.setStatus(1L); List userGroupBuyingList = userGroupBuyingService.selectUserGroupBuyingList(userGroupBuyingData); System.out.println("已支付的拼团人数: " + (userGroupBuyingList != null ? userGroupBuyingList.size() : 0)); - - if (userGroupBuyingList.size() >= serviceGoods.getGroupnum()) { + + if (userGroupBuyingList != null && serviceGoods != null && userGroupBuyingList.size() >= serviceGoods.getGroupnum()) { System.out.println("拼团人数已满足要求,开始更新所有拼团订单状态"); - for (UserGroupBuying groupBuying1 : userGroupBuyingList){ + for (UserGroupBuying groupBuying1 : userGroupBuyingList) { System.out.println("更新拼团记录 - ID: " + groupBuying1.getId() + ", 订单ID: " + groupBuying1.getPtorderid()); groupBuying1.setStatus(2L); groupBuying1.setPaystatus(1L); int groupUpdateResult = userGroupBuyingService.updateUserGroupBuying(groupBuying1); System.out.println("拼团记录更新结果: " + groupUpdateResult); - + Order orderdata = orderService.selectOrderByOrderId(groupBuying1.getPtorderid()); System.out.println("查询到的订单: " + (orderdata != null ? orderdata.getOrderId() : "null")); - if (orderdata != null){ + if (orderdata != null) { System.out.println("更新订单状态为已成团待预约"); orderdata.setStatus(10L);//已成团待预约 int orderUpdateResult = orderService.updateOrder(orderdata); @@ -898,8 +961,6 @@ public class OrderUtil { } } System.out.println("拼团成功,所有订单状态已更新"); - } else { - System.out.println("拼团人数未满足要求,继续等待"); } System.out.println("拼团订单处理完成,返回order: " + order.getOrderId()); dispatchOrderCheck(order); @@ -1033,21 +1094,22 @@ public class OrderUtil { public static int ISTOPAYSIZE(String orderid) { IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class); IOrderService orderService = SpringUtils.getBean(IOrderService.class); - UsersPayBefor payBefore = new UsersPayBefor(); - payBefore.setLastorderid(orderid); - payBefore.setStatus(1L); - List payBeforeList = usersPayBeforService.selectUsersPayBeforList(payBefore); - Order order = orderService.selectOrderByOrderId(orderid); - if (order != null) { - if (order.getStatus() == 6){ - if (payBeforeList.isEmpty()){ - order.setStatus(4L); + int count = usersPayBeforService.countByLastOrderIdAndStatus(orderid); + System.out.println("count订单日志: " +count); + if(count <= 0){ + Order order = orderService.selectOrderByOrderId(orderid); + if(order != null){ + OrderLog orderLog = orderLogService.selectDataTheFirstNew(order.getId()); + System.out.println("订单日志: " + (orderLog != null ? orderLog.toString() : "null")); + System.out.println("orderLog.getType()订单日志: " + orderLog.getType()); + if(orderLog.getType().compareTo(new BigDecimal("6")) > 0){ + // 修改订单状态为6 + order.setStatus(6L); orderService.updateOrder(order); } - } } - return payBeforeList.size(); + return count; } @@ -1113,4 +1175,87 @@ public class OrderUtil { result.put("msg", "无需指定工人派单"); return result; } + + /** + * 获取维修订单派单师傅列表 + * @param orderId 订单id + * @return 符合条件的师傅列表 + */ + public static List getDispatchWorkerList(Long orderId) { + IUsersService usersService = SpringUtils.getBean(IUsersService.class); + IOrderService orderService = SpringUtils.getBean(IOrderService.class); + IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class); + IUserAddressService userAddressService = SpringUtils.getBean(IUserAddressService.class); + List result = new ArrayList<>(); + // 2. 查询订单、服务、地址 + Order order = orderService.selectOrderById(orderId); + if (order == null) return result; + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + if (serviceGoods == null) return result; + UserAddress address = userAddressService.selectUserAddressById(order.getAddressId()); + if (address == null) return result; + // 服务技能要求 + List requiredSkills = new ArrayList<>(); + if (serviceGoods.getSkillIds() != null && !serviceGoods.getSkillIds().trim().isEmpty()) { + requiredSkills = JSONArray.parseArray(serviceGoods.getSkillIds(), String.class); + } + // 1. 查找当日签到过的师傅(type=2,is_stop=0,worker_time为当天) + String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + Users query = new Users(); + query.setType("2"); + query.setWorkerTimeStr(today); + query.setSkillArr(requiredSkills); + query.setIsStop(0); + List signedWorkers = usersService.selectUsersList(query); + if (signedWorkers.isEmpty()) return result; + // 3. 逐个师傅筛选技能和服务区域 + for (Users worker : signedWorkers) { +// // 技能匹配 +// boolean skillMatch = false; +// if (worker.getSkillIds() != null && !worker.getSkillIds().trim().isEmpty() && !requiredSkills.isEmpty()) { +// List workerSkills = com.alibaba.fastjson.JSONArray.parseArray(worker.getSkillIds(), String.class); +// for (String s : requiredSkills) { +// if (workerSkills.contains(s)) { +// skillMatch = true; +// break; +// } +// } +// } +// if (!skillMatch) continue; +// // 区域匹配 +// boolean areaMatch = false; +// // 假设addressInfo字段中包含城市ID(如有cityId字段请替换) +// String addressCityId = null; +// if (address.getAddressInfo() != null) { +// addressCityId = address.getAddressInfo(); // 这里请根据实际情况提取城市ID +// } +// if (worker.getServiceCityIds() != null && !worker.getServiceCityIds().trim().isEmpty() && addressCityId != null) { +// List workerAreas = com.alibaba.fastjson.JSONArray.parseArray(worker.getServiceCityIds(), String.class); +// if (workerAreas.contains(addressCityId)) { +// areaMatch = true; +// } +// } +// if (!areaMatch) continue; + result.add(worker); + } + // 排序:先按等级降序,再按质保金降序 + result.sort((a, b) -> { + int levelA = a.getLevel() != null ? a.getLevel() : 0; + int levelB = b.getLevel() != null ? b.getLevel() : 0; + int cmp = Integer.compare(levelB, levelA); + if (cmp != 0) return cmp; + BigDecimal marginA = a.getMargin() != null ? a.getMargin() : BigDecimal.ZERO; + BigDecimal marginB = b.getMargin() != null ? b.getMargin() : BigDecimal.ZERO; + return marginB.compareTo(marginA); + }); + return result; + } + + public static void main(String[] args) { + // 构造一个测试用的json字符串 + String testJson = "{\"project\":{\"name\":\"项目费用\",\"price\":1132.00},\"reduction\":{\"name\":\"优惠金额\",\"price\":\"1\"},\"deposit\":{\"name\":\"定金\",\"price\":\"10\"},\"basic\":[{\"name\":\"测试基建2\",\"select\":true},{\"name\":\"测试基建5\",\"select\":true},{\"name\":\"测试基建8\",\"select\":true}],\"craft\":[{\"name\":\"三挂一方柜\",\"price\":\"336.00\",\"pid\":192,\"id\":1889,\"count\":3}],\"material\":[{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1241,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1240,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":92,\"count\":1},{\"name\":\"111\",\"price\":\"10.00\",\"id\":1250,\"pid\":92,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":92,\"count\":2}]}"; + OrderUtil util = new OrderUtil(); + JSONObject result = util.getbaojiajson(testJson); + System.out.println("处理后的结果: " + result.toJSONString()); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/PayBeforeUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/PayBeforeUtil.java index 5859a35..84805e0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/PayBeforeUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/PayBeforeUtil.java @@ -345,7 +345,7 @@ public class PayBeforeUtil { * @param orderLog 订单日志实体 * @param baojiajson 报价json字符串 */ - public void handleQuotationPayBefore(Users user, OrderLog orderLog, String baojiajson) { + public void handleQuotationPayBefore(Users user, OrderLog orderLog, String baojiajson,String lastorderid) { if (user == null || orderLog == null || baojiajson == null || baojiajson.trim().isEmpty()) { return; } @@ -368,7 +368,7 @@ public class PayBeforeUtil { orderLog.getId(), // oid null, // serviceId 8L, // type=8 定金 - null, null, null, null, null, 1L, null, orderLog.getOrderId() + null, null, null, null, null, 1L, null, lastorderid ); } } @@ -403,7 +403,7 @@ public class PayBeforeUtil { orderLog.getId(), // oid null, // serviceId 9L, // type=9 尾款 - null, null, null, null, null, 1L, null, orderLog.getOrderId() + null, null, null, null, null, 1L, null, lastorderid ); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayV3Util.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayV3Util.java index 601c861..88a5ef5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayV3Util.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayV3Util.java @@ -31,7 +31,7 @@ import java.util.*; /** * 微信支付V3工具类 - * + * * 提供微信支付V3 API的完整功能实现: * 1. JSAPI支付(小程序支付) * 2. 申请退款 @@ -40,7 +40,7 @@ import java.util.*; * 5. 查询转账 * 6. V3签名生成和验证 * 7. 敏感字段解密 - * + * * @author Mr. Zhang Pan * @version 2.0 * @date 2025-01-17 @@ -50,7 +50,7 @@ public class WechatPayV3Util { private static final Logger log = LoggerFactory.getLogger(WechatPayV3Util.class); private static final RestTemplate restTemplate = createRestTemplate(); - + // 微信支付V3 API地址 private static final String V3_BASE_URL = "https://api.mch.weixin.qq.com"; private static final String JSAPI_PAY_URL = "/v3/pay/transactions/jsapi"; @@ -58,7 +58,7 @@ public class WechatPayV3Util { private static final String TRANSFER_BATCH_URL = "/v3/transfer/batches"; private static final String QUERY_REFUND_URL = "/v3/refund/domestic/refunds/"; private static final String QUERY_TRANSFER_URL = "/v3/transfer/batches/out-batch-no/"; - + // 算法常量 private static final String ALGORITHM_RSA_SHA256 = "SHA256withRSA"; private static final String ALGORITHM_AES_GCM = "AES/GCM/NoPadding"; @@ -77,7 +77,7 @@ public class WechatPayV3Util { private static WechatConfig wechatConfig() { WechatConfig config = SpringUtils.getBean(WechatConfig.class); - log.info("📋 获取微信配置成功 - AppID: {}, MchID: {}", + log.info("📋 获取微信配置成功 - AppID: {}, MchID: {}", maskSensitiveData(config.getAppid()), maskSensitiveData(config.getMchid())); return config; } @@ -104,10 +104,10 @@ public class WechatPayV3Util { log.info(" ├─ 时间戳: {}", timestamp); log.info(" ├─ 随机字符串: {}", nonceStr); log.info(" └─ 请求体长度: {} 字符", body != null ? body.length() : 0); - + String message = method + "\n" + url + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n"; log.debug("🔍 待签名字符串: \n{}", message); - + try { PrivateKey privateKey = getPrivateKey(); Signature signature = Signature.getInstance(ALGORITHM_RSA_SHA256); @@ -130,10 +130,10 @@ public class WechatPayV3Util { long timestamp = System.currentTimeMillis() / 1000; String nonceStr = generateNonceStr(); String signature = buildSignature(method, url, timestamp, nonceStr, body); - + String authHeader = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", wechatConfig().getMchid(), nonceStr, signature, timestamp, wechatConfig().getSerialNo()); - + log.info("✅ Authorization头构建成功"); log.debug("🔍 Authorization: {}", authHeader); return authHeader; @@ -141,7 +141,7 @@ public class WechatPayV3Util { /** * 构建通用请求头 - * + * * @param method HTTP方法 * @param url 请求URL * @param body 请求体 @@ -153,7 +153,7 @@ public class WechatPayV3Util { /** * 构建通用请求头 - * + * * @param method HTTP方法 * @param url 请求URL * @param body 请求体 @@ -163,56 +163,56 @@ public class WechatPayV3Util { private HttpHeaders buildCommonHeaders(String method, String url, String body, boolean includeWechatpaySerial) { log.info("📤 开始构建请求头"); HttpHeaders headers = new HttpHeaders(); - + // 构建Authorization头 headers.set("Authorization", buildAuthorizationHeader(method, url, body)); - + // 设置基本头部 headers.set("Content-Type", "application/json"); headers.set("Accept", "application/json"); headers.set("User-Agent", "RuoYi-WechatPay-V3"); - + // 重要:添加微信支付平台证书序列号 if (includeWechatpaySerial) { // 根据微信支付V3文档,对于转账接口,可以暂时不设置Wechatpay-Serial头 String wechatpaySerial = getWechatpayPlatformSerial(); - if (wechatpaySerial != null && !wechatpaySerial.trim().isEmpty() && - !wechatpaySerial.equals(wechatConfig().getSerialNo())) { + if (wechatpaySerial != null && !wechatpaySerial.trim().isEmpty() && + !wechatpaySerial.equals(wechatConfig().getSerialNo())) { // 只有当平台证书序列号与商户证书序列号不同时才设置 headers.set("Wechatpay-Serial", wechatpaySerial); log.info(" ├─ 已添加微信支付平台证书序列号: {}", maskSensitiveData(wechatpaySerial)); } else { // 临时使用商户证书序列号 headers.set("Wechatpay-Serial", wechatConfig().getSerialNo()); - log.warn(" ⚠️ 使用商户证书序列号作为平台证书序列号: {}", + log.warn(" ⚠️ 使用商户证书序列号作为平台证书序列号: {}", maskSensitiveData(wechatConfig().getSerialNo())); } } else { log.info(" ├─ 跳过Wechatpay-Serial头设置(测试模式)"); } - + log.info("✅ 请求头构建完成"); - log.debug("🔍 请求头详情: Authorization=[已隐藏], Wechatpay-Serial={}", + log.debug("🔍 请求头详情: Authorization=[已隐藏], Wechatpay-Serial={}", headers.getFirst("Wechatpay-Serial")); - + return headers; } /** * 获取微信支付平台证书序列号 * 优先从配置中获取,如果没有配置则尝试自动获取 - * + * * @return 微信支付平台证书序列号 */ private String getWechatpayPlatformSerial() { // 优先从配置文件中获取微信支付平台证书序列号 String wechatpaySerial = wechatConfig().getWechatpaySerial(); - + if (wechatpaySerial != null && !wechatpaySerial.trim().isEmpty()) { log.debug("🔍 从配置中获取微信支付平台证书序列号: {}", maskSensitiveData(wechatpaySerial)); return wechatpaySerial; } - + // 如果配置中没有,尝试自动获取 try { String autoSerial = getWechatpaySerialFromApi(); @@ -223,7 +223,7 @@ public class WechatPayV3Util { } catch (Exception e) { log.warn("⚠️ 自动获取微信支付平台证书序列号失败: {}", e.getMessage()); } - + // 如果都没有,返回null,将使用商户证书序列号作为临时方案 log.debug("🔍 未配置微信支付平台证书序列号,将使用商户证书序列号"); return null; @@ -231,7 +231,7 @@ public class WechatPayV3Util { /** * 从API自动获取微信支付平台证书序列号 - * + * * @return 平台证书序列号 */ private String getWechatpaySerialFromApi() { @@ -248,14 +248,14 @@ public class WechatPayV3Util { try { String privateKeyPath = wechatConfig().getPrivateKeyPath(); log.info(" ├─ 私钥文件路径: {}", privateKeyPath); - + // 处理不同类型的路径 String privateKeyContent = null; if (privateKeyPath.startsWith("classpath:")) { // classpath路径处理 String resourcePath = privateKeyPath.substring(10); log.info(" ├─ 解析classpath路径: {}", resourcePath); - + try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resourcePath)) { if (inputStream == null) { throw new RuntimeException("无法找到classpath资源: " + resourcePath); @@ -279,30 +279,30 @@ public class WechatPayV3Util { log.info(" ├─ 从classpath读取私钥成功,内容长度: {} 字符", privateKeyContent.length()); } } - + if (privateKeyContent == null || privateKeyContent.trim().isEmpty()) { throw new RuntimeException("私钥文件内容为空"); } - + // 清理私钥内容格式 log.info(" ├─ 开始清理私钥格式"); privateKeyContent = privateKeyContent .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s+", ""); - + if (privateKeyContent.isEmpty()) { throw new RuntimeException("清理后的私钥内容为空,请检查私钥文件格式"); } - + log.info(" ├─ 私钥格式清理完成,Base64内容长度: {} 字符", privateKeyContent.length()); - + // 解码并生成私钥 byte[] keyBytes = Base64.getDecoder().decode(privateKeyContent); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(spec); - + log.info("✅ 商户私钥加载成功,算法: {}", privateKey.getAlgorithm()); return privateKey; } catch (Exception e) { @@ -328,19 +328,19 @@ public class WechatPayV3Util { log.info(" ├─ 附加数据: {}", associatedData); log.info(" ├─ 随机串长度: {} 字符", nonce != null ? nonce.length() : 0); log.info(" └─ 密文长度: {} 字符", ciphertext != null ? ciphertext.length() : 0); - + try { byte[] key = wechatConfig().getApiv3Key().getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKey = new SecretKeySpec(key, "AES"); - + Cipher cipher = Cipher.getInstance(ALGORITHM_AES_GCM); GCMParameterSpec spec = new GCMParameterSpec(128, nonce.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8)); - + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext)); String decryptedValue = new String(decryptedBytes, StandardCharsets.UTF_8); - + log.info("✅ AES-GCM解密成功,明文长度: {} 字符", decryptedValue.length()); return decryptedValue; } catch (Exception e) { @@ -353,7 +353,7 @@ public class WechatPayV3Util { /** * 申请退款 - * + * * @param orderNo 商户订单号 * @param refundNo 退款单号 * @param totalFee 订单总金额(分) @@ -370,9 +370,9 @@ public class WechatPayV3Util { log.info(" ├─ 退款金额: {} 分 ({}元)", refundFee, fenToYuan(refundFee)); log.info(" ├─ 退款原因: {}", reason); log.info(" └─ 回调地址: {}", notifyUrl); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -382,14 +382,14 @@ public class WechatPayV3Util { result.put("message", "商户订单号不能为空"); return result; } - + if (refundNo == null || refundNo.trim().isEmpty()) { log.warn("❌ 参数验证失败: 退款单号不能为空"); result.put("success", false); result.put("message", "退款单号不能为空"); return result; } - + if (refundFee <= 0 || refundFee > totalFee) { log.warn("❌ 参数验证失败: 退款金额无效 (退款金额: {}, 订单金额: {})", refundFee, totalFee); result.put("success", false); @@ -397,56 +397,56 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + // 构建请求参数 log.info("🔧 开始构建请求参数"); Map amount = new HashMap<>(); amount.put("refund", refundFee); amount.put("total", totalFee); amount.put("currency", "CNY"); - + Map params = new HashMap<>(); params.put("out_trade_no", orderNo); params.put("out_refund_no", refundNo); params.put("reason", reason != null ? reason : "用户申请退款"); params.put("amount", amount); - + if (notifyUrl != null && !notifyUrl.trim().isEmpty()) { params.put("notify_url", notifyUrl); } - + String bodyJson = JSONObject.toJSONString(params); log.info("✅ 请求参数构建完成"); log.debug("🔍 请求体JSON: {}", bodyJson); - + // 构建请求头 HttpHeaders headers = buildCommonHeaders("POST", REFUND_URL, bodyJson); - + // 发送请求 String fullUrl = V3_BASE_URL + REFUND_URL; log.info("🚀 开始发送退款请求"); log.info(" ├─ 请求方法: POST"); log.info(" ├─ 请求地址: {}", fullUrl); log.info(" └─ 请求体大小: {} 字节", bodyJson.getBytes(StandardCharsets.UTF_8).length); - + HttpEntity requestEntity = new HttpEntity<>(bodyJson, headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.POST, - requestEntity, + fullUrl, + HttpMethod.POST, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到退款响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("✅ 退款申请成功"); log.info("🔍 响应详情:"); if (jsonResponse != null) { @@ -456,7 +456,7 @@ public class WechatPayV3Util { log.info(" └─ 退款金额: {} 分", jsonResponse.getJSONObject("amount").getInteger("refund")); } log.debug("🔍 完整响应: {}", responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("message", "申请退款成功"); @@ -464,34 +464,34 @@ public class WechatPayV3Util { log.error("❌ 退款申请失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "申请退款失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 退款申请异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "申请退款异常:" + e.getMessage()); } - + log.info("🏁 退款申请流程结束,结果: {}", result.get("success")); return result; } /** * 查询退款 - * + * * @param refundNo 退款单号 * @return 退款查询结果 */ public Map queryRefund(String refundNo) { log.info("🔍 开始查询退款"); log.info(" └─ 退款单号: {}", refundNo); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -502,36 +502,36 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + String url = QUERY_REFUND_URL + refundNo; String fullUrl = V3_BASE_URL + url; - + // 构建请求头 HttpHeaders headers = buildCommonHeaders("GET", url, ""); - + // 发送请求 log.info("🚀 开始发送查询请求"); log.info(" ├─ 请求方法: GET"); log.info(" └─ 请求地址: {}", fullUrl); - + HttpEntity requestEntity = new HttpEntity<>(headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.GET, - requestEntity, + fullUrl, + HttpMethod.GET, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到查询响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("✅ 退款查询成功"); log.info("🔍 查询结果:"); if (jsonResponse != null) { @@ -541,7 +541,7 @@ public class WechatPayV3Util { log.info(" └─ 退款渠道: {}", jsonResponse.getString("channel")); } log.debug("🔍 完整响应: {}", responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("message", "查询退款成功"); @@ -549,18 +549,18 @@ public class WechatPayV3Util { log.error("❌ 退款查询失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "查询退款失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 退款查询异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "查询退款异常:" + e.getMessage()); } - + log.info("🏁 退款查询流程结束,结果: {}", result.get("success")); return result; } @@ -569,7 +569,7 @@ public class WechatPayV3Util { /** * 商户提现(转账到零钱) - * + * * @param openid 用户openid * @param amount 金额(分) * @param desc 提现描述 @@ -582,9 +582,9 @@ public class WechatPayV3Util { log.info(" ├─ 提现金额: {} 分 ({}元)", amount, fenToYuan(amount)); log.info(" ├─ 提现描述: {}", desc); log.info(" └─ 真实姓名: {}", userName != null ? maskSensitiveData(userName) : "未提供"); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -594,7 +594,7 @@ public class WechatPayV3Util { result.put("message", "用户openid不能为空"); return result; } - + if (amount <= 0) { log.warn("❌ 参数验证失败: 提现金额必须大于0,当前: {}", amount); result.put("success", false); @@ -602,14 +602,14 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + // 生成批次号和明细号(只包含数字和字母) String outBatchNo = generateValidBatchNo("WITHDRAW"); String detailNo = generateValidBatchNo("DETAIL"); log.info("🆔 生成业务单号"); log.info(" ├─ 批次号: {}", outBatchNo); log.info(" └─ 明细号: {}", detailNo); - + // 构建转账明细 log.info("🔧 开始构建转账明细"); Map detail = new HashMap<>(); @@ -617,7 +617,7 @@ public class WechatPayV3Util { detail.put("transfer_amount", amount); detail.put("transfer_remark", desc != null ? desc : "用户提现"); detail.put("openid", openid); - + // 如果提供了真实姓名,进行RSA加密 if (userName != null && !userName.trim().isEmpty()) { log.info("🔒 开始加密用户姓名"); @@ -627,10 +627,10 @@ public class WechatPayV3Util { } else { log.info(" └─ 未提供用户姓名,跳过实名校验"); } - + List> detailList = new ArrayList<>(); detailList.add(detail); - + // 构建请求参数 log.info("🔧 开始构建请求参数"); Map params = new HashMap<>(); @@ -645,46 +645,46 @@ public class WechatPayV3Util { String bodyJson = JSONObject.toJSONString(params); log.info("✅ 请求参数构建完成"); log.debug("🔍 请求体JSON: {}", bodyJson); - + // 构建请求头 HttpHeaders headers = buildCommonHeaders("POST", TRANSFER_BATCH_URL, bodyJson); - + // 发送请求 String fullUrl = V3_BASE_URL + TRANSFER_BATCH_URL; log.info("🚀 开始发送提现请求"); log.info(" ├─ 请求方法: POST"); log.info(" ├─ 请求地址: {}", fullUrl); log.info(" └─ 请求体大小: {} 字节", bodyJson.getBytes(StandardCharsets.UTF_8).length); - + HttpEntity requestEntity = new HttpEntity<>(bodyJson, headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.POST, - requestEntity, + fullUrl, + HttpMethod.POST, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到提现响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("🔓 开始解密敏感字段"); // 解密敏感字段(如果有) decryptSensitiveFields(jsonResponse); - + // 提取关键信息 Map transferInfo = new HashMap<>(); transferInfo.put("out_batch_no", outBatchNo); transferInfo.put("batch_id", jsonResponse.getString("batch_id")); transferInfo.put("create_time", jsonResponse.getString("create_time")); transferInfo.put("batch_status", jsonResponse.getString("batch_status")); - + log.info("✅ 提现申请成功"); log.info("🔍 提现详情:"); log.info(" ├─ 微信批次ID: {}", jsonResponse.getString("batch_id")); @@ -692,7 +692,7 @@ public class WechatPayV3Util { log.info(" ├─ 创建时间: {}", jsonResponse.getString("create_time")); log.info(" └─ 商户批次号: {}", outBatchNo); log.debug("🔍 完整响应: {}", responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("transfer_info", transferInfo); @@ -701,25 +701,25 @@ public class WechatPayV3Util { log.error("❌ 提现申请失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "提现申请失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 提现申请异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "提现异常:" + e.getMessage()); } - + log.info("🏁 提现申请流程结束,结果: {}", result.get("success")); return result; } /** * 查询转账批次 - * + * * @param outBatchNo 商户批次单号 * @param needDetail 是否需要转账明细 * @return 转账查询结果 @@ -728,9 +728,9 @@ public class WechatPayV3Util { log.info("🔍 开始查询转账"); log.info(" ├─ 批次单号: {}", outBatchNo); log.info(" └─ 是否需要明细: {}", needDetail); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -741,44 +741,44 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + String url = QUERY_TRANSFER_URL + outBatchNo; if (needDetail) { url += "?need_query_detail=true&detail_status=ALL"; log.info("📝 已添加查询明细参数"); } String fullUrl = V3_BASE_URL + url; - + // 构建请求头 HttpHeaders headers = buildCommonHeaders("GET", url, ""); - + // 发送请求 log.info("🚀 开始发送查询请求"); log.info(" ├─ 请求方法: GET"); log.info(" └─ 请求地址: {}", fullUrl); - + HttpEntity requestEntity = new HttpEntity<>(headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.GET, - requestEntity, + fullUrl, + HttpMethod.GET, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到查询响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("🔓 开始解密敏感字段"); // 解密敏感字段(如果有) decryptSensitiveFields(jsonResponse); - + log.info("✅ 转账查询成功"); log.info("🔍 查询结果:"); if (jsonResponse != null) { @@ -788,7 +788,7 @@ public class WechatPayV3Util { log.info(" └─ 创建时间: {}", jsonResponse.getString("create_time")); } log.debug("🔍 完整响应: {}", responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("message", "查询转账成功"); @@ -796,18 +796,18 @@ public class WechatPayV3Util { log.error("❌ 转账查询失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "查询转账失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 转账查询异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "查询转账异常:" + e.getMessage()); } - + log.info("🏁 转账查询流程结束,结果: {}", result.get("success")); return result; } @@ -822,7 +822,7 @@ public class WechatPayV3Util { log.debug("🔓 无需解密:响应为空"); return; } - + log.info("🔓 开始递归解密敏感字段"); int decryptedCount = decryptObjectFields(jsonResponse); log.info("✅ 敏感字段解密完成,共解密 {} 个字段", decryptedCount); @@ -830,23 +830,23 @@ public class WechatPayV3Util { private int decryptObjectFields(JSONObject obj) { if (obj == null) return 0; - + int decryptedCount = 0; for (String key : obj.keySet()) { Object value = obj.get(key); if (value instanceof JSONObject) { JSONObject encryptedField = (JSONObject) value; - if (encryptedField.containsKey("algorithm") && - encryptedField.containsKey("ciphertext") && - encryptedField.containsKey("nonce")) { - + if (encryptedField.containsKey("algorithm") && + encryptedField.containsKey("ciphertext") && + encryptedField.containsKey("nonce")) { + // 这是一个加密字段,进行解密 log.info("🔍 发现加密字段: {}", key); String algorithm = encryptedField.getString("algorithm"); String ciphertext = encryptedField.getString("ciphertext"); String nonce = encryptedField.getString("nonce"); String associatedData = encryptedField.getString("associated_data"); - + if ("AEAD_AES_256_GCM".equals(algorithm)) { String decryptedValue = decryptAesGcm(associatedData, nonce, ciphertext); obj.put(key, decryptedValue); @@ -867,7 +867,7 @@ public class WechatPayV3Util { /** * RSA加密敏感字段 * 使用微信支付平台证书的公钥加密敏感信息 - * + * * @param plaintext 明文 * @return 加密后的密文(Base64编码) */ @@ -875,21 +875,21 @@ public class WechatPayV3Util { if (plaintext == null || plaintext.trim().isEmpty()) { return null; } - + log.info("🔒 开始RSA加密敏感字段"); log.info(" └─ 明文长度: {} 字符", plaintext.length()); - + try { // 获取微信支付平台证书的公钥 PublicKey publicKey = getWechatpayPublicKey(); - + // 使用RSA/ECB/OAEPWithSHA-1AndMGF1Padding进行加密 Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); - + byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes); - + log.info("✅ RSA加密成功,密文长度: {} 字符", encryptedText.length()); return encryptedText; } catch (Exception e) { @@ -901,23 +901,23 @@ public class WechatPayV3Util { /** * 获取微信支付平台证书的公钥 * 用于加密敏感字段 - * + * * @return 微信支付平台证书的公钥 */ private PublicKey getWechatpayPublicKey() { log.info("🔐 开始获取微信支付平台证书公钥"); - + try { // 尝试从本地证书文件中读取 String certDir = wechatConfig().getCertDir(); String wechatpaySerial = getWechatpayPlatformSerial(); - + if (wechatpaySerial != null && certDir != null) { String certFileName = "wechatpay_" + wechatpaySerial + ".pem"; String certPath = certDir + "/" + certFileName; - + log.info(" ├─ 尝试加载证书文件: {}", certPath); - + try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(certPath)) { if (inputStream != null) { String certContent = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); @@ -929,11 +929,11 @@ public class WechatPayV3Util { log.warn("⚠️ 从本地证书文件获取公钥失败: {}", e.getMessage()); } } - + // 如果本地证书文件不存在,临时使用商户证书的公钥(仅用于测试) log.warn("⚠️ 未找到微信支付平台证书,临时使用商户证书公钥(仅测试用)"); return getMerchantPublicKey(); - + } catch (Exception e) { log.error("❌ 获取微信支付平台证书公钥失败: {}", e.getMessage(), e); throw new RuntimeException("获取微信支付平台证书公钥失败: " + e.getMessage(), e); @@ -942,7 +942,7 @@ public class WechatPayV3Util { /** * 从证书内容中解析公钥 - * + * * @param certContent 证书内容(PEM格式) * @return 公钥 */ @@ -952,30 +952,30 @@ public class WechatPayV3Util { .replace("-----BEGIN CERTIFICATE-----", "") .replace("-----END CERTIFICATE-----", "") .replaceAll("\\s+", ""); - + byte[] certBytes = Base64.getDecoder().decode(cleanCert); - + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) certFactory.generateCertificate( new ByteArrayInputStream(certBytes)); - + return certificate.getPublicKey(); } /** * 获取商户证书的公钥(临时方案) - * + * * @return 商户证书的公钥 */ private PublicKey getMerchantPublicKey() throws Exception { // 这里可以从商户证书文件中读取公钥 // 临时实现:从私钥生成对应的公钥(仅用于测试) PrivateKey privateKey = getPrivateKey(); - + // 注意:这只是临时方案,实际应该使用微信支付平台证书的公钥 // 这里我们需要从商户证书文件中读取公钥 String certPath = wechatConfig().getCertDir() + "/apiclient_cert.pem"; - + try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(certPath)) { if (inputStream != null) { String certContent = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); @@ -984,14 +984,14 @@ public class WechatPayV3Util { } catch (Exception e) { log.warn("⚠️ 读取商户证书失败: {}", e.getMessage()); } - + // 如果都失败了,抛出异常 throw new RuntimeException("无法获取公钥,请确保微信支付平台证书或商户证书文件存在"); } /** * 快速退款(简化参数) - * + * * @param orderNo 商户订单号 * @param refundFee 退款金额(元,会自动转换为分) * @param reason 退款原因 @@ -1002,25 +1002,25 @@ public class WechatPayV3Util { log.info(" ├─ 订单号: {}", orderNo); log.info(" ├─ 退款金额: {}元", refundFee); log.info(" └─ 退款原因: {}", reason); - + // 生成退款单号(符合微信支付V3规范) String refundNo = generateValidRefundNo("REFUND"); log.info("🆔 生成退款单号: {}", refundNo); - + // 这里需要查询原订单金额,简化处理假设退款金额就是订单金额 int refundFeeInt = refundFee.multiply(new BigDecimal(100)).intValue(); int totalFeeInt = refundFeeInt; // 实际应用中需要查询原订单金额 - + log.warn("⚠️ 注意:当前使用简化处理,订单总金额 = 退款金额"); log.info("💰 金额转换: {}元 = {}分", refundFee, refundFeeInt); - + return refund(orderNo, refundNo, totalFeeInt, refundFeeInt, reason, null); } /** * 生成符合微信支付V3规范的批次号 * 规则:只能包含数字和字母,长度不超过32位 - * + * * @param prefix 前缀 * @return 批次号 */ @@ -1028,15 +1028,15 @@ public class WechatPayV3Util { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String timestamp = sdf.format(new Date()); String random = String.valueOf((int) (Math.random() * 10000)); - + // 确保只包含数字和字母 String batchNo = prefix + timestamp + random; - + // 限制长度不超过32位 if (batchNo.length() > 32) { batchNo = batchNo.substring(0, 32); } - + log.debug("🆔 生成批次号: {} (长度: {})", batchNo, batchNo.length()); return batchNo; } @@ -1044,7 +1044,7 @@ public class WechatPayV3Util { /** * 生成符合微信支付V3规范的退款单号 * 规则:只能包含数字和字母,长度不超过64位 - * + * * @param prefix 前缀 * @return 退款单号 */ @@ -1052,22 +1052,22 @@ public class WechatPayV3Util { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String timestamp = sdf.format(new Date()); String random = String.valueOf((int) (Math.random() * 10000)); - + // 确保只包含数字和字母 String refundNo = prefix + timestamp + random; - + // 限制长度不超过64位 if (refundNo.length() > 64) { refundNo = refundNo.substring(0, 64); } - + log.debug("🆔 生成退款单号: {} (长度: {})", refundNo, refundNo.length()); return refundNo; } /** * 快速提现(简化参数) - * + * * @param openid 用户openid * @param amount 金额(元,会自动转换为分) * @param desc 提现描述 @@ -1078,16 +1078,16 @@ public class WechatPayV3Util { log.info(" ├─ 用户OpenID: {}", maskSensitiveData(openid)); log.info(" ├─ 提现金额: {}元", amount); log.info(" └─ 提现描述: {}", desc); - + int amountInt = amount.multiply(new BigDecimal(100)).intValue(); log.info("💰 金额转换: {}元 = {}分", amount, amountInt); - + return withdraw(openid, amountInt, desc, null); } /** * 简化提现(不加密敏感字段,用于测试) - * + * * @param openid 用户openid * @param amount 金额(分) * @param desc 提现描述 @@ -1098,9 +1098,9 @@ public class WechatPayV3Util { log.info(" ├─ 用户OpenID: {}", maskSensitiveData(openid)); log.info(" ├─ 提现金额: {} 分 ({}元)", amount, fenToYuan(amount)); log.info(" └─ 提现描述: {}", desc); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -1110,7 +1110,7 @@ public class WechatPayV3Util { result.put("message", "用户openid不能为空"); return result; } - + if (amount <= 0) { log.warn("❌ 参数验证失败: 提现金额必须大于0,当前: {}", amount); result.put("success", false); @@ -1118,14 +1118,14 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + // 生成批次号和明细号(只包含数字和字母) String outBatchNo = generateValidBatchNo("WITHDRAW"); String detailNo = generateValidBatchNo("DETAIL"); log.info("🆔 生成业务单号"); log.info(" ├─ 批次号: {}", outBatchNo); log.info(" └─ 明细号: {}", detailNo); - + // 构建转账明细(不加密) log.info("🔧 开始构建转账明细(简化版)"); Map detail = new HashMap<>(); @@ -1134,10 +1134,10 @@ public class WechatPayV3Util { detail.put("transfer_remark", desc != null ? desc : "用户提现"); detail.put("openid", openid); // 注意:简化版不包含user_name字段,避免加密问题 - + List> detailList = new ArrayList<>(); detailList.add(detail); - + // 构建请求参数 log.info("🔧 开始构建请求参数"); Map params = new HashMap<>(); @@ -1152,46 +1152,46 @@ public class WechatPayV3Util { String bodyJson = JSONObject.toJSONString(params); log.info("✅ 请求参数构建完成"); log.debug("🔍 请求体JSON: {}", bodyJson); - + // 构建请求头 HttpHeaders headers = buildCommonHeaders("POST", TRANSFER_BATCH_URL, bodyJson); - + // 发送请求 String fullUrl = V3_BASE_URL + TRANSFER_BATCH_URL; log.info("🚀 开始发送提现请求"); log.info(" ├─ 请求方法: POST"); log.info(" ├─ 请求地址: {}", fullUrl); log.info(" └─ 请求体大小: {} 字节", bodyJson.getBytes(StandardCharsets.UTF_8).length); - + HttpEntity requestEntity = new HttpEntity<>(bodyJson, headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.POST, - requestEntity, + fullUrl, + HttpMethod.POST, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到提现响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("🔓 开始解密敏感字段"); // 解密敏感字段(如果有) decryptSensitiveFields(jsonResponse); - + // 提取关键信息 Map transferInfo = new HashMap<>(); transferInfo.put("out_batch_no", outBatchNo); transferInfo.put("batch_id", jsonResponse.getString("batch_id")); transferInfo.put("create_time", jsonResponse.getString("create_time")); transferInfo.put("batch_status", jsonResponse.getString("batch_status")); - + log.info("✅ 简化提现申请成功"); log.info("🔍 提现详情:"); log.info(" ├─ 微信批次ID: {}", jsonResponse.getString("batch_id")); @@ -1199,7 +1199,7 @@ public class WechatPayV3Util { log.info(" ├─ 创建时间: {}", jsonResponse.getString("create_time")); log.info(" └─ 商户批次号: {}", outBatchNo); log.debug("🔍 完整响应: {}", responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("transfer_info", transferInfo); @@ -1208,18 +1208,18 @@ public class WechatPayV3Util { log.error("❌ 简化提现申请失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "简化提现申请失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 简化提现申请异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "简化提现异常:" + e.getMessage()); } - + log.info("🏁 简化提现申请流程结束,结果: {}", result.get("success")); return result; } @@ -1257,68 +1257,68 @@ public class WechatPayV3Util { /** * 获取微信支付平台证书 * 通过API自动获取微信支付平台证书和序列号 - * + * * @return 平台证书信息 */ public Map getCertificates() { log.info("📜 开始获取微信支付平台证书"); Map result = new HashMap<>(); - + try { String url = "/v3/certificates"; String fullUrl = V3_BASE_URL + url; - + // 构建请求头(不包含Wechatpay-Serial,因为这是获取证书的接口) HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", buildAuthorizationHeader("GET", url, "")); headers.set("Accept", "application/json"); headers.set("User-Agent", "RuoYi-WechatPay-V3"); - + log.info("🚀 开始请求平台证书"); log.info(" ├─ 请求方法: GET"); log.info(" └─ 请求地址: {}", fullUrl); - + HttpEntity requestEntity = new HttpEntity<>(headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.GET, - requestEntity, + fullUrl, + HttpMethod.GET, + requestEntity, String.class ); - + log.info("📥 收到证书响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + log.info("✅ 获取平台证书成功"); - + // 解析证书列表 if (jsonResponse.containsKey("data")) { Object dataObj = jsonResponse.get("data"); if (dataObj instanceof List) { @SuppressWarnings("unchecked") List certList = (List) dataObj; - + log.info("🔍 找到 {} 个平台证书", certList.size()); - + for (int i = 0; i < certList.size(); i++) { if (certList.get(i) instanceof Map) { @SuppressWarnings("unchecked") Map cert = (Map) certList.get(i); - + String serialNo = (String) cert.get("serial_no"); String effectiveTime = (String) cert.get("effective_time"); String expireTime = (String) cert.get("expire_time"); - - log.info(" 证书 {}: 序列号={}, 生效时间={}, 过期时间={}", - i + 1, - maskSensitiveData(serialNo), - effectiveTime, + + log.info(" 证书 {}: 序列号={}, 生效时间={}, 过期时间={}", + i + 1, + maskSensitiveData(serialNo), + effectiveTime, expireTime); - + // 返回第一个有效证书的序列号 if (i == 0) { result.put("platform_serial", serialNo); @@ -1329,11 +1329,11 @@ public class WechatPayV3Util { } } } - + result.put("success", true); result.put("data", jsonResponse); result.put("message", "获取平台证书成功"); - + // 如果获取到了平台证书序列号,给出配置建议 if (result.containsKey("platform_serial")) { String platformSerial = (String) result.get("platform_serial"); @@ -1342,30 +1342,30 @@ public class WechatPayV3Util { log.info(" wechat:"); log.info(" wechatpay-serial: {}", platformSerial); } - + } else { log.error("❌ 获取平台证书失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "获取平台证书失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 获取平台证书异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "获取平台证书异常:" + e.getMessage()); } - + log.info("🏁 获取平台证书流程结束,结果: {}", result.get("success")); return result; } /** * 无Wechatpay-Serial头的提现方法(解决证书序列号错误问题) - * + * * @param openid 用户openid * @param amount 金额(分) * @param desc 提现描述 @@ -1376,9 +1376,9 @@ public class WechatPayV3Util { log.info(" ├─ 用户OpenID: {}", maskSensitiveData(openid)); log.info(" ├─ 提现金额: {} 分 ({}元)", amount, fenToYuan(amount)); log.info(" └─ 提现描述: {}", desc); - + Map result = new HashMap<>(); - + try { // 参数验证 log.info("📋 开始参数验证"); @@ -1388,7 +1388,7 @@ public class WechatPayV3Util { result.put("message", "用户openid不能为空"); return result; } - + if (amount <= 0) { log.warn("❌ 参数验证失败: 提现金额必须大于0,当前: {}", amount); result.put("success", false); @@ -1396,14 +1396,14 @@ public class WechatPayV3Util { return result; } log.info("✅ 参数验证通过"); - + // 生成批次号和明细号 String outBatchNo = generateValidBatchNo("WITHDRAW"); String detailNo = generateValidBatchNo("DETAIL"); log.info("🆔 生成业务单号"); log.info(" ├─ 批次号: {}", outBatchNo); log.info(" └─ 明细号: {}", detailNo); - + // 构建转账明细 log.info("🔧 开始构建转账明细"); Map detail = new HashMap<>(); @@ -1411,10 +1411,10 @@ public class WechatPayV3Util { detail.put("transfer_amount", amount); detail.put("transfer_remark", desc != null ? desc : "用户提现"); detail.put("openid", openid); - + List> detailList = new ArrayList<>(); detailList.add(detail); - + // 构建请求参数 log.info("🔧 开始构建请求参数"); Map params = new HashMap<>(); @@ -1429,7 +1429,7 @@ public class WechatPayV3Util { String bodyJson = JSONObject.toJSONString(params); log.info("✅ 请求参数构建完成"); log.debug("🔍 请求体JSON: {}", bodyJson); - + // 构建请求头(不包含Wechatpay-Serial) log.info("📤 开始构建请求头(不包含Wechatpay-Serial)"); HttpHeaders headers = new HttpHeaders(); @@ -1438,53 +1438,53 @@ public class WechatPayV3Util { headers.set("Accept", "application/json"); headers.set("User-Agent", "RuoYi-WechatPay-V3"); log.info("✅ 请求头构建完成(已跳过Wechatpay-Serial)"); - + // 发送请求 String fullUrl = V3_BASE_URL + TRANSFER_BATCH_URL; log.info("🚀 开始发送提现请求"); log.info(" ├─ 请求方法: POST"); log.info(" ├─ 请求地址: {}", fullUrl); log.info(" └─ 请求体大小: {} 字节", bodyJson.getBytes(StandardCharsets.UTF_8).length); - + HttpEntity requestEntity = new HttpEntity<>(bodyJson, headers); ResponseEntity response = restTemplate.exchange( - fullUrl, - HttpMethod.POST, - requestEntity, + fullUrl, + HttpMethod.POST, + requestEntity, String.class ); - + // 处理响应 log.info("📥 收到提现响应"); log.info(" ├─ 响应状态码: {}", response.getStatusCode()); - log.info(" └─ 响应体大小: {} 字节", + log.info(" └─ 响应体大小: {} 字节", response.getBody() != null ? response.getBody().getBytes(StandardCharsets.UTF_8).length : 0); - + if (response.getStatusCode().is2xxSuccessful()) { String responseBody = response.getBody(); JSONObject jsonResponse = JSONObject.parseObject(responseBody); - + result.put("success", true); result.put("data", jsonResponse); result.put("message", "无序列号提现测试成功"); - + log.info("✅ 无序列号提现测试成功"); } else { log.error("❌ 无序列号提现测试失败"); log.error(" ├─ 状态码: {}", response.getStatusCode()); log.error(" └─ 错误响应: {}", response.getBody()); - + result.put("success", false); result.put("message", "无序列号提现测试失败,状态码:" + response.getStatusCode()); result.put("error", response.getBody()); } - + } catch (Exception e) { log.error("❌ 无序列号提现测试异常: {}", e.getMessage(), e); result.put("success", false); result.put("message", "无序列号提现测试异常:" + e.getMessage()); } - + log.info("🏁 无序列号提现测试流程结束,结果: {}", result.get("success")); return result; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java index 17c3042..1887d26 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java @@ -279,6 +279,13 @@ public class Order extends BaseEntity public String getDayDate() { return dayDate; } public void setDayDate(String dayDate) { this.dayDate = dayDate; } + private Date receiveTimeStart; + private Date receiveTimeEnd; + public Date getReceiveTimeStart() { return receiveTimeStart; } + public void setReceiveTimeStart(Date receiveTimeStart) { this.receiveTimeStart = receiveTimeStart; } + public Date getReceiveTimeEnd() { return receiveTimeEnd; } + public void setReceiveTimeEnd(Date receiveTimeEnd) { this.receiveTimeEnd = receiveTimeEnd; } + public void setId(Long id) { this.id = id; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderTypeCount.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderTypeCount.java new file mode 100644 index 0000000..d213c8f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderTypeCount.java @@ -0,0 +1,18 @@ +package com.ruoyi.system.domain; + +public class OrderTypeCount { + private int bigtype; + private int count; + + public OrderTypeCount() {} + + public OrderTypeCount(int bigtype, int count) { + this.bigtype = bigtype; + this.count = count; + } + + public int getBigtype() { return bigtype; } + public void setBigtype(int bigtype) { this.bigtype = bigtype; } + public int getCount() { return count; } + public void setCount(int count) { this.count = count; } +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/QuoteMaterial.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/QuoteMaterial.java index 3b3589e..ea4f27e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/QuoteMaterial.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/QuoteMaterial.java @@ -66,6 +66,14 @@ public class QuoteMaterial extends BaseEntity @Excel(name = "附件图片") private String image; + @Excel(name = "附件图片") + private String manyimages; + + @Excel(name = "附件图片") + private String content; + + + @Excel(name = "是否有分佣 1:有 2:无 (默认有分佣)") private Integer iscommissions; @@ -249,6 +257,23 @@ public class QuoteMaterial extends BaseEntity this.image = image; } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getManyimages() { + return manyimages; + } + + public void setManyimages(String manyimages) { + this.manyimages = manyimages; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Users.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Users.java index ec2f025..fb41e7f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Users.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Users.java @@ -183,15 +183,40 @@ public class Users extends BaseEntity private BigDecimal commissionMin; private BigDecimal commissionMax; private String remember_token; - + private String workerTimeStr; private Map order_num; private Map goods_order_num; private List areaList; private String skill; + // 个人中心接口扩展字段 + private Object levelInfo; + private String levelImg; + private String prohibit; + private List skillArr; + private List serviceCityArr; - public void setId(Long id) + public Object getLevelInfo() { return levelInfo; } + public void setLevelInfo(Object levelInfo) { this.levelInfo = levelInfo; } + public String getLevelImg() { return levelImg; } + public void setLevelImg(String levelImg) { this.levelImg = levelImg; } + public String getProhibit() { return prohibit; } + public void setProhibit(String prohibit) { this.prohibit = prohibit; } + public List getSkillArr() { return skillArr; } + public void setSkillArr(List skillArr) { this.skillArr = skillArr; } + public List getServiceCityArr() { return serviceCityArr; } + public void setServiceCityArr(List serviceCityArr) { this.serviceCityArr = serviceCityArr; } + + public String getWorkerTimeStr() { + return workerTimeStr; + } + + public void setWorkerTimeStr(String workerTimeStr) { + this.workerTimeStr = workerTimeStr; + } + + public void setId(Long id) { this.id = id; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java index dbcd676..413a934 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java @@ -64,4 +64,22 @@ public interface OrderCommentMapper * @return 结果 */ public int deleteOrderCommentByIds(Long[] ids); + + /** + * 根据oid列表和type分页查询评价 + * @param oids 订单id列表 + * @param type 评价类型,可为null + * @param offset 分页起始 + * @param limit 分页大小 + * @return 评价列表 + */ + List selectOrderCommentListByOidsAndType(List oids, Long type, int offset, int limit); + + /** + * 根据oid列表和type统计数量 + * @param oids 订单id列表 + * @param type 评价类型 + * @return 数量 + */ + int countByOidsAndType(List oids, Long type); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java index 4062e2d..049cd5b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java @@ -70,4 +70,11 @@ public interface OrderLogMapper * @return 结果 */ public int deleteOrderLogByIds(Long[] ids); + + /** + * 根据师傅ID查询所有服务订单oid + * @param workerId 师傅ID + * @return oid列表 + */ + List selectOidListByWorkerId(Long workerId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java index 604f4ae..081dec4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java @@ -59,4 +59,22 @@ public interface IOrderCommentService * @return 结果 */ public int deleteOrderCommentById(Long id); + + /** + * 根据oid列表和type分页查询评价 + * @param oids 订单id列表 + * @param type 评价类型,可为null + * @param offset 分页起始 + * @param limit 分页大小 + * @return 评价列表 + */ + List selectOrderCommentListByOidsAndType(List oids, Long type, int offset, int limit); + + /** + * 根据oid列表和type统计数量 + * @param oids 订单id列表 + * @param type 评价类型 + * @return 数量 + */ + int countByOidsAndType(List oids, Long type); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java index 9427c47..4abebba 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java @@ -85,4 +85,11 @@ public interface IOrderLogService * @return 结果 */ public int deleteOrderLogById(Long id); + + /** + * 根据师傅ID查询所有服务订单oid + * @param workerId 师傅ID + * @return oid列表 + */ + List selectOidListByWorkerId(Long workerId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java index 55be101..a7766c5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java @@ -51,6 +51,16 @@ public class OrderCommentServiceImpl implements IOrderCommentService return orderCommentMapper.selectOrderCommentList(orderComment); } + @Override + public List selectOrderCommentListByOidsAndType(List oids, Long type, int offset, int limit) { + return orderCommentMapper.selectOrderCommentListByOidsAndType(oids, type, offset, limit); + } + + @Override + public int countByOidsAndType(List oids, Long type) { + return orderCommentMapper.countByOidsAndType(oids, type); + } + /** * 新增订单评价 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java index c393bff..847a312 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java @@ -130,4 +130,14 @@ public class OrderLogServiceImpl implements IOrderLogService { return orderLogMapper.deleteOrderLogById(id); } + + /** + * 根据师傅ID查询所有服务订单oid + * @param workerId 师傅ID + * @return oid列表 + */ + @Override + public List selectOidListByWorkerId(Long workerId) { + return orderLogMapper.selectOidListByWorkerId(workerId); + } } diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml index f5c6332..74874da 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml @@ -121,4 +121,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml index 2f125b3..83ab77e 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml @@ -116,6 +116,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select * from order_log where order_id = #{orderId} order by id DESC + + insert into order_log diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml index 9e790cf..6560a27 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml @@ -238,6 +238,10 @@ + + and receive_time BETWEEN #{receiveTimeStart} AND #{receiveTimeEnd} + + order by id desc diff --git a/ruoyi-system/src/main/resources/mapper/system/QuoteMaterialMapper.xml b/ruoyi-system/src/main/resources/mapper/system/QuoteMaterialMapper.xml index 2311d87..6da1030 100644 --- a/ruoyi-system/src/main/resources/mapper/system/QuoteMaterialMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/QuoteMaterialMapper.xml @@ -12,6 +12,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + @@ -19,7 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, good_id, type_id, title, price, unit,profit,commissions,iscommissions,image, created_at, updated_at from quote_material + select id, good_id, type_id, title, price, unit,manyimages,content,profit,commissions,iscommissions,image, created_at, updated_at from quote_material diff --git a/ruoyi-ui/src/views/system/GoodsShangPin/index.vue b/ruoyi-ui/src/views/system/GoodsShangPin/index.vue index 3226dd9..46cb5ec 100644 --- a/ruoyi-ui/src/views/system/GoodsShangPin/index.vue +++ b/ruoyi-ui/src/views/system/GoodsShangPin/index.vue @@ -750,4 +750,65 @@ export default { handleExport() { this.download('system/ServiceGoods/export', { ...this.queryParams - }, ` \ No newline at end of file + }); + }, + // 添加问答 + addQuestion() { + this.form.questionsArray.push({ + question: '', + answer: '' + }); + }, + // 删除问答 + removeQuestion(index) { + this.form.questionsArray.splice(index, 1); + }, + // 问答内容变化 + handleQuestionChange() { + // 当问答内容变化时,重新验证表单 + this.$nextTick(() => { + this.$refs.form.validateField('questionsArray'); + }); + }, + // 打开编辑对话框 + openEditDialog(row, field, label) { + // 深拷贝,避免直接引用导致视图未更新 + this.editRow = JSON.parse(JSON.stringify(row)); + this.editField = field; + this.editFieldLabel = label; + this.editFieldValue = row[field]; + this.editDialogVisible = true; + }, + // 保存编辑的值 + saveEditField() { + // 更新本地数据 + this.editRow[this.editField] = this.editFieldValue; + // 调用后端接口保存 + updateServiceGoods(this.editRow).then(response => { + this.$modal.msgSuccess("保存成功"); + this.editDialogVisible = false; + this.getList(); // 刷新主表 + }).catch(error => { + this.$modal.msgError("保存失败,请稍后重试"); + }); + }, + // 取消编辑 + cancelEdit() { + this.editDialogVisible = false; + }, + // 获取关联服务列表 + getForServiceList(callback) { + getselectTypeList(1).then(response => { + this.forServiceList = response.data; + if (callback) { + callback(); + } + }); + }, + } +} + + + diff --git a/ruoyi-ui/src/views/system/QuoteMaterial/index.vue b/ruoyi-ui/src/views/system/QuoteMaterial/index.vue index 5b04da9..405739f 100644 --- a/ruoyi-ui/src/views/system/QuoteMaterial/index.vue +++ b/ruoyi-ui/src/views/system/QuoteMaterial/index.vue @@ -124,6 +124,16 @@ + + + + + + @@ -286,6 +303,8 @@ export default { iscommissions: null, commissions: null, profit: null, + manyimages: [], + content: '', createdAt: null, updatedAt: null }, @@ -344,6 +363,8 @@ export default { iscommissions: null, commissions: null, profit: null, + manyimages: [], + content: '', createdAt: null, updatedAt: null } @@ -418,7 +439,9 @@ export default { this.form = { ...response.data, goodsintids: response.data.goodsintids || [], - typeintids: response.data.typeintids || [] + typeintids: response.data.typeintids || [], + manyimages: Array.isArray(response.data.manyimages) ? response.data.manyimages : (typeof response.data.manyimages === 'string' && response.data.manyimages ? response.data.manyimages.split(',') : []), + content: response.data.content || '' } // 如果分佣比例为空,设置为 material_commissions if (this.form.commissions === null || this.form.commissions === undefined || this.form.commissions === '') { @@ -436,6 +459,10 @@ export default { submitForm() { this.$refs["form"].validate(valid => { if (valid) { + // 处理轮播图为JSON字符串(数组形式) + if (Array.isArray(this.form.manyimages)) { + this.form.manyimages = JSON.stringify(this.form.manyimages.filter(Boolean)); + } if (this.form.id != null) { updateQuoteMaterial(this.form).then(response => { this.$modal.msgSuccess("修改成功")