package com.ruoyi.system.ControllerUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.*; import com.ruoyi.system.domain.AppleDoMain.OrderApple; import com.ruoyi.system.service.*; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.*; import javax.servlet.http.HttpServletRequest; /** * 小程序控制器工具类 *

* 提供小程序相关的数据处理、响应实体转换等工具方法 * 主要功能: * 1. 服务商品响应数据格式化 * 2. 分类数据构建 * 3. 用户数据处理 * 4. 图片和基础信息数组解析 * 5. 统一响应格式处理 * * @author Mr. Zhang Pan * @version 1.0 * @date 2025-01-03 */ public class AppletControllerUtil { private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class); private static final IUserAddressService userAddressService = SpringUtils.getBean(IUserAddressService.class); // ============================== 统一响应处理方法 ============================== /** * 成功响应 - code: 200 * * @param data 响应数据 * @return AjaxResult */ public static AjaxResult appletSuccess(Object data) { AjaxResult result = new AjaxResult(); result.put("code", 200); result.put("msg", "OK"); result.put("data", data); return result; } /** * 成功响应 - code: 200,无数据 * * @param message 成功消息 * @return AjaxResult */ public static AjaxResult appletSuccess(String message) { return appletSuccess((Object) message); } /** * 成功响应 - code: 200,默认消息 * * @return AjaxResult */ public static AjaxResult appletSuccess() { return appletSuccess("操作成功"); } /** * 业务提示响应 - code: 422 * * @param message 提示消息 * @return AjaxResult */ public static AjaxResult appletWarning(String message) { AjaxResult result = new AjaxResult(); result.put("code", 422); result.put("msg", message); result.put("data", new ArrayList<>()); return result; } /** * 业务提示响应 - code:500 * * @param message 提示消息 * @return AjaxResult */ public static AjaxResult appletkaifaWarning(String message) { AjaxResult result = new AjaxResult(); result.put("code", 500); result.put("msg", message); result.put("data", new ArrayList<>()); return result; } /** * 业务提示响应 - code: 422,带数据 * * @param message 提示消息 * @param data 响应数据 * @return AjaxResult */ public static AjaxResult appletWarning(String message, Object data) { AjaxResult result = new AjaxResult(); result.put("code", 422); result.put("msg", message); result.put("data", data != null ? data : new ArrayList<>()); return result; } /** * Token验证失败响应 - code: 332 * * @return AjaxResult */ public static AjaxResult appletUnauthorized() { return appletUnauthorized("用户未登录或token无效,请重新登录"); } /** * Token验证失败响应 - code: 332,自定义消息 * * @param message 提示消息 * @return AjaxResult */ public static AjaxResult appletUnauthorized(String message) { AjaxResult result = new AjaxResult(); result.put("code", 332); result.put("msg", message); result.put("data", new ArrayList<>()); return result; } /** * 系统错误响应 - code: 500 * * @param message 错误消息 * @return AjaxResult */ public static AjaxResult appletError(String message) { AjaxResult result = new AjaxResult(); result.put("code", 500); result.put("msg", message); result.put("data", new 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 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 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()); serviceGoodsQuery.setStatus("1"); // 如果有关键词,添加搜索条件 if (keywords != null && !keywords.trim().isEmpty()) { serviceGoodsQuery.setTitle(keywords.trim()); } // 查询商品列表 List goodsList = serviceGoodsService.selectServiceGoodsList(serviceGoodsQuery); List> goodsDataList = new 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师傅 // 时间信息 Date now = new 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 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 (user.getStatus()!=1) { 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 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表示验证通过 *

* 功能说明: * - 验证地址对象的必填字段是否完整 * - 验证手机号格式是否正确(11位数字) * - 为地址新增和编辑功能提供统一的参数验证 */ public static 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; // 验证通过 } /** * 构建地址新增对象 * * @param params 请求参数Map,包含新地址的各个字段信息 * @param userId 当前登录用户的ID * @return UserAddress对象,包含新地址的完整信息 *

