WechatGroup
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AppWechatEntity {
|
||||
|
||||
public long Expire_time;
|
||||
|
||||
public String Jsapi_ticket;
|
||||
|
||||
public String appId;
|
||||
|
||||
public String nonceStr;
|
||||
|
||||
public String timestamp;
|
||||
|
||||
public String signature;
|
||||
|
||||
public String access_token;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
public class Base64Util {
|
||||
public static String longIdToBase64(long id) {
|
||||
// 将 Long 转换为字节数组
|
||||
byte[] bytes = new byte[8];
|
||||
bytes[0] = (byte) (id >> 56);
|
||||
bytes[1] = (byte) (id >> 48);
|
||||
bytes[2] = (byte) (id >> 40);
|
||||
bytes[3] = (byte) (id >> 32);
|
||||
bytes[4] = (byte) (id >> 24);
|
||||
bytes[5] = (byte) (id >> 16);
|
||||
bytes[6] = (byte) (id >> 8);
|
||||
bytes[7] = (byte) id;
|
||||
|
||||
// 使用 Base64 编码
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.out.println(Base64.getEncoder().encodeToString(String.valueOf(118154768l).getBytes()));
|
||||
}
|
||||
}
|
||||
241
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/DictUtils.java
Normal file
241
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/DictUtils.java
Normal file
@@ -0,0 +1,241 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.ruoyi.cms.domain.BussinessDictData;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DictUtils
|
||||
{
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
/**
|
||||
* 设置字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @param dictDatas 字典数据列表
|
||||
*/
|
||||
public static void setDictCache(String key, List<BussinessDictData> dictDatas)
|
||||
{
|
||||
SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @return dictDatas 字典数据列表
|
||||
*/
|
||||
public static List<BussinessDictData> getDictCache(String key)
|
||||
{
|
||||
JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNotNull(arrayCache))
|
||||
{
|
||||
return arrayCache.toList(BussinessDictData.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @return 字典标签
|
||||
*/
|
||||
public static String getDictLabel(String dictType, String dictValue)
|
||||
{
|
||||
if (StringUtils.isEmpty(dictValue))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return getDictLabel(dictType, dictValue, SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValue(String dictType, String dictLabel)
|
||||
{
|
||||
if (StringUtils.isEmpty(dictLabel))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return getDictValue(dictType, dictLabel, SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @param separator 分隔符
|
||||
* @return 字典标签
|
||||
*/
|
||||
public static String getDictLabel(String dictType, String dictValue, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<BussinessDictData> datas = getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
if (StringUtils.containsAny(separator, dictValue))
|
||||
{
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
for (String value : dictValue.split(separator))
|
||||
{
|
||||
if (value.equals(dict.getDictValue()))
|
||||
{
|
||||
propertyString.append(dict.getDictLabel()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
if (dictValue.equals(dict.getDictValue()))
|
||||
{
|
||||
return dict.getDictLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @param separator 分隔符
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValue(String dictType, String dictLabel, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<BussinessDictData> datas = getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
if (StringUtils.containsAny(separator, dictLabel))
|
||||
{
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
for (String label : dictLabel.split(separator))
|
||||
{
|
||||
if (label.equals(dict.getDictLabel()))
|
||||
{
|
||||
propertyString.append(dict.getDictValue()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
if (dictLabel.equals(dict.getDictLabel()))
|
||||
{
|
||||
return dict.getDictValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型获取字典所有值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValues(String dictType)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<BussinessDictData> datas = getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
propertyString.append(dict.getDictValue()).append(SEPARATOR);
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型获取字典所有标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictLabels(String dictType)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<BussinessDictData> datas = getDictCache(dictType);
|
||||
if (StringUtils.isNull(datas))
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
for (BussinessDictData dict : datas)
|
||||
{
|
||||
propertyString.append(dict.getDictLabel()).append(SEPARATOR);
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定字典缓存
|
||||
*
|
||||
* @param key 字典键
|
||||
*/
|
||||
public static void removeDictCache(String key)
|
||||
{
|
||||
SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
public static void clearDictCache()
|
||||
{
|
||||
Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.BUSSINESS_DICT_KEY + "*");
|
||||
SpringUtils.getBean(RedisCache.class).deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
public static String getCacheKey(String configKey)
|
||||
{
|
||||
return CacheConstants.BUSSINESS_DICT_KEY + configKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; // 改为XSSFWorkbook
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExcelToObject {
|
||||
|
||||
public static <T> List<T> readExcelToObjects(String filePath, Class<T> clazz) throws Exception {
|
||||
List<T> resultList = new ArrayList<>();
|
||||
|
||||
try (FileInputStream fileInputStream = new FileInputStream(filePath);
|
||||
Workbook workbook = new XSSFWorkbook(fileInputStream)) { // 使用XSSFWorkbook处理 .xlsx 文件
|
||||
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
Row headerRow = sheet.getRow(0);
|
||||
|
||||
// 获取表头名称和列索引的映射
|
||||
Map<String, Integer> headerMap = new HashMap<>();
|
||||
for (Cell cell : headerRow) {
|
||||
headerMap.put(cell.getStringCellValue(), cell.getColumnIndex());
|
||||
}
|
||||
|
||||
// 处理每一行数据
|
||||
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
|
||||
Row dataRow = sheet.getRow(i);
|
||||
T obj = clazz.newInstance();
|
||||
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
String fieldName = field.getName();
|
||||
if (headerMap.containsKey(fieldName)) {
|
||||
int columnIndex = headerMap.get(fieldName);
|
||||
Cell cell = dataRow.getCell(columnIndex);
|
||||
|
||||
// 将表格的值赋给Java对象的字段
|
||||
field.setAccessible(true);
|
||||
setFieldValue(field, obj, cell);
|
||||
}
|
||||
}
|
||||
|
||||
resultList.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private static void setFieldValue(Field field, Object obj, Cell cell) throws IllegalAccessException {
|
||||
if (cell == null) return;
|
||||
|
||||
switch (cell.getCellType()) {
|
||||
case STRING:
|
||||
if (field.getType() == String.class) {
|
||||
field.set(obj, cell.getStringCellValue());
|
||||
}
|
||||
break;
|
||||
case NUMERIC:
|
||||
if (field.getType() == int.class || field.getType() == Integer.class) {
|
||||
field.set(obj, (int) cell.getNumericCellValue());
|
||||
} else if (field.getType() == double.class || field.getType() == Double.class) {
|
||||
field.set(obj, cell.getNumericCellValue());
|
||||
} else if (field.getType() == String.class) {
|
||||
// Special handling for phone numbers and other numeric fields as strings
|
||||
BigDecimal bigDecimalValue = new BigDecimal(cell.getNumericCellValue());
|
||||
field.set(obj, bigDecimalValue.toPlainString());
|
||||
}
|
||||
break;
|
||||
case BOOLEAN:
|
||||
if (field.getType() == boolean.class || field.getType() == Boolean.class) {
|
||||
field.set(obj, cell.getBooleanCellValue());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// try {
|
||||
// List<MyClass> objects = readExcelToObjects("path/to/your/excel.xlsx", MyClass.class);
|
||||
// objects.forEach(System.out::println);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
//// 示例Java对象
|
||||
//class MyClass {
|
||||
// private String name;
|
||||
// private int age;
|
||||
// private double salary;
|
||||
//
|
||||
// // getter和setter方法
|
||||
//
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "MyClass{" +
|
||||
// "name='" + name + '\'' +
|
||||
// ", age=" + age +
|
||||
// ", salary=" + salary +
|
||||
// '}';
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Excel 数据对象
|
||||
*/
|
||||
@Data
|
||||
public class IndustryExcel {
|
||||
@ExcelProperty("序号")
|
||||
private Integer index;
|
||||
|
||||
@ExcelProperty("清洗后所属行业门类")
|
||||
private String level1;
|
||||
|
||||
@ExcelProperty("清洗后所属二级行业")
|
||||
private String level2;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.ruoyi.common.core.domain.entity.Industry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工具类:读取 Excel 并构建树结构
|
||||
*/
|
||||
public class IndustryUtils {
|
||||
|
||||
/**
|
||||
* 读取 Excel 文件并转换为 Industry 列表
|
||||
*/
|
||||
public static List<Industry> readExcel(String filePath) {
|
||||
// 读取 Excel 文件
|
||||
List<IndustryExcel> excelDataList = EasyExcel.read(filePath)
|
||||
.head(IndustryExcel.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
// 构建树结构
|
||||
return buildTree(excelDataList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树结构
|
||||
*/
|
||||
private static List<Industry> buildTree(List<IndustryExcel> excelDataList) {
|
||||
Map<String, Industry> level1Map = new HashMap<>(); // 一级分类缓存
|
||||
List<Industry> result = new ArrayList<>(); // 最终结果
|
||||
|
||||
long industryId = 1; // 自增 ID
|
||||
|
||||
for (IndustryExcel excelData : excelDataList) {
|
||||
// 处理一级分类(可能有多个,用逗号分隔)
|
||||
String[] level1Names = excelData.getLevel1().split(",");
|
||||
for (String level1Name : level1Names) {
|
||||
Industry level1 = level1Map.get(level1Name.trim());
|
||||
if (level1 == null) {
|
||||
level1 = new Industry();
|
||||
level1.setIndustryId(industryId++);
|
||||
level1.setIndustryName(level1Name.trim());
|
||||
level1.setParentId(0L); // 根节点
|
||||
level1Map.put(level1Name.trim(), level1);
|
||||
result.add(level1);
|
||||
}
|
||||
|
||||
// 处理二级分类
|
||||
Industry level2 = new Industry();
|
||||
level2.setIndustryId(industryId++);
|
||||
level2.setIndustryName(excelData.getLevel2());
|
||||
level2.setParentId(level1.getIndustryId()); // 父节点为一级分类
|
||||
level1.getChildren().add(level2);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class JobTitleExcel {
|
||||
@ExcelProperty("序号")
|
||||
private Integer index;
|
||||
|
||||
@ExcelProperty("一级分类")
|
||||
private String level1;
|
||||
|
||||
@ExcelProperty("二级分类")
|
||||
private String level2;
|
||||
|
||||
@ExcelProperty("三级分类")
|
||||
private String level3;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.ruoyi.common.core.domain.entity.JobTitle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工具类:读取 Excel 并构建树结构
|
||||
*/
|
||||
public class JobTitleUtils {
|
||||
|
||||
/**
|
||||
* 读取 Excel 文件并转换为 JobTitle 列表
|
||||
*/
|
||||
public static List<JobTitle> readExcel(String filePath) {
|
||||
// 读取 Excel 文件
|
||||
List<JobTitleExcel> excelDataList = EasyExcel.read(filePath)
|
||||
.head(JobTitleExcel.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
|
||||
// 构建树结构
|
||||
return buildTree(excelDataList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树结构
|
||||
*/
|
||||
private static List<JobTitle> buildTree(List<JobTitleExcel> excelDataList) {
|
||||
Map<String, JobTitle> level1Map = new HashMap<>(); // 一级分类缓存
|
||||
Map<String, JobTitle> level2Map = new HashMap<>(); // 二级分类缓存
|
||||
List<JobTitle> result = new ArrayList<>(); // 最终结果
|
||||
|
||||
long jobId = 1; // 自增 ID
|
||||
|
||||
for (JobTitleExcel excelData : excelDataList) {
|
||||
// 处理一级分类
|
||||
JobTitle level1 = level1Map.get(excelData.getLevel1());
|
||||
if (level1 == null) {
|
||||
level1 = new JobTitle();
|
||||
level1.setJobId(jobId++);
|
||||
level1.setJobName(excelData.getLevel1());
|
||||
level1.setParentId(0L); // 根节点
|
||||
level1Map.put(excelData.getLevel1(), level1);
|
||||
result.add(level1);
|
||||
}
|
||||
|
||||
// 处理二级分类
|
||||
JobTitle level2 = level2Map.get(excelData.getLevel2());
|
||||
if (level2 == null) {
|
||||
level2 = new JobTitle();
|
||||
level2.setJobId(jobId++);
|
||||
level2.setJobName(excelData.getLevel2());
|
||||
level2.setParentId(level1.getJobId()); // 父节点为一级分类
|
||||
level2Map.put(excelData.getLevel2(), level2);
|
||||
level1.getChildren().add(level2);
|
||||
}
|
||||
|
||||
// 处理三级分类
|
||||
JobTitle level3 = new JobTitle();
|
||||
level3.setJobId(jobId++);
|
||||
level3.setJobName(excelData.getLevel3());
|
||||
level3.setParentId(level2.getJobId()); // 父节点为二级分类
|
||||
level2.getChildren().add(level3);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ListUtil {
|
||||
public static Boolean isEmptyOrNull(List<String> s){
|
||||
if(Objects.isNull(s)){return true;}
|
||||
return s.isEmpty();
|
||||
}
|
||||
public static Boolean isListEmptyOrNull(List<Long> s){
|
||||
if(Objects.isNull(s)){return true;}
|
||||
return s.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Station {
|
||||
@JsonProperty("n")
|
||||
private String stationName; // 站点名称
|
||||
|
||||
@JsonProperty("sl")
|
||||
private String location; // 经纬度(格式为 "经度,纬度")
|
||||
|
||||
@JsonProperty("rs")
|
||||
private String order; // 排序信息
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StringUtil {
|
||||
public static Boolean isEmptyOrNull(String s){
|
||||
if(Objects.isNull(s)){return true;}
|
||||
return s.isEmpty();
|
||||
}
|
||||
/**
|
||||
* 将逗号分隔的数字字符串转换为List<Integer>
|
||||
*/
|
||||
public static List<Integer> convertStringToIntegerList(String input) {
|
||||
if (isEmptyOrNull(input)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return Arrays.stream(input.split(",")) // 按逗号分割字符串
|
||||
.map(String::trim) // 去除每个部分的前后空格
|
||||
.map(Integer::parseInt) // 将字符串转换为Integer
|
||||
.collect(Collectors.toList()); // 收集为List
|
||||
}
|
||||
/**
|
||||
* 将逗号分隔的数字字符串转换为List<Integer>
|
||||
*/
|
||||
public static List<Long> convertStringToLongList(String input) {
|
||||
List<Integer> longs = convertStringToIntegerList(input);
|
||||
return longs.stream().map(Long::valueOf).collect(Collectors.toList());
|
||||
}
|
||||
/**
|
||||
* 找到List<Integer>中的最大值
|
||||
*/
|
||||
public static Integer findMaxValue(String input) {
|
||||
List<Integer> numbers = convertStringToIntegerList(input);
|
||||
if (numbers == null || numbers.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return numbers.stream()
|
||||
.mapToInt(Integer::intValue) // 将Integer转换为int
|
||||
.max() // 找到最大值
|
||||
.orElseThrow(() -> new RuntimeException("列表为空,无法找到最大值")); // 如果列表为空,抛出异常
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SubwayData {
|
||||
@JsonProperty("l")
|
||||
private List<SubwayLineJson> lines; // 线路列表
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SubwayLineJson {
|
||||
@JsonProperty("ln")
|
||||
private String lineName; // 线路名称
|
||||
|
||||
@JsonProperty("st")
|
||||
private List<Station> stations; // 站点列表
|
||||
}
|
||||
|
||||
|
||||
|
||||
229
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/WechatUtil.java
Normal file
229
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/WechatUtil.java
Normal file
@@ -0,0 +1,229 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import cn.hutool.core.io.file.FileReader;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WechatUtil {
|
||||
/**
|
||||
* 生成signature
|
||||
**/
|
||||
private static String appid = "wx7cab1155e849fe18";
|
||||
private static String secret = "0263f34d422d24588d6c2df8f09500ab";
|
||||
public AppWechatEntity sign(String url) {
|
||||
Map<String, String> ret = new HashMap();
|
||||
String nonceStr = create_nonce_str();
|
||||
String timestamp = Long.toString(create_timestamp());
|
||||
String string1;
|
||||
String signature = "";
|
||||
//获取jsapi_ticket和过期时间
|
||||
AppWechatEntity appWechatEntity = getJsapiTicket();
|
||||
String jsapiTicket = appWechatEntity.getJsapi_ticket();
|
||||
Long expireTime = appWechatEntity.getExpire_time();
|
||||
//注意这里参数名必须全部小写,且必须有序
|
||||
string1 = "jsapi_ticket=" + jsapiTicket +
|
||||
"&noncestr=" + nonceStr +
|
||||
"×tamp=" + timestamp +
|
||||
"&url=" + url;
|
||||
try {
|
||||
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
|
||||
crypt.reset();
|
||||
crypt.update(string1.getBytes(StandardCharsets.UTF_8));
|
||||
signature = byteToHex(crypt.digest());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
appWechatEntity.setAppId(appid);
|
||||
appWechatEntity.setExpire_time(expireTime);
|
||||
appWechatEntity.setNonceStr(nonceStr);
|
||||
appWechatEntity.setTimestamp(timestamp);
|
||||
appWechatEntity.setSignature(signature);
|
||||
return appWechatEntity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取jsapi_ticket
|
||||
**/
|
||||
public AppWechatEntity getJsapiTicket() {
|
||||
//logger.debug("--------------开始执行getJsapiTicket方法--------------");
|
||||
//定义过期时间
|
||||
AppWechatEntity appWechatEntity = new AppWechatEntity();
|
||||
String accessTokenString = "";
|
||||
String jsapiTicketString = "";
|
||||
String jsapi_ticket = "";
|
||||
String access_token = "";
|
||||
jsapiTicketString = readWechatTokenFile(getJsapiTicketFilePath());
|
||||
if (!StringUtils.isEmpty(jsapiTicketString)) {
|
||||
appWechatEntity = JSONObject.parseObject(jsapiTicketString, AppWechatEntity.class);
|
||||
long expireTime = appWechatEntity.getExpire_time();
|
||||
long curTime = create_timestamp();
|
||||
if (expireTime >= curTime && StrUtil.isNotEmpty(appWechatEntity.getJsapi_ticket())) {
|
||||
//logger.debug("已有的jsapi_ticket=" + jsapi_ticket);
|
||||
return appWechatEntity;
|
||||
}
|
||||
}
|
||||
|
||||
long timestamp = create_timestamp() + 7000;//过期时间是2小时(7200s)
|
||||
access_token =
|
||||
getAccessTokenData("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid+ "&secret=" + secret);
|
||||
Map accessTokenMap = new HashMap();
|
||||
accessTokenMap.put("expire_time", timestamp);
|
||||
accessTokenMap.put("access_token", access_token);
|
||||
accessTokenString = JSONObject.toJSONString(accessTokenMap);
|
||||
|
||||
jsapi_ticket = getJsapiTicketData("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi");
|
||||
Map jsapiTicketMap = new HashMap();
|
||||
jsapiTicketMap.put("expire_time", timestamp);
|
||||
jsapiTicketMap.put("jsapi_ticket", jsapi_ticket);
|
||||
jsapiTicketString = JSONObject.toJSONString(jsapiTicketMap);
|
||||
|
||||
// 写文件
|
||||
try {
|
||||
FileUtils.writeStringToFile(new File(getAccessTokenFilePath()), accessTokenString, CharsetUtil.CHARSET_UTF_8);
|
||||
FileUtils.writeStringToFile(new File(getJsapiTicketFilePath()), jsapiTicketString, CharsetUtil.CHARSET_UTF_8);
|
||||
//logger.debug("写入文件成功");
|
||||
} catch (IOException e) {
|
||||
log.debug("写文件异常:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
appWechatEntity.setJsapi_ticket(jsapi_ticket);
|
||||
appWechatEntity.setExpire_time(timestamp);
|
||||
appWechatEntity.setAccess_token(access_token);
|
||||
//logger.debug("--------------结束执行getJsapiTicket方法--------------");
|
||||
return appWechatEntity;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
//logger.debug("--------------开始执行getAccessToken方法--------------");
|
||||
String access_token = "";
|
||||
String accessTokenString = "";
|
||||
AppWechatEntity appWechatEntity = new AppWechatEntity();
|
||||
accessTokenString = readWechatTokenFile(getAccessTokenFilePath());
|
||||
if (StringUtils.isNotEmpty(accessTokenString)) {
|
||||
appWechatEntity = JSONObject.parseObject(accessTokenString, AppWechatEntity.class);
|
||||
access_token = appWechatEntity.getAccess_token();
|
||||
long expireTime = appWechatEntity.getExpire_time();
|
||||
long curTime = create_timestamp();
|
||||
if (expireTime >= curTime) {
|
||||
//logger.debug("已有的access_token=" + access_token);
|
||||
return access_token;
|
||||
}
|
||||
}
|
||||
|
||||
long timestamp = create_timestamp() + 6000;//过期时间是2小时,但是可以提前进行更新,防止前端正好过期
|
||||
access_token =
|
||||
getAccessTokenData("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret);
|
||||
Map accessTokenMap = new HashMap();
|
||||
accessTokenMap.put("expire_time", timestamp);
|
||||
accessTokenMap.put("access_token", access_token);
|
||||
accessTokenString = JSONObject.toJSONString(accessTokenMap);
|
||||
|
||||
// 写文件
|
||||
try {
|
||||
FileUtils.writeStringToFile(new File(getAccessTokenFilePath()), accessTokenString, CharsetUtil.CHARSET_UTF_8);
|
||||
} catch (IOException e) {
|
||||
log.debug("写文件异常:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
//logger.debug("新的access_token=" + access_token);
|
||||
//logger.debug("--------------结束执行getAccessToken方法--------------");
|
||||
return access_token;
|
||||
}
|
||||
|
||||
private String readWechatTokenFile(String filePath) {
|
||||
String content = "";
|
||||
try {
|
||||
if (new File(filePath).exists()) {
|
||||
FileReader fileReader = new FileReader(filePath, CharsetUtil.CHARSET_UTF_8);
|
||||
content = fileReader.readString();
|
||||
} else {
|
||||
new File(filePath).createNewFile();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("读文件异常:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private String getAccessTokenData(String url) {
|
||||
String str = "";
|
||||
String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
|
||||
if (StringUtils.isEmpty(result))
|
||||
return str;
|
||||
str = parseData("access_token", "expires_in", result);
|
||||
return str;
|
||||
}
|
||||
|
||||
private String getJsapiTicketData(String url) {
|
||||
String str = "";
|
||||
String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);
|
||||
if (StringUtils.isEmpty(result))
|
||||
return str;
|
||||
str = parseData("ticket", "expires_in", result);
|
||||
return str;
|
||||
}
|
||||
|
||||
private String parseData(String tokenName, String expiresInName, String data) {
|
||||
String tokenConent = "";
|
||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||
try {
|
||||
tokenConent = jsonObject.get(tokenName).toString();
|
||||
if (StringUtils.isEmpty(tokenConent)) {
|
||||
log.error("token获取失败,获取结果" + data);
|
||||
return tokenConent;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("token 结果解析失败,token参数名称: " + tokenName + "有效期参数名称:" + expiresInName + "token请求结果:" + data);
|
||||
e.printStackTrace();
|
||||
return tokenConent;
|
||||
}
|
||||
return tokenConent;
|
||||
}
|
||||
|
||||
private String byteToHex(final byte[] hash) {
|
||||
Formatter formatter = new Formatter();
|
||||
for (byte b : hash) {
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
String result = formatter.toString();
|
||||
formatter.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
private String create_nonce_str() {
|
||||
return IdUtil.simpleUUID();
|
||||
}
|
||||
|
||||
private Long create_timestamp() {
|
||||
return System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
|
||||
private String getJsapiTicketFilePath() {
|
||||
return "/data/wechat" + "/" +appid + "_jsapiTicket.txt";
|
||||
}
|
||||
|
||||
private String getAccessTokenFilePath() {
|
||||
return "/data/wechat" + "/" + appid + "_accessToken.txt";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user