news 2026/4/23 15:21:20

第一组 - U-Linker - 第二篇冲刺博客

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第一组 - U-Linker - 第二篇冲刺博客

第一组 - U-Linker - 第二篇冲刺博客

Fifth AssignmentU-Linker
课程EE308FZ - 软件工程
要求Fifth Assignment——Alpha Sprint
目标记录冲刺阶段第3-4天的项目进展、团队协作与问题解决

目录

  • 第一组 - U-Linker - 第二篇冲刺博客
    • I. 项目燃起图
    • II. 模块运行展示
    • III. 重点代码
      • 1. 个人中心(“我的”)
      • 2. 编辑个人信息
      • 3. 积分明细
    • IV. 成员分工 & 提交记录

I. 项目燃起图

截至目前(第4天),项目的整体进度如下:

项目目前剩余工作量为 68%。相比于理想状态下的剩余工作量(约 66.7%),我们的实际进度曲线(红线)略微浮于理想曲线(蓝线)上方。这意味着我们存在极小幅度的任务积压(约 1-2% 的偏差),但整体处于完全可控的范围内。

II. 模块运行展示

我们的UI设计与前端开发组完成了个人中心页面的深度交互,实现了用户头像、昵称及积分数据的实时响应式展示。同时,重点攻克了积分明细的可视化列表渲染,通过动态样式逻辑自动区分“收入”与“支出”的视觉反馈。

我们的后端开发组完成了项目最核心的交易模块开发,实现了“购买服务”与“悬赏任务申请/选人”的复杂业务逻辑,确立了订单状态流转与积分扣除机制。此外,新增了即时通讯模块的API接口,支持创建会话与发送消息,并升级了用户信息接口,实现了头像文件的上传、重命名与存储逻辑,打通了从用户交互到数据库持久化的完整链路。

我们的测试与体验优化组完成了对新上线的交易接口与聊天接口的边界测试,重点验证了积分不足、重复申请任务等异常场景下的系统稳定性。同时,对个人中心进行了前后端联调测试,确保前端修改的信息能准确无误地同步至数据库,且页面加载时的状态回显迅速、准确。

  1. 编辑个人信息
  1. 积分明细

III. 重点代码

1. 个人中心(“我的”)

前端
响应式数据绑定与用户交互
个人中心页面的模板设计充分体现了Vue的数据驱动特性。我们使用多种绑定语法将JavaScript数据与HTML元素无缝连接,当数据变化时,视图会自动更新,无需手动操作DOM。这种设计模式既提升了开发效率,也保证了用户体验的一致性。

<template><!-- 数据绑定 --><h2class="text-xl font-bold text-gray-900 truncate">{{ userInfo.name }}</h2><!-- 条件渲染 --><spanv-if="unreadMessages > 0"class="bg-red-500 text-white text-[10px] px-1.5 rounded-full">{{ unreadMessages }}</span><!-- 事件绑定 --><button@click="handleEditProfile">编辑</button><!-- 动态属性绑定 -->< img :src="userInfo.avatar" alt="用户头像"><!-- 响应式积分显示 --><divclass="text-3xl font-bold font-mono tracking-wider">{{ userInfo.points }}</div></template>

后端
通过 models.py 定义用户结构,并提供 /auth/profile 接口供前端获取当前用户的核心数据(如头像、积分、姓名)。

classUser(db.Model):__tablename__='user'id=db.Column(db.Integer,primary_key=True)username=db.Column(db.String(50),unique=True,nullable=False)name=db.Column(db.String(50))points=db.Column(db.Integer,default=100)# 对应前端显示的积分avatar=db.Column(db.String(200))# 对应前端绑定的 :src# ...defto_dict(self):return{'id':self.id,'username':self.username,'name':self.name,'points':self.points,'avatar':self.avatar}
@auth_bp.route('/profile',methods=['GET'])defget_profile():# 获取 URL 参数 user_iduser_id=request.args.get('user_id')# ...# 在数据库中查找user=db.session.get(User,user_id)ifuser:returnsuccess(data=user.to_dict())# 返回包含 points, avatar 的字典else:returnerror(message="用户不存在")

2. 编辑个人信息

前端
(1)这是Vue最核心的功能,建立了表单输入框和JavaScript数据之间的双向连接。用户输入 → 自动更新数据;数据变化 → 自动更新界面显示。