* 功能说明: * - 从请求参数中提取地址信息并构建UserAddress对象 * - 智能处理is_default字段的多种数据类型(boolean/number/string) * - 为地址新增功能提供数据转换和默认值设置 */ public static 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); } } 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(Order order, String phone, String mark, Users user, IOrderReworkService orderReworkService, IOrderService orderService) { try { // 1. 创建售后返修记录 OrderRework orderRework = new 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) Order updateOrder = new 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 Cooperate buildCooperateApplication(Map params, Long uid, String uname) { Cooperate cooperate = new 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(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 List> buildIntegralOrderList( List integralOrderList, IIntegralProductService integralProductService) { List> formattedOrderList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (IntegralOrder order : integralOrderList) { Map orderData = new 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 Map buildIntegralProductInfo(Long productId, IIntegralProductService integralProductService) { if (productId == null) { return null; } try { IntegralProduct product = integralProductService.selectIntegralProductById(productId); if (product != null) { Map productData = new 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 List> buildIntegralLogList( List integralLogList) { List> formattedLogList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (IntegralLog log : integralLogList) { Map logData = new 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 List> buildCouponUserList( List couponUserList, IServiceCateService serviceCateService, IServiceGoodsService serviceGoodsService, String productId, BigDecimal totalPrice) { List> resultList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (CouponUser couponUser : couponUserList) { Map couponData = new HashMap<>(); ServiceGoods serviceGoods = null; if (couponUser.getProductId() != null && couponUser.getProductId() > 0) { serviceGoods=serviceGoodsService.selectServiceGoodsById(couponUser.getProductId()); } // 基础字段 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) { Date addTime = new 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 = true; // 添加 suit_title 字段 String suitTitle = ""; if (couponUser.getCateId() != null && couponUser.getCateId() > 0) { try { ServiceCate serviceCate = serviceCateService.selectServiceCateById(couponUser.getCateId()); if (serviceCate != null && serviceCate.getTitle() != null) { suitTitle = serviceCate.getTitle(); } } catch (Exception e) { System.err.println("查询服务分类异常:" + e.getMessage()); } if (serviceGoods != null && Objects.equals(serviceGoods.getCateId(), couponUser.getCateId())) { isUsed=false; } if (totalPrice!=null){ if (totalPrice.compareTo(new BigDecimal(couponUser.getMinPrice()))>0){ isUsed=false; } } } if (couponUser.getProductId() != null && couponUser.getProductId() > 0) { try { serviceGoods = serviceGoodsService.selectServiceGoodsById(couponUser.getProductId()); if (serviceGoods != null && serviceGoods.getTitle() != null) { suitTitle = serviceGoods.getTitle(); } } catch (Exception e) { System.err.println("查询服务分类异常:" + e.getMessage()); } if (serviceGoods != null && Objects.equals(serviceGoods.getId(),productId)) { isUsed=false; } if (totalPrice!=null){ if (totalPrice.compareTo(new BigDecimal(couponUser.getMinPrice()))>0){ isUsed=false; } } } if (couponUser.getReceiveType().equals("1")){ if (totalPrice!=null){ if (totalPrice.compareTo(new BigDecimal(couponUser.getMinPrice()))>0){ isUsed=false; } } } couponData.put("is_used", isUsed); 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; } /** * 构建优惠券列表数据 * * @return 格式化的优惠券列表 */ public static List> buildCouponDataList(List couponsList, IServiceCateService serviceCateService, IServiceGoodsService serviceGoodsService) { List> resultList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (Coupons coupons : couponsList) { Map couponData = new HashMap<>(); couponData.put("id", coupons.getId()); couponData.put("title", coupons.getId()); couponData.put("price", coupons.getPrice()); couponData.put("min_price", coupons.getMinPrice()); couponData.put("start_time", coupons.getStartTime()); couponData.put("end_time", coupons.getEndTime()); couponData.put("count", coupons.getCount()); couponData.put("is_permanent", coupons.getIsPermanent()); couponData.put("status", coupons.getStatus()); couponData.put("coupon_time", coupons.getCouponTime()); couponData.put("product_id", coupons.getProductId()); couponData.put("type", coupons.getType()); couponData.put("receive_type", coupons.getReceiveType()); couponData.put("sort", coupons.getSort()); couponData.put("cate_id", coupons.getCateId()); couponData.put("user_ids", coupons.getUserIds()); couponData.put("created_at", coupons.getCreatedAt() != null ? sdf.format(coupons.getCreatedAt()) : null); couponData.put("updated_at", coupons.getCreatedAt() != null ? sdf.format(coupons.getCreatedAt()) : null); couponData.put("deleted_at", coupons.getCreatedAt() != null ? sdf.format(coupons.getCreatedAt()) : null); couponData.put("cate", coupons.getId()); couponData.put("product", coupons.getId()); if (coupons.getCateId()!=null){ JSONObject cate = new JSONObject(); ServiceCate serviceCate = serviceCateService.selectServiceCateById(coupons.getCateId()); if (serviceCate!=null){ cate.put("id", serviceCate.getId()); cate.put("title", serviceCate.getTitle()); couponData.put("cate", cate); } } if (coupons.getProductId()!=null){ JSONObject product = new JSONObject(); ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(coupons.getProductId()); if (serviceGoods != null) { product.put("id", serviceGoods.getId()); product.put("title", serviceGoods.getTitle()); couponData.put("product", product); } } // 添加 tag 字段 String tag = "优惠券"; if (coupons.getReceiveType() != null) { String receiveType = String.valueOf(coupons.getReceiveType()); if (receiveType.equals("1")) { tag = "通用券"; } if (receiveType.equals("2")) { tag = "品类券"; } if (receiveType.equals("3")) { tag = "商品券"; } // if (receiveType.equals("4")) { // tag = "通用券"; // } // tag = switch (receiveType) { // case "1" -> "通用券"; // case "2" -> "品类券"; // case "3" -> "商品券"; // default -> "优惠券"; // }; } couponData.put("suit_title", tag); resultList.add(couponData); } return resultList; } /** * 构建积分订单日志列表 * * @param orderId 订单ID * @param integralOrderLogService 积分订单日志服务 * @return 格式化的日志列表 */ public static List> buildIntegralOrderLogList(Long orderId, IIntegralOrderLogService integralOrderLogService) { List> logList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { IntegralOrderLog logQuery = new IntegralOrderLog(); logQuery.setOid(orderId); List orderLogs = integralOrderLogService.selectIntegralOrderLogList(logQuery); for (IntegralOrderLog log : orderLogs) { Map logData = new 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 Map buildIntegralOrderDetail( IntegralOrder integralOrder, IIntegralProductService integralProductService, IIntegralOrderLogService integralOrderLogService) { Map orderData = new HashMap<>(); SimpleDateFormat sdf = new 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 { IntegralProduct product = integralProductService.selectIntegralProductById(integralOrder.getProductId()); if (product != null) { Map productData = new 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 Map buildUserDataInfo(Users user) { Map userData = new 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 Map buildPaginationResponse( PageInfo pageInfo, List> formattedData, String baseUrl) { Map responseData = new 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"); List> links = new ArrayList<>(); // Previous link 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); // Page numbers for (int i = 1; i <= pageInfo.getPages(); i++) { Map pageLink = new HashMap<>(); pageLink.put("url", baseUrl + "?page=" + i); pageLink.put("label", String.valueOf(i)); pageLink.put("active", i == pageInfo.getPageNum()); links.add(pageLink); } // Next 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); 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 List filterCouponsByPrice( List couponUserList, Integer price) { if (price == null || price <= 0) { return couponUserList; } List filteredList = new ArrayList<>(); for (CouponUser coupon : couponUserList) { if (coupon.getMinPrice() == null || coupon.getMinPrice() >= price) { filteredList.add(coupon); } } return filteredList; } /** * 构建积分商品列表数据 * * @param integralProductList 积分商品列表 * @return 格式化的积分商品列表 */ public static List> buildIntegralProductList( List integralProductList) { List> formattedProductList = new ArrayList<>(); for (IntegralProduct product : integralProductList) { Map productData = new 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 ArrayList<>()); // 默认空的tags数组 formattedProductList.add(productData); } return formattedProductList; } /** * 构建积分商品详情数据 * * @param integralProduct 积分商品对象 * @return 格式化的积分商品详情 */ public static Map buildIntegralProductDetail( IntegralProduct integralProduct) { Map productDetail = new 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 SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(integralProduct.getCreatedAt()) : null); productDetail.put("image", buildImageUrl(integralProduct.getImage())); // 处理轮播图数组 List imagesList = new ArrayList<>(); if (integralProduct.getImages() != null && !integralProduct.getImages().trim().isEmpty()) { try { // 尝试解析JSON数组 JSONArray imagesArray = 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信息 Map skuInfo = new HashMap<>(); if (integralProduct.getSku() != null && !integralProduct.getSku().trim().isEmpty()) { try { // 尝试解析SKU的JSON格式 JSONObject skuJson = 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()); // 处理标签 List tagsList = new ArrayList<>(); if (integralProduct.getTags() != null && !integralProduct.getTags().trim().isEmpty()) { try { // 尝试解析JSON数组 JSONArray tagsArray = 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 SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(integralProduct.getUpdatedAt()) : null); return productDetail; } /** * 构建小程序通知订阅状态数据 * * @param user 用户对象 * @return 小程序通知订阅状态数据 */ public static Map buildMiniProgramNotificationStatus(Users user) { Map notificationStatus = new HashMap<>(); // 定义三个消息模板ID String integralTemplate = "pv3cba-wPoinUbBZSskp0KpDNnJwrHqS0rvGBfDNQ1M"; // 积分相关通知 String successTemplate = "YKnuTCAD-oEEhNGoI3LUVkAqNsykOMTcyrf71S9vev8"; // 成功通知 String workerTemplate = "5lA-snytEPl25fBS7rf6rQi8Y0i5HOSdG0JMVdUnMcU"; // 工作人员通知 String payTemplate = "5rd-P19jRZaOkBXJlsG-SZDx_ZSEkvwIsGt_UoQAF6c"; // 支付消息通知 // 构建不同类型的通知订阅状态 List integralList = new ArrayList<>(); integralList.add(integralTemplate); notificationStatus.put("integral", integralList); List makeSuccessList = new ArrayList<>(); makeSuccessList.add(successTemplate); makeSuccessList.add(workerTemplate); notificationStatus.put("make_success", makeSuccessList); notificationStatus.put("is", workerTemplate); List newSuccessList = new ArrayList<>(); newSuccessList.add(integralTemplate); notificationStatus.put("new_success", newSuccessList); notificationStatus.put("s", integralTemplate); List workersList = new ArrayList<>(); workersList.add(workerTemplate); notificationStatus.put("workers", workersList); notificationStatus.put("a", workerTemplate); List paymsgList = new ArrayList<>(); paymsgList.add(payTemplate); notificationStatus.put("payinfo", paymsgList); notificationStatus.put("pay_template", payTemplate); return notificationStatus; } /** * 构建小程序zhifu通知订阅状态数据 * * @param user 用户对象 * @return 小程序通知订阅状态数据 */ public static Map buildMiniProgramNotificationpayStatus(Users user) { Map notificationStatus = new HashMap<>(); // 定义三个消息模板ID String payTemplate = "5rd-P19jRZaOkBXJlsG-SZDx_ZSEkvwIsGt_UoQAF6c"; // 积分相关通知 List workersList = new ArrayList<>(); workersList.add(payTemplate); notificationStatus.put("template_id", workersList); notificationStatus.put("template", payTemplate); return notificationStatus; } /** * 验证积分兑换参数 * * @param params 请求参数 * @return 验证结果,null表示验证通过,否则返回错误信息 */ public static String validateIntegralExchangeParams(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(Users user, Long totalIntegral) { if (user.getIntegral() == null) { return false; } return user.getIntegral() >= totalIntegral; } /** * 生成积分订单号 * * @return 订单号 */ public static String generateIntegralOrderId() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String timestamp = sdf.format(new Date()); // 添加4位随机数 int random = (int) (Math.random() * 9000) + 1000; return "JF" + timestamp + random; } /** * 构建积分订单对象 * * @param params 请求参数 * @param user 用户信息 * @param product 积分商品信息 * @param address 收货地址信息 * @return 积分订单对象 */ public static IntegralOrder buildIntegralOrder( Map params, Users user, IntegralProduct product, UserAddress address) { IntegralOrder order = new 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"); // 时间 Date now = new Date(); order.setCreatedAt(now); order.setUpdatedAt(now); return order; } /** * 构建积分日志对象 * * @param user 用户信息 * @param integralAmount 积分数量(负数表示扣减) * @param orderId 订单号 * @param productTitle 商品名称 * @return 积分日志对象 */ public static IntegralLog buildIntegralLog( Users user, Long integralAmount, String orderId, String productTitle) { IntegralLog log = new 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-减少 Date now = new Date(); log.setCreatedAt(now); log.setUpdatedAt(now); return log; } /** * 构建服务订单详情数据 * @param order 订单对象 * @param orderLogService 订单日志服务 * @param serviceGoodsService 商品服务 * @return 订单详情Map */ public static Map buildServiceOrderDetail(Order order, IOrderLogService orderLogService, IServiceGoodsService serviceGoodsService) { Map orderDetail = new HashMap<>(); // 订单基本信息 orderDetail.put("id", order.getId()); orderDetail.put("order_id", order.getOrderId()); orderDetail.put("status", order.getStatus()); orderDetail.put("total_price", order.getTotalPrice() != null ? order.getTotalPrice().toString() : "0.00"); orderDetail.put("num", order.getNum()); orderDetail.put("created_at", order.getCreatedAt()); // 商品信息 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("icon", buildImageUrl(serviceGoods.getIcon())); orderDetail.put("product", productInfo); } } // 订单日志 List logList = orderLogService.selectOrderLogByOrderId(order.getOrderId()); List> logs = new ArrayList<>(); for (OrderLog log : logList) { Map logMap = new HashMap<>(); logMap.put("id", log.getId()); logMap.put("title", log.getTitle()); logMap.put("type", log.getType()); logMap.put("content", log.getContent()); logMap.put("created_at", log.getCreatedAt()); logs.add(logMap); } orderDetail.put("logs", logs); return orderDetail; } // ============================== 今天新增的工具方法 ============================== /** * 构建城市树状结构 * * @param cityList 城市列表 * @return 树状结构的城市数据 */ public static List> buildCityTree(List cityList) { // 转换为Map便于处理 Map> cityMap = new HashMap<>(); List> rootCities = new ArrayList<>(); // 第一遍:创建所有节点 for (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 (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 order 订单主键 * @return 是否可用 */ public static Users creatWorkerForOrder(Order order) { GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil(); UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId()); // if (userAddress != null){ // String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude()); // if (city != null){ // // }else{ // // } // } Users worker = usersService.selectUsersById(2l); return worker; } /** * 判断时间段是否可用 * * @param day 日期 * @param timeSlot 时间段 * @return 是否可用 */ public static boolean isTimeSlotAvailable(String day, String timeSlot) { try { // 获取当前时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date appointmentDate = sdf.parse(day); Date currentDate = new Date(); // 如果是今天,需要检查当前时间是否已过 if (isSameDay(appointmentDate, currentDate)) { String currentTime = new SimpleDateFormat("HH:mm").format(new 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 { SimpleDateFormat sdf = new 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 { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date appointmentDate = sdf.parse(dateStr); Date currentDate = new Date(); // 移除时间部分,只比较日期 String currentDateStr = sdf.format(currentDate); 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(Date date1, Date date2) { SimpleDateFormat sdf = new 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 GoodsCart findExistingCartItem(Long userId, Long goodId, String sku, IGoodsCartService goodsCartService) { try { GoodsCart queryCart = new 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 AjaxResult updateCartItemQuantity( GoodsCart cartItem, ServiceGoods serviceGoods, IGoodsCartService goodsCartService) { try { // 数量加1 Long newQuantity = (cartItem.getGoodNum() != null ? cartItem.getGoodNum() : 0L) + 1L; // 检查库存限制 if (serviceGoods.getStock() != null && newQuantity > serviceGoods.getStock()) { return appletWarning("购物车中该商品数量已达到库存上限"); } // 更新购物车记录 GoodsCart updateCart = new GoodsCart(); updateCart.setId(cartItem.getId()); updateCart.setGoodNum(newQuantity); updateCart.setUpdatedAt(new 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 AjaxResult addNewCartItem( Users user, ServiceGoods serviceGoods, String sku, IGoodsCartService goodsCartService) { try { // 构建购物车记录 GoodsCart newCartItem = new GoodsCart(); newCartItem.setUid(user.getId()); newCartItem.setGoodId(serviceGoods.getId()); newCartItem.setSku(sku); newCartItem.setGoodNum(1L); // 默认数量为1 newCartItem.setCreatedAt(new Date()); newCartItem.setUpdatedAt(new 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, IServiceGoodsService serviceGoodsService) { Map goodInfo = new HashMap<>(); try { ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodId); if (serviceGoods != null) { goodInfo.put("id", serviceGoods.getId()); goodInfo.put("title", serviceGoods.getTitle()); goodInfo.put("price", serviceGoods.getPrice()); 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(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.getPrice()); 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请求体 JSONObject json = 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; } //完成订单的初步创建之后开始进行派单和发送订阅,以及预约师傅的操作 public static Map creatOrderTheNext(String imageUrl) { Map imageData = new HashMap<>(); //第一步给客户发送订阅消息,告诉客户预约成功 imageData.put("url", imageUrl); imageData.put("thumb", imageUrl); return imageData; } /** * 发送微信小程序订阅消息(自动获取accessToken) * * @param touser 接收者(用户)的openid * @param templateId 订阅消息模板ID * @param page 跳转页面路径(可选,可为null) * @param data 模板内容(如{"thing1":{"value":"内容"}}) * @return 微信接口响应字符串(JSON格式) * @throws Exception 异常信息 *

* 使用示例: * Map data = new HashMap<>(); * Map thing1 = new HashMap<>(); * thing1.put("value", "测试内容"); * data.put("thing1", thing1); * String result = AppletControllerUtil.WXSendMsgUtil(openid, templateId, "pages/index/index", data); */ public static String WXSendMsgUtil(String touser, String templateId, String page, Map data) throws Exception { // 1. 获取accessToken String accessToken = WechatApiUtil.getAccessToken().get("access_token").toString(); // 2. 微信订阅消息接口地址 String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken; // 3. 组装请求参数 Map param = new HashMap<>(); param.put("touser", touser); param.put("template_id", templateId); if (page != null && !page.isEmpty()) { param.put("page", page); } param.put("data", data); String body = JSON.toJSONString(param); // 4. 发送POST请求 HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); conn.setDoOutput(true); try (OutputStream os = conn.getOutputStream()) { os.write(body.getBytes(StandardCharsets.UTF_8)); } // 5. 读取响应 InputStream is = conn.getInputStream(); StringBuilder sb = new StringBuilder(); byte[] buf = new byte[1024]; int len; while ((len = is.read(buf)) != -1) { sb.append(new String(buf, 0, len, StandardCharsets.UTF_8)); } is.close(); return sb.toString(); } //时间转化,将int的时间戳转换为时间,这个方法用于订单详情里面的预约时间 public static String timeStamp2Date(Order order) { // 定义日期格式化模式 String formattedDate = ""; SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");// 注意:Java的Date构 if (order != null) { if (order.getMakeTime() != null) { // 将时间戳转换为Date对象 Date date = new Date((long) order.getMakeTime() * 1000); formattedDate = sdf.format(date); if (order.getMakeHour() != null) { formattedDate += " " + order.getMakeHour(); } } } return formattedDate.replace("-", "~"); } /** * 生成自定义前缀+16位唯一数字码 * 例如:FEEB724145038871780 * * @param prefix 前缀字母(可为null或空,自动生成4位大写字母) * @return 生成的码 */ public static String generateCustomCode(String prefix) { // 生成前缀 String codePrefix = prefix; if (codePrefix == null || codePrefix.trim().isEmpty()) { // 随机生成4位大写字母 StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < 4; i++) { char c = (char) ('A' + random.nextInt(26)); sb.append(c); } codePrefix = sb.toString(); } // 生成16位唯一数字 // 用当前时间戳+3位随机数,保证唯一性和随机性 long timestamp = System.currentTimeMillis(); String timePart = String.valueOf(timestamp); // 补足到16位 StringBuilder numberPart = new StringBuilder(timePart); Random random = new Random(); while (numberPart.length() < 16) { numberPart.append(random.nextInt(10)); } // 如果超出16位则截取 String finalNumber = numberPart.substring(0, 16); return codePrefix + finalNumber; } /** * 构建type=2商品的响应数据(按照json.txt格式) * * @param goods ServiceGoods商品对象 * @return 格式化的商品响应数据 */ public static Map buildType2ServiceGoodsResponse(ServiceGoods goods) { Map data = new HashMap<>(); // 基础信息 data.put("id", goods.getId()); data.put("title", goods.getTitle()); data.put("icon", buildImageUrl(goods.getIcon())); data.put("sub_title", goods.getSubTitle()); data.put("info", goods.getInfo()); data.put("price", goods.getPrice() != null ? goods.getPrice().toString() : "0.00"); data.put("price_zn", goods.getPriceZn()); data.put("sales", goods.getSales() != null ? goods.getSales().intValue() : 0); data.put("stock", goods.getStock() != null ? goods.getStock().intValue() : 0); data.put("status", goods.getStatus() != null ? goods.getStatus() : "1"); data.put("description", goods.getDescription()); data.put("sku_type", goods.getSkuType() != null ? goods.getSkuType().intValue() : 1); data.put("latitude", goods.getLatitude()); data.put("longitude", goods.getLongitude()); data.put("type", goods.getType() != null ? goods.getType().intValue() : 2); data.put("cate_id", goods.getCateId()); data.put("project", goods.getProject()); data.put("sort", goods.getSort() != null ? goods.getSort().intValue() : 1); data.put("material", goods.getMaterial()); data.put("postage", goods.getPostage() != null ? goods.getPostage().toString() : null); data.put("basic", parseBasicStringToArray(goods.getBasic())); data.put("margin", goods.getMargin() != null ? goods.getMargin().toString() : null); data.put("skill_ids", goods.getSkillIds()); // 处理图片数组 data.put("imgs", parseImagesStringToArray(goods.getImgs())); // 处理SKU数据 data.put("sku", parseSkuStringToObject(goods.getSku())); // 时间字段 data.put("created_at", formatDateToString(goods.getCreatedAt())); data.put("updated_at", formatDateToString(goods.getUpdatedAt())); data.put("deleted_at", goods.getDeletedAt() != null ? formatDateToString(goods.getDeletedAt()) : null); // 评论对象(预留) data.put("comment", null); return data; } /** * 解析图片字符串为数组(支持JSON和逗号分隔) * * @param imgs 图片字符串 * @return 图片URL列表 */ public static List parseImagesStringToArray(String imgs) { List imageList = new ArrayList<>(); if (imgs != null && !imgs.trim().isEmpty()) { try { // 尝试解析为JSON数组 JSONArray jsonArray = JSONArray.parseArray(imgs); for (int i = 0; i < jsonArray.size(); i++) { String img = jsonArray.getString(i); if (img != null && !img.trim().isEmpty()) { imageList.add(buildImageUrl(img)); } } } catch (Exception e) { // JSON解析失败,尝试按逗号分割 String[] imgArray = imgs.split("[,,]"); for (String img : imgArray) { if (img != null && !img.trim().isEmpty()) { imageList.add(buildImageUrl(img.trim())); } } } } return imageList; } /** * 解析基础现象字符串为数组 * * @param basic 基础现象字符串 * @return 基础现象列表,如果为空则返回null */ public static List parseBasicStringToArray(String basic) { if (basic == null || basic.trim().isEmpty()) { return null; } List basicList = new ArrayList<>(); try { // 尝试解析为JSON数组 JSONArray jsonArray = JSONArray.parseArray(basic); for (int i = 0; i < jsonArray.size(); i++) { String item = jsonArray.getString(i); if (item != null && !item.trim().isEmpty()) { basicList.add(item.trim()); } } } catch (Exception e) { // JSON解析失败,尝试按换行或逗号分割 String[] basicArray = basic.split("[\\n,,]"); for (String item : basicArray) { if (item != null && !item.trim().isEmpty()) { basicList.add(item.trim()); } } } return basicList.isEmpty() ? null : basicList; } /** * 解析SKU字符串为对象 * * @param sku SKU字符串 * @return SKU对象,解析失败返回null */ public static Map parseSkuStringToObject(String sku) { if (sku == null || sku.trim().isEmpty()) { return null; } try { // 尝试解析为JSON对象 JSONObject skuJson = JSONObject.parseObject(sku); return skuJson.toJavaObject(Map.class); } catch (Exception e) { // 解析失败,返回null return null; } } /** * 将字符串转换为JSON对象(通用工具方法) *

* 支持将JSON字符串转换为Map对象 * 如果字符串为空或解析失败,返回null * * @param jsonString JSON字符串 * @return JSON对象,解析失败返回null */ public static Map parseStringToJson(String jsonString) { if (jsonString == null || jsonString.trim().isEmpty()) { return null; } try { // 预处理字符串,移除可能的特殊字符 String cleanJsonString = cleanJsonString(jsonString); // 尝试解析为JSON对象 JSONObject jsonObject = JSONObject.parseObject(cleanJsonString); return jsonObject.toJavaObject(Map.class); } catch (Exception e) { // 解析失败,打印详细错误信息并返回null System.err.println("JSON解析失败,原始字符串: [" + jsonString + "], 错误: " + e.getMessage()); return null; } } /** * 清理JSON字符串,移除可能导致解析失败的字符 * * @param jsonString 原始JSON字符串 * @return 清理后的JSON字符串 */ private static String cleanJsonString(String jsonString) { if (jsonString == null) { return null; } // 移除BOM字符 if (jsonString.startsWith("\uFEFF")) { jsonString = jsonString.substring(1); } // 去除首尾空白字符 jsonString = jsonString.trim(); // 如果不是以{或[开头,可能不是有效的JSON if (!jsonString.startsWith("{") && !jsonString.startsWith("[")) { return "{}"; // 返回空对象 } return jsonString; } /** * 将字符串转换为JSON对象(带默认值) *

* 支持将JSON字符串转换为Map对象 * 如果字符串为空或解析失败,返回提供的默认值 * * @param jsonString JSON字符串 * @param defaultValue 解析失败时的默认值 * @return JSON对象,解析失败返回默认值 */ public static Map parseStringToJson(String jsonString, Map defaultValue) { Map result = parseStringToJson(jsonString); return result != null ? result : defaultValue; } /** * 格式化日期为字符串 * * @param date 日期对象 * @return 格式化后的日期字符串,格式为 "yyyy-MM-dd HH:mm:ss" */ public static String formatDateToString(Date date) { if (date == null) { return null; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(date); } /** * 处理SKU参数,确保以JSON字符串格式存储 * * @param skuParam 前端传递的SKU参数 * @return JSON字符串格式的SKU */ public static String processSkuParam(Object skuParam) { if (skuParam == null) { return ""; } if (skuParam instanceof Map) { // 如果是Map对象,转换为JSON字符串 try { return JSON.toJSONString(skuParam); } catch (Exception e) { System.err.println("SKU转换JSON失败:" + e.getMessage()); return skuParam.toString(); } } else { // 如果是字符串,直接使用 return skuParam.toString().trim(); } } /** * 获取订单状态文本 */ public static String getOrderStatusText(Long status) { if (status == null) { return "未知状态"; } 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 "未知状态"; } } /** * 从请求参数构建更新用户对象 * * @param params 请求参数 * @param userId 用户ID * @return 用户更新对象 */ public static Users buildUpdateUserFromdataParams(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 { BigDecimal propose = new 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; } /** * 构建用户信息响应 */ public static 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", buildImageUrl(avatar)); } else { userInfo.put("avatar", "https://img.huafurenjia.cn/default/user_avatar.jpeg"); } if (user.getType().equals("2")) { userInfo.put("commission", user.getCommission().toString() != null ? user.getCommission().toString() : "0.00"); userInfo.put("total_comm", user.getTotalComm().toString() != null ? user.getTotalComm().toString() : "0.00"); userInfo.put("propose", user.getPropose().toString() != null ? user.getPropose().toString() : "0.00"); } if (user.getType().equals("1")) { userInfo.put("balance", user.getBalance().toString() != null ? user.getBalance().toString() : "0.00"); userInfo.put("ismember", user.getIsmember()); userInfo.put("member_begin",user.getMemberBegin() != null ? sdf.format(user.getMemberBegin()) : null ); userInfo.put("member_end",user.getMemberEnd() != null ? sdf.format(user.getMemberEnd()) : null ); } 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("remember_token", user.getRememberToken()); userInfo.put("status", user.getStatus() != null ? user.getStatus() : 1); userInfo.put("tpd", 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); } if (user.getServiceCityIds() != null && !user.getServiceCityIds().isEmpty()) { userInfo.put("service_city_ids", parseStringToList(user.getServiceCityIds())); } else { userInfo.put("service_city_ids", new ArrayList<>()); } if (user.getSkillIds() != null && !user.getSkillIds().isEmpty()) { userInfo.put("skill_ids", parseStringToList(user.getSkillIds())); } else { userInfo.put("skill_ids", new ArrayList<>()); } return userInfo; } /** * 从请求参数构建更新用户对象 */ public static 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()); } 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); } 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) { String proposeStr = params.get("propose").toString().trim(); try { BigDecimal propose = new BigDecimal(proposeStr); updateUser.setPropose(propose); } catch (NumberFormatException e) { } } if (params.get("type") != null) { updateUser.setType(params.get("type").toString().trim()); } if (params.get("service_city_ids") != null) { List serviceCityIds = (List) params.get("service_city_ids"); if (!serviceCityIds.isEmpty()) { updateUser.setServiceCityIds(String.join(",", serviceCityIds)); } } 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类型(用于编辑接口) */ public static 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类型(用于编辑接口) */ public static 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; } /** * 验证用户编辑参数 */ public static 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; } /** * 构建商品订单详情 */ public static 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); orderDetail.put("address", addressInfo); } } if (order.getProductId() != null) { ServiceGoods product = SpringUtils.getBean(IServiceGoodsService.class).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", buildImageUrl(product.getIcon())); orderDetail.put("product", productInfo); } } orderDetail.put("comment", new ArrayList<>()); orderDetail.put("delivery", new ArrayList<>()); return orderDetail; } /** * 校验token并返回用户对象 * @param request HTTP请求对象 * @param usersService 用户服务 * @return 用户对象,未登录或无效返回null */ public static Users validateAndGetUser(HttpServletRequest request, IUsersService usersService) { String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); if (!(Boolean) userValidation.get("valid")) { return null; } return (Users) userValidation.get("user"); } /** * 构建售后返修分页数据 * @param user 当前用户 * @param status 返修状态 * @param page 页码 * @param limit 每页数量 * @param orderReworkService 返修服务 * @return 分页数据Map */ public static Map buildReworkListData(Users user, int status, int page, int limit, IOrderReworkService orderReworkService) { PageHelper.startPage(page, limit); OrderRework queryCondition = new OrderRework(); queryCondition.setUid(user.getId()); queryCondition.setStatus(status); List reworkList = orderReworkService.selectOrderReworkList(queryCondition); PageInfo pageInfo = new PageInfo<>(reworkList); 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 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 responseData; } /** * 构建购物车分页数据 * @param user 当前用户 * @param page 页码 * @param limit 每页数量 * @param goodsCartService 购物车服务 * @param serviceGoodsService 商品服务 * @return 分页数据Map */ public static Map buildCartListData(Users user, int page, int limit, IGoodsCartService goodsCartService, IServiceGoodsService serviceGoodsService) { PageHelper.startPage(page, limit); GoodsCart queryCart = new GoodsCart(); queryCart.setUid(user.getId()); List cartList = goodsCartService.selectGoodsCartList(queryCart); 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()); if (cart.getSku() != null && !cart.getSku().isEmpty()) { cartData.put("sku", com.alibaba.fastjson2.JSONObject.parseObject(cart.getSku())); } else { cartData.put("sku", null); } 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 = getGoodDetailForCart(cart.getGoodId(), serviceGoodsService); cartData.put("good", goodInfo); resultList.add(cartData); } PageInfo pageInfo = new PageInfo<>(cartList); 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); 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 responseData; } /** * 构建商品订单分页数据 * @param user 当前用户 * @param page 页码 * @param limit 每页数量 * @param status 订单状态 * @param goodsOrderService 商品订单服务 * @param serviceGoodsService 商品服务 * @return 分页数据Map */ public static Map buildGoodsOrderListData(Users user, int page, int limit, String status, IGoodsOrderService goodsOrderService, IServiceGoodsService serviceGoodsService) { PageHelper.startPage(page, limit); GoodsOrder queryOrder = new GoodsOrder(); queryOrder.setUid(user.getId()); if (status != null && !"".equals(status)) { queryOrder.setStatus(Long.valueOf(status)); } List orderList = goodsOrderService.selectGoodsOrderList(queryOrder); 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() != null ? order.getSku() : null); orderData.put("pay_time", order.getPayTime() != null ? sdf.format(order.getPayTime()) : null); orderData.put("created_at", order.getCreatedAt() != null ? sdf.format(order.getCreatedAt()) : 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", 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); } PageInfo pageInfo = new PageInfo<>(orderList); 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 responseData; } /** * 创建服务/商品订单,包含商品、服务、优惠券、微信支付等完整业务逻辑 * @param params 前端参数 * @param user 当前用户 * @param usersService 用户服务 * @param userAddressService 地址服务 * @param serviceGoodsService 商品服务 * @param goodsOrderService 商品订单服务 * @param orderService 服务订单服务 * @param orderLogService 订单日志服务 * @param couponUserService 优惠券服务 * @param wechatPayUtil 微信支付工具 * @return AjaxResult 结果 */ public static AjaxResult createServiceOrGoodsOrder(Map params, Users user, IUsersService usersService, IUserAddressService userAddressService, IServiceGoodsService serviceGoodsService, IGoodsOrderService goodsOrderService, IOrderService orderService, IOrderLogService orderLogService, ICouponUserService couponUserService, WechatPayUtil wechatPayUtil) { // 这里完整迁移原createServiceOrder方法的实现 // ... 由于篇幅限制,建议分段迁移 ... // 这里只做结构示例,具体实现请参考原控制器方法 return AjaxResult.success(); } /** * 构建师傅端订单分页数据 * @param user 当前师傅 * @param page 页码 * @param limit 每页数量 * @param orderService 订单服务 * @param userAddressService 地址服务 * @param serviceGoodsService 商品服务 * @return 带分页和统计的结果Map */ public static Map buildWorkerOrderListData(Users user, int page, int limit, IOrderService orderService, IUserAddressService userAddressService, IServiceGoodsService serviceGoodsService) { // 这里完整迁移原getWorkerOrderList方法的实现 // ... 由于篇幅限制,建议分段迁移 ... // 这里只做结构示例,具体实现请参考原控制器方法 return new HashMap<>(); } /** * 获取订单状态文本 * @param status 订单状态 * @return 状态文本 */ public static String getOrderStatusText1(Long status) { if (status == null) { return "未知状态"; } 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 "未知状态"; } } // ============================== 新增的工具方法 ============================== /** * 为分类列表中的图片添加CDN前缀 * * @param categoryList 分类列表 */ public static void addImageCdnPrefixForCategories(List categoryList) { if (categoryList != null) { for (ServiceCate category : categoryList) { category.setIcon(buildImageUrl(category.getIcon())); } } } /** * 为广告图片列表添加CDN前缀 * * @param advImgList 广告图片列表 */ public static void addImageCdnPrefixForAdvImages(List advImgList) { if (advImgList != null) { for (AdvImg advImg : advImgList) { advImg.setImage(buildImageUrl(advImg.getImage())); } } } /** * 获取系统配置信息 * * @param name 配置名称 * @param siteConfigService 配置服务 * @return 配置对象,如果不存在返回null */ public static SiteConfig getSiteConfig(String name, ISiteConfigService siteConfigService) { if (name == null || name.trim().isEmpty()) { return null; } SiteConfig configQuery = new SiteConfig(); configQuery.setName(name.trim()); List configList = siteConfigService.selectSiteConfigList(configQuery); return configList.isEmpty() ? null : configList.get(0); } /** * 解析配置值为JSON对象 * * @param configValue 配置值字符串 * @return JSON对象,解析失败返回空对象 */ public static JSONObject parseConfigValue(String configValue) { if (configValue == null || configValue.trim().isEmpty()) { return new JSONObject(); } try { return JSONObject.parseObject(configValue); } catch (Exception e) { return new JSONObject(); } } /** * 验证用户地址归属权 * * @param addressId 地址ID * @param userId 用户ID * @param userAddressService 地址服务 * @return 用户地址对象,如果不存在或无权访问返回null */ public static UserAddress validateUserAddress(Long addressId, Long userId, IUserAddressService userAddressService) { if (addressId == null || userId == null) { return null; } UserAddress userAddress = userAddressService.selectUserAddressById(addressId); if (userAddress == null || !userAddress.getUid().equals(userId)) { return null; } return userAddress; } /** * 处理地址修改逻辑 * * @param params 修改参数 * @param user 当前用户 * @param userAddressService 地址服务 * @return 处理结果 */ public static AjaxResult processAddressEdit(Map params, Users user, IUserAddressService userAddressService) { try { // 参数验证 if (params == null || params.get("id") == null) { return appletWarning("地址ID不能为空"); } Long addressId; try { addressId = Long.valueOf(params.get("id").toString()); if (addressId <= 0) { return appletWarning("地址ID无效"); } } catch (NumberFormatException e) { return appletWarning("地址ID格式错误"); } // 查询原地址信息并验证归属权 UserAddress existingAddress = validateUserAddress(addressId, user.getId(), userAddressService); if (existingAddress == null) { return appletWarning("地址不存在或无权修改"); } // 构建更新的地址对象 UserAddress updateAddress = buildUpdateAddress(params, addressId, user.getId()); // 验证必填字段 String validationResult = validateAddressParams(updateAddress); if (validationResult != null) { return appletWarning(validationResult); } // 处理默认地址逻辑 if (updateAddress.getIsDefault() != null && updateAddress.getIsDefault() == 1L) { userAddressService.updateUserAddressDefault(user.getId()); } // 执行地址更新 int updateResult = userAddressService.updateUserAddress(updateAddress); if (updateResult > 0) { return appletSuccess("地址修改成功"); } else { return appletWarning("地址修改失败"); } } catch (Exception e) { return appletError("修改地址失败:" + e.getMessage()); } } /** * 处理地址新增逻辑 * * @param params 新增参数 * @param user 当前用户 * @param userAddressService 地址服务 * @return 处理结果 */ public static AjaxResult processAddressAdd(Map params, Users user, IUserAddressService userAddressService) { try { // 构建新增的地址对象 UserAddress newAddress = buildNewAddress(params, user.getId()); // 验证必填字段 String validationResult = validateAddressParams(newAddress); if (validationResult != null) { return appletWarning(validationResult); } // 处理默认地址逻辑 if (newAddress.getIsDefault() != null && newAddress.getIsDefault() == 1L) { userAddressService.updateUserAddressDefault(user.getId()); } // 执行地址新增 int insertResult = userAddressService.insertUserAddress(newAddress); if (insertResult > 0) { return appletSuccess("地址新增成功"); } else { return appletWarning("地址新增失败"); } } catch (Exception e) { return appletError("新增地址失败:" + e.getMessage()); } } /** * 处理售后返修申请 * * @param params 申请参数 * @param user 当前用户 * @param orderService 订单服务 * @param orderReworkService 返修服务 * @return 处理结果 */ public static AjaxResult processReworkApplication(Map params, Users user, IOrderService orderService, IOrderReworkService orderReworkService) { try { // 参数验证 if (params == null) { return appletWarning("请求参数不能为空"); } String orderId = (String) params.get("order_id"); String phone = (String) params.get("phone"); String mark = (String) params.get("mark"); if (orderId == null || orderId.isEmpty()) { return appletWarning("订单ID不能为空"); } if (phone == null || phone.isEmpty()) { return appletWarning("联系电话不能为空"); } // 验证手机号格式 if (!phone.matches("^1[3-9]\\d{9}$")) { return appletWarning("联系电话格式不正确"); } if (mark == null || mark.isEmpty()) { return appletWarning("返修原因不能为空"); } // 查询订单信息并验证归属权 Order order = orderService.selectOrderByOrderId(orderId); if (order == null) { return appletWarning("订单不存在"); } if (!order.getUid().equals(user.getId())) { return appletWarning("无权操作此订单"); } // 验证订单状态是否允许申请售后 if (!isOrderAllowRework(order.getStatus())) { return appletWarning("当前订单状态不允许申请售后"); } // 处理售后返修申请 boolean reworkResult = processReworkApplication(order, phone, mark, user, orderReworkService, orderService); if (reworkResult) { return appletSuccess("售后返修申请已提交,我们会尽快联系您处理"); } else { return appletWarning("售后申请提交失败,请稍后重试"); } } catch (Exception e) { return appletError("售后申请失败:" + e.getMessage()); } } /** * 小程序查询用户余额日志接口(简化版) * * @param params 请求参数Map,包含分页参数page、limit * @param token 用户token * @param usersService 用户服务 * @param userMemnerConsumptionLogService 用户余额日志服务 * @return 余额日志分页数据 * * 请求参数: * - page: 页码,默认1 * - limit: 每页数量,默认10,最大50 * * 返回数据格式: * { * "code": 200, * "msg": "OK", * "data": { * "current_page": 1, * "data": [ * { * "id": 1, * "amount": "+100.00", * "before_amount": "0.00", * "after_amount": "100.00", * "remark": "服务收入", * "created_time": "2024-01-01 12:00:00" * } * ], * "total": 100, * "per_page": 10, * "last_page": 10, * "has_more": true * } * } */ public static AjaxResult getUserBalanceLogList(Map params, String token, IUsersService usersService, IUserMemnerConsumptionLogService userMemnerConsumptionLogService) { try { // 1. 验证用户token Map tokenValidation = validateUserToken(token, usersService); if (!(Boolean) tokenValidation.get("valid")) { return appletUnauthorized((String) tokenValidation.get("message")); } // 从tokenValidation中获取用户信息Map,然后提取userId Map userInfoMap = (Map) tokenValidation.get("userInfo"); Long userId = (Long) userInfoMap.get("userId"); // 2. 解析分页参数 int page = 1; int limit = 10; if (params != null && params.get("page") != null) { try { page = Integer.parseInt(params.get("page").toString()); if (page < 1) page = 1; } catch (NumberFormatException e) { return appletWarning("页码参数格式错误"); } } if (params != null && params.get("limit") != null) { try { limit = Integer.parseInt(params.get("limit").toString()); if (limit < 1) limit = 10; if (limit > 50) limit = 50; // 限制最大每页数量 } catch (NumberFormatException e) { return appletWarning("每页数量参数格式错误"); } } // 3. 设置分页 PageHelper.startPage(page, limit); // 4. 构建查询条件 UserMemnerConsumptionLog queryCondition = new UserMemnerConsumptionLog(); queryCondition.setUid(userId.intValue()); // 5. 查询余额日志列表 List logList = userMemnerConsumptionLogService.selectUserMemnerConsumptionLogList(queryCondition); // 6. 构建返回数据 List> formattedLogList = buildSimpleBalanceLogResponseList(logList); // 7. 构建分页信息 PageInfo pageInfo = new PageInfo<>(logList); Map responseData = new HashMap<>(); responseData.put("current_page", pageInfo.getPageNum()); responseData.put("data", formattedLogList); responseData.put("total", pageInfo.getTotal()); responseData.put("per_page", pageInfo.getPageSize()); responseData.put("last_page", pageInfo.getPages()); responseData.put("has_more", pageInfo.isHasNextPage()); return appletSuccess(responseData); } catch (Exception e) { System.err.println("查询用户余额日志异常:" + e.getMessage()); return appletError("查询余额日志失败:" + e.getMessage()); } } /** * 构建简化的用户余额日志响应列表 * * @param logList 原始日志列表 * @return 格式化的日志响应列表 */ public static List> buildSimpleBalanceLogResponseList(List logList) { List> formattedList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (UserMemnerConsumptionLog log : logList) { Map logData = new HashMap<>(); // 基础信息 logData.put("id", log.getId()); // 金额信息格式化 BigDecimal amount = log.getConsumptionmoney() != null ? log.getConsumptionmoney() : BigDecimal.ZERO; String amountStr; if (log.getType() != null && log.getType() == 1) { // 收入显示正号 amountStr = "+" + amount.setScale(2, BigDecimal.ROUND_HALF_UP).toString(); } else { // 支出显示负号 amountStr = "-" + amount.setScale(2, BigDecimal.ROUND_HALF_UP).toString(); } logData.put("amount", amountStr); logData.put("paytime", sdf.format(log.getConsumptiontime())); // 余额信息 logData.put("before_amount", log.getBeformoney() != null ? log.getBeformoney().setScale(2, BigDecimal.ROUND_HALF_UP).toString() : "0.00"); logData.put("after_amount", log.getAftermoney() != null ? log.getAftermoney().setScale(2, BigDecimal.ROUND_HALF_UP).toString() : "0.00"); // 备注信息 logData.put("remark", log.getReamk() != null ? log.getReamk() : ""); logData.put("orderid", log.getOrderid() != null ? log.getOrderid() : ""); // // 时间信息 // if (log.getCreatedAt() != null) { // logData.put("created_time", sdf.format(log.getCreatedAt())); // } else if (log.getConsumptiontime() != null) { // logData.put("created_time", sdf.format(log.getConsumptiontime())); // } else { // logData.put("created_time", null); // } formattedList.add(logData); } return formattedList; } // ============================== 用户余额日志接口响应类 ============================== /** * 用户余额日志接口统一响应类 * 适用于 /api/user/benefit/log 接口 */ public static class UserBalanceLogResponse { /** * 响应状态码 * 200: 成功 * 422: 业务提示 * 332: 未登录 * 500: 系统错误 */ private Integer code; /** * 响应消息 */ private String msg; /** * 响应数据 */ private UserBalanceLogPageData data; // 构造方法 public UserBalanceLogResponse() {} public UserBalanceLogResponse(Integer code, String msg, UserBalanceLogPageData data) { this.code = code; this.msg = msg; this.data = data; } // Getter 和 Setter public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public UserBalanceLogPageData getData() { return data; } public void setData(UserBalanceLogPageData data) { this.data = data; } } /** * 用户余额日志分页数据类 */ public static class UserBalanceLogPageData { /** * 当前页码 */ private Integer current_page; /** * 每页数量 */ private Integer per_page; /** * 总记录数 */ private Long total; /** * 总页数 */ private Integer last_page; /** * 是否还有更多数据 */ private Boolean has_more; /** * 余额日志列表 */ private List data; // 构造方法 public UserBalanceLogPageData() {} // Getter 和 Setter public Integer getCurrent_page() { return current_page; } public void setCurrent_page(Integer current_page) { this.current_page = current_page; } public Integer getPer_page() { return per_page; } public void setPer_page(Integer per_page) { this.per_page = per_page; } public Long getTotal() { return total; } public void setTotal(Long total) { this.total = total; } public Integer getLast_page() { return last_page; } public void setLast_page(Integer last_page) { this.last_page = last_page; } public Boolean getHas_more() { return has_more; } public void setHas_more(Boolean has_more) { this.has_more = has_more; } public List getData() { return data; } public void setData(List data) { this.data = data; } } /** * 用户余额日志单条记录类 */ public static class UserBalanceLogItem { /** * 日志记录ID */ private Integer id; /** * 变动金额 * 格式:"+100.00" 表示收入,"-50.00" 表示支出 */ private String amount; /** * 变动前余额 * 格式:保留两位小数,如 "150.00" */ private String before_amount; /** * 变动后余额 * 格式:保留两位小数,如 "250.00" */ private String after_amount; /** * 变动说明/备注 * 如:服务收入、商品购买、提现等 */ private String remark; /** * 记录创建时间 * 格式:yyyy-MM-dd HH:mm:ss */ private String created_time; // 构造方法 public UserBalanceLogItem() {} public UserBalanceLogItem(Integer id, String amount, String before_amount, String after_amount, String remark, String created_time) { this.id = id; this.amount = amount; this.before_amount = before_amount; this.after_amount = after_amount; this.remark = remark; this.created_time = created_time; } // Getter 和 Setter public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } public String getBefore_amount() { return before_amount; } public void setBefore_amount(String before_amount) { this.before_amount = before_amount; } public String getAfter_amount() { return after_amount; } public void setAfter_amount(String after_amount) { this.after_amount = after_amount; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String getCreated_time() { return created_time; } public void setCreated_time(String created_time) { this.created_time = created_time; } } /** * 构建用户余额日志响应对象的工具方法 * * @param code 响应码 * @param msg 响应消息 * @param pageInfo 分页信息 * @param logList 日志列表 * @return 完整的响应对象 */ public static UserBalanceLogResponse buildUserBalanceLogResponse(Integer code, String msg, PageInfo pageInfo, List> logList) { UserBalanceLogResponse response = new UserBalanceLogResponse(); response.setCode(code); response.setMsg(msg); if (pageInfo != null && logList != null) { UserBalanceLogPageData pageData = new UserBalanceLogPageData(); pageData.setCurrent_page(pageInfo.getPageNum()); pageData.setPer_page(pageInfo.getPageSize()); pageData.setTotal(pageInfo.getTotal()); pageData.setLast_page(pageInfo.getPages()); pageData.setHas_more(pageInfo.isHasNextPage()); // 转换日志列表 List items = new ArrayList<>(); for (Map logMap : logList) { UserBalanceLogItem item = new UserBalanceLogItem(); item.setId((Integer) logMap.get("id")); item.setAmount((String) logMap.get("amount")); item.setBefore_amount((String) logMap.get("before_amount")); item.setAfter_amount((String) logMap.get("after_amount")); item.setRemark((String) logMap.get("remark")); item.setCreated_time((String) logMap.get("created_time")); items.add(item); } pageData.setData(items); response.setData(pageData); } return response; } /** * 用户余额日志接口实际返回值备注说明 * * API接口:/api/user/benefit/log * * 完整返回值结构说明: * { * "msg": "OK", // 响应消息,成功时为"OK" * "code": 200, // 响应状态码:200=成功,422=业务提示,332=未登录,500=系统错误 * "data": { // 响应数据 * "per_page": "10", // 每页显示条数,字符串类型 * "total": 1, // 总记录数,整数类型 * "data": [ // 日志记录列表 * { * "createBy": null, // 创建人,通常为null * "createTime": null, // 创建时间,通常为null * "updateBy": null, // 更新人,通常为null * "updateTime": null, // 更新时间,通常为null * "remark": null, // 系统备注,通常为null * "id": 1, // 记录ID,整数类型,唯一标识 * "type": 1, // 变动类型:1=收入,2=支出 * "dotime": "2025-07-04", // 操作日期,格式:yyyy-MM-dd * "ordermoney": 10.00, // 订单金额,BigDecimal类型,保留2位小数 * "money": 1.00, // 变动金额,BigDecimal类型,保留2位小数 * "ordertype": 1, // 订单类型:1=服务订单,2=商品订单,3=其他 * "uid": 2750, // 用户ID,整数类型 * "beformoney": 0.00, // 变动前金额,BigDecimal类型,保留2位小数 * "aftremoney": 10.00, // 变动后金额,BigDecimal类型,保留2位小数 * "createdAt": "2025-07-04", // 创建日期,格式:yyyy-MM-dd * "updatedAt": null, // 更新日期,通常为null * "orderid": 4, // 关联订单ID,整数类型 * "reamk": "5" // 用户备注/说明,字符串类型 * } * ], * "last_page": 1, // 最后一页页码,整数类型 * "next_page_url": null, // 下一页URL,通常为null * "from": 1, // 当前页起始记录位置 * "to": 1, // 当前页结束记录位置 * "prev_page_url": null, // 上一页URL,通常为null * "current_page": 1 // 当前页码,整数类型 * } * } * * 字段类型说明: * - BigDecimal字段:ordermoney, money, beformoney, aftremoney * - Integer字段:id, type, ordertype, uid, orderid, total, last_page, from, to, current_page * - String字段:dotime, createdAt, updatedAt, reamk, per_page * - 可为null的字段:createBy, createTime, updateBy, updateTime, remark, updatedAt, next_page_url, prev_page_url * * 业务逻辑说明: * 1. type=1时表示收入,money为正值;type=2时表示支出,money为负值 * 2. beformoney + money = aftremoney(变动前金额 + 变动金额 = 变动后金额) * 3. orderid关联具体的订单记录 * 4. reamk字段存储用户的备注信息 * 5. ordermoney是关联订单的总金额 * 6. ordertype区分不同类型的订单来源 * * 前端展示建议: * 1. 金额显示:根据type字段决定显示正负号,如"+1.00"或"-1.00" * 2. 时间显示:优先使用createdAt,格式化为"yyyy-MM-dd HH:mm:ss" * 3. 备注显示:使用reamk字段内容 * 4. 分页信息:使用current_page、total、last_page构建分页组件 * * 错误处理: * - code!=200时,显示msg中的错误信息 * - data字段可能为null或空数组 * - 金额字段可能为null,需要默认值处理 */ }