这套二手物品交易信息管理系统采用当前主流的前后端分离架构,后端基于SpringBoot框架实现RESTful API服务,前端使用Vue.js构建用户界面,数据存储选用MySQL关系型数据库。系统最大的特点是开箱即用——源码经过完整测试,包含必要的环境配置文件,开发者下载后只需简单配置即可启动运行。
我在实际部署测试中发现,这套系统完整实现了二手交易的核心业务流程:从商品发布、浏览搜索、在线沟通到订单生成和支付对接(预留接口),每个环节都考虑到了实际运营需求。特别是后台管理模块,提供了完善的数据统计和用户管理功能,非常适合中小型二手交易平台的快速搭建。
系统后端采用经典的MVC分层架构:
值得注意的几个技术实现细节:
提示:源码中的application.yml已经配置了多环境支持,开发时可以通过
spring.profiles.active参数切换dev/test/prod环境
前端项目采用Vue CLI搭建,主要目录结构说明:
code复制src/
├── api/ # 所有后端接口请求封装
├── assets/ # 静态资源
├── components/ # 公共组件
├── router/ # 路由配置
├── store/ # Vuex状态管理
├── utils/ # 工具函数
└── views/ # 页面组件
关键技术选型:
MySQL数据库主要包含以下核心表:
sql复制CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录账号',
`password` varchar(100) NOT NULL COMMENT '密码',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像URL',
`status` tinyint DEFAULT '1' COMMENT '状态(0-禁用 1-正常)',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
sql复制CREATE TABLE `goods` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '发布用户ID',
`category_id` int NOT NULL COMMENT '分类ID',
`title` varchar(100) NOT NULL COMMENT '商品标题',
`price` decimal(10,2) NOT NULL COMMENT '价格',
`original_price` decimal(10,2) DEFAULT NULL COMMENT '原价',
`description` text COMMENT '商品描述',
`view_count` int DEFAULT '0' COMMENT '浏览数',
`status` tinyint DEFAULT '1' COMMENT '状态(0-下架 1-在售 2-已售出)',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
sql复制CREATE TABLE `order` (
`id` bigint NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL COMMENT '订单编号',
`buyer_id` bigint NOT NULL COMMENT '买家ID',
`seller_id` bigint NOT NULL COMMENT '卖家ID',
`goods_id` bigint NOT NULL COMMENT '商品ID',
`total_amount` decimal(10,2) NOT NULL COMMENT '订单金额',
`payment_status` tinyint DEFAULT '0' COMMENT '支付状态',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_order_no` (`order_no`),
KEY `idx_buyer` (`buyer_id`),
KEY `idx_seller` (`seller_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
后端环境要求:
前端环境要求:
bash复制mysql -u root -p
CREATE DATABASE second_hand DEFAULT CHARACTER SET utf8mb4;
bash复制mysql -u root -p second_hand < db/schema.sql
mysql -u root -p second_hand < db/data.sql
yaml复制# application-dev.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/second_hand?useSSL=false
username: root
password: yourpassword
bash复制mvn clean package
bash复制java -jar target/secondhand-0.0.1-SNAPSHOT.jar
bash复制npm install
bash复制npm run serve
bash复制npm run build
后端Controller关键代码:
java复制@PostMapping("/goods")
@PreAuthorize("hasRole('USER')")
public Result publishGoods(@Valid @RequestBody GoodsDTO goodsDTO,
@RequestHeader("Authorization") String token) {
String username = jwtTokenUtil.getUsernameFromToken(token);
User user = userRepository.findByUsername(username);
Goods goods = new Goods();
BeanUtils.copyProperties(goodsDTO, goods);
goods.setUserId(user.getId());
goods.setStatus(GoodsStatus.ON_SALE);
goodsRepository.save(goods);
return Result.success("发布成功");
}
前端关键实现:
javascript复制// 在Vue组件中处理表单提交
async handleSubmit() {
try {
const formData = new FormData()
formData.append('title', this.form.title)
formData.append('price', this.form.price)
// 其他字段...
const res = await publishGoods(formData)
if (res.code === 200) {
this.$message.success('商品发布成功')
this.$router.push('/my-goods')
}
} catch (error) {
console.error(error)
}
}
Elasticsearch集成配置:
java复制@Configuration
@EnableElasticsearchRepositories
public class ESConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration config = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(config).rest();
}
}
搜索服务实现:
java复制@Service
public class GoodsSearchServiceImpl implements GoodsSearchService {
@Autowired
private ElasticsearchOperations operations;
@Override
public Page<Goods> search(String keyword, Pageable pageable) {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "description"))
.withPageable(pageable)
.build();
return operations.queryForPage(query, Goods.class);
}
}
后端解决方案(SpringBoot配置):
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
前端开发环境代理配置(vue.config.js):
javascript复制module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
SpringBoot默认上传限制为1MB,需要调整配置:
yaml复制spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
同时前端需要检查文件大小:
javascript复制beforeUpload(file) {
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isLt10M) {
this.$message.error('上传文件大小不能超过10MB!');
return false;
}
return true;
}
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
root /path/to/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
bash复制java -Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m -jar your-app.jar
基于这套基础系统,可以考虑以下扩展方向:
java复制@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*");
}
}
java复制@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
private AlipayClient alipayClient;
@Override
public String createPayment(Order order) {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(paymentProperties.getReturnUrl());
request.setNotifyUrl(paymentProperties.getNotifyUrl());
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setOutTradeNo(order.getOrderNo());
model.setTotalAmount(order.getTotalAmount().toString());
model.setSubject("二手商品交易:" + order.getGoods().getTitle());
request.setBizModel(model);
return alipayClient.pageExecute(request).getBody();
}
}
数据统计增强:使用Spring Batch处理每日数据报表
移动端适配:开发基于Uniapp的跨平台移动应用
这套二手交易系统源码在实际测试中表现稳定,特别是权限控制和事务管理做得比较完善。我在本地部署时发现商品图片上传功能需要特别注意路径权限问题,建议在Linux服务器上部署时提前配置好存储目录的读写权限。另外,系统预留了足够的扩展接口,非常适合作为毕业设计或创业项目的基础框架进行二次开发。