谈论一些代码实现的逻辑(四)

谈论一些代码实现的逻辑(四)

文章目录

  • 前言
  • 1. 登录功能
  • 2. 悬浮框功能
  • 3. markdown编辑器和富文本编辑器的共同集成
  • 4. 工具库的类别的分类
  • 5. 在flask中引入echarts图表
  • 6. 聊天室的实现
  • 总结


前言

上一篇博客介绍了项目的目录结构,已经有了一点对项目的认识,接下来我将具体简述一些主要功能的代码实现的逻辑(原本我是想具体讲述的,然后发现太多了,于是就挑选几个来将一下实现的逻辑吧)

其余更多代码实现还是直接看源码吧


1. 登录功能

主要分为登录、注册、找回密码

有两个登录的地方,一个是介绍页面、一个是星云笔记页面

前者的前端是用bootstrap的选项卡功能实现的,后者则是加上了模态框。

至于其对应的js代码,我也是放在 /resource/js/login.js 文件中

实现了发送邮件、登录、注册、退出登录的事件

另外,我还添加了接受经度和维度,获取用户的地理位置的代码,及用户每次登录、以及用户注册时会获取(但是,这个功能要支持https服务才能开启,不然会被拦截,不能实现)

2. 悬浮框功能

这是一个小的功能,方便用户的快速跳转到主要功能页面

其主要是依靠css样式和js的鼠标监听事件来完成的

<link rel="stylesheet" href="/css/悬浮框.css"/>
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script><div class="Box_xuanfu"><div class="box_xuanfu"><ion-icon name="apps-sharp"></ion-icon></div><div><a href="/notebook" class="panel" ><ion-icon name="brush"></ion-icon><span class="tooltiptext">笔记</span></a><a href="/person/{{session.get('userid')}}" class="panel" ><ion-icon name="person"></ion-icon></a><a href="/chatroom/index" class="panel" ><ion-icon name="chatbox-ellipses"></ion-icon></a><a href="/home/{{session.get('userid')}}" class="panel" ><ion-icon name="home"></ion-icon></a><a href="/tools" class="panel" ><ion-icon name="construct"></ion-icon></a><a href="#" class="panel" ><ion-icon name="settings"></ion-icon></a></div></div><script src="/js/悬浮框.js"></script>

3. markdown编辑器和富文本编辑器的共同集成

星云笔记是支持使用markdown编辑器和富文本编辑器的共同使用。

而我是如何区分哪些文章是由markdown语法编写,哪些文章是html语法呢。

可以通过在article表中插入一列,来区别,比如我用1表示是markdown,用表示是文本,
然后我可以在提交文章的代码中添加这个判断参数,传给后端处理,

我定义了一个函数,用来区分它们


def is_markdown(articleid):article = Article()result = article.find_is_markdown_by_id(articleid)if result and result.is_markdown == 1:return "md_article"else:return "article"

将返回的值拼接到URL中,就能区别开来

markdown语法写的:
http://www.whtuu.cn/notebook/md_article/41富文本写的:
http://www.whtuu.cn/notebook/article/42

4. 工具库的类别的分类

在工具库的工具分类时,我是通过给每一个类别映射一个数字

# 1代表AI工具、11代表AI工具下的”常用"、12代表AI工具下的”AI图像工具"、13代表AI工具下的”AI聊天工具"、14代表AI工具下的”AI 视频工具"# 2代表生信软件,21、22、23、24# 3代表生信网站,31、32、33、34# 4代表消息获取# 5代表设计美化# 6代表学习网站# 7代表其它

然后在提交工具的时候,将每个类别对应的数字提交到数据库就行

同样我也定义了一个代码用来返回对应的分类名称

