javacodeadmin/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletControllerUtil.java

2734 lines
108 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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