欢迎光临
我们一直在努力

基于区块链的商品溯源平台的设计与实现(源码+文档)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、Nodejs、Python、区块链等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文降重、长期答辩答疑辅导、腾讯会议一对一专业讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路。 🍅文末获取源码联系🍅 🍅文末获取源码联系🍅 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 《区块链开发专栏》 《区块链系统学习案例专栏》 ⛺️心若有所向往,何惧道阻且长

项目演示视频:https://www.bilibili.com/video/BV14msbzgEFK/?share_source=copy_web&vd_source=e69b77ddfb8292c5076e23cb71c075d8

一、运行环境与开发工具

1.1 环境要求

  • Java: JDK 1.8 及以上
  • Node.js: v12 及以上
  • 前端开发工具:VSCode
  • 后端开发工具: IntelliJ IDEA 等
  • 区块链平台: FISCO BCOS
  • 中间件: WeBASE-Front

1.2 技术版本

  • Spring Boot: 2.6.13
  • Vue.js: 2.6.14
  • Element UI: 2.15.14
  • Solidity: 0.4.25
  • Maven: 3.6+
  • npm: 6.0+

二、系统功能详解

本系统围绕商品全流程溯源,主要包括以下功能模块:

2.1 核心功能模块

用户管理模块

  • 用户注册: 支持多角色注册(生产商、供应商、零售商)
  • 用户登录: 基于区块链地址的登录验证
  • 角色管理: 智能合约实现角色权限控制
  • 用户注销: 支持撤销用户角色

商品溯源模块

  • 生产信息录入: 生产商添加商品基本信息(溯源码、商品名称、生产时间、生产地址等)
  • 供应信息录入: 供应商添加供应链信息(入库时间、质检情况、物流信息等)
  • 零售信息录入: 零售商添加零售信息(入库时间、发货信息等)
  • 溯源查询: 消费者通过溯源码查询商品完整流转信息

区块链存证模块

  • 链上数据存储: 所有溯源信息写入区块链,确保不可篡改
  • 区块信息查询: 查看每个环节的区块号、交易信息
  • 节点状态监控: 实时查看区块链网络节点状态
  • 系统统计: 查看交易总数、区块总数等统计信息

二维码溯源

  • 二维码生成: 为每个商品生成唯一溯源二维码
  • 扫码查询: 消费者扫描二维码即可查看溯源详情
  • 时间线展示: 图形化展示商品流转全过程

2.2 系统角色

角色代码权限功能
生产商 1 添加商品基本信息 创建溯源码、录入生产信息
供应商 2 添加供应链信息 录入仓储、质检、物流信息
零售商 3 添加零售信息 录入销售、配送信息
消费者 4 查询溯源信息 扫码或输入溯源码查询

三、技术栈

3.1 后端技术栈

Spring Boot 2.6.13 # 后端框架
Maven # 项目构建工具
Lombok # 简化Java代码
HttpClient 4.5.3 # HTTP客户端(与区块链通信)
Swagger2 3.0.0 # API文档生成
HuTool 5.8.11 # Java工具类库

3.2 前端技术栈

Vue.js 2.6.14 # 前端框架
Vue Router 3.5.1 # 路由管理
Vuex 3.6.2 # 状态管理
Element UI 2.15.14 # UI组件库
Axios 1.7.7 # HTTP请求库
QRCode 1.5.4 # 二维码生成
vue-json-pretty 1.9.5 # JSON展示组件

3.3 智能合约技术栈

Solidity 0.4.25 # 智能合约开发语言
FISCO BCOS # 区块链底层平台
WeBASE-Front # 区块链中间件

3.4 系统架构

前端(Vue) <–HTTP–> 后端(Spring Boot) <–HTTP–> WeBASE-Front <–RPC–> FISCO BCOS


四、功能页面展示

在这里插入图片描述 请添加图片描述 请添加图片描述

五、核心代码展示

5.1 智能合约代码

// SPDX-License-Identifier: MIT
pragma experimental ABIEncoderV2;
pragma solidity ^0.4.25;
import "./User.sol";
import "./ProductInfo.sol";

contract ProductTrace is User {
// 溯源码 -> ProductInfo
mapping(string => ProductInfo) productInfos;
string[] public traceCodes;

constructor(
address _producer,
address _supplier,
address _retailer
) public {
// 初始化用户角色
setUser(1, _producer);
setUser(2, _supplier);
setUser(3, _retailer);
}

// 生产商添加商品基本信息
function addProductBaseInfo(
string _traceCode,
string _productName,
string _producer,
uint256 _productionTime,
string _productionAddress
) public onlyProducer onlyValidTraceCode(_traceCode) {
// 创建新的ProductInfo实例
ProductInfo productInfo = new ProductInfo();

// 设置商品基本信息
productInfo.setProductBase(
msg.sender,
_productName,
_producer,
_productionTime,
_productionAddress
);

// 存储产品信息和溯源码
productInfos[_traceCode] = productInfo;
traceCodes.push(_traceCode);
}

// 供应商添加基本信息
function addSupplierInfo(
string _traceCode,
uint256 _storageTime,
string _qualityCheck,
string _shippingUnit,
string _receivingUnit,
string _receivingAddress
) public onlySupplier onlyExistingTraceCode(_traceCode) {
productInfos[_traceCode].setSupplierInfo(
msg.sender,
_storageTime,
_qualityCheck,
_shippingUnit,
_receivingUnit,
_receivingAddress
);
}

// 零售商添加基本信息
function addRetailerInfo(
string _traceCode,
uint256 _storageTime,
string _qualityCheck,
string _shippingUnit,
string _receivingUnit,
string _receivingAddress
) public onlyRetailer onlyExistingTraceCode(_traceCode) {
productInfos[_traceCode].setRetailerInfo(
msg.sender,
_storageTime,
_qualityCheck,
_shippingUnit,
_receivingUnit,
_receivingAddress
);
}

// 获取所有溯源码
function getAllTraceCodes() public view returns (string[]) {
return traceCodes;
}
}

