首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,590 阅读
2
Mac打印机设置黑白打印
4,903 阅读
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-14
OneDrive几个令人疑惑的设定
OneDrive 是微软(Microsoft)提供的云存储服务,允许用户将文件、照片和其他数据存储在云端,并通过互联网连接从任何设备访问这些数据。 OneDrive 是一款强大的云存储工具,但在使用过程中可能会遇到一些令人疑惑的东西,下面以我个人经历来说一下。网页端不可用 这一点当然不是微软的问题,国内环境特殊,但是网页端不让用,客户端却没啥影响,不知何故。超过存储空间导致客户端无法登录 这个确实比较坑,当超过存储空间时,会导致客户端无法使用,客户端登陆的时候只有错误代码,也不提示具体原因,但是因为国内无法使用网页端,就导致了一个死结:因为超额,导致OneDrive无法登录,必须去网页端才能释放空间,但是网页端又无法登录。删除的文件无法自动上传 OneDrive有一套判断文件是否需要上传的机制,当你在OneDrive中删除过一次文件之后,这个文件永远不会重新上传,除非你自己手工上传。订阅机制 这个订阅很奇怪,大家都知道OneDrive免费提供5G的空间,通过某宝可以扩展到15G,但是OneDrive在不同终端订阅方式是不一样的。 网页端及Windows客户端需要配合Microsoft 365 个人版一起购买,最低收费39元/月,我没找到单独购买OneDrive的地方。 IOS、Mac端,购买100G空间收费15元/月,相对来说是比较合适的。各种各样的Bug 自从阿三接管了微软,微软的产品就越来越难用了,后续不断完善遇到的bug及解决思路。{mtitle title="文件资源管理器出现两个一样的OneDrive图标"/}已解决,可以参考 https://lisen.cc/blog/two-onedrive-files-appear-on-the-left-side-of-windows-file-manager.html {mtitle title="桌面出现一个OneDrive文件夹"/}电脑桌面出现一个OneDrive的文件夹,即便删除之后,重启电脑又会再次出现,此问题尚未解决。
2025年03月14日
71 阅读
0 评论
0 点赞
2025-03-13
OneDrive与iCloud该如何选择
经常使用网盘的童鞋,相信对于OneDrive及iCloud都不会陌生,下面结合我个人的使用经验区分不同需求教大家选择最适合的云存储服务。非Apple用户这里说的非Apple用户指的是不同任何苹果设备的用户,也就是Mac、iPad、iPhone都不使用,这种情况下,毫无疑问的选择OneDrive。Android手机+Mac的用户建议使用OneDrive,因为手机不是iPhone是无法使用iCloud的,也无法体验跨设备协调的便利性,另外OneDrive的速度也相对较快,抽风的情况比较少。iPhone手机+Windows电脑建议使用iCloud,iPhone手机中,iCloud的便利性及强大功能,是OneDrive不能比拟的,比如照片可以随时自动上传到iCloud,同时手机的各种备份OneDrive也无法满足。Apple全家桶用户这里说的Apple全家桶用户,指的是主力设备都是苹果用户,像我这种,家里用Mac、手机用iPhone、公司电脑是Windows的也可以归为此类用户,这类人群,结合我个人的使用经验,建议使用iCloud,之所以推荐使用iCloud,主要基于以下几个方面。跨设备使用便捷性:比如我们用手机拍照,iCloud会自动上传并同步到不同的终端,我们无需额外操作在Mac、iPad上直接可以查看,即便是使用Windows电脑,安装iCloud后,照片也能自动同步过去。云端与本地数据一致性:还是以照片为例,我们拍照时,iCloud会自动同步到云端,我们本地删除照片时,所有的终端包括云端能同步删除。但是OneDrive却不行,使用OneDrive,照片能自动上传到云端,但是我们删除本地照片时,云端的数据不会自动删除,同时如果别的终端下载了照片,删除的图片也不会同步在其他终端删除。数据一致性检查:iCloud因为是终端数据自动同步的,所以我们不需要单独下载图片。但是OneDrive需要我们手工保存一下图片,但是OneDrive保存图片时,并不会校验本地是否已经存在,像我手机里面有几千张图片,如果我要保存一张图片,但是不确定本机是否已经有这张图片,那么在保存后,很可能导致图片重复,即便同一个照片,我们多次保存时,OneDrive也会在本机保存多张同一张图片。OneDrive会导致图片顺序错乱:当图片上传到OneDrive时,OneDrive会把照片的拍摄时间搞混乱。OneDrive令人迷惑的逻辑一:同一张图片,如果我们在OneDrive删除过一次的话,后续OneDrive便永远不会再次自动同步这张图片,即便我们打开了相机自动备份,除非我们自己手工上传。OneDrive令人迷惑的逻辑二:这个地方倒也可以理解,假设我们OneDrive在非本机图片文件夹内有一个图片,但是本机没有,当我们把这张图片存储到本机后,如果开启了OneDrive的相机自动备份,此时OneDrive会立即将这张图片再次保存到OneDrive的本机图片文件夹中。OneDrive超过存储空间的致命问题:当OneDrive的存储内容超过空间大小时,OneDrive客户端是无法登录的,打开OneDrive就会让你关闭,不会给你任何释放空间的机会,如果想释放空间,必须登录OneDrive网页版,但是因为国内的特殊性,OneDrive不通过特殊手段是无法登录的,这也就意味着,一旦超过空间大小,OneDrive很可能就无法使用了。当然,iCloud也不是说多好,如果我们使用苹果全家桶,你会发现iCloud在不同设备之间同步非常快,速度方面绝对不比OneDrive慢,但是如果你使用Windows上的iCloud,你会发现速度比蜗牛都慢,当文件特别多时,甚至会出现文件无法下载的情况。
2025年03月13日
77 阅读
0 评论
0 点赞
2025-03-13
Windows文件管理器左侧出现两个OneDrive
很久没有使用过过OneDrive了,之前系统自带的甚至都卸载了。最近因为iCloud购买的50G的空间即将满了,看着单独购买OneDrive的100G空间只需要15元,想着将iCloud的东西迁移到OneDrive上,结果安装完OneDrive后,发现资源管理器的快捷访问栏有两个一模一样的OneDrive图标,如下图之所以会这样,个人猜测可能跟之前安装过商业版、个人版不同版本的OneDrive没卸载干净导致的,网上搜索了一下,发现很多人都遇到过,但是好多地方提供的修改方式并没有用,要么注册表的位置不对,要么电脑重启之后,会反复出现。直到使用了下面这种方式才彻底解决了。首先打开注册表,定位到HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\然后删除{04271989-C4D2-D678-C596-AE7D03458BA4}这个键。至此,测试解决了。
2025年03月13日
78 阅读
0 评论
0 点赞
2025-02-19
使用Page Assist实现本地部署DeepSeek对话及数据投喂
在 ollama本地部署 DeepSeek详细教程:小白也能轻松搞定! 中我们实现了deepseek的本地部署及使用chatbox可视化界面搭建,但是chatbox无法进行本地模型的训练,界面也不是很美观,这里我们介绍另外一个浏览器插件Page Assist实现模型对话与训练。安装Page Assist插件我是用的Edge浏览器,Chrome浏览器也是类似的。打开扩展界面,搜索Page Assist第一个就是,点击获取进行安装安装完成后,点击这个小图标(真的好小)如果本地ollama正在运行,会出现下面的页面我们点击右上角的设置按钮,进行设置先修改一下语言,改成简体中文设置完成后,返回首页,在左上角选择我们的模型,就可以进行对话了本地模型训练为了让模型更加了解我们的需求,我们可以给模型投喂数据,这里我们需要用一个量化的工具,把各种格式的数据量化给人工智能,让它能看得懂。也就是RAG。这里我们使用ollama提供的nomic-embed-text可以打开[](https://ollama.com/library/nomic-embed-text)这个页面查看拉取命令将命令ollama pull nomic-embed-text复制到终端里面执行即可安装完成后,我们进入Page Assist的设置界面在RAG设置标签页,选择nomic-embed-text:last然后切换到管理知识页,点击添加新知识,就可以对我们的模型进行投喂了添加完成后,可以查看处理状态及历史数据
2025年02月19日
412 阅读
0 评论
0 点赞
2025-02-19
ollama本地部署 DeepSeek详细教程:小白也能轻松搞定!
2025蛇年伊始,DeepSeek如平地惊雷般引发空前讨论,不知腾讯等大厂的产品积极拥抱DeepSeek,就连我们普通人就在使用DeepSeek解决一些问题,俨然进入了全民AI时代。DeepSeek-R1 已发布并开源,性能对标 OpenAI o1 正式版。DeepSeek 不同版本模型硬件要求不同版本对应参数量不同,参数量越大,使用效果越好,当然对应电脑配置要求越高。以下是 DeepSeek 不同版本模型的硬件要求,小伙伴们可以结合自己电脑配置选择版本模型版本参数量显存需求(FP16)推荐 GPU(单卡)多卡支持量化支持适用场景DeepSeek-R1-1.5B15亿3GBGTX 1650(4GB显存)无需支持低资源设备部署(树莓派、旧款笔记本)、实时文本生成、嵌入式系统DeepSeek-R1-7B70亿14GBRTX 3070/4060(8GB显存)可选支持中等复杂度任务(文本摘要、翻译)、轻量级多轮对话系统DeepSeek-R1-8B80亿16GBRTX 4070(12GB显存)可选支持需更高精度的轻量级任务(代码生成、逻辑推理)DeepSeek-R1-14B140亿32GBRTX 4090/A5000(16GB显存)推荐支持企业级复杂任务(合同分析、报告生成)、长文本理解与生成DeepSeek-R1-32B320亿64GBA100 40GB(24GB显存)推荐支持高精度专业领域任务(医疗/法律咨询)、多模态任务预处理DeepSeek-R1-70B700亿140GB2x A100 80GB/4x RTX 4090(多卡并行)必需支持科研机构/大型企业(金融预测、大规模数据分析)、高复杂度生成任务DeepSeek-671B6710亿512GB+(单卡显存需求极高,通常需要多节点分布式训练)8x A100/H100(服务器集群)必需支持国家级/超大规模 AI 研究(气候建模、基因组分析)、通用人工智能(AGI)探索DeepSeek本地安装目前ollama已经支持DeepSeek,我们这里也使用ollama进行安装。下载并安装Ollama访问Ollama官网 下载选择自己电脑对应的操作系统版本进行下载安装即可。也可以直接使用下面的链接下载对应系统版本Windows MacOS Linux可以直接使用curl命令安装,命令如下curl -fsSL https://ollama.com/install.sh | sh本文以Windows为例进行介绍验证Ollama是否安装成功下载后,会得到OllamaSetup.exe文件,直接双击安装,完成后,打开终端,输入ollama -v,如果输出对应的版本号代表安装成功。通过Ollama部署DeepSeek 模型之前部署过1.5B的,感觉效果差强人意,这次尝试一下7B的,也可以选择其他版本详细部署版本可以查看 https://ollama.com/library/deepseek-r1 命令行输入:ollama run deepseek-r1:7b 拉取DeepSeek模型7B模型大概4.7G,根据电脑网速,下载时间有所不同下载完成后,就可以进行对话了每次进行对话时,可以在命令行输入:ollama run deepseek-r1:7b部署可视化前端界面目前虽然已经可以在终端进行对话,但是界面比较简陋,我们可以使用Chatbox这个可视化图文交互界面来提升使用体验。进入 Chatbox官网 下载对应版本的安装包。安装完成后,打开,选择使用自己本地模型在弹出的界面,选择ollama api在弹出界面中,模型选择本地模型,因为我部署的是deepseek-r1:7b,所以选择deepseek-r1:7b即可然后就可以进行对话了
2025年02月19日
220 阅读
0 评论
0 点赞
2025-02-09
Harmony OS Next自定义键盘实现车牌输入
爱车记App有一个我的车库功能,用户可以维护自己的车辆信息,包括车牌号码,为了方便输入车牌,可以通过自定义键盘的方式实现车牌号码的录入。 //展示的text @State @Watch('setCarNumberText') carNumberText: string = ""; //屏幕宽度 @State screenWidth: number = 0; @State isShow: boolean = false @State inputValue: string = "" //车牌号最大长度 @State carNumberMaxLength: number = 8; @State carNumberIndex: number[] = [] //控制动画的 @State showMouse: boolean[] = []; @State isFirstInput: boolean = true provincesKeyBoard: string[][] = [["京", "津", "晋", "冀", "蒙", "辽", "吉", "黑", "沪"], ["苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘"], ["粤", "桂", "琼", "渝", "川", "贵", "云", "藏"], ["陕", "甘", "青", "宁", "新", "", getStringFromResource($r("app.string.item_key_delete"))]] commonKeys: string[][] = [["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"], ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"], ["A", "S", "D", "F", "G", "H", "J", "K", "L"], ["Z", "X", "C", "V", "B", "N", "M"], ["港", "澳", "学", getStringFromResource($r("app.string.item_key_delete"))]] commonKeyBoard: CommonKeyItem[][] = [[], [], [], [], []] // 输入框的大小 inputBoxSize: number = 0 controller: TextInputController = new TextInputController() //未选中的样式 private btnCancelBorder?: commonBorder = { width: '3px', color: '#ccc', style: BorderStyle.Solid } //选中的样式 private btnCancelBorderActive: commonBorder = { width: '3px', color: Color.Red, style: BorderStyle.Solid } build() { // 车牌 Column() { Text($r("app.string.car_number")) .fontSize(10) .fontColor($r("app.color.label_font_color")) .alignSelf(ItemAlign.Start) this.carNumberComponentBuilder() } .justifyContent(FlexAlign.Start) .padding({ left: 15, right: 15 }) .width('100%') .borderRadius(15) } } onPageShow(): void { //自定义键盘 this.screenWidth = 1080; this.showMouse = new Array(this.carNumberMaxLength).fill(false); this.showMouse[0] = true for (let i = 0; i < this.carNumberMaxLength; i++) { this.carNumberIndex[i] = i } this.inputBoxSize = px2vp(this.screenWidth) / (this.carNumberIndex.length + 1) - 2 for (let i = 0; i < this.commonKeys.length; i++) { for (let j = 0; j < this.commonKeys[i].length; j++) { this.commonKeyBoard[i][j] = new CommonKeyItem(this.commonKeys[i][j], true) } } } /** * 车牌号改变监听 */ setCarNumberText() { if (this.carNumberText.length == 0) { this.isFirstInput = true } else { this.isFirstInput = false } this.getForbiddenInput(this.carNumberText) this.handelInputTxt(this.carNumberText.length, this.carNumberText); this.myCar.number = this.carNumberText } //可以控制禁止输入的按键 getForbiddenInput(input: string) { // if (input && input.length === 1) { // this.commonKeyBoard[0][0].display = false // this.commonKeyBoard[0][1].display = false // this.commonKeyBoard[0][2].display = false // this.commonKeyBoard[0][3].display = false // this.commonKeyBoard[0][4].display = false // this.commonKeyBoard[0][5].display = false // this.commonKeyBoard[0][6].display = false // this.commonKeyBoard[0][7].display = false // this.commonKeyBoard[0][8].display = false // this.commonKeyBoard[0][9].display = false // // this.commonKeyBoard[4][0].display = false // this.commonKeyBoard[4][1].display = false // this.commonKeyBoard[4][2].display = false // } else if (input && input.length === 2) { // this.commonKeyBoard[0][0].display = false // this.commonKeyBoard[0][1].display = false // this.commonKeyBoard[0][2].display = false // this.commonKeyBoard[0][3].display = false // this.commonKeyBoard[0][4].display = false // this.commonKeyBoard[0][5].display = false // this.commonKeyBoard[0][6].display = false // this.commonKeyBoard[0][7].display = false // this.commonKeyBoard[0][8].display = false // this.commonKeyBoard[0][9].display = false // // this.commonKeyBoard[1][0].display = false // this.commonKeyBoard[1][1].display = false // this.commonKeyBoard[1][2].display = true // this.commonKeyBoard[1][3].display = false // this.commonKeyBoard[1][4].display = false // this.commonKeyBoard[1][5].display = false // this.commonKeyBoard[1][6].display = false // this.commonKeyBoard[1][7].display = false // this.commonKeyBoard[1][8].display = false // this.commonKeyBoard[1][9].display = false // // this.commonKeyBoard[2][0].display = true // this.commonKeyBoard[2][1].display = false // this.commonKeyBoard[2][2].display = true // this.commonKeyBoard[2][3].display = false // this.commonKeyBoard[2][4].display = false // this.commonKeyBoard[2][5].display = false // this.commonKeyBoard[2][6].display = false // this.commonKeyBoard[2][7].display = false // this.commonKeyBoard[2][8].display = false // // this.commonKeyBoard[3][0].display = true // this.commonKeyBoard[3][1].display = false // this.commonKeyBoard[3][2].display = true // this.commonKeyBoard[3][3].display = false // this.commonKeyBoard[3][4].display = true // this.commonKeyBoard[3][5].display = false // this.commonKeyBoard[3][6].display = false // // this.commonKeyBoard[4][0].display = false // this.commonKeyBoard[4][1].display = false // this.commonKeyBoard[4][2].display = false // } else { // this.commonKeyBoard[0][0].display = true // this.commonKeyBoard[0][1].display = true // this.commonKeyBoard[0][2].display = true // this.commonKeyBoard[0][3].display = true // this.commonKeyBoard[0][4].display = true // this.commonKeyBoard[0][5].display = true // this.commonKeyBoard[0][6].display = true // this.commonKeyBoard[0][7].display = true // this.commonKeyBoard[0][8].display = true // this.commonKeyBoard[0][9].display = true // // this.commonKeyBoard[1][0].display = true // this.commonKeyBoard[1][1].display = true // this.commonKeyBoard[1][2].display = true // this.commonKeyBoard[1][3].display = true // this.commonKeyBoard[1][4].display = true // this.commonKeyBoard[1][5].display = true // this.commonKeyBoard[1][6].display = true // this.commonKeyBoard[1][7].display = true // this.commonKeyBoard[1][8].display = true // this.commonKeyBoard[1][9].display = true // // this.commonKeyBoard[2][0].display = true // this.commonKeyBoard[2][1].display = true // this.commonKeyBoard[2][2].display = true // this.commonKeyBoard[2][3].display = true // this.commonKeyBoard[2][4].display = true // this.commonKeyBoard[2][5].display = true // this.commonKeyBoard[2][6].display = true // this.commonKeyBoard[2][7].display = true // this.commonKeyBoard[2][8].display = true // // this.commonKeyBoard[3][0].display = true // this.commonKeyBoard[3][1].display = true // this.commonKeyBoard[3][2].display = true // this.commonKeyBoard[3][3].display = true // this.commonKeyBoard[3][4].display = true // this.commonKeyBoard[3][5].display = true // this.commonKeyBoard[3][6].display = true // // this.commonKeyBoard[4][0].display = true // this.commonKeyBoard[4][1].display = true // this.commonKeyBoard[4][2].display = true // } } //改变输入框选中的值 handelInputTxt(length: number, _val: string) { for (let i = 0; i < this.carNumberMaxLength; i++) { this.showMouse[i] = false } this.showMouse[length] = true } //自定义键盘样式 @Builder CustomKeyboardBuilder() { Column() { if (this.isFirstInput) { this.buildProvinceKeyboard(this.provincesKeyBoard[0]) this.buildProvinceKeyboard(this.provincesKeyBoard[1]) this.buildProvinceKeyboard(this.provincesKeyBoard[2]) this.buildProvinceKeyboard(this.provincesKeyBoard[3]) } else { this.buildCommonKeyboard(this.commonKeyBoard[0]) this.buildCommonKeyboard(this.commonKeyBoard[1]) this.buildCommonKeyboard(this.commonKeyBoard[2]) this.buildCommonKeyboard(this.commonKeyBoard[3]) this.buildCommonKeyboard(this.commonKeyBoard[4]) } }.backgroundColor(0xf0f0f0).padding({ bottom: px2vp(this.bottomRectHeight) }) } @Builder buildCommonKeyboard(keyboard: CommonKeyItem[]) { Grid() { ForEach(keyboard, (item: CommonKeyItem) => { GridItem() { if (item.key === getStringFromResource($r("app.string.item_key_delete"))) { Text() { ImageSpan($r('app.media.custom_keyboard_delete')) .width('100px') .height('100px') .objectFit(ImageFit.Fill) .verticalAlign(ImageSpanAlignment.CENTER); } .fontSize(16) .textAlign(TextAlign.Center) .width(36) .height(40) .backgroundColor(Color.White) .borderRadius(4) .onClick(() => { this.carNumberText = this.carNumberText.slice(0, -1); }); } else { if (item.display) { Text(item.key) .width(25) .backgroundColor(Color.White) .fontSize(16) .textAlign(TextAlign.Center) .width(35) .height(40) .backgroundColor(Color.White) .borderRadius(4) .onClick(() => { if (this.carNumberText.length < this.carNumberMaxLength) { this.carNumberText += item.key; } }); } else { Text(item.key) .width(25) .backgroundColor(Color.White) .fontSize(16) .textAlign(TextAlign.Center) .width(35) .height(40) .backgroundColor(0xE0E0f0) .borderRadius(4) .onClick(() => { }); } } }; }); }.maxCount(keyboard.length).columnsGap(4).rowsGap(4).padding(3) } @Builder buildProvinceKeyboard(keyboard: string[]) { Grid() { ForEach(keyboard, (item: string) => { GridItem() { if (item == getStringFromResource($r("app.string.item_key_delete"))) { Text() { ImageSpan($r('app.media.custom_keyboard_delete')) .width('100px') .height('100px') .objectFit(ImageFit.Fill) .verticalAlign(ImageSpanAlignment.CENTER); } .fontSize(16) // .fontWeight(600) .textAlign(TextAlign.Center) .width(38) .height(40) .backgroundColor($r("app.color.white")) .borderRadius(4) .onClick(() => { this.carNumberText = this.carNumberText.slice(0, -1); }); } else { Text(item) .fontSize(16)// .fontWeight(600) .textAlign(TextAlign.Center) .width(38) .height(40) .backgroundColor($r("app.color.white")) .borderRadius(4) .onClick(() => { if (!item) { return } if (this.carNumberText.length < this.carNumberMaxLength) { this.carNumberText += item; } }); } }; }); } .maxCount(keyboard.length) .columnsGap(4) .rowsGap(4) .padding(3) } @Builder carNumberComponentBuilder() { Column() { this.buildCarNumberInput() } } //车牌号码构造器 @Builder buildCarNumberInput() { Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) { Column() { Row() { Text(this.carNumberText[0]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[0]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[1]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[1]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[2]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[2]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[3]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[3]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[4]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[4]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[5]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[5]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[6]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[6]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) Text(this.carNumberText[7]) .fontSize(16) .textAlign(TextAlign.Center) .width(this.inputBoxSize) .height(this.inputBoxSize) .margin({ left: 1, right: 1 }) .border(this.showMouse[this.carNumberIndex[7]] ? this.btnCancelBorderActive : this.btnCancelBorder) .borderRadius(5) } .onClick(() => { focusControl.requestFocus('LicensePlateInput') }).width('100%').justifyContent(FlexAlign.SpaceBetween) TextInput() .width('100%') .height(250) .opacity(0) .id('LicensePlateInput') .enableKeyboardOnFocus(true) .customKeyboard(this.CustomKeyboardBuilder()) }.width('100%') } .height(32) .id("customInput") .defaultFocus(false) } } export interface commonBorder { width?: Length | EdgeWidths, color?: ResourceColor | EdgeColors, radius?: Length | BorderRadiuses, style?: BorderStyle | EdgeStyles } class CommonKeyItem { key: string; display: boolean; constructor(key: string, display: boolean) { this.key = key; this.display = display } }
2025年02月09日
112 阅读
0 评论
0 点赞
2025-01-26
Harmony OS Next实现长按复制内容
爱车记App有个查询附近充电站的功能,为了方便使用在其他导航使用(我们默认使用的是华为的花瓣地图,因为花瓣地图POI查询不支持电价,比较不方便),我们支持在充电站列表界面长按复制充电站名称,所以我们介绍一下,在Harmony OS Next中实现长按复制文本的功能。{mtitle title="封装公共复制方法"/}为了方便不同地方使用,我们增加一个复制的公共方法。/** * 复制 * @param text 复制的文本 */ export function copyText(text: string) { const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); const systemPasteboard = pasteboard.getSystemPasteboard(); systemPasteboard.setData(pasteboardData); // 将数据放入剪切板 IBestToast.show({ message: getStringFromResource($r("app.string.copy_success")) }); }{mtitle title="实现长按复制"/}ListItem() { if (this.renderItem) { this.renderItem(nearbyChargeStation, index) } } .onClick(() => { this.naviChargeState(nearbyChargeStation) }) .swipeAction({ end: () => { this.swiperAction(nearbyChargeStation, index) } }) .borderRadius(8) .backgroundColor($r("app.color.white")) .gesture( LongPressGesture({ repeat: false, fingers: 1 }) .onAction((event: GestureEvent) => { if (event) { copyText(nearbyChargeStation.name) } }) .onActionEnd((event: GestureEvent) => { }) )我们重点关注.gesture( LongPressGesture({ repeat: false, fingers: 1 }) .onAction((event: GestureEvent) => { if (event) { copyText(nearbyChargeStation.name) } }) .onActionEnd((event: GestureEvent) => { }) )LongPressGesture代表长按手势:参数repeat代表是否重复触发,因为我们只是复制一次,因此设置false。fingers代表手指个数,取值范围是[1,10],我们这里只需要一个手指即可,因此设置1。onAction是触发事件,我们调用封装的公共copyText方法。onActionEnd是结束触发事件,如果有其他操作,比如清理资源啥的,可以在这个事件中处理。
2025年01月26日
118 阅读
0 评论
0 点赞
2025-01-24
typora 1.9.5破解教程
两年半之前,我们介绍过Typora 1.2.4破解版 。时过境迁,Typora现在也更新到1.9.5版本了。typora 1.9.5破解与1.2.4版本一样简单。壹、安装Typora直接从官网下载1.9.5版本即可。贰、替换winmm.dll下载下面的zip文件,解压之后得到winmm.dll{abtn icon="fa-download" color="#ff6800" href="https://oss.lisen.cc/typecho/uploads/2025/01/4140134200.zip" radius="" content="winmm.zip"/} 将winmm.dll复制到Typora的安装目录即可。
2025年01月24日
158 阅读
0 评论
0 点赞
2025-01-24
Navicat 最新版(16、17)永久激活教程
{mtitle title="版本说明"/}本教程适用于Navicat最新的16、17版本,截止本文发文时,17最新版本为17.1.12本教程测试版本为Navicat Premium 17.1.12版本,其他版本未做测试,理论上是通用的本教程只适合Windows版本,Mac OS 及Linux版本不支持{mtitle title="本文使用的资源文件"/}Navicat安装包,可自行在官网下载对应版本。winmm.zip破解包,通过以下链接下载{abtn icon="fa-download" color="#ff6800" href="https://oss.lisen.cc/typecho/uploads/2025/01/1120572478.zip" radius="" content="winmm.zip"/}{mtitle title="使用教程"/}壹、卸载旧版本的Navicat未安装过的用户可直接跳过该步骤,如果已安装旧版本的Navicat,记得先卸载干净,防止破解失效,卸载完成后将以下内容复制下来,新建一个的Navicat.bat脚本,然后双击执行。一闪而过表示正常,已成功删除Navicat的注册信息和相关的注册表数据。@echo off echo Delete HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium\Registration[version and language] for /f %%i in ('"REG QUERY "HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium" /s | findstr /L Registration"') do ( reg delete %%i /va /f ) echo. echo Delete Info folder under HKEY_CURRENT_USER\Software\Classes\CLSID for /f %%i in ('"REG QUERY "HKEY_CURRENT_USER\Software\Classes\CLSID" /s | findstr /E Info"') do ( reg delete %%i /va /f ) echo. echo Finish贰、安装Navicat安装过程不做过多赘述,正常安装即可。{message type="error" content="需要注意,安装完成之后,不要打开Navicat"/}叁、替换winmm.dll文件将资源文件中的winmm.zip解压后,会得到winmm.dll文件,将winmm.dll复制到Navicat的安装目录。操作完成后,打开Navicat,如果没有提示试用,则说明激活成功,可永久使用
2025年01月24日
1,180 阅读
2 评论
3 点赞
2025-01-16
Harmony OS Next中List铺满剩余屏幕
在Harmony OS Next开发过程中,我们经常使用List组件进行数据展示。比如爱车记App中,有一个Excel导入功能,后台将错误信息按照数组形式返回,前端通过List组件展示错误信息。整体页面大概如下,这里主要面临两个问题页面是沉浸式布局List组件内容数量不固定如果List内容足够多时,我们将List组件滚动到最下面,会发现底部的内容被导航栏(非安全区域)遮挡了。相似下图展示的界面,实际List组件有101条,但是只展示出来了90条。为了解决这个问题,我们可以给List设置.layoutWeight(1)属性,这样List组件变能够铺满剩余屏幕。 List({ space: 5 }) { ForEach(this.errorList, (item: string) => { ListItem() { Text(item).fontSize(14).fontColor(getRandomColor(1)).width('100%') } }) } .padding({ left: 15, right: 15 }) .scrollBar(BarState.Off) .borderRadius(8).layoutWeight(1)
2025年01月16日
83 阅读
0 评论
0 点赞
2025-01-15
Harmony OS Next实现文件分享
在日常开发过程中,将数据导出到Excel是常见的一种需求。爱车记App有个数据导出功能,可以将用户的充电记录导出Excel,因为Harmony OS Next的沙盒机制,默认导出的文件只能保存到App自己的目录中,为了方便用户保存数据,我们可以通过文件分享功能,用户可以将文件保存到手机的任意位置。一、后端导出Excel文件后端代码我们不做过多介绍,就是使用EasyExcel导出Excel文件并下载。/** * 数据导出 * * @throws IOException IO异常 */ @GetMapping(value = "export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public void export() throws IOException { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletResponse response = null; HttpServletRequest request = null; if (servletRequestAttributes != null) { response = servletRequestAttributes.getResponse(); request = servletRequestAttributes.getRequest(); } if (response == null) { throw new CustomException("未获取到用户信息"); } response.setContentType("application/x-msdownload"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("充电记录.xlsx", "UTF-8")); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); // 创建excel对象 CarUser user = tokenUtil.getLoginUser(request); List<CarEnergyExportVO> carEnergyList4Export = carEnergyService.selectCarEnergyList4Export(user.getId()); //内容样式策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); //垂直居中,水平居中 contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT); contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); contentWriteCellStyle.setBorderTop(BorderStyle.THIN); contentWriteCellStyle.setBorderRight(BorderStyle.THIN); contentWriteCellStyle.setBorderBottom(BorderStyle.THIN); //设置 自动换行 contentWriteCellStyle.setWrapped(true); // 字体策略 WriteFont contentWriteFont = new WriteFont(); // 字体大小 contentWriteFont.setFontHeightInPoints((short) 12); contentWriteFont.setFontName("仿宋"); contentWriteCellStyle.setWriteFont(contentWriteFont); //头策略使用默认 设置字体大小 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); WriteFont headWriteFont = new WriteFont(); headWriteFont.setFontHeightInPoints((short) 12); headWriteFont.setFontName("仿宋"); headWriteCellStyle.setWriteFont(headWriteFont); headWriteCellStyle.setFillForegroundColor(IndexedColors.TAN.getIndex()); ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), CarEnergyExportVO.class) .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle)) .build(); //创建sheet WriteSheet writeSheet = EasyExcel.writerSheet("充电记录").head(CarEnergyExportVO.class).build(); //导出 excelWriter.write(carEnergyList4Export, writeSheet); excelWriter.finish(); }二、下载文件文件下载我们调用downloadFile(context: BaseContext, config: DownloadConfig)方法,context是上下文信息,DownloadConfig是参数信息,其中url是我们的后台地址,filePath是文件保存到本地的路径,header是传递到后端的头部信息,比如我这里的token是传递的认证信息。在下载文件的回调方法中,我们监听downloadTask事件,complete代表文件下载完成,文件下载文成后,调用分装的公共的文件分享方法shareFile对文件进行分享。 IBestToast.show({ icon: $r("app.media.mine_exporting_data"), message: getStringFromResource($r("app.string.exporting")) }) try { // 判断文件是否存在,存在就删除 let context = getContext(this) as common.UIAbilityContext; let filesDir = context.filesDir; let path = filesDir + '/爱车记.xlsx'; if (fs.accessSync(path)) { fs.unlinkSync(path); } request.downloadFile(context, { url: Constants.API + '/common/export', filePath: path, header: { "token": PreferencesUtil.readDataSync<string>("token") } }).then((downloadTask: request.DownloadTask) => { downloadTask.on('complete', () => { IBestToast.hide() shareFile(path) // let file = fs.openSync(filesDir + '/car_expense.xlsx', fs.OpenMode.READ_WRITE); // let arrayBuffer = new ArrayBuffer(1024); // let readLen = fs.readSync(file.fd, arrayBuffer); // let buf = buffer.from(arrayBuffer, 0, readLen); // console.info(`The content of file: ${buf.toString()}`); // fs.closeSync(file); }) }).catch((err: BusinessError) => { IBestToast.hide() console.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`); }); } catch (error) { IBestToast.hide() let err: BusinessError = error as BusinessError; console.error(`Invoke downloadFile failed, code is ${err.code}, message is ${err.message}`); }三、文件分享方法文件分享时,我们传递文件的路径,这里有两个注意事项:action:这个地方我们需要使用ohos.want.action.viewData,如果调用ohos.want.action.sendData,会使用默认的程序打开,比如我这里是Excel文件,如果安装了WPS,会直接调用WPS打开type:这个是MIME Type,比如Excel 2007后续版本(xlsx后缀)默认为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet/** * 分享文件 */ export async function shareFile(filePath: string) { let context = AppStorage.get('context') as common.UIAbilityContext; // 获取文件沙箱路径 // let filePath = this.context.filesDir + '/test.txt'; // 将沙箱路径转换为 URI let uri = fileUri.getUriFromPath(filePath); // 创建分享意图 let want: Want = { flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION, action: 'ohos.want.action.viewData', uri: uri, type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }; // 启动分享 context.startAbility(want) .then(() => { console.log('Share file successfully'); }) .catch((err: BusinessError) => { console.error('Failed to share file:', err); }); }四、配置权限为了实现分享,我们需要在模块下的module.json5文件中配置相应的权限,在skills的uris添加如下内容{ "scheme": "file", "host": "*", "path": "/storage/*" }
2025年01月15日
111 阅读
0 评论
0 点赞
2025-01-12
开源免费的微信视频号下载工具
主要功能一键下载:在视频号页面直接添加下载按钮,无需复制链接或者抓包多画质选择:支持下载不同清晰度的视频,包括原始视频质量图片下载:支持批量下载视频号中的图片内容,自动打包成压缩文件直播回放:支持下载视频号的直播回放内容跨平台支持:同时支持 Windows 和 macOS 系统 使用说明安装过程非常简单,只需要下载对应系统的可执行文件即可使用,不过 Windows 和 macOS 的安装步骤略有不同。Windows安装说明下载 Windows 版本的可执行文件,以管理员身份运行,首次打开会自动安装证书,然后启动服务。当终端提示「服务已正确启动」就说明可以使用了。Mac OS安装说明- 下载 macOS 版本的可执行文件(文件名类似 wx_video_download_drawin_xxx)- 打开终端,进入文件所在目录- 执行以下命令赋予文件执行权限:chmod +x ./wx_video_download_drawin_xxx- 使用管理员权限运行程序sudo ./wx_video_download_drawin_xxx- 请求安装证书权限,同意即可使用说明打开微信PC端,点击需要下载的视频,在视频下方的操作按钮一栏,会多出一个下载按钮,如下所示- 如果没有,可以看看「更多」这里是否有「下载视频」按钮。- 等待视频开始播放,然后暂停视频,点击下载按扭即可下载视频。下载成功后,会在上方显示已下载的文件,下载文件名最后面会标志该视频质量。项目地址{anote icon="fa-download" href="https://github.com/ltaoo/wx_channels_download?tab=readme-ov-file" type="secondary" content="https://github.com/ltaoo/wx_channels_download?tab=readme-ov-file"/}
2025年01月12日
315 阅读
0 评论
1 点赞
1
...
4
5
6
...
52