首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,590 阅读
2
Mac打印机设置黑白打印
4,903 阅读
3
修改elementUI中el-table树形结构图标
4,874 阅读
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
篇与
的结果
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日
356 阅读
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日
166 阅读
0 评论
1 点赞
2024-07-31
Mac卸载微信输入法
之前体验了一段时间的微信输入法,各方面使用起来,也没感觉到比系统自带的输入法强在哪,当然只带了一个跨设备复制粘贴功能,但是我基本上也没有这块的需求。微信输入法的口号是:简洁、好用、打字快。但是说实在的,简洁这个确实挺简洁的,但是好用、打字快这两点,确实没体会到,好用这个见仁见智,但是打字快确实没感受到,跟搜狗、百度这些老牌输入法相比,差距还是比较大的。输入法的联想等等体验并不是很好。所以,最近打算卸载掉微信输入法,但是在Mac上卸载微信输入法,却并不像微信输入法描述的一样简洁,使用过搜狗输入法的应该知道,搜狗输入法卸载时,只需要下载搜狗输入法的安装包,它会提供一个卸载的选项,但是微信输入法,你可以尝试一下,它并没有提供卸载功能,如果想卸载微信输入法,会比较麻烦。壹、移除输入法打开输入法管理,找到微信输入法,点击左下角的-,删除掉微信输入法。贰、停用微信输入法的进程在【活动台】,找到【活动监视器】,找到【微信输入法】进程,点击上方的X,结束到微信输入法的进程。叁、删除微信输入法文件点击【访达】,在工具栏依次点击【前往】➡️【前往文件夹】,也可以输入快捷键command+shift+G,输入/Library/Input Methods在打开的文件夹中能看到wetype.app,右键点击,然后点击【移到废纸篓】,在清空回收站就行了。肆、重新添加输入法重新启动Mac,然后重新添加输入法即可。
2024年07月31日
1,138 阅读
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,416 阅读
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日
703 阅读
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日
1,019 阅读
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,308 阅读
0 评论
0 点赞
2024-07-21
typecho借助IndexNow提高bing网站收录速度
{mtitle title="插件使用"/}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日
796 阅读
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日
897 阅读
0 评论
1 点赞
2024-07-19
150款CSS实现的加载中动画
每个里面可能都有多种动画,可以直接运行查看150款CSS实现的加载中动画.zip
2024年07月19日
846 阅读
0 评论
0 点赞
2024-07-17
Vue使用mavon-editor插件实现Markdown文件编辑及预览
因为开发在线知识库系统,因为主要面向研发人员,所以在文档编辑器上,更加倾向于使用markdown,基于vue的markdown编辑器有很多,在经过实际体验后,从易用性、美观性等综合考量,最重选择了mavon-editor。MavonEditor简介MavonEditor是一款基于Vue的Markdown编辑器,它结合了Markdown语法和Typora的实时预览功能,提供了一个所见即所得(WYSIWYG)的编辑体验。MavonEditor不仅支持基本的Markdown语法,还支持LaTeX公式、代码高亮、目录生成、自动目录锚点链接等功能,使其成为撰写技术文档、博客文章等的理想工具。但是MavonEditor也有一个缺点,就是它依赖的highlightjs、katex插件,默认是基于CDN的,当然我们可以改成基于本地的,这个后面再详细介绍。安装插件npm install mavon-editor --save引入因为我涉及在后端编辑,前端预览,所以直接选择了全局引入,编辑main.js// mavonEditor全局注册 import mavonEditor from 'mavon-editor' import 'mavon-editor/dist/css/index.css' Vue.use(mavonEditor)后端编辑页面<mavon-editor ref="md" v-model="form.content" @imgAdd="markdownImageAdd" :toolbars="toolbars" @imgDel="markdownImageDelete" class="content-show" codeStyle="docco" :ishljs="true" :externalLink="externalLink"/>v-model是绑定的内容imgAdd是图片上传后的回调,mavon-editor上传图片后,会转成base64,在回调方法内,我们可以拿到base64编码的图片信息,上传到服务器或OSS后进行存储。imgDel是删除图片后的回调,这里需要注意一点,如果我们是将图片上传到自己服务器,需要有个记录表记录一下,因为在后期编辑文档的时候,工具栏是没有删除图片按钮的,如果我们需要删除图片的话,就需要一个专门维护的地方。toolbars是配置工具栏按钮codeStyle配置代码高亮样式。可选的配色方案可以参考https://hinesboy.github.io/mavonEditor/src/lib/core/hljs/lang.hljs.css.jsishljs是否开启代码高亮。externalLink配置外链应用,如果我们不使用CDN时,需要配置这个data() { return { toolbars: { bold: true, // 粗体 italic: true, // 斜体 header: true, // 标题 underline: true, // 下划线 strikethrough: true, // 中划线 mark: true, // 标记 superscript: true, // 上角标 subscript: true, // 下角标 quote: true, // 引用 ol: true, // 有序列表 ul: true, // 无序列表 link: true, // 链接 imagelink: true, // 图片链接 code: true, // code table: true, // 表格 fullscreen: true, // 全屏编辑 readmodel: false, // 沉浸式阅读 htmlcode: true, // 展示html源码 help: false, // 帮助 /* 1.3.5 */ undo: true, // 上一步 redo: true, // 下一步 trash: true, // 清空 save: false, // 保存(触发events中的save事件) /* 1.4.2 */ navigation: false, // 导航目录 /* 2.1.8 */ alignleft: true, // 左对齐 aligncenter: true, // 居中 alignright: true, // 右对齐 /* 2.2.1 */ subfield: true, // 单双栏模式 preview: true, // 预览 boxShadow: false }, //加载本地资源 externalLink: { markdown_css: function() { // 这是你的markdown css文件路径 return '/markdown/github-markdown.min.css' }, hljs_js: function() { // 这是你的hljs文件路径 return '/highlightjs/highlight.min.js' }, hljs_css: function(css) { // 这是你的代码高亮配色文件路径 return '/highlightjs/styles/' + css + '.min.css' }, hljs_lang: function(lang) { // 这是你的代码高亮语言解析路径 return '/highlightjs/languages/' + lang + '.min.js' }, katex_css: function() { // 这是你的katex配色方案路径路径 return '/katex/katex.min.css' }, katex_js: function() { // 这是你的katex.js路径 return '/katex/katex.min.js' } }, } },methods: { //编辑器图片删除 markdownImageDelete(file) { let filePath = file[0] if (filePath.indexOf(this.baseApi) === 0) { filePath = filePath.replace(this.baseApi, '') } delImage(filePath).then(response => { if (response.code === '200') { this.$modal.msgSuccess('图片删除成功') } }) }, //编辑器插入图片 markdownImageAdd(fileIndex, file) { if (!file.articleId) { file.articleId = this.form.articleId } uploadImage(JSON.stringify(file)).then((res) => { if (res.code === 200) { this.$refs.md.$img2Url(fileIndex, this.baseApi + res.data) this.$modal.msgSuccess('图片上传成功') } else { this.$refs.md.$img2Url(fileIndex, '') } }).catch(() => { this.$refs.md.$img2Url(fileIndex, '') }) } }至此,我们后端编辑功能基本完成了前端预览界面<mavon-editor ref="mavonEditor" :editable="false" v-model="article.content" :defaultOpen="'preview'" :subfield="false" :toolbarsFlag="false" :navigation="true" codeStyle="docco" :ishljs="true" :scroll-style="true" :box-shadow="false" preview-background="#ffffff" :externalLink="externalLink"/>编辑页面相同的属性就不介绍了,介绍一下其他的。editable是否可编辑,因为我们是预览界面,所以设置成不可编辑defaultOpen在单栏(subfield=false)时默认展示区域, edit: 默认展示编辑区域,preview: 默认展示预览区域。subfield单栏还是双栏暂时,true: 双栏(编辑预览同屏), false: 单栏(编辑预览分屏)toolbarsFlag是否显示工具栏navigation是否展示目录scroll-style开启滚动条样式box-shadow开启边框阴影preview-background预览框背景颜色配置本地外链加载如果你想自己引入而不希望mavon-editor加载的话,可以将externalLink设置为false.如果想本地按需加载,你需要安装copy-webpack-plugin插件(npm install copy-webpack-plugin -D) 配置webpack如下所示: (假定webpack配置文件位于项目的/webpack/webpack.js, 而你希望将hljs以及markdown相关文件导出位于项目的/dist/highlightjs以及/dist/markdown目录之下, katex和上面一样)var CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { // ... plugins: [ // ... new CopyWebpackPlugin([{ from: 'node_modules/mavon-editor/dist/highlightjs', to: path.resolve(__dirname, '../dist/highlightjs'), // 插件将会把文件导出于/dist/highlightjs之下 }, { from: 'node_modules/mavon-editor/dist/markdown', to: path.resolve(__dirname, '../dist/markdown'), // 插件将会把文件导出于/dist/markdown之下 }, { from: 'node_modules/mavon-editor/dist/katex', // 插件将会把文件导出 to: path.resolve(__dirname, '../dist/katex') }]), // ... ], // ... }然后你需要给mavon-editor设置externalLink 相关代码如下所示: (假定你的web根目录位于项目的/dist/, 你的网站是www.site.com, 那么 markdown, hljs_js, hljs_css, hljs_lang, katex_css, katex_js返回的是你的网站对应文件位置, 比如www.site.com/markdown/github-markdown.min.css 对应的文件应该位于项目的/dist/markdown/github-markdown.min.css)<template> <div id="app"> <mavon-editor :subfield = "subfield" :code_style="code_style" :ishljs="true" :externalLink="externalLink" ></mavon-editor> </div> </template> <script> export default { data () { return { subfield: true, code_style: 'solarized-dark', externalLink: { markdown_css: function() { // 这是你的markdown css文件路径 return '/markdown/github-markdown.min.css'; }, hljs_js: function() { // 这是你的hljs文件路径 return '/highlightjs/highlight.min.js'; }, hljs_css: function(css) { // 这是你的代码高亮配色文件路径 return '/highlightjs/styles/' + css + '.min.css'; }, hljs_lang: function(lang) { // 这是你的代码高亮语言解析路径 return '/highlightjs/languages/' + lang + '.min.js'; }, katex_css: function() { // 这是你的katex配色方案路径路径 return '/katex/katex.min.css'; }, katex_js: function() { // 这是你的katex.js路径 return '/katex/katex.min.js'; }, } } }, } </script>Notice: 如果你想禁用mavon-editor的自动加载, 可以将externalLink设置为false或externalLink中的某函数值设置为false 如:export default { // ... data() { return { externalLink: false, // 这里只能为`true`/`false`和一个`Object`, 如果为`true`代表全使用外链且自动加载, 如果为`false`则禁用,如果为`Object`则如上所示 } } // ... }或者:export default { // ... data() { return { externalLink: { hljs_css: function(css) { // 这是你的代码高亮配色文件路径 return '/highlightjs/styles/' + css + '.min.css'; }, katex_css: false, // `false`表示禁用自动加载,它也可以是个函数,如果它是个函数,那么这个函数应该返回一个可访问的`katex`的css路径字符串 // 我们没有设置`katex_js`, `hljs_js`, `hljs_lang`, `markdown_css`, `mavon-editor`会认为它的值为`true`,它会默认使用`cdnjs`相关外链加载 }, } } // ... }
2024年07月17日
993 阅读
0 评论
0 点赞
2024-07-06
Sprint Boot接入阿里通义千问
阿里通义千问是阿里巴巴推出的大规模语言模型,由达摩院研发。它是基于先进的自然语言处理技术构建的,旨在提供高质量的文本生成和理解能力。通义千问的特点包括:多语言支持:通义千问能够理解和生成多种语言的文本,包括但不限于中文、英文、日文、法文、西班牙文和德文等,这使得它具有全球化的交流能力。训练数据丰富:它的训练数据来自阿里巴巴内部的大量语言和文本资源,涵盖了文学、历史、科学、艺术等各种主题,旨在提供广泛的知识基础。应用场景广泛:通义千问不仅可以用于日常对话和信息查询,还可以为企业和个人用户提供定制化服务,如行业咨询、文档撰写、智能助手等,帮助用户生成内容或解答问题。与阿里巴巴产品整合:2023年4月,阿里巴巴宣布其所有产品将接入通义千问,这意味着用户可以在钉钉、天猫精灵等平台上直接体验到该模型的服务,企业也可以利用阿里云的能力来定制自己的行业专属大模型。合规性:2023年9月13日,通义千问通过了相关备案并正式对公众开放,表明其在遵守法律法规的前提下提供服务。商业价值:张勇(阿里巴巴集团董事会主席兼CEO)强调了通义千问对于提升阿里巴巴产品和服务的智能化水平,以及帮助企业利用人工智能进行创新。如果你是基于Python或Java开发,那么通义千问支持的SDK还是比较完善的,本文已Spring Boot接入阿里通义千问为例进行说明。壹、申请Key进入阿里云官网,定位到【API-KEY管理】,如果已经有Key的话,可以直接使用,如果没有可以创建一个新的。贰、创建Spring Boot工程具体怎么创建工程就不过多介绍了,现在主要说说创建完之后的配置及开发工作。2.1、添加依赖<dependency> <groupId>com.alibaba</groupId> <artifactId>dashscope-sdk-java</artifactId> <version>2.14.0</version> </dependency>2.2、修改配置文件在配置文件application.yml中添加我们申请到的Key注意替换成你实际的keyqwen: ai-api-key: sk-XXXX2.3、创建配置文件,读取配置信息@Component @ConfigurationProperties(prefix = "qwen") @Data public class QWenConfig { private String aiApiKey; }2.4、创建通义千问的配置文件@Configuration public class AliQWenConfig { @Bean public Generation generation() { return new Generation(); } }2.5、创建请求@RestController @RequestMapping("ai") public class QWenController { @Resource private Generation generation; @Resource private QWenConfig qWenConfig; /** * 测试demo * * @param content 用书输入文本内容 */ @PostMapping(value = "qwen") public String send(@RequestBody String content) throws NoApiKeyException, InputRequiredException { //用户与模型的对话历史。list中的每个元素形式为{“role”:角色, “content”: 内容}。 Message userMessage = Message.builder() .role(Role.USER.getValue()) .content(content) .build(); GenerationParam param = GenerationParam.builder() //指定用于对话的通义千问模型名 .model("qwen-turbo") .messages(Collections.singletonList(userMessage)) // .resultFormat(GenerationParam.ResultFormat.MESSAGE) //生成过程中核采样方法概率阈值,例如,取值为0.8时,仅保留概率加起来大于等于0.8的最可能token的最小集合作为候选集。 // 取值范围为(0,1.0),取值越大,生成的随机性越高;取值越低,生成的确定性越高。 .topP(0.8) //阿里云控制台DASHSCOPE获取的api-key .apiKey(qWenConfig.getAiApiKey()) //启用互联网搜索,模型会将搜索结果作为文本生成过程中的参考信息,但模型会基于其内部逻辑“自行判断”是否使用互联网搜索结果。 .enableSearch(true) .build(); GenerationResult generationResult = generation.call(param); return generationResult.getOutput().getChoices().get(0).getMessage().getContent(); } }叁、测试使用ApiFox测试一下
2024年07月06日
1,121 阅读
0 评论
0 点赞
1
...
5
6
7
...
52