Java
2024-08-07 14:45:29 0 举报
AI智能生成
整理自己的Java思路,想写一点有用的东西
作者其他创作
大纲/内容
部署上线
解析域名
登录云服务,找到对应的ip,解析一个子ip
(必填的项一个填自己要名字前缀、一个填服务器的ip)
(必填的项一个填自己要名字前缀、一个填服务器的ip)
部署到服务器
打包前确定
1、数据库地址密码
2、redis
3、支付回调地址
4、图片地址
还有当前使用的application是哪个
当然还有端口
1、数据库地址密码
2、redis
3、支付回调地址
4、图片地址
还有当前使用的application是哪个
当然还有端口
部署之前:备份原来的代码
上传新文件
脚本启动
查看日志
上传新文件
脚本启动
查看日志
同步数据库
结构、数据同步
结构、数据同步
技术点
MongoDB
redis
密码
终端临时配置redis密码的命令:config set requirepass "123456"
rabbitMQ
websocket
定时任务
XXLjob
Spring Task
搜索引擎
nacos
常用习惯
数据库常用
时间(为空也展示,连续一周)
对应的代码
表——>接口?
新增、修改
列表查询(假删除记得加筛选)
管理后台的、小程序的
商家的、用户的、后台管理员的
回显(要是回显的跟列表的一模一样就不用了)
管理后台、小程序
商家、用户的、管理后台的
删除
修改状态
建表
考虑哪些问题?
假删除?
加状态判断?
快捷键
格式化:Ctrl+shift+L
移除没用上的import:Ctrl+alt+O
展开/合上所有方法:ctrl+shift + +/-
展开/合上当前方法:Ctrl+ +/-
常用小语句
分页
Page p = new Page<>(page,limit);
~Mapper.selectPage(p,qw);
~Mapper.selectPage(p,qw);
升序排序
Collections.sort()
获得当前登录的用户id
SysUser sysUser = iSysUserService.getById(StpUtil.getLoginIdAsLong());
JSON相关
String s = JSON.toJSONString(page6Top.getValue());//把对象转换成JSON字符串的
JSONObject s = JSON.parseObject(page6Top.getValue());//把JSON字符串转换成对象的
JSONArray s = JSON.parseArray(page6Top.getValue());//把JSON字符串转换成数组
JSONObject s = JSON.parseObject(page6Top.getValue());//把JSON字符串转换成对象的
JSONArray s = JSON.parseArray(page6Top.getValue());//把JSON字符串转换成数组
常用工具类(判断等)
对象
对象不为空
对象为空
Integer为空
String
String相等
String不相等
以什么什么结尾
.endWith()
去除表中的空字符串:(str[0] + "").replace(" ", "");
map
List
List为空
CollectionUtils.isEmpty(list)
List不空
CollectionUtils.isNotEmpty(list)
正则表达式
我的String.matches(正则表达式String)
// 手机号正则表达式
public boolean isValidPhoneNumber(String phoneNumber) {
String regex = "^(13|14|15|17|18)[0-9]{9}$";
return phoneNumber != null && phoneNumber.matches(regex);
}
public boolean isValidPhoneNumber(String phoneNumber) {
String regex = "^(13|14|15|17|18)[0-9]{9}$";
return phoneNumber != null && phoneNumber.matches(regex);
}
开发
环境
maven等环境配置、搭建
常用注解
端口被占用
win
查看端口
netstat -ano | findstr 8080
杀掉端口
taskkill /f /t /im 9380
逻辑、功能
网管
拦截器
登录
Sa-Token
token(长短token、续token)
验证token
String token = request.getHeader("token");
if (token == null) {
return Result.error( "token不存在");
}
Object loginIdByToken = StpUtil.getLoginIdByToken(token);
if (loginIdByToken == null) {
Result result = new Result(401, "登录失效");
return result;
}
String userId = loginIdByToken.toString();
User user = userMapper.selectById(userId);
if (user == null) {
return Result.error( "用户不存在");
}
if (token == null) {
return Result.error( "token不存在");
}
Object loginIdByToken = StpUtil.getLoginIdByToken(token);
if (loginIdByToken == null) {
Result result = new Result(401, "登录失效");
return result;
}
String userId = loginIdByToken.toString();
User user = userMapper.selectById(userId);
if (user == null) {
return Result.error( "用户不存在");
}
退出登录
常见加密
接口加密
public static <T> Result<T> success(String msg,T data) {
Result<T> result = new Result<>();
result.setCode(StatusCodeEnum.STATUS200.getCode());
result.setMsg(msg);
result.setData(data);
//---------------------------------核心代码-------------------------------
if(ObjectUtil.isNotNull(data))
{
try{
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(data);
AES aes = new AES("CBC", "PKCS7Padding",
// 密钥,可以自定义
key.getBytes(),
// iv加盐,按照实际需求添加
Iv.getBytes());
result.setData((T) aes.encryptHex(jsonString));
}catch (Exception e)
{
e.printStackTrace();
}
}
//---------------------------------核心代码-------------------------------
return result;
}
Result<T> result = new Result<>();
result.setCode(StatusCodeEnum.STATUS200.getCode());
result.setMsg(msg);
result.setData(data);
//---------------------------------核心代码-------------------------------
if(ObjectUtil.isNotNull(data))
{
try{
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(data);
AES aes = new AES("CBC", "PKCS7Padding",
// 密钥,可以自定义
key.getBytes(),
// iv加盐,按照实际需求添加
Iv.getBytes());
result.setData((T) aes.encryptHex(jsonString));
}catch (Exception e)
{
e.printStackTrace();
}
}
//---------------------------------核心代码-------------------------------
return result;
}
多数据库元
application.properties
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.strict=false
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://127.0.0.1:3306/jinchang-recruit?serverTimezone=GMT%2B8
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=EifjMh2G
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://127.0.0.1:3306/jinchang-job-supermarket?serverTimezone=GMT%2B8
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=EifjMh2G
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.strict=false
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://127.0.0.1:3306/jinchang-recruit?serverTimezone=GMT%2B8
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=EifjMh2G
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://127.0.0.1:3306/jinchang-job-supermarket?serverTimezone=GMT%2B8
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=EifjMh2G
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.cj.jdbc.Driver
图片上传
目标:写上传接口,把图片存到数据————>写查看图片的接口,图片能展示
上传本地
/**
* 上传文件
*/
@ApiOperation("上传图片")
@PostMapping("/upload")
public Result<?> upload(HttpServletRequest request,
@RequestParam("file") MultipartFile file) throws IOException {
String token = request.getHeader("token");
if (token == null) {
return Result.error( StatusCodeEnum.STATUS401.getMsg());
}
String mobile = TokenUtils.nothingness(token);
String type = file.getOriginalFilename();
if (!type.endsWith("jpg") &&!type.endsWith("png") &&!type.endsWith("jpeg") &&!type.endsWith("gif") &&!type.endsWith("bmp") ){
return Result.error("文件类型错误,请上传图片!");
}
File filePath;
if (!file.isEmpty()) {
//上传文件路径
String path = "";
path = SystemConstant.DEFAULT_UPLOAD_URL;
//获得上传文件名
String fileName = file.getOriginalFilename();
assert fileName != null;
int lastIndexOf = fileName.lastIndexOf(".");
String date = getRandomString2(8);
//获取文件的后缀名 .jpg
String suffix = fileName.substring(lastIndexOf);
filePath = new File(path + date + suffix);
System.out.println(filePath);
//如果文件目录不存在,创建目录
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
}
//将上传文件保存到一个目标文件中
file.transferTo(filePath);
return Result.success( "/file/" + date + suffix);
} else {
return Result.error( "上传失败");
}
}
* 上传文件
*/
@ApiOperation("上传图片")
@PostMapping("/upload")
public Result<?> upload(HttpServletRequest request,
@RequestParam("file") MultipartFile file) throws IOException {
String token = request.getHeader("token");
if (token == null) {
return Result.error( StatusCodeEnum.STATUS401.getMsg());
}
String mobile = TokenUtils.nothingness(token);
String type = file.getOriginalFilename();
if (!type.endsWith("jpg") &&!type.endsWith("png") &&!type.endsWith("jpeg") &&!type.endsWith("gif") &&!type.endsWith("bmp") ){
return Result.error("文件类型错误,请上传图片!");
}
File filePath;
if (!file.isEmpty()) {
//上传文件路径
String path = "";
path = SystemConstant.DEFAULT_UPLOAD_URL;
//获得上传文件名
String fileName = file.getOriginalFilename();
assert fileName != null;
int lastIndexOf = fileName.lastIndexOf(".");
String date = getRandomString2(8);
//获取文件的后缀名 .jpg
String suffix = fileName.substring(lastIndexOf);
filePath = new File(path + date + suffix);
System.out.println(filePath);
//如果文件目录不存在,创建目录
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
}
//将上传文件保存到一个目标文件中
file.transferTo(filePath);
return Result.success( "/file/" + date + suffix);
} else {
return Result.error( "上传失败");
}
}
文件相关的工具方法
@GetMapping("/test")
public ApiResult test(@RequestParam MultipartFile file) throws IOException {
// 原文件名称
System.out.println("file.getOriginalFilename() = " + file.getOriginalFilename());
// 文件的接收参数 @RequestParam MultipartFile file 中的 file
System.out.println("file.getName() = " + file.getName());
// 文件的类型
System.out.println("file.getContentType() = " + file.getContentType());
System.out.println("file.getResource() = " + file.getResource());
System.out.println("file.getBytes() = " + file.getBytes());
// 文件大小
System.out.println("file.getSize() = " + file.getSize());
return ApiResult.ok();
}
public ApiResult test(@RequestParam MultipartFile file) throws IOException {
// 原文件名称
System.out.println("file.getOriginalFilename() = " + file.getOriginalFilename());
// 文件的接收参数 @RequestParam MultipartFile file 中的 file
System.out.println("file.getName() = " + file.getName());
// 文件的类型
System.out.println("file.getContentType() = " + file.getContentType());
System.out.println("file.getResource() = " + file.getResource());
System.out.println("file.getBytes() = " + file.getBytes());
// 文件大小
System.out.println("file.getSize() = " + file.getSize());
return ApiResult.ok();
}
返回值
file.getOriginalFilename() = lbxx.jpg
file.getName() = file
file.getContentType() = image/jpeg
file.getResource() = MultipartFile resource [file]
file.getBytes() = [B@1fa8cd72
file.getSize() = 22820
file.getName() = file
file.getContentType() = image/jpeg
file.getResource() = MultipartFile resource [file]
file.getBytes() = [B@1fa8cd72
file.getSize() = 22820
png jpg jpeg gif bmp 之间的区别
PNG:无损压缩,支持透明,适合图标和图形。
JPG/JPEG:有损压缩,不支持透明,适合照片。
GIF:无损压缩,支持动画和简单透明,适合简单动画和图标。
BMP:无压缩,不支持透明,适合高质量无压缩图像。
JPG/JPEG:有损压缩,不支持透明,适合照片。
GIF:无损压缩,支持动画和简单透明,适合简单动画和图标。
BMP:无压缩,不支持透明,适合高质量无压缩图像。
public static final String DEFAULT_UPLOAD_URL = System.getProperty("user.dir") + File.separator + "file" + File.separator;
System.getProperty("user.dir"):获取当前用户的工作目录。
例如,如果当前用户的工作目录是 /home/user,那么 System.getProperty("user.dir") 返回 /home/user。
例如,如果当前用户的工作目录是 /home/user,那么 System.getProperty("user.dir") 返回 /home/user。
File.separator:文件分隔符,根据操作系统不同,可能是 /(Unix/Linux)或 \(Windows)。
综合起来,DEFAULT_UPLOAD_URL 的值可能是:
在 Unix/Linux 系统上:/home/user/file/
在 Windows 系统上:C:\Users\user\file\
在 Unix/Linux 系统上:/home/user/file/
在 Windows 系统上:C:\Users\user\file\
assert fileName != null;
assert——>断言
如果断言条件为假,程序将抛出一个 AssertionError 异常,并终止执行。
在这个示例中,如果 fileName 为 null,程序将抛出 AssertionError,并输出消息 "fileName cannot be null"。
在这个示例中,如果 fileName 为 null,程序将抛出 AssertionError,并输出消息 "fileName cannot be null"。
启用断言:
默认情况下,断言是禁用的。要启用断言,需要在运行程序时使用 -ea 或 -enableassertions 选项。例如:
java -ea MyClass
默认情况下,断言是禁用的。要启用断言,需要在运行程序时使用 -ea 或 -enableassertions 选项。例如:
java -ea MyClass
fileName.lastIndexOf(".");
lastIndexOf 是 Java 字符串类(String)中的一个方法,用于查找指定字符或子字符串在字符串中最后一次出现的位置。如果找到,返回该位置的索引;如果没有找到,返回 -1。
getRandomString2(8); 该方法可以根据指定的长度生成一个包含大写字母、小写字母和数字的随机字符串。
public static String getRandomString2(int length) {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(3);
long result = 0;
switch (number) {
case 0:
result = Math.round(Math.random() * 25 + 65);
sb.append(String.valueOf((char) result));
break;
case 1:
result = Math.round(Math.random() * 25 + 97);
sb.append(String.valueOf((char) result));
break;
case 2:
sb.append(String.valueOf(new Random().nextInt(10)));
break;
}
}
return sb.toString();
}
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(3);
long result = 0;
switch (number) {
case 0:
result = Math.round(Math.random() * 25 + 65);
sb.append(String.valueOf((char) result));
break;
case 1:
result = Math.round(Math.random() * 25 + 97);
sb.append(String.valueOf((char) result));
break;
case 2:
sb.append(String.valueOf(new Random().nextInt(10)));
break;
}
}
return sb.toString();
}
fileName.substring(lastIndexOf);
表示从 fileName 字符串中提取从 lastIndexOf 位置开始到字符串末尾的子字符串。
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
}
filePath.getParentFile().mkdirs();
}
filePath.getParentFile().exists()
filePath.getParentFile():
filePath 是一个 File 对象,表示一个文件或目录的路径。
getParentFile() 方法返回 filePath 的父目录的 File 对象。如果 filePath 没有父目录,返回 null。
exists():
exists() 方法是 File 类的一个方法,用于检查文件或目录是否存在。
如果文件或目录存在,返回 true;否则返回 false。
filePath 是一个 File 对象,表示一个文件或目录的路径。
getParentFile() 方法返回 filePath 的父目录的 File 对象。如果 filePath 没有父目录,返回 null。
exists():
exists() 方法是 File 类的一个方法,用于检查文件或目录是否存在。
如果文件或目录存在,返回 true;否则返回 false。
file.transferTo(filePath);
文件.transferTo(文件路径)
当前这个是文件是接口接到的参数的变量名
当前这个是文件是接口接到的参数的变量名
return Result.success( "/file/" + date + suffix);
最终返回去掉前缀的一半的文件名
Excel
Excel模板下载
@ApiOperation(value = "下载导入模板文件")
@GetMapping("/downloadImportTemplateFile")
public void downloadImportTemplateFile(HttpServletResponse response, String fileName)throws Exception {
// 定义文件路径
String filePath = System.getProperty("user.dir") + "/template/燃气表信息收集录入需求表.xlsx";
File file = FileUtils.getFile(filePath);
String newfilename = URLEncoder.encode("燃气表信息收集录入需求表", "UTF-8");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename="
+ newfilename + ".xlsx");
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
// fis = new FileInputStream(file);
fis = FileUtils.openInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null!=bis) bis.close();
if(null!=fis) fis.close();
}
}
@GetMapping("/downloadImportTemplateFile")
public void downloadImportTemplateFile(HttpServletResponse response, String fileName)throws Exception {
// 定义文件路径
String filePath = System.getProperty("user.dir") + "/template/燃气表信息收集录入需求表.xlsx";
File file = FileUtils.getFile(filePath);
String newfilename = URLEncoder.encode("燃气表信息收集录入需求表", "UTF-8");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename="
+ newfilename + ".xlsx");
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
// fis = new FileInputStream(file);
fis = FileUtils.openInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null!=bis) bis.close();
if(null!=fis) fis.close();
}
}
File file = FileUtils.getFile(filePath);
根据提供的文件路径创建一个 File 对象。这个 File 对象可以用来表示文件或目录的路径,但它本身并不创建文件或目录。
filePath 是一个字符串,表示文件的路径。
FileUtils.getFile(filePath) 是 Apache Commons IO 库中的一个方法,用于根据文件路径创建一个 File 对象。
filePath 是一个字符串,表示文件的路径。
FileUtils.getFile(filePath) 是 Apache Commons IO 库中的一个方法,用于根据文件路径创建一个 File 对象。
使用 URLEncoder.encode 方法将文件名编码为 UTF-8 格式,以处理文件名中的特殊字符。
设置 HTTP 响应的内容类型为 application/vnd.ms-excel,表示返回的是 Excel 文件。
设置 HTTP 响应头 Content-disposition,指示浏览器将文件作为附件下载,并设置下载时的文件名为 newfilename + ".xlsx"。
try 块:
使用 FileUtils.openInputStream 方法打开文件输入流(注释掉的行是直接使用 FileInputStream 的替代方式)。
使用 BufferedInputStream 包装 FileInputStream,以提高读取效率。
获取 HTTP 响应的输出流 OutputStream。
从 BufferedInputStream 中读取数据到缓冲区,并将缓冲区中的数据写入到输出流中,直到文件读取完毕。
catch 块:
捕获并打印所有异常的堆栈信息。
finally 块:
确保在读取文件完成后,关闭 BufferedInputStream 和 FileInputStream,释放资源。
使用 FileUtils.openInputStream 方法打开文件输入流(注释掉的行是直接使用 FileInputStream 的替代方式)。
使用 BufferedInputStream 包装 FileInputStream,以提高读取效率。
获取 HTTP 响应的输出流 OutputStream。
从 BufferedInputStream 中读取数据到缓冲区,并将缓冲区中的数据写入到输出流中,直到文件读取完毕。
catch 块:
捕获并打印所有异常的堆栈信息。
finally 块:
确保在读取文件完成后,关闭 BufferedInputStream 和 FileInputStream,释放资源。
BufferedInputStream提升效率原理
使用 BufferedInputStream 包装 FileInputStream 是一种常见的优化技巧,可以显著提高文件读取的效率。
这是因为 BufferedInputStream 在内部使用了一个缓冲区,减少了直接从文件系统读取数据的次数,从而提高了读取性能。
这是因为 BufferedInputStream 在内部使用了一个缓冲区,减少了直接从文件系统读取数据的次数,从而提高了读取性能。
使用 bis.read(buffer) 方法从 BufferedInputStream 中读取数据到缓冲区。
循环读取数据,直到文件末尾(返回 -1)。
循环读取数据,直到文件末尾(返回 -1)。
在 finally 块中关闭 BufferedInputStream 和 FileInputStream,释放资源。
Excel导入
@ApiOperation(value = "导入模板文件")
@PostMapping("/importTemplateFile")
public Result importTemplateFile(HttpServletRequest request,
@RequestParam("file") MultipartFile mfile) throws Exception {
if (!StpUtil.hasPermission("admin:equipment:import")){
return Result.error(TotalConfig.NO_PERMISSION);
}
String token = request.getHeader("token");
if (token == null) {
return Result.error(StatusCodeEnum.STATUS401.getMsg());
}
String type = mfile.getOriginalFilename();
if (!type.endsWith("xlsx")){
return Result.error("文件类型错误,请上传xlsx格式!");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<String[]> list = LiExcelHelperUtils.readExcelToStringArray(mfile,0);
List<String> accountList = new ArrayList<>();
List<String> gasNumberList = new ArrayList<>();
QueryWrapper<PersonnelInformation> queryWrapper = new QueryWrapper<>();
List<PersonnelInformation> personnelInformations = personnelInformationMapper.selectList(queryWrapper);
for (PersonnelInformation personnelInformation : personnelInformations) {
accountList.add(personnelInformation.getAccount());
gasNumberList.add(personnelInformation.getGasNumber());
}
QueryWrapper<GasDetails> queryWrapper1 = new QueryWrapper<>();
List<GasDetails> gas = gasDetailsMapper.selectList(queryWrapper1);
for (GasDetails gasDetails : gas) {
accountList.add(gasDetails.getAccount());
gasNumberList.add(gasDetails.getGasNumber());
}
QueryWrapper<Company> queryWrapper2 = new QueryWrapper<>();
List<Company> companies = companyMapper.selectList(queryWrapper2);
String companyName = "";
Integer companyId = null;
if (companies.size() == 1){
companyName = companies.get(0).getCompanyName();
companyId = companies.get(0).getId();
}
//去重
accountList = new ArrayList<>(new HashSet<>(accountList));
gasNumberList = new ArrayList<>(new HashSet<>(gasNumberList));
int validRows = 0; // 用于跟踪有效数据行的数量
List<PersonnelInformation> addlist = new ArrayList<>();
List<GasDetails> addGasDetailslist = new ArrayList<>();
Set<String> accountSet = new HashSet<>();
Set<String> gasNumberSet = new HashSet<>();
List<String> errorList = new ArrayList<>();
for (int i = 1; i < list.size(); i++) {
String[] str = list.get(i);
if (str.length < 8) {
return Result.error("请下载导入模板编辑后再上传!");
}
String account = (str[0] + "").replace(" ", "");
String user_name = (str[1] + "").replace(" ", "");
String user_phone = (str[2] + "").replace(" ", "");
String address = (str[3] + "").replace(" ", "");
String gas_number = (str[4] + "").replace(" ", "");
String install_time = (str[5] + "").replace(" ", "");
String gas_quantity = (str[6] + "").replace(" ", "");
String notes = (str[7] + "").replace(" ", "");
System.err.println("account:" + account + " user_name:" + user_name + " user_phone:" + user_phone + " address:" + address + " gas_number:" + gas_number + " install_time:" + install_time + " gas_quantity:" + gas_quantity + " notes:" + notes);
if (1==i){
if (!"户号".equals(account) || !"客户姓名".equals(user_name) || !"联系电话①".equals(user_phone) || !"详细地址".equals(address)
|| !"燃气表编号②".equals(gas_number) || !"安装日期".equals(install_time) || !"表具初始读数③".equals(gas_quantity) || !"备注".equals(notes)){
return Result.error("请下载导入模板编辑后再上传!");
}
}else {
if (account.contains("备注")){
break;
}
//所有数据为空,则无数据,跳出当前循环
if (StrUtil.isBlankIfStr(account)
&& StrUtil.isBlankIfStr(user_name)
&& StrUtil.isBlankIfStr(user_phone)
&& StrUtil.isBlankIfStr(address)
&& StrUtil.isBlankIfStr(gas_number)
&& StrUtil.isBlankIfStr(install_time)
&& StrUtil.isBlankIfStr(gas_quantity)
&& StrUtil.isBlankIfStr(notes)) {
break;
}
// 如果当前行不是全部为空,则视为有效数据行
boolean isAllEmpty = StrUtil.isBlankIfStr(account)
&& StrUtil.isBlankIfStr(user_name)
&& StrUtil.isBlankIfStr(user_phone)
&& StrUtil.isBlankIfStr(address)
&& StrUtil.isBlankIfStr(gas_number)
&& StrUtil.isBlankIfStr(install_time)
&& StrUtil.isBlankIfStr(gas_quantity)
&& StrUtil.isBlankIfStr(notes);
if (!isValidPhoneNumber(user_phone)){
errorList.add("户号 " + account + "联系电话格式不正确,请重新填写!");
}
BigDecimal gas_quantity_bigdecimal = null;
try {
gas_quantity_bigdecimal = new BigDecimal(gas_quantity);
}catch (Exception e) {
e.printStackTrace();
errorList.add("户号 " + account + "表具初始读数格式不正确,请重新填写!");
}
if (gas_number.length()!=16){
errorList.add("户号 " + account + "燃气表编号格式不正确,请录入16位!");
}
LocalDateTime localDateTime = null;
try {
Date date = sdf.parse(install_time);
// 使用Instant类作为桥梁
Instant instant = date.toInstant();
// 转换Instant到LocalDateTime需要指定时区
// 这里使用系统默认时区作为示例
localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
} catch (Exception e) {
e.printStackTrace();
errorList.add("户号 " + account + " 日期格式不正确,请重新填写!");
}
if (accountList.contains(account)) {
errorList.add("户号 " + account + " 已存在!");
}
if (gasNumberList.contains(gas_number)) {
errorList.add("燃气表编号 " + account + " 已存在!");
}
// 校验表格中账号是否重复
if (!accountSet.add(account)) {
errorList.add("户号 " + account + " 重复!");
}
// 校验表格中燃气表编号是否重复
if (!gasNumberSet.add(gas_number)) {
errorList.add("燃气表编号 " + gas_number + " 重复!");
}
if (!isAllEmpty) {
validRows++; // 增加有效数据行的计数器
PersonnelInformation personnelInformation = new PersonnelInformation();
personnelInformation.setAccount(account);
personnelInformation.setUserName(user_name);
personnelInformation.setUserPhone(user_phone);
personnelInformation.setAddress(address);
personnelInformation.setGasNumber(gas_number);
personnelInformation.setInstallTime(localDateTime);
personnelInformation.setGasQuantity(gas_quantity_bigdecimal);
personnelInformation.setNotes(notes);
personnelInformation.setCreateTime(LocalDateTime.now());
personnelInformation.setStatus(1);
addlist.add(personnelInformation);
GasDetails gasDetails = new GasDetails();
gasDetails.setAccount(account);
gasDetails.setUserName(user_name);
gasDetails.setGasMeterBalance(gas_quantity_bigdecimal);
gasDetails.setGasMeterTotal(gas_quantity_bigdecimal);
gasDetails.setGasNumber(gas_number);
gasDetails.setUserAddress(address);
gasDetails.setCreateTime(localDateTime);
gasDetails.setCompanyName(companyName);
gasDetails.setCompanyId(companyId);
addGasDetailslist.add(gasDetails);
}else {
return Result.error("表格中所有列均必填,请填写完整后导入!");
}
}
}
//如果有错误数据,则返回错误信息
if (errorList.size() > 0) {
//去重
errorList = new ArrayList<>(new HashSet<>(errorList));
String result = String.join(";", errorList);
return Result.error(result);
}
if (validRows != addlist.size()) {
return Result.error("表格中有错误数据,请填写后重新上传!");
}
//批量插入数据
personnelInformationServiceImpl.batchInsert(addlist);
//批量插入数据
gasDetailsServiceImpl.batchInsert(addGasDetailslist);
return Result.success("导入成功!");
}
@PostMapping("/importTemplateFile")
public Result importTemplateFile(HttpServletRequest request,
@RequestParam("file") MultipartFile mfile) throws Exception {
if (!StpUtil.hasPermission("admin:equipment:import")){
return Result.error(TotalConfig.NO_PERMISSION);
}
String token = request.getHeader("token");
if (token == null) {
return Result.error(StatusCodeEnum.STATUS401.getMsg());
}
String type = mfile.getOriginalFilename();
if (!type.endsWith("xlsx")){
return Result.error("文件类型错误,请上传xlsx格式!");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<String[]> list = LiExcelHelperUtils.readExcelToStringArray(mfile,0);
List<String> accountList = new ArrayList<>();
List<String> gasNumberList = new ArrayList<>();
QueryWrapper<PersonnelInformation> queryWrapper = new QueryWrapper<>();
List<PersonnelInformation> personnelInformations = personnelInformationMapper.selectList(queryWrapper);
for (PersonnelInformation personnelInformation : personnelInformations) {
accountList.add(personnelInformation.getAccount());
gasNumberList.add(personnelInformation.getGasNumber());
}
QueryWrapper<GasDetails> queryWrapper1 = new QueryWrapper<>();
List<GasDetails> gas = gasDetailsMapper.selectList(queryWrapper1);
for (GasDetails gasDetails : gas) {
accountList.add(gasDetails.getAccount());
gasNumberList.add(gasDetails.getGasNumber());
}
QueryWrapper<Company> queryWrapper2 = new QueryWrapper<>();
List<Company> companies = companyMapper.selectList(queryWrapper2);
String companyName = "";
Integer companyId = null;
if (companies.size() == 1){
companyName = companies.get(0).getCompanyName();
companyId = companies.get(0).getId();
}
//去重
accountList = new ArrayList<>(new HashSet<>(accountList));
gasNumberList = new ArrayList<>(new HashSet<>(gasNumberList));
int validRows = 0; // 用于跟踪有效数据行的数量
List<PersonnelInformation> addlist = new ArrayList<>();
List<GasDetails> addGasDetailslist = new ArrayList<>();
Set<String> accountSet = new HashSet<>();
Set<String> gasNumberSet = new HashSet<>();
List<String> errorList = new ArrayList<>();
for (int i = 1; i < list.size(); i++) {
String[] str = list.get(i);
if (str.length < 8) {
return Result.error("请下载导入模板编辑后再上传!");
}
String account = (str[0] + "").replace(" ", "");
String user_name = (str[1] + "").replace(" ", "");
String user_phone = (str[2] + "").replace(" ", "");
String address = (str[3] + "").replace(" ", "");
String gas_number = (str[4] + "").replace(" ", "");
String install_time = (str[5] + "").replace(" ", "");
String gas_quantity = (str[6] + "").replace(" ", "");
String notes = (str[7] + "").replace(" ", "");
System.err.println("account:" + account + " user_name:" + user_name + " user_phone:" + user_phone + " address:" + address + " gas_number:" + gas_number + " install_time:" + install_time + " gas_quantity:" + gas_quantity + " notes:" + notes);
if (1==i){
if (!"户号".equals(account) || !"客户姓名".equals(user_name) || !"联系电话①".equals(user_phone) || !"详细地址".equals(address)
|| !"燃气表编号②".equals(gas_number) || !"安装日期".equals(install_time) || !"表具初始读数③".equals(gas_quantity) || !"备注".equals(notes)){
return Result.error("请下载导入模板编辑后再上传!");
}
}else {
if (account.contains("备注")){
break;
}
//所有数据为空,则无数据,跳出当前循环
if (StrUtil.isBlankIfStr(account)
&& StrUtil.isBlankIfStr(user_name)
&& StrUtil.isBlankIfStr(user_phone)
&& StrUtil.isBlankIfStr(address)
&& StrUtil.isBlankIfStr(gas_number)
&& StrUtil.isBlankIfStr(install_time)
&& StrUtil.isBlankIfStr(gas_quantity)
&& StrUtil.isBlankIfStr(notes)) {
break;
}
// 如果当前行不是全部为空,则视为有效数据行
boolean isAllEmpty = StrUtil.isBlankIfStr(account)
&& StrUtil.isBlankIfStr(user_name)
&& StrUtil.isBlankIfStr(user_phone)
&& StrUtil.isBlankIfStr(address)
&& StrUtil.isBlankIfStr(gas_number)
&& StrUtil.isBlankIfStr(install_time)
&& StrUtil.isBlankIfStr(gas_quantity)
&& StrUtil.isBlankIfStr(notes);
if (!isValidPhoneNumber(user_phone)){
errorList.add("户号 " + account + "联系电话格式不正确,请重新填写!");
}
BigDecimal gas_quantity_bigdecimal = null;
try {
gas_quantity_bigdecimal = new BigDecimal(gas_quantity);
}catch (Exception e) {
e.printStackTrace();
errorList.add("户号 " + account + "表具初始读数格式不正确,请重新填写!");
}
if (gas_number.length()!=16){
errorList.add("户号 " + account + "燃气表编号格式不正确,请录入16位!");
}
LocalDateTime localDateTime = null;
try {
Date date = sdf.parse(install_time);
// 使用Instant类作为桥梁
Instant instant = date.toInstant();
// 转换Instant到LocalDateTime需要指定时区
// 这里使用系统默认时区作为示例
localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
} catch (Exception e) {
e.printStackTrace();
errorList.add("户号 " + account + " 日期格式不正确,请重新填写!");
}
if (accountList.contains(account)) {
errorList.add("户号 " + account + " 已存在!");
}
if (gasNumberList.contains(gas_number)) {
errorList.add("燃气表编号 " + account + " 已存在!");
}
// 校验表格中账号是否重复
if (!accountSet.add(account)) {
errorList.add("户号 " + account + " 重复!");
}
// 校验表格中燃气表编号是否重复
if (!gasNumberSet.add(gas_number)) {
errorList.add("燃气表编号 " + gas_number + " 重复!");
}
if (!isAllEmpty) {
validRows++; // 增加有效数据行的计数器
PersonnelInformation personnelInformation = new PersonnelInformation();
personnelInformation.setAccount(account);
personnelInformation.setUserName(user_name);
personnelInformation.setUserPhone(user_phone);
personnelInformation.setAddress(address);
personnelInformation.setGasNumber(gas_number);
personnelInformation.setInstallTime(localDateTime);
personnelInformation.setGasQuantity(gas_quantity_bigdecimal);
personnelInformation.setNotes(notes);
personnelInformation.setCreateTime(LocalDateTime.now());
personnelInformation.setStatus(1);
addlist.add(personnelInformation);
GasDetails gasDetails = new GasDetails();
gasDetails.setAccount(account);
gasDetails.setUserName(user_name);
gasDetails.setGasMeterBalance(gas_quantity_bigdecimal);
gasDetails.setGasMeterTotal(gas_quantity_bigdecimal);
gasDetails.setGasNumber(gas_number);
gasDetails.setUserAddress(address);
gasDetails.setCreateTime(localDateTime);
gasDetails.setCompanyName(companyName);
gasDetails.setCompanyId(companyId);
addGasDetailslist.add(gasDetails);
}else {
return Result.error("表格中所有列均必填,请填写完整后导入!");
}
}
}
//如果有错误数据,则返回错误信息
if (errorList.size() > 0) {
//去重
errorList = new ArrayList<>(new HashSet<>(errorList));
String result = String.join(";", errorList);
return Result.error(result);
}
if (validRows != addlist.size()) {
return Result.error("表格中有错误数据,请填写后重新上传!");
}
//批量插入数据
personnelInformationServiceImpl.batchInsert(addlist);
//批量插入数据
gasDetailsServiceImpl.batchInsert(addGasDetailslist);
return Result.success("导入成功!");
}
小程序的
通过微信小程序的code获取用户手机号的静态方法:
方式一:
public static Map<String, Object> getPhone(String code) throws Exception {
// 获取token
String token = WxQrCode.redisToken();
// 使用前端code获取手机号码 参数为json格式
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token;
Map<String, String> paramMap = new HashMap<>();
paramMap.put("code", code);
HttpHeaders headers = new HttpHeaders();
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
System.out.println(httpEntity);
ResponseEntity<Object> response = restTemplate.postForEntity(url, httpEntity, Object.class);
return (Map<String, Object>) response.getBody();
}
public static Map<String, Object> getPhone(String code) throws Exception {
// 获取token
String token = WxQrCode.redisToken();
// 使用前端code获取手机号码 参数为json格式
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token;
Map<String, String> paramMap = new HashMap<>();
paramMap.put("code", code);
HttpHeaders headers = new HttpHeaders();
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
System.out.println(httpEntity);
ResponseEntity<Object> response = restTemplate.postForEntity(url, httpEntity, Object.class);
return (Map<String, Object>) response.getBody();
}
方式二:
public static String getMobile(String mobileCode) {
//获取access_token
String token = redisToken();
// 使用前端code获取手机号码 参数为json格式
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token;
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("code", mobileCode);
String response = HttpUtil.post(url, JSONUtil.toJsonStr(paramMap));
log.info("获取用户手机号 响应:{}", response);
cn.hutool.json.JSONObject entries = JSONUtil.parseObj(response);
String phone = entries.getJSONObject("phone_info").getStr("phoneNumber");
return phone;
}
public static String getMobile(String mobileCode) {
//获取access_token
String token = redisToken();
// 使用前端code获取手机号码 参数为json格式
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token;
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("code", mobileCode);
String response = HttpUtil.post(url, JSONUtil.toJsonStr(paramMap));
log.info("获取用户手机号 响应:{}", response);
cn.hutool.json.JSONObject entries = JSONUtil.parseObj(response);
String phone = entries.getJSONObject("phone_info").getStr("phoneNumber");
return phone;
}
常见报错
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysRoleMapper' defined in file
找不见mapper中的方法
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.app.mapper.PublicAnnouncementMapper.noticeList
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.app.mapper.PublicAnnouncementMapper.noticeList
改正.yaml中加:mybatis-plus.mapper-locations=classpath*:**/xml/*Mapper.xml
400 401 token登录失效
不是道服务器之后找不见包文件
Impl中大小写问题
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysRoleMapper' defined in file
有不用的xxxMapper.xml注释了,但没删除,删掉就好了
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
POST请求,前后端参数没对上
解决方式一:@RequestBody注解去掉
解决方式二:前端修改提交的参数类型(表单提交改成application/json这个)
运行 'A.test' 时出错 无法解析 org.junit.vintage:junit-vintage-engine:5.8.2
测试、抓包、内网穿透
swagger
Apifox/postman
postman测试图片上传
postman测试Excel上传
并发性等测试工具
内网穿透
抓包小程序
接口:
请求路径:
请求参数:(参数类型:表单、JSON、路径参数、简单参数)
请求路径:
请求参数:(参数类型:表单、JSON、路径参数、简单参数)
收藏
收藏
0 条评论
下一页