首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,590 阅读
2
Mac打印机设置黑白打印
4,902 阅读
3
修改elementUI中el-table树形结构图标
4,873 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,654 阅读
5
intelliJ Idea 2022.2.X破解
4,333 阅读
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Vue
Spring Cloud
Mac
MyBatis
WordPress
MacOS
asp.net
Element UI
Nacos
.Net
Spring Cloud Alibaba
MySQL
Mybatis-Plus
Typecho
jQuery
Java Script
微信小程序
Oracle
Laughing
累计撰写
618
篇文章
累计收到
1,419
条评论
首页
栏目
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
友链
广告合作
壁纸
美女主播
搜索到
618
篇与
的结果
2025-03-21
AISeo:一款Typecho主题Joe借助AI生成SEO关键词和SEO描述语的插件
一个网页的keywords及description对于网站的SEO是非常重要的,因此,我们在发布文章时,需要针对文章设置一个合理的keywords及description。但是如果每个文章,我们都手工设置keywords及description,势必会浪费我们极大的精力,在这个全名疯狂的AI时代,不利用AI生成一下keywords及description感觉自己不属于这个时代似的。{mtitle title="实现原理"/}其实整个实现过程是非常简单的,在发布文章页面,增加一个按钮,按钮点击时,通过http的方式调用对应模型的接口,并要求模型返回对应的keywords及description,使用正则表达式对返回的内容进行拆分,获取keywords及description信息,赋值到对应的字段上。{mtitle title="环境介绍"/}本文实现是有条件的,当然你可以在本文的基础上自行修改,进行更多的适配。李森的博客使用的是轻量高效的开源博客程序-Typecho,主题使用的是Joe,因此本文所有介绍的内容都是基于这两个前提的,当然,我们后续的代码会进行说明,方便你在其他地方使用或者使用了Typecho但是不是使用的Joe主题时,也能顺畅的使用。{mtitle title="GPT-API-free介绍"/}本着免费的原则,本文使用的AI工具是GPT-API-free。GPT-API-free是一个提供免费ChatGPT API密钥的开源项目,支持多种模型并允许开发者低成本接入GPT服务。特点支持Models, Embedding, text-davinci(免费版不支持), GPT-3.5-Turbo, GPT-3.5-Turbo-16K(免费版不支持), GPT-4, DALLE(免费版不支持), Whisper(免费版不支持)。(免费版就可以支持AutoGPT, gpt_academic, langchain等)免费版支持gpt-4,一天3次;支持gpt-4o-mini,和gpt-3.5-turbo共享一天200次。与官方完全一致的接口标准,兼容各种软件/插件。支持流式响应。国内线路使用动态加速,体验远优于使用代理连接官方。无需科学上网,国内环境直接可用。个人完全免费使用。免费使用申请领取内测免费API Key,申请地址 https://api.chatanywhere.org/v1/oauth/free/renderHost: https://api.chatanywhere.tech (国内中转,延时更低){mtitle title="博客引入AI"/}{alert type="error"}本插件只适用于Typecho并且需要使用Joe插件,{/alert}下载插件我已经将需要使用的插件封装好,可以直接下载使用{cloud title="AISeo.zip" type="bd" url="https://pan.baidu.com/s/1Nuoce_U8vkI9IG-60MEFlw?pwd=ccdd" password="ccdd"/}下载插件后解压,得到AISeo文件夹,将文件夹整体上传到网站的/usr/plugins文件夹内启用并配置插件进入网站后台,找到并启用AISeo插件点击设置按钮,进入设置页面模型名:gpt-3.5-turboAPI KEY:通过申请领取内测免费API Key介绍的网址免费申请。注意:申请API Key需要Github授权。输入地址:https://api.chatanywhere.tech其他保持默认即可,然后保存插件设置。配置文章编辑页面到admin目录下,找到write-post.php文件。在标题下方插入一个按钮<button type="button" class="generate-seo" onclick="generateSeoKeywords()">生成SEO关键词和描述</button>然后在最后一个div标签后面,添加以下代码<script> function generateSeoKeywords() { // 获取标题和内容 const title = document.querySelector('input[name="title"]').value; const text = document.querySelector('textarea[name="text"]').value; // 获取插件设置 const apiUrl = "<?php echo rtrim(Typecho_Widget::widget('Widget_Options')->plugin('AISeo')->apiUrl, '/') . '/v1/chat/completions'; ?>"; const keyValue = "<?php echo Typecho_Widget::widget('Widget_Options')->plugin('AISeo')->keyValue; ?>"; const modelName = "<?php echo Typecho_Widget::widget('Widget_Options')->plugin('AISeo')->modelName; ?>"; const maxLength = "<?php echo Typecho_Widget::widget('Widget_Options')->plugin('AISeo')->maxLength; ?>"; // 获取UUID const uuid = "<?php echo AISeo_Plugin::getUuid(); ?>"; // 从插件中获取UUID // 发起 AJAX 请求 fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + keyValue, 'X-Request-ID': uuid // 添加UUID到请求头 }, body: JSON.stringify({ model: modelName, messages: [{ role: "system", content: "请你扮演一个文本SEO关键词和SEO描述生成器,下面是一篇关于 '" + title + "' 的文章,请你根据文章标题生成 " + maxLength + " 字左右的SEO关键词和SEO描述,格式使用SEO关键词:SEO描述:,关键词使用英文逗号分隔,除了你生成的内容,请不要输出其他任何无关内容" }, { role: "user", content: text }], temperature: 0 }) }) .then(response => response.json()) .then(data => { if (data.choices && data.choices.length > 0) { const content = data.choices[0].message.content; // 使用特定的分隔符进行分割 const keywordsMatch = content.match(/SEO关键词:(.*?)SEO描述:(.*)/s); if (keywordsMatch && keywordsMatch.length === 3) { const keywords = keywordsMatch[1].replace(/\s+/g, ''); // 关键词 const description = keywordsMatch[2].trim(); // 描述 const keywordField = document.querySelector('input[name="fields[keywords]"]'); const descriptionField = document.querySelector('textarea[name="fields[description]"]'); // 始终覆盖自定义字段 keywordField.value = keywords; descriptionField.value = description; // 使用 cocoMessage 显示成功提示 console.success('SEO关键词和描述生成成功!'); } else { // 使用 cocoMessage 显示失败提示 console.error('生成失败,请重试。'); } } else { // 使用 cocoMessage 显示失败提示 console.error('生成失败,请重试。'); } }) .catch(error => { // 捕获并处理错误 console.error('请求失败:' + error.message); }); } </script>配置按钮样式找到admin/css/style.css,在任意位置,增加以下样式.generate-seo { padding: 8px 10px; /* 缩小内边距,减少按钮高度 */ background-color: #4CAF50; /* 绿色背景 */ color: white; /* 字体颜色为白色 */ border: none; /* 去除边框 */ border-radius: 4px; /* 圆角边框 */ cursor: pointer; /* 鼠标悬停时显示为指针 */ font-size: 14px; /* 字体大小 */ transition: background-color 0.5s ease; /* 背景颜色渐变效果 */ margin-top: 0px; /* 仅调整此按钮的顶部外边距 */ } .generate-seo:hover { background-color: #45a049; /* 悬停时更深的绿色 */ }
2025年03月21日
74 阅读
0 评论
0 点赞
2025-03-21
Typecho主题Joe首页底部增加友情链接
Joe是typecho下一款非常优秀的主题,本站也是使用的Joe的主题,只不过进行了一些改动。{message type="warning" content="本文实现方式只只用于Joe主题,其他主题需要自己修改"/}增加首页友情链接文件在主题public文件夹下增加homefriend.php文件,文件内容如下<!-- * 博客底部-友情链接 * Joe主题在想要显示的地方直接引入即可,其他主题需根据主题自身情况修改。 * $this->need('public/homefriend.php'); * * @Author:李森的博客 * @site:https://lisen.cc --> <style> .ls_friend_home { border-radius: 5px; margin: 0 auto; overflow: hidden } .ls_sites { overflow: hidden; padding-top: 10px } .ls_sites li { width: 31%; float: left; text-align: center; border-radius: 5px; line-height: 35px; margin: 0 3px; margin-bottom: 10px; position: relative } .ls_sites li a { text-decoration: none; color: #fff; display: block; text-overflow: ellipsis; white-space: nowrap; overflow: hidden } .ls_sites li:before, .ls_sites li:after { content: ''; position: absolute; top: 0; right: 0; height: 3px; width: 0; background: #fff; transition: 400ms ease all } .ls_sites li:after { right: inherit; top: inherit; left: 0; bottom: 0 } .ls_sites li:hover:before, .ls_sites li:hover:after { width: 100%; transition: 800ms ease all } @media(min-width:576px) { .ls_friend_home { max-width: 540px } .ls_sites li { width: 30% } } @media(min-width:768px) { .ls_friend_home { max-width: 720px } .ls_sites li { width: 30% } } @media(min-width:992px) { .ls_friend_home { max-width: 960px } .ls_sites li { width: 16.6% } } @media(min-width:1200px) { .ls_friend_home { max-width: 1140px } .ls_sites li { width: 16.6% } } @media(min-width:1400px) { .ls_friend_home { max-width: 1320px } .ls_sites li { width: 16.6% } } </style> <?php /*获取友情链接【这里Joe主题可直接使用,其他主题需要自己重写,原理相同,获取到链接进行循环。】*/ $friends = []; $friends_color = ['#F8D800','#0396FF','#EA5455','#7367F0','#32CCBC','#F6416C','#28C76F','#9F44D3','#F55555','#736EFE','#E96D71','#DE4313','#D939CD','#4C83FF','#F072B6','#C346C2','#5961F9','#FD6585','#465EFB','#FFC600','#FA742B','#5151E5','#BB4E75','#FF52E5','#49C628','#00EAFF','#F067B4','#F067B4','#ff9a9e','#00f2fe','#4facfe','#f093fb','#6fa3ef','#bc99c4','#46c47c','#f9bb3c','#e8583d','#f68e5f']; $friends_text = $this->options->JFriends; if ($friends_text) { $friends_arr = explode("\r\n", $friends_text); if (count($friends_arr) > 0) { for ($i = 0; $i < count($friends_arr); $i++) { $name = explode("||", $friends_arr[$i])[0]; $url = explode("||", $friends_arr[$i])[1]; $avatar = explode("||", $friends_arr[$i])[2]; $desc = explode("||", $friends_arr[$i])[3]; $friends[] = array("name" => trim($name), "url" => trim($url), "avatar" => trim($avatar),"desc" => trim($desc)); }; } } ?> <?php if (sizeof($friends) > 0) : ?> <div class="ls_friend_home"> <ul class="ls_sites"> <?php foreach ($friends as $item) : ?> <li style="background: <?php echo $friends_color[mt_rand(0, count($friends_color) - 1)] ?>"> <a href="<?php echo $item['url']; ?>" target="_blank" rel="noopener noreferrer" title="<?php echo $item['desc']; ?>"> <img width="20" height="20" class="lazyload" style="border-radius: 50%;object-fit: cover;" src="<?php _getAvatarLazyload(); ?>" data-src="<?php echo $item['avatar']; ?>" alt="<?php echo $item['name']; ?>" /> <?php echo $item['name']; ?> </a> </li> <?php endforeach; ?> </ul> </div> <?php endif; ?>在需要展示的地方,引入友情链接文件如果你想全站显示,建议放到public/footer.php的合适位置。因为我只想在首页显示,所以我是在index.php文件引入的,位置的话,放到了最底部<!-- 友情链接 --> <?php $this->need('public/homefriend.php'); ?>
2025年03月21日
81 阅读
0 评论
0 点赞
2025-03-19
爱链网停业整顿暂停一切业务,是不是要凉凉?
爱链网是我之前博客的不多收入之一,爱链网也是国内比较大的链接交易平台,一切手续、流程也是比较正规的。从2025年2月8号整改开始,截止到今天(2025年3月19号)已经快一个半月了,目前没有任何恢复的迹象。记得3月初的时候,已经整站关闭了,后来网站恢复访问了,但是目前提现已经提不出来了。{timeline}{timeline-item color="#19be6b"}2025.3.24 爱链网官网再次无法访问。{/timeline-item}{timeline-item color="#19be6b"}2025.2.23 平台停业整顿,暂停一切中介业务。买卖双方提现会另行通知。{/timeline-item}{timeline-item color="#ed4014"}2025.2.8 爱链网暂停充值业务,买家需要提现的,请在网站后台留言{/timeline-item}{/timeline}如果想购买本站的友情链接、发布软文或者发布广告,可以通过51链购买,购买地址: https://www.51link.com/link-sell?uid=30403
2025年03月19日
51 阅读
0 评论
0 点赞
2025-03-19
云闪付登录逻辑:用户发短信?这是什么神仙操作?
云闪付是一种非现金收付款移动交易结算工具,是在中国人民银行的指导下,由中国银联携手各商业银行、支付机构等产业各方共同开发建设、共同维护运营的移动支付APP,于2017年12月11日正式发布。最近想购买扩展坞,用云闪付可以直接国补抵扣,在使用云闪付时发现它的手机号码登录逻辑简直让人哭笑不得。作为一个支付工具,安全性和便捷性本该是核心,但云闪付的登录流程却让我怀疑人生——竟然需要用户主动发短信才能登录!而且它还是给你发送一个短信,告诉你需要给它发送一个短信进行验证。。。这是什么神仙操作?今天就来吐槽一下这个让人摸不着头脑的设计。登录流程:用户发短信?认真的吗?正常的移动App通常的登录流程是:输入手机号 → 接收验证码 → 输入验证码 → 登录成功。简单直接,一气呵成。但云闪付的流程却是:输入手机号 → 系统给你发一条短信提示你发一条短信到指定号码 → 发完短信 → 等待系统验证 → 登录成功。What? 我不仅要输入手机号,还要自己发短信?这操作简直让人一脸懵。难道云闪付觉得用户的时间不值钱还是觉得用户发短信不需要钱,还是觉得发短信是一件很有趣的事情?用户体验:繁琐又反人类步骤繁琐: 本来一键接收验证码就能搞定的事情,非要让用户手动发短信。操作复杂: 尤其是对不太熟悉手机操作的中老年用户,发短信可能比接收验证码难多了。浪费时间: 发短信、等待验证,整个过程比普通登录多花了好几倍时间。浪费金钱: 用户想要注册或者登录你的产品,你还得要用户掏钱去认证?云闪付的产品经理是不是觉得用户都太闲了? 这种设计简直是把用户体验按在地上摩擦。安全性:真的更安全吗?可能有人会说,这种设计是为了安全。但仔细想想,发短信真的比接收验证码更安全吗?短信拦截风险:如果用户的手机被恶意软件控制,短信内容同样可能被截获。用户体验牺牲:为了所谓的安全,牺牲了用户体验,真的值得吗?对比其他App:差距明显看看支付宝、微信支付,甚至其他普通的App,哪个不是一键验证码登录?简单、快捷、安全,这才是用户需要的。而云闪付却偏偏要走一条“与众不同”的路,结果就是让用户感到困惑和不便。希望云闪付的产品团队能好好反思一下,用户需要的是便捷和安全,而不是折腾和困惑。如果下次登录还要我发短信,我可能真的要考虑卸载了。最后,灵魂一问:云闪付,你是认真的吗?还是说,这只是为了让我多花点短信费?(手动狗头)
2025年03月19日
62 阅读
0 评论
0 点赞
2025-03-19
Windows11查看系统密玥
通过命令查看这种方式只能查看OEM密玥,如果不是OEM激活的,这个密玥也没啥用。打开终端,输入以下命令 wmic path SoftwareLicensingService get OA3xOriginalProductKey通过注册表查看那么只要右键开始菜单,选择运行,其中输入regedit回车打开注册表。接依次定位到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform,如下图可以双击BackupProductKeyDefault,在弹出的界面可以复制密玥。
2025年03月19日
37 阅读
0 评论
0 点赞
2025-03-18
Java优雅判空技巧:瞧瞧别人家的判空,太香啦!
在 Java 开发中,空指针异常(NullPointerException,简称NPE) 是程序员最常遇到的错误之一。无论是新手还是资深开发者,几乎每个人都曾因为一个突如其来的 NullPointerException 而抓狂过。想象一下这样的场景:项目即将上线,整个团队正忙于最后的部署工作,突然系统抛出了一个堆栈错误。大家花费大量时间排查,最终发现竟然是因为某个变量未初始化。再一看代码,满屏的 if (xxx == null),层层嵌套,复杂到让人头晕目眩。这种低效且低级的判空方式,不仅降低了代码的可读性,还增加了维护成本。然而,判空的方式远不止传统的 if (xxx == null)!今天,我要向大家推荐‘别人家的代码’——那些优雅、高效的判空技巧,简直是代码的艺术品。接下来,我们将一起探讨Java 中如何优雅、高效地进行判空操作*,帮助你彻底告别繁琐的判空代码,提升代码的可读性和可维护性。一、传统判空的血泪史在我们之前的开发过程中,最常见的判空方式,可能就是这样了:if (user != null) { if (user.getAddress() != null) { if (user.getAddress().getStreet() != null) { // 做一些事情 } } }一层又一层的嵌套判空,简直是代码的噩梦!尤其是当这种判空逻辑遍布代码的多个地方时,整个程序的可读性急剧下降,维护成本也随之飙升。更糟糕的是,在调用外部数据接口时,稍有不慎就会引发大量的空指针异常(NPE)。而在高并发场景下,这种问题会被进一步放大,程序崩溃的概率成倍增加,给系统稳定性带来巨大威胁。那么,如何优化这种灾难级别的代码呢?接下来,我们将探讨如何通过现代化的判空技巧,彻底告别多层嵌套判空,提升代码的可读性与健壮性,同时有效避免高并发场景下的空指针异常。二、Java 8+ 时代的判空革命随着Java 8的到来,我们迎来了判空操作的一次革命性升级——Optional!这个神器彻底改变了传统的判空方式,让代码变得更加优雅、简洁。通过链式调用,Optional 不仅避免了繁琐的 if (xxx == null) 判断,还大大提升了代码的可读性和可维护性。无论是新手还是资深开发者,都对它爱不释手。接下来,我们将深入探讨 Optional 的使用技巧,包括基础用法、链式调用以及高级功能,帮助你彻底告别繁琐的判空代码,提升开发效率。1. Optional 黄金三板斧链式调用判空:使用 Optional.ofNullable()Optional 是一个容器对象,它能帮助我们避免空指针异常。通过 Optional.ofNullable(),我们可以优雅地处理可能为 null 的对象,而无需一层层地嵌套判断。让我们看个例子:Optional.ofNullable(user) .map(User::getAddress) .map(Address::getStreet) .ifPresent(street -> { // 在这里使用 street,避免了 NullPointerException });看!这段代码比那段嵌套的 if 优雅多了吧?简洁明了,能够有效避免 NullPointerException,而且还能链式调用,代码的可读性大大提升。高级用法:条件过滤与业务异常抛出Optional 还能用于更复杂的情况,比如在判空时抛出业务异常。比如我们有一个方法,接收一个可能为空的用户对象,并希望如果用户没有地址,就抛出一个自定义的异常:User user = getUser(); String street = Optional.ofNullable(user) .map(User::getAddress) .map(Address::getStreet) .orElseThrow(() -> new IllegalStateException("用户地址不能为空"));当 user 或者 address 为 null 时,代码会自动抛出 IllegalStateException,避免了不必要的 null 检查。2. 封装通用工具类你可能会想,写了这么多判空代码,我能不能封装一个工具类,让其他地方直接调用?当然可以。你可以封装一个 NullSafe 工具类,让判空变得更加简单。比如:public class NullSafe { public static <T> Optional<T> ofNullable(T value) { return Optional.ofNullable(value); } }然后直接调用:String street = NullSafe.ofNullable(user) .map(User::getAddress) .map(Address::getStreet) .orElse("默认街道");三、现代化框架的判空银弹1. Spring 实战技巧如果你在用 Spring 框架,那么 Spring 提供了一些非常好用的工具类来帮助我们判空,比如 CollectionUtils 和 StringUtils。if (CollectionUtils.isEmpty(userList)) { // 处理用户列表为空的情况 } if (StringUtils.isEmpty(user.getName())) { // 处理用户名为空的情况 }这些工具类能大大简化我们的代码,让判空更加直接和简洁。2. Lombok 保驾护航Lombok是我们项目中的老朋友了,@NonNull 注解简直是自动生成判空代码的神奇宝贝。通过它,我们可以在方法参数中标记某个参数不能为 null,如果为 null,Lombok 会自动抛出 NullPointerException,省去了手动检查的麻烦。public void setUserName(@NonNull String name) { this.name = name; }调用这个方法时,如果传入 null,Lombok 会帮我们自动抛出 NullPointerException,这样一来,代码简洁且异常处理得当。四、工程级解决方案在一些大型项目中,空指针检查可能变得尤为复杂,传统的判空方式已经不适用了,这时我们可以考虑采用一些工程级的方案。1. 空对象模式空对象模式是一种很巧妙的解决方案,它通过定义一个空对象来替代 null,避免了频繁的 null 检查。比如,我们可以定义一个 Notification 接口的空对象,实现一个空的 Notification 对象,从而避免频繁的 null 检查。public class EmptyNotification implements Notification { @Override public void notifyUser() { // 什么也不做 } }这样,当没有通知需要发送时,直接使用 EmptyNotification,不需要担心 null 的问题。2. Guava 的 Optional 增强Guava的 Optional 提供了一些更为强大的功能,比如 transform 和 or 方法,能够帮助我们进行更复杂的操作。比如:Optional<String> name = Optional.of("John"); String upperName = name.transform(String::toUpperCase).or("Default Name");这段代码用 Guava 的 Optional 实现了 String 大写转换,并且提供了一个默认值,简洁且优雅。五、防御式编程进阶在一些关键性业务中,我们还可以通过防御式编程来增强系统的健壮性,防止出现 null 值导致的问题。1. Assert 断言式拦截断言(assert)能够帮助我们验证某些关键参数在方法执行之前是有效的。如果某个参数为 null,程序会立即抛出异常。public void processData(@NonNull String data) { assert data != null : "数据不能为空"; // 处理数据 }这样我们就能确保传入的数据不会为 null,提高了代码的健壮性。2. 全局 AOP 拦截AOP 拦截可以帮助我们全局处理参数判空的逻辑,尤其是在接口调用时非常有用。通过自定义注解与 AOP 结合,我们可以在调用接口之前拦截请求,进行判空处理,避免了重复编写判空代码。@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NotNullCheck { // 自定义判空注解 }然后通过 AOP 拦截:@Aspect @Component public class NullCheckAspect { @Before("@annotation(NotNullCheck)") public void checkParamsNotNull(JoinPoint joinPoint) { for (Object arg : joinPoint.getArgs()) { if (arg == null) { throw new IllegalArgumentException("参数不能为null"); } } } }六、总结在 Java 开发中,判空问题一直是程序员面临的挑战之一。从传统的多层 if (xxx == null) 判空,到 Java 8 引入的革命性工具 Optional,再到现代化框架提供的强大支持,判空操作已经经历了显著的进化。如今,程序员不再需要一遍遍地编写冗长的 if 判断,代码变得更加简洁、优雅,可读性也大幅提升。无论是通过 Optional 的链式调用,还是借助 Spring、Lombok 等现代化框架的工具类,Java 开发者都可以轻松实现高效、优雅的判空操作。接下来,我们将总结这些判空技巧,帮助你彻底告别繁琐的判空代码,提升开发效率与代码质量。
2025年03月18日
37 阅读
0 评论
0 点赞
2025-03-18
Spring 官宣接入 DeepSeek,太香了!
Spring AI已经支持DeepSeek。今天和大家聊聊如何在Spring Boot项目制使用DeepSeek,还是非常方便的!Spring AI介绍Spring AI是一个用于AI工程的应用程序框架,将Spring生态系统设计原则应用于AI领域。其核心是通过抽象化和模块化设计,简化AI功能的接入步骤,同时保持与Spring生态的无缝兼容。以下是其主要特点与功能:统一的抽象API:支持主流AI服务,如 OpenAI、DeepSeek、Google、和Ollama等,提供了提供标准化的接口。核心功能模块:模型交互、向量处理、检索增强生成(RAG)、函数调用。低代码集成:通过Spring Boot Starter依赖快速接入,在配置文件中配置好AI服务即可使用。结构化输出:将模型响应直接映射为Java对象,简化数据处理。流式响应:支持Flux流式输出,适用于实时聊天等场景。Spring AI集成DeepSeek申请Api Key首先我们需要去DeepSeek官网申请Api Key,地址:https://platform.deepseek.com/api_keys Spring Boot中集成DeepSeek首先在SpringBoot项目中添加Spring AI对应的依赖;<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>1.0.0-M6</version> </dependency>然后在项目的application.yml配置文件中添加调用AI服务相关的配置;spring: ai: openai: # 调用AI接口时表明身份的API KEY api-key: <YOUR_API_KEY> # 调用AI接口时的基础路径,配置的是阿里云百炼的基础路径 base-url: https://api.deepseek.com chat: options: # 调用的模型,DeepSeek的话可以选择deepseek-r1或deepseek-v3 model: deepseek-chat # 用来控制文本生成的随机性(创造力),值越小越严谨 temperature: 0.8创建一个控制器类,用于处理与 DeepSeek 的交互,import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/chat") public class ChatController { @Autowired private DeepSeekClient deepSeekClient; @PostMapping public String chat(@RequestBody String message) { return deepSeekClient.chatCompletion(message).getOutput().getContent(); } @GetMapping(value = "/stream", produces = "text/event-stream") public Flux<String> chatStream(@RequestParam String message) { return deepSeekClient.chatFluxCompletion(message) .map(response -> response.getOutput().getContent()); } }
2025年03月18日
26 阅读
0 评论
0 点赞
2025-03-17
iPhone12~iPhone16E支持5GA网络IPCC文件
目前IOS 18.4 Beta2测试版本身已经支持,其他版本的如果想体验5GA可以通过更新IPCC的方式实现。目前5GA要求条件比较苛刻,如果想体验的,请先看一下是否满足一下条件:iPhone12以上机型,不区分普通版、Pro或者Plus或者Max,全系均可。IOS18.2及以上系统(IOS 18.4本身已经支持,无需更新IPCC)。环境要求较高,目前5GA覆盖不完善,基本只有大城市的核心区域才覆盖。下载ipcc文件我这里已经整理好了iPhone12~iPhone16E对应版本的IPCC文件,所有IPCC文件都是最新的63.0版本。如有需要的,可以选择自己对应的版本下载。{cloud title="ipcc下载" type="bd" url="https://pan.baidu.com/s/180I5qvR7cuC8YDysrvQSnQ" password="j6dg"/}注意,每个压缩包内都有对应移动、联通、电信、广电的IPCC文件,具体区分如下{card-describe title="IPCC说明"}中国广电 CBN_cn.ipcc 63.0中国电信 ChinaTelecom_USIM_cn.ipcc 63.0中国移动 CMCC_cn.ipcc 63.0中国联通 Unicom_cn.ipcc 63.0{/card-describe}使用爱思助手刷如ipcc打开爱思助手,切换到【工具箱】,点击【更新IPCC文件】如果是双卡手机,注意选择SIM卡对应的电信运营商,点击【选择本地IPCC】{message type="error" content="一定要正确选择对应运营商的IPCC文件"/}点击立即更新IPCC刷完后手机会立即重新搜索信号,我们可以到手机设置-通用-关于本机-下拉到底-看运营商后面的数字是不是你刷的IPCC版本号数字,比如你刷的是63.0 IPCC,刷完这里会变成63.0即成功。这个时候,如果你所在地区支持5GA网络,那么你的手机原来的5G就会变成5GA
2025年03月17日
71 阅读
0 评论
0 点赞
2025-03-16
HarmonyOS Next自带浏览器如何更换搜索引擎
之前买的Mate 60 Pro一直在吃灰,今天因为手机被孩子拿手了,临时用了一下,竟然发现了HarmonyOS Next自带的华为浏览器的无语的功能。HarmonyOS Next自带的华为浏览器默认搜索引擎竟然是360搜索,感觉哪怕默认个百度搜索我都不说啥了,百度搜索虽然说广告多、虚假内容多,但是起码内容比较全,360搜索,这不光广告多、虚假内容多,关键是搜索内容少呀。出自之外,华为浏览器想更换搜索引擎,对于普通人来说还是比较麻烦的。感觉这产品经理不是回扣吃的多就是个脑残瞅瞅下面这骚操作,这是给人用的东西吗,好像除了华为浏览器这个骚操作,别的浏览器还真没见过这样的,其他浏览器基本都能直接切换。{mtitle title="华为浏览器更换Bing搜索引擎"/}这里,推荐大家使用Bing搜索,搜索内容比较多,没有乱七八糟的广告或者虚假内容,具体更换方法如下:打开浏览器,切换到【我的】页签在【我的】页签,点击【设置】在【设置】页面点击【搜索引擎】点击下面那行小字【编辑自定义搜索引擎】第一行随便输入名称即可,我这里输入的Bing第二行很关键,输入https://cn.bing.com/search?q=%s点击右上角的[√]保存设置在返回的页面,勾选我们新添加的Bing搜索
2025年03月16日
38 阅读
0 评论
0 点赞
2025-03-16
开源文件管理系统Cloudreve,超好用的私人网盘
在日常工作和学习中,经常需要在不同终端设备间传输文件,或是需要将孩子照片或者其他重要文档备份到云端。但市面上的云盘要么收费高昂,要么空间有限,还时常担心隐私泄露的问题。不仅如此,我们还总会遇到各种限制:下载速度慢、单次上传大小受限、无法预览特定格式文件等,更不用说在多个云盘间切换的麻烦。最近在 GitHub 上发现了一款名为Cloudreve的开源文件管理系统,完美解决了这些问题。无论是个人存储照片视频、团队共享文档,还是构建公司内部的文件管理系统,都能高效应对。它不仅支持多种云存储集成,还提供了强大的文件管理功能,让我们能够轻松掌控自己的数据,不再受制于商业云服务的各种限制。主要功能Cloudreve的功能非常全面,几乎涵盖了所有文件管理的需求:存储管理:可将文件存储在本地、远程服务器支持七牛云、阿里云 OSS、腾讯 COS、OneDrive并兼容S3接口的多种云存储服务文件传输:支持直传文件并可限制传输速度,大文件上传下载不再是问题集成Aria2实现离线下载功能,还能使用多个下载节点分担负载支持拖拽上传文件或文件夹,并提供流式上传处理文件管理:支持压缩/解压文件,批量下载文件等操作通过拖放操作管理文件,界面直观易用覆盖所有存储提供商的 WebDAV 协议支持用户与分享:支持多用户多用户组管理,权限分明可创建带有过期日期的文件和文件夹分享链接内容预览:支持在线预览视频、图片、音频、ePub文件支持在线编辑文本和 Office 文档界面定制:可自定义主题颜色,支持暗黑模式支持 PWA 应用、单页应用以及国际化安装指南安装指南安装Cloudreve非常简单,只需几个步骤就能完成部署:首先,从 GitHub下载适合自己操作系统和 CPU 架构的Cloudreve安装包解压下载的文件:tar -zxvf cloudreve_版本号_系统_架构.tar.gz授予执行权限:chmod +x ./cloudreve直接运行:./cloudreve这样,Cloudreve就成功启动了。如果需要更完整的部署方案,可以参考官方文档。使用指南使用Cloudreve也十分直观:启动Cloudreve后,通过浏览器访问程序运行的地址(默认为http://localhost:5212)首次访问时,系统会自动创建管理员账户并显示登录信息登录后,可以通过直观的界面上传、管理文件,或配置各类云存储对于文件操作,只需简单拖拽即可完成上传、移动等操作需要分享文件时,选中文件点击分享按钮,即可生成带有访问控制的分享链接
2025年03月16日
131 阅读
1 评论
0 点赞
2025-03-15
Apple Watch需要贴膜吗
先说结论:有必要但是无法贴。先说一下为啥有必要,Apple Watch的屏幕虽然日常使用中不会轻易破碎,但是真的很不耐磨,平时靠着墙边走路时,容易磕碰到墙体,又或时不时的被门框、桌子等硬物的摩擦使用中产生一些痕迹,可能会影响观感,也会影响二手出售时的品相。我当初选择贴膜,就是因为屏幕在办公桌被划出了多条很深的划痕。再说一下为啥没法贴,Apple Watch屏幕本身是带有弧度的,因此贴膜时,也只能贴那种软膜,这种膜本身贴的难度就很大,所以即使要贴膜,一定要买自带贴膜神器的。但是贴膜之后,使用几天,基本都会翘边,就像下面这样,而且随着时间的推移,翘边会越来越严重,最终的结果也只能是撕掉。综合所述,在日常生活中,因为磕碰是在所难免的,如果是完美主义者,需要贴膜,但是因为Apple Watch屏幕的异边形,导致无法贴膜。
2025年03月15日
59 阅读
0 评论
0 点赞
2025-03-14
iCloud云盘提升下载速度的一个小妙招
使用过苹果全家桶的童鞋应该知道,iCloud在苹果设备下同步速度是非常快的,但是Windows下的iCloud云盘的同步速度慢的令人发指,按道理来讲,国内iCloud是由云上贵州运营的,服务器也在国内,同步速度应该是非常快的,根据网友抓包反馈,是因为iCloud数据是以区块的形式单独存放在本土服务器上的,每个区块单独加密,每个区块都有个秘钥,秘钥是保存在苹果服务器,每次同步服务,需要到苹果服务器请求一次秘钥。所以导致iCloud同步速度很慢。 如果你也有在Windows下使用iCloud的需求,可以尝试在iCloud存储一个较大的文件,在iCloud同步数据时,双击打开这个较大的文件,手工触发下载过程,这样其他的文件下载速度也会比较快。
2025年03月14日
57 阅读
0 评论
0 点赞
1
...
3
4
5
...
52