<!-- 模板部分 --><inputtype="text"v-model="formData.username"<!--核心:双向数据绑定-->@input="validateUsername" ><!-- 数据部分 --><scriptsetup>constformData=reactive({username:'李晓明'// 与v-model建立双向连接})</script>

(2)实现了边输入边验证的体验,用户不需要点击提交按钮就能立即得到反馈。

<inputtype="text"v-model="formData.username"@input="validateUsername"<!--核心:输入时实时触发验证-->>
<scriptsetup>// 核心验证函数constvalidateUsername=()=>{constusername=formData.username.trim()if(username===''){validationErrors.username='用户名不能为空'}elseif(username.length<2){validationErrors.username='用户名至少2个字符'}else{validationErrors.username=''checkUsernameUnique(username)// 触发异步验证}}</script>

(3)自动计算表单是否有效,并智能控制保存按钮状态,用户界面状态完全由数据驱动。

<scriptsetup>// 核心:计算表单验证状态constisFormValid=computed(()=>{returnformData.username.trim()!==''&&!validationErrors.username})</script>
<!-- 使用计算属性 --><button :disabled="!isFormValid"<!-- 核心:自动启用/禁用按钮 -->@click="handleSave" > 保存修改</button>

后端
(1)数据接收与处理 (auth.py):对应前端的双向绑定,后端在 update_profile 接口接收表单数据。虽然前端做了验证,后端依然需要验证用户是否存在。

@auth_bp.route('/update_profile',methods=['POST'])defupdate_profile():# 1. 获取当前用户user_id=request.form.get('user_id')# ...user=db.session.get(User,user_id)ifnotuser:returnerror(message="用户不存在")# 2. 修改普通资料 (对应前端 v-model 绑定的数据)new_name=request.form.get('name')ifnew_name:user.name=new_name# ...

(2)实时验证支持:虽然代码中未展示专门的“检查用户名唯一性”的独立接口,但在注册接口中存在类似的逻辑,可被复用或封装以支持前端的 checkUsernameUnique。

# 逻辑参考:检查重复 (auth.py 中的 register 函数)existing_user=User.query.filter(or_(User.username==username,User.student_id==student_id)).first()ifexisting_user:# 返回错误信息供前端展示ifexisting_user.username==username:returnerror(message="该用户名已经被注册")

(3)保存修改与头像上传 (auth.py):对应前端“保存修改”按钮的点击事件。后端处理文件上传、重命名(防止冲突)以及更新数据库路径。

# ...接 update_profile 函数try:# 3. 处理头像上传 (对应前端文件输入)if'avatar'inrequest.files:file=request.files['avatar']# 检查文件是否存在且格式合法iffileandallowed_file(file.filename):# 为了防止文件名冲突,重命名为: user_id_时间戳.jpgext=file.filename.rsplit('.',1)[1].lower()filename=secure_filename(f"user_{user.id}_{int(datetime.now().timestamp())}.{ext}")# ...保存文件逻辑 (省略路径拼接代码)...file.save(file_path)# 4. 更新数据库里的路径user.avatar=url_for('static',filename=f'avatars/{filename}')db.session.commit()# 提交事务,完成保存returnsuccess(message="个人资料修改成功",data=user.to_dict())# ...

3. 积分明细

前端
(1)通过ref和reactive建立集中式数据源,积分总额与明细记录完全响应式,一处更新处处同步。

<scriptsetup>import{ref,reactive,computed}from'vue'// 核心:积分总额响应式管理consttotalPoints=ref(350)// 核心:积分明细列表响应式数据constpointsRecords=reactive([{id:1,title:'完成任务:数据标注',amount:90,type:'income',icon:'mdi:check-circle-outline',color:'green',date:'2025-11-05 14:30',status:'任务完成'},// ...更多记录])</script>

(2)利用动态CSS类绑定实现收入/支出自动颜色区分,图标、背景、文字颜色完全由数据类型驱动。

<template><!-- 积分记录列表 --><divv-for="record in pointsRecords":key="record.id"class="bg-white p-4 rounded-xl shadow-sm border border-gray-100 flex justify-between items-center"><!-- 图标区域:动态样式绑定 --><divclass="flex items-center gap-3"><div:class="['w-10 h-10 rounded-full flex items-center justify-center', record.type ==='income'?'bg-green-50 text-green-600':'bg-red-50 text-red-500']"><spanclass="iconify w-6 h-6":data-icon="record.icon"></span></div><div><divclass="text-sm font-bold text-gray-800">{{ record.title }}</div><divclass="text-xs text-gray-400 mt-0.5">{{ record.date }}</div></div></div><!-- 金额区域:动态样式绑定 --><divclass="text-right"><div:class="['text-lg font-bold', record.type ==='income'?'text-green-600':'text-red-500']">{{ record.type === 'income' ? '+' : '-' }}{{ record.amount }}</div><divclass="text-[10px] text-gray-400">{{ record.status }}</div></div></div></template>

(3)通过computed属性实现智能数据筛选与实时统计,时间筛选、收入支出分类统计完全自动化计算。

<scriptsetup>// 核心:筛选条件响应式管理constfilterPeriod=ref('month')// 核心:计算属性实现智能筛选constfilteredRecords=computed(()=>{constnow=newDate()constthirtyDaysAgo=newDate(now.setDate(now.getDate()-30))returnpointsRecords.filter(record=>{constrecordDate=newDate(record.date)if(filterPeriod.value==='month'){// 筛选本月记录returnrecordDate.getMonth()===newDate().getMonth()}elseif(filterPeriod.value==='week'){// 筛选本周记录constweekAgo=newDate(now.setDate(now.getDate()-7))returnrecordDate>=weekAgo}returntrue})})// 核心:统计计算consttotalIncome=computed(()=>{returnfilteredRecords.value.filter(record=>record.type==='income').reduce((sum,record)=>sum+record.amount,0)})consttotalExpense=computed(()=>{returnfilteredRecords.value.filter(record=>record.type==='expense').reduce((sum,record)=>sum+record.amount,0)})</script>

后端
(1)数据源定义 (models.py):后端没有独立的积分流水表,而是通过 Order(订单)表来记录交易。前端的“积分记录”对应后端的订单记录。

classOrder(db.Model):__tablename__='orders'# ...buyer_id=db.Column(db.Integer,db.ForeignKey('user.id'),nullable=False)# 买家 (支出方)seller_id=db.Column(db.Integer,db.ForeignKey('user.id'),nullable=False)# 卖家 (收入方)# ...price=db.Column(db.Integer,default=0)# 对应积分金额created_at=db.Column(db.DateTime,default=datetime.now)# 对应时间

(2)获取交易记录 (transaction.py):对应前端的列表渲染。后端查询我参与的所有订单(我是买家或我是卖家),前端根据 buyer_id 或 seller_id 是否为当前用户来判断是 income(收入/绿色)还是 expense(支出/红色)。

@transaction_bp.route('/my_involved',methods=['GET'])defget_my_involved():user_id=request.args.get('user_id')# ...# 核心逻辑: 只要 buyer_id 是我,或者 seller_id 是我,都算我参与的query=Order.query.filter(or_(Order.buyer_id==user_id,Order.seller_id==user_id)).order_by(Order.created_at.desc())# 按时间倒序,对应前端的时间排序# 分页返回,支持前端的滚动加载或分页pagination=query.paginate(page=page,per_page=per_page,error_out=False)returnsuccess(data={'total':pagination.total,# ...'items':[o.to_dict()foroinpagination.items]# 返回数据列表供前端 v-for})

IV. 成员分工 & 提交记录

Student IDName (姓名)Work (工作)Contribution (贡献)
832301330颜一顺Backend Development8.5%
832302227程一鸣Backend Development8.5%
832301320陶炯Backend Development8.5%
832301326曾渝Backend Development8.5%
832302213林语婧Front-end development8.5%
832302230薛易明Front-end development8.5%
832302209陈舒薇Front-end development8.5%
832301123杨璐Front-end development8.5%
832301315高子言Front-end development8.5%
832302225黄祉睿Testing and Optimization8.5%
832302202张健涛UI Design7.5%
832302205陈乐晗UI Design7.5%

提交记录:

GitHub链接

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:28:56

19、移动环境中处理时空查询的动态电压和频率缩放方法

移动环境中处理时空查询的动态电压和频率缩放方法 一、引言 近年来,物联网数据(包括移动性、健康传感信息、蜂窝数据等)的积累显著增加,数据驱动的决策系统也广泛应用于生活的各个方面。这使得云数据中心以及边缘和雾节点越来越受欢迎。同时,随着支持 GPS 的智能设备的普…

作者头像 李华
网站建设 2026/4/23 12:11:32

教程11:使用Android-Studio编译构建--behaviac

原文 Android Studio是一个为Android平台开发程序的集成开发环境&#xff0c;可供开发者免费使用。需要在官网下载并安装最新版的Android Studio&#xff0c;然后继续后文的编译构建。 可以参考源码包中tutorials/tutorial_11的做法类似构建自己的项目&#xff0c;具体步骤如下…

作者头像 李华
网站建设 2026/4/23 13:30:19

B站Linux客户端终极指南:解锁桌面观影新姿势

B站Linux客户端终极指南&#xff1a;解锁桌面观影新姿势 【免费下载链接】bilibili-linux 基于哔哩哔哩官方客户端移植的Linux版本 支持漫游 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-linux 还在为Linux系统上无法畅享B站而烦恼吗&#xff1f;这款专为Lin…

作者头像 李华
网站建设 2026/4/23 12:50:12

Nugget命令行下载工具:简单高效的极简解决方案

Nugget命令行下载工具&#xff1a;简单高效的极简解决方案 【免费下载链接】nugget minimalist wget clone written in node. HTTP GET files and downloads them into the current directory 项目地址: https://gitcode.com/gh_mirrors/nu/nugget 在当今数字化时代&…

作者头像 李华
网站建设 2026/4/23 14:12:55

3步搞定Rustdesk服务器:零基础搭建专属远程控制平台

还在为复杂的远程桌面配置而头疼吗&#xff1f;Rustdesk服务器一键部署方案让你在短短几分钟内拥有完全自主掌控的远程访问系统。这款基于Rust语言开发的高性能解决方案&#xff0c;专为追求简单高效的用户设计&#xff0c;无论是个人远程办公还是企业IT管理&#xff0c;都能轻…

作者头像 李华