# 根据tools_type命名对应的分类信息
def ming_tools_by_type(type):primary_category = ""secondary_category = ""if type.startswith("1"):primary_category = "AI工具"if type == "11":secondary_category = "常用"elif type == "12":secondary_category = "AI图像工具"elif type == "13":secondary_category = "AI聊天工具"elif type == "14":secondary_category = "AI视频工具"elif type.startswith("2"):primary_category = "生信软件"if type == "21":secondary_category = "常用"elif type == "22":secondary_category = "基因相关"elif type == "23":secondary_category = "环境相关"elif type == "24":secondary_category = "其它"elif type.startswith("3"):primary_category = "生信网站"if type == "31":secondary_category = "常用"elif type == "32":secondary_category = "基因相关"elif type == "33":secondary_category = "环境相关"elif type == "34":secondary_category = "其它"elif type.startswith("4"):primary_category = "消息获取"if type == "41":secondary_category = "日常"elif type == "42":secondary_category = "生信相关"elif type == "43":secondary_category = "AI相关"elif type == "44":secondary_category = "古诗词文化"elif type == "5":primary_category = "设计美化"elif type == "6":primary_category = "学习网站"elif type == "7":primary_category = "其他"return primary_category, secondary_category

5. 在flask中引入echarts图表

主要是将从后端获取的数据填充到前端的图表中

大致分为两类:

一类是 返回 xxx.dump_options_with_quotes()


# 用户的文章条形图
@py_echarts.route("/py_echarts/bar-article-user", methods=["POST", "GET"])
def get_bar_chart_user():userid = request.form.get("userid")article = Article()favorite = Favorite()comment = Comment()favorite_count = favorite.query_my_favorite_count(userid)favorited_count = favorite.query_my_article_favorited_count(userid)article_count = article.get_count_user_except_drafted(userid)drafted_count = article.get_count_user_drafted(user_id=userid)comment_count = comment.query_comments_count_by_userid(userid)commented_count = comment.query_comments_count_by_articleid(userid)read_count = article.get_readcount_by_user(userid)recommend_count = article.query_recommend_count_by_user(userid)hide_count = article.query_hide_count_by_user(userid)# 设置条形图的标签和值bar = (Bar().add_xaxis(["收藏数", "被收藏数", "文章数", "草稿数", "评论数", "被评论数", "阅读数", "推荐数", "隐藏数"])  # x轴标签.add_yaxis("用户文章信息",[favorite_count, favorited_count, article_count, drafted_count, comment_count, commented_count,read_count, recommend_count, hide_count], itemstyle_opts=opts.ItemStyleOpts(color="#749f83"))  # y轴值,对应上面的标签)return bar.dump_options_with_quotes()

然后在前端页面的js代码中发送ajax请求给上面定义的接口

 //文章总结的条形图var chart_bar = echarts.init(document.getElementById('bar-article'), 'white', {renderer: 'canvas'});$(function () {fetchData_bar(chart_bar);});function fetchData_bar() {$.ajax({type: "POST",data: {userid: userid},url: "/py_echarts/bar-article-user",dataType: "json",success: function (result) {chart_bar.setOption(result);}});}

另一类则是,使用flask 的render_template() 函数将 生成的嵌入式代码 rendered_chart = c.render_embed(),传给前端;

# 管理后台的用户数据
@py_echarts.route("/person/admin/user")
def admin_user():user = Users()user_at = user.find_by_admin()user_count = user.get_count_all_user()user_locations = user.find_all_users_location()# 在这里执行生成地图的代码from pyecharts import options as opts# 创建 Geo 地图实例c = (Geo(InitOpts(width="1000px", height="1000px")).add_schema(maptype="china")  # 设置地图类型为中国地图)data = []# 遍历 user_locations,添加每个用户的地理位置到地图中for userid, time, lon, lat in user_locations:# 添加坐标点,这里假设每个用户的位置都有一个唯一的名称# 例如,可以使用时间戳或者用户ID作为名称name = useridc.add_coordinate(name, lon, lat)value = str(time)  # 或者其他您想展示的值# 将当前用户的位置和值添加到 data 列表中data.append((name, value))series_name = "用户来源"c.add(series_name, data, type_=ChartType.EFFECT_SCATTER)# 设置系列和全局选项c.set_series_opts(label_opts=opts.LabelOpts(is_show=False))  # 设置标签不显示c.set_global_opts(visualmap_opts=opts.VisualMapOpts(is_show=False),  # 设置视觉映射配置项,比如颜色条title_opts=opts.TitleOpts(title="用户地理位置分布")  # 设置图表标题)# 生成嵌入代码rendered_chart = c.render_embed()return render_template('/shujumianbang/user_admin.html',user_at=user_at, user_count=user_count, chart=rendered_chart)

