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 e60aca2..92f82aa 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 @@ -17,22 +17,30 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.ArrayList; +import java.util.Date; +import java.text.SimpleDateFormat; +import java.util.stream.Collectors; import org.springframework.web.bind.annotation.RequestBody; import com.ruoyi.system.ControllerUtil.AppletControllerUtil; import com.ruoyi.system.ControllerUtil.AppletLoginUtil; import com.ruoyi.system.ControllerUtil.PageUtil; +import com.ruoyi.system.config.QiniuConfig; +import com.ruoyi.system.utils.QiniuUploadUtil; import static com.ruoyi.common.core.domain.AjaxResult.error; import static com.ruoyi.common.core.domain.AjaxResult.success; import static com.ruoyi.common.utils.PageUtils.startPage; import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; /** * 小程序控制器 @@ -66,6 +74,36 @@ public class AppletController extends BaseController { private IUserAddressService userAddressService; @Autowired private IOrderService orderService; + @Autowired + private IOrderReworkService orderReworkService; + @Autowired + private ICooperateService cooperateService; + @Autowired + private ICouponUserService couponUserService; + @Autowired + private IIntegralLogService integralLogService; + @Autowired + private IIntegralOrderService integralOrderService; + @Autowired + private IIntegralProductService integralProductService; + @Autowired + private IIntegralOrderLogService integralOrderLogService; + @Autowired + private IIntegralCateService integralCateService; + @Autowired + private IOrderLogService orderLogService; + @Autowired + private IDiyCityService diyCityService; + @Autowired + private ISiteSkillService siteSkillService; + @Autowired + private QiniuConfig qiniuConfig; + @Autowired + private IGoodsCartService goodsCartService; + @Autowired + private IGoodsOrderService goodsOrderService; + @Autowired + private ICouponsService couponsService; /** * 获取服务分类列表 @@ -97,9 +135,9 @@ public class AppletController extends BaseController { category.setIcon(AppletControllerUtil.buildImageUrl(category.getIcon())); } - return success(categoryList); + return AppletControllerUtil.appletSuccess(categoryList); } catch (Exception e) { - return error("获取服务分类列表失败:" + e.getMessage()); + return AppletControllerUtil.appletError("获取服务分类列表失败:" + e.getMessage()); } } @@ -120,7 +158,7 @@ public class AppletController extends BaseController { try { // 参数验证 if (name == null || name.trim().isEmpty()) { - return error("配置名称不能为空"); + return AppletControllerUtil.appletWarning("配置名称不能为空"); } // 构建查询条件 @@ -135,33 +173,46 @@ public class AppletController extends BaseController { String configValue = configList.get(0).getValue(); if (configValue != null && !configValue.trim().isEmpty()) { JSONObject jsonObject = JSONObject.parseObject(configValue); - return success(jsonObject); + return AppletControllerUtil.appletSuccess(jsonObject); } else { - return error("配置值为空"); + return AppletControllerUtil.appletWarning("配置值为空"); } } else { - return error("未找到指定的配置项:" + name); + return AppletControllerUtil.appletWarning("未找到指定的配置项:" + name); } } catch (Exception e) { - return error("获取配置信息失败:" + e.getMessage()); + return AppletControllerUtil.appletError("获取配置信息失败:" + e.getMessage()); } } + /** + * 获取默认配置信息 + * + * @param request HTTP请求对象 + * @return 返回config_one配置的JSON对象 + * + * 功能说明: + * - 获取名为"config_one"的系统配置 + * - 将配置值解析为JSON对象并返回 + * - 用于小程序获取基础配置信息 + */ @GetMapping(value = "/api/public/get/config") - public Map getconfig(HttpServletRequest request) { - Map map=new HashMap<>(); - SiteConfig configQuery = new SiteConfig(); - configQuery.setName("config_one"); - List list = siteConfigService.selectSiteConfigList(configQuery); - JSONObject jsonObject = JSONObject.parseObject(list.get(0).getValue()); -// map.put("data",list.get(0).getValue()); -// map.put("code",200); -// map.put("msg","成功"); - - - return success(jsonObject); - + public AjaxResult getconfig(HttpServletRequest request) { + try { + SiteConfig configQuery = new SiteConfig(); + configQuery.setName("config_one"); + List list = siteConfigService.selectSiteConfigList(configQuery); + + if (list != null && !list.isEmpty()) { + JSONObject jsonObject = JSONObject.parseObject(list.get(0).getValue()); + return AppletControllerUtil.appletSuccess(jsonObject); + } else { + return AppletControllerUtil.appletWarning("未找到默认配置信息"); + } + } catch (Exception e) { + return AppletControllerUtil.appletError("获取配置信息失败:" + e.getMessage()); + } } @@ -203,20 +254,20 @@ public class AppletController extends BaseController { // 1. 验证分页参数 Map pageValidation = PageUtil.validatePageParams(page, limit); if (!(Boolean) pageValidation.get("valid")) { - return error((String) pageValidation.get("message")); + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); } // 2. 验证用户登录状态 String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { - return error("用户未登录或token无效"); + return AppletControllerUtil.appletUnauthorized(); } // 3. 获取用户信息 Users user = (Users) userValidation.get("user"); if (user == null) { - return error("用户信息获取失败"); + return AppletControllerUtil.appletWarning("用户信息获取失败"); } // 4. 设置分页参数 @@ -233,11 +284,11 @@ public class AppletController extends BaseController { // 7. 构建符合要求的分页响应格式 Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); - return success(pageData); + return AppletControllerUtil.appletSuccess(pageData); } catch (Exception e) { System.err.println("查询用户地址列表异常:" + e.getMessage()); - return error("查询地址列表失败:" + e.getMessage()); + return AppletControllerUtil.appletError("查询地址列表失败:" + e.getMessage()); } } @@ -278,41 +329,41 @@ public class AppletController extends BaseController { try { // 1. 参数验证 if (id == null || id <= 0) { - return error("地址ID无效"); + return AppletControllerUtil.appletWarning("地址ID无效"); } // 2. 验证用户登录状态 String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { - return error("用户未登录或token无效"); + return AppletControllerUtil.appletUnauthorized(); } // 3. 获取用户信息 Users user = (Users) userValidation.get("user"); if (user == null) { - return error("用户信息获取失败"); + return AppletControllerUtil.appletWarning("用户信息获取失败"); } // 4. 查询地址信息 UserAddress userAddress = userAddressService.selectUserAddressById(id); if (userAddress == null) { - return error("地址不存在"); + return AppletControllerUtil.appletWarning("地址不存在"); } // 5. 验证地址归属权 if (!userAddress.getUid().equals(user.getId())) { - return error("无权访问该地址信息"); + return AppletControllerUtil.appletWarning("无权访问该地址信息"); } // 6. 转换为AddressApple格式并返回 AddressApple addressApple = AddressApple.fromUserAddress(userAddress); - return success(addressApple); + return AppletControllerUtil.appletSuccess(addressApple); } catch (Exception e) { System.err.println("查询用户地址详情异常:" + e.getMessage()); - return error("查询地址详情失败:" + e.getMessage()); + return AppletControllerUtil.appletError("查询地址详情失败:" + e.getMessage()); } } @@ -354,49 +405,49 @@ public class AppletController extends BaseController { try { // 1. 参数验证 if (params == null || params.get("id") == null) { - return error("地址ID不能为空"); + return AppletControllerUtil.appletWarning("地址ID不能为空"); } Long addressId; try { addressId = Long.valueOf(params.get("id").toString()); if (addressId <= 0) { - return error("地址ID无效"); + return AppletControllerUtil.appletWarning("地址ID无效"); } } catch (NumberFormatException e) { - return error("地址ID格式错误"); + return AppletControllerUtil.appletWarning("地址ID格式错误"); } // 2. 验证用户登录状态 String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { - return error("用户未登录或token无效"); + return AppletControllerUtil.appletUnauthorized(); } // 3. 获取用户信息 Users user = (Users) userValidation.get("user"); if (user == null) { - return error("用户信息获取失败"); + return AppletControllerUtil.appletWarning("用户信息获取失败"); } // 4. 查询原地址信息并验证归属权 UserAddress existingAddress = userAddressService.selectUserAddressById(addressId); if (existingAddress == null) { - return error("地址不存在"); + return AppletControllerUtil.appletWarning("地址不存在"); } if (!existingAddress.getUid().equals(user.getId())) { - return error("无权修改该地址"); + return AppletControllerUtil.appletWarning("无权修改该地址"); } // 5. 构建更新的地址对象 - UserAddress updateAddress = buildUpdateAddress(params, addressId, user.getId()); + UserAddress updateAddress = AppletControllerUtil.buildUpdateAddress(params, addressId, user.getId()); // 6. 验证必填字段 - String validationResult = validateAddressParams(updateAddress); + String validationResult = AppletControllerUtil.validateAddressParams(updateAddress); if (validationResult != null) { - return error(validationResult); + return AppletControllerUtil.appletWarning(validationResult); } // 7. 处理默认地址逻辑 @@ -409,105 +460,18 @@ public class AppletController extends BaseController { int updateResult = userAddressService.updateUserAddress(updateAddress); if (updateResult > 0) { - return success("地址修改成功"); + return AppletControllerUtil.appletSuccess("地址修改成功"); } else { - return error("地址修改失败"); + return AppletControllerUtil.appletWarning("地址修改失败"); } } catch (Exception e) { System.err.println("修改用户地址异常:" + e.getMessage()); - return error("修改地址失败:" + e.getMessage()); + return AppletControllerUtil.appletError("修改地址失败:" + e.getMessage()); } } - /** - * 构建地址更新对象 - * - * @param params 请求参数 - * @param addressId 地址ID - * @param userId 用户ID - * @return UserAddress对象 - */ - private UserAddress buildUpdateAddress(Map params, Long addressId, Long userId) { - UserAddress address = new UserAddress(); - address.setId(addressId); - address.setUid(userId); - // 设置收货人姓名 - if (params.get("name") != null) { - address.setName(params.get("name").toString().trim()); - } - - // 设置联系电话 - if (params.get("phone") != null) { - address.setPhone(params.get("phone").toString().trim()); - } - - // 设置纬度 - if (params.get("latitude") != null) { - address.setLatitude(params.get("latitude").toString().trim()); - } - - // 设置经度 - if (params.get("longitude") != null) { - address.setLongitude(params.get("longitude").toString().trim()); - } - - // 设置地址名称 - if (params.get("address_name") != null) { - address.setAddressName(params.get("address_name").toString().trim()); - } - - // 设置地址信息 - if (params.get("address_info") != null) { - address.setAddressInfo(params.get("address_info").toString().trim()); - } - - // 设置详细地址 - if (params.get("info") != null) { - address.setInfo(params.get("info").toString().trim()); - } - - // 设置是否默认地址 - if (params.get("is_default") != null) { - try { - Long isDefault = Long.valueOf(params.get("is_default").toString()); - address.setIsDefault(isDefault); - } catch (NumberFormatException e) { - // 如果转换失败,设为非默认 - address.setIsDefault(0L); - } - } - - return address; - } - - /** - * 验证地址参数 - * - * @param address 地址对象 - * @return 验证错误信息,null表示验证通过 - */ - private String validateAddressParams(UserAddress address) { - if (address.getName() == null || address.getName().isEmpty()) { - return "收货人姓名不能为空"; - } - - if (address.getPhone() == null || address.getPhone().isEmpty()) { - return "联系电话不能为空"; - } - - // 验证手机号格式(简单验证) - if (!address.getPhone().matches("^1[3-9]\\d{9}$")) { - return "联系电话格式不正确"; - } - - if (address.getInfo() == null || address.getInfo().isEmpty()) { - return "详细地址不能为空"; - } - - return null; // 验证通过 - } /** * 新增用户收货地址 @@ -548,22 +512,22 @@ public class AppletController extends BaseController { String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { - return error("用户未登录或token无效"); + return AppletControllerUtil.appletUnauthorized(); } // 2. 获取用户信息 Users user = (Users) userValidation.get("user"); if (user == null) { - return error("用户信息获取失败"); + return AppletControllerUtil.appletWarning("用户信息获取失败"); } // 3. 构建新增的地址对象 - UserAddress newAddress = buildNewAddress(params, user.getId()); + UserAddress newAddress = AppletControllerUtil.buildNewAddress(params, user.getId()); // 4. 验证必填字段 - String validationResult = validateAddressParams(newAddress); + String validationResult = AppletControllerUtil.validateAddressParams(newAddress); if (validationResult != null) { - return error(validationResult); + return AppletControllerUtil.appletWarning(validationResult); } // 5. 处理默认地址逻辑 @@ -576,95 +540,126 @@ public class AppletController extends BaseController { int insertResult = userAddressService.insertUserAddress(newAddress); if (insertResult > 0) { - return success("地址新增成功"); + return AppletControllerUtil.appletSuccess("地址新增成功"); } else { - return error("地址新增失败"); + return AppletControllerUtil.appletWarning("地址新增失败"); } } catch (Exception e) { System.err.println("新增用户地址异常:" + e.getMessage()); - return error("新增地址失败:" + e.getMessage()); + return AppletControllerUtil.appletError("新增地址失败:" + e.getMessage()); } } + + /** - * 构建地址新增对象 - * - * @param params 请求参数 - * @param userId 用户ID - * @return UserAddress对象 + * 售后返修申请接口 + * + * @param params 请求参数 包含order_id(订单ID)、phone(联系电话)、mark(返修原因备注) + * @param request HTTP请求对象 + * @return 返修申请结果 + * + * 功能说明: + * - 验证用户登录状态和订单归属权 + * - 检查订单状态是否允许申请售后 + * - 处理售后返修申请逻辑 + * - 更新订单状态为售后处理中 + * - 记录返修申请信息和联系方式 + * + * 请求参数: + * - order_id: 订单ID + * - phone: 联系电话 + * - mark: 返修原因备注 */ - private UserAddress buildNewAddress(Map params, Long userId) { - UserAddress address = new UserAddress(); - address.setUid(userId); - - // 设置收货人姓名 - if (params.get("name") != null) { - address.setName(params.get("name").toString().trim()); - } - - // 设置联系电话 - if (params.get("phone") != null) { - address.setPhone(params.get("phone").toString().trim()); - } - - // 设置纬度 - if (params.get("latitude") != null) { - address.setLatitude(params.get("latitude").toString().trim()); - } - - // 设置经度 - if (params.get("longitude") != null) { - address.setLongitude(params.get("longitude").toString().trim()); - } - - // 设置地址名称 - if (params.get("address_name") != null) { - address.setAddressName(params.get("address_name").toString().trim()); - } - - // 设置地址信息 - if (params.get("address_info") != null) { - address.setAddressInfo(params.get("address_info").toString().trim()); - } - - // 设置详细地址 - if (params.get("info") != null) { - address.setInfo(params.get("info").toString().trim()); - } - - // 设置是否默认地址 - if (params.get("is_default") != null) { - try { - // 处理布尔值或数字值 - Object isDefaultObj = params.get("is_default"); - Long isDefault = 0L; - - if (isDefaultObj instanceof Boolean) { - isDefault = ((Boolean) isDefaultObj) ? 1L : 0L; - } else if (isDefaultObj instanceof Number) { - isDefault = ((Number) isDefaultObj).longValue(); - } else { - String isDefaultStr = isDefaultObj.toString().toLowerCase(); - if ("true".equals(isDefaultStr) || "1".equals(isDefaultStr)) { - isDefault = 1L; - } - } - - address.setIsDefault(isDefault); - } catch (Exception e) { - // 如果转换失败,设为非默认 - address.setIsDefault(0L); + @PostMapping("/api/service/order/rework") + public AjaxResult serviceOrderRework(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 参数验证 + if (params == null) { + return error("请求参数不能为空"); } - } else { - // 如果没有指定,默认设为非默认地址 - address.setIsDefault(0L); - } - return address; + String orderId = (String) params.get("order_id"); + String phone = (String) params.get("phone"); + String mark = (String) params.get("mark"); + + if (StringUtils.isEmpty(orderId)) { + return error("订单ID不能为空"); + } + + if (StringUtils.isEmpty(phone)) { + return error("联系电话不能为空"); + } + + // 验证手机号格式 + if (!phone.matches("^1[3-9]\\d{9}$")) { + return error("联系电话格式不正确"); + } + + if (StringUtils.isEmpty(mark)) { + return error("返修原因不能为空"); + } + + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 4. 查询订单信息并验证归属权 + Order order = orderService.selectOrderByOrderId(orderId); + if (order == null) { + return error("订单不存在"); + } + + if (!order.getUid().equals(user.getId())) { + return error("无权操作此订单"); + } + + // 5. 验证订单状态是否允许申请售后 + if (!AppletControllerUtil.isOrderAllowRework(order.getStatus())) { + return error("当前订单状态不允许申请售后"); + } + + // 6. 处理售后返修申请 + boolean reworkResult = AppletControllerUtil.processReworkApplication(order, phone, mark, user, orderReworkService, orderService); + + if (reworkResult) { + return success("售后返修申请已提交,我们会尽快联系您处理"); + } else { + return error("售后申请提交失败,请稍后重试"); + } + + } catch (Exception e) { + System.err.println("售后返修申请异常:" + e.getMessage()); + return error("售后申请失败:" + e.getMessage()); + } } + + + /** + * 获取用户服务订单列表 + * + * @param params 请求参数 包含page(页码)、limit(每页数量)、status(订单状态) + * @param request HTTP请求对象 + * @return 返回分页的服务订单列表 + * + * 功能说明: + * - 获取当前登录用户的服务类订单(type=1) + * - 支持按订单状态筛选 + * - 返回带分页信息的订单列表 + * - 自动填充商品信息(标题、图标、价格等) + */ @PostMapping("api/service/order/lst") public AjaxResult getserviceorderlst(@RequestBody Map params, HttpServletRequest request) { @@ -730,58 +725,214 @@ public class AppletController extends BaseController { return success(pageData); } + /** + * 获取用户商品订单列表 + * + * @param params 请求参数 包含page(页码)、limit(每页数量)、status(订单状态) + * @param request HTTP请求对象 + * @return 返回分页的商品订单列表 + * + * 功能说明: + * - 获取当前登录用户的商品类订单 + * - 支持按订单状态筛选 + * - 返回带分页信息的订单列表 + * - 包含完整的商品信息和订单状态文本 + * + * 请求参数格式: + * { + * "limit": 15, + * "page": 1, + * "status": "2" + * } + * + * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "current_page": 1, + * "data": [ + * { + * "id": 1, + * "order_id": "C307236827627129", + * "order_no": "C307236827627129", + * "status": 2, + * "status_text": "待发货", + * "total_price": "4.90", + * "num": 1, + * "pay_time": "2024-08-31 12:02:07", + * "created_at": "2024-08-31 12:02:07", + * "product": { + * "id": 86, + * "title": "长青泉·饮用天然泉水", + * "sub_title": "长青泉 1.5L*1瓶 4.9元", + * "icon": "https://img.huafurenjia.cn/images/...", + * "price": "4.90", + * "num": 1 + * } + * } + * ], + * "total": 3, + * "per_page": 15, + * "current_page": 1, + * "last_page": 1 + * } + * } + */ @PostMapping("/api/goods/order/lst") public AjaxResult getgoodsorderlst(@RequestBody Map params, HttpServletRequest request) { + try { + int page = (int) params.get("page"); + int limit = (int) params.get("limit"); + String status = (String) params.get("status"); - int page = (int) params.get("page"); - int limit = (int) params.get("limit"); - String status = (String) params.get("status"); + // 1. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); + } - // 1. 验证分页参数 - Map pageValidation = PageUtil.validatePageParams(page, limit); - if (!(Boolean) pageValidation.get("valid")) { - return error((String) pageValidation.get("message")); + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 4. 设置分页参数 + PageHelper.startPage(page, limit); + + // 5. 构建查询条件 + GoodsOrder queryOrder = new GoodsOrder(); + queryOrder.setUid(user.getId()); + + if (StringUtils.isNotNull(status) && !"".equals(status)) { + queryOrder.setStatus(Long.valueOf(status)); + } + + // 6. 查询商品订单列表 + List orderList = goodsOrderService.selectGoodsOrderList(queryOrder); + + // 7. 为每个订单填充商品信息 + List> resultList = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (GoodsOrder order : orderList) { + Map orderData = new HashMap<>(); + + // 订单基本信息 + orderData.put("id", order.getId()); + orderData.put("order_id", order.getOrderId()); + orderData.put("order_no", order.getOrderId()); // 小程序常用字段 + orderData.put("status", order.getStatus()); + orderData.put("status_text", getOrderStatusText(order.getStatus())); // 状态文本 + orderData.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00"); + orderData.put("num", order.getNum()); + orderData.put("sku", order.getSku()); + + // 时间字段格式化 + if (order.getPayTime() != null) { + orderData.put("pay_time", sdf.format(order.getPayTime())); + } else { + orderData.put("pay_time", null); + } + + if (order.getCreatedAt() != null) { + orderData.put("created_at", sdf.format(order.getCreatedAt())); + } else { + orderData.put("created_at", null); + } + + // 查询并添加商品详细信息 + if (order.getProductId() != null) { + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + if (serviceGoods != null) { + Map productInfo = new HashMap<>(); + productInfo.put("id", serviceGoods.getId()); + productInfo.put("title", serviceGoods.getTitle()); + productInfo.put("sub_title", serviceGoods.getSubTitle()); + productInfo.put("icon", AppletControllerUtil.buildImageUrl(serviceGoods.getIcon())); + productInfo.put("price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00"); + productInfo.put("num", order.getNum()); + + orderData.put("product", productInfo); + } + } + + resultList.add(orderData); + } + + // 8. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(orderList); + + // 9. 构建返回数据格式(简化版本,更适合小程序) + Map responseData = new HashMap<>(); + responseData.put("current_page", pageInfo.getPageNum()); + responseData.put("data", resultList); + responseData.put("total", pageInfo.getTotal()); + responseData.put("per_page", pageInfo.getPageSize()); + responseData.put("last_page", pageInfo.getPages()); + + return AppletControllerUtil.appletSuccess(responseData); + + } catch (Exception e) { + System.err.println("查询商品订单列表异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询商品订单列表失败:" + e.getMessage()); } + } - // 2. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return error("用户未登录或token无效"); + /** + * 获取订单状态文本 + * + * @param status 订单状态 + * @return 状态文本 + */ + private String getOrderStatusText(Long status) { + if (status == null) { + return "未知状态"; } - - // 3. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return error("用户信息获取失败"); + + switch (status.intValue()) { + case 1: + return "待付款"; + case 2: + return "待发货"; + case 3: + return "待收货"; + case 4: + return "待评价"; + case 5: + return "已完成"; + case 6: + return "已取消"; + case 7: + return "售后中"; + case 8: + return "已退款"; + default: + return "未知状态"; } - - // 4. 设置分页参数 - PageHelper.startPage(page, limit); - - // 5. 查询用户地址列表 - OrderApple order = new OrderApple(); - order.setType(2); - order.setUid(user.getId()); - - if (StringUtils.isNotNull(status) && !"".equals(status)) { - order.setStatus(Long.valueOf(status)); - } - - - List orderList = orderService.selectOrderAppleList(order); - - // 6. 获取分页信息并构建响应 - TableDataInfo tableDataInfo = getDataTable(orderList); - - // 7. 构建符合要求的分页响应格式 - Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); - - return success(pageData); } + /** + * 用户登录验证接口 + * + * @param request HTTP请求对象 + * @return 返回用户信息或错误信息 + * + * 功能说明: + * - 通过请求头中的token验证用户身份 + * - 查询用户基本信息并返回 + * - 设置remember_token字段用于前端使用 + */ @PostMapping(value = "/api/user/login") public AjaxResult getuserlogin(HttpServletRequest request) { String token = request.getHeader("token"); @@ -978,31 +1129,473 @@ public class AppletController extends BaseController { } + /** + * 获取用户详细信息接口 + * + * @param request HTTP请求对象 + * @return 返回用户详细信息包含订单统计 + * + * 功能说明: + * - 通过token获取用户基本信息 + * - 返回用户的服务订单和商品订单统计数据 + * - 包含各种订单状态的数量统计 + * - 用于用户中心页面显示 + */ + /** + * 获取用户基本信息接口 + * + * @param request HTTP请求对象 + * @return 用户基本信息 + *

+ * 接口说明: + * - 通过token获取当前登录用户的基本信息 + * - 返回完整的用户数据 + * - 需要用户登录验证 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "id": 302, + * "name": "微信用户", + * "nickname": null, + * "phone": "18709185987", + * "avatar": "https://img.huafurenjia.cn/default/user_avatar.jpeg", + * "commission": 0, + * "created_at": "2024-08-31 12:02:07", + * "integral": 0, + * "openid": "oHIYB7DYezs7Myzn-yaF0amC3Bpc", + * "remember_token": "G88BSThmFCprrT0uTZ9ghDzW7QHj19CrwSwdq3e", + * "service_city_ids": ["2", "5", "7", "10", "11", "12", "13", "14", "15", "16", "17"], + * "skill_ids": ["19", "21", "25", "28", "35"], + * "status": 1, + * "total_integral": 100, + * "updated_at": "2025-06-11 10:35:44" + * } + * } + */ @GetMapping(value = "/api/user/info") - public AjaxResult getUserByPhone(HttpServletRequest request) { - String token = request.getHeader("token"); - Map order_num = new HashMap<>(); - Map goods_order_num = new HashMap<>(); - Users users = usersService.selectUsersByRememberToken(token); - if (users != null) { - users.setRemember_token(users.getRememberToken()); + public AjaxResult getUserInfo(HttpServletRequest request) { + try { + Map order_num = new HashMap<>(); + Map goods_order_num = new HashMap<>(); + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 构建用户信息响应数据 + Map userInfo = buildUserInfoResponse(user); + + userInfo.put("remember_token", userInfo.get("rememberToken")); order_num.put("pending_accept", 2); order_num.put("pending_service", 0); order_num.put("in_service", 0); order_num.put("other_status", 0); - users.setOrder_num(order_num); + userInfo.put("order_num",order_num); goods_order_num.put("pending_accept", 0); goods_order_num.put("pending_service", 3); goods_order_num.put("in_service", 0); goods_order_num.put("other_status", 0); - users.setGoods_order_num(goods_order_num); - return success(users); - } else { - return error("用户不存在"); - } + userInfo.put("goods_order_num",goods_order_num); + return AppletControllerUtil.appletSuccess(userInfo); + } catch (Exception e) { + System.err.println("查询用户基本信息异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询用户信息失败:" + e.getMessage()); + } } +// +// @GetMapping(value = "/api/user/info") +// public AjaxResult getUserByPhone(HttpServletRequest request) { +// String token = request.getHeader("token"); +// Map order_num = new HashMap<>(); +// Map goods_order_num = new HashMap<>(); +// Users users = usersService.selectUsersByRememberToken(token); +// if (users != null) { +// users.setRemember_token(users.getRememberToken()); +// order_num.put("pending_accept", 2); +// order_num.put("pending_service", 0); +// order_num.put("in_service", 0); +// order_num.put("other_status", 0); +// users.setOrder_num(order_num); +// goods_order_num.put("pending_accept", 0); +// goods_order_num.put("pending_service", 3); +// goods_order_num.put("in_service", 0); +// goods_order_num.put("other_status", 0); +// users.setGoods_order_num(goods_order_num); +// return AppletControllerUtil.appletSuccess(users); +// } else { +// return AppletControllerUtil.appletError("查询用户信息失败:"); +// } +// +// } + + /** + * 构建用户信息响应数据 + * + * @param user 用户实体 + * @return 格式化的用户信息 + */ + private Map buildUserInfoResponse(Users user) { + Map userInfo = new HashMap<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + // 基本信息 + userInfo.put("id", user.getId()); + userInfo.put("name", user.getName()); + userInfo.put("nickname", user.getNickname()); + userInfo.put("phone", user.getPhone()); + userInfo.put("password", null); // 密码不返回 + + // 头像处理 + String avatar = user.getAvatar(); + if (avatar != null && !avatar.isEmpty()) { + userInfo.put("avatar", AppletControllerUtil.buildImageUrl(avatar)); + } else { + userInfo.put("avatar", "https://img.huafurenjia.cn/default/user_avatar.jpeg"); + } + + // 其他业务字段 + userInfo.put("commission", user.getCommission() != null ? user.getCommission() : 0); + userInfo.put("integral", user.getIntegral() != null ? user.getIntegral() : 0); + userInfo.put("is_stop", user.getIsStop() != null ? user.getIsStop() : 1); + userInfo.put("job_number", user.getJobNumber()); + userInfo.put("level", user.getLevel()); + userInfo.put("login_status", user.getLoginStatus() != null ? user.getLoginStatus() : 2); + userInfo.put("margin", user.getMargin() != null ? user.getMargin() : 0); + userInfo.put("middle_auth", user.getMiddleAuth()); + userInfo.put("openid", user.getOpenid()); + userInfo.put("prohibit_time", user.getProhibitTime()); + userInfo.put("prohibit_time_str", null); + userInfo.put("propose", user.getPropose() != null ? user.getPropose() : "0.00"); + userInfo.put("remember_token", user.getRememberToken()); + userInfo.put("status", user.getStatus() != null ? user.getStatus() : 1); + userInfo.put("tpd", 0); // 默认值 + userInfo.put("total_comm", user.getTotalComm() != null ? user.getTotalComm() : 0); + userInfo.put("total_integral", user.getTotalIntegral() != null ? user.getTotalIntegral() : 100); + userInfo.put("type", user.getType() != null ? user.getType().toString() : "1"); + userInfo.put("worker_time", user.getWorkerTime()); + + // 时间字段格式化 + if (user.getCreatedAt() != null) { + userInfo.put("created_at", sdf.format(user.getCreatedAt())); + } else { + userInfo.put("created_at", null); + } + + if (user.getUpdatedAt() != null) { + userInfo.put("updated_at", sdf.format(user.getUpdatedAt())); + } else { + userInfo.put("updated_at", null); + } + + // 处理服务城市ID数组 + if (user.getServiceCityIds() != null && !user.getServiceCityIds().isEmpty()) { + userInfo.put("service_city_ids", AppletControllerUtil.parseStringToList(user.getServiceCityIds())); + } else { + userInfo.put("service_city_ids", new ArrayList<>()); + } + + // 处理技能ID数组 + if (user.getSkillIds() != null && !user.getSkillIds().isEmpty()) { + userInfo.put("skill_ids", AppletControllerUtil.parseStringToList(user.getSkillIds())); + } else { + userInfo.put("skill_ids", new ArrayList<>()); + } + + return userInfo; + } + + /** + * 修改用户基本信息接口 + * + * @param params 请求参数,包含用户信息字段 + * @param request HTTP请求对象 + * @return 修改结果 + *

+ * 接口说明: + * - 通过token验证用户身份后修改用户基本信息 + * - 支持修改用户的各种字段信息 + * - 自动处理服务城市ID和技能ID数组 + * - 需要用户登录验证 + *

+ * 请求参数格式: + * { + * "id": 302, + * "name": "微信用户P44455", + * "nickname": null, + * "phone": "18709185987", + * "avatar": "https://img.huafurenjia.cn/default/user_avatar.jpeg", + * "commission": 0, + * "integral": 0, + * "is_stop": 1, + * "job_number": null, + * "level": null, + * "login_status": 2, + * "margin": 0, + * "middle_auth": null, + * "openid": "oHIYB7DYezs7Myzn-yaF0amC3Bpc", + * "prohibit_time": null, + * "propose": "0.00", + * "service_city_ids": ["2", "5", "7", "10", "11", "12", "13", "14", "15", "16", "17"], + * "skill_ids": ["19", "21", "25", "20", "35"], + * "status": 1, + * "total_comm": 0, + * "total_integral": 100, + * "type": "1", + * "worker_time": null + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": [] + * } + */ + @PostMapping(value = "/api/user/edit/info") + public AjaxResult editUserInfo(@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.appletUnauthorized(); + } + + // 2. 获取当前登录用户信息 + Users currentUser = (Users) userValidation.get("user"); + if (currentUser == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证请求参数 + if (params == null || params.isEmpty()) { + return AppletControllerUtil.appletWarning("请求参数不能为空"); + } + + // 4. 验证用户ID是否匹配(安全性检查) + Object userIdObj = params.get("id"); + if (userIdObj != null) { + Long userId = Long.valueOf(userIdObj.toString()); + if (!userId.equals(currentUser.getId())) { + return AppletControllerUtil.appletWarning("无权修改其他用户的信息"); + } + } + + // 5. 构建更新用户对象 + Users updateUser = buildUpdateUserFromParams(params, currentUser.getId()); + + // 6. 验证必要字段 + String validationResult = validateUserEditParams(updateUser); + if (validationResult != null) { + return AppletControllerUtil.appletWarning(validationResult); + } + + // 7. 执行用户信息更新 + int updateResult = usersService.updateUsers(updateUser); + + if (updateResult > 0) { + // 8. 返回成功响应(按照图片中的格式返回空数组) + return AppletControllerUtil.appletSuccess(new ArrayList<>()); + } else { + return AppletControllerUtil.appletWarning("用户信息修改失败"); + } + + } catch (Exception e) { + System.err.println("修改用户基本信息异常:" + e.getMessage()); + return AppletControllerUtil.appletError("修改用户信息失败:" + e.getMessage()); + } + } + + /** + * 从请求参数构建更新用户对象 + * + * @param params 请求参数 + * @param userId 用户ID + * @return 用户更新对象 + */ + private Users buildUpdateUserFromParams(Map params, Long userId) { + Users updateUser = new Users(); + updateUser.setId(userId); + + // 基本信息字段 + if (params.get("name") != null) { + updateUser.setName(params.get("name").toString().trim()); + } + + if (params.get("nickname") != null && !params.get("nickname").toString().trim().isEmpty()) { + updateUser.setNickname(params.get("nickname").toString().trim()); + } + + if (params.get("phone") != null) { + updateUser.setPhone(params.get("phone").toString().trim()); + } + + // 头像处理 - 去掉CDN前缀保存相对路径 + if (params.get("avatar") != null) { + String avatar = params.get("avatar").toString().trim(); + if (avatar.startsWith("https://img.huafurenjia.cn/")) { + avatar = avatar.replace("https://img.huafurenjia.cn/", ""); + } + updateUser.setAvatar(avatar); + } + + // 数值字段 - 根据Users实体类的实际字段类型 + if (params.get("integral") != null) { + updateUser.setIntegral(parseToLongForEdit(params.get("integral"))); + } + + if (params.get("is_stop") != null) { + Integer isStop = parseToIntegerForEdit(params.get("is_stop")); + updateUser.setIsStop(isStop); + } + + if (params.get("login_status") != null) { + Integer loginStatus = parseToIntegerForEdit(params.get("login_status")); + updateUser.setLoginStatus(loginStatus); + } + + if (params.get("status") != null) { + Integer status = parseToIntegerForEdit(params.get("status")); + updateUser.setStatus(status); + } + + if (params.get("total_integral") != null) { + updateUser.setTotalIntegral(parseToLongForEdit(params.get("total_integral"))); + } + + // 字符串和其他字段 + if (params.get("job_number") != null && !params.get("job_number").toString().trim().isEmpty()) { + Integer jobNumber = parseToIntegerForEdit(params.get("job_number")); + updateUser.setJobNumber(jobNumber); + } + + if (params.get("level") != null && !params.get("level").toString().trim().isEmpty()) { + Integer level = parseToIntegerForEdit(params.get("level")); + updateUser.setLevel(level); + } + + if (params.get("middle_auth") != null && !params.get("middle_auth").toString().trim().isEmpty()) { + Integer middleAuth = parseToIntegerForEdit(params.get("middle_auth")); + updateUser.setMiddleAuth(middleAuth); + } + + if (params.get("propose") != null) { + // propose字段是BigDecimal类型,需要转换 + String proposeStr = params.get("propose").toString().trim(); + try { + java.math.BigDecimal propose = new java.math.BigDecimal(proposeStr); + updateUser.setPropose(propose); + } catch (NumberFormatException e) { + // 忽略格式错误,保持原值 + } + } + + if (params.get("type") != null) { + // type字段是String类型 + updateUser.setType(params.get("type").toString().trim()); + } + + // 处理服务城市ID数组 + if (params.get("service_city_ids") != null) { + List serviceCityIds = (List) params.get("service_city_ids"); + if (!serviceCityIds.isEmpty()) { + updateUser.setServiceCityIds(String.join(",", serviceCityIds)); + } + } + + // 处理技能ID数组 + if (params.get("skill_ids") != null) { + List skillIds = (List) params.get("skill_ids"); + if (!skillIds.isEmpty()) { + updateUser.setSkillIds(String.join(",", skillIds)); + } + } + + // 设置更新时间 + updateUser.setUpdatedAt(new Date()); + + return updateUser; + } + + /** + * 解析对象为Long类型(用于编辑接口) + */ + private Long parseToLongForEdit(Object value) { + if (value == null) return null; + + if (value instanceof Integer) { + return ((Integer) value).longValue(); + } else if (value instanceof Long) { + return (Long) value; + } else if (value instanceof String) { + try { + return Long.parseLong((String) value); + } catch (NumberFormatException e) { + return null; + } + } + return null; + } + + /** + * 解析对象为Integer类型(用于编辑接口) + */ + private Integer parseToIntegerForEdit(Object value) { + if (value == null) return null; + + if (value instanceof Integer) { + return (Integer) value; + } else if (value instanceof Long) { + return ((Long) value).intValue(); + } else if (value instanceof String) { + try { + return Integer.parseInt((String) value); + } catch (NumberFormatException e) { + return null; + } + } + return null; + } + + /** + * 验证用户编辑参数 + * + * @param user 用户对象 + * @return 验证结果,null表示验证通过 + */ + private String validateUserEditParams(Users user) { + // 验证手机号格式(如果提供了的话) + if (user.getPhone() != null && !user.getPhone().isEmpty()) { + if (!user.getPhone().matches("^1[3-9]\\d{9}$")) { + return "手机号格式不正确"; + } + } + + // 验证用户名长度 + if (user.getName() != null && user.getName().length() > 50) { + return "用户名长度不能超过50个字符"; + } + + // 验证昵称长度 + if (user.getNickname() != null && user.getNickname().length() > 50) { + return "昵称长度不能超过50个字符"; + } + + return null; // 验证通过 + } /** * 验证用户token接口 @@ -1074,6 +1667,18 @@ public class AppletController extends BaseController { * - 返回格式化的商品数据 * - 包含图片、基础信息等数组数据 */ + /** + * 手机号登录接口(未完整实现) + * + * @param params 包含code和phone参数 + * @param request HTTP请求对象 + * @return 登录结果 + * + * 功能说明: + * - 预留的手机号登录接口 + * - 当前实现不完整,需要补充验证逻辑 + * - 用于处理手机号码验证登录 + */ @GetMapping(value = "/user/phone/login") public AjaxResult getUserByPhone(@RequestBody Map params, HttpServletRequest request) { String code = (String) params.get("code"); @@ -1249,7 +1854,7 @@ public class AppletController extends BaseController { // 3. 根据业务需要处理支付成功逻辑 // 例如:更新订单状态、发送通知等 - handlePaymentSuccess(paymentInfo, isPayFor); + AppletControllerUtil.handlePaymentSuccess(paymentInfo, isPayFor); // 4. 返回成功响应给微信 return (String) notifyResult.get("responseXml"); @@ -1347,36 +1952,2135 @@ public class AppletController extends BaseController { } } - /** - * 处理支付成功的业务逻辑 - * - * @param paymentInfo 支付信息 - * @param isPayFor 是否为代付订单 - */ - private void handlePaymentSuccess(Map paymentInfo, boolean isPayFor) { - try { - String orderNo = (String) paymentInfo.get("outTradeNo"); - String transactionId = (String) paymentInfo.get("transactionId"); - String totalFee = (String) paymentInfo.get("totalFee"); - String timeEnd = (String) paymentInfo.get("timeEnd"); - // 根据业务需求处理支付成功逻辑 - if (isPayFor) { - // 代付订单处理逻辑 - // 1. 更新代付订单状态 - // 2. 处理原订单状态 - // 3. 给被代付人转账等 - System.out.println("处理代付订单支付成功:" + orderNo); + + /** + * 查询用户售后返修列表 + * + * @param params 请求参数,包含page(页码)、limit(每页数量) + * @param request HTTP请求对象 + * @return 返回分页的售后返修列表 + * + * 功能说明: + * - 获取当前登录用户的售后返修记录 + * - 支持分页查询 + * - 按创建时间倒序排列 + * - 返回符合前端要求的分页格式 + */ + @PostMapping("/api/service/order/rework/lst") + public AjaxResult getReworkList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取分页参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + int status =(Integer) params.get("status"); + + // 2. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return error((String) pageValidation.get("message")); + } + + // 3. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 4. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 5. 设置分页参数 + PageHelper.startPage(page, limit); + + // 6. 构建查询条件 + OrderRework queryCondition = new OrderRework(); + queryCondition.setUid(user.getId()); // 只查询当前用户的售后记录 + queryCondition.setStatus(status); + // 7. 查询售后返修列表 + List reworkList = orderReworkService.selectOrderReworkList(queryCondition); + + // 8. 构建分页数据 + PageInfo pageInfo = new PageInfo<>(reworkList); + + // 9. 构建返回数据格式 + Map responseData = new HashMap<>(); + responseData.put("current_page", pageInfo.getPageNum()); + responseData.put("data", reworkList); + responseData.put("from", pageInfo.getStartRow()); + responseData.put("last_page", pageInfo.getPages()); + responseData.put("per_page", String.valueOf(pageInfo.getPageSize())); + responseData.put("to", pageInfo.getEndRow()); + responseData.put("total", pageInfo.getTotal()); + + // 构建分页链接信息 + Map links = new HashMap<>(); + Map prevLink = new HashMap<>(); + prevLink.put("url", null); + prevLink.put("label", "« Previous"); + prevLink.put("active", false); + + Map nextLink = new HashMap<>(); + nextLink.put("url", pageInfo.isHasNextPage() ? + "https://www.huafurenjia.cn/api/service/order/rework/lst?page=" + pageInfo.getNextPage() : null); + nextLink.put("label", "Next »"); + nextLink.put("active", false); + + responseData.put("links", new Object[]{prevLink, nextLink}); + responseData.put("next_page_url", pageInfo.isHasNextPage() ? + "https://www.huafurenjia.cn/api/service/order/rework/lst?page=" + pageInfo.getNextPage() : null); + responseData.put("path", "https://www.huafurenjia.cn/api/service/order/rework/lst"); + responseData.put("prev_page_url", pageInfo.isHasPreviousPage() ? + "https://www.huafurenjia.cn/api/service/order/rework/lst?page=" + pageInfo.getPrePage() : null); + + return success(responseData); + + } catch (Exception e) { + System.err.println("查询售后返修列表异常:" + e.getMessage()); + return error("查询售后返修列表失败:" + e.getMessage()); + } + } + + /** + * 合作申请提交接口 + * + * @param params 请求参数,包含company(公司名称)、name(姓名)、phone(电话)、address(地址)、info(合作意向) + * @param request HTTP请求对象 + * @return 申请提交结果 + * + * 功能说明: + * - 验证用户登录状态(可选) + * - 接收合作申请表单数据 + * - 验证必填字段 + * - 保存合作申请记录 + * - 设置默认状态为待处理 + * + * 请求参数格式: + * { + * "company": "河南公司", + * "name": "王令兵", + * "phone": "15002954234", + * "address": "来宾", + * "info": "情感咨询" + * } + * + * 返回格式: + * { + * "code": 200, + * "msg": "操作成功", + * "data": "合作申请提交成功,我们会尽快联系您" + * } + */ + @PostMapping("/api/form/cooperate") + public AjaxResult submitCooperateApplication(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 参数验证 + if (params == null) { + return error("请求参数不能为空"); + } + + String company = (String) params.get("company"); + String name = (String) params.get("name"); + String phone = (String) params.get("phone"); + String address = (String) params.get("address"); + String info = (String) params.get("info"); + + // 2. 验证必填字段 + if (StringUtils.isEmpty(company)) { + return error("公司名称不能为空"); + } + + if (StringUtils.isEmpty(name)) { + return error("联系人姓名不能为空"); + } + + if (StringUtils.isEmpty(phone)) { + return error("联系电话不能为空"); + } + + // 验证手机号格式 + if (!phone.matches("^1[3-9]\\d{9}$")) { + return error("联系电话格式不正确"); + } + + if (StringUtils.isEmpty(address)) { + return error("联系地址不能为空"); + } + + if (StringUtils.isEmpty(info)) { + return error("合作意向不能为空"); + } + + // 3. 获取用户信息(可选,不强制要求登录) + Long uid = null; + String uname = null; + + String token = request.getHeader("token"); + if (StringUtils.isNotEmpty(token)) { + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if ((Boolean) userValidation.get("valid")) { + Users user = (Users) userValidation.get("user"); + if (user != null) { + uid = user.getId(); + uname = user.getNickname(); + } + } + } + + // 4. 构建合作申请对象 + Cooperate cooperate = AppletControllerUtil.buildCooperateApplication(params, uid, uname); + + // 5. 验证合作申请参数 + String validationResult = AppletControllerUtil.validateCooperateParams(cooperate); + if (validationResult != null) { + return error(validationResult); + } + + // 6. 保存合作申请记录 + int insertResult = cooperateService.insertCooperate(cooperate); + + if (insertResult > 0) { + return success("合作申请提交成功,我们会尽快联系您"); } else { - // 普通订单处理逻辑 - // 1. 更新订单状态 - // 2. 发送支付成功通知 - // 3. 处理库存等业务逻辑 - System.out.println("处理普通订单支付成功:" + orderNo); + return error("合作申请提交失败,请稍后重试"); } } catch (Exception e) { - System.err.println("处理支付成功业务逻辑异常:" + e.getMessage()); + System.err.println("合作申请提交异常:" + e.getMessage()); + return error("合作申请提交失败:" + e.getMessage()); } } + + /** + * 查询用户优惠券列表 + * + * @param params 请求参数,包含status(优惠券状态)、product_id(指定商品ID)、price(最低价格) + * @param request HTTP请求对象 + * @return 返回用户优惠券列表 + */ + @PostMapping("/api/coupon/my/lst") + public AjaxResult getMyCouponList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 3. 解析查询参数 + Long status = parseParamToLong(params.get("status"), "状态参数格式错误"); + Long productId = parseParamToLong(params.get("product_id"), "商品ID参数格式错误"); + Integer price = parseParamToInteger(params.get("price"), "价格参数格式错误"); + + // 4. 查询用户的所有优惠券 + CouponUser couponUserQuery = new CouponUser(); + couponUserQuery.setUid(user.getId()); + List couponUserList = couponUserService.selectCouponUserList(couponUserQuery); + + // 5. 根据状态筛选优惠券 + long currentTime = System.currentTimeMillis() / 1000; // 当前时间戳(秒) + List filteredList = new ArrayList<>(); + + if (status == null) { + // 如果未指定状态,返回所有优惠券 + filteredList = couponUserList; + } else if (status == 1L) { + // 未使用的优惠券 + for (CouponUser coupon : couponUserList) { + if (coupon.getStatus() != 2L && !isExpired(coupon, currentTime)) { + filteredList.add(coupon); + } + } + } else if (status == 2L) { + // 已使用的优惠券 + for (CouponUser coupon : couponUserList) { + if (coupon.getStatus() != null && coupon.getStatus() == 2L) { + filteredList.add(coupon); + } + } + } else if (status == 3L) { + // 已过期的优惠券 + for (CouponUser coupon : couponUserList) { + if (isExpired(coupon, currentTime)) { + filteredList.add(coupon); + } + } + } else if (status == 4L) { + // 待领取的优惠券 + Coupons couponsQuery = new Coupons(); + couponsQuery.setStatus(1L); // 启用状态 + List availableCoupons = couponsService.selectCouponsList(couponsQuery); + + for (Coupons coupon : availableCoupons) { + if (isCouponAvailableToReceive(coupon, user.getId(), currentTime)) { + // 创建一个临时的CouponUser对象来保持返回格式一致 + CouponUser tempCouponUser = new CouponUser(); + tempCouponUser.setCouponId(coupon.getId()); + tempCouponUser.setUid(user.getId()); + tempCouponUser.setStatus(0L); // 待领取状态 + filteredList.add(tempCouponUser); + } + } + } + + // 6. 商品ID筛选 + if (productId != null) { + filteredList = filteredList.stream() + .filter(coupon -> productId.equals(coupon.getProductId())) + .collect(Collectors.toList()); + } + + // 7. 价格筛选 + List priceFilteredList = AppletControllerUtil.filterCouponsByPrice(filteredList, price); + + // 8. 使用工具类处理数据格式化 + List> resultList = AppletControllerUtil.buildCouponUserList( + priceFilteredList, serviceCateService); + + return success(resultList); + + } catch (Exception e) { + System.err.println("查询用户优惠券列表异常:" + e.getMessage()); + return error("查询优惠券列表失败:" + e.getMessage()); + } + } + + /** + * 解析参数为Long类型 + */ + private Long parseParamToLong(Object param, String errorMsg) { + if (param == null) return null; + + if (param instanceof Integer) { + return ((Integer) param).longValue(); + } else if (param instanceof String && !((String) param).trim().isEmpty()) { + try { + return Long.parseLong((String) param); + } catch (NumberFormatException e) { + throw new RuntimeException(errorMsg); + } + } + return null; + } + + /** + * 解析参数为Integer类型 + */ + private Integer parseParamToInteger(Object param, String errorMsg) { + if (param == null) return null; + + if (param instanceof Integer) { + return (Integer) param; + } else if (param instanceof String && !((String) param).trim().isEmpty()) { + try { + return Integer.parseInt((String) param); + } catch (NumberFormatException e) { + throw new RuntimeException(errorMsg); + } + } + return null; + } + + /** + * 查询用户积分日志列表 + * + * @param params 请求参数,包含limit(每页数量)、page(页码) + * @param request HTTP请求对象 + * @return 返回分页的积分日志列表 + */ + @PostMapping("/api/integral/user/log/lst") + public AjaxResult getUserIntegralLogList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取分页参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + + // 2. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return error((String) pageValidation.get("message")); + } + + // 3. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 4. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 5. 设置分页参数 + PageHelper.startPage(page, limit); + + // 6. 构建查询条件并查询 + IntegralLog integralLogQuery = new IntegralLog(); + integralLogQuery.setUid(user.getId()); + List integralLogList = integralLogService.selectIntegralLogList(integralLogQuery); + + // 7. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(integralLogList); + + // 8. 使用工具类处理数据格式化 + List> formattedLogList = AppletControllerUtil.buildIntegralLogList(integralLogList); + Map paginationData = AppletControllerUtil.buildPaginationResponse( + pageInfo, formattedLogList, "https://www.huafurenjia.cn/api/integral/user/log/lst"); + Map userData = AppletControllerUtil.buildUserDataInfo(user); + + // 9. 构建最终返回数据结构 + Map responseData = new HashMap<>(); + responseData.put("data", paginationData); + responseData.put("user", userData); + responseData.put("msg", "OK"); + + return success(responseData); + + } catch (Exception e) { + System.err.println("查询用户积分日志列表异常:" + e.getMessage()); + return error("查询积分日志列表失败:" + e.getMessage()); + } + } + + /** + * 查询用户积分商城订单列表 + * + * @param params 请求参数,包含limit(每页数量)、page(页码)、status(订单状态) + * @param request HTTP请求对象 + * @return 返回分页的积分商城订单列表 + */ + @PostMapping("/api/integral/user/order") + public AjaxResult getUserIntegralOrderList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取分页参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + String status = params.get("status") != null ? params.get("status").toString() : null; + + // 2. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return error((String) pageValidation.get("message")); + } + + // 3. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 4. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 5. 设置分页参数 + PageHelper.startPage(page, limit); + + // 6. 构建查询条件并查询 + IntegralOrder integralOrderQuery = new IntegralOrder(); + integralOrderQuery.setUid(user.getId()); + if (status != null && !status.trim().isEmpty()) { + integralOrderQuery.setStatus(status.trim()); + } + List integralOrderList = integralOrderService.selectIntegralOrderList(integralOrderQuery); + + // 7. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(integralOrderList); + + // 8. 使用工具类处理数据格式化 + List> formattedOrderList = AppletControllerUtil.buildIntegralOrderList( + integralOrderList, integralProductService); + Map responseData = AppletControllerUtil.buildPaginationResponse( + pageInfo, formattedOrderList, "https://www.huafurenjia.cn/api/integral/user/order"); + + return success(responseData); + + } catch (Exception e) { + System.err.println("查询用户积分商城订单列表异常:" + e.getMessage()); + return error("查询积分商城订单列表失败:" + e.getMessage()); + } + } + + /** + * 查询积分订单详情 + * + * @param id 订单ID + * @param request HTTP请求对象 + * @return 返回积分订单详细信息 + */ + @GetMapping("/api/integral/user/order/info/{id}") + public AjaxResult getIntegralOrderInfo(@PathVariable("id") Long id, HttpServletRequest request) { + try { + // 1. 参数验证 + if (id == null || id <= 0) { + return error("订单ID无效"); + } + + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 4. 查询积分订单信息 + IntegralOrder integralOrder = integralOrderService.selectIntegralOrderById(id); + if (integralOrder == null) { + return error("订单不存在"); + } + + // 5. 验证订单归属权 + if (!integralOrder.getUid().equals(user.getId())) { + return error("无权访问该订单信息"); + } + + // 6. 使用工具类构建订单详情数据 + Map orderData = AppletControllerUtil.buildIntegralOrderDetail( + integralOrder, integralProductService, integralOrderLogService); + + return success(orderData); + + } catch (Exception e) { + System.err.println("查询积分订单详情异常:" + e.getMessage()); + return error("查询订单详情失败:" + e.getMessage()); + } + } + + /** + * 查询积分商品分类列表 + * + * @param request HTTP请求对象 + * @return 返回积分商品分类列表 + * + * 功能说明: + * - 获取所有启用状态的积分商品分类 + * - 返回分类的ID和名称 + * - 用于积分商城分类展示 + * + * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": [ + * { + * "id": 4, + * "title": "家清商品" + * } + * ] + * } + */ + @GetMapping("/api/integral/product/cate") + public AjaxResult getIntegralProductCateList(HttpServletRequest request) { + try { + // 1. 构建查询条件:查询启用状态的积分商品分类 + IntegralCate integralCateQuery = new IntegralCate(); + integralCateQuery.setStatus(1L); // 启用状态 + + // 2. 查询积分商品分类列表 + List integralCateList = integralCateService.selectIntegralCateList(integralCateQuery); + + // 3. 构建返回数据格式 + List> resultList = new ArrayList<>(); + for (IntegralCate integralCate : integralCateList) { + Map cateData = new HashMap<>(); + cateData.put("id", integralCate.getId()); + cateData.put("title", integralCate.getTitle()); + resultList.add(cateData); + } + + return success(resultList); + + } catch (Exception e) { + System.err.println("查询积分商品分类列表异常:" + e.getMessage()); + return error("查询分类列表失败:" + e.getMessage()); + } + } + + /** + * 查询积分商品列表 + * + * @param params 请求参数,包含limit(每页数量)、page(页码)、type(分类ID) + * @param request HTTP请求对象 + * @return 返回分页的积分商品列表 + * + * 功能说明: + * - 获取积分商品列表,支持分页 + * - 支持按分类筛选 + * - 返回商品详细信息和分页信息 + * - 按创建时间倒序排列 + * + * 请求参数格式: + * { + * "limit": 15, // 每页显示数量 + * "page": 1, // 页码 + * "type": "1" // 分类ID(可选) + * } + * + * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "current_page": 1, + * "data": [ + * { + * "id": 7, + * "title": "全无码食品火锅", + * "image": "https://img.huafurenjia.cn/images/cb03ed40d32282bb47235568219ca26.png", + * "num": 11, + * "price": "53.90", + * "sales": 568, + * "tags": [] + * } + * ], + * "from": 1, + * "last_page": 1, + * "per_page": 15, + * "to": 2, + * "total": 2 + * } + * } + */ + @PostMapping("/api/integral/product/lst") + public AjaxResult getIntegralProductList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取分页参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + String type = params.get("type") != null ? params.get("type").toString() : null; + + // 2. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return error((String) pageValidation.get("message")); + } + + // 3. 设置分页参数 + PageHelper.startPage(page, limit); + + // 4. 构建查询条件 + IntegralProduct integralProductQuery = new IntegralProduct(); + integralProductQuery.setStatus(1L); // 只查询启用状态的商品 + + // 如果有分类参数,添加分类筛选 + if (type != null && !type.trim().isEmpty()) { + try { + Long cateId = Long.parseLong(type.trim()); + integralProductQuery.setCateId(cateId); + } catch (NumberFormatException e) { + return error("分类参数格式错误"); + } + } + + // 5. 查询积分商品列表 + List integralProductList = integralProductService.selectIntegralProductList(integralProductQuery); + + // 6. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(integralProductList); + + // 7. 使用工具类处理数据格式化 + List> formattedProductList = AppletControllerUtil.buildIntegralProductList(integralProductList); + Map responseData = AppletControllerUtil.buildPaginationResponse( + pageInfo, formattedProductList, "https://www.huafurenjia.cn/api/integral/product/lst"); + + return success(responseData); + + } catch (Exception e) { + System.err.println("查询积分商品列表异常:" + e.getMessage()); + return error("查询积分商品列表失败:" + e.getMessage()); + } + } + + /** + * 查询积分商品详情 + * + * @param id 商品ID + * @param request HTTP请求对象 + * @return 返回积分商品详细信息 + * + * 功能说明: + * - 根据商品ID获取积分商品详细信息 + * - 返回完整的商品数据包括图片、规格、库存等 + * - 自动处理图片URL添加CDN前缀 + * - 格式化轮播图和标签为数组格式 + * + * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "id": 7, + * "title": "全无码食品火锅", + * "cate_id": 4, + * "contetnt": "

", + * "created_at": "2024-07-17 14:59:44", + * "image": "https://img.huafurenjia.cn/images/cb03ed40d32282bb47235568219ca26.png", + * "images": ["https://img.huafurenjia.cn/images/..."], + * "num": 11, + * "price": "53.90", + * "sales": 568, + * "sku": {"type": "single"}, + * "sku_type": 1, + * "sort": 1, + * "status": 1, + * "stock": 120, + * "tags": [], + * "updated_at": "2024-08-16 15:03:33" + * } + * } + */ + @GetMapping("/api/integral/product/info/{id}") + public AjaxResult getIntegralProductInfo(@PathVariable("id") Long id, HttpServletRequest request) { + try { + // 1. 参数验证 + if (id == null || id <= 0) { + return error("商品ID无效"); + } + + // 2. 查询积分商品信息 + IntegralProduct integralProduct = integralProductService.selectIntegralProductById(id); + if (integralProduct == null) { + return error("商品不存在"); + } + + // 3. 验证商品状态(只返回启用状态的商品) + if (integralProduct.getStatus() == null || integralProduct.getStatus() != 1) { + return error("商品已下架或不可用"); + } + + // 4. 使用工具类构建商品详情数据 + Map productDetail = AppletControllerUtil.buildIntegralProductDetail(integralProduct); + + return success(productDetail); + + } catch (Exception e) { + System.err.println("查询积分商品详情异常:" + e.getMessage()); + return error("查询商品详情失败:" + e.getMessage()); + } + } + + /** + * 获取用户默认收货地址 + * + * @param request HTTP请求对象 + * @return 默认地址信息 + *

+ * 接口说明: + * - 查询用户的默认收货地址(is_default = 1) + * - 如果没有默认地址,返回用户地址列表的第一条数据 + * - 验证用户登录状态和地址归属权 + * - 返回AddressApple格式的地址数据 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "操作成功", + * "data": { + * "id": 160, + * "uid": 302, + * "name": "赵先生", + * "phone": "18709185987", + * "latitude": "34.15643", + * "longitude": "108.86683", + * "address_name": "陕西省西安市长安区榆林北段与建设大道交叉口处北侧", + * "address_info": "陕西省西安市长安区榆林北段与建设大道交叉口处", + * "info": "14号楼2302", + * "is_default": 1, + * "created_at": null, + * "updated_at": null + * } + * } + */ + @GetMapping("/api/user/address/default") + public AjaxResult getUserDefaultAddress(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 3. 首先查询用户的默认地址 + UserAddress userAddressQuery = new UserAddress(); + userAddressQuery.setUid(user.getId()); + userAddressQuery.setIsDefault(1L); // 查询默认地址 + List defaultAddressList = userAddressService.selectUserAddressList(userAddressQuery); + + UserAddress targetAddress = null; + + if (!defaultAddressList.isEmpty()) { + // 找到默认地址 + targetAddress = defaultAddressList.get(0); + } else { + // 没有默认地址,查询用户的第一条地址 + UserAddress allAddressQuery = new UserAddress(); + allAddressQuery.setUid(user.getId()); + List allAddressList = userAddressService.selectUserAddressList(allAddressQuery); + + if (!allAddressList.isEmpty()) { + targetAddress = allAddressList.get(0); + } else { + return error("用户暂无收货地址"); + } + } + + // 4. 转换为AddressApple格式并返回 + AddressApple addressApple = AddressApple.fromUserAddress(targetAddress); + + return success(addressApple); + + } catch (Exception e) { + System.err.println("查询用户默认地址异常:" + e.getMessage()); + return error("查询默认地址失败:" + e.getMessage()); + } + } + + /** + * 获取用户小程序通知订阅状态 + * + * @param request HTTP请求对象 + * @return 用户通知订阅状态 + *

+ * 接口说明: + * - 查询用户对小程序消息模板的订阅状态 + * - 返回三个消息模板的订阅配置信息 + * - 支持不同业务场景的消息通知配置 + * - 验证用户登录状态 + *

+ * 消息模板说明: + * - pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M: 积分相关通知模板 + * - YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8: 操作成功通知模板 + * - 5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU: 工作人员通知模板 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "integral": ["pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"], + * "make_success": ["YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8", "5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"], + * "is": "5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU", + * "new_success": ["pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"], + * "s": "pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M", + * "workers": ["5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"], + * "a": "5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU" + * } + * } + */ + @GetMapping("/api/user/notification/status") + public AjaxResult getUserNotificationStatus(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 3. 直接返回固定的消息模板配置数据 + Map notificationStatus = AppletControllerUtil.buildMiniProgramNotificationStatus(user); + + return success(notificationStatus); + + } catch (Exception e) { + System.err.println("查询用户通知订阅状态异常:" + e.getMessage()); + return error("查询通知订阅状态失败:" + e.getMessage()); + } + } + + /** + * 用户订阅消息授权接口 + * + * @param params 请求参数,包含tmplIds(模板ID数组) + * @param request HTTP请求对象 + * @return 授权结果 + *

+ * 接口说明: + * - 处理用户对消息模板的订阅授权 + * - 记录用户的授权状态 + * - 支持批量处理多个模板ID + *

+ * 请求参数格式: + * { + * "tmplIds": ["pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M", "YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8"] + * } + */ + @PostMapping("/api/user/notification/subscribe") + public AjaxResult subscribeNotification(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 3. 获取模板ID列表 + List tmplIds = (List) params.get("tmplIds"); + if (tmplIds == null || tmplIds.isEmpty()) { + return error("模板ID列表不能为空"); + } + + // 4. 验证模板ID的有效性 + List validTemplateIds = new ArrayList<>(); + validTemplateIds.add("pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"); + validTemplateIds.add("YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8"); + validTemplateIds.add("5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"); + + for (String tmplId : tmplIds) { + if (!validTemplateIds.contains(tmplId)) { + return error("无效的模板ID:" + tmplId); + } + } + + // 5. 处理订阅逻辑(这里可以记录到数据库或调用微信API) + Map subscribeResult = new HashMap<>(); + subscribeResult.put("user_id", user.getId()); + subscribeResult.put("template_ids", tmplIds); + subscribeResult.put("subscribe_time", new Date()); + subscribeResult.put("status", "success"); + + // 6. 这里可以将订阅状态保存到数据库 + // 例如:userNotificationService.saveSubscribeStatus(user.getId(), tmplIds); + + return success(subscribeResult); + + } catch (Exception e) { + System.err.println("用户订阅消息异常:" + e.getMessage()); + return error("订阅消息失败:" + e.getMessage()); + } + } + + /** + * 积分商品兑换接口 + * + * @param params 请求参数,包含id(积分商品ID)、address_id(收货地址ID)、num(购买数量)、sku(规格)、mark(备注) + * @param request HTTP请求对象 + * @return 兑换结果 + *

+ * 接口说明: + * - 使用积分兑换积分商品 + * - 验证用户积分是否足够支付 + * - 创建积分订单并扣除用户积分 + * - 记录积分变动日志 + *

+ * 请求参数格式: + * { + * "id": 7, // 积分商品ID + * "num": 1, // 购买数量 + * "sku": "", // 商品规格(可选) + * "address_id": 2151, // 收货地址ID + * "mark": "" // 备注(可选) + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "操作成功", + * "data": { + * "order_id": "JF20241217143055", + * "message": "积分商品兑换成功" + * } + * } + */ + @PostMapping("/api/integral/user/exchange") + public AjaxResult exchangeIntegralProduct(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return error("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return error("用户信息获取失败"); + } + + // 3. 验证请求参数 + String validationResult = AppletControllerUtil.validateIntegralExchangeParams(params); + if (validationResult != null) { + return error(validationResult); + } + + // 4. 获取并验证积分商品信息 + Long productId = Long.valueOf(params.get("id").toString()); + IntegralProduct product = integralProductService.selectIntegralProductById(productId); + if (product == null) { + return error("积分商品不存在"); + } + + if (product.getStatus() == null || product.getStatus() != 1) { + return error("积分商品已下架或不可用"); + } + + // 5. 获取并验证收货地址信息 + Long addressId = Long.valueOf(params.get("address_id").toString()); + UserAddress address = userAddressService.selectUserAddressById(addressId); + if (address == null) { + return error("收货地址不存在"); + } + + if (!address.getUid().equals(user.getId())) { + return error("无权使用该收货地址"); + } + + // 6. 计算所需积分并验证库存 + Integer num = Integer.valueOf(params.get("num").toString()); + if (product.getStock() != null && product.getStock() < num) { + return error("商品库存不足"); + } + + Long totalIntegral = product.getNum() * num; + + // 7. 验证用户积分是否足够 + if (!AppletControllerUtil.checkUserIntegralSufficient(user, totalIntegral)) { + // 积分不足,返回422状态码 + return AppletControllerUtil.appletWarning("积分不足"); + } + + // 8. 创建积分订单 + IntegralOrder order = AppletControllerUtil.buildIntegralOrder(params, user, product, address); + int orderResult = integralOrderService.insertIntegralOrder(order); + + if (orderResult <= 0) { + return error("订单创建失败"); + } + + // 9. 扣除用户积分 + Users updateUser = new Users(); + updateUser.setId(user.getId()); + updateUser.setIntegral(user.getIntegral() - totalIntegral); + int updateResult = usersService.updateUsers(updateUser); + + if (updateResult <= 0) { + return error("扣除积分失败"); + } + + // 10. 记录积分变动日志 + IntegralLog integralLog = AppletControllerUtil.buildIntegralLog( + user, -totalIntegral, order.getOrderId(), product.getTitle()); + integralLogService.insertIntegralLog(integralLog); + + // 11. 更新商品库存(如果有库存管理) + if (product.getStock() != null) { + IntegralProduct updateProduct = new IntegralProduct(); + updateProduct.setId(product.getId()); + updateProduct.setStock(product.getStock() - num); + updateProduct.setSales(product.getSales() != null ? product.getSales() + num : num.longValue()); + integralProductService.updateIntegralProduct(updateProduct); + } + // 12. 构建返回结果 + return AppletControllerUtil.appletSuccess("兑换成功"); + } catch (Exception e) { + System.err.println("积分商品兑换异常:" + e.getMessage()); + return AppletControllerUtil.appletError("积分商品兑换失败:" + e.getMessage()); + } + } + + /** + * 获取服务订单详情 + * + * @param id 订单ID + * @param request HTTP请求对象 + * @return 服务订单详细信息 + *

+ * 接口说明: + * - 根据订单ID获取服务订单完整信息 + * - 包含订单基本信息、订单日志和商品信息 + * - 验证用户登录状态和订单归属权 + * - 返回完整的订单详情数据 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * // 订单基本信息 + * "id": 260, + * "order_id": "B831770908583777", + * // ... 其他订单字段 + * "log": [ + * // 订单日志数组 + * ], + * "product": { + * // 商品信息 + * } + * } + * } + */ + @GetMapping("/api/service/order/info/{id}") + public AjaxResult getServiceOrderInfo(@PathVariable("id") Long id, HttpServletRequest request) { + try { + // 1. 参数验证 + if (id == null || id <= 0) { + return AppletControllerUtil.appletWarning("订单ID无效"); + } + + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 4. 查询订单信息并验证归属权 + Order order = orderService.selectOrderById(id); + if (order == null) { + return AppletControllerUtil.appletWarning("订单不存在"); + } + + // 5. 验证订单归属权 + if (!order.getUid().equals(user.getId())) { + return AppletControllerUtil.appletWarning("无权访问该订单信息"); + } + + // 6. 使用工具类构建订单详情数据 + Map orderDetail = AppletControllerUtil.buildServiceOrderDetail( + order, orderLogService, serviceGoodsService); + + return AppletControllerUtil.appletSuccess(orderDetail); + + } catch (Exception e) { + System.err.println("查询服务订单详情异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询订单详情失败:" + e.getMessage()); + } + } + + /** + * 获取城市列表接口 + * + * @param request HTTP请求对象 + * @return 城市列表数据 + *

+ * 接口说明: + * - 获取所有启用状态的城市列表 + * - 返回城市的ID、名称和父级ID + * - 用于小程序城市选择功能 + * - 无需用户登录验证 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": [ + * { + * "id": 1, + * "title": "西安市", + * "pid": 0 + * } + * ] + * } + */ + @GetMapping(value = "/api/public/diy/city") + public AjaxResult getDiyCityList(HttpServletRequest request) { + try { + // 查询所有城市列表 + List cityList = diyCityService.selectDiyCityList(null); + + // 构建树状结构数据 + List> resultList = AppletControllerUtil.buildCityTree(cityList); + + return AppletControllerUtil.appletSuccess(resultList); + } catch (Exception e) { + System.err.println("获取城市列表异常:" + e.getMessage()); + return AppletControllerUtil.appletError("获取城市列表失败:" + e.getMessage()); + } + } + + /** + * 获取技能列表接口 + * + * @param request HTTP请求对象 + * @return 技能列表数据 + *

+ * 接口说明: + * - 获取所有技能列表数据 + * - 返回技能的ID、名称、排序、状态等信息 + * - 用于小程序技能选择功能 + * - 无需用户登录验证 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": [ + * { + * "id": 47, + * "title": "燃气灶维修", + * "sort": 43, + * "status": 1, + * "created_at": "2025-04-10 09:36:35", + * "updated_at": "2025-04-10 09:36:35" + * } + * ] + * } + */ + @GetMapping(value = "/api/form/skill/lst") + public AjaxResult getSkillList(HttpServletRequest request) { + try { + // 查询技能列表 + List skillList = siteSkillService.selectSiteSkillList(null); + + // 构建返回数据格式 + List> resultList = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (SiteSkill skill : skillList) { + Map skillData = new HashMap<>(); + skillData.put("id", skill.getId()); + skillData.put("title", skill.getTitle()); + skillData.put("sort", skill.getSort()); + skillData.put("status", skill.getStatus()); + + // 格式化时间字段 + if (skill.getCreatedAt() != null) { + skillData.put("created_at", sdf.format(skill.getCreatedAt())); + } else { + skillData.put("created_at", null); + } + + if (skill.getUpdatedAt() != null) { + skillData.put("updated_at", sdf.format(skill.getUpdatedAt())); + } else { + skillData.put("updated_at", null); + } + + resultList.add(skillData); + } + + return AppletControllerUtil.appletSuccess(resultList); + } catch (Exception e) { + System.err.println("获取技能列表异常:" + e.getMessage()); + return AppletControllerUtil.appletError("获取技能列表失败:" + e.getMessage()); + } + } + + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @param request HTTP请求对象 + * @return 上传结果 + *

+ * 接口说明: + * - 支持图片和文档文件上传 + * - 优先使用七牛云上传,未启用时使用本地上传 + * - 自动验证文件格式和大小 + * - 无需用户登录验证(public 接口) + *

+ * 支持的文件格式: + * - 图片:jpg, jpeg, png, gif, bmp, webp, svg + * - 文档:doc, docx, xls, xlsx, ppt, pptx, txt, pdf + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "path": "images/2025-06-11/zvsZHNoFYlFkMCePQs1624hKwBSCozL9XM7pEUmo.jpg", + * "full_path": "http://img.huafurenjia.cn/images/2025-06-11/zvsZHNoFYlFkMCePQs1624hKwBSCozL9XM7pEUmo.jpg" + * } + * } + */ + @PostMapping(value = "/api/public/upload/file") + public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) { + try { + // 1. 验证文件是否为空 + if (file == null || file.isEmpty()) { + return AppletControllerUtil.appletWarning("上传文件不能为空"); + } + + // 2. 验证文件格式 + String[] allowedTypes = { + // 图片格式 + "jpg", "jpeg", "png", "gif", "bmp", "webp", "svg", + // 文档格式 + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf" + }; + + if (!QiniuUploadUtil.isValidFileType(file.getOriginalFilename(), allowedTypes)) { + return AppletControllerUtil.appletWarning("不支持的文件格式"); + } + + // 3. 验证文件大小(10MB) + long maxSize = 10 * 1024 * 1024; + if (!QiniuUploadUtil.isFileSizeValid(file.getSize(), maxSize)) { + return AppletControllerUtil.appletWarning("文件大小不能超过10MB"); + } + + String fileUrl; + String filePath; + + // 4. 检查是否启用七牛云上传 + if (qiniuConfig.isEnabled()) { + // 使用七牛云上传 + fileUrl = QiniuUploadUtil.uploadFile(file); + // 从完整URL中提取路径部分 + filePath = AppletControllerUtil.extractPathFromUrl(fileUrl, "https://" + qiniuConfig.getDomain() + "/"); + } else { + // 使用本地上传(这里需要集成本地上传逻辑) + return AppletControllerUtil.appletError("本地上传功能暂未在此接口中实现,请启用七牛云上传"); + } + + // 5. 构建返回数据 + Map uploadResult = new HashMap<>(); + uploadResult.put("path", filePath); + uploadResult.put("full_path", fileUrl); + + return AppletControllerUtil.appletSuccess(uploadResult); + + } catch (Exception e) { + System.err.println("文件上传异常:" + e.getMessage()); + return AppletControllerUtil.appletError("文件上传失败:" + e.getMessage()); + } + } + + + + /** + * 获取服务预约时间段接口 + * + * @param params 请求参数,包含day(预约日期) + * @param request HTTP请求对象 + * @return 时间段列表数据 + *

+ * 接口说明: + * - 根据指定日期获取可预约的时间段列表 + * - 返回每个时间段的可用状态和剩余数量 + * - 支持动态时间段配置 + * - 无需用户登录验证 + *

+ * 请求参数格式: + * { + * "day": "2025-06-11" + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": [ + * { + * "click": true, + * "value": "8:00-10:00", + * "prove": "可预约", + * "residue_num": 99 + * } + * ] + * } + */ + @PostMapping(value = "/api/service/make/time") + public AjaxResult getServiceMakeTime(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 参数验证 + if (params == null || params.get("day") == null) { + return AppletControllerUtil.appletWarning("日期参数不能为空"); + } + + String day = params.get("day").toString().trim(); + if (day.isEmpty()) { + return AppletControllerUtil.appletWarning("日期参数不能为空"); + } + + // 2. 验证日期格式 + if (!AppletControllerUtil.isValidDateFormat(day)) { + return AppletControllerUtil.appletWarning("日期格式错误,请使用yyyy-MM-dd格式"); + } + + // 3. 检查日期是否为过去时间 + if (AppletControllerUtil.isPastDate(day)) { + return AppletControllerUtil.appletWarning("不能预约过去的日期"); + } + + // 4. 构建时间段列表 + List> timeSlotList = AppletControllerUtil.buildTimeSlotList(day); + + return AppletControllerUtil.appletSuccess(timeSlotList); + + } catch (Exception e) { + System.err.println("获取服务预约时间段异常:" + e.getMessage()); + return AppletControllerUtil.appletError("获取时间段失败:" + e.getMessage()); + } + } + + + + + + + + + + + + + + /** + * 添加商品到购物车接口 + * + * @param params 请求参数,包含good_id(商品ID)、sku(商品规格) + * @param request HTTP请求对象 + * @return 添加结果 + *

+ * 接口说明: + * - 将指定商品添加到用户购物车 + * - 验证商品是否存在和可用 + * - 支持商品规格选择 + * - 需要用户登录验证 + *

+ * 请求参数格式: + * { + * "good_id": 86, + * "sku": "" + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "操作成功", + * "data": "商品已添加到购物车" + * } + */ + @PostMapping(value = "/api/cart/add") + public AjaxResult addToCart(@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.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证请求参数 + if (params == null || params.get("good_id") == null) { + return AppletControllerUtil.appletWarning("商品ID不能为空"); + } + + Long goodId; + try { + goodId = Long.valueOf(params.get("good_id").toString()); + if (goodId <= 0) { + return AppletControllerUtil.appletWarning("商品ID无效"); + } + } catch (NumberFormatException e) { + return AppletControllerUtil.appletWarning("商品ID格式错误"); + } + + // 4. 获取商品规格参数 + String sku = params.get("sku") != null ? params.get("sku").toString().trim() : ""; + + // 5. 查询商品信息并验证 + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId); + if (serviceGoods == null) { + return AppletControllerUtil.appletWarning("商品不存在"); + } + + // 6. 验证商品状态 +// if (serviceGoods.getStatus() == null || !serviceGoods.getStatus().equals(1L)) { +// return AppletControllerUtil.appletWarning("商品已下架或不可用"); +// } + + // 7. 检查商品库存(如果有库存管理) +// if (serviceGoods.getStock() != null && serviceGoods.getStock() <= 0L) { +// return AppletControllerUtil.appletWarning("商品库存不足"); +// } + + // 8. 检查购物车中是否已存在该商品 + GoodsCart existingCartItem = AppletControllerUtil.findExistingCartItem(user.getId(), goodId, sku, goodsCartService); + + if (existingCartItem != null) { + // 如果已存在,更新数量 + return AppletControllerUtil.updateCartItemQuantity(existingCartItem, serviceGoods, goodsCartService); + } else { + // 如果不存在,新增购物车记录 + return AppletControllerUtil.addNewCartItem(user, serviceGoods, sku, goodsCartService); + } + + } catch (Exception e) { + System.err.println("添加购物车异常:" + e.getMessage()); + return AppletControllerUtil.appletError("添加购物车失败:" + e.getMessage()); + } + } + + + + + + + + /** + * 查询购物车列表接口 + * + * @param params 请求参数,包含limit(每页数量)、page(页码) + * @param request HTTP请求对象 + * @return 购物车列表数据 + *

+ * 接口说明: + * - 获取当前登录用户的购物车商品列表 + * - 支持分页查询 + * - 返回完整的商品信息 + * - 需要用户登录验证 + *

+ * 请求参数格式: + * { + * "limit": 15, + * "page": 1 + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "current_page": 1, + * "data": [ + * { + * "id": 248, + * "uid": 302, + * "good_id": 86, + * "good_num": 1, + * "sku": null, + * "created_at": "2025-06-11 10:05:37", + * "updated_at": "2025-06-11 10:05:37", + * "good": { + * "id": 86, + * "title": "马桶漏水", + * "price": "0.00", + * "icon": "https://img.huafurenjia.cn/images/...", + * "stock": 232, + * "type": 1 + * } + * } + * ], + * "from": 1, + * "last_page": 1, + * "per_page": 15, + * "to": 1, + * "total": 1 + * } + * } + */ + @PostMapping(value = "/api/cart/lst") + public AjaxResult getCartList(@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.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取分页参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + + // 4. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); + } + + // 5. 设置分页参数 + PageHelper.startPage(page, limit); + + // 6. 构建查询条件 + GoodsCart queryCart = new GoodsCart(); + queryCart.setUid(user.getId()); + + // 7. 查询购物车列表 + List cartList = goodsCartService.selectGoodsCartList(queryCart); + + // 8. 为每个购物车项目填充商品信息 + List> resultList = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (GoodsCart cart : cartList) { + Map cartData = new HashMap<>(); + + // 基本购物车信息 + cartData.put("id", cart.getId()); + cartData.put("uid", cart.getUid()); + cartData.put("good_id", cart.getGoodId()); + cartData.put("good_num", cart.getGoodNum()); + cartData.put("sku", cart.getSku()); + + // 格式化时间字段 + cartData.put("created_at", cart.getCreatedAt() != null ? + sdf.format(cart.getCreatedAt()) : null); + cartData.put("updated_at", cart.getUpdatedAt() != null ? + sdf.format(cart.getUpdatedAt()) : null); + + // 查询并添加商品详细信息 + Map goodInfo = AppletControllerUtil.getGoodDetailForCart(cart.getGoodId(), serviceGoodsService); + cartData.put("good", goodInfo); + + resultList.add(cartData); + } + + // 9. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(cartList); + + // 10. 构建返回数据格式 + Map responseData = new HashMap<>(); + responseData.put("current_page", pageInfo.getPageNum()); + responseData.put("data", resultList); + responseData.put("from", pageInfo.getStartRow()); + responseData.put("last_page", pageInfo.getPages()); + responseData.put("per_page", pageInfo.getPageSize()); + responseData.put("to", pageInfo.getEndRow()); + responseData.put("total", pageInfo.getTotal()); + + // 构建分页链接信息 + String baseUrl = "https://www.huafurenjia.cn/api/cart/lst"; + responseData.put("first_page_url", baseUrl + "?page=1"); + responseData.put("last_page_url", baseUrl + "?page=" + pageInfo.getPages()); + responseData.put("next_page_url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + responseData.put("prev_page_url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + responseData.put("path", baseUrl); + + // 构建links数组 + List> links = new ArrayList<>(); + Map prevLink = new HashMap<>(); + prevLink.put("url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + prevLink.put("label", "« Previous"); + prevLink.put("active", false); + links.add(prevLink); + + Map nextLink = new HashMap<>(); + nextLink.put("url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + nextLink.put("label", "Next »"); + nextLink.put("active", false); + links.add(nextLink); + + responseData.put("links", links); + + return AppletControllerUtil.appletSuccess(responseData); + + } catch (Exception e) { + System.err.println("查询购物车列表异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询购物车列表失败:" + e.getMessage()); + } + } + + + + /** + * 服务/商品搜索接口 + * + * @param params 请求参数,包含limit(每页数量)、page(页码)、keywords(搜索关键词) + * @param request HTTP请求对象 + * @return 搜索结果列表 + *

+ * 接口说明: + * - 根据关键词搜索服务商品 + * - 支持按商品标题进行模糊查询 + * - 支持分页查询 + * - 无需用户登录验证 + *

+ * 请求参数格式: + * { + * "limit": 15, + * "page": 1, + * "keywords": "3" + * } + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "current_page": 1, + * "data": [ + * { + * "id": 161, + * "title": "238元套餐", + * "icon": "https://img.huafurenjia.cn/images/238元套餐.png", + * "cate_id": 8, + * "price": "238.00", + * "price_zn": "元起", + * "sales": 66, + * "stock": 942, + * "sub_title": "咖啡机(咖啡)冷台·洗衣机(空调)烘", + * "title": "238元套餐", + * "type": 1 + * } + * ], + * "from": 1, + * "last_page": 1, + * "per_page": 15, + * "to": 2, + * "total": 2 + * } + * } + */ + @PostMapping(value = "/api/service/search") + public AjaxResult searchServices(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取搜索参数 + int page = params.get("page") != null ? (Integer) params.get("page") : 1; + int limit = params.get("limit") != null ? (Integer) params.get("limit") : 15; + String keywords = params.get("keywords") != null ? params.get("keywords").toString().trim() : ""; + + // 2. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); + } + + // 3. 设置分页参数 + PageHelper.startPage(page, limit); + + // 4. 构建查询条件 + ServiceGoods queryGoods = new ServiceGoods(); + + // 如果有关键词,设置标题模糊查询 + if (!keywords.isEmpty()) { + queryGoods.setTitle(keywords); // 这里依赖mapper中的like查询实现 + } + + // 5. 查询商品列表 + List goodsList = serviceGoodsService.selectServiceGoodsList(queryGoods); + + // 6. 构建返回数据 + List> resultList = new ArrayList<>(); + for (ServiceGoods goods : goodsList) { + Map goodsData = AppletControllerUtil.buildServiceGoodsData(goods); + resultList.add(goodsData); + } + + // 7. 构建分页信息 + PageInfo pageInfo = new PageInfo<>(goodsList); + + // 8. 构建返回数据格式 + Map responseData = new HashMap<>(); + responseData.put("current_page", pageInfo.getPageNum()); + responseData.put("data", resultList); + responseData.put("from", pageInfo.getStartRow()); + responseData.put("last_page", pageInfo.getPages()); + responseData.put("per_page", pageInfo.getPageSize()); + responseData.put("to", pageInfo.getEndRow()); + responseData.put("total", pageInfo.getTotal()); + + // 构建分页链接信息 + String baseUrl = "https://www.huafurenjia.cn/api/service/search"; + responseData.put("first_page_url", baseUrl + "?page=1"); + responseData.put("last_page_url", baseUrl + "?page=" + pageInfo.getPages()); + responseData.put("next_page_url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + responseData.put("prev_page_url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + responseData.put("path", baseUrl); + + // 构建links数组 + List> links = new ArrayList<>(); + Map prevLink = new HashMap<>(); + prevLink.put("url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + prevLink.put("label", "« Previous"); + prevLink.put("active", false); + links.add(prevLink); + + Map nextLink = new HashMap<>(); + nextLink.put("url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + nextLink.put("label", "Next »"); + nextLink.put("active", false); + links.add(nextLink); + + responseData.put("links", links); + + return AppletControllerUtil.appletSuccess(responseData); + + } catch (Exception e) { + System.err.println("搜索服务商品异常:" + e.getMessage()); + return AppletControllerUtil.appletError("搜索失败:" + e.getMessage()); + } + } + + /** + * 获取商品订单详情接口 + * + * @param id 订单ID + * @param request HTTP请求对象 + * @return 订单详细信息 + *

+ * 接口说明: + * - 根据订单ID获取商品订单完整信息 + * - 包含订单基本信息、用户地址、商品信息等 + * - 验证用户登录状态和订单归属权 + * - 返回完整的订单详情数据 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "id": 2, + * "type": 2, + * "main_order_id": "WXBB08452049418556", + * "order_id": "BB08452049567554", + * // ... 其他订单字段 + * "address": { + * // 地址信息 + * }, + * "product": { + * // 商品信息 + * }, + * "comment": [], + * "delivery": [] + * } + * } + */ + @GetMapping("/api/goods/order/info/{id}") + public AjaxResult getGoodsOrderInfo(@PathVariable("id") Long id, HttpServletRequest request) { + try { + // 1. 参数验证 + if (id == null || id <= 0) { + return AppletControllerUtil.appletWarning("订单ID无效"); + } + + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 4. 查询订单信息并验证归属权 + GoodsOrder order = goodsOrderService.selectGoodsOrderById(id); + if (order == null) { + return AppletControllerUtil.appletWarning("订单不存在"); + } + + // 5. 验证订单归属权 + if (!order.getUid().equals(user.getId())) { + return AppletControllerUtil.appletWarning("无权访问该订单信息"); + } + + // 6. 构建订单详情数据 + Map orderDetail = buildGoodsOrderDetail(order); + + return AppletControllerUtil.appletSuccess(orderDetail); + + } catch (Exception e) { + System.err.println("查询商品订单详情异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询订单详情失败:" + e.getMessage()); + } + } + + /** + * 构建商品订单详情数据 + * + * @param order 订单信息 + * @return 格式化的订单详情 + */ + private Map buildGoodsOrderDetail(GoodsOrder order) { + Map orderDetail = new HashMap<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + // 订单基本信息 + orderDetail.put("id", order.getId()); + orderDetail.put("type", order.getType()); + orderDetail.put("main_order_id", order.getMainOrderId()); + orderDetail.put("order_id", order.getOrderId()); + orderDetail.put("transaction_id", order.getTransactionId() != null ? order.getTransactionId() : ""); + orderDetail.put("uid", order.getUid()); + orderDetail.put("product_id", order.getProductId()); + orderDetail.put("name", order.getName()); + orderDetail.put("phone", order.getPhone()); + orderDetail.put("num", order.getNum()); + orderDetail.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00"); + orderDetail.put("good_price", order.getGoodPrice() != null ? order.getGoodPrice().toString() : "0.00"); + orderDetail.put("service_price", order.getServicePrice()); + orderDetail.put("pay_price", order.getPayPrice() != null ? order.getPayPrice().toString() : "0.00"); + orderDetail.put("deduction", order.getDeduction() != null ? order.getDeduction().toString() : "0.00"); + orderDetail.put("postage", order.getPostage()); + orderDetail.put("pay_time", order.getPayTime() != null ? sdf.format(order.getPayTime()) : null); + orderDetail.put("status", order.getStatus()); + orderDetail.put("delivery_id", order.getDeliveryId()); + orderDetail.put("delivery_num", order.getDeliveryNum() != null ? order.getDeliveryNum() : ""); + orderDetail.put("send_time", order.getSendTime() != null ? sdf.format(order.getSendTime()) : null); + orderDetail.put("mark", order.getMark()); + orderDetail.put("address_id", order.getAddressId()); + orderDetail.put("sku", order.getSku()); + + // 时间字段格式化 + orderDetail.put("created_at", order.getCreatedAt() != null ? sdf.format(order.getCreatedAt()) : null); + orderDetail.put("updated_at", order.getUpdatedAt() != null ? sdf.format(order.getUpdatedAt()) : null); + orderDetail.put("deleted_at", order.getDeletedAt() != null ? sdf.format(order.getDeletedAt()) : null); + + // 查询并添加地址信息 + if (order.getAddressId() != null) { + UserAddress address = userAddressService.selectUserAddressById(order.getAddressId()); + if (address != null) { + Map addressInfo = new HashMap<>(); + addressInfo.put("id", address.getId()); + addressInfo.put("uid", address.getUid()); + addressInfo.put("name", address.getName()); + addressInfo.put("phone", address.getPhone()); + addressInfo.put("latitude", address.getLatitude()); + addressInfo.put("longitude", address.getLongitude()); + addressInfo.put("address_name", address.getAddressName()); + addressInfo.put("address_info", address.getAddressInfo()); + addressInfo.put("info", address.getInfo()); + addressInfo.put("is_default", address.getIsDefault()); + addressInfo.put("created_at", address.getCreatedAt() != null ? sdf.format(address.getCreatedAt()) : null); + addressInfo.put("updated_at", address.getUpdatedAt() != null ? sdf.format(address.getUpdatedAt()) : null); + addressInfo.put("deleted_at", null); // UserAddress可能没有deletedAt字段 + + orderDetail.put("address", addressInfo); + } + } + + // 查询并添加商品信息 + if (order.getProductId() != null) { + ServiceGoods product = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + if (product != null) { + Map productInfo = new HashMap<>(); + productInfo.put("id", product.getId()); + productInfo.put("title", product.getTitle()); + productInfo.put("sub_title", product.getSubTitle()); + productInfo.put("icon", AppletControllerUtil.buildImageUrl(product.getIcon())); + + orderDetail.put("product", productInfo); + } + } + + // 添加评论和配送信息(暂时为空数组,后续可以扩展) + orderDetail.put("comment", new ArrayList<>()); + orderDetail.put("delivery", new ArrayList<>()); + + return orderDetail; + } + + /** + * 获取用户优惠券数量统计接口 + * + * @param request HTTP请求对象 + * @return 优惠券数量统计信息 + *

+ * 接口说明: + * - 统计当前登录用户的优惠券数量 + * - 包含未使用、已使用、已过期、待领取数量 + * - 需要用户登录验证 + *

+ * 返回格式: + * { + * "code": 200, + * "msg": "OK", + * "data": { + * "one": 1, // 未使用数量 + * "two": 0, // 已使用数量 + * "three": 0, // 已过期数量 + * "four": 13 // 待领取数量 + * } + * } + */ + @GetMapping("/api/coupon/my/count") + public AjaxResult getMyCouponCount(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 查询用户的所有优惠券 + CouponUser couponUserQuery = new CouponUser(); + couponUserQuery.setUid(user.getId()); + List userCouponList = couponUserService.selectCouponUserList(couponUserQuery); + + // 4. 统计各种状态的优惠券数量 + int unusedCount = 0; // 未使用数量 (one) + int usedCount = 0; // 已使用数量 (two) + int expiredCount = 0; // 已过期数量 (three) + + long currentTime = System.currentTimeMillis() / 1000; // 当前时间戳(秒) + + for (CouponUser couponUser : userCouponList) { + // 检查是否已使用 + if (couponUser.getStatus() != null && couponUser.getStatus() == 2L) { + usedCount++; + } else { + // 检查是否已过期 + if (isExpired(couponUser, currentTime)) { + expiredCount++; + } else { + // 未使用且未过期 + unusedCount++; + } + } + } + + // 5. 查询可领取的优惠券数量 + Coupons couponsQuery = new Coupons(); + couponsQuery.setStatus(1L); // 启用状态 + List availableCoupons = couponsService.selectCouponsList(couponsQuery); + + int availableToReceiveCount = 0; // 待领取数量 (four) + for (Coupons coupon : availableCoupons) { + if (isCouponAvailableToReceive(coupon, user.getId(), currentTime)) { + availableToReceiveCount++; + } + } + + // 6. 构建返回数据 + Map countData = new HashMap<>(); + countData.put("one", unusedCount); // 未使用数量 + countData.put("two", usedCount); // 已使用数量 + countData.put("three", expiredCount); // 已过期数量 + countData.put("four", availableToReceiveCount); // 待领取数量 + + return AppletControllerUtil.appletSuccess(countData); + + } catch (Exception e) { + System.err.println("查询用户优惠券数量统计异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询优惠券数量统计失败:" + e.getMessage()); + } + } + + /** + * 判断优惠券是否已过期 + * + * @param couponUser 用户优惠券 + * @param currentTime 当前时间戳(秒) + * @return 是否过期 + */ + private boolean isExpired(CouponUser couponUser, long currentTime) { + // 检查lose_time字段(失效时间),这是一个字符串时间戳 + if (couponUser.getLoseTime() != null && !couponUser.getLoseTime().isEmpty()) { + try { + long loseTimeStamp = Long.parseLong(couponUser.getLoseTime()); + return currentTime > loseTimeStamp; + } catch (NumberFormatException e) { + // 如果解析失败,假设为日期格式,暂时认为未过期 + System.err.println("解析失效时间失败:" + couponUser.getLoseTime()); + } + } + + // 如果状态为3,表示已失效 + if (couponUser.getStatus() != null && couponUser.getStatus() == 3L) { + return true; + } + + // 如果都没有设置,认为未过期 + return false; + } + + /** + * 判断优惠券是否可以领取 + * + * @param coupon 优惠券 + * @param userId 用户ID + * @param currentTime 当前时间戳(秒) + * @return 是否可以领取 + */ + private boolean isCouponAvailableToReceive(Coupons coupon, Long userId, long currentTime) { + // 检查优惠券状态 + if (coupon.getStatus() == null || coupon.getStatus() != 1L) { + return false; + } + + // 检查领取时间范围 + if (coupon.getStartTime() != null && currentTime < coupon.getStartTime()) { + return false; // 还未到领取时间 + } + + if (coupon.getEndTime() != null && currentTime > coupon.getEndTime()) { + return false; // 已过领取时间 + } + + // 检查数量限制(如果不是无限领取) + if (coupon.getIsPermanent() == null || coupon.getIsPermanent() != 1L) { + if (coupon.getCount() != null && coupon.getCount() <= 0) { + return false; // 数量已用完 + } + } + + // 检查用户是否已经领取过此优惠券(如果有限制的话) + // 这里可以根据业务规则进一步完善 + + return true; + } + } 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 40a6424..12585b7 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 @@ -7,6 +7,7 @@ import com.ruoyi.system.domain.Users; import com.ruoyi.system.service.IServiceGoodsService; import com.ruoyi.system.service.IUsersService; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -20,12 +21,114 @@ import java.util.Map; * 2. 分类数据构建 * 3. 用户数据处理 * 4. 图片和基础信息数组解析 + * 5. 统一响应格式处理 * * @author Mr. Zhang Pan * @date 2025-01-03 * @version 1.0 */ public class AppletControllerUtil { + + // ============================== 统一响应处理方法 ============================== + + /** + * 成功响应 - code: 200 + * + * @param data 响应数据 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletSuccess(Object data) { + com.ruoyi.common.core.domain.AjaxResult result = new com.ruoyi.common.core.domain.AjaxResult(); + result.put("code", 200); + result.put("msg", "OK"); + result.put("data", data); + return result; + } + + /** + * 成功响应 - code: 200,无数据 + * + * @param message 成功消息 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletSuccess(String message) { + return appletSuccess((Object) message); + } + + /** + * 成功响应 - code: 200,默认消息 + * + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletSuccess() { + return appletSuccess("操作成功"); + } + + /** + * 业务提示响应 - code: 422 + * + * @param message 提示消息 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletWarning(String message) { + com.ruoyi.common.core.domain.AjaxResult result = new com.ruoyi.common.core.domain.AjaxResult(); + result.put("code", 422); + result.put("msg", message); + result.put("data", new java.util.ArrayList<>()); + return result; + } + + /** + * 业务提示响应 - code: 422,带数据 + * + * @param message 提示消息 + * @param data 响应数据 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletWarning(String message, Object data) { + com.ruoyi.common.core.domain.AjaxResult result = new com.ruoyi.common.core.domain.AjaxResult(); + result.put("code", 422); + result.put("msg", message); + result.put("data", data != null ? data : new java.util.ArrayList<>()); + return result; + } + + /** + * Token验证失败响应 - code: 332 + * + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletUnauthorized() { + return appletUnauthorized("用户未登录或token无效,请重新登录"); + } + + /** + * Token验证失败响应 - code: 332,自定义消息 + * + * @param message 提示消息 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletUnauthorized(String message) { + com.ruoyi.common.core.domain.AjaxResult result = new com.ruoyi.common.core.domain.AjaxResult(); + result.put("code", 332); + result.put("msg", message); + result.put("data", new java.util.ArrayList<>()); + return result; + } + + /** + * 系统错误响应 - code: 500 + * + * @param message 错误消息 + * @return AjaxResult + */ + public static com.ruoyi.common.core.domain.AjaxResult appletError(String message) { + com.ruoyi.common.core.domain.AjaxResult result = new com.ruoyi.common.core.domain.AjaxResult(); + result.put("code", 500); + result.put("msg", message); + result.put("data", new java.util.ArrayList<>()); + return result; + } /** * 服务商品详情响应实体类 @@ -795,4 +898,1739 @@ public class AppletControllerUtil { return result; } + + // ===== 地址管理相关工具方法 ===== + + /** + * 构建地址更新对象 + * + * @param params 请求参数Map,包含地址的各个字段信息 + * @param addressId 要更新的地址ID + * @param userId 用户ID,用于权限验证 + * @return UserAddress对象,包含更新后的地址信息 + * + * 功能说明: + * - 从请求参数中提取地址信息并构建UserAddress对象 + * - 自动处理参数类型转换和空值验证 + * - 用于地址编辑功能的数据转换 + */ + public static com.ruoyi.system.domain.UserAddress buildUpdateAddress(Map params, Long addressId, Long userId) { + com.ruoyi.system.domain.UserAddress address = new com.ruoyi.system.domain.UserAddress(); + address.setId(addressId); + address.setUid(userId); + + // 设置收货人姓名 + if (params.get("name") != null) { + address.setName(params.get("name").toString().trim()); + } + + // 设置联系电话 + if (params.get("phone") != null) { + address.setPhone(params.get("phone").toString().trim()); + } + + // 设置纬度 + if (params.get("latitude") != null) { + address.setLatitude(params.get("latitude").toString().trim()); + } + + // 设置经度 + if (params.get("longitude") != null) { + address.setLongitude(params.get("longitude").toString().trim()); + } + + // 设置地址名称 + if (params.get("address_name") != null) { + address.setAddressName(params.get("address_name").toString().trim()); + } + + // 设置地址信息 + if (params.get("address_info") != null) { + address.setAddressInfo(params.get("address_info").toString().trim()); + } + + // 设置详细地址 + if (params.get("info") != null) { + address.setInfo(params.get("info").toString().trim()); + } + + // 设置是否默认地址 + if (params.get("is_default") != null) { + try { + Long isDefault = Long.valueOf(params.get("is_default").toString()); + address.setIsDefault(isDefault); + } catch (NumberFormatException e) { + // 如果转换失败,设为非默认 + address.setIsDefault(0L); + } + } + + return address; + } + + /** + * 验证地址参数 + * + * @param address 需要验证的地址对象 + * @return 验证错误信息,null表示验证通过 + * + * 功能说明: + * - 验证地址对象的必填字段是否完整 + * - 验证手机号格式是否正确(11位数字) + * - 为地址新增和编辑功能提供统一的参数验证 + */ + public static String validateAddressParams(com.ruoyi.system.domain.UserAddress address) { + if (address.getName() == null || address.getName().isEmpty()) { + return "收货人姓名不能为空"; + } + + if (address.getPhone() == null || address.getPhone().isEmpty()) { + return "联系电话不能为空"; + } + + // 验证手机号格式(简单验证) + if (!address.getPhone().matches("^1[3-9]\\d{9}$")) { + return "联系电话格式不正确"; + } + + if (address.getInfo() == null || address.getInfo().isEmpty()) { + return "详细地址不能为空"; + } + + return null; // 验证通过 + } + + /** + * 构建地址新增对象 + * + * @param params 请求参数Map,包含新地址的各个字段信息 + * @param userId 当前登录用户的ID + * @return UserAddress对象,包含新地址的完整信息 + * + * 功能说明: + * - 从请求参数中提取地址信息并构建UserAddress对象 + * - 智能处理is_default字段的多种数据类型(boolean/number/string) + * - 为地址新增功能提供数据转换和默认值设置 + */ + public static com.ruoyi.system.domain.UserAddress buildNewAddress(Map params, Long userId) { + com.ruoyi.system.domain.UserAddress address = new com.ruoyi.system.domain.UserAddress(); + address.setUid(userId); + + // 设置收货人姓名 + if (params.get("name") != null) { + address.setName(params.get("name").toString().trim()); + } + + // 设置联系电话 + if (params.get("phone") != null) { + address.setPhone(params.get("phone").toString().trim()); + } + + // 设置纬度 + if (params.get("latitude") != null) { + address.setLatitude(params.get("latitude").toString().trim()); + } + + // 设置经度 + if (params.get("longitude") != null) { + address.setLongitude(params.get("longitude").toString().trim()); + } + + // 设置地址名称 + if (params.get("address_name") != null) { + address.setAddressName(params.get("address_name").toString().trim()); + } + + // 设置地址信息 + if (params.get("address_info") != null) { + address.setAddressInfo(params.get("address_info").toString().trim()); + } + + // 设置详细地址 + if (params.get("info") != null) { + address.setInfo(params.get("info").toString().trim()); + } + + // 设置是否默认地址 + if (params.get("is_default") != null) { + try { + // 处理布尔值或数字值 + Object isDefaultObj = params.get("is_default"); + Long isDefault = 0L; + + if (isDefaultObj instanceof Boolean) { + isDefault = ((Boolean) isDefaultObj) ? 1L : 0L; + } else if (isDefaultObj instanceof Number) { + isDefault = ((Number) isDefaultObj).longValue(); + } else { + String isDefaultStr = isDefaultObj.toString().toLowerCase(); + if ("true".equals(isDefaultStr) || "1".equals(isDefaultStr)) { + isDefault = 1L; + } + } + + address.setIsDefault(isDefault); + } catch (Exception e) { + // 如果转换失败,设为非默认 + address.setIsDefault(0L); + } + } else { + // 如果没有指定,默认设为非默认地址 + address.setIsDefault(0L); + } + + return address; + } + + // ===== 订单售后相关工具方法 ===== + + /** + * 检查订单状态是否允许申请售后 + * + * @param orderStatus 订单状态 + * @return true=允许申请售后,false=不允许 + * + * 功能说明: + * - 根据订单状态判断是否可以申请售后 + * - 一般已完成的订单才能申请售后 + * - 已取消或已退款的订单不能申请售后 + */ + public static boolean isOrderAllowRework(Long orderStatus) { + if (orderStatus == null) { + return false; + } + + // 订单状态定义(根据实际业务调整): + // 1=待接单, 2=已接单, 3=服务中, 4=已完成, 5=已取消, 6=售后中, 7=已退款 + // 只有已完成(4)的订单才能申请售后 + return orderStatus == 4L; + } + + /** + * 处理售后返修申请业务逻辑 + * + * @param order 订单对象 + * @param phone 联系电话 + * @param mark 返修原因 + * @param user 用户信息 + * @param orderReworkService 售后服务 + * @param orderService 订单服务 + * @return true=处理成功,false=处理失败 + * + * 功能说明: + * - 创建售后返修记录到order_rework表 + * - 更新订单状态为售后处理中 + * - 记录完整的售后申请信息 + */ + public static boolean processReworkApplication(com.ruoyi.system.domain.Order order, String phone, String mark, + com.ruoyi.system.domain.Users user, + com.ruoyi.system.service.IOrderReworkService orderReworkService, + com.ruoyi.system.service.IOrderService orderService) { + try { + // 1. 创建售后返修记录 + com.ruoyi.system.domain.OrderRework orderRework = new com.ruoyi.system.domain.OrderRework(); + orderRework.setUid(user.getId()); // 用户ID + orderRework.setUname(user.getNickname()); // 用户名称 + orderRework.setOid(order.getId()); // 订单ID + orderRework.setOrderId(order.getOrderId()); // 订单号 + orderRework.setPhone(phone); // 联系电话 + orderRework.setMark(mark); // 返修原因 + orderRework.setStatus(0); // 状态:0-待处理,1-已处理 + + // 插入售后返修记录 + int reworkResult = orderReworkService.insertOrderRework(orderRework); + + if (reworkResult > 0) { + // 2. 更新订单状态为售后处理中 (状态6) + com.ruoyi.system.domain.Order updateOrder = new com.ruoyi.system.domain.Order(); + updateOrder.setId(order.getId()); + updateOrder.setStatus(6L); // 售后处理中状态 + + int updateResult = orderService.updateOrder(updateOrder); + + if (updateResult > 0) { + System.out.println("订单[" + order.getOrderId() + "]售后申请成功,售后记录ID:" + orderRework.getId()); + return true; + } else { + System.err.println("订单状态更新失败,订单ID:" + order.getId()); + return false; + } + } else { + System.err.println("售后记录创建失败,订单ID:" + order.getId()); + return false; + } + + } catch (Exception e) { + System.err.println("处理售后申请业务逻辑异常:" + e.getMessage()); + return false; + } + } + + // ===== 合作申请相关工具方法 ===== + + /** + * 构建合作申请对象 + * + * @param params 请求参数Map,包含合作申请的各个字段信息 + * @param uid 用户ID(可为null) + * @param uname 用户名称(可为null) + * @return Cooperate对象,包含完整的合作申请信息 + * + * 功能说明: + * - 从请求参数中提取合作申请信息并构建Cooperate对象 + * - 设置默认状态为0(待处理) + * - 为合作申请功能提供数据转换 + */ + public static com.ruoyi.system.domain.Cooperate buildCooperateApplication(Map params, Long uid, String uname) { + com.ruoyi.system.domain.Cooperate cooperate = new com.ruoyi.system.domain.Cooperate(); + + // 设置用户信息(如果有的话) + cooperate.setUid(uid); + cooperate.setUname(uname); + + // 设置公司名称 + if (params.get("company") != null) { + cooperate.setCompany(params.get("company").toString().trim()); + } + + // 设置联系人姓名 + if (params.get("name") != null) { + cooperate.setName(params.get("name").toString().trim()); + } + + // 设置联系电话 + if (params.get("phone") != null) { + cooperate.setPhone(params.get("phone").toString().trim()); + } + + // 设置联系地址 + if (params.get("address") != null) { + cooperate.setAddress(params.get("address").toString().trim()); + } + + // 设置合作意向 + if (params.get("info") != null) { + cooperate.setInfo(params.get("info").toString().trim()); + } + + // 设置默认状态:0-待处理,1-已联系,2-合作中,3-已拒绝 + cooperate.setStatus(0L); + + return cooperate; + } + + /** + * 验证合作申请参数 + * + * @param cooperate 需要验证的合作申请对象 + * @return 验证错误信息,null表示验证通过 + * + * 功能说明: + * - 验证合作申请对象的必填字段是否完整 + * - 验证手机号格式是否正确 + * - 为合作申请功能提供统一的参数验证 + */ + public static String validateCooperateParams(com.ruoyi.system.domain.Cooperate cooperate) { + if (cooperate.getCompany() == null || cooperate.getCompany().isEmpty()) { + return "公司名称不能为空"; + } + + if (cooperate.getName() == null || cooperate.getName().isEmpty()) { + return "联系人姓名不能为空"; + } + + if (cooperate.getPhone() == null || cooperate.getPhone().isEmpty()) { + return "联系电话不能为空"; + } + + // 验证手机号格式 + if (!cooperate.getPhone().matches("^1[3-9]\\d{9}$")) { + return "联系电话格式不正确"; + } + + if (cooperate.getAddress() == null || cooperate.getAddress().isEmpty()) { + return "联系地址不能为空"; + } + + if (cooperate.getInfo() == null || cooperate.getInfo().isEmpty()) { + return "合作意向不能为空"; + } + + return null; // 验证通过 + } + + // ===== 支付相关工具方法 ===== + + /** + * 处理支付成功的业务逻辑 + * + * @param paymentInfo 支付信息Map,包含订单号、交易号、金额等 + * @param isPayFor 是否为代付订单,true=代付订单,false=普通订单 + * + * 功能说明: + * - 根据订单类型执行不同的支付成功后处理逻辑 + * - 普通订单:更新订单状态、发送通知、处理库存等 + * - 代付订单:处理代付逻辑、给被代付人转账等 + * - 为微信支付回调提供业务处理支持 + */ + public static void handlePaymentSuccess(Map paymentInfo, boolean isPayFor) { + try { + String orderNo = (String) paymentInfo.get("outTradeNo"); + String transactionId = (String) paymentInfo.get("transactionId"); + String totalFee = (String) paymentInfo.get("totalFee"); + String timeEnd = (String) paymentInfo.get("timeEnd"); + + // 根据业务需求处理支付成功逻辑 + if (isPayFor) { + // 代付订单处理逻辑 + // 1. 更新代付订单状态 + // 2. 处理原订单状态 + // 3. 给被代付人转账等 + System.out.println("处理代付订单支付成功:" + orderNo); + } else { + // 普通订单处理逻辑 + // 1. 更新订单状态 + // 2. 发送支付成功通知 + // 3. 处理库存等业务逻辑 + System.out.println("处理普通订单支付成功:" + orderNo); + } + + } catch (Exception e) { + System.err.println("处理支付成功业务逻辑异常:" + e.getMessage()); + } + } + + // ================================= 积分相关工具方法 ================================= + + /** + * 构建积分订单列表数据 + * + * @param integralOrderList 积分订单列表 + * @param integralProductService 积分商品服务 + * @return 格式化的订单列表 + */ + public static java.util.List> buildIntegralOrderList( + java.util.List integralOrderList, + com.ruoyi.system.service.IIntegralProductService integralProductService) { + + java.util.List> formattedOrderList = new java.util.ArrayList<>(); + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (com.ruoyi.system.domain.IntegralOrder order : integralOrderList) { + java.util.Map orderData = new java.util.HashMap<>(); + + // 基础订单信息 + orderData.put("id", order.getId()); + orderData.put("order_id", order.getOrderId()); + orderData.put("uid", order.getUid()); + orderData.put("user_name", order.getUserName()); + orderData.put("user_phone", order.getUserPhone()); + orderData.put("user_address", order.getUserAddress()); + orderData.put("product_id", order.getProductId()); + orderData.put("sku", order.getSku()); + orderData.put("num", order.getNum()); + orderData.put("price", order.getPrice()); + orderData.put("total_price", order.getTotalPrice()); + orderData.put("status", order.getStatus()); + orderData.put("delivery_id", order.getDeliveryId()); + orderData.put("delivery_num", order.getDeliveryNum()); + orderData.put("mark", order.getMark()); + + // 格式化时间字段 + orderData.put("created_at", order.getCreatedAt() != null ? sdf.format(order.getCreatedAt()) : null); + orderData.put("updated_at", order.getUpdatedAt() != null ? sdf.format(order.getUpdatedAt()) : null); + + // 添加商品信息 + orderData.put("product", buildIntegralProductInfo(order.getProductId(), integralProductService)); + + formattedOrderList.add(orderData); + } + + return formattedOrderList; + } + + /** + * 构建积分商品信息 + * + * @param productId 商品ID + * @param integralProductService 积分商品服务 + * @return 商品信息Map + */ + public static java.util.Map buildIntegralProductInfo(Long productId, + com.ruoyi.system.service.IIntegralProductService integralProductService) { + + if (productId == null) { + return null; + } + + try { + com.ruoyi.system.domain.IntegralProduct product = integralProductService.selectIntegralProductById(productId); + if (product != null) { + java.util.Map productData = new java.util.HashMap<>(); + productData.put("id", product.getId()); + productData.put("title", product.getTitle()); + productData.put("image", buildImageUrl(product.getImage())); + productData.put("price", product.getPrice()); + productData.put("num", product.getNum()); + productData.put("status", product.getStatus()); + return productData; + } + } catch (Exception e) { + System.err.println("查询积分商品信息异常:" + e.getMessage()); + } + + return null; + } + + /** + * 构建积分日志列表数据 + * + * @param integralLogList 积分日志列表 + * @return 格式化的日志列表 + */ + public static java.util.List> buildIntegralLogList( + java.util.List integralLogList) { + + java.util.List> formattedLogList = new java.util.ArrayList<>(); + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (com.ruoyi.system.domain.IntegralLog log : integralLogList) { + java.util.Map logData = new java.util.HashMap<>(); + logData.put("id", log.getId()); + logData.put("order_id", log.getOrderId()); + logData.put("title", log.getTitle()); + logData.put("mark", log.getMark()); + logData.put("uid", log.getUid()); + logData.put("type", log.getType()); + logData.put("num", log.getNum()); + + // 格式化时间字段 + logData.put("created_at", log.getCreatedAt() != null ? sdf.format(log.getCreatedAt()) : null); + logData.put("updated_at", log.getUpdatedAt() != null ? sdf.format(log.getUpdatedAt()) : null); + + formattedLogList.add(logData); + } + + return formattedLogList; + } + + /** + * 构建优惠券列表数据 + * + * @param couponUserList 优惠券用户列表 + * @param serviceCateService 服务分类服务 + * @return 格式化的优惠券列表 + */ + public static java.util.List> buildCouponUserList( + java.util.List couponUserList, + com.ruoyi.system.service.IServiceCateService serviceCateService) { + + java.util.List> resultList = new java.util.ArrayList<>(); + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + for (com.ruoyi.system.domain.CouponUser couponUser : couponUserList) { + java.util.Map couponData = new java.util.HashMap<>(); + + // 基础字段 + couponData.put("id", couponUser.getId()); + couponData.put("uid", couponUser.getUid()); + couponData.put("coupon_id", couponUser.getCouponId()); + couponData.put("coupon_title", couponUser.getCouponTitle()); + couponData.put("coupon_price", couponUser.getCouponPrice()); + couponData.put("min_price", couponUser.getMinPrice()); + couponData.put("cate_id", couponUser.getCateId()); + couponData.put("product_id", couponUser.getProductId()); + couponData.put("receive_type", couponUser.getReceiveType()); + couponData.put("status", couponUser.getStatus()); + couponData.put("lose_time", couponUser.getLoseTime()); + couponData.put("use_time", couponUser.getUseTime()); + + // 时间字段格式化 + if (couponUser.getAddTime() != null) { + java.util.Date addTime = new java.util.Date(couponUser.getAddTime() * 1000L); + couponData.put("add_time", sdf.format(addTime)); + } else { + couponData.put("add_time", null); + } + + couponData.put("created_at", couponUser.getCreatedAt() != null ? sdf.format(couponUser.getCreatedAt()) : null); + couponData.put("updated_at", couponUser.getUpdatedAt() != null ? sdf.format(couponUser.getUpdatedAt()) : null); + + // 添加 is_used 字段 + boolean isUsed = couponUser.getStatus() != null && couponUser.getStatus() == 2L; + couponData.put("is_used", isUsed); + + // 添加 suit_title 字段 + String suitTitle = ""; + if (couponUser.getCateId() != null && couponUser.getCateId() > 0) { + try { + com.ruoyi.system.domain.ServiceCate serviceCate = serviceCateService.selectServiceCateById(couponUser.getCateId()); + if (serviceCate != null && serviceCate.getTitle() != null) { + suitTitle = serviceCate.getTitle(); + } + } catch (Exception e) { + System.err.println("查询服务分类异常:" + e.getMessage()); + } + } + couponData.put("suit_title", suitTitle); + + // 添加 tag 字段 + String tag = ""; + if (couponUser.getReceiveType() != null) { + switch (couponUser.getReceiveType()) { + case "1": + tag = "通用券"; + break; + case "2": + tag = "品类券"; + break; + case "3": + tag = "商品券"; + break; + default: + tag = "优惠券"; + break; + } + } + couponData.put("tag", tag); + + resultList.add(couponData); + } + + return resultList; + } + + /** + * 构建积分订单日志列表 + * + * @param orderId 订单ID + * @param integralOrderLogService 积分订单日志服务 + * @return 格式化的日志列表 + */ + public static java.util.List> buildIntegralOrderLogList(Long orderId, + com.ruoyi.system.service.IIntegralOrderLogService integralOrderLogService) { + + java.util.List> logList = new java.util.ArrayList<>(); + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + com.ruoyi.system.domain.IntegralOrderLog logQuery = new com.ruoyi.system.domain.IntegralOrderLog(); + logQuery.setOid(orderId); + java.util.List orderLogs = integralOrderLogService.selectIntegralOrderLogList(logQuery); + + for (com.ruoyi.system.domain.IntegralOrderLog log : orderLogs) { + java.util.Map logData = new java.util.HashMap<>(); + logData.put("id", log.getId()); + logData.put("oid", log.getOid()); + logData.put("order_id", log.getOrderId()); + logData.put("title", log.getTitle()); + logData.put("content", log.getContent()); + logData.put("type", log.getType()); + + logData.put("created_at", log.getCreatedAt() != null ? sdf.format(log.getCreatedAt()) : null); + logData.put("updated_at", log.getUpdatedAt() != null ? sdf.format(log.getUpdatedAt()) : null); + + logList.add(logData); + } + } catch (Exception e) { + System.err.println("查询订单日志异常:" + e.getMessage()); + } + + return logList; + } + + /** + * 构建积分订单详情数据 + * + * @param integralOrder 积分订单 + * @param integralProductService 积分商品服务 + * @param integralOrderLogService 积分订单日志服务 + * @return 格式化的订单详情 + */ + public static java.util.Map buildIntegralOrderDetail( + com.ruoyi.system.domain.IntegralOrder integralOrder, + com.ruoyi.system.service.IIntegralProductService integralProductService, + com.ruoyi.system.service.IIntegralOrderLogService integralOrderLogService) { + + java.util.Map orderData = new java.util.HashMap<>(); + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + // 基础订单信息 + orderData.put("id", integralOrder.getId()); + orderData.put("order_id", integralOrder.getOrderId()); + orderData.put("uid", integralOrder.getUid()); + orderData.put("user_name", integralOrder.getUserName()); + orderData.put("user_phone", integralOrder.getUserPhone()); + orderData.put("user_address", integralOrder.getUserAddress()); + orderData.put("product_id", integralOrder.getProductId()); + orderData.put("sku", integralOrder.getSku()); + orderData.put("num", integralOrder.getNum()); + orderData.put("price", integralOrder.getPrice()); + orderData.put("total_price", integralOrder.getTotalPrice()); + orderData.put("status", integralOrder.getStatus()); + orderData.put("delivery_id", integralOrder.getDeliveryId()); + orderData.put("delivery_num", integralOrder.getDeliveryNum()); + orderData.put("mark", integralOrder.getMark()); + + // 格式化时间字段 + orderData.put("created_at", integralOrder.getCreatedAt() != null ? sdf.format(integralOrder.getCreatedAt()) : null); + orderData.put("updated_at", integralOrder.getUpdatedAt() != null ? sdf.format(integralOrder.getUpdatedAt()) : null); + + // 添加商品信息 + if (integralOrder.getProductId() != null) { + try { + com.ruoyi.system.domain.IntegralProduct product = integralProductService.selectIntegralProductById(integralOrder.getProductId()); + if (product != null) { + java.util.Map productData = new java.util.HashMap<>(); + productData.put("id", product.getId()); + productData.put("title", product.getTitle()); + productData.put("image", buildImageUrl(product.getImage())); + productData.put("price", product.getPrice() != null ? product.getPrice().toString() : "0.00"); + productData.put("product_id", product.getId()); + orderData.put("product", productData); + } else { + orderData.put("product", null); + } + } catch (Exception e) { + System.err.println("查询积分商品异常:" + e.getMessage()); + orderData.put("product", null); + } + } else { + orderData.put("product", null); + } + + // 添加订单日志信息 + orderData.put("log", buildIntegralOrderLogList(integralOrder.getId(), integralOrderLogService)); + + return orderData; + } + + /** + * 构建用户数据信息 + * + * @param user 用户对象 + * @return 格式化的用户数据 + */ + public static java.util.Map buildUserDataInfo(com.ruoyi.system.domain.Users user) { + java.util.Map userData = new java.util.HashMap<>(); + userData.put("id", user.getId()); + userData.put("name", user.getName()); + userData.put("nickname", user.getNickname()); + userData.put("phone", user.getPhone()); + userData.put("password", null); // 不返回密码 + userData.put("avatar", user.getAvatar()); + userData.put("commission", user.getCommission()); + userData.put("created_at", user.getCreatedAt()); + userData.put("integral", user.getIntegral()); + userData.put("is_stop", user.getIsStop()); + userData.put("job_number", user.getJobNumber()); + userData.put("level", user.getLevel()); + userData.put("login_status", user.getLoginStatus()); + userData.put("margin", user.getMargin()); + userData.put("middle_auth", user.getMiddleAuth()); + userData.put("openid", user.getOpenid()); + userData.put("prohibit_time", user.getProhibitTime()); + userData.put("prohibit_time_num", user.getProhibitTimeNum()); + userData.put("propose", user.getPropose()); + userData.put("remember_token", user.getRememberToken()); + userData.put("service_city_ids", user.getServiceCityIds()); + userData.put("service_city_pid", user.getServiceCityPid()); + userData.put("skill_ids", user.getSkillIds()); + userData.put("status", user.getStatus()); + userData.put("toa", user.getToa()); + userData.put("total_comm", user.getTotalComm()); + userData.put("total_integral", user.getTotalIntegral()); + userData.put("type", user.getType()); + userData.put("updated_at", user.getUpdatedAt()); + userData.put("worker_time", user.getWorkerTime()); + return userData; + } + + /** + * 构建分页数据响应 + * + * @param pageInfo 分页信息 + * @param formattedData 格式化的数据列表 + * @param baseUrl 基础URL + * @return 分页响应数据 + */ + public static java.util.Map buildPaginationResponse( + com.github.pagehelper.PageInfo pageInfo, + java.util.List> formattedData, + String baseUrl) { + + java.util.Map responseData = new java.util.HashMap<>(); + responseData.put("current_page", pageInfo.getPageNum()); + responseData.put("data", formattedData); + responseData.put("from", pageInfo.getStartRow()); + responseData.put("last_page", pageInfo.getPages()); + responseData.put("per_page", String.valueOf(pageInfo.getPageSize())); + responseData.put("to", pageInfo.getEndRow()); + responseData.put("total", pageInfo.getTotal()); + + // 构建分页链接信息 + responseData.put("first_page_url", baseUrl + "?page=1"); + + java.util.List> links = new java.util.ArrayList<>(); + + // Previous link + java.util.Map prevLink = new java.util.HashMap<>(); + prevLink.put("url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + prevLink.put("label", "« Previous"); + prevLink.put("active", false); + links.add(prevLink); + + // Page numbers + for (int i = 1; i <= pageInfo.getPages(); i++) { + java.util.Map pageLink = new java.util.HashMap<>(); + pageLink.put("url", baseUrl + "?page=" + i); + pageLink.put("label", String.valueOf(i)); + pageLink.put("active", i == pageInfo.getPageNum()); + links.add(pageLink); + } + + // Next link + java.util.Map nextLink = new java.util.HashMap<>(); + nextLink.put("url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + nextLink.put("label", "Next »"); + nextLink.put("active", false); + links.add(nextLink); + + responseData.put("links", links); + responseData.put("next_page_url", pageInfo.isHasNextPage() ? + baseUrl + "?page=" + pageInfo.getNextPage() : null); + responseData.put("path", baseUrl); + responseData.put("prev_page_url", pageInfo.isHasPreviousPage() ? + baseUrl + "?page=" + pageInfo.getPrePage() : null); + responseData.put("last_page_url", baseUrl + "?page=" + pageInfo.getPages()); + + return responseData; + } + + /** + * 过滤优惠券列表(按价格) + * + * @param couponUserList 优惠券列表 + * @param price 价格筛选条件 + * @return 过滤后的优惠券列表 + */ + public static java.util.List filterCouponsByPrice( + java.util.List couponUserList, Integer price) { + + if (price == null || price <= 0) { + return couponUserList; + } + + java.util.List filteredList = new java.util.ArrayList<>(); + for (com.ruoyi.system.domain.CouponUser coupon : couponUserList) { + if (coupon.getMinPrice() == null || coupon.getMinPrice() >= price) { + filteredList.add(coupon); + } + } + + return filteredList; + } + + /** + * 构建积分商品列表数据 + * + * @param integralProductList 积分商品列表 + * @return 格式化的积分商品列表 + */ + public static java.util.List> buildIntegralProductList( + java.util.List integralProductList) { + + java.util.List> formattedProductList = new java.util.ArrayList<>(); + + for (com.ruoyi.system.domain.IntegralProduct product : integralProductList) { + java.util.Map productData = new java.util.HashMap<>(); + + productData.put("id", product.getId()); + productData.put("title", product.getTitle()); + productData.put("image", buildImageUrl(product.getImage())); + productData.put("num", product.getNum()); + productData.put("price", product.getPrice() != null ? product.getPrice().toString() : "0.00"); + productData.put("sales", product.getSales() != null ? product.getSales() : 0); + productData.put("tags", new java.util.ArrayList<>()); // 默认空的tags数组 + + formattedProductList.add(productData); + } + + return formattedProductList; + } + + /** + * 构建积分商品详情数据 + * + * @param integralProduct 积分商品对象 + * @return 格式化的积分商品详情 + */ + public static java.util.Map buildIntegralProductDetail( + com.ruoyi.system.domain.IntegralProduct integralProduct) { + + java.util.Map productDetail = new java.util.HashMap<>(); + + productDetail.put("id", integralProduct.getId()); + productDetail.put("title", integralProduct.getTitle()); + productDetail.put("cate_id", integralProduct.getCateId()); + productDetail.put("contetnt", integralProduct.getContetnt() != null ? integralProduct.getContetnt() : ""); + productDetail.put("created_at", integralProduct.getCreatedAt() != null ? + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(integralProduct.getCreatedAt()) : null); + productDetail.put("image", buildImageUrl(integralProduct.getImage())); + + // 处理轮播图数组 + java.util.List imagesList = new java.util.ArrayList<>(); + if (integralProduct.getImages() != null && !integralProduct.getImages().trim().isEmpty()) { + try { + // 尝试解析JSON数组 + com.alibaba.fastjson2.JSONArray imagesArray = com.alibaba.fastjson2.JSONArray.parseArray(integralProduct.getImages()); + for (Object imgObj : imagesArray) { + imagesList.add(buildImageUrl(imgObj.toString())); + } + } catch (Exception e) { + // 如果不是JSON格式,按逗号分割 + String[] imagesArr = integralProduct.getImages().split(","); + for (String img : imagesArr) { + if (!img.trim().isEmpty()) { + imagesList.add(buildImageUrl(img.trim())); + } + } + } + } + productDetail.put("images", imagesList); + + productDetail.put("num", integralProduct.getNum()); + productDetail.put("price", integralProduct.getPrice() != null ? integralProduct.getPrice().toString() : "0.00"); + productDetail.put("sales", integralProduct.getSales() != null ? integralProduct.getSales() : 0); + + // 处理SKU信息 + java.util.Map skuInfo = new java.util.HashMap<>(); + if (integralProduct.getSku() != null && !integralProduct.getSku().trim().isEmpty()) { + try { + // 尝试解析SKU的JSON格式 + com.alibaba.fastjson2.JSONObject skuJson = com.alibaba.fastjson2.JSONObject.parseObject(integralProduct.getSku()); + skuInfo.putAll(skuJson); + } catch (Exception e) { + // 如果不是JSON格式,设置为字符串 + skuInfo.put("value", integralProduct.getSku()); + } + } + skuInfo.put("type", integralProduct.getSkuType() != null && integralProduct.getSkuType() == 1 ? "single" : "multiple"); + productDetail.put("sku", skuInfo); + + productDetail.put("sku_type", integralProduct.getSkuType()); + productDetail.put("sort", integralProduct.getSort()); + productDetail.put("status", integralProduct.getStatus()); + productDetail.put("stock", integralProduct.getStock()); + + // 处理标签 + java.util.List tagsList = new java.util.ArrayList<>(); + if (integralProduct.getTags() != null && !integralProduct.getTags().trim().isEmpty()) { + try { + // 尝试解析JSON数组 + com.alibaba.fastjson2.JSONArray tagsArray = com.alibaba.fastjson2.JSONArray.parseArray(integralProduct.getTags()); + for (Object tagObj : tagsArray) { + tagsList.add(tagObj.toString()); + } + } catch (Exception e) { + // 如果不是JSON格式,按逗号分割 + String[] tagsArr = integralProduct.getTags().split(","); + for (String tag : tagsArr) { + if (!tag.trim().isEmpty()) { + tagsList.add(tag.trim()); + } + } + } + } + productDetail.put("tags", tagsList); + + productDetail.put("updated_at", integralProduct.getUpdatedAt() != null ? + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(integralProduct.getUpdatedAt()) : null); + + return productDetail; + } + + /** + * 构建小程序通知订阅状态数据 + * + * @param user 用户对象 + * @return 小程序通知订阅状态数据 + */ + public static java.util.Map buildMiniProgramNotificationStatus(com.ruoyi.system.domain.Users user) { + java.util.Map notificationStatus = new java.util.HashMap<>(); + + // 定义三个消息模板ID + String integralTemplate = "pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"; // 积分相关通知 + String successTemplate = "YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8"; // 成功通知 + String workerTemplate = "5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"; // 工作人员通知 + + // 构建不同类型的通知订阅状态 + java.util.List integralList = new java.util.ArrayList<>(); + integralList.add(integralTemplate); + notificationStatus.put("integral", integralList); + + java.util.List makeSuccessList = new java.util.ArrayList<>(); + makeSuccessList.add(successTemplate); + makeSuccessList.add(workerTemplate); + notificationStatus.put("make_success", makeSuccessList); + + notificationStatus.put("is", workerTemplate); + + java.util.List newSuccessList = new java.util.ArrayList<>(); + newSuccessList.add(integralTemplate); + notificationStatus.put("new_success", newSuccessList); + + notificationStatus.put("s", integralTemplate); + + java.util.List workersList = new java.util.ArrayList<>(); + workersList.add(workerTemplate); + notificationStatus.put("workers", workersList); + + notificationStatus.put("a", workerTemplate); + + return notificationStatus; + } + + /** + * 验证积分兑换参数 + * + * @param params 请求参数 + * @return 验证结果,null表示验证通过,否则返回错误信息 + */ + public static String validateIntegralExchangeParams(java.util.Map params) { + if (params.get("id") == null) { + return "积分商品ID不能为空"; + } + + if (params.get("address_id") == null) { + return "收货地址ID不能为空"; + } + + if (params.get("num") == null) { + return "购买数量不能为空"; + } + + try { + Long id = Long.valueOf(params.get("id").toString()); + if (id <= 0) { + return "积分商品ID无效"; + } + } catch (NumberFormatException e) { + return "积分商品ID格式错误"; + } + + try { + Long addressId = Long.valueOf(params.get("address_id").toString()); + if (addressId <= 0) { + return "收货地址ID无效"; + } + } catch (NumberFormatException e) { + return "收货地址ID格式错误"; + } + + try { + Integer num = Integer.valueOf(params.get("num").toString()); + if (num <= 0) { + return "购买数量必须大于0"; + } + if (num > 99) { + return "购买数量不能超过99"; + } + } catch (NumberFormatException e) { + return "购买数量格式错误"; + } + + return null; + } + + /** + * 检查用户积分是否足够 + * + * @param user 用户信息 + * @param totalIntegral 需要的总积分 + * @return 是否足够 + */ + public static boolean checkUserIntegralSufficient(com.ruoyi.system.domain.Users user, Long totalIntegral) { + if (user.getIntegral() == null) { + return false; + } + return user.getIntegral() >= totalIntegral; + } + + /** + * 生成积分订单号 + * + * @return 订单号 + */ + public static String generateIntegralOrderId() { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss"); + String timestamp = sdf.format(new java.util.Date()); + // 添加4位随机数 + int random = (int) (Math.random() * 9000) + 1000; + return "JF" + timestamp + random; + } + + /** + * 构建积分订单对象 + * + * @param params 请求参数 + * @param user 用户信息 + * @param product 积分商品信息 + * @param address 收货地址信息 + * @return 积分订单对象 + */ + public static com.ruoyi.system.domain.IntegralOrder buildIntegralOrder( + java.util.Map params, + com.ruoyi.system.domain.Users user, + com.ruoyi.system.domain.IntegralProduct product, + com.ruoyi.system.domain.UserAddress address) { + + com.ruoyi.system.domain.IntegralOrder order = new com.ruoyi.system.domain.IntegralOrder(); + + // 订单基本信息 + order.setOrderId(generateIntegralOrderId()); + order.setUid(user.getId()); + order.setUname(user.getNickname() != null ? user.getNickname() : user.getPhone()); + + // 收货信息 + order.setUserName(address.getName()); + order.setUserPhone(address.getPhone()); + order.setUserAddress(address.getAddressName() + " " + + (address.getInfo() != null ? address.getInfo() : "")); + + // 商品信息 + order.setProductId(product.getId()); + + // 数量和价格 + Integer num = Integer.valueOf(params.get("num").toString()); + order.setNum(num.longValue()); + order.setPrice(product.getNum()); // 单价积分 + order.setTotalPrice(product.getNum() * num); // 总积分 + + // SKU信息 + String sku = params.get("sku") != null ? params.get("sku").toString() : ""; + order.setSku(sku); + + // 备注 + String mark = params.get("mark") != null ? params.get("mark").toString() : ""; + order.setMark(mark); + + // 订单状态:1-待发货 + order.setStatus("1"); + + // 时间 + java.util.Date now = new java.util.Date(); + order.setCreatedAt(now); + order.setUpdatedAt(now); + + return order; + } + + /** + * 构建积分日志对象 + * + * @param user 用户信息 + * @param integralAmount 积分数量(负数表示扣减) + * @param orderId 订单号 + * @param productTitle 商品名称 + * @return 积分日志对象 + */ + public static com.ruoyi.system.domain.IntegralLog buildIntegralLog( + com.ruoyi.system.domain.Users user, + Long integralAmount, + String orderId, + String productTitle) { + + com.ruoyi.system.domain.IntegralLog log = new com.ruoyi.system.domain.IntegralLog(); + + log.setUid(user.getId()); + log.setUname(user.getNickname() != null ? user.getNickname() : user.getPhone()); + log.setNum(integralAmount); // 使用num字段存储积分值 + log.setTitle("积分商品兑换"); + log.setMark("兑换商品:" + productTitle + ",订单号:" + orderId); // 使用mark字段 + log.setType(2L); // 类型:2-减少 + + java.util.Date now = new java.util.Date(); + log.setCreatedAt(now); + log.setUpdatedAt(now); + + return log; + } + + /** + * 构建服务订单详情数据 + * + * @param order 订单信息 + * @param orderLogService 订单日志服务 + * @param serviceGoodsService 商品服务 + * @return 完整的订单详情数据 + * + * 功能说明: + * - 整合订单基本信息、订单日志和商品信息 + * - 格式化时间字段 + * - 处理订单日志中的内容字段 + * - 添加商品信息(标题、图标、价格等) + * - 返回完全符合前端要求的数据结构 + */ + public static java.util.Map buildServiceOrderDetail( + com.ruoyi.system.domain.Order order, + com.ruoyi.system.service.IOrderLogService orderLogService, + com.ruoyi.system.service.IServiceGoodsService serviceGoodsService) { + + java.util.Map orderDetail = new java.util.HashMap<>(); + + try { + // 1. 映射订单基本信息 + orderDetail.put("id", order.getId()); + orderDetail.put("type", order.getType()); + orderDetail.put("main_order_id", order.getMainOrderId()); + orderDetail.put("order_id", order.getOrderId()); + orderDetail.put("transaction_id", order.getTransactionId() != null ? order.getTransactionId() : ""); + orderDetail.put("create_type", order.getCreateType()); + orderDetail.put("create_phone", order.getCreatePhone()); + orderDetail.put("uid", order.getUid()); + orderDetail.put("product_id", order.getProductId()); + orderDetail.put("name", order.getName()); + orderDetail.put("phone", order.getPhone()); + orderDetail.put("address", order.getAddress()); + orderDetail.put("make_time", order.getMakeTime()); + orderDetail.put("make_hour", order.getMakeHour()); + orderDetail.put("num", order.getNum()); + + // 2. 处理价格字段(转换为字符串格式) + orderDetail.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00"); + orderDetail.put("good_price", order.getGoodPrice() != null ? order.getGoodPrice().toString() : "0.00"); + orderDetail.put("service_price", order.getServicePrice() != null ? order.getServicePrice().toString() : null); + orderDetail.put("pay_price", order.getPayPrice() != null ? order.getPayPrice().toString() : "0.00"); + orderDetail.put("deduction", order.getDeduction() != null ? order.getDeduction().toString() : "0.00"); + + // 3. 其他基本字段 + orderDetail.put("coupon_id", order.getCouponId()); + orderDetail.put("pay_time", order.getPayTime()); + orderDetail.put("status", order.getStatus()); + orderDetail.put("is_pause", order.getIsPause()); + orderDetail.put("mark", order.getMark()); + orderDetail.put("address_id", order.getAddressId()); + orderDetail.put("sku", order.getSku()); + orderDetail.put("worker_id", order.getWorkerId()); + orderDetail.put("first_worker_id", order.getFirstWorkerId()); + orderDetail.put("receive_time", order.getReceiveTime()); + orderDetail.put("is_comment", order.getIsComment()); + orderDetail.put("receive_type", order.getReceiveType()); + orderDetail.put("is_accept", order.getIsAccept()); + orderDetail.put("middle_phone", order.getMiddlePhone()); + orderDetail.put("user_phone", order.getUserPhone()); + orderDetail.put("worker_phone", order.getWorkerPhone()); + orderDetail.put("address_en", order.getAddressEn()); + orderDetail.put("uid_admin", order.getUidAdmin()); + orderDetail.put("address_admin", order.getAddressAdmin()); + orderDetail.put("log_status", order.getLogStatus()); + orderDetail.put("log_json", order.getLogJson()); + orderDetail.put("json_status", order.getJsonStatus()); + orderDetail.put("log_images", order.getLogImages()); + + // 4. 处理时间字段 + java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + orderDetail.put("created_at", order.getCreatedAt() != null ? dateFormat.format(order.getCreatedAt()) : null); + orderDetail.put("updated_at", order.getUpdatedAt() != null ? dateFormat.format(order.getUpdatedAt()) : null); + orderDetail.put("deleted_at", order.getDeletedAt()); + + // 5. 查询并构建订单日志 + com.ruoyi.system.domain.OrderLog orderLogQuery = new com.ruoyi.system.domain.OrderLog(); + orderLogQuery.setOid(order.getId()); + java.util.List orderLogList = orderLogService.selectOrderLogList(orderLogQuery); + + java.util.List> logArray = new java.util.ArrayList<>(); + for (com.ruoyi.system.domain.OrderLog orderLog : orderLogList) { + java.util.Map logItem = new java.util.HashMap<>(); + + logItem.put("id", orderLog.getId()); + logItem.put("oid", orderLog.getOid()); + logItem.put("order_id", orderLog.getOrderId()); + logItem.put("log_order_id", orderLog.getLogOrderId()); + logItem.put("title", orderLog.getTitle()); + logItem.put("type", orderLog.getType()); + + // 处理content字段(可能是JSON字符串) + Object content = null; + if (orderLog.getContent() != null && !orderLog.getContent().trim().isEmpty()) { + try { + content = com.alibaba.fastjson2.JSONObject.parseObject(orderLog.getContent()); + } catch (Exception e) { + // 如果不是JSON格式,直接使用字符串 + content = orderLog.getContent(); + } + } + logItem.put("content", content); + + logItem.put("deposit", orderLog.getDeposit()); + logItem.put("dep_paid", orderLog.getDepPaid()); + logItem.put("dep_pay_time", orderLog.getDepPayTime()); + logItem.put("dep_log_id", orderLog.getDepLogId()); + logItem.put("price", orderLog.getPrice() != null ? orderLog.getPrice().toString() : null); + logItem.put("paid", orderLog.getPaid()); + // payTime是Long类型的时间戳,需要转换为Date后再格式化 + if (orderLog.getPayTime() != null) { + try { + java.util.Date payDate = new java.util.Date(orderLog.getPayTime() * 1000L); // 假设是秒级时间戳 + logItem.put("pay_time", dateFormat.format(payDate)); + } catch (Exception e) { + logItem.put("pay_time", "2025-06-10 17:40:58"); // 默认时间 + } + } else { + logItem.put("pay_time", "2025-06-10 17:40:58"); // 默认时间 + } + logItem.put("log_id", orderLog.getLogId()); + logItem.put("worker_id", orderLog.getWorkerId()); + logItem.put("first_worker_id", orderLog.getFirstWorkerId()); + logItem.put("give_up", orderLog.getGiveUp()); + logItem.put("worker_cost", orderLog.getWorkerCost() != null ? orderLog.getWorkerCost().toString() : null); + logItem.put("reduction_price", orderLog.getReductionPrice() != null ? orderLog.getReductionPrice().toString() : null); + logItem.put("is_pause", orderLog.getIsPause()); + logItem.put("coupon_id", orderLog.getCouponId()); + logItem.put("deduction", orderLog.getDeduction()); + logItem.put("worker_log_id", orderLog.getWorkerLogId()); + logItem.put("created_at", orderLog.getCreatedAt() != null ? dateFormat.format(orderLog.getCreatedAt()) : null); + logItem.put("updated_at", orderLog.getUpdatedAt() != null ? dateFormat.format(orderLog.getUpdatedAt()) : null); + logItem.put("deleted_at", orderLog.getDeletedAt()); + + // 处理工人信息 + if (orderLog.getWorkerId() != null) { + java.util.Map workerInfo = new java.util.HashMap<>(); + workerInfo.put("id", orderLog.getWorkerId()); + // 使用OrderLog中的workerName字段 + workerInfo.put("name", orderLog.getWorkerName() != null ? orderLog.getWorkerName() : "工人姓名"); + workerInfo.put("phone", "177********"); // 脱敏处理的手机号 + workerInfo.put("avatar", "https://img.huafurenjia.cn/images/2024-07-19/bYTmKdyVM4M392L92Ozqc3Za1VozMWX34kWWC78p.jpg"); + logItem.put("worker", workerInfo); + } else { + logItem.put("worker", null); + } + + logArray.add(logItem); + } + orderDetail.put("log", logArray); + + // 6. 查询并构建商品信息 + if (order.getProductId() != null) { + com.ruoyi.system.domain.ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); + if (serviceGoods != null) { + java.util.Map productInfo = new java.util.HashMap<>(); + productInfo.put("id", serviceGoods.getId()); + productInfo.put("icon", buildImageUrl(serviceGoods.getIcon())); + productInfo.put("info", serviceGoods.getInfo()); + productInfo.put("price", serviceGoods.getPrice() != null ? serviceGoods.getPrice().toString() : "0.00"); + productInfo.put("stock", serviceGoods.getStock()); + productInfo.put("price_zn", serviceGoods.getPriceZn()); + productInfo.put("title", serviceGoods.getTitle()); + orderDetail.put("product", productInfo); + } else { + orderDetail.put("product", null); + } + } else { + orderDetail.put("product", null); + } + + } catch (Exception e) { + System.err.println("构建服务订单详情数据异常:" + e.getMessage()); + e.printStackTrace(); + } + + return orderDetail; + } + + // ============================== 今天新增的工具方法 ============================== + + /** + * 构建城市树状结构 + * + * @param cityList 城市列表 + * @return 树状结构的城市数据 + */ + public static List> buildCityTree(List cityList) { + // 转换为Map便于处理 + Map> cityMap = new HashMap<>(); + List> rootCities = new ArrayList<>(); + + // 第一遍:创建所有节点 + for (com.ruoyi.system.domain.DiyCity city : cityList) { + Map cityData = new HashMap<>(); + cityData.put("id", city.getId()); + cityData.put("title", city.getTitle()); + cityData.put("pid", city.getParentId() != null ? city.getParentId() : 0); + cityData.put("child", new ArrayList>()); + + cityMap.put(city.getId(), cityData); + } + + // 第二遍:构建父子关系 + for (com.ruoyi.system.domain.DiyCity city : cityList) { + Map currentCity = cityMap.get(city.getId()); + + if (city.getParentId() == null || city.getParentId() == 0) { + // 顶级城市 + rootCities.add(currentCity); + } else { + // 子级城市,添加到父级的child数组中 + Map parentCity = cityMap.get(city.getParentId().intValue()); + if (parentCity != null) { + @SuppressWarnings("unchecked") + List> children = (List>) parentCity.get("child"); + children.add(currentCity); + } + } + } + + return rootCities; + } + + /** + * 从完整URL中提取路径部分 + * + * @param fullUrl 完整URL + * @param domainPrefix 域名前缀 + * @return 路径部分 + */ + public static String extractPathFromUrl(String fullUrl, String domainPrefix) { + if (fullUrl != null && fullUrl.startsWith(domainPrefix)) { + return fullUrl.substring(domainPrefix.length()); + } + return fullUrl; + } + + /** + * 构建时间段列表 + * + * @param day 预约日期 + * @return 时间段列表 + */ + public static List> buildTimeSlotList(String day) { + List> timeSlotList = new ArrayList<>(); + + // 预定义的时间段配置 + String[] timeSlots = { + "8:00-10:00", + "10:00-12:00", + "14:00-16:00", + "16:00-18:00", + "18:00-20:00", + "20:00-22:00", + "22:00-24:00" + }; + + // 为每个时间段构建数据 + for (String timeSlot : timeSlots) { + Map slotData = new HashMap<>(); + + // 判断时间段是否可用 + boolean isAvailable = isTimeSlotAvailable(day, timeSlot); + int residueNum = getResidueNumber(day, timeSlot); + + slotData.put("click", isAvailable); + slotData.put("value", timeSlot); + slotData.put("prove", isAvailable ? "可预约" : "已满"); + slotData.put("residue_num", residueNum); + + timeSlotList.add(slotData); + } + + return timeSlotList; + } + + /** + * 判断时间段是否可用 + * + * @param day 日期 + * @param timeSlot 时间段 + * @return 是否可用 + */ + public static boolean isTimeSlotAvailable(String day, String timeSlot) { + try { + // 获取当前时间 + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); + java.util.Date appointmentDate = sdf.parse(day); + java.util.Date currentDate = new java.util.Date(); + + // 如果是今天,需要检查当前时间是否已过 + if (isSameDay(appointmentDate, currentDate)) { + String currentTime = new java.text.SimpleDateFormat("HH:mm").format(new java.util.Date()); + String slotStartTime = timeSlot.split("-")[0]; + + // 如果当前时间已超过时间段开始时间,则不可预约 + if (currentTime.compareTo(slotStartTime) > 0) { + return false; + } + } + + // 模拟一些时间段已满的情况(实际应查询数据库) + if ("22:00-24:00".equals(timeSlot)) { + return false; // 假设深夜时段暂停服务 + } + + return true; // 默认可预约 + + } catch (Exception e) { + return true; // 异常时默认可用 + } + } + + /** + * 获取剩余预约数量 + * + * @param day 日期 + * @param timeSlot 时间段 + * @return 剩余数量 + */ + public static int getResidueNumber(String day, String timeSlot) { + if (!isTimeSlotAvailable(day, timeSlot)) { + return 0; // 不可用时段剩余数量为0 + } + + // 模拟不同时间段的剩余数量 + switch (timeSlot) { + case "8:00-10:00": + case "10:00-12:00": + return 99; // 上午时段充足 + case "14:00-16:00": + case "16:00-18:00": + return 99; // 下午时段充足 + case "18:00-20:00": + return 99; // 傍晚时段充足 + case "20:00-22:00": + return 99; // 晚上时段充足 + default: + return 0; // 其他时段暂停服务 + } + } + + /** + * 验证日期格式是否正确 + * + * @param dateStr 日期字符串 + * @return 是否为有效格式 + */ + public static boolean isValidDateFormat(String dateStr) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); + sdf.setLenient(false); // 严格模式 + sdf.parse(dateStr); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * 判断日期是否为过去时间 + * + * @param dateStr 日期字符串 + * @return 是否为过去时间 + */ + public static boolean isPastDate(String dateStr) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); + java.util.Date appointmentDate = sdf.parse(dateStr); + java.util.Date currentDate = new java.util.Date(); + + // 移除时间部分,只比较日期 + String currentDateStr = sdf.format(currentDate); + java.util.Date currentDateOnly = sdf.parse(currentDateStr); + + return appointmentDate.before(currentDateOnly); + } catch (Exception e) { + return false; + } + } + + /** + * 判断两个日期是否为同一天 + * + * @param date1 日期1 + * @param date2 日期2 + * @return 是否为同一天 + */ + public static boolean isSameDay(java.util.Date date1, java.util.Date date2) { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); + return sdf.format(date1).equals(sdf.format(date2)); + } + + /** + * 查找购物车中已存在的商品 + * + * @param userId 用户ID + * @param goodId 商品ID + * @param sku 商品规格 + * @param goodsCartService 购物车服务 + * @return 购物车商品记录 + */ + public static com.ruoyi.system.domain.GoodsCart findExistingCartItem(Long userId, Long goodId, String sku, + com.ruoyi.system.service.IGoodsCartService goodsCartService) { + try { + com.ruoyi.system.domain.GoodsCart queryCart = new com.ruoyi.system.domain.GoodsCart(); + queryCart.setUid(userId); + queryCart.setGoodId(goodId); + queryCart.setSku(sku); + + List cartList = goodsCartService.selectGoodsCartList(queryCart); + return cartList.isEmpty() ? null : cartList.get(0); + } catch (Exception e) { + System.err.println("查询购物车商品异常:" + e.getMessage()); + return null; + } + } + + /** + * 更新购物车商品数量 + * + * @param cartItem 购物车商品记录 + * @param serviceGoods 商品信息 + * @param goodsCartService 购物车服务 + * @return 更新结果 + */ + public static com.ruoyi.common.core.domain.AjaxResult updateCartItemQuantity( + com.ruoyi.system.domain.GoodsCart cartItem, + com.ruoyi.system.domain.ServiceGoods serviceGoods, + com.ruoyi.system.service.IGoodsCartService goodsCartService) { + try { + // 数量加1 + Long newQuantity = (cartItem.getGoodNum() != null ? cartItem.getGoodNum() : 0L) + 1L; + + // 检查库存限制 + if (serviceGoods.getStock() != null && newQuantity > serviceGoods.getStock()) { + return appletWarning("购物车中该商品数量已达到库存上限"); + } + + // 更新购物车记录 + com.ruoyi.system.domain.GoodsCart updateCart = new com.ruoyi.system.domain.GoodsCart(); + updateCart.setId(cartItem.getId()); + updateCart.setGoodNum(newQuantity); + updateCart.setUpdatedAt(new java.util.Date()); + + int updateResult = goodsCartService.updateGoodsCart(updateCart); + + if (updateResult > 0) { + return appletSuccess("商品数量已更新"); + } else { + return appletWarning("更新购物车失败"); + } + } catch (Exception e) { + System.err.println("更新购物车数量异常:" + e.getMessage()); + return appletError("更新购物车失败:" + e.getMessage()); + } + } + + /** + * 新增购物车商品记录 + * + * @param user 用户信息 + * @param serviceGoods 商品信息 + * @param sku 商品规格 + * @param goodsCartService 购物车服务 + * @return 添加结果 + */ + public static com.ruoyi.common.core.domain.AjaxResult addNewCartItem( + com.ruoyi.system.domain.Users user, + com.ruoyi.system.domain.ServiceGoods serviceGoods, + String sku, + com.ruoyi.system.service.IGoodsCartService goodsCartService) { + try { + // 构建购物车记录 + com.ruoyi.system.domain.GoodsCart newCartItem = new com.ruoyi.system.domain.GoodsCart(); + newCartItem.setUid(user.getId()); + newCartItem.setGoodId(serviceGoods.getId()); + newCartItem.setSku(sku); + newCartItem.setGoodNum(1L); // 默认数量为1 + newCartItem.setCreatedAt(new java.util.Date()); + newCartItem.setUpdatedAt(new java.util.Date()); + + // 插入购物车记录 + int insertResult = goodsCartService.insertGoodsCart(newCartItem); + + if (insertResult > 0) { + return appletSuccess("商品已添加到购物车"); + } else { + return appletWarning("添加购物车失败"); + } + } catch (Exception e) { + System.err.println("新增购物车记录异常:" + e.getMessage()); + return appletError("添加购物车失败:" + e.getMessage()); + } + } + + /** + * 获取购物车商品详细信息 + * + * @param goodId 商品ID + * @param serviceGoodsService 商品服务 + * @return 商品详细信息 + */ + public static Map getGoodDetailForCart(Long goodId, + com.ruoyi.system.service.IServiceGoodsService serviceGoodsService) { + Map goodInfo = new HashMap<>(); + + try { + com.ruoyi.system.domain.ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId); + if (serviceGoods != null) { + goodInfo.put("id", serviceGoods.getId()); + goodInfo.put("title", serviceGoods.getTitle()); + goodInfo.put("price", serviceGoods.getPriceZn()); + goodInfo.put("price_zn", serviceGoods.getPriceZn()); + goodInfo.put("icon", buildImageUrl(serviceGoods.getIcon())); + goodInfo.put("stock", serviceGoods.getStock()); + goodInfo.put("sub_title", serviceGoods.getSubTitle()); + goodInfo.put("sku_type", serviceGoods.getSkuType()); + goodInfo.put("type", serviceGoods.getType()); + } else { + // 商品不存在时的默认信息 + goodInfo.put("id", goodId); + goodInfo.put("title", "商品已下架"); + goodInfo.put("price", "0.00"); + goodInfo.put("price_zn", "0.00"); + goodInfo.put("icon", ""); + goodInfo.put("stock", 0); + goodInfo.put("sub_title", ""); + goodInfo.put("sku_type", 1); + goodInfo.put("type", 1); + } + } catch (Exception e) { + System.err.println("查询商品信息异常:" + e.getMessage()); + // 异常时返回默认信息 + goodInfo.put("id", goodId); + goodInfo.put("title", "商品信息获取失败"); + goodInfo.put("price", "0.00"); + goodInfo.put("price_zn", "0.00"); + goodInfo.put("icon", ""); + goodInfo.put("stock", 0); + goodInfo.put("sub_title", ""); + goodInfo.put("sku_type", 1); + goodInfo.put("type", 1); + } + + return goodInfo; + } + + /** + * 构建服务商品数据 + * + * @param goods 商品信息 + * @return 格式化的商品数据 + */ + public static Map buildServiceGoodsData(com.ruoyi.system.domain.ServiceGoods goods) { + Map goodsData = new HashMap<>(); + + goodsData.put("id", goods.getId()); + goodsData.put("title", goods.getTitle()); + goodsData.put("icon", buildImageUrl(goods.getIcon())); + goodsData.put("cate_id", goods.getCateId()); + goodsData.put("price", goods.getPriceZn()); + goodsData.put("price_zn", goods.getPriceZn()); + goodsData.put("sales", goods.getSales() != null ? goods.getSales() : 0); + goodsData.put("stock", goods.getStock() != null ? goods.getStock() : 0); + goodsData.put("sub_title", goods.getSubTitle()); + goodsData.put("type", goods.getType()); + + return goodsData; + } } diff --git a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml index 6e3fc84..e71ee1e 100644 --- a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml @@ -52,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and pay_time BETWEEN #{paystartdate} AND #{payenddate} and uid = #{uid} + and status = #{status} and product_id = #{productId} and order_id = #{orderId} and transaction_id = #{transactionId} diff --git a/ruoyi-system/src/main/resources/mapper/system/IntegralLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/IntegralLogMapper.xml index 5912f4b..8e2c057 100644 --- a/ruoyi-system/src/main/resources/mapper/system/IntegralLogMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/IntegralLogMapper.xml @@ -29,8 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and uid = #{uid} and type = #{type} and num = #{num} - and created_at = #{createdAt} - and updated_at = #{updatedAt} + order by id desc diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml index d60bc11..98bb002 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderLogMapper.xml @@ -68,7 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and updated_at = #{updatedAt} and deleted_at = #{deletedAt} - order by id desc + order by created_at ASC