5.2 后端控制器代码

@RestController
@Api(tags = "商品溯源接口")
public class ProductTraceController {
@Autowired
private HttpUtil httpUtil;

/**
* 生产商添加商品基本信息
*/

@PostMapping("/product/baseinfo")
@ApiOperation(value = "生产商添加商品基本信息")
public Result addProductBaseInfo(@RequestBody ProductBaseInfoRequest request) {
String address = AddressContext.getAddress();
httpUtil.sendTransaction(
address,
"addProductBaseInfo",
Arrays.asList(
request.getTraceCode(),
request.getProductName(),
request.getProducer(),
String.valueOf(request.getProductionTime()),
request.getProductionAddress()
)
);
return Result.success();
}

/**
* 获取完整的溯源信息
*/

@GetMapping("/trace/detail/{traceCode}")
@ApiOperation(value = "获取完整的溯源信息")
public Result getDetailTraceInfo(@PathVariable String traceCode) {
JSONObject result = new JSONObject();
result.set("traceCode", traceCode);

// 获取商品基本信息
JSONObject productBaseInfo = getProductBaseInfo(traceCode);
if(productBaseInfo == null){
throw new WeBaseFrontException("未找到该溯源信息");
}
result.set("productBaseInfo", productBaseInfo);

// 获取供应商信息
JSONObject supplierInfo = getSupplierInfo(traceCode);
result.set("supplierInfo", supplierInfo == null ? new JSONObject() : supplierInfo);

// 获取零售商信息
JSONObject retailerInfo = getRetailerInfo(traceCode);
result.set("retailerInfo", retailerInfo == null ? new JSONObject() : retailerInfo);

return Result.success(result);
}

/**
* 获取商品基本信息
*/

private JSONObject getProductBaseInfo(String traceCode) {
JSONArray result = httpUtil.call("getProductBaseInfo", Arrays.asList(traceCode));
if (result.size() == 1) {
return null;
}
JSONObject jsonObj = new JSONObject();
jsonObj.set("producerAddr", result.getStr(0));
jsonObj.set("productName", result.getStr(1));
jsonObj.set("producer", result.getStr(2));
jsonObj.set("productionTime", result.getLong(3));
jsonObj.set("productionAddress", result.getStr(4));
jsonObj.set("blockNumber", result.getLong(5));
jsonObj.set("traceCode", traceCode);
return jsonObj;
}
}

5.3 前端页面代码

<template>
<div class="login-box">
<div class="login-container">
<div class="login-card">
<div class="login-header">
<img src="/logo.png" alt="logo" class="logo">
<h1 class="title">商品溯源平台</h1>
<p class="subtitle">登录账号</p>
</div>

<el-form :model="loginForm" :rules="rules" ref="loginForm" class="login-form">
<el-form-item prop="role" class="form-item">
<el-select v-model="loginForm.role" placeholder="选择用戶角色" class="role-select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>

<el-form-item prop="address" v-if="loginForm.role !== '4'" class="form-item">
<el-input v-model="loginForm.address" placeholder="输入用户地址" class="custom-input">
</el-input>
</el-form-item>

<div class="button-group">
<el-button role="primary" @click="submitForm('loginForm')" class="submit-btn">
登录
</el-button>
<el-button @click="goRegister" class="register-btn">
注册账号
</el-button>
</div>
</el-form>
</div>
</div>
</div>
</template>

<script>
import { localStorageService } from '@/utils/commonUtil';

export default {
name: 'login-view',
data() {
return {
loginForm: {
address: '',
role: ''
},
options: [
{ value: '1', label: '生产商' },
{ value: '2', label: '供应商' },
{ value: '3', label: '零售商' },
{ value: '4', label: '消费者' }
]
};
},
methods: {
async submitForm(formName) {
let { role } = this.loginForm;

// 消费者角色特殊处理
if (role === '4') {
const { data } = await this.$http.get('/getContractOwner');
this.loginForm.address = data.owner;
localStorageService.setItem('userInfo', this.loginForm);
this.$message.success('登录成功');
this.$router.push('/trace');
return;
}

// 其他角色正常登录
this.$refs[formName].validate(async (valid) => {
if (valid) {
const { code, mes } = await this.$http.post('/user/login', this.loginForm);
if (code == 200) {
this.$message.success('登录成功');
localStorageService.setItem('userInfo', this.loginForm);
this.$router.push('/trace');
} else {
this.$message.error(mes);
}
}
});
}
}
};
</script>

赞(0)
未经允许不得转载:171主机测评 » 基于区块链的商品溯源平台的设计与实现(源码+文档)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址