package com.ruoyi.system.ControllerUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.ruoyi.system.domain.ServiceCate; import com.ruoyi.system.domain.ServiceGoods; import com.ruoyi.system.domain.Users; import com.ruoyi.system.service.IServiceGoodsService; import com.ruoyi.system.service.IUsersService; import com.github.pagehelper.PageInfo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 小程序控制器工具类 * * 提供小程序相关的数据处理、响应实体转换等工具方法 * 主要功能: * 1. 服务商品响应数据格式化 * 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; } /** * 判断字符串是否能转换为 JSONArray * * @param str 需要判断的字符串 * @return 如果是合法的JSON数组字符串,返回 true;否则返回 false */ public static boolean canParseToJSONArray(String str) { if (str == null || str.trim().isEmpty()) { return false; } try { Object obj = JSON.parse(str); return obj instanceof JSONArray; } catch (Exception e) { // 解析失败,不是合法的JSON数组 return false; } } /** * 服务商品详情响应实体类 * * 用于格式化服务商品数据,统一小程序端的数据结构 * 将数据库实体ServiceGoods转换为前端需要的JSON格式 * * 主要特性: * - 自动处理图片URL添加CDN前缀 * - 支持JSON数组和逗号分隔的字符串解析 * - 统一数据类型转换(BigDecimal转String等) * - 设置合理的默认值避免空值异常 */ public static class ServiceGoodsResponse { /** 商品ID */ private Long id; /** 商品标题 */ private String title; /** 商品图标(自动添加CDN前缀) */ private String icon; /** 商品轮播图数组(自动添加CDN前缀) */ private List imgs; /** 商品副标题 */ private String sub_title; /** 商品简介 */ private String info; /** 商品价格(字符串格式) */ private String price; /** 列表价格显示(字符串格式) */ private String price_in; /** 销量 */ private Integer sales; /** 库存 */ private Integer stock; /** 状态 */ private String status; /** 商品详情描述 */ private String description; /** 规格类型 1:单规格 2:多规格 */ private Integer sku_type; /** SKU规格对象 */ private Map sku; /** 纬度 */ private String latitude; /** 经度 */ private String longitude; /** 类型 1:服务 2:商品 */ private Integer type; /** 分类ID */ private Long cate_id; /** 服务项目 */ private String project; /** 排序 */ private Integer sort; /** 物料费用 */ private String material; /** 邮费(字符串格式) */ private String postage; /** 基检现象数组 */ private List basic; /** 保证金(字符串格式) */ private String margin; /** 所需技能ID */ private String skill_ids; /** 创建时间 */ private String created_at; /** 更新时间 */ private String updated_at; /** 删除时间 */ private String deleted_at; /** 评论对象(预留扩展) */ private Map comment; /** * 构造方法 - 将ServiceGoods实体转换为响应格式 * * @param goods ServiceGoods实体对象 * * 主要处理: * 1. 基础字段映射和类型转换 * 2. 图片URL添加CDN前缀 * 3. 数组字段解析(支持JSON和逗号分隔) * 4. 空值处理和默认值设置 * 5. 特殊对象构建(SKU、评论等) */ public ServiceGoodsResponse(ServiceGoods goods) { // 基础字段映射 this.id = goods.getId(); this.title = goods.getTitle(); this.icon = buildImageUrl(goods.getIcon()); this.sub_title = goods.getSubTitle(); this.info = goods.getInfo(); // 价格字段处理 - BigDecimal转String避免精度问题 this.price = goods.getPrice() != null ? goods.getPrice().toString() : "0.00"; this.price_in = goods.getPriceZn() != null ? goods.getPriceZn() : ""; // 数值字段处理 - Long转Integer并设置默认值 this.sales = goods.getSales() != null ? goods.getSales().intValue() : 0; this.stock = goods.getStock() != null ? goods.getStock().intValue() : 0; this.sort = goods.getSort() != null ? goods.getSort().intValue() : 1; // 状态和类型字段 this.status = goods.getStatus() != null ? goods.getStatus() : "1"; this.type = goods.getType() != null ? goods.getType().intValue() : 1; this.sku_type = goods.getSkuType() != null ? goods.getSkuType().intValue() : 1; // 文本字段 this.description = goods.getDescription(); this.latitude = goods.getLatitude(); this.longitude = goods.getLongitude(); this.cate_id = goods.getCateId(); this.project = goods.getProject(); this.material = goods.getMaterial(); this.skill_ids = goods.getSkillIds(); // 金额字段处理 - BigDecimal转String this.postage = goods.getPostage() != null ? goods.getPostage().toString() : ""; this.margin = goods.getMargin() != null ? goods.getMargin().toString() : ""; // 时间字段处理 this.created_at = goods.getCreatedAt() != null ? goods.getCreatedAt().toString() : ""; this.updated_at = goods.getUpdatedAt() != null ? goods.getUpdatedAt().toString() : ""; this.deleted_at = goods.getDeletedAt() != null ? goods.getDeletedAt().toString() : null; // 数组字段解析 this.imgs = parseStringToImageList(goods.getImgs()); this.basic = parseStringToList(goods.getBasic()); // 构建SKU对象 - 默认单规格 this.sku = new HashMap<>(); this.sku.put("type", "single"); // 构建评论对象 - 预留扩展 this.comment = new HashMap<>(); } // Getter和Setter方法(完整实现) public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public List getImgs() { return imgs; } public void setImgs(List imgs) { this.imgs = imgs; } public String getSub_title() { return sub_title; } public void setSub_title(String sub_title) { this.sub_title = sub_title; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getPrice_in() { return price_in; } public void setPrice_in(String price_in) { this.price_in = price_in; } public Integer getSales() { return sales; } public void setSales(Integer sales) { this.sales = sales; } public Integer getStock() { return stock; } public void setStock(Integer stock) { this.stock = stock; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getSku_type() { return sku_type; } public void setSku_type(Integer sku_type) { this.sku_type = sku_type; } public Map getSku() { return sku; } public void setSku(Map sku) { this.sku = sku; } public String getLatitude() { return latitude; } public void setLatitude(String latitude) { this.latitude = latitude; } public String getLongitude() { return longitude; } public void setLongitude(String longitude) { this.longitude = longitude; } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public Long getCate_id() { return cate_id; } public void setCate_id(Long cate_id) { this.cate_id = cate_id; } public String getProject() { return project; } public void setProject(String project) { this.project = project; } public Integer getSort() { return sort; } public void setSort(Integer sort) { this.sort = sort; } public String getMaterial() { return material; } public void setMaterial(String material) { this.material = material; } public String getPostage() { return postage; } public void setPostage(String postage) { this.postage = postage; } public List getBasic() { return basic; } public void setBasic(List basic) { this.basic = basic; } public String getMargin() { return margin; } public void setMargin(String margin) { this.margin = margin; } public String getSkill_ids() { return skill_ids; } public void setSkill_ids(String skill_ids) { this.skill_ids = skill_ids; } public String getCreated_at() { return created_at; } public void setCreated_at(String created_at) { this.created_at = created_at; } public String getUpdated_at() { return updated_at; } public void setUpdated_at(String updated_at) { this.updated_at = updated_at; } public String getDeleted_at() { return deleted_at; } public void setDeleted_at(String deleted_at) { this.deleted_at = deleted_at; } public Map getComment() { return comment; } public void setComment(Map comment) { this.comment = comment; } } /** * CDN域名常量 * 用于图片URL统一添加CDN前缀 */ private static final String CDN_BASE_URL = "https://img.huafurenjia.cn/"; /** * 构建完整的图片URL * * @param imagePath 图片路径 * @return 完整的图片URL(包含CDN前缀) * * 处理逻辑: * - 如果图片路径为空,返回空字符串 * - 自动添加CDN域名前缀 * - 确保URL格式正确 */ public static String buildImageUrl(String imagePath) { if (imagePath == null || imagePath.trim().isEmpty()) { return ""; } return CDN_BASE_URL + imagePath.trim(); } /** * 解析字符串为图片URL列表 * * @param imgsString 图片字符串(支持JSON数组或逗号分隔) * @return 图片URL列表(已添加CDN前缀) * * 支持的格式: * 1. JSON数组格式:["img1.jpg", "img2.jpg"] * 2. 逗号分隔格式:img1.jpg,img2.jpg * * 处理特性: * - 自动识别数据格式 * - 过滤空值和空白字符 * - 自动添加CDN前缀 * - 异常容错处理 */ public static List parseStringToImageList(String imgsString) { List imageList = new java.util.ArrayList<>(); if (imgsString == null || imgsString.trim().isEmpty()) { return imageList; } try { // 尝试解析JSON数组格式 JSONArray jsonArray = JSONArray.parseArray(imgsString); for (int i = 0; i < jsonArray.size(); i++) { String img = jsonArray.getString(i); if (img != null && !img.trim().isEmpty()) { imageList.add(buildImageUrl(img.trim())); } } } catch (Exception e) { // JSON解析失败,按逗号分割处理 String[] imgArray = imgsString.split(","); for (String img : imgArray) { String trimmedImg = img.trim(); if (!trimmedImg.isEmpty()) { imageList.add(buildImageUrl(trimmedImg)); } } } return imageList; } /** * 解析字符串为普通字符串列表 * * @param dataString 数据字符串(支持JSON数组或逗号分隔) * @return 字符串列表 * * 用于解析基检现象、标签等文本数组数据 * * 支持的格式: * 1. JSON数组格式:["现象1", "现象2"] * 2. 逗号分隔格式:现象1,现象2 * * 处理特性: * - 自动识别数据格式 * - 过滤空值和空白字符 * - 异常容错处理 */ public static List parseStringToList(String dataString) { List dataList = new java.util.ArrayList<>(); if (dataString == null || dataString.trim().isEmpty()) { return dataList; } try { // 尝试解析JSON数组格式 JSONArray jsonArray = JSONArray.parseArray(dataString); for (int i = 0; i < jsonArray.size(); i++) { String item = jsonArray.getString(i); if (item != null && !item.trim().isEmpty()) { dataList.add(item.trim()); } } } catch (Exception e) { // JSON解析失败,按逗号分割处理 String[] dataArray = dataString.split(","); for (String item : dataArray) { String trimmedItem = item.trim(); if (!trimmedItem.isEmpty()) { dataList.add(trimmedItem); } } } return dataList; } /** * 构建分类数据 * * @param category 分类信息 * @param keywords 搜索关键词(可选) * @param serviceGoodsService 服务商品Service * @return 格式化的分类数据 * * 返回数据结构: * { * "id": 分类ID, * "title": 分类标题, * "icon": 分类图标URL, * "type": 分类类型, * "cate_id": 分类ID, * "goods": [商品列表] * } * * 功能特性: * - 查询分类下的所有商品 * - 支持关键词搜索过滤 * - 自动添加图片CDN前缀 * - 返回统一的数据格式 */ public static Map buildCategoryData(ServiceCate category, String keywords, IServiceGoodsService serviceGoodsService) { Map categoryData = new HashMap<>(); // 分类基础信息 categoryData.put("id", category.getId()); categoryData.put("title", category.getTitle()); categoryData.put("icon", buildImageUrl(category.getIcon())); categoryData.put("type", category.getType()); categoryData.put("cate_id", category.getId()); // 查询该分类下的商品 ServiceGoods serviceGoodsQuery = new ServiceGoods(); serviceGoodsQuery.setCateId(category.getId()); // 如果有关键词,添加搜索条件 if (keywords != null && !keywords.trim().isEmpty()) { serviceGoodsQuery.setTitle(keywords.trim()); } // 查询商品列表 List goodsList = serviceGoodsService.selectServiceGoodsList(serviceGoodsQuery); List> goodsDataList = new java.util.ArrayList<>(); // 构建商品数据列表 for (ServiceGoods goods : goodsList) { Map goodsData = new HashMap<>(); goodsData.put("id", goods.getId()); goodsData.put("title", goods.getTitle()); goodsData.put("icon", buildImageUrl(goods.getIcon())); goodsData.put("type", goods.getType()); goodsData.put("cate_id", goods.getCateId()); goodsDataList.add(goodsData); } categoryData.put("goods", goodsDataList); return categoryData; } /** * 获取用户数据 * * @param token 用户令牌 * @param usersService 用户Service * @return 用户数据Map * * 返回数据结构: * - code: 200(成功) / 302(未登录) / 400(令牌无效) * - user: 用户信息对象(成功时返回) * * 状态码说明: * - 200: 令牌有效,用户存在 * - 302: 未提供令牌,需要登录 * - 400: 令牌无效或用户不存在 * * 主要用途: * - 验证用户登录状态 * - 获取用户基础信息 * - 权限验证前置处理 */ public static Map getUserData(String token, IUsersService usersService) { Map resultMap = new HashMap<>(); if (token == null || token.trim().isEmpty()) { // 未提供令牌 resultMap.put("code", 302); resultMap.put("message", "未登录,请先登录"); } else { // 查询用户信息 Users user = usersService.selectUsersByRememberToken(token.trim()); if (user != null) { // 用户存在且令牌有效 resultMap.put("code", 200); resultMap.put("user", user); resultMap.put("message", "获取用户信息成功"); } else { // 令牌无效或用户不存在 resultMap.put("code", 400); resultMap.put("message", "令牌无效或用户不存在"); } } return resultMap; } /** * 微信用户登录方法 * * @param openid 微信用户openid * @param usersService 用户Service * @return 登录结果Map * * 返回数据结构: * { * "success": true/false, // 登录是否成功 * "token": "用户token", // 登录成功时返回 * "userInfo": {...}, // 用户信息 * "message": "提示信息" // 操作结果消息 * } * * 登录流程: * 1. 验证openid的有效性 * 2. 查询或创建用户记录 * 3. 生成用户token * 4. 更新用户登录信息 * 5. 返回登录结果 * * 业务逻辑: * - 首次登录:创建新用户记录 * - 再次登录:更新登录时间和token * - 支持用户信息同步更新 */ public static Map wechatUserLogin(String openid, IUsersService usersService) { Map result = new HashMap<>(); try { // 1. 参数验证 if (openid == null || openid.trim().isEmpty()) { result.put("success", false); result.put("message", "openid不能为空"); return result; } String trimmedOpenid = openid.trim(); // 2. 验证openid有效性 Map validationResult = WechatApiUtil.validateOpenid(trimmedOpenid); if (!(Boolean) validationResult.get("valid")) { result.put("success", false); result.put("message", "openid验证失败:" + validationResult.get("errorMsg")); return result; } // 3. 获取微信用户信息 Map wechatUserInfo = (Map) validationResult.get("userInfo"); // 4. 查询数据库中是否已存在该用户 Users existingUser = usersService.selectUsersByOpenid(trimmedOpenid); Users userRecord; boolean isNewUser = false; if (existingUser == null) { // 4.1 首次登录,创建新用户记录 userRecord = createNewWechatUser(trimmedOpenid, wechatUserInfo); isNewUser = true; } else { // 4.2 用户已存在,更新用户信息 userRecord = updateExistingWechatUser(existingUser, wechatUserInfo); } // 5. 生成新的用户token String userToken = WechatApiUtil.generateUserToken(trimmedOpenid); userRecord.setRememberToken(userToken); // 6. 保存或更新用户记录到数据库 if (isNewUser) { // 插入新用户 int insertResult = usersService.insertUsers(userRecord); if (insertResult <= 0) { result.put("success", false); result.put("message", "创建用户记录失败"); return result; } } else { // 更新现有用户 int updateResult = usersService.updateUsers(userRecord); if (updateResult <= 0) { result.put("success", false); result.put("message", "更新用户记录失败"); return result; } } // 7. 构建返回数据 Map responseUserInfo = buildUserResponseInfo(userRecord, wechatUserInfo); result.put("success", true); result.put("token", userToken); result.put("userInfo", responseUserInfo); result.put("isNewUser", isNewUser); result.put("loginTime", System.currentTimeMillis()); result.put("message", isNewUser ? "注册并登录成功" : "登录成功"); } catch (Exception e) { result.put("success", false); result.put("message", "登录过程中发生错误:" + e.getMessage()); } return result; } /** * 创建新的微信用户记录 * * @param openid 微信openid * @param wechatUserInfo 微信用户信息 * @return 新创建的用户记录 * * 用户字段设置: * - 基础信息:openid、昵称、头像等 * - 状态信息:启用状态、注册时间等 * - 默认值:密码、角色等系统字段 */ private static Users createNewWechatUser(String openid, Map wechatUserInfo) { Users newUser = new Users(); // 基础信息 newUser.setOpenid(openid); newUser.setNickname((String) wechatUserInfo.get("nickname")); newUser.setAvatar((String) wechatUserInfo.get("avatar")); // 用户名使用openid(可以根据业务需求调整) newUser.setName("wx_" + openid.substring(openid.length() - 8)); // 设置默认密码(微信登录不需要密码) newUser.setPassword(""); // 实际项目中可能需要加密的默认密码 // 状态信息 newUser.setStatus(1); // 启用状态:1启用 0关闭 newUser.setType("1"); // 用户类型:1普通用户 2师傅 // 时间信息 java.util.Date now = new java.util.Date(); newUser.setCreateTime(now); newUser.setUpdateTime(now); // 其他信息 newUser.setRemark("微信小程序用户"); return newUser; } /** * 更新现有微信用户记录 * * @param existingUser 现有用户记录 * @param wechatUserInfo 微信用户信息 * @return 更新后的用户记录 * * 更新策略: * - 同步微信最新信息:昵称、头像等 * - 更新登录时间 * - 保持原有的系统信息不变 */ private static Users updateExistingWechatUser(Users existingUser, Map wechatUserInfo) { // 更新微信相关信息 existingUser.setNickname((String) wechatUserInfo.get("nickname")); existingUser.setAvatar((String) wechatUserInfo.get("avatar")); // 更新登录时间 existingUser.setUpdateTime(new java.util.Date()); return existingUser; } /** * 构建用户响应信息 * * @param userRecord 用户数据库记录 * @param wechatUserInfo 微信用户信息 * @return 格式化的用户信息 * * 返回字段: * - 基础信息:用户ID、昵称、头像等 * - 微信信息:openid等 * - 状态信息:用户状态、注册时间等 * - 过滤敏感信息:密码等 */ private static Map buildUserResponseInfo(Users userRecord, Map wechatUserInfo) { Map userInfo = new HashMap<>(); // 基础用户信息 userInfo.put("userId", userRecord.getId()); userInfo.put("username", userRecord.getName()); userInfo.put("nickname", userRecord.getNickname()); userInfo.put("avatar", userRecord.getAvatar()); userInfo.put("openid", userRecord.getOpenid()); // 状态信息 userInfo.put("status", userRecord.getStatus()); userInfo.put("userType", userRecord.getType()); userInfo.put("createTime", userRecord.getCreateTime()); userInfo.put("updateTime", userRecord.getUpdateTime()); // 微信附加信息 userInfo.put("gender", wechatUserInfo.get("gender")); userInfo.put("city", wechatUserInfo.get("city")); userInfo.put("province", wechatUserInfo.get("province")); userInfo.put("country", wechatUserInfo.get("country")); return userInfo; } /** * 验证用户token有效性 * * @param token 用户token * @param usersService 用户Service * @return 验证结果Map * * 返回数据结构: * { * "valid": true/false, // token是否有效 * "userInfo": {...}, // 用户信息(有效时返回) * "message": "提示信息" // 验证结果消息 * } * * 验证逻辑: * 1. 检查token格式是否正确 * 2. 从数据库查询token对应的用户 * 3. 验证用户状态是否正常 * 4. 检查token是否过期(可选) * 5. 返回验证结果 */ public static Map validateUserToken(String token, IUsersService usersService) { Map result = new HashMap<>(); try { // 1. 参数验证 if (token == null || token.trim().isEmpty()) { result.put("valid", false); result.put("message", "token不能为空"); return result; } String trimmedToken = token.trim(); // 2. 检查token格式 if (!WechatApiUtil.isValidTokenFormat(trimmedToken)) { result.put("valid", false); result.put("message", "token格式无效"); return result; } // 3. 从数据库查询token对应的用户 Users user = usersService.selectUsersByRememberToken(trimmedToken); if (user == null) { result.put("valid", false); result.put("message", "token无效或已过期"); return result; } // 4. 检查用户状态 if (!"1".equals(user.getStatus())) { result.put("valid", false); result.put("message", "用户账号已被禁用"); return result; } // 5. 构建用户信息(过滤敏感字段) Map userInfo = new HashMap<>(); userInfo.put("userId", user.getId()); userInfo.put("username", user.getName()); userInfo.put("nickname", user.getNickname()); userInfo.put("avatar", user.getAvatar()); userInfo.put("openid", user.getOpenid()); userInfo.put("status", user.getStatus()); userInfo.put("userType", user.getType()); userInfo.put("createTime", user.getCreateTime()); userInfo.put("updateTime", user.getUpdateTime()); result.put("valid", true); result.put("userInfo", userInfo); result.put("message", "token验证成功"); } catch (Exception e) { result.put("valid", false); result.put("message", "验证token时发生错误:" + e.getMessage()); } 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; } /** * 构建分页响应结构,适用于小程序worker相关接口 * @param pageInfo PageInfo对象 * @param dataList 数据列表 * @param baseUrl 分页url前缀 * @return Map分页结构 */ public static Map buildPageResult(PageInfo pageInfo, List dataList, String baseUrl) { Map dataPage = new HashMap<>(); dataPage.put("current_page", pageInfo.getPageNum()); dataPage.put("data", dataList); dataPage.put("first_page_url", baseUrl + "?page=1"); dataPage.put("from", pageInfo.getStartRow()); dataPage.put("last_page", pageInfo.getPages()); dataPage.put("last_page_url", baseUrl + "?page=" + pageInfo.getPages()); // 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); for (int i = 1; i <= pageInfo.getPages(); i++) { Map link = new HashMap<>(); link.put("url", baseUrl + "?page=" + i); link.put("label", String.valueOf(i)); link.put("active", i == pageInfo.getPageNum()); links.add(link); } 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); dataPage.put("links", links); dataPage.put("next_page_url", pageInfo.isHasNextPage() ? baseUrl + "?page=" + pageInfo.getNextPage() : null); dataPage.put("path", baseUrl); dataPage.put("per_page", pageInfo.getPageSize()); dataPage.put("prev_page_url", pageInfo.isHasPreviousPage() ? baseUrl + "?page=" + pageInfo.getPrePage() : null); dataPage.put("to", pageInfo.getEndRow()); dataPage.put("total", pageInfo.getTotal()); return dataPage; } /** * 云信交互式语音通知回调接口 *

* 用于接收云信平台推送的语音通知结果,解析callId、result、message等字段。 * 该方法可直接作为Controller层的回调接口方法使用。 *

* @param requestBody 云信平台推送的JSON字符串 * @return 标准响应结果 */ public static Map voiceInteractNotifyCallback(String requestBody) { Map resultMap = new HashMap<>(); try { // 解析JSON请求体 com.alibaba.fastjson2.JSONObject json = com.alibaba.fastjson2.JSONObject.parseObject(requestBody); String callId = json.getString("callId"); String result = json.getString("result"); String message = json.getString("message"); // 业务处理:可根据callId、result、message进行自定义逻辑 // 例如:记录日志、更新数据库、通知业务系统等 // 返回标准响应 resultMap.put("code", 200); resultMap.put("msg", "回调接收成功"); resultMap.put("callId", callId); resultMap.put("result", result); resultMap.put("message", message); } catch (Exception e) { resultMap.put("code", 500); resultMap.put("msg", "回调处理异常: " + e.getMessage()); } return resultMap; } }