然后,在前端使用jinji2的语法 {{chart | safe}},将图表插入

<div class="row"><div class="col-md-12"><div class="card"><div class="card-body"><div class="row" style="text-align: center;"><div class="col-6"><div class="d-md-flex align-items-center " style="width:900px"><h2>用户的来源记录</h2></div><div style="width:1600px; height:900px;">{{chart |safe}}</div></div></div></div></div></div></div>

6. 聊天室的实现

要安装flask_socketio ,创建socketio实例

控制台代码:

@chatroom.route("/chatroom/chatroom", methods=['POST', 'GET'])
def chatroom_chatroom():if session.get('islogin') is None:return redirect(url_for('index'))else:user_id = session.get('userid')message = Message()message_result = message.get_messages()# users = Users().find_all_users_all()follow = Follow()user_guanzhu = follow.get_follow_users_with_details(userid=session.get('userid'))avatar = message.get_at_avatar(user_id=user_id)# nickname = session.get('nickname')return render_template("/chatroom/chatroom.html", message_result=message_result, user_guanzhu=user_guanzhu,avatar=avatar)# 连接聊天室
@socketio.on('connect', namespace='/chatroom/chatroom')
def connect():print('连接成功!!')# 加入房间
@socketio.on('joined', namespace='/chatroom/chatroom')
def joined(information):# 'joined'路由是传入一个room_name,给该websocket连接分配房间,返回一个'status'路由room_name = 'chat room'user_name = session.get('nickname')print(user_name)join_room(room_name)emit('status', {'server_to_client': user_name + ' enter the room'}, 'room=room_name')# 接收聊天信息
@socketio.on('text', namespace='/chatroom/chatroom')
def text(information):text = information.get('text')nick_name = session.get('nickname')  # 获取用户名称user_id = session.get('userid')  # 获取用户IDcommunicate_user = request.form.get('communicate_user')Message().insert_message(content=text, communicate_userid=communicate_user)  # 将聊天信息插入数据库,更新数据库create_time = time.strftime('%Y-%m-%d %H:%M:%S')avatar = Message().get_at_avatar(user_id=user_id)  # 获取用户头像# 返回聊天信息给前端emit('message', {'nickname': nick_name,'text': text,'create_time': create_time,'avatar': avatar,})

前后台对接的js代码:

