首页
归档
留言
广告合作
友链
美女主播
Search
1
博瑞GE车机升级/降级
5,146 阅读
2
Mac打印机设置黑白打印
4,517 阅读
3
修改elementUI中el-table树形结构图标
4,516 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,351 阅读
5
intelliJ Idea 2022.2.X破解
4,060 阅读
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Spring Cloud
Mac
mybatis
WordPress
Nacos
Spring Cloud Alibaba
Mybatis-Plus
jQuery
Java Script
asp.net
微信小程序
Sentinel
UniApp
MySQL
asp.net core
IntelliJ IDEA
Jpa
树莓派
Laughing
累计撰写
570
篇文章
累计收到
1,424
条评论
首页
栏目
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
广告合作
友链
美女主播
搜索到
570
篇与
的结果
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日
3 阅读
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日
5 阅读
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日
7 阅读
0 评论
0 点赞
2024-12-22
Harmony OS Next封装公共资源访问方法
在Harmony OS Next开发时,对于静态字符串常量,我们都是定义在resources文件夹下的string.json文件中,在日常访问时,通过$r进行访问,如下Text($r("app.string.agree")).fontSize(14)这种方式范围问你资源文件,只适用于有前端上下文的地方,比如我们前端页面或公共的组件中,如果我们在封装的公共方法中或者其他定义API的界面,这种方式是获取不到值的。为了在所有地方都能获取到资源文件的值,我们可以借助应用上下文获取ResourceManager后,调用不同资源管理接口访问不同资源,比如还是上面的资源文件,我们可以通过getContext().resourceManager.getStringSync($r("app.string.agree"))当然,上面这段代码里面还是有应用的上下文信息getContext(),这个上下文不是一直都能取到的,为了便捷获取资源文件,我们可以将上下文信息存储到AppStorage中,这样通过定义一个公共方法,从AppStorage中获取到应用上下文信息即可。一、存储上下文信息在应用启动的时候,我们EntryAbility.ets文件中的onWindowStageCreate方法中,将应用上下文信息存储到AppStorage中。AppStorage.setOrCreate('context', this.context);二、定义获取资源文件的公共方法/** * 获取string中的值 * @param source 资源文件 * @returns 值 */ export function getStringFromResource(source: Resource) { let context = AppStorage.get('context') as common.UIAbilityContext let value = context.resourceManager.getStringSync(source.id) return value }三、使用这样,我们在应用程序的任意位置就能访问资源文件了。getStringFromResource($r("app.string.notify"))
2024年12月22日
134 阅读
1 评论
0 点赞
2024-12-20
Harmony OS Next实现调用系统邮件App发送邮件功能
爱车记App有一个【问题反馈】功能,用户点击此功能后,会自动打开Harmony OS Next自带的邮件功能,并且在收件人里面填充我们的邮箱,邮件内容默认填充请在此处详细描述您遇到的问题,在Harmony OS Next中,我们可以通过want方式打开邮件App并传递对应参数。 /** * 问题反馈 */ feedback() { let ctx = getContext(this) as common.UIAbilityContext; let mailUri: string = 'mailto:收件人?subject=邮件主题&body=邮件内容' let want: Want = { bundleName: 'com.huawei.hmos.email', abilityName: 'EntryAbility', moduleName: 'entry', uri: mailUri, action: 'ohos.want.action.viewData', }; try { ctx.startAbility(want) .then(() => { console.info('startAbility success'); }) .catch((err: BusinessError) => { console.info('startAbility error.', err.message); }) } catch (e) { console.info('error:', e); } }
2024年12月20日
140 阅读
0 评论
1 点赞
2024-07-31
Mac卸载微信输入法
之前体验了一段时间的微信输入法,各方面使用起来,也没感觉到比系统自带的输入法强在哪,当然只带了一个跨设备复制粘贴功能,但是我基本上也没有这块的需求。微信输入法的口号是:简洁、好用、打字快。但是说实在的,简洁这个确实挺简洁的,但是好用、打字快这两点,确实没体会到,好用这个见仁见智,但是打字快确实没感受到,跟搜狗、百度这些老牌输入法相比,差距还是比较大的。输入法的联想等等体验并不是很好。所以,最近打算卸载掉微信输入法,但是在Mac上卸载微信输入法,却并不像微信输入法描述的一样简洁,使用过搜狗输入法的应该知道,搜狗输入法卸载时,只需要下载搜狗输入法的安装包,它会提供一个卸载的选项,但是微信输入法,你可以尝试一下,它并没有提供卸载功能,如果想卸载微信输入法,会比较麻烦。壹、移除输入法打开输入法管理,找到微信输入法,点击左下角的-,删除掉微信输入法。贰、停用微信输入法的进程在【活动台】,找到【活动监视器】,找到【微信输入法】进程,点击上方的X,结束到微信输入法的进程。叁、删除微信输入法文件点击【访达】,在工具栏依次点击【前往】➡️【前往文件夹】,也可以输入快捷键command+shiff+G,输入/Library/Input Methods在打开的文件夹中能看到wetype.app,右键点击,然后点击【移到废纸篓】,在清空回收站就行了。肆、重新添加输入法重新启动Mac,然后重新添加输入法即可。
2024年07月31日
984 阅读
0 评论
0 点赞
2024-07-30
CentOS 7升级openssh 9.8完整过程
CentOS 7自带的openssh版本是1.0.2,版本号很低,最近服务器被公司扫描出来有不少相关的中高危漏洞,所以只能升级到最新版本。壹、安装openssl1.1.1及以上版本因为 OpenSSH 9.8p1 需要 OpenSSL 的版本 >= 1.1.1,所以需要安装 openssl11安装编译 OpenSSL 所需的包,包括 gcc、make、perl 和 zlib-devel。可以通过运行以下命令完成:yum install -y gcc make perl zlib-devel下载 OpenSSL 1.1.1 的源码包,可以从 OpenSSL 官网下载(https://www.openssl.org/source/openssl-1.1.1.tar.gz)或使用以下命令下载:wget https://www.openssl.org/source/openssl-1.1.1.tar.gz解压源码包并进入解压后的目录:tar -zxvf openssl-1.1.1.tar.gz cd openssl-1.1.1 初始化并编译、安装 OpenSSL:./config --prefix=/opt/openssl-1.1.1 make make install添加环境变量vim /etc/profile export PATH=/opt/openssl-1.1.1/bin:$PATH export LD_LIBRARY_PATH=/opt/openssl-1.1.1/lib:$LD_LIBRARY_PATH使配置文件生效source /etc/profile这会在系统中安装新的 OpenSSL 版本。可以通过运行以下命令检查 OpenSSL 版本:openssl version如果输出结果中的版本号为 1.1.1 或更高版本,则说明 OpenSSL 已成功升级。如果还是原来的版本,没变成新版本,可以做软连接使其挂用新版本 ,将原来的openssl,做备份mv /usr/bin/openssl /usr/bin/openssl_20240730bak mv /usr/lib64/openssl /usr/lib64/openssl_20240730bak然后将新安装的OpenSSL做软连接到这个路径ln -s /opt/openssl-1.1.1/bin/openssl /usr/bin/openssl再执行以下命令检查 OpenSSL 版本:openssl version贰、安装openssh可以从Open SSH: 官网 和 GitHub Releases下载,上传到服务器指定位置tar -zxvf openssh-portable-V_9_8_P1.tar.gz进入目录cd openssh-portable-V_9_8_P1 依次执行下面命令进行编译、安装,注意LDFLAGS需要是我们openssl 1.1.1对应的位置./configure --prefix=/usr/local/openssh --sysconfdir=/etc/ssh --with-pam --with-ssl-dir=/opt/openssl-1.1.1 --with-md5-passwords --mandir=/usr/share/man --with-zlib=/usr/local/zlib --without-hardening make make install查看是否安装成功ssh -V如果输出正确的版本,则代表安装正确OpenSSH_9.8p1, OpenSSL 1.1.1 11 Sep 2018复制并修改启动sshd.init脚本# 从源码目录下复制sshd.init到/etc/init.d/ cp contrib/redhat/sshd.init /etc/init.d/ ## 查看并修改SSHD的新路径,将新的openssh安装路径更新 cat /etc/init.d/sshd.init | grep SSHD sed -i "s/SSHD=\/usr\/sbin\/sshd/SSHD=\/usr\/local\/openssh\/sbin\/sshd/g" /etc/init.d/sshd.init cat /etc/init.d/sshd.init | grep SSHD ## 查看并修改ssh-keygen的新路径,将新的ssh-keygen安装路径更新 cat -n /etc/init.d/sshd.init | grep ssh-keygen sed -i "s#/usr/bin/ssh-keygen -A#/usr/local/openssh/bin/ssh-keygen -A#g" /etc/init.d/sshd.init cat -n /etc/init.d/sshd.init | grep ssh-keygen修改配置文件# 开启允许X11转发 echo 'X11Forwarding yes' >> /etc/ssh/sshd_config # 开启允许密码验证 echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config # 允许root登录 echo "PermitRootLogin yes" >> /etc/ssh/sshd_config启动openssh,并设置开机启动# 复制ssh的相关命令 cp -arp /usr/local/openssh/bin/* /usr/bin/ # 启动sshd服务 /etc/init.d/sshd.init # 查看版本 ssh –V # 添加开机启动 chmod +x /etc/rc.d/rc.local echo "/etc/init.d/sshd.init start" >> /etc/rc.d/rc.local
2024年07月30日
1,359 阅读
0 评论
0 点赞
2024-07-30
rpmdb: BDB0113 Thread/process 22476/140186202454080 failed: BDB1507 Thread died in Berkeley DB library
使用yum update或者yum install等命令时,提示rpmdb: BDB0113 Thread/process 22476/140186202454080 failed: BDB1507 Thread died in Berkeley DB library解决方法很简单,输入下面命令mv /var/lib/rpm/__db.00* /tmp/&&yum clean all然后重新执行命令就可以了
2024年07月30日
684 阅读
0 评论
0 点赞
2024-07-29
uniapp组件uni-file-picker中对上传的图片进行压缩
在平时开发时,不管是前端、后端或者小程序端,为了节省带宽及存储空间,我们一般都会对上传的图片进行压缩。本文我们介绍一下使用uniapp开发小程序时,基于uni-file-picker组件进行图片压缩的方法。开启uni-file-picker自带的压缩配置uni-file-picker 组件通过配置 sizeType可以开启自带的压缩功能。sizeType: { type: Array, default () { return ['original', 'compressed'] } },'original'代表原始文件'compressed'代表启用压缩。使用也比较简单,配置一下就行了。<uni-file-picker return-type="object" fileMediatype="image" mode="grid" :sizeType="sizeType" :auto-upload="false" @select="selectImage" @delete="deleteImage"/>通过以上设置,便可实现对图片进行压缩,一般能够实现对半压缩的,比如10M的图片压缩成5M左右这样的。当然这个不是绝对的,只是个约莫的压缩率。如果需要测试,需要使用手机进行真机调试,才可以看出来文件压缩后的大小。如果对图片大小没有太大限制 ,直接这样压缩就可以了,但是有的项目会限制对图片的大小必须小于1M,这时候,光有这个设置,就满足不了需求了,这时候我们可以再采取一点措施。自定义图片压缩当uni-file-picker自带的压缩功能不能满足我们需要时,我们可以自己对图片进行压缩,自定义压缩图片时,我们可以指定压缩率或循环压缩到指定大小。当然,也需要注意压缩后的图片质量。一、创建公共压缩方法创建公共方法imageCompress,传入file进行压缩。// 图片压缩递归,小于1M跳出 export function imageCompress(file){ return new Promise((resolve, reject)=>{ let { size,path } = file let type = path.split(".")[1] //大于1M进行压缩, if(size< (1024*1024)){ resolve(file) return false } uni.compressImage({ src: path, quality: 80, success: res => { let newPath = res.tempFilePath+type let newName = res.tempFilePath.split("/")[res.tempFilePath.split("/").length-1]+type uni.getFileInfo({ filePath:res.tempFilePath, success:async (info)=>{ let newFile = {...file,size:info.size,path:newPath,name:newName,tempFilePath:res.tempFilePath} resolve(await imageCompress(newFile)) } }) } }) }) }二、修改uni-file-picker上传方法在uni-file-picker上传方法时,先调用公共方法imageCompress进行压缩,压缩完成后在进行上传。import { imageCompress } from "@/utils/leeframe.js" import { uploadImageCommon } from "@/common/api.js" export default { data() { return{ sizeType:['compressed'], //设置图片压缩 } }, onLoad(option) { this.workId = option.workId }, methods:{ //选择照片 selectImage(e){ this.timeSeting() if(e.tempFilePaths&&e.tempFiles){ this.file = e.tempFiles[0].file this.type = 'mentou' this.uploadImage() } }, // 删除照片 deleteImage(e){ this.mentouValue = {} }, // 上传照片 async uploadImage(){ // 压缩图片 this.file = await imageCompress(this.file) // 要传的参数 let params = { file:this.file } // 上传图片到相依的接口 uni.uploadFile({ url: uploadImageCommon, //后台上传地址 filePath: this.file.tempFilePath?this.file.tempFilePath:this.file.path, fileType: "image", formData:{...params}, name: 'file', header: { "content-type": "multipart/form-data", "Authorization": uni.getStorageSync('token') }, success: uploadFileRes => { let imageName = JSON.parse(uploadFileRes.data).data // 这里可以对返回的参数进行处理了 uni.showToast({ title: '上传成功', icon: "success" }); }, fail(err) { uni.showToast({ title: '上传失败', icon: "error" }); } }) }, } }
2024年07月29日
969 阅读
0 评论
0 点赞
2024-07-25
吉利汽车App IOS端终于支持小组件了
IOS小组件是一个不用打开App便可快速执行操作的功能,吉利汽车App的小组件功能一直以来呼声也是很高,之前包括领克、吉利博瑞、缤瑞等,也可以通过scriptable的方式间接实现小组件的功能,但是毕竟作为第三方,需要涉及账号、密码,通过scriptable实现小组件的方式也被封禁了。但是吉利汽车App、G-NetLink、GKUI等吉利App都没有提供小组件功能。最近好消息就是,吉利汽车APP终于终于是支持小组件了。如果需要使用小组件,可以将吉利汽车App更新到3.23.0及以上版本。小组件目前提供了两种样式,一种是4*2,一种是2*2,具体的可以看下我下面的截图壹、IOS18安装小组件步骤 在手机桌面的空白区域长按屏幕进入编辑状态 点击左上角的编辑按钮,然后点击添加小组件向下滑动,找到并点击吉利汽车选择一个自己喜欢的大小,点击添加小组件,这样小组件就添加到桌面了。贰、小组件显示内容小组件显示基本信息包括车辆图片、续航里程、车辆状态等信息,车辆状态会根据车门未关、车窗未关等动态显示。大号小组件,根据混动、纯电、燃油车,可以显示续航里程、剩余电量、车辆解锁、寻找车辆、开关空调、车辆通风等信息。电量、油量等会根据剩余情况切换显示颜色。具体可以参考下面图片叁、注意事项需要登录吉利汽车App才能显示车辆信息。需要在吉利汽车App内设置默认车辆,不然小程序会显示【请选择车辆】不支持远程控制的车辆,会显示【当前车辆不支持远程控制】
2024年07月25日
1,170 阅读
0 评论
0 点赞
2024-07-21
typecho借助IndexNow提高bing网站收录速度
插件使用1、下载插件Github:https://github.com/TwoThreeWang/PostToBingIndexNow下载后上传服务器,解压,将目录名改为 PostToBingIndexNow2、进入 typecho 后台,插件页面,启用插件3、设置插件在网站根目录创建 temp_log 目录,用来存放日志文件输入在 Bing 站长平台申请的 key 并保存key申请地址:https://www.bing.com/indexnow注意,请根据 Bing 页面说明步骤进行相关设置除了获取 key,还需要将 key.txt 文本文件下载后上传到你网站的根目录4、测试是否生效发布一篇新文章,查看temp_log目录下的push_bing.log文件,每次发布会记录两行日志,第一行为发送给 API 的body内容,第二行为 API 返回内容,如果返回内容中 code 不是 200,请根据 Bing 站长平台说明进行修改。注意需要配置文件夹权限,不然无法创建文件。另外也可以在站长平台 IndexNow 页面查看是否推送成功
2024年07月21日
769 阅读
0 评论
1 点赞
2024-07-21
提取Html内容生成文章目录
最近在开发一款在线知识库系统,为了方便使用,提供了两种编辑器,一种是基于markdown的,一种是基于富文本的。基于markdown的编辑器,我们使用了MavonEditor插件,同时也是使用该插件进行markdown内容的展示,这个插件自带了目录功能,我们可以直接使用,感兴趣的可以看一下Vue使用mavon-editor插件实现Markdown文件编辑及预览为了保证使用体验的一致性,基于富文本编辑器的内容,我们也给他添加一个目录功能,目录结构的展示我们使用elementUI框架的el-tree组件。template代码template代码比较简单,因为是基于elementUI框架的el-tree组件的,所以需要先安装elementUI。<el-tree class="toc-tree" ref="tree" node-key="uuid" :data="tocTreeData" :props="tocDefaultProps" v-if="tocTreeData && tocTreeData.length>0" default-expand-all> <div class="custom-tree-node" slot-scope="{ node, data }"> <div @click="toDiv(data)">{{ data.text }}</div> </div> </el-tree>data代码其实看到上面template的代码,我们大概能猜测到data里面需要的内容tocTreeData: [], tocDefaultProps: { label: 'text', children: 'children' },tocTreeData是我们存储的目录树形的结构tocDefaultProps是el-tree组件用来配置展示内容及子节点的。js代码getCatalog()是入口方法,当我们在前端完成富文本内容的渲染后,就可以调用此方法,创建目录数据,进行展示。当然,提取目录的层级是根据我们的<h>标签进行提取的,可以自己定义提取的深度,比如我这里提取到了<h6>。toDiv()是点击目录时,用于页面滚动到对应位置的方法。getCatalog() { const h = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] const elements = document.querySelectorAll(h) let hElements = [] for (const key of elements) { if (h.indexOf(key.localName) > -1) { let text if (key.children && key.children.length) { text = this.getText(key.children) } else { text = key.innerHTML } hElements.push({ hLevel: parseInt(key.localName[1]), text, id: key.localName, uuid: key.id, offsetTop: key.offsetTop }) } } this.tocTreeData = this.toTree(hElements) }, getText(arr) { let result = null if (!arr.length) return for (let i = 0; i < arr.length; i++) { if (arr[i].children && arr[i].children.length) { result = this.getText(arr[i].children) } else { result = arr[i].innerHTML } } return result }, toTree(flatArr) { const tree = [] const copyArr = flatArr.map(function(item) { return item }) // 根据指定级别查找该级别的子孙级,并删除掉已经查找到的子孙级 const getChildrenByLevel = function(currentLevelItem, arr, level) { if (!currentLevelItem) { return } // 将level值转成负数,再进行比较 const minusCurrentLevel = -currentLevelItem.hLevel const children = [] let i = 0, len = arr.length for (; i < len; i++) { const levelItem = arr[i] if (-levelItem.hLevel < minusCurrentLevel) { children.push(levelItem) } else { // 只找最近那些子孙级 break } } // 从数组中删除已经找到的那些子孙级,以免影响到其他子孙级的查找 if (children.length > 0) { arr.splice(0, children.length) } return children } const getTree = function(result, arr, level) { // 首先将数组第一位移除掉,并添加到结果集中 let currentItem = arr.shift() currentItem.level = level result.push(currentItem) while (arr.length > 0) { if (!currentItem) { return } // 根据当前级别获取它的子孙级 const children = getChildrenByLevel(currentItem, arr, level) // 如果当前级别没有子孙级则开始下一个 if (children.length === 0) { currentItem = arr.shift() currentItem.level = level if (currentItem) { result.push(currentItem) } continue } currentItem.children = [] // 查找到的子孙级继续查找子孙级 getTree(currentItem.children, children, level + 1) } } getTree(tree, copyArr, 1) return tree }, toDiv(data) { document.getElementById('contentMainId').scrollTop = data.offsetTop - 20 },
2024年07月21日
829 阅读
0 评论
1 点赞
1
2
...
48