image-20240402094632607

软工集市,软工人定义的世界

项目介绍

SSE_MARKET是一个跨校区的学院内部交流平台,主要以论坛的形式为软工师生提供自由交流和信息汇集的半匿名空间,可在上面看帖、搜索、发帖、评论、回复、点赞等,提供宽松、平等的交流氛围,致力于消除学院内部的信息差以及促进数字文化传承。

SSE_MARKET又称软工集市,主要由21级本科生组成的 SSE_MARKET小组负责设计、开发、部署和维护,它脱胎于软件中级实训课,并在学院的支持下逐步发展,现注册加入师生约 800人,学生包括大一到大四本科生以及各级研究生,教师包括行政老师、技术老师到专业老师等。

软工集市成功交接,欢迎新任成员 – SSE_MARKET博客 (ssemarket.cn)

在2024.3.6,软工集市正式完成交接。现在的软工集市由22级和23级本科生组成的新小组负责开发、部署、优化、维护。

官方博客

商城分区项目介绍

在软工集市的不断迭代与扩展中,商城分区作为其核心组件之一,承载着学院内部师生间二手物品交易、闲置资源流转的重任。商城项目采用 Vue.js 构建前端,以 Gin 框架搭建后端服务,形成了一套功能完备、交互流畅且适应多端访问的交易系统。

前端架构与设计

Vue.js 前端由多个精巧设计的界面与组件构成,遵循模块化开发原则,确保代码复用性与维护性:

主界面与商品列表(shopView)

  • 路由驱动动态展示:通过 Vue Router 实现路由参数捕获,传递至后端 API实现“全站商品”与“我的商品”双视图切换。
  • 响应式布局:采用响应式布局设置,自适应不同屏幕尺寸,兼顾PC端和移动端。

商品详情界面(productView)

  • 动态路由参数解析:通过商品卡片的productID获取商品ID,发起 /api/productdetail/${productId} 请求加载详情。

商品发布界面(saleView)

  • 界面设计:saleView 界面采用模块化表单设计,支持商品信息的高效录入与多图上传预览。实时验证机制确保数据准确性,结合优雅的动效与直观的操作引导,优化用户发布体验,确保商品信息精准提交。

组件设计哲学

  • productCard 商品卡片组件:实现可定制化操作按钮(如“收藏”/“私聊”)以及高可复用性。
  • shopSidebar 功能侧边栏:在PC端情况下正常显示,当检测到屏幕大小缩小到手机比例时自动消失,此时出现悬浮球,用悬浮球来控制组件的显示。
  • 悬浮球交互设计:悬浮球固定定位,点击切换图标(“菜单”变“<”),控制侧边栏展开与收起。样式上添加悬停放大效果与阴影增强,提升视觉反馈。侧边栏初始宽度 0%,通过 CSS 过渡动画平滑展开至全屏,优化移动端空间利用率,确保功能可达性。

后端功能实现

Gin 后端以 RESTful API 设计规范为核心,提供稳定高效的服务支撑:

用户认证与授权

  • JWT 认证机制:通过 /api/auth/login 接口实现用户登录,返回 JWT 令牌用于后续请求认证。
  • 权限控制:利用中间件 AuthMiddleware 验证请求中的 JWT 令牌,确保只有认证用户才能访问受保护的接口(如商品发布、删除等)。

商品管理功能

  • 商品发布:通过 /api/auth/postProduct 接口,允许用户提交商品信息(包括名称、描述、价格、图片等),后端验证数据完整性后存储至数据库。
  • 商品列表获取:支持多条件筛选,如 /api/auth/getProducts 接口可根据用户 ID、是否已出售等条件返回商品列表。
  • 商品详情查询:通过 /api/auth/getProductDetail 接口,根据商品 ID 返回详细信息,包括用户信息(若非匿名发布)。
  • 商品状态更新:提供 /api/auth/deleteProduct/api/auth/saleProduct 接口,允许用户标记商品为已删除或已售出。

数据统计与扩展功能

  • 商品数量统计:通过 /api/auth/getProductNum 接口,返回用户已发布商品的总数,用于个人中心数据展示。
  • 轮播图管理:使用 /api/auth/getCarouselImg 接口获取轮播图图片链接列表,支持后台动态更新展示内容。

模型设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package model

import (
"time"
)

type Product struct {
ProductID int `gorm:"primary_key;column:productID"` // 商品主键ID
UserID int `gorm:"index:postuser;column:userID;type:int"` // 发布用户ID,建立索引提高查询效率
User User `gorm:"association_foreignkey:userID;foreignkey:userID"` // 用户关联,便于获取发布者信息
Name string `gorm:"column:product_name;type:varchar(20)"` // 商品名称,限制长度提高存储效率
Description string `gorm:"column:description;type:varchar(500)"` // 商品描述
PostTime time.Time `gorm:"column:post_time;type:datetime"` // 发布时间,用于排序和统计
Photos string `gorm:"column:photos;type:varchar(1000)"` // 图片存储路径,JSON格式字符串
ISSold bool `gorm:"column:is_sold;type:bool"` // 是否已售出标记
Price int `gorm:"column:price;type:int"` // 价格,整数类型简化计算
ISAnonymous bool `gorm:"column:is_anonymous;type:bool"` // 是否匿名发布
ISDelete bool `gorm:"column:is_delete;type:bool"` // 逻辑删除标记,软删除实现
}

路由设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 主商品路由组
{
r.Use(middleware.CORSMiddleware()) // 全局跨域中间件
auth := r.Group("")
noauth := r.Group("")
auth.Use(middleware.AuthMiddleware()) // 认证中间件组

auth.POST("/api/auth/postProduct", controller.PostProduct) // 商品发布接口
auth.POST("/api/auth/getProducts", controller.GetProducts) // 获取商品列表
auth.POST("/api/auth/getProductDetail", controller.GetProductDetail) // 获取商品详情
auth.POST("/api/auth/getProductNum", controller.GetProductNum) // 获取商品数量
auth.POST("/api/auth/deleteProduct", controller.DeleteProduct) // 删除商品
auth.POST("/api/auth/saleProduct", controller.SaleProduct) // 标记商品已售出
auth.POST("/api/auth/getCarouselImg", controller.GetCarouselImg) // 获取轮播图
}

目前该项目已正式上线