From 146195e3fb44c942af0bab0fe63e63fbe0d72c85 Mon Sep 17 00:00:00 2001 From: PQZ Date: Wed, 5 Nov 2025 10:18:26 +0800 Subject: [PATCH] 1111 --- .../BaseCalendarEventController.java | 12 ++ .../service/IBaseCalendarEventService.java | 2 + .../impl/BaseCalendarEventServiceImpl.java | 68 +++++++++++- .../service/impl/BaseCalendarServiceImpl.java | 12 +- .../src/main/resources/application.yml | 5 + .../web/service/SysLoginService.java | 8 +- dl_vue/src/api/base/event.js | 7 ++ dl_vue/src/permission.js | 30 +++++ dl_vue/src/utils/watermark.js | 74 +++++++++++++ dl_vue/src/views/base/calendar/index.vue | 103 ++++++++++++++---- dl_vue/src/views/base/event/index.vue | 20 +++- 11 files changed, 306 insertions(+), 35 deletions(-) create mode 100644 dl_vue/src/utils/watermark.js diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseCalendarEventController.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseCalendarEventController.java index c718818..fe118fe 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseCalendarEventController.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseCalendarEventController.java @@ -53,6 +53,18 @@ public class BaseCalendarEventController extends BaseController return success(list); } + /** + * 同步中国节假日 + * @author PQZ + * @date 17:18 2025/11/3 + * @return com.ruoyi.common.core.domain.AjaxResult + **/ + @GetMapping("/syncEvent") + public AjaxResult syncEvent() { + baseCalendarEventService.syncEvent(); + return success(); + } + /** * 导出节日列表 */ diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseCalendarEventService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseCalendarEventService.java index 28181ac..a0ad38f 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseCalendarEventService.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseCalendarEventService.java @@ -15,4 +15,6 @@ import com.ruoyi.base.domain.BaseCalendarEvent; public interface IBaseCalendarEventService extends IService { IPage queryListPage(BaseCalendarEvent pageReqVO, Page page); + + void syncEvent(); } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarEventServiceImpl.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarEventServiceImpl.java index 65f107d..69d9fcc 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarEventServiceImpl.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarEventServiceImpl.java @@ -1,29 +1,91 @@ package com.ruoyi.base.service.impl; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.time.Year; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.base.mapper.BaseCalendarEventMapper; import com.ruoyi.base.domain.BaseCalendarEvent; import com.ruoyi.base.service.IBaseCalendarEventService; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; /** * 节日Service业务层处理 - * + * * @author pqz * @date 2025-10-31 */ @Service -public class BaseCalendarEventServiceImpl extends ServiceImpl implements IBaseCalendarEventService -{ +public class BaseCalendarEventServiceImpl extends ServiceImpl implements IBaseCalendarEventService { @Autowired private BaseCalendarEventMapper baseCalendarEventMapper; + private final RestTemplate restTemplate = new RestTemplate(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public IPage queryListPage(BaseCalendarEvent pageReqVO, Page page) { return baseCalendarEventMapper.queryListPage(pageReqVO, page); } + + @Override + public void syncEvent() { + String apiKey = "55bc9d05a05e5e1c0183f7ab380707d8"; + String baseUrl = "https://apis.tianapi.com/jiejiari/index"; + String date = "2025"; + String type = "1"; + + try { + // 构建请求URL + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl) + .queryParam("key", apiKey) + .queryParam("date", date) + .queryParam("type", type); + + // 发送GET请求 + String response = restTemplate.getForObject(builder.toUriString(), String.class); + + // 解析响应JSON + if (response != null) { + Map resultMap = objectMapper.readValue(response, Map.class); + Integer code = (Integer) resultMap.get("code"); + + // 检查请求是否成功 + if (code != null && code == 200) { + Map newsMap = (Map) resultMap.get("result"); + List> dataList = (List>) newsMap.get("list"); + + // 输出数据到控制台 + System.out.println("获取到 " + dataList.size() + " 条节假日数据:"); + for (Map data : dataList) { + System.out.println("日期: " + data.get("date") + + ", 名称: " + data.get("name") + + ", 类型: " + data.get("type")); + } + } else { + System.err.println("获取节假日数据失败,错误码: " + code + + ", 错误信息: " + resultMap.get("msg")); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarServiceImpl.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarServiceImpl.java index f3f6b4e..de143e3 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarServiceImpl.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseCalendarServiceImpl.java @@ -44,7 +44,6 @@ public class BaseCalendarServiceImpl extends ServiceImpl { // 判断当前用户是否已拉取完user_info信息 store.dispatch('GetInfo').then(() => { isRelogin.show = false + // 清理可能存在的旧水印 + watermark.remove() + + // 设置新水印 + const currentUser = store.getters.name || '未知用户' + const currentDate = new Date().toLocaleDateString() + watermark.set({ + text: `${currentUser}\n${currentDate}`, + color: 'rgba(180, 180, 180, 0.3)', + fontSize: 16, + rotate: -15, + density: 0.6, + zIndex: 9999 + }) + store.dispatch('GenerateRoutes').then(accessRoutes => { // 根据roles权限生成可访问的路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表 @@ -43,6 +59,20 @@ router.beforeEach((to, from, next) => { }) }) } else { + // 清理可能存在的旧水印 + watermark.remove() + + // 设置新水印 + const currentUser = store.getters.name || '未知用户' + const currentDate = new Date().toLocaleDateString() + watermark.set({ + text: `${currentUser}\n${currentDate}`, + color: 'rgba(180, 180, 180, 0.3)', + fontSize: 16, + rotate: -15, + density: 0.6, + zIndex: 9999 + }) next() } } diff --git a/dl_vue/src/utils/watermark.js b/dl_vue/src/utils/watermark.js new file mode 100644 index 0000000..0ea4a59 --- /dev/null +++ b/dl_vue/src/utils/watermark.js @@ -0,0 +1,74 @@ +// src/utils/watermark.js +let watermarkDom = null // 水印DOM缓存 + +/** + * 创建水印 + * @param {Object} options 水印配置 + * @param {String} options.text 水印文字(支持\n换行) + * @param {String} options.color 文字颜色(默认rgba(180,180,180,0.3)) + * @param {Number} options.fontSize 字体大小(默认18px) + * @param {Number} options.rotate 旋转角度(默认-15) + * @param {Number} options.density 密度(0-1,默认0.3) + * @param {Number} options.zIndex 层级(默认9999) + */ +function createWatermark(options = {}) { + // 合并默认配置 + const { + text = 'RuoYi 水印', + color = 'rgba(180, 180, 180, 0.5)', + fontSize = 10, + rotate = -15, + density = 0.6, + zIndex = 9999 + } = options + + // 移除已存在的水印 + if (watermarkDom) { + document.body.removeChild(watermarkDom) + } + + // 创建水印容器 + watermarkDom = document.createElement('div') + watermarkDom.style.position = 'fixed' + watermarkDom.style.top = '0' + watermarkDom.style.left = '0' + watermarkDom.style.width = '100%' + watermarkDom.style.height = '100%' + watermarkDom.style.pointerEvents = 'none' // 不影响页面交互 + watermarkDom.style.zIndex = zIndex + document.body.appendChild(watermarkDom) + + // 生成Canvas水印图 + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d') + // 计算单条水印大小(根据文字长度动态调整) + const textArr = text.split('\n') + const maxTextLength = Math.max(...textArr.map(t => t.length)) + canvas.width = maxTextLength * fontSize * 1.2 // 宽度适配文字,增加间距 + canvas.height = textArr.length * fontSize * 3.2 // 高度适配行数,增加间距 + // 绘制文字 + ctx.fillStyle = color + ctx.font = `${fontSize}px SimHei, sans-serif` + ctx.textAlign = 'center' + ctx.textBaseline = 'middle' + ctx.rotate((Math.PI / 180) * rotate) // 旋转 + // 多行文字绘制 + textArr.forEach((line, index) => { + ctx.fillText(line, canvas.width / 2, canvas.height / 2 + (index - (textArr.length - 1) / 2) * fontSize * 1.5) + }) + // 设置为背景图,重复平铺 + watermarkDom.style.backgroundImage = `url(${canvas.toDataURL('image/png')})` + watermarkDom.style.backgroundSize = `${canvas.width / density}px ${canvas.height / density}px` // 调整密度控制逻辑 +} + +export default { + // 设置水印(创建或更新) + set: (options) => createWatermark(options), + // 移除水印 + remove: () => { + if (watermarkDom && document.body.contains(watermarkDom)) { + document.body.removeChild(watermarkDom) + watermarkDom = null + } + } +} diff --git a/dl_vue/src/views/base/calendar/index.vue b/dl_vue/src/views/base/calendar/index.vue index 1081441..d22de9b 100644 --- a/dl_vue/src/views/base/calendar/index.vue +++ b/dl_vue/src/views/base/calendar/index.vue @@ -1,10 +1,23 @@