$(document).ready(function () {//创建实例socket = io.connect('https://' + document.domain + ':' + location.port + '/chatroom/chatroom');log('xxqqq', socket)// alert()socket.on('connect', function () {log('连接成功');});socket.on('message', function (data) {Username = data.nicknametext = data.textcreate_time = data.create_timevar avatar_url = data.avatarlog(Username + ':' + text)var deleteButton = "";// if (userid === session.get("userid")) {deleteButton = "<button class='delete-chedi btn btn-outline-success' data-messageid='" + data.message_id + "'>❌</button>";// }if (filepath) {$(".chat-discussion").append("<div class='chat-message left'> <img class='message-avatar' src='/chat_room/images/" + avatar_url + "' alt='' > <div class='message'><a class='message-author' > " + Username + "</a> <span class='message-date'>" + create_time + " </span><span class='message-content'> <img src='" + filepath + "' class='imgchat' style='height: 100px;weight:100px'/>" + text + "</span> " + deleteButton +"</div> </div>");$(".img").attr("src", '');} else {$(".chat-discussion").append("<div class='chat-message left'> <img class='message-avatar' src='/chat_room/images/" + avatar_url + "' alt='' > <div class='message'><a class='message-author' > " + Username + "</a> <span class='message-date'>" + create_time + " </span><span class='message-content'>" + text + "</span>" + deleteButton + "  </div> </div>");}});$('.enter').keypress(function (e) {var code = e.keyCode || e.which;if (code == 13) {//获取聊天框聊天内容var Texttext = $('.enter').val();//清空聊天框$('.enter').val('');//向后端发送聊天内容socket.emit('text', {'text': Texttext});}});$('#Emoji').change(function () {//一:console.log($(this).val());//二:$("#Emoji").val();//获取当前选择项的值.var options = $("#Emoji option:selected");//获取当前选择项.options.val();//获取当前选择项的值.$('.enter').val($('.enter').val() + options.val());console.log(options.val());})});

总结

差不多就到这吧,其实,这个项目感觉并没有达到预期,只能说与我最开始想的样子不太一样,但是不管怎么说,也就先做到这一步了,虽然有些功能还有问题,需要完善。

寂寞空庭春欲晚,梨花满地不开门

–2024-3-22

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查询正在运行的Top SQL的脚本(建议收藏)

这篇文章提供了一些现成的SQL脚本&#xff0c;通过查询V$SQLSTATS视图找到正在运行的TOP SQL&#xff0c;用于后续的优化。建议大家收藏&#xff0c;需要查询TOP SQL时直接复制和粘贴即可。 之前的一篇文章解释了为什么要使用V$SQLSTATS视图。 当数据库表现出各种不同的性能问…

javaSwing推箱子游戏

一、简介 策略性游戏可以锻炼人的思维能力还能缓解人的压力&#xff0c;使人们暂时忘却生活当中的烦恼&#xff0c;增强人们的逻辑思维能力&#xff0c;游戏的艺术美也吸引着越来越多的玩家和厂商&#xff0c;寓教于乐&#xff0c;在放松人们心情的同时还可以活跃双手。在人类…

Docker数据卷与网络模式

华子目录 数据卷注意数据卷操作查看镜像&#xff0c;容器&#xff0c;数据卷所占空间 Docker的网络模式查看指定容器的网络模式bridge模式none模式host模式container模式 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录&#xff0c;它绕过UFS&#xff0c;可以提供很多有…

Open CASCADE学习|显示文本

目录 1、修改代码 Viewer.h&#xff1a; Viewer.cpp&#xff1a; 2、显示文本 OpenCasCade 你好啊 霜吹花落 1、修改代码 在文章《Open CASCADE学习|显示模型》基础上&#xff0c;增加部分代码&#xff0c;实现对文本显示的支持&#xff0c;具体如下&#xff1a; Viewer…

从数据页的角度看 B+ 树

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 大家背八股文的时候&#xff0c;都知道 MySQL 里 InnoDB 存储引擎是采用 B 树来组织数据的。 这点没错&#xff0c;但是大家知道 B 树里的节点里存放的是什么呢&#xff1f;查询数据的过程又是怎样的&am…

Spark 集群管理器

Spark 集群管理器 Spark最主要资源管理方式按排名为Hadoop Yarn, Apache Standalone 和Mesos。在单机使用时&#xff0c;Spark还可以采用最基本的local模式。 目前Apache Spark支持三种分布式部署方式&#xff0c;分别是standalone、spark on mesos和 spark on YARN&#xff…

云安全与云计算的关系

云计算又被称为网格计算&#xff0c;是分布式计算的一种&#xff0c;能够将大量的数据计算处理程序通过网络“云”分解成多个小程序&#xff0c;然后将这些小程序的结果反馈给用户。云计算主要就是能够解决任务分发&#xff0c;并进行计算结果的合并。 云安全则是我国企业创造的…

填补市场空白,Apache TsFile 如何重新定义时序数据管理

欢迎全球开发者参与到 Apache TsFile 项目中。 刚刚过去的 2023 年&#xff0c;国产开源技术再次获得国际认可。 2023 年 11 月 15 日&#xff0c;经全球最大的开源软件基金会 ASF 董事会投票决议&#xff0c;时序数据文件格式 TsFile 正式通过&#xff0c;直接晋升为 Apache T…

【C++从练气到飞升】05---运算符重载

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 ⛳️推荐 一、运算符重载的引用 二、运算符重载 三、赋值运算符重载 1 .赋值运算符重载格式: 2 .赋值运算符只能重载成…

同源策略

浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作DOM&#xff0c;那么会有⼀套基础的安全策略的制约&#xff0c;我们把这称为 同源策略。它的存在可以保护用户隐私信息&#xff0c;防止身份伪造等(读取Cookie) <i…

【智能算法】飞蛾扑火算法(MFO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2015年&#xff0c;Mirjalili等人受到飞蛾受到火焰吸引行为启发&#xff0c;提出了飞蛾算法(Moth-Flame Optimization&#xff0c;MFO)。 2.算法原理 2.1算法思想 MFO基于自然界中飞蛾寻找光源的…

C++测试代码

C测试代码 目录 基于C实现的AOP功能 基于C实现的AOP功能 #include <iostream> #include <string>struct LogHeader {std::string prefix;std::string aspect; };template <typename T> void before(const std::string& msg, const LogHeader& heade…

Qt读取本地系统时间的几种方式

一&#xff0c;使用Windows API函数GetLocalTime&#xff08;精确到毫秒&#xff09; typedef struct _SYSTEMTIME //SYSTEMTIME结构体定义 {   WORD wYear;//年   WORD wMonth;//月   WORD wDayOfWeek;//星期&#xff0c;0为星期日&#xff0c;1为星期一&#xff0c…

2024年华为OD机试真题-考古学家-Java-OD统一考试(C卷)

题目描述: 有一个考古学家发现一个石碑,但是很可惜,发现时其已经断成多段,原地发现n个断口整齐的石碑碎片。为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗? 输入描述: 第一行输入n,n表示石碑碎片的个数。 第二行依次输入石碑碎片上…

PCL ICP配准高阶用法——统计每次迭代的配准误差并可视化

目录 一、概述二、代码实现三、可视化代码四、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 在进行论文写作时,需要做对比实验,来分析改进算法的性能,期间用到了迭代误差分布统计的比较分析,为直…

进一步理解C++里的封装有什么作用

当谈论封装时&#xff0c;我们实际上是在讨论面向对象编程中的一个重要概念&#xff0c;即数据隐藏。封装通过将数据和操作数据的方法捆绑在一起&#xff0c;从而防止外部对象直接访问和修改类的内部数据&#xff0c;以保护数据的完整性和安全性。 用费曼学习法&#xff08;Fe…

leetcode 322.零钱兑换

思路&#xff1a;完全背包。 首先分析问题我们可以知道&#xff0c;这个题的本质就是对于每一个硬币选于不选的问题&#xff0c;也就是所谓的背包问题。而后&#xff0c;这里的每一个硬币都是无限多的&#xff0c;也就是说&#xff0c;这不是01背包或者其他背包问题&#xff0…

Claude 3似乎比GPT-4性能更高,更多的人在尝试使用它

Anthropic 是 OpenAI 的主要竞争对手之一&#xff0c;于 3 月初推出了其最新的大型语言模型 (LLM)&#xff0c;称为 Claude 3。事实证明&#xff0c;Claude 3 的性能优于 OpenAI 的旗舰产品 GPT-4&#xff0c;这让 AI 社区感到惊讶&#xff0c;这标志着 GPT-4 的第一个实例被超…

C++中string容器的元素访问

以string容器为例&#xff0c;容器中元素访问的方式有三种&#xff1a; 1.下标[ ]运算符重载 访问元素 普通对象&#xff1a;char& operator[] (size_t pos) 常对象&#xff1a;const char& operator[] (size_t pos) const string s1("abcdefg"); cout &…

线程的常用方法有哪些?

1、典型回答 线程常用方法有以下这些&#xff1a; start()&#xff1a;启动线程&#xff0c;并调用线程的 run() 方法来执行任务。run()&#xff1a;线程的实际工作方法 (普通方法)&#xff0c;定义线程要执行的任务。sleep(long millis)&#xff1a;暂停当前线程的执行&#…