十年前,你爱我,我逃避不见,十年后,我爱你,你不在身边。人生的错过就是如此。一刹便是永远,追悔也是纪念。
码不停蹄,前端代码重构了,优化了部分功能,微信消息定时推送自动化平台再次升级归来,增加了古诗句,农历日期,24节气显示等数据。下面让我们展开描述基础使用吧,包括关键代码呈现等。
点击跳转
访问地址:https://www.rucoding.cn/
平台注册登录访问地址:点击跳转
点击扫码登录
模板=手机查收的效果
如下操作图示:按需确认选择自己的模板,复制对应内容,粘贴到模板内容,提交后会生成模板ID。
表单基础信息填写,标注星号*都是必填项的,但如果模板没展示对应内容,可随意选择填写。
模板ID复制粘贴:
复制第三步4.3生成的模板ID
点击推送测试,查看推送效果
启动定时推送
平台代码是基于SpringBoot+Mybatis+LayUI开发的,同时,定时推送任务整合了XXL-JOB。
类型 | 内容 |
---|---|
开发语言 | Java |
框架 | Spring Boot |
前端 | LayUI |
任务调度 | XXL-JOB |
JDK版本 | JDK1.8 |
数据库 | MySQL 5.7 |
数据库工具 | Navicat15 |
开发软件 | IDEA |
Maven包 | Maven3.6.1 |
浏览器 | 谷歌浏览器 |
Spring Boot是Spring Framework的一个子项目,它是一个快速构建基于Spring的应用程序的框架。Spring Boot旨在简化Spring应用程序的配置和部署过程,让开发人员能够更专注于业务逻辑的实现而不是繁琐的配置。它提供了自动配置和起步依赖项的功能,通过这些功能,可以轻松地集成和使用各种Spring模块和第三方库。Spring Boot还内置了一个内嵌的Web服务器,可以轻松地将我们的应用程序打包为独立的可执行JAR文件,使部署变得非常简单。
MyBatis是一个开源的持久层框架,它是在Java中使用的一种对象关系映射(ORM)框架。它允许我们通过XML或注解的方式将SQL查询语句映射到Java对象,从而实现了数据库操作和Java对象的映射。相比其他ORM框架,MyBatis更加灵活,因为我们可以直接编写SQL查询,这对于复杂的查询和性能优化非常有利。MyBatis支持多种数据库,并且可以与Spring框架无缝集成,因此在Spring Boot项目中使用MyBatis非常方便。
LayUI是一款简单易用的前端UI框架,它基于HTML、CSS和JavaScript构建。它的设计目标是提供一套轻量级的界面组件和交互体验,使得前端开发变得更加快速和简单。LayUI具有丰富的UI组件,如表格、表单、弹出层、导航、按钮等,同时也支持响应式设计,使得我们的Web应用程序在不同设备上都能有很好的显示效果。LayUI的文档和示例都非常清晰,使得前端开发者可以迅速上手并构建出漂亮的用户界面。
XXL-JOB是一款开源的分布式任务调度平台,旨在解决大规模分布式任务调度问题。该平台提供了动态任务调度、任务管理、任务执行日志、分片广播任务、失败重试等功能,以及报警监控和多种任务触发方式。XXL-JOB的易用性和灵活性使其成为许多企业和项目中首选的任务调度框架。
用户-前端控制器
@OperLog(operModule = "用户管理", operType = "克隆", operDesc = "数据克隆")
@PostMapping("dataClone")
@ResponseBody
public Result<String> dataClone(@RequestBody SysUser user, Map<String, Object> map) {
if (user.getId() == null) {
// 设置创建者姓名
user.setCreateUser("");
user.setCreateTime(new Date());
Integer cloneOperTotal = userService.getCloneOperTotal(user.getAppId());
if (cloneOperTotal > 5) {
return ResultUtil.fail("数据条数已达上限哦!");
} else {
// 保存用户
boolean result = userService.save(user);
if (!result) {
return ResultUtil.fail("添加失败!");
}
}
}
return ResultUtil.ok();
}
@OperLog(operModule = "推送信息", operType = "推送", operDesc = "数据推送")
@PostMapping("sendMsg")
@ResponseBody
@RequestLimit(maxCount = 6) //频控30min内限制请求6次
public Result<String> sendMsg(@RequestBody SysUser user, Map<String, Object> map) {
String result = userService.sendMsg(user);
return ResultUtil.ok(result);
}
@OperLog(operModule = "用户管理", operType = "删除", operDesc = "删除用户")
@PostMapping("remove")
@ResponseBody
public Result<String> remove(@RequestParam Integer id) {
// 1.删除用户与角色的关联记录
Map<String, Object> param = new HashMap<>();
param.put("user_id", id);
roleUserService.removeByMap(param);
// 2.删除用户
if (!userService.removeById(id)) {
return ResultUtil.fail("删除失败!");
}
return ResultUtil.ok();
}
@GetMapping("info/{userId}")
public String selectInfo(Map<String, Object> map, @PathVariable(required = true) Integer userId) {
SysUser user = userService.getById(userId);
map.put("user", user);
return "user/info";
}
// 根据用户Id查询其拥有的角色
@GetMapping("/getRoles/{userId}")
@ResponseBody
public List<SysRole> getRoles(@PathVariable Integer userId) {
List<SysRole> roles = userService.selectRolesByUserId(userId);
return roles;
}
// 保存用户角色
@OperLog(operModule = "用户管理", operType = "修改", operDesc = "分配角色")
@PostMapping("saveRole")
@ResponseBody
public Result<String> saveRole(@RequestParam Integer userId, @RequestParam(value = "roleIds[]") Integer[] roleIds) {
userService.saveRole(userId, Arrays.asList(roleIds));
return ResultUtil.ok();
}
频控:规定时间段内接口访问次数限制
/*
* @author :xiaoixan
* @date :2023/04/02 21:42
* @class :RequestLimitAspect
* @description :统计规定时间段内接口访问次数限制
* @version :1.0
**/
@Slf4j
@Aspect
@Component
public class RequestLimitAspect {
@Autowired
private RedisTemplate redisTemplate;
// @Before("within(@org.springframework.web.bind.annotation.RestController *) && @annotation(requestLimit)")
@Before("within(@org.springframework.stereotype.Controller *) && @annotation(requestLimit)")
public void requestLimit(final JoinPoint joinPoint, RequestLimit requestLimit) throws RequestLimitException {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
SysUser user = (SysUser) request.getSession().getAttribute("userSession");
String ip = request.getRemoteAddr();
String uri = request.getRequestURI().toString();
String url = request.getRequestURL().toString();
String key = user.getUsername() + "-request-limit-" + url;
long count = redisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
redisTemplate.expire(key, requestLimit.timeout(), TimeUnit.MILLISECONDS);
}
if (count > requestLimit.maxCount()) {
String error = "用户:" + (user.getUsername()) + ":HTTP请求【" + url + "】超过了限定的访问次数【" + requestLimit.maxCount() + "】";
log.error(error);
throw new RequestLimitException(error);
}
}
}
天气接口-工具类
/**
* 获取天气数据-对接天行数据接口
*
* @author Rucoding
*/
public class TianXingWeatherUtil {
public static Result getWeather() {
Result result = new Result();
String tianapi_data = "";
try {
URL url = new URL( "https://apis.tianapi.com/tianqi/index");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setDoOutput(true);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
OutputStream outputStream = conn.getOutputStream();
String content = "key=" + PushConfigure.getRainbowKey() + "&type=1" + "&city=101020100";
outputStream.write(content.getBytes());
conn.getOutputStream().flush();
conn.getOutputStream().close();
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader (inputStream,"utf-8");
BufferedReader bufferedReader = new BufferedReader (inputStreamReader);
StringBuilder tianapi = new StringBuilder();
String temp = null;
while ( null != (temp = bufferedReader.readLine())){
tianapi.append(temp);
}
tianapi_data = tianapi.toString();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
JSONObject json = JSONObject.parseObject(tianapi_data);
int code = json.getInteger("code");
String msg = json.getString("msg");
JSONObject resultJSONObject = json.getJSONObject("result");
TianXingWeather weather = null;
if (resultJSONObject != null) {
weather = new TianXingWeather();
weather.setWeather(resultJSONObject.getString("weather"));
weather.setHighest(resultJSONObject.getString("highest"));
weather.setLowest(resultJSONObject.getString("lowest"));
weather.setWindsc(resultJSONObject.getString("windsc"));
weather.setWind(resultJSONObject.getString("wind"));
weather.setWindspeed(resultJSONObject.getString("windspeed"));
weather.setSunrise(resultJSONObject.getString("sunrise"));
weather.setSunset(resultJSONObject.getString("sunset"));
weather.setTips(resultJSONObject.getString("tips"));
weather.setDate(resultJSONObject.getString("date"));
weather.setWeek(resultJSONObject.getString("week"));
weather.setReal(resultJSONObject.getString("real"));
weather.setArea(resultJSONObject.getString("area"));
weather.setProvince(resultJSONObject.getString("province"));
} else {
System.out.println("The 'weather' key does not exist in the result JSON object.");
}
result.setCode(String.valueOf(code));
result.setData(weather);
return result;
}
}
/**
* 早安心语接口调用
*
* @author cws
*/
public class TianQiMoriningUtil {
public static Result getMoriningWords() {
String tianapi_data = "";
try {
URL url = new URL("https://apis.tianapi.com/zaoan/index");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setDoOutput(true);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
OutputStream outputStream = conn.getOutputStream();
String content = "key=" + PushConfigure.getRainbowKey();
outputStream.write(content.getBytes());
conn.getOutputStream().flush();
conn.getOutputStream().close();
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder tianapi = new StringBuilder();
String temp;
while ((temp = bufferedReader.readLine()) != null) {
tianapi.append(temp);
}
tianapi_data = tianapi.toString();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return createErrorResult("天行数据接口调用出错:" + e.getMessage());
}
JSONObject jsonObject = JSONObject.parseObject(tianapi_data);
if (jsonObject == null) {
return createErrorResult("天行数据接口返回为空,请检查接口地址!");
}
String code = jsonObject.getString("code");
if (!"200".equals(code)) {
String msg = jsonObject.getString("msg");
return createErrorResult("天行数据接口调用报错: " + msg);
}
String content = jsonObject.getJSONObject("result").getString("content");
if (content == null || content.isEmpty()) {
return createErrorResult("天行数据接口返回数据为空!");
}
String data = content;
return createSuccessResult(code, data);
}
private static Result createErrorResult(String message) {
Result result = new Result();
result.setCode("500");
result.setMessage(message);
return result;
}
private static Result createSuccessResult(String code, String data) {
Result result = new Result();
result.setCode(code);
result.setData(data);
return result;
}
}
当初相遇,犹如《登鹳雀楼》般高高在上,注定是一段美好缘分。如今你们牵手共行,犹如《青玉案·元夕》般情意绵绵,缱绻依偎。
愿你们的爱情如《如梦令》般如梦如幻,甜蜜入心。像《诉衷情·花谢花飞花满天》一般,情话绵绵,美好不绝。
愿你们的相爱,如同《浣溪沙》般清新纯净,细水长流。愿你们的思念,如同《声声慢》般温柔入耳,念念不忘。
无论岁月如何变迁,愿你们的情意如《钗头凤·世情薄》一样厚重,心心相印。如《夜泊牛渚怀古》般,回忆往昔,唯美不减。
愿你们的相守,如《浪淘沙令·席上送张仲固帅》般坚定不移,相伴一生。如《长相思·山一程》般,情深意长,相思无尽。
愿你们的未来,如同《南乡子·登京口北固亭有怀》般美丽迷人,幸福永恒。愿你们的爱情,如《夜雨寄北》般真挚深情,永不凋零。