KongHen02 发布的文章 - 空痕博客
首页
小记
php
python
uni
前端
其他
机器人
QQ机器人
APP
KHMD
KHMD-v3
其他页面
友情链接
用户留言
联系空痕
热门文章
PHP搭建QQ机器人(QQ官方)
下载文件到指定文件夹
欢迎回来 Typecho !
UTS引用原生jar包进行原生插件开发
PHP封装功能较全CURL函数
标签搜索
uniapp
PHP
APP
KongHen
机器人
QQ
UTS
ID3
python
pyinstaller
redis
Echarts
模板
邮箱
js
lyear
发布
登录
找到
11
篇与
相关的结果
2025-06-28
光年模板(V5)侧边栏菜单js修改
主要修改了初始化JSON结构,使菜单层级更清晰。 修改后的代码 // 侧边栏列表 var menu_list = [ { "name": "首页", "url": ["/", "/index/index"], "icon": "mdi mdi-home-variant-outline", "is_out": 0 }, { "name": "链接管理", "url": ["#!"], "icon": "mdi mdi-cookie-outline", "is_out": 0, "children": [ { "name": "链接列表", "url": ["/link/list", "/link/data"], "is_out": 0 }, { "name": "创建链接", "url": ["/link/create", "/link/edit"], "is_out": 0 } ] }, { "name": "财务管理", "url": ["#!"], "icon": "mdi mdi-credit-card-chip-outline", "is_out": 0, "children": [ { "name": "余额充值", "url": ["/finance/recharge"], "is_out": 0 }, { "name": "账单列表", "url": ["/finance/bills"], "is_out": 0 } ] }, { "name": "用户管理", "url": ["/user/list"], "icon": "mdi mdi-account-outline", "is_out": 0, }, { "name": "系统设置", "url": ["#!"], "icon": ["mdi mdi-cog-outline"], "is_out": 0, "children": [ { "name": "个人资料", "url": ["/system/user"], "is_out": 0, }, { "name": "操作日志", "url": ["/system/logs"], "is_out": 0, "children": [ { "name": "账单日志", "url": ["/system/logs/bills"], "is_out": 0, }, { "name": "登录日志", "url": ["/system/logs/login"], "is_out": 0, }, { "name": "链接日志", "url": ["/system/logs/link"], "is_out": 0, } ] } ] }, { "name": "退出登录", "url": ["/user/logout"], "icon": "mdi mdi-location-exit", "is_out": 0 } ]; setSidebar(menu_list); /** * 菜单 * @param data 菜单JSON数据 * name 菜单名称 string * url 菜单链接地址 array 首个为跳转地址。当路由为其中一个时,激活当前菜单选中状态。 * icon 图标 * is_out 是否外链0否|1是 int 外链a标签没有class='multitabs' * children 子菜单 array */ function setSidebar(data) { if (data.length == 0) return false; processMenu(data); console.log(data); html = createMenu(data, true); $('.sidebar-main').append(html); } // 创建html数据 function createMenu(data, is_frist) { var menu_body = is_frist ? '<ul class="nav-drawer">' : '<ul class="nav nav-subnav">'; for (var i = 0; i < data.length; i++) { iframe_class = data[i].is_out == 1 ? 'target="_blank"' : 'class="multitabs"'; icon_div = data[i].is_root == 1 ? '<i class="' + data[i].icon + '"></i>' : ''; menuName = data[i].is_root == 1 ? '<span>' + data[i].name + '</span>' : data[i].name; if (data[i].children && data[i].children.length > 0) { selected = data[i].is_active == 1 ? 'active open' : ''; menu_body += '<li class="nav-item nav-item-has-subnav ' + selected + '"><a href="javascript:void(0)">' + icon_div + menuName + '</a>'; menu_body += createMenu(data[i].children); } else { selected = data[i].is_active == 1 ? 'active' : ''; menu_body += '<li class="nav-item ' + selected + '"><a href="' + data[i].url[0] + '" ' + iframe_class + '>' + icon_div + menuName + '</a>'; } menu_body += '</li>'; } menu_body += '</ul>'; return menu_body; }; // 添加 is_active 和 is_root 属性到所有层级 function addProperties(menu) { menu.forEach(item => { item.is_active = 0; item.is_root = 0; if (item.children && item.children.length > 0) { addProperties(item.children); } }); } // 标记激活状态和父级路径 function markActivePath(menu, currentPath, parentChain = []) { for (let i = 0; i < menu.length; i++) { const item = menu[i]; const newParentChain = [...parentChain, item]; // 检查当前路径是否匹配 const isMatch = item.url.some(url => url === currentPath); if (isMatch) { // 标记当前节点为激活 item.is_active = 1; // 标记整个父链为激活 newParentChain.forEach(node => { node.is_active = 1; node.is_root = 1; }); return true; // 找到匹配路径 } // 递归检查子节点 if (item.children && item.children.length > 0) { const foundInChildren = markActivePath(item.children, currentPath, newParentChain); if (foundInChildren) { // 标记当前节点为激活(因为子节点已激活) item.is_active = 1; item.is_root = 1; return true; } } } return false; // 当前分支未找到匹配 } // 主处理函数 function processMenu(menu) { // 1. 添加初始属性 addProperties(menu); // 2. 标记第一层级为根节点 menu.forEach(item => { item.is_root = 1; }); // 3. 获取当前页面路径 const currentPath = window.location.pathname; // 4. 标记激活路径 markActivePath(menu, currentPath); }光年模板原代码 var menu_list = [ { "id": "1", "name": "后台首页", "url": "lyear_main_1_v5.html", "pid": 0, "icon": "mdi mdi-home", "is_out": 0, "is_home": 1 }, { "id": "2", "name": "布局示例", "url": "#!", "pid": 0, "icon": "mdi mdi-palette", "is_out": 0, "is_home": 0 }, { "id": "3", "name": "表单布局示例", "url": "lyear_layout_form.html", "pid": 2, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "4", "name": "聊天页面示例", "url": "lyear_layout_chat.html", "pid": 2, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "5", "name": "logo处使用文字", "url": "lyear_layout_logo_text.html", "pid": 2, "icon": "", "is_out": 1, "is_home": 0 }, { "id": "6", "name": "多级菜单", "url": "#!", "pid": 0, "icon": "mdi mdi-menu", "is_out": 0, "is_home": 0 }, { "id": "7", "name": "一级菜单", "url": "#!", "pid": 6, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "8", "name": "一级菜单", "url": "#!", "pid": 6, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "9", "name": "二级菜单", "url": "#!", "pid": 8, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "10", "name": "二级菜单", "url": "#!", "pid": 8, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "11", "name": "三级菜单", "url": "#!", "pid": 10, "icon": "", "is_out": 0, "is_home": 0 }, { "id": "12", "name": "三级菜单", "url": "#!", "pid": 10, "icon": "", "is_out": 0, "is_home": 0 } ]; setSidebar(menu_list); /** * 菜单 * @param data 菜单JSON数据 * id 菜单唯一ID * name 菜单名称 * url 菜单链接地址 * icon 图标 * pid 父级ID * is_out 是否外链0否|1是,外链a标签没有class='multitabs' * is_home 是否首页 */ function setSidebar(data){ if (data.length == 0) return false; var treeObj = getTrees(data, 0, 'id', 'pid', 'children'); html = createMenu(treeObj, true); $('.sidebar-main').append(html); } function createMenu(data, is_frist) { var menu_body = is_frist ? '<ul class="nav-drawer">' : '<ul class="nav nav-subnav">'; for(var i = 0; i < data.length; i++){ iframe_class = data[i].is_out == 1 ? 'target="_blank"' : 'class="multitabs"'; icon_div = data[i].pid == 0 ? '<i class="' + data[i].icon + '"></i>' : ''; selected = (data[i].pid == 0) && (data[i].is_home == 1) ? 'active' : ''; menuName = data[i].pid == 0 ? '<span>' + data[i].name + '</span>' : data[i].name; homeIdName = (data[i].pid == 0) && (data[i].is_home == 1) ? 'id="default-page"' : ''; if (data[i].children && data[i].children.length > 0) { menu_body += '<li class="nav-item nav-item-has-subnav"><a href="javascript:void(0)">' + icon_div + menuName + '</a>'; menu_body += createMenu(data[i].children); } else { menu_body += '<li class="nav-item ' + selected + '"><a href="' + data[i].url + '" '+ iframe_class + homeIdName + '>' + icon_div + menuName + '</a>'; } menu_body += '</li>'; } menu_body += '</ul>'; return menu_body; }; /** * 树状的算法 * @params list 代转化数组 * @params parentId 起始节点 * @params idName 主键ID名 * @params parentIdName 父级ID名称 * @params childrenName 子级名称 * @author CSDN博主「伤包子」 */ function getTrees(list, parentId, idName, parentIdName, childrenName) { let items= {}; // 获取每个节点的直属子节点,*记住是直属,不是所有子节点 for (let i = 0; i < list.length; i++) { let key = list[i][parentIdName]; if (items[key]) { items[key].push(list[i]); } else { items[key] = []; items[key].push(list[i]); } } return formatTree(items, parentId, idName, childrenName); } /** * 利用递归格式化每个节点 */ function formatTree(items, parentId, idName, childrenName) { let result = []; if (!items[parentId]) { return result; } for (let t in items[parentId]) { items[parentId][t][childrenName] = formatTree(items, items[parentId][t][idName], idName, childrenName) result.push(items[parentId][t]); } return result; }参考文献 侧边栏菜单的JS初始化 - 光年模板(V5)
前端
# js
# lyear
KongHen02
3天前
0
1
0
2025-06-27
邮箱验证码html模板
适配大屏和小屏 问题:fa图标在邮件中不显示,请自行替换成图片 演示图片 大屏演示图片 代码 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>用户注册 - Xcode验证码</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> /* 基础样式重置 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif; } body { background: linear-gradient(135deg, #f5f7fa 0%, #e4edfb 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 30px; letter-spacing: 0.5px; } /* 亮色毛玻璃效果容器 */ .glass-container { background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-radius: 24px; border: 1px solid rgba(255, 255, 255, 0.8); box-shadow: 0 12px 40px rgba(98, 131, 252, 0.15), 0 4px 20px rgba(98, 131, 252, 0.08); width: 100%; max-width: 780px; overflow: hidden; padding: 50px 40px; position: relative; transition: all 0.4s ease; } .glass-container:hover { box-shadow: 0 15px 50px rgba(98, 131, 252, 0.2), 0 6px 25px rgba(98, 131, 252, 0.12); transform: translateY(-5px); } /* 装饰元素 */ .decoration { position: absolute; border-radius: 50%; background: linear-gradient(135deg, rgba(67, 203, 255, 0.15) 0%, rgba(151, 8, 204, 0.1) 100%); z-index: -1; opacity: 0.7; } .decoration-1 { width: 180px; height: 180px; top: -60px; left: -60px; animation: float 8s infinite ease-in-out; } .decoration-2 { width: 120px; height: 120px; bottom: 30px; right: 30px; animation: float 10s infinite ease-in-out; animation-delay: 1s; } .decoration-3 { width: 90px; height: 90px; top: 30%; right: -30px; animation: float 12s infinite ease-in-out; animation-delay: 2s; } @keyframes float { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(-10px, 15px); } 50% { transform: translate(5px, -10px); } 75% { transform: translate(10px, 5px); } } /* 头部样式 */ .header { text-align: center; margin-bottom: 40px; position: relative; } .logo { display: flex; justify-content: center; align-items: center; margin-bottom: 25px; } .logo-icon { width: 65px; height: 65px; background: linear-gradient(135deg, #43CBFF 0%, #9708CC 100%); border-radius: 18px; display: flex; justify-content: center; align-items: center; margin-right: 18px; box-shadow: 0 8px 20px rgba(151, 8, 204, 0.25); transition: all 0.3s ease; } .logo-icon:hover { transform: rotate(10deg) scale(1.05); } .logo-icon img { margin: 20%; width: 60%; height: 60%; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); } .logo-text { font-size: 32px; font-weight: 700; background: linear-gradient(135deg, #2c3e50 0%, #4a6491 100%); -webkit-background-clip: text; background-clip: text; color: transparent; letter-spacing: 1.2px; } .title { font-size: 28px; font-weight: 700; color: #2c3e50; margin-bottom: 30px; position: relative; display: inline-block; } .title::after { content: ""; position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); width: 60px; height: 4px; background: linear-gradient(135deg, #43CBFF 0%, #9708CC 100%); border-radius: 2px; } .subtitle { font-size: 18px; color: #5a6a85; line-height: 1.7; margin: 0 auto; /* max-width: 600px; */ padding: 0 20px; } /* 验证码区域 - 亮色系突出 */ .verification-section { background: rgba(255, 255, 255, 0.95); border-radius: 20px; padding: 40px 30px; margin: 40px 0; text-align: center; backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.9); box-shadow: 0 10px 30px rgba(98, 131, 252, 0.1), inset 0 0 15px rgba(151, 8, 204, 0.05); position: relative; overflow: hidden; transition: all 0.3s ease; } .verification-section::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 5px; background: linear-gradient(135deg, #43CBFF 0%, #9708CC 100%); } .verification-section:hover { transform: translateY(-5px); box-shadow: 0 15px 40px rgba(98, 131, 252, 0.15), inset 0 0 20px rgba(151, 8, 204, 0.08); } .verification-label { font-size: 18px; color: #5a6a85; margin-bottom: 20px; font-weight: 500; } .verification-code { width: 100%; font-size: 56px; font-weight: 800; letter-spacing: 10px; background: linear-gradient(135deg, #2c3e50 0%, #4a6491 100%); -webkit-background-clip: text; background-clip: text; color: transparent; padding: 20px 40px; border-radius: 16px; margin: 20px 0; display: inline-block; box-shadow: inset 0 0 25px rgba(98, 131, 252, 0.1), 0 8px 20px rgba(98, 131, 252, 0.1); border: 1px solid rgba(98, 131, 252, 0.15); text-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; } .verification-code:hover { letter-spacing: 12px; box-shadow: inset 0 0 30px rgba(98, 131, 252, 0.15), 0 10px 25px rgba(98, 131, 252, 0.15); } .expiration { font-size: 16px; color: #7a8ca5; margin-top: 20px; display: flex; align-items: center; justify-content: center; gap: 10px; } .expiration i { color: #ff6b6b; } /* 操作区域 */ .action-section { text-align: center; margin-top: 50px; } .action-button { background: linear-gradient(135deg, #43CBFF 0%, #9708CC 100%); color: white; border: none; padding: 18px 50px; font-size: 20px; font-weight: 600; border-radius: 60px; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 8px 25px rgba(151, 8, 204, 0.3); text-decoration: none; display: inline-flex; align-items: center; gap: 12px; position: relative; overflow: hidden; } .action-button::before { content: ""; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); transition: 0.5s; } .action-button:hover::before { left: 100%; } .action-button:hover { transform: translateY(-5px) scale(1.05); box-shadow: 0 12px 35px rgba(151, 8, 204, 0.4); } .action-button:active { transform: translateY(0) scale(0.98); } .copyright-link { color: #7a8ca5; text-decoration: none; transition: all 0.3s ease; } .copyright-link:hover { color: #9708CC; text-decoration: underline; } /* 底部信息 */ .footer { text-align: center; margin-top: 50px; color: #7a8ca5; font-size: 15px; line-height: 1.7; } .footer p { margin-bottom: 8px; } .social-icons { display: flex; justify-content: center; gap: 20px; margin-top: 25px; } .social-icons a { width: 45px; height: 45px; border-radius: 50%; background: rgba(98, 131, 252, 0.1); display: flex; align-items: center; justify-content: center; color: #5a6a85; font-size: 18px; transition: all 0.3s ease; } .social-icons a:hover { background: linear-gradient(135deg, #43CBFF 0%, #9708CC 100%); color: white; transform: translateY(-5px); } /* 响应式设计 */ @media (max-width: 768px) { .glass-container { padding: 40px 30px; max-width: 100%; } .logo-icon { width: 55px; height: 55px; } .logo-text { font-size: 28px; } .title { font-size: 24px; } .subtitle { font-size: 16px; } .verification-section { padding: 30px 20px; } .verification-code { font-size: 42px; padding: 15px 30px; letter-spacing: 8px; } .action-button { padding: 16px 40px; font-size: 18px; } } @media (max-width: 480px) { .glass-container { padding: 30px 20px; } .logo { flex-direction: column; gap: 15px; } .logo-icon { margin-right: 0; } .logo-text { font-size: 26px; } .title { font-size: 22px; } .verification-section { padding: 25px 15px; } .verification-code { font-size: 36px; padding: 12px 20px; letter-spacing: 6px; } .action-button { padding: 14px 35px; font-size: 16px; } } </style> </head> <body> <div class="glass-container"> <!-- 装饰元素 --> <div class="decoration decoration-1"></div> <div class="decoration decoration-2"></div> <div class="decoration decoration-3"></div> <div class="header"> <div class="logo"> <div class="logo-icon"> <img src="http://xma.dev.khkj.xyz/static/images/logo.png" alt="Xcode Logo"> </div> <div class="logo-text">Xcode - X码</div> </div> <h1 class="title">用户注册验证码</h1> <p class="subtitle">感谢您注册Xcode平台!请使用以下验证码完成账户验证,验证码将在 <text style="color:red;">6</text> 分钟后失效。</p> </div> <div class="verification-section"> <div class="verification-label">您的验证码</div> <div class="verification-code">843721</div> <div class="expiration"> <i class="fas fa-clock"></i>有效期至: 2025年6月27日 15:30 </div> </div> <div class="action-section"> <a href="https://xma.run" class="action-button"> <i class="fas fa-arrow-right"></i>前往 X码 平台 </a> </div> <div class="footer"> <p>此邮件由系统自动发送,请勿直接回复</p> <p>如果您未进行此操作,请忽略此邮件</p> <p>© 2025 <a href="https://xma.run" class="copyright-link">Xcode - X码</a> 版权所有</p> <div class="social-icons"> <a href="#"><i class="fab fa-weixin"></i></a> <a href="#"><i class="fab fa-qq"></i></a> <a href="#"><i class="fab fa-weibo"></i></a> <a href="#"><i class="fab fa-github"></i></a> </div> </div> </div> <script> // 添加简单的交互效果 document.addEventListener('DOMContentLoaded', function() { const verificationCode = document.querySelector('.verification-code'); // 添加点击复制功能 verificationCode.addEventListener('click', function() { const text = this.innerText; const tempInput = document.createElement('input'); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); alert("复制成功"); }); }); </script> </body> </html>
其他
# 模板
# 邮箱
KongHen02
4天前
0
2
0
2025-06-22
Echarts绘制中国地图并将南海诸岛化为简图
下载中国地图数据 下载地址:DataV.GeoAtlas地理小工具 绘制演示 绘制演示图片 绘制地图 显示南海诸岛简图 地图绘制时设置`china`有南海诸岛简图,设置`China`则没有简图 echarts.registerMap('china', usaJson);隐藏海南诸岛边界线 搜索100000_JD,删除图中的数据片段 隐藏南海诸岛边界线代码位置图片 隐藏南海诸岛 搜索海南,修改海南省的数据,将图中的数据修改为以下数据 南海诸岛数据修改位置图片 "coordinates": [ [ [ [ 110.106396, 20.026812 ], [ 110.042339, 19.991384 ], [ 109.997375, 19.980136 ], [ 109.965346, 19.993634 ], [ 109.898825, 19.994196 ], [ 109.855093, 19.984073 ], [ 109.814441, 19.993072 ], [ 109.76147, 19.981261 ], [ 109.712195, 20.017253 ], [ 109.657993, 20.01163 ], [ 109.585312, 19.98801 ], [ 109.526797, 19.943573 ], [ 109.498464, 19.873236 ], [ 109.411001, 19.895184 ], [ 109.349407, 19.898561 ], [ 109.300748, 19.917693 ], [ 109.25948, 19.898561 ], [ 109.255784, 19.867045 ], [ 109.231147, 19.863105 ], [ 109.159082, 19.79048 ], [ 109.169553, 19.736411 ], [ 109.147379, 19.704863 ], [ 109.093792, 19.68965 ], [ 109.048829, 19.619764 ], [ 108.993394, 19.587065 ], [ 108.92872, 19.524468 ], [ 108.855424, 19.469182 ], [ 108.806148, 19.450561 ], [ 108.765496, 19.400894 ], [ 108.694047, 19.387346 ], [ 108.644772, 19.349518 ], [ 108.609048, 19.276661 ], [ 108.591186, 19.141592 ], [ 108.598577, 19.055633 ], [ 108.630606, 19.003017 ], [ 108.637997, 18.924346 ], [ 108.595497, 18.872256 ], [ 108.593033, 18.809386 ], [ 108.65278, 18.740258 ], [ 108.663866, 18.67337 ], [ 108.641077, 18.565614 ], [ 108.644772, 18.486738 ], [ 108.68912, 18.447571 ], [ 108.776583, 18.441894 ], [ 108.881293, 18.416344 ], [ 108.905315, 18.389087 ], [ 108.944735, 18.314107 ], [ 109.006329, 18.323198 ], [ 109.108575, 18.323766 ], [ 109.138756, 18.268081 ], [ 109.17448, 18.260125 ], [ 109.287813, 18.264671 ], [ 109.355566, 18.215221 ], [ 109.441182, 18.199303 ], [ 109.467051, 18.173718 ], [ 109.527413, 18.169169 ], [ 109.584696, 18.143579 ], [ 109.661688, 18.175424 ], [ 109.726362, 18.177698 ], [ 109.749767, 18.193618 ], [ 109.785492, 18.339672 ], [ 109.919767, 18.375457 ], [ 110.022629, 18.360121 ], [ 110.070672, 18.376025 ], [ 110.090382, 18.399309 ], [ 110.116867, 18.506602 ], [ 110.214186, 18.578662 ], [ 110.246215, 18.609859 ], [ 110.329366, 18.642185 ], [ 110.367555, 18.631977 ], [ 110.499366, 18.651824 ], [ 110.499366, 18.751592 ], [ 110.578206, 18.784458 ], [ 110.590525, 18.838841 ], [ 110.585597, 18.88075 ], [ 110.619474, 19.152334 ], [ 110.676756, 19.286264 ], [ 110.706321, 19.320153 ], [ 110.729727, 19.378878 ], [ 110.787009, 19.399765 ], [ 110.844292, 19.449996 ], [ 110.888023, 19.518827 ], [ 110.920668, 19.552668 ], [ 111.008747, 19.60398 ], [ 111.061718, 19.612436 ], [ 111.071573, 19.628784 ], [ 111.043856, 19.763448 ], [ 111.013675, 19.850159 ], [ 110.966248, 20.018377 ], [ 110.940994, 20.028499 ], [ 110.871393, 20.01163 ], [ 110.808567, 20.035808 ], [ 110.778386, 20.068415 ], [ 110.744509, 20.074036 ], [ 110.717408, 20.148778 ], [ 110.687843, 20.163947 ], [ 110.655814, 20.134169 ], [ 110.562191, 20.110006 ], [ 110.526467, 20.07516 ], [ 110.495054, 20.077408 ], [ 110.387265, 20.113378 ], [ 110.318279, 20.108882 ], [ 110.28933, 20.056047 ], [ 110.243135, 20.077408 ], [ 110.144585, 20.074598 ], [ 110.106396, 20.026812 ] ] ]下载修改后的完整文件 下载完整文件 下载地址:https://www.khkj6.com/usr/uploads/2025/06/3432059456.json 提取码: 参考文档 vue echarts 中国地图处理南海诸岛为简图-CSDN
所有文章
前端
# Echarts
KongHen02
6月22日
0
5
0
2025-02-20
php利用redis实现接口数据缓存
php利用redis实现服务端数据缓存。 要求php版本大于8.0 缓存类 文件RedisCache.php <?php /** * 请求缓存类 * 利用redis实现数据缓存 * * 作者:KongHen02 * */ class RedisCache { private string $key; private Redis $redis; public function __construct(int $db = 0, bool $device = false) { $config = [ 'host' => '127.0.0.1', 'port' => 6379, 'timeout' => 2, 'database' => $db ]; try { $this->redis = new Redis(); $this->redis->connect( $config['host'], $config['port'], $config['timeout'] ); $this->redis->select($config['database']); } catch (RedisException $e) { error_log("Redis连接失败: " . $e->getMessage()); throw new RuntimeException("缓存服务不可用"); } $this->key = $this->generateKey($device); } public function getCache(): mixed { try { header('X-Cache: ' . ($this->redis->exists($this->key) ? 'HIT' : 'MISS')); $data = $this->redis->get($this->key); return $data !== false ? unserialize($data) : null; } catch (RedisException $e) { error_log("读取缓存数据失败: " . $e->getMessage()); return null; } } public function setCache(mixed $data, int $ttl = 7200): bool { try { return $this->redis->setex( $this->key, $ttl, serialize($data) ); } catch (RedisException $e) { error_log("写入缓存数据失败: " . $e->getMessage()); return false; } } public function __destruct() { try { $this->redis?->close(); } catch (RedisException $e) { error_log("关闭Redis连接失败: " . $e->getMessage()); } } private function generateKey(bool $device): string { $url = $_SERVER['HTTP_HOST']; $urlArray = explode("?", $_SERVER['REQUEST_URI']); $url .= $urlArray[0]; $params = $_POST; ksort($params); $keyParts = [ $_SERVER['REQUEST_METHOD'], $device ? $this->detectDevice() : null, $url, substr(md5($urlArray[1]), 0, 8), substr(md5(http_build_query($params)), 0, 8) ]; return implode(':', array_filter($keyParts)); } private function detectDevice(): string { $ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? ''); return match(true) { (bool)preg_match('/mobile|android|iphone|ipod|windows phone/', $ua) => 'mobile', (bool)preg_match('/tablet|ipad|kindle/', $ua) => 'tablet', default => 'desktop' }; } } ?>使用说明 <?php // 导入缓存类 require_once($_SERVER['DOCUMENT_ROOT'] . "/RedisCache.php"); try { // 0:redis表序;0-15;必填 // true:是否区分客户端类型(手机/平板/电脑);true/false(默认);可空 $RedisCache = new RedisCache(0, true); if (($result = $RedisCache->getCache()) !== null) { exit($result); } } catch (RuntimeException $e) { // 缓存服务不可用时继续执行 header('X-Cache-Status: Down'); } // 业务逻辑处理 $result = "数据内容,不限制类型"; // 缓存成功结果 if (isset($result)) { // $result:需要缓存的数据;mixed;必填 // 7200:数据有效期;int(默认7200);可空 $RedisCache?->setCache($result, 7200); } echo($result); ?>
所有文章
PHP
# PHP
# redis
KongHen02
2月20日
6
0
0
2025-02-07
使用pyinstaller打包python程序
准备内容 py程序文件main.py(以单文件为例) 程序图标favicon.ico(如果需要的话),可使用在线生成透明ICO图标生成。 python环境 创建虚拟环境 使用venv库(python3.3以后内置此库)创建虚拟环境 python3 -m venv music参数描述示例music虚拟环境名称,修改为自己的虚拟环境名称即可music# 示例 python3 -m venv music1.jpg图片 激活虚拟环境 # Mac source ./music/bin/activate # Windows .\music\scripts\activate2.jpg图片 安装pyinstaller pip install pyinstaller注意:安装pyinstaller,一定要在虚拟环境中安装,否则打包会丢失库,导致程序无法运行。 3.jpg图片 安装其他必须库 我编写的程序需要用到requests登其他库,所以需要安装,根据自己的程序按需安装即可。 编写程序 示例文件为main.py,并在虚拟环境并安装必须库。 4.jpg图片 测试运行 python3 main.py开始打包 pyinstaller --clean -F -i favicon.ico main.py参数描述示例--clean清理历史构建缓存--clean-F打包为单文件程序-F-i favicon.ico程序图标,如不需要删除即可-i favicon.icomain.pypython程序文件main.py输出以下内容表示打包成功 INFO: Building EXE from EXE-00.toc completed successfully.5.jpg图片 打包结果 打包结果程序位于dist目录下,与程序文件同名。 6.jpg图片 运行测试 7.jpg图片 退出虚拟环境 deactivate总结 pyinstaller需要安装的虚拟环境内,不能安装在全局 使用Mac只能打包为Mac程序,使用Windows只能打包Windows程序 参考 创建虚拟环境的四种方式(venv | pipenv | conda | poetry) Python pyinstaller打包exe最完整教程 pyinstaller 打包 提示 ModuleNotFoundError: No module named ‘xxx‘
小记
python
# python
# pyinstaller
KongHen02
2月7日
0
1
0
1
2
3
下一页
易航博客