更新项目文件结构,统一文档风格
This commit is contained in:
37
backend/database/.env
Normal file
37
backend/database/.env
Normal file
@@ -0,0 +1,37 @@
|
||||
# 服务器配置
|
||||
PORT=8888
|
||||
NODE_ENV=development
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=nj-cdb-3pwh2kz1.sql.tencentcdb.com
|
||||
DB_PORT=20784
|
||||
DB_USER=xymg
|
||||
DB_PASSWORD=aiot741$xymg
|
||||
DB_NAME=xumgdata
|
||||
DB_CHARSET=utf8mb4
|
||||
|
||||
# Redis配置 (待配置)
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET=xlxumu_jwt_secret_key_2024
|
||||
JWT_EXPIRES_IN=24h
|
||||
|
||||
# 腾讯云对象存储配置 (待配置)
|
||||
COS_SECRET_ID=
|
||||
COS_SECRET_KEY=
|
||||
COS_BUCKET=
|
||||
COS_REGION=
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=info
|
||||
LOG_FILE=./logs/app.log
|
||||
|
||||
# 安全配置
|
||||
RATE_LIMIT_MAX=100
|
||||
RATE_LIMIT_WINDOW=15
|
||||
|
||||
# WebSocket配置
|
||||
WS_PORT=8001
|
||||
220
backend/database/DATABASE_SETUP.md
Normal file
220
backend/database/DATABASE_SETUP.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# 数据库配置指南
|
||||
|
||||
## 数据库配置信息
|
||||
|
||||
### 腾讯云MySQL配置
|
||||
- **主机地址**: nj-cdb-3pwh2kz1.sql.tencentcdb.com
|
||||
- **端口**: 20784
|
||||
- **数据库名**: xumgdata
|
||||
- **用户名**: xymg
|
||||
- **密码**: aiot741$xymg
|
||||
|
||||
### 当前状态
|
||||
🔴 **连接状态**: 访问受限(IP白名单问题)
|
||||
📍 **当前IP**: 43.153.101.71(需要添加到白名单)
|
||||
|
||||
## 解决IP白名单问题
|
||||
|
||||
### 步骤1:登录腾讯云控制台
|
||||
1. 访问 [腾讯云控制台](https://console.cloud.tencent.com/)
|
||||
2. 登录账户
|
||||
|
||||
### 步骤2:找到数据库实例
|
||||
1. 进入 **云数据库 MySQL** 控制台
|
||||
2. 找到实例:`nj-cdb-3pwh2kz1`
|
||||
|
||||
### 步骤3:配置安全组/白名单
|
||||
1. 点击实例进入详情页
|
||||
2. 找到 **安全组** 或 **白名单** 设置
|
||||
3. 添加以下IP地址:
|
||||
- `43.153.101.71` (当前开发服务器IP)
|
||||
- `0.0.0.0/0` (临时开放所有IP,生产环境不推荐)
|
||||
|
||||
### 步骤4:验证连接
|
||||
执行以下命令测试连接:
|
||||
```bash
|
||||
cd /Users/ainongkeji/code/vue/xlxumu/backend/database
|
||||
node database-manager.js test
|
||||
```
|
||||
|
||||
## 数据库初始化
|
||||
|
||||
### 一键初始化
|
||||
```bash
|
||||
# 测试连接
|
||||
node database-manager.js test
|
||||
|
||||
# 初始化数据库表结构
|
||||
node database-manager.js init
|
||||
|
||||
# 重置数据库(删除所有数据后重新创建)
|
||||
node database-manager.js reset
|
||||
```
|
||||
|
||||
### 手动初始化
|
||||
如果自动化工具无法使用,可以手动执行SQL脚本:
|
||||
|
||||
1. **连接数据库**:
|
||||
```bash
|
||||
mysql -h nj-cdb-3pwh2kz1.sql.tencentcdb.com -P 20784 -u xymg -p xumgdata
|
||||
```
|
||||
|
||||
2. **执行表结构脚本**:
|
||||
```sql
|
||||
source /Users/ainongkeji/code/vue/xlxumu/backend/database/init_tables.sql;
|
||||
```
|
||||
|
||||
3. **执行初始数据脚本**:
|
||||
```sql
|
||||
source /Users/ainongkeji/code/vue/xlxumu/backend/database/init_data.sql;
|
||||
```
|
||||
|
||||
## 数据库表结构
|
||||
|
||||
### 核心业务表(21张)
|
||||
|
||||
#### 1. 用户权限模块
|
||||
- `users` - 用户表
|
||||
- `roles` - 角色表
|
||||
- `permissions` - 权限表
|
||||
- `user_roles` - 用户角色关联表
|
||||
- `role_permissions` - 角色权限关联表
|
||||
|
||||
#### 2. 牛只档案模块
|
||||
- `cattle` - 牛只档案表
|
||||
- `feeding_records` - 饲养记录表
|
||||
- `breeding_records` - 繁殖记录表
|
||||
|
||||
#### 3. 金融业务模块
|
||||
- `loan_applications` - 贷款申请表
|
||||
- `insurance_applications` - 保险申请表
|
||||
- `claims` - 理赔申请表
|
||||
|
||||
#### 4. 交易管理模块
|
||||
- `transactions` - 交易记录表
|
||||
- `contracts` - 合同表
|
||||
|
||||
#### 5. 政府监管模块
|
||||
- `farms` - 牧场注册表
|
||||
- `government_inspections` - 政府检查记录表
|
||||
- `policies` - 政策法规表
|
||||
|
||||
#### 6. 商城管理模块
|
||||
- `products` - 商品表
|
||||
- `orders` - 订单表
|
||||
- `order_items` - 订单商品表
|
||||
- `product_reviews` - 商品评价表
|
||||
|
||||
#### 7. 质量追溯模块
|
||||
- `product_traceability` - 产品追溯表
|
||||
|
||||
#### 8. 系统管理模块
|
||||
- `operation_logs` - 操作日志表
|
||||
|
||||
## 初始数据说明
|
||||
|
||||
### 默认用户账户
|
||||
| 用户名 | 密码 | 角色 | 姓名 | 描述 |
|
||||
|--------|------|------|------|------|
|
||||
| admin | 123456 | 系统管理员 | 系统管理员 | 拥有所有权限 |
|
||||
| farmer001 | 123456 | 养殖户 | 张三 | 测试养殖户1 |
|
||||
| farmer002 | 123456 | 养殖户 | 李四 | 测试养殖户2 |
|
||||
| banker001 | 123456 | 银行职员 | 王五 | 测试银行职员 |
|
||||
| insurer001 | 123456 | 保险员 | 赵六 | 测试保险员 |
|
||||
| inspector001 | 123456 | 政府检查员 | 钱七 | 测试政府检查员 |
|
||||
| trader001 | 123456 | 交易员 | 孙八 | 测试交易员 |
|
||||
| merchant001 | 123456 | 商户 | 周九 | 测试商户 |
|
||||
|
||||
### 角色权限配置
|
||||
- **管理员**: 拥有所有权限
|
||||
- **养殖户**: 牛只管理、金融申请、交易参与
|
||||
- **银行职员**: 贷款审核和管理
|
||||
- **保险员**: 保险审核和理赔管理
|
||||
- **政府检查员**: 监管检查和质量追溯
|
||||
- **政府管理员**: 监管数据统计和政策管理
|
||||
- **交易员**: 交易和合同管理
|
||||
- **商户**: 商品和订单管理
|
||||
|
||||
### 示例数据
|
||||
- **3个示例牧场**:锡林浩特市第一牧场、东乌旗生态牧场、西乌旗示范牧场
|
||||
- **5头示例牛只**:包含不同品种和基本信息
|
||||
- **5个示例商品**:牛肉、乳制品、肉制品等
|
||||
|
||||
## 验证安装
|
||||
|
||||
### 1. 检查表创建
|
||||
```sql
|
||||
SELECT TABLE_NAME, TABLE_COMMENT
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = 'xumgdata'
|
||||
ORDER BY TABLE_NAME;
|
||||
```
|
||||
|
||||
### 2. 检查数据插入
|
||||
```sql
|
||||
-- 检查角色数量
|
||||
SELECT COUNT(*) as role_count FROM roles;
|
||||
|
||||
-- 检查权限数量
|
||||
SELECT COUNT(*) as permission_count FROM permissions;
|
||||
|
||||
-- 检查用户数量
|
||||
SELECT COUNT(*) as user_count FROM users;
|
||||
|
||||
-- 检查管理员用户
|
||||
SELECT username, real_name, user_type FROM users WHERE user_type = 'admin';
|
||||
```
|
||||
|
||||
### 3. 测试API连接
|
||||
启动API服务器后,访问:
|
||||
```
|
||||
http://localhost:8889/health
|
||||
http://localhost:8889/api/v1/database/status
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见错误
|
||||
|
||||
#### 1. Access denied for user
|
||||
**错误**: `Access denied for user 'xymg'@'43.153.101.71'`
|
||||
**解决**: 检查IP白名单设置
|
||||
|
||||
#### 2. Can't connect to MySQL server
|
||||
**错误**: `Can't connect to MySQL server`
|
||||
**解决**: 检查网络连接和端口访问
|
||||
|
||||
#### 3. Unknown database
|
||||
**错误**: `Unknown database 'xumgdata'`
|
||||
**解决**: 确认数据库名称正确
|
||||
|
||||
#### 4. Table already exists
|
||||
**错误**: `Table 'xxx' already exists`
|
||||
**解决**: 正常情况,使用 `CREATE TABLE IF NOT EXISTS`
|
||||
|
||||
### 联系支持
|
||||
如遇到问题,请检查:
|
||||
1. 网络连接是否正常
|
||||
2. 腾讯云账户状态
|
||||
3. 数据库实例状态
|
||||
4. IP白名单配置
|
||||
|
||||
## 生产环境注意事项
|
||||
|
||||
### 安全配置
|
||||
1. **修改默认密码**: 所有测试账户密码
|
||||
2. **限制IP访问**: 仅允许必要的IP访问
|
||||
3. **启用SSL**: 加密数据传输
|
||||
4. **定期备份**: 设置自动备份策略
|
||||
|
||||
### 性能优化
|
||||
1. **索引优化**: 根据查询模式优化索引
|
||||
2. **分区表**: 对大数据量表进行分区
|
||||
3. **连接池**: 优化数据库连接池配置
|
||||
4. **监控**: 设置性能监控和告警
|
||||
|
||||
### 运维管理
|
||||
1. **日志管理**: 配置慢查询日志
|
||||
2. **权限管理**: 定期审查用户权限
|
||||
3. **版本管理**: 使用数据库迁移工具
|
||||
4. **容灾**: 配置主从复制和故障转移
|
||||
231
backend/database/database-manager.js
Normal file
231
backend/database/database-manager.js
Normal file
@@ -0,0 +1,231 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config();
|
||||
|
||||
// 数据库连接配置
|
||||
const dbConfig = {
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
charset: 'utf8mb4',
|
||||
multipleStatements: true
|
||||
};
|
||||
|
||||
async function initializeDatabase() {
|
||||
let connection = null;
|
||||
|
||||
try {
|
||||
console.log('🔗 正在连接数据库...');
|
||||
console.log(`📍 连接地址: ${dbConfig.host}:${dbConfig.port}`);
|
||||
console.log(`📊 数据库名: ${dbConfig.database}`);
|
||||
|
||||
// 创建数据库连接
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
console.log('✅ 数据库连接成功!');
|
||||
|
||||
// 读取初始化脚本
|
||||
const sqlFilePath = path.join(__dirname, 'init_tables.sql');
|
||||
console.log(`📄 读取SQL脚本: ${sqlFilePath}`);
|
||||
|
||||
if (!fs.existsSync(sqlFilePath)) {
|
||||
throw new Error(`SQL脚本文件不存在: ${sqlFilePath}`);
|
||||
}
|
||||
|
||||
const sqlScript = fs.readFileSync(sqlFilePath, 'utf8');
|
||||
console.log(`📋 SQL脚本大小: ${(sqlScript.length / 1024).toFixed(2)} KB`);
|
||||
|
||||
// 执行初始化脚本
|
||||
console.log('🚀 开始执行数据库初始化...');
|
||||
const [results] = await connection.execute(sqlScript);
|
||||
|
||||
console.log('✅ 数据库初始化完成!');
|
||||
|
||||
// 验证表创建情况
|
||||
console.log('🔍 验证表创建情况...');
|
||||
const [tables] = await connection.execute(
|
||||
'SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME',
|
||||
[dbConfig.database]
|
||||
);
|
||||
|
||||
console.log(`📊 成功创建 ${tables.length} 张表:`);
|
||||
tables.forEach((table, index) => {
|
||||
console.log(` ${index + 1}. ${table.TABLE_NAME} - ${table.TABLE_COMMENT || '无注释'}`);
|
||||
});
|
||||
|
||||
// 检查初始数据
|
||||
console.log('\n🔍 检查初始数据...');
|
||||
|
||||
// 检查角色表
|
||||
const [roles] = await connection.execute('SELECT COUNT(*) as count FROM roles');
|
||||
console.log(`👥 角色数量: ${roles[0].count}`);
|
||||
|
||||
// 检查权限表
|
||||
const [permissions] = await connection.execute('SELECT COUNT(*) as count FROM permissions');
|
||||
console.log(`🔐 权限数量: ${permissions[0].count}`);
|
||||
|
||||
// 检查用户表
|
||||
const [users] = await connection.execute('SELECT COUNT(*) as count FROM users');
|
||||
console.log(`👤 用户数量: ${users[0].count}`);
|
||||
|
||||
if (users[0].count > 0) {
|
||||
const [adminUser] = await connection.execute(
|
||||
'SELECT username, real_name, user_type FROM users WHERE user_type = "admin" LIMIT 1'
|
||||
);
|
||||
if (adminUser.length > 0) {
|
||||
console.log(`🔧 管理员用户: ${adminUser[0].username} (${adminUser[0].real_name})`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎉 数据库初始化成功完成!');
|
||||
console.log('📝 下一步可以启动API服务器进行测试');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 数据库初始化失败:', error.message);
|
||||
|
||||
if (error.code === 'ENOTFOUND') {
|
||||
console.error('🌐 网络连接问题:无法解析数据库主机名');
|
||||
} else if (error.code === 'ER_ACCESS_DENIED_ERROR') {
|
||||
console.error('🔐 认证失败:用户名或密码错误');
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
console.error('🚫 连接被拒绝:数据库服务器可能未运行或端口被封锁');
|
||||
} else if (error.code === 'ER_BAD_DB_ERROR') {
|
||||
console.error('🗃️ 数据库不存在:请先创建目标数据库');
|
||||
} else if (error.message.includes('Access denied')) {
|
||||
console.error('🛡️ IP访问限制:请检查数据库白名单设置');
|
||||
console.error('💡 解决方案:在腾讯云控制台添加当前IP到数据库白名单');
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('🔚 数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 测试数据库连接
|
||||
async function testConnection() {
|
||||
let connection = null;
|
||||
|
||||
try {
|
||||
console.log('🧪 测试数据库连接...');
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
|
||||
const [result] = await connection.execute('SELECT 1 as test, NOW() as current_time');
|
||||
console.log('✅ 连接测试成功!');
|
||||
console.log(`⏰ 数据库时间: ${result[0].current_time}`);
|
||||
|
||||
const [versionResult] = await connection.execute('SELECT VERSION() as version');
|
||||
console.log(`🗄️ MySQL版本: ${versionResult[0].version}`);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ 连接测试失败:', error.message);
|
||||
return false;
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有表(危险操作,仅用于重置)
|
||||
async function dropAllTables() {
|
||||
let connection = null;
|
||||
|
||||
try {
|
||||
console.log('⚠️ 警告:即将删除所有表!');
|
||||
console.log('3秒后开始执行...');
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
|
||||
// 获取所有表
|
||||
const [tables] = await connection.execute(
|
||||
'SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?',
|
||||
[dbConfig.database]
|
||||
);
|
||||
|
||||
if (tables.length === 0) {
|
||||
console.log('📭 数据库中没有表需要删除');
|
||||
return;
|
||||
}
|
||||
|
||||
// 禁用外键检查
|
||||
await connection.execute('SET FOREIGN_KEY_CHECKS = 0');
|
||||
|
||||
// 删除所有表
|
||||
for (const table of tables) {
|
||||
console.log(`🗑️ 删除表: ${table.TABLE_NAME}`);
|
||||
await connection.execute(`DROP TABLE IF EXISTS \`${table.TABLE_NAME}\``);
|
||||
}
|
||||
|
||||
// 启用外键检查
|
||||
await connection.execute('SET FOREIGN_KEY_CHECKS = 1');
|
||||
|
||||
console.log('✅ 所有表已删除');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 删除表失败:', error.message);
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
const command = process.argv[2];
|
||||
|
||||
switch (command) {
|
||||
case 'test':
|
||||
await testConnection();
|
||||
break;
|
||||
case 'init':
|
||||
await initializeDatabase();
|
||||
break;
|
||||
case 'reset':
|
||||
console.log('⚠️ 确认要重置数据库吗?这将删除所有数据!');
|
||||
console.log('如果确认,请在5秒内按Ctrl+C取消,否则将继续执行...');
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
await dropAllTables();
|
||||
await initializeDatabase();
|
||||
break;
|
||||
default:
|
||||
console.log('🔧 锡林郭勒盟智慧养殖平台 - 数据库管理工具');
|
||||
console.log('');
|
||||
console.log('使用方法:');
|
||||
console.log(' node database-manager.js test - 测试数据库连接');
|
||||
console.log(' node database-manager.js init - 初始化数据库表');
|
||||
console.log(' node database-manager.js reset - 重置数据库(删除所有表后重新创建)');
|
||||
console.log('');
|
||||
console.log('环境变量配置:');
|
||||
console.log(` DB_HOST: ${process.env.DB_HOST || '未设置'}`);
|
||||
console.log(` DB_PORT: ${process.env.DB_PORT || '未设置'}`);
|
||||
console.log(` DB_USER: ${process.env.DB_USER || '未设置'}`);
|
||||
console.log(` DB_NAME: ${process.env.DB_NAME || '未设置'}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 优雅处理进程退出
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n👋 程序被用户中断');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error('❌ 未处理的Promise拒绝:', reason);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// 运行主函数
|
||||
main().catch(error => {
|
||||
console.error('❌ 程序执行失败:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
232
backend/database/init_data.sql
Normal file
232
backend/database/init_data.sql
Normal file
@@ -0,0 +1,232 @@
|
||||
-- ======================================
|
||||
-- 锡林郭勒盟智慧养殖产业平台 - 初始数据脚本
|
||||
-- ======================================
|
||||
|
||||
-- 清理现有数据(可选)
|
||||
-- DELETE FROM user_roles;
|
||||
-- DELETE FROM role_permissions;
|
||||
-- DELETE FROM users WHERE id > 1;
|
||||
|
||||
-- ======================================
|
||||
-- 1. 角色和权限初始化
|
||||
-- ======================================
|
||||
|
||||
-- 插入角色数据
|
||||
INSERT IGNORE INTO `roles` (`name`, `description`) VALUES
|
||||
('admin', '系统管理员 - 拥有所有权限'),
|
||||
('farmer', '养殖户 - 管理自己的牛只和交易'),
|
||||
('banker', '银行职员 - 处理贷款申请'),
|
||||
('insurer', '保险员 - 处理保险和理赔'),
|
||||
('government_inspector', '政府检查员 - 进行合规检查'),
|
||||
('government_admin', '政府管理员 - 查看监管数据'),
|
||||
('trader', '交易员 - 处理交易业务'),
|
||||
('merchant', '商户 - 管理商城商品');
|
||||
|
||||
-- 插入权限数据
|
||||
INSERT IGNORE INTO `permissions` (`name`, `description`, `module`) VALUES
|
||||
-- 用户管理权限
|
||||
('user_view', '查看用户信息', 'user'),
|
||||
('user_create', '创建用户', 'user'),
|
||||
('user_edit', '编辑用户信息', 'user'),
|
||||
('user_delete', '删除用户', 'user'),
|
||||
('user_manage', '用户管理(包含所有用户操作)', 'user'),
|
||||
|
||||
-- 牛只管理权限
|
||||
('cattle_view', '查看牛只信息', 'cattle'),
|
||||
('cattle_create', '创建牛只档案', 'cattle'),
|
||||
('cattle_edit', '编辑牛只信息', 'cattle'),
|
||||
('cattle_delete', '删除牛只档案', 'cattle'),
|
||||
('cattle_manage', '牛只管理(包含所有牛只操作)', 'cattle'),
|
||||
|
||||
-- 金融服务权限
|
||||
('loan_view', '查看贷款信息', 'finance'),
|
||||
('loan_create', '创建贷款申请', 'finance'),
|
||||
('loan_review', '审核贷款申请', 'finance'),
|
||||
('loan_manage', '贷款管理', 'finance'),
|
||||
('insurance_view', '查看保险信息', 'finance'),
|
||||
('insurance_create', '创建保险申请', 'finance'),
|
||||
('insurance_review', '审核保险申请', 'finance'),
|
||||
('insurance_manage', '保险管理', 'finance'),
|
||||
|
||||
-- 交易管理权限
|
||||
('transaction_view', '查看交易信息', 'trading'),
|
||||
('transaction_create', '创建交易记录', 'trading'),
|
||||
('transaction_manage', '交易管理', 'trading'),
|
||||
('contract_view', '查看合同信息', 'trading'),
|
||||
('contract_create', '创建合同', 'trading'),
|
||||
('contract_manage', '合同管理', 'trading'),
|
||||
|
||||
-- 政府监管权限
|
||||
('government_supervision', '政府监管权限', 'government'),
|
||||
('government_inspection', '政府检查权限', 'government'),
|
||||
('government_statistics', '政府统计权限', 'government'),
|
||||
('government_report', '政府报告权限', 'government'),
|
||||
('quality_trace', '质量追溯权限', 'government'),
|
||||
('policy_view', '查看政策法规', 'government'),
|
||||
('policy_manage', '管理政策法规', 'government'),
|
||||
|
||||
-- 商城管理权限
|
||||
('product_view', '查看商品信息', 'mall'),
|
||||
('product_create', '创建商品', 'mall'),
|
||||
('product_edit', '编辑商品信息', 'mall'),
|
||||
('product_delete', '删除商品', 'mall'),
|
||||
('product_manage', '商品管理', 'mall'),
|
||||
('order_view', '查看订单信息', 'mall'),
|
||||
('order_manage', '订单管理', 'mall'),
|
||||
('mall_statistics', '商城统计', 'mall'),
|
||||
|
||||
-- 系统管理权限
|
||||
('system_config', '系统配置', 'system'),
|
||||
('data_view', '数据查看', 'system'),
|
||||
('data_export', '数据导出', 'system'),
|
||||
('log_view', '日志查看', 'system');
|
||||
|
||||
-- ======================================
|
||||
-- 2. 角色权限分配
|
||||
-- ======================================
|
||||
|
||||
-- 管理员角色 - 拥有所有权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p WHERE r.name = 'admin';
|
||||
|
||||
-- 养殖户角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'farmer' AND p.name IN (
|
||||
'cattle_view', 'cattle_create', 'cattle_edit', 'cattle_manage',
|
||||
'loan_view', 'loan_create', 'insurance_view', 'insurance_create',
|
||||
'transaction_view', 'transaction_create', 'contract_view',
|
||||
'product_view', 'order_view', 'data_view'
|
||||
);
|
||||
|
||||
-- 银行职员角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'banker' AND p.name IN (
|
||||
'loan_view', 'loan_review', 'loan_manage',
|
||||
'cattle_view', 'user_view', 'data_view'
|
||||
);
|
||||
|
||||
-- 保险员角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'insurer' AND p.name IN (
|
||||
'insurance_view', 'insurance_review', 'insurance_manage',
|
||||
'cattle_view', 'user_view', 'data_view'
|
||||
);
|
||||
|
||||
-- 政府检查员角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'government_inspector' AND p.name IN (
|
||||
'government_supervision', 'government_inspection', 'quality_trace',
|
||||
'cattle_view', 'user_view', 'policy_view', 'data_view'
|
||||
);
|
||||
|
||||
-- 政府管理员角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'government_admin' AND p.name IN (
|
||||
'government_supervision', 'government_statistics', 'government_report',
|
||||
'policy_view', 'policy_manage', 'quality_trace',
|
||||
'cattle_view', 'user_view', 'data_view', 'data_export'
|
||||
);
|
||||
|
||||
-- 交易员角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'trader' AND p.name IN (
|
||||
'transaction_view', 'transaction_create', 'transaction_manage',
|
||||
'contract_view', 'contract_create', 'contract_manage',
|
||||
'cattle_view', 'user_view', 'data_view'
|
||||
);
|
||||
|
||||
-- 商户角色权限
|
||||
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||
SELECT r.id, p.id FROM `roles` r, `permissions` p
|
||||
WHERE r.name = 'merchant' AND p.name IN (
|
||||
'product_view', 'product_create', 'product_edit', 'product_manage',
|
||||
'order_view', 'order_manage', 'mall_statistics',
|
||||
'data_view'
|
||||
);
|
||||
|
||||
-- ======================================
|
||||
-- 3. 测试用户数据
|
||||
-- ======================================
|
||||
|
||||
-- 创建测试用户(密码都是:123456)
|
||||
INSERT IGNORE INTO `users` (`username`, `email`, `phone`, `password_hash`, `real_name`, `user_type`, `status`) VALUES
|
||||
('admin', 'admin@xlxumu.com', '13900000001', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '系统管理员', 'admin', 1),
|
||||
('farmer001', 'farmer001@example.com', '13900000002', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '张三', 'farmer', 1),
|
||||
('farmer002', 'farmer002@example.com', '13900000003', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '李四', 'farmer', 1),
|
||||
('banker001', 'banker001@example.com', '13900000004', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '王五', 'banker', 1),
|
||||
('insurer001', 'insurer001@example.com', '13900000005', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '赵六', 'insurer', 1),
|
||||
('inspector001', 'inspector001@example.com', '13900000006', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '钱七', 'government', 1),
|
||||
('trader001', 'trader001@example.com', '13900000007', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '孙八', 'trader', 1),
|
||||
('merchant001', 'merchant001@example.com', '13900000008', '$2b$10$N9qo8uLOickgx2ZMRZoMye1VrVCjhAhLOEI8aSqJZmL4Q9DQKqWV.', '周九', 'trader', 1);
|
||||
|
||||
-- 分配用户角色
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'admin' AND r.name = 'admin';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'farmer001' AND r.name = 'farmer';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'farmer002' AND r.name = 'farmer';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'banker001' AND r.name = 'banker';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'insurer001' AND r.name = 'insurer';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'inspector001' AND r.name = 'government_inspector';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'trader001' AND r.name = 'trader';
|
||||
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`)
|
||||
SELECT u.id, r.id FROM `users` u, `roles` r
|
||||
WHERE u.username = 'merchant001' AND r.name = 'merchant';
|
||||
|
||||
-- ======================================
|
||||
-- 4. 示例牧场数据
|
||||
-- ======================================
|
||||
|
||||
INSERT IGNORE INTO `farms` (`farm_name`, `registration_number`, `owner_id`, `legal_representative`, `contact_phone`, `contact_email`, `address`, `region`, `farm_area`, `cattle_capacity`, `current_cattle_count`, `registration_date`, `license_number`, `license_expiry_date`, `status`, `compliance_status`) VALUES
|
||||
('锡林浩特市第一牧场', 'REG2024001', 2, '张三', '13900000002', 'farm001@example.com', '锡林浩特市郊区草原路123号', '锡林浩特市', 150.5, 300, 240, '2023-06-15', 'LIC2023001', '2025-06-15', 'active', 'compliant'),
|
||||
('东乌旗生态牧场', 'REG2024002', 3, '李四', '13900000003', 'farm002@example.com', '东乌旗珠恩嘎达布其镇', '东乌旗', 200.8, 400, 320, '2023-08-20', 'LIC2023002', '2025-08-20', 'active', 'compliant'),
|
||||
('西乌旗示范牧场', 'REG2024003', 2, '张三', '13900000002', 'farm003@example.com', '西乌旗巴拉嘎尔高勒镇', '西乌旗', 300.2, 500, 450, '2023-05-10', 'LIC2023003', '2025-05-10', 'active', 'compliant');
|
||||
|
||||
-- ======================================
|
||||
-- 5. 示例牛只数据
|
||||
-- ======================================
|
||||
|
||||
INSERT IGNORE INTO `cattle` (`ear_tag`, `name`, `breed`, `gender`, `birth_date`, `color`, `weight`, `health_status`, `owner_id`, `farm_location`, `status`) VALUES
|
||||
('C001', '小黄', '西门塔尔牛', 'female', '2022-03-15', '黄色', 450.5, 'healthy', 2, '锡林浩特市第一牧场', 'active'),
|
||||
('C002', '大力', '安格斯牛', 'male', '2021-11-20', '黑色', 620.8, 'healthy', 2, '锡林浩特市第一牧场', 'active'),
|
||||
('C003', '花花', '夏洛莱牛', 'female', '2022-07-08', '白色', 380.2, 'healthy', 3, '东乌旗生态牧场', 'active'),
|
||||
('C004', '壮壮', '利木赞牛', 'male', '2021-09-12', '金黄色', 580.0, 'healthy', 3, '东乌旗生态牧场', 'active'),
|
||||
('C005', '美美', '西门塔尔牛', 'female', '2022-12-25', '棕色', 420.3, 'healthy', 2, '西乌旗示范牧场', 'active');
|
||||
|
||||
-- ======================================
|
||||
-- 6. 示例商品数据
|
||||
-- ======================================
|
||||
|
||||
INSERT IGNORE INTO `products` (`name`, `sku`, `category`, `description`, `price`, `original_price`, `stock`, `weight`, `origin`, `brand`, `seller_id`, `status`, `featured`, `rating`, `review_count`) VALUES
|
||||
('优质牛肉礼盒装', 'BEEF001', 'beef', '来自锡林浩特优质牧场的新鲜牛肉,肉质鲜美,营养丰富', 268.00, 298.00, 45, 2.000, '锡林浩特市第一牧场', '草原优品', 2, 'active', 1, 4.8, 56),
|
||||
('有机牛奶', 'DAIRY001', 'dairy', '纯天然有机牛奶,无添加剂,营养价值高', 35.00, 35.00, 120, 1.000, '东乌旗生态牧场', '草原乳业', 3, 'active', 1, 4.6, 32),
|
||||
('草原牛肉干', 'SNACK001', 'snacks', '传统工艺制作的牛肉干,口感醇香,营养丰富', 68.00, 78.00, 88, 0.500, '西乌旗牧场', '草原食品', 8, 'active', 0, 4.9, 78),
|
||||
('精选牛排', 'BEEF002', 'beef', '精选优质牛排,适合煎烤,肉质鲜嫩', 158.00, 168.00, 25, 1.500, '锡林浩特市第一牧场', '草原优品', 2, 'active', 1, 4.7, 43),
|
||||
('酸奶', 'DAIRY002', 'dairy', '传统发酵工艺制作的酸奶,口感醇厚', 25.00, 25.00, 200, 0.500, '东乌旗生态牧场', '草原乳业', 3, 'active', 0, 4.5, 67);
|
||||
|
||||
SELECT '初始数据插入完成!' AS message;
|
||||
614
backend/database/init_tables.sql
Normal file
614
backend/database/init_tables.sql
Normal file
@@ -0,0 +1,614 @@
|
||||
-- ======================================
|
||||
-- 锡林郭勒盟智慧养殖产业平台 - 数据库初始化脚本
|
||||
-- ======================================
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ======================================
|
||||
-- 1. 用户权限相关表
|
||||
-- ======================================
|
||||
|
||||
-- 用户表
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
|
||||
`username` VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名(用于登录)',
|
||||
`email` VARCHAR(100) UNIQUE COMMENT '邮箱(用于通知和找回密码)',
|
||||
`phone` VARCHAR(20) UNIQUE COMMENT '手机号(实名认证用)',
|
||||
`password_hash` VARCHAR(255) NOT NULL COMMENT '密码哈希值(BCrypt加密)',
|
||||
`real_name` VARCHAR(50) COMMENT '真实姓名(需与身份证一致)',
|
||||
`avatar_url` VARCHAR(255) COMMENT '头像URL(OSS存储路径)',
|
||||
`user_type` ENUM('farmer', 'banker', 'insurer', 'government', 'trader', 'admin') NOT NULL COMMENT '用户类型:牧民/银行职员/保险员/政府人员/交易员/管理员',
|
||||
`status` TINYINT DEFAULT 1 COMMENT '状态: 1-正常, 0-禁用(禁用用户无法登录)',
|
||||
`last_login` TIMESTAMP NULL COMMENT '最后登录时间(用于活跃度分析)',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(不可修改)',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间(自动维护)',
|
||||
INDEX `idx_username` (`username`),
|
||||
INDEX `idx_email` (`email`),
|
||||
INDEX `idx_phone` (`phone`),
|
||||
INDEX `idx_user_type` (`user_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
|
||||
|
||||
-- 角色表
|
||||
CREATE TABLE IF NOT EXISTS `roles` (
|
||||
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '角色ID',
|
||||
`name` VARCHAR(50) NOT NULL UNIQUE COMMENT '角色名称',
|
||||
`description` TEXT COMMENT '角色描述',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
|
||||
|
||||
-- 用户角色关联表
|
||||
CREATE TABLE IF NOT EXISTS `user_roles` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`role_id` INT UNSIGNED NOT NULL COMMENT '角色ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE,
|
||||
UNIQUE KEY `uk_user_role` (`user_id`, `role_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';
|
||||
|
||||
-- 权限表
|
||||
CREATE TABLE IF NOT EXISTS `permissions` (
|
||||
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '权限ID',
|
||||
`name` VARCHAR(100) NOT NULL UNIQUE COMMENT '权限名称',
|
||||
`description` TEXT COMMENT '权限描述',
|
||||
`module` VARCHAR(50) COMMENT '所属模块',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表';
|
||||
|
||||
-- 角色权限关联表
|
||||
CREATE TABLE IF NOT EXISTS `role_permissions` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||
`role_id` INT UNSIGNED NOT NULL COMMENT '角色ID',
|
||||
`permission_id` INT UNSIGNED NOT NULL COMMENT '权限ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`) ON DELETE CASCADE,
|
||||
UNIQUE KEY `uk_role_permission` (`role_id`, `permission_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表';
|
||||
|
||||
-- ======================================
|
||||
-- 2. 牛只档案相关表
|
||||
-- ======================================
|
||||
|
||||
-- 牛只档案表
|
||||
CREATE TABLE IF NOT EXISTS `cattle` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '牛只ID',
|
||||
`ear_tag` VARCHAR(50) NOT NULL UNIQUE COMMENT '耳标号',
|
||||
`name` VARCHAR(50) COMMENT '名称',
|
||||
`breed` VARCHAR(50) COMMENT '品种',
|
||||
`gender` ENUM('male', 'female') COMMENT '性别',
|
||||
`birth_date` DATE COMMENT '出生日期',
|
||||
`color` VARCHAR(30) COMMENT '毛色',
|
||||
`weight` DECIMAL(5,2) COMMENT '体重(kg)',
|
||||
`health_status` ENUM('healthy', 'sick', 'quarantine', 'dead') DEFAULT 'healthy' COMMENT '健康状况',
|
||||
`owner_id` BIGINT UNSIGNED COMMENT '所有者ID(牧民)',
|
||||
`farm_location` VARCHAR(255) COMMENT '牧场位置',
|
||||
`status` ENUM('active', 'sold', 'dead', 'quarantine') DEFAULT 'active' COMMENT '状态',
|
||||
`image_url` VARCHAR(255) COMMENT '图片URL',
|
||||
`qr_code_url` VARCHAR(255) COMMENT '二维码URL',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`owner_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_ear_tag` (`ear_tag`),
|
||||
INDEX `idx_owner` (`owner_id`),
|
||||
INDEX `idx_breed` (`breed`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牛只档案表';
|
||||
|
||||
-- 饲养记录表
|
||||
CREATE TABLE IF NOT EXISTS `feeding_records` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '记录ID',
|
||||
`cattle_id` BIGINT UNSIGNED NOT NULL COMMENT '牛只ID',
|
||||
`record_type` ENUM('feed', 'vaccine', 'treatment', 'checkup') NOT NULL COMMENT '记录类型: 饲料, 疫苗, 治疗, 检查',
|
||||
`feed_type` VARCHAR(100) COMMENT '饲料类型',
|
||||
`feed_amount` DECIMAL(6,2) COMMENT '饲料量(kg)',
|
||||
`vaccine_name` VARCHAR(100) COMMENT '疫苗名称',
|
||||
`treatment_desc` TEXT COMMENT '治疗描述',
|
||||
`medicine_name` VARCHAR(100) COMMENT '药品名称',
|
||||
`dosage` VARCHAR(100) COMMENT '用量',
|
||||
`veterinarian` VARCHAR(50) COMMENT '兽医',
|
||||
`cost` DECIMAL(10,2) COMMENT '费用',
|
||||
`record_date` DATE NOT NULL COMMENT '记录日期',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`operator_id` BIGINT UNSIGNED COMMENT '操作员ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`cattle_id`) REFERENCES `cattle`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`operator_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_cattle_date` (`cattle_id`, `record_date`),
|
||||
INDEX `idx_record_type` (`record_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='饲养记录表';
|
||||
|
||||
-- 繁殖记录表
|
||||
CREATE TABLE IF NOT EXISTS `breeding_records` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '记录ID',
|
||||
`cattle_id` BIGINT UNSIGNED NOT NULL COMMENT '母牛ID',
|
||||
`breeding_method` ENUM('natural', 'artificial') NOT NULL COMMENT '配种方式',
|
||||
`breeding_date` DATE NOT NULL COMMENT '配种日期',
|
||||
`breeding_male_id` BIGINT UNSIGNED COMMENT '公牛ID',
|
||||
`semen_code` VARCHAR(50) COMMENT '冻精编号',
|
||||
`expected_delivery_date` DATE COMMENT '预产期',
|
||||
`actual_delivery_date` DATE COMMENT '实际产犊日期',
|
||||
`calf_count` TINYINT DEFAULT 1 COMMENT '产犊数',
|
||||
`calf_ids` JSON COMMENT '犊牛IDs',
|
||||
`breeding_result` ENUM('success', 'failed', 'pending') DEFAULT 'pending' COMMENT '配种结果',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`operator_id` BIGINT UNSIGNED COMMENT '操作员ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`cattle_id`) REFERENCES `cattle`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`breeding_male_id`) REFERENCES `cattle`(`id`) ON DELETE SET NULL,
|
||||
FOREIGN KEY (`operator_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_cattle_date` (`cattle_id`, `breeding_date`),
|
||||
INDEX `idx_result` (`breeding_result`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='繁殖记录表';
|
||||
|
||||
-- ======================================
|
||||
-- 3. 金融业务相关表
|
||||
-- ======================================
|
||||
|
||||
-- 贷款申请表
|
||||
CREATE TABLE IF NOT EXISTS `loan_applications` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '贷款申请ID',
|
||||
`applicant_id` BIGINT UNSIGNED NOT NULL COMMENT '申请人ID',
|
||||
`loan_type` ENUM('cattle', 'farm', 'equipment', 'operating') NOT NULL COMMENT '贷款类型',
|
||||
`cattle_ids` JSON COMMENT '质押牛只IDs',
|
||||
`loan_amount` DECIMAL(15,2) NOT NULL COMMENT '贷款金额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`interest_rate` DECIMAL(5,4) COMMENT '利率',
|
||||
`term_months` INT COMMENT '期限(月)',
|
||||
`purpose` TEXT COMMENT '用途',
|
||||
`repayment_method` ENUM('equal_principal', 'equal_payment', 'bullet') COMMENT '还款方式',
|
||||
`guarantee_type` ENUM('cattle_pledge', 'guarantor', 'insurance', 'credit') COMMENT '担保方式',
|
||||
`status` ENUM('submitted', 'under_review', 'approved', 'rejected', 'disbursed', 'completed', 'overdue') DEFAULT 'submitted' COMMENT '状态',
|
||||
`reviewer_id` BIGINT UNSIGNED COMMENT '审核人ID',
|
||||
`review_notes` TEXT COMMENT '审核备注',
|
||||
`approved_amount` DECIMAL(15,2) COMMENT '批准金额',
|
||||
`approved_date` TIMESTAMP NULL COMMENT '批准日期',
|
||||
`disbursement_date` TIMESTAMP NULL COMMENT '放款日期',
|
||||
`repayment_schedule` JSON COMMENT '还款计划',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`applicant_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`reviewer_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_applicant` (`applicant_id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_type` (`loan_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='贷款申请表';
|
||||
|
||||
-- 保险申请表
|
||||
CREATE TABLE IF NOT EXISTS `insurance_applications` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '保险申请ID',
|
||||
`applicant_id` BIGINT UNSIGNED NOT NULL COMMENT '申请人ID',
|
||||
`insurance_type` ENUM('cattle_death', 'cattle_health', 'cattle_theft', 'property') NOT NULL COMMENT '保险类型',
|
||||
`cattle_ids` JSON COMMENT '保险牛只IDs',
|
||||
`policy_number` VARCHAR(50) UNIQUE COMMENT '保单号',
|
||||
`insured_amount` DECIMAL(15,2) COMMENT '保险金额',
|
||||
`premium` DECIMAL(12,2) COMMENT '保费',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`start_date` DATE COMMENT '起保日期',
|
||||
`end_date` DATE COMMENT '终保日期',
|
||||
`status` ENUM('applied', 'underwriting', 'issued', 'active', 'expired', 'cancelled', 'claiming', 'settled') DEFAULT 'applied' COMMENT '状态',
|
||||
`underwriter_id` BIGINT UNSIGNED COMMENT '核保人ID',
|
||||
`underwriting_notes` TEXT COMMENT '核保备注',
|
||||
`policy_file_url` VARCHAR(255) COMMENT '保单文件URL',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`applicant_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`underwriter_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_applicant` (`applicant_id`),
|
||||
INDEX `idx_policy_number` (`policy_number`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='保险申请表';
|
||||
|
||||
-- 理赔申请表
|
||||
CREATE TABLE IF NOT EXISTS `claims` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '理赔申请ID',
|
||||
`insurance_id` BIGINT UNSIGNED NOT NULL COMMENT '保险ID',
|
||||
`applicant_id` BIGINT UNSIGNED NOT NULL COMMENT '申请人ID',
|
||||
`claim_amount` DECIMAL(12,2) NOT NULL COMMENT '理赔金额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`incident_date` DATE NOT NULL COMMENT '事故日期',
|
||||
`incident_type` ENUM('death', 'illness', 'accident', 'theft') NOT NULL COMMENT '事故类型',
|
||||
`description` TEXT COMMENT '事故描述',
|
||||
`evidence_files` JSON COMMENT '证据文件URL列表',
|
||||
`status` ENUM('submitted', 'under_review', 'approved', 'rejected', 'paid') DEFAULT 'submitted' COMMENT '状态',
|
||||
`reviewer_id` BIGINT UNSIGNED COMMENT '审核人ID',
|
||||
`review_notes` TEXT COMMENT '审核备注',
|
||||
`approved_amount` DECIMAL(12,2) COMMENT '批准金额',
|
||||
`paid_amount` DECIMAL(12,2) COMMENT '赔付金额',
|
||||
`submitted_at` TIMESTAMP NULL COMMENT '提交时间',
|
||||
`reviewed_at` TIMESTAMP NULL COMMENT '审核时间',
|
||||
`approved_at` TIMESTAMP NULL COMMENT '批准时间',
|
||||
`paid_at` TIMESTAMP NULL COMMENT '赔付时间',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`insurance_id`) REFERENCES `insurance_applications`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`applicant_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`reviewer_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_insurance` (`insurance_id`),
|
||||
INDEX `idx_applicant` (`applicant_id`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='理赔申请表';
|
||||
|
||||
-- ======================================
|
||||
-- 4. 交易管理相关表
|
||||
-- ======================================
|
||||
|
||||
-- 交易记录表
|
||||
CREATE TABLE IF NOT EXISTS `transactions` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '交易ID',
|
||||
`transaction_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '交易编号',
|
||||
`transaction_type` ENUM('cattle_sale', 'feed_purchase', 'equipment_sale', 'service') NOT NULL COMMENT '交易类型',
|
||||
`buyer_id` BIGINT UNSIGNED NOT NULL COMMENT '买方ID',
|
||||
`seller_id` BIGINT UNSIGNED NOT NULL COMMENT '卖方ID',
|
||||
`cattle_ids` JSON COMMENT '交易牛只IDs',
|
||||
`product_name` VARCHAR(200) COMMENT '商品名称',
|
||||
`quantity` DECIMAL(10,2) COMMENT '数量',
|
||||
`unit` VARCHAR(20) COMMENT '单位',
|
||||
`unit_price` DECIMAL(12,2) COMMENT '单价',
|
||||
`total_amount` DECIMAL(15,2) NOT NULL COMMENT '总金额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`payment_method` ENUM('cash', 'bank_transfer', 'installment', 'check') COMMENT '付款方式',
|
||||
`payment_status` ENUM('pending', 'paid', 'partial', 'overdue') DEFAULT 'pending' COMMENT '付款状态',
|
||||
`delivery_method` ENUM('pickup', 'delivery', 'installation') COMMENT '交付方式',
|
||||
`delivery_address` TEXT COMMENT '交付地址',
|
||||
`delivery_date` TIMESTAMP NULL COMMENT '交付日期',
|
||||
`delivery_status` ENUM('pending', 'in_transit', 'delivered', 'cancelled') DEFAULT 'pending' COMMENT '交付状态',
|
||||
`status` ENUM('pending', 'confirmed', 'in_progress', 'completed', 'cancelled', 'refunded') DEFAULT 'pending' COMMENT '交易状态',
|
||||
`contract_id` BIGINT UNSIGNED COMMENT '合同ID',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`buyer_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`seller_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_transaction_number` (`transaction_number`),
|
||||
INDEX `idx_buyer` (`buyer_id`),
|
||||
INDEX `idx_seller` (`seller_id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_type` (`transaction_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易记录表';
|
||||
|
||||
-- 合同表
|
||||
CREATE TABLE IF NOT EXISTS `contracts` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '合同ID',
|
||||
`contract_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '合同编号',
|
||||
`contract_type` ENUM('cattle_sale', 'feed_supply', 'equipment_purchase', 'service') NOT NULL COMMENT '合同类型',
|
||||
`party_a_id` BIGINT UNSIGNED NOT NULL COMMENT '甲方ID',
|
||||
`party_b_id` BIGINT UNSIGNED NOT NULL COMMENT '乙方ID',
|
||||
`contract_amount` DECIMAL(15,2) NOT NULL COMMENT '合同金额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`signing_date` DATE COMMENT '签订日期',
|
||||
`effective_date` DATE COMMENT '生效日期',
|
||||
`expiry_date` DATE COMMENT '到期日期',
|
||||
`payment_terms` TEXT COMMENT '付款条款',
|
||||
`delivery_terms` TEXT COMMENT '交付条款',
|
||||
`status` ENUM('draft', 'active', 'completed', 'cancelled', 'expired') DEFAULT 'draft' COMMENT '合同状态',
|
||||
`contract_content` LONGTEXT COMMENT '合同内容',
|
||||
`contract_url` VARCHAR(255) COMMENT '合同文件URL',
|
||||
`digital_signature_a` TEXT COMMENT '甲方数字签名',
|
||||
`digital_signature_b` TEXT COMMENT '乙方数字签名',
|
||||
`witness_id` BIGINT UNSIGNED COMMENT '见证人ID',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`party_a_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`party_b_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
FOREIGN KEY (`witness_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_contract_number` (`contract_number`),
|
||||
INDEX `idx_party_a` (`party_a_id`),
|
||||
INDEX `idx_party_b` (`party_b_id`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合同表';
|
||||
|
||||
-- ======================================
|
||||
-- 5. 政府监管相关表
|
||||
-- ======================================
|
||||
|
||||
-- 牧场注册表
|
||||
CREATE TABLE IF NOT EXISTS `farms` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '牧场ID',
|
||||
`farm_name` VARCHAR(100) NOT NULL COMMENT '牧场名称',
|
||||
`registration_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '注册编号',
|
||||
`owner_id` BIGINT UNSIGNED NOT NULL COMMENT '所有者ID',
|
||||
`legal_representative` VARCHAR(50) COMMENT '法定代表人',
|
||||
`contact_phone` VARCHAR(20) COMMENT '联系电话',
|
||||
`contact_email` VARCHAR(100) COMMENT '联系邮箱',
|
||||
`address` TEXT COMMENT '详细地址',
|
||||
`region` VARCHAR(50) COMMENT '所属区域',
|
||||
`coordinates` POINT COMMENT '经纬度坐标',
|
||||
`farm_area` DECIMAL(10,2) COMMENT '牧场面积(亩)',
|
||||
`cattle_capacity` INT COMMENT '牲畜容量',
|
||||
`current_cattle_count` INT DEFAULT 0 COMMENT '当前牲畜数量',
|
||||
`registration_date` DATE COMMENT '注册日期',
|
||||
`license_number` VARCHAR(50) COMMENT '许可证号',
|
||||
`license_expiry_date` DATE COMMENT '许可证到期日期',
|
||||
`status` ENUM('active', 'inactive', 'suspended', 'cancelled') DEFAULT 'active' COMMENT '状态',
|
||||
`compliance_status` ENUM('compliant', 'warning', 'violation', 'pending') DEFAULT 'pending' COMMENT '合规状态',
|
||||
`last_inspection_date` DATE COMMENT '最后检查日期',
|
||||
`next_inspection_date` DATE COMMENT '下次检查日期',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`owner_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_registration_number` (`registration_number`),
|
||||
INDEX `idx_owner` (`owner_id`),
|
||||
INDEX `idx_region` (`region`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牧场注册表';
|
||||
|
||||
-- 政府检查记录表
|
||||
CREATE TABLE IF NOT EXISTS `government_inspections` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '检查记录ID',
|
||||
`farm_id` BIGINT UNSIGNED NOT NULL COMMENT '牧场ID',
|
||||
`inspector_id` BIGINT UNSIGNED NOT NULL COMMENT '检查员ID',
|
||||
`inspection_type` ENUM('routine', 'follow_up', 'complaint', 'emergency') NOT NULL COMMENT '检查类型',
|
||||
`inspection_date` DATE NOT NULL COMMENT '检查日期',
|
||||
`inspection_scope` JSON COMMENT '检查范围',
|
||||
`checklist` JSON COMMENT '检查清单',
|
||||
`score` DECIMAL(5,2) COMMENT '检查评分',
|
||||
`result` ENUM('passed', 'conditional_pass', 'failed') COMMENT '检查结果',
|
||||
`violations` JSON COMMENT '违规事项',
|
||||
`improvements` JSON COMMENT '改进建议',
|
||||
`corrective_actions` JSON COMMENT '整改要求',
|
||||
`next_inspection_date` DATE COMMENT '下次检查日期',
|
||||
`report_file_url` VARCHAR(255) COMMENT '检查报告文件URL',
|
||||
`photos` JSON COMMENT '检查照片URLs',
|
||||
`inspector_notes` TEXT COMMENT '检查员备注',
|
||||
`farm_response` TEXT COMMENT '牧场回应',
|
||||
`status` ENUM('completed', 'pending_correction', 'follow_up_required') DEFAULT 'completed' COMMENT '状态',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`farm_id`) REFERENCES `farms`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`inspector_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_farm_date` (`farm_id`, `inspection_date`),
|
||||
INDEX `idx_inspector` (`inspector_id`),
|
||||
INDEX `idx_result` (`result`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政府检查记录表';
|
||||
|
||||
-- 政策法规表
|
||||
CREATE TABLE IF NOT EXISTS `policies` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '政策ID',
|
||||
`title` VARCHAR(200) NOT NULL COMMENT '政策标题',
|
||||
`policy_number` VARCHAR(50) UNIQUE COMMENT '政策编号',
|
||||
`category` ENUM('regulation', 'support_policy', 'subsidy', 'standard', 'guideline') NOT NULL COMMENT '政策类别',
|
||||
`authority` VARCHAR(100) COMMENT '发布机关',
|
||||
`content_summary` TEXT COMMENT '内容摘要',
|
||||
`content_detail` LONGTEXT COMMENT '详细内容',
|
||||
`document_url` VARCHAR(255) COMMENT '文档URL',
|
||||
`publish_date` DATE COMMENT '发布日期',
|
||||
`effective_date` DATE COMMENT '生效日期',
|
||||
`expiry_date` DATE COMMENT '失效日期',
|
||||
`status` ENUM('draft', 'active', 'expired', 'repealed') DEFAULT 'draft' COMMENT '状态',
|
||||
`target_audience` JSON COMMENT '适用对象',
|
||||
`keywords` VARCHAR(500) COMMENT '关键词',
|
||||
`created_by` BIGINT UNSIGNED COMMENT '创建人ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_policy_number` (`policy_number`),
|
||||
INDEX `idx_category` (`category`),
|
||||
INDEX `idx_status` (`status`),
|
||||
FULLTEXT `idx_keywords` (`title`, `content_summary`, `keywords`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政策法规表';
|
||||
|
||||
-- ======================================
|
||||
-- 6. 商城相关表
|
||||
-- ======================================
|
||||
|
||||
-- 商品表
|
||||
CREATE TABLE IF NOT EXISTS `products` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '商品ID',
|
||||
`name` VARCHAR(200) NOT NULL COMMENT '商品名称',
|
||||
`sku` VARCHAR(50) UNIQUE COMMENT '商品SKU',
|
||||
`category` ENUM('beef', 'dairy', 'snacks', 'processed', 'equipment', 'feed', 'other') NOT NULL COMMENT '商品类别',
|
||||
`subcategory` VARCHAR(50) COMMENT '子类别',
|
||||
`description` TEXT COMMENT '商品描述',
|
||||
`price` DECIMAL(10,2) NOT NULL COMMENT '价格',
|
||||
`original_price` DECIMAL(10,2) COMMENT '原价',
|
||||
`cost_price` DECIMAL(10,2) COMMENT '成本价',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`stock` INT DEFAULT 0 COMMENT '库存数量',
|
||||
`sales_count` INT DEFAULT 0 COMMENT '销售数量',
|
||||
`weight` DECIMAL(8,3) COMMENT '重量(kg)',
|
||||
`dimensions` VARCHAR(100) COMMENT '尺寸',
|
||||
`shelf_life` INT COMMENT '保质期(天)',
|
||||
`storage_conditions` VARCHAR(200) COMMENT '储存条件',
|
||||
`origin` VARCHAR(100) COMMENT '产地',
|
||||
`brand` VARCHAR(100) COMMENT '品牌',
|
||||
`specifications` JSON COMMENT '规格参数',
|
||||
`images` JSON COMMENT '商品图片URLs',
|
||||
`video_url` VARCHAR(255) COMMENT '视频URL',
|
||||
`seller_id` BIGINT UNSIGNED NOT NULL COMMENT '卖家ID',
|
||||
`status` ENUM('active', 'inactive', 'out_of_stock', 'pending_review', 'rejected') DEFAULT 'pending_review' COMMENT '状态',
|
||||
`featured` TINYINT DEFAULT 0 COMMENT '是否推荐',
|
||||
`rating` DECIMAL(3,2) DEFAULT 0 COMMENT '评分',
|
||||
`review_count` INT DEFAULT 0 COMMENT '评价数量',
|
||||
`seo_title` VARCHAR(200) COMMENT 'SEO标题',
|
||||
`seo_description` TEXT COMMENT 'SEO描述',
|
||||
`seo_keywords` VARCHAR(500) COMMENT 'SEO关键词',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`seller_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_sku` (`sku`),
|
||||
INDEX `idx_category` (`category`),
|
||||
INDEX `idx_seller` (`seller_id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_featured` (`featured`),
|
||||
FULLTEXT `idx_search` (`name`, `description`, `seo_keywords`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
|
||||
|
||||
-- 订单表
|
||||
CREATE TABLE IF NOT EXISTS `orders` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
|
||||
`order_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '订单号',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`order_type` ENUM('normal', 'group_buy', 'presale', 'custom') DEFAULT 'normal' COMMENT '订单类型',
|
||||
`total_amount` DECIMAL(12,2) NOT NULL COMMENT '商品总金额',
|
||||
`discount_amount` DECIMAL(12,2) DEFAULT 0 COMMENT '优惠金额',
|
||||
`shipping_fee` DECIMAL(10,2) DEFAULT 0 COMMENT '运费',
|
||||
`tax_amount` DECIMAL(10,2) DEFAULT 0 COMMENT '税费',
|
||||
`final_amount` DECIMAL(12,2) NOT NULL COMMENT '最终金额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`payment_method` ENUM('wechat_pay', 'alipay', 'bank_transfer', 'cash_on_delivery') COMMENT '支付方式',
|
||||
`payment_status` ENUM('pending', 'paid', 'partial', 'refunded', 'failed') DEFAULT 'pending' COMMENT '支付状态',
|
||||
`shipping_method` ENUM('express', 'self_pickup', 'same_city') COMMENT '配送方式',
|
||||
`shipping_address` TEXT COMMENT '收货地址',
|
||||
`shipping_name` VARCHAR(50) COMMENT '收货人姓名',
|
||||
`shipping_phone` VARCHAR(20) COMMENT '收货人电话',
|
||||
`tracking_number` VARCHAR(100) COMMENT '快递单号',
|
||||
`status` ENUM('pending_payment', 'paid', 'processing', 'shipping', 'delivered', 'completed', 'cancelled', 'refunded') DEFAULT 'pending_payment' COMMENT '订单状态',
|
||||
`coupon_code` VARCHAR(50) COMMENT '优惠券代码',
|
||||
`notes` TEXT COMMENT '订单备注',
|
||||
`order_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
|
||||
`payment_date` TIMESTAMP NULL COMMENT '支付时间',
|
||||
`shipping_date` TIMESTAMP NULL COMMENT '发货时间',
|
||||
`delivery_date` TIMESTAMP NULL COMMENT '收货时间',
|
||||
`completion_date` TIMESTAMP NULL COMMENT '完成时间',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_order_number` (`order_number`),
|
||||
INDEX `idx_user` (`user_id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_payment_status` (`payment_status`),
|
||||
INDEX `idx_order_date` (`order_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
|
||||
|
||||
-- 订单商品表
|
||||
CREATE TABLE IF NOT EXISTS `order_items` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '订单商品ID',
|
||||
`order_id` BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
|
||||
`product_id` BIGINT UNSIGNED NOT NULL COMMENT '商品ID',
|
||||
`product_name` VARCHAR(200) NOT NULL COMMENT '商品名称快照',
|
||||
`product_sku` VARCHAR(50) COMMENT '商品SKU快照',
|
||||
`product_image` VARCHAR(255) COMMENT '商品图片快照',
|
||||
`unit_price` DECIMAL(10,2) NOT NULL COMMENT '单价',
|
||||
`quantity` INT NOT NULL COMMENT '数量',
|
||||
`total_price` DECIMAL(12,2) NOT NULL COMMENT '小计',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`specifications` JSON COMMENT '规格参数快照',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE RESTRICT,
|
||||
INDEX `idx_order` (`order_id`),
|
||||
INDEX `idx_product` (`product_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品表';
|
||||
|
||||
-- 商品评价表
|
||||
CREATE TABLE IF NOT EXISTS `product_reviews` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '评价ID',
|
||||
`product_id` BIGINT UNSIGNED NOT NULL COMMENT '商品ID',
|
||||
`order_id` BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`rating` TINYINT NOT NULL COMMENT '评分(1-5)',
|
||||
`content` TEXT COMMENT '评价内容',
|
||||
`images` JSON COMMENT '评价图片URLs',
|
||||
`helpful_count` INT DEFAULT 0 COMMENT '有用数',
|
||||
`reply_content` TEXT COMMENT '商家回复',
|
||||
`reply_date` TIMESTAMP NULL COMMENT '回复时间',
|
||||
`status` ENUM('active', 'hidden', 'deleted') DEFAULT 'active' COMMENT '状态',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
INDEX `idx_product` (`product_id`),
|
||||
INDEX `idx_user` (`user_id`),
|
||||
INDEX `idx_rating` (`rating`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品评价表';
|
||||
|
||||
-- ======================================
|
||||
-- 7. 质量追溯相关表
|
||||
-- ======================================
|
||||
|
||||
-- 产品追溯表
|
||||
CREATE TABLE IF NOT EXISTS `product_traceability` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '追溯ID',
|
||||
`product_id` BIGINT UNSIGNED COMMENT '商品ID',
|
||||
`batch_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '批次号',
|
||||
`cattle_ids` JSON COMMENT '源头牛只IDs',
|
||||
`farm_id` BIGINT UNSIGNED COMMENT '来源牧场ID',
|
||||
`slaughter_date` DATE COMMENT '屠宰日期',
|
||||
`slaughterhouse` VARCHAR(100) COMMENT '屠宰场',
|
||||
`processing_date` DATE COMMENT '加工日期',
|
||||
`processor` VARCHAR(100) COMMENT '加工商',
|
||||
`packaging_date` DATE COMMENT '包装日期',
|
||||
`quality_certificates` JSON COMMENT '质量证书URLs',
|
||||
`inspection_reports` JSON COMMENT '检验报告URLs',
|
||||
`transportation_records` JSON COMMENT '运输记录',
|
||||
`storage_conditions` JSON COMMENT '储存条件记录',
|
||||
`chain_of_custody` JSON COMMENT '监管链记录',
|
||||
`qr_code` VARCHAR(255) COMMENT '二维码内容',
|
||||
`blockchain_hash` VARCHAR(255) COMMENT '区块链哈希值',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE SET NULL,
|
||||
FOREIGN KEY (`farm_id`) REFERENCES `farms`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_batch_number` (`batch_number`),
|
||||
INDEX `idx_product` (`product_id`),
|
||||
INDEX `idx_farm` (`farm_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品追溯表';
|
||||
|
||||
-- ======================================
|
||||
-- 8. 系统日志相关表
|
||||
-- ======================================
|
||||
|
||||
-- 操作日志表
|
||||
CREATE TABLE IF NOT EXISTS `operation_logs` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '日志ID',
|
||||
`user_id` BIGINT UNSIGNED COMMENT '操作用户ID',
|
||||
`operation_type` VARCHAR(50) NOT NULL COMMENT '操作类型',
|
||||
`operation_module` VARCHAR(50) NOT NULL COMMENT '操作模块',
|
||||
`operation_desc` TEXT COMMENT '操作描述',
|
||||
`request_method` VARCHAR(10) COMMENT '请求方法',
|
||||
`request_url` VARCHAR(500) COMMENT '请求URL',
|
||||
`request_params` JSON COMMENT '请求参数',
|
||||
`response_code` INT COMMENT '响应状态码',
|
||||
`response_message` TEXT COMMENT '响应消息',
|
||||
`ip_address` VARCHAR(45) COMMENT 'IP地址',
|
||||
`user_agent` TEXT COMMENT '用户代理',
|
||||
`execution_time` INT COMMENT '执行时间(毫秒)',
|
||||
`success` TINYINT DEFAULT 1 COMMENT '是否成功',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_user` (`user_id`),
|
||||
INDEX `idx_type` (`operation_type`),
|
||||
INDEX `idx_module` (`operation_module`),
|
||||
INDEX `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- ======================================
|
||||
-- 插入初始数据
|
||||
-- ======================================
|
||||
|
||||
-- 插入默认角色
|
||||
INSERT IGNORE INTO `roles` (`name`, `description`) VALUES
|
||||
('admin', '系统管理员'),
|
||||
('farmer', '养殖户'),
|
||||
('banker', '银行职员'),
|
||||
('insurer', '保险员'),
|
||||
('government', '政府监管人员'),
|
||||
('trader', '交易员');
|
||||
|
||||
-- 插入默认权限
|
||||
INSERT IGNORE INTO `permissions` (`name`, `description`, `module`) VALUES
|
||||
('user_manage', '用户管理', 'user'),
|
||||
('cattle_manage', '牛只管理', 'cattle'),
|
||||
('loan_manage', '贷款管理', 'loan'),
|
||||
('insurance_manage', '保险管理', 'insurance'),
|
||||
('trade_manage', '交易管理', 'trade'),
|
||||
('government_supervise', '政府监管', 'government'),
|
||||
('data_view', '数据查看', 'data'),
|
||||
('system_config', '系统配置', 'system');
|
||||
|
||||
-- 插入默认管理员用户 (密码: admin123)
|
||||
INSERT IGNORE INTO `users` (`username`, `email`, `password_hash`, `real_name`, `user_type`, `status`) VALUES
|
||||
('admin', 'admin@xlxumu.com', '$2b$10$8K1p/a0dFd2XeyGWm7S9me5qHEF1K/ZEGPmU0ISGwXc7hdsXkn8ZO', '系统管理员', 'admin', 1);
|
||||
|
||||
SELECT '数据库表结构创建完成!' AS message;
|
||||
287
backend/database/init_tables_extended.sql
Normal file
287
backend/database/init_tables_extended.sql
Normal file
@@ -0,0 +1,287 @@
|
||||
-- ======================================
|
||||
-- 锡林郭勒盟智慧养殖产业平台 - 数据库初始化脚本(第二部分)
|
||||
-- 交易系统、商城管理、政府监管相关表
|
||||
-- ======================================
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ======================================
|
||||
-- 4. 交易系统相关表
|
||||
-- ======================================
|
||||
|
||||
-- 合同表
|
||||
CREATE TABLE IF NOT EXISTS `contracts` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '合同ID',
|
||||
`contract_number` VARCHAR(50) NOT NULL UNIQUE COMMENT '合同编号',
|
||||
`seller_id` BIGINT UNSIGNED NOT NULL COMMENT '卖方ID',
|
||||
`buyer_id` BIGINT UNSIGNED NOT NULL COMMENT '买方ID',
|
||||
`cattle_details` JSON COMMENT '牛只详情',
|
||||
`total_price` DECIMAL(15,2) NOT NULL COMMENT '总价',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`contract_date` DATE NOT NULL COMMENT '合同日期',
|
||||
`effective_date` DATE COMMENT '生效日期',
|
||||
`expiry_date` DATE COMMENT '到期日期',
|
||||
`payment_terms` TEXT COMMENT '付款条款',
|
||||
`delivery_terms` TEXT COMMENT '交付条款',
|
||||
`contract_status` ENUM('draft', 'signed', 'active', 'completed', 'cancelled') DEFAULT 'draft' COMMENT '合同状态',
|
||||
`contract_file_url` VARCHAR(255) COMMENT '合同文件URL',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`seller_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`buyer_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
INDEX `idx_contract_number` (`contract_number`),
|
||||
INDEX `idx_seller` (`seller_id`),
|
||||
INDEX `idx_buyer` (`buyer_id`),
|
||||
INDEX `idx_status` (`contract_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合同表';
|
||||
|
||||
-- 交易记录表
|
||||
CREATE TABLE IF NOT EXISTS `transactions` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '交易ID',
|
||||
`cattle_id` BIGINT UNSIGNED NOT NULL COMMENT '牛只ID',
|
||||
`seller_id` BIGINT UNSIGNED NOT NULL COMMENT '卖方ID',
|
||||
`buyer_id` BIGINT UNSIGNED NOT NULL COMMENT '买方ID',
|
||||
`transaction_type` ENUM('direct', 'auction', 'platform') NOT NULL COMMENT '交易类型',
|
||||
`price` DECIMAL(12,2) NOT NULL COMMENT '交易价格',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`transaction_date` DATETIME NOT NULL COMMENT '交易时间',
|
||||
`contract_id` BIGINT UNSIGNED COMMENT '合同ID',
|
||||
`status` ENUM('pending', 'completed', 'cancelled') DEFAULT 'pending' COMMENT '状态',
|
||||
`payment_status` ENUM('unpaid', 'partial', 'paid') DEFAULT 'unpaid' COMMENT '付款状态',
|
||||
`delivery_status` ENUM('pending', 'in_transit', 'delivered') DEFAULT 'pending' COMMENT '交付状态',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`cattle_id`) REFERENCES `cattle`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`seller_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`buyer_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`contract_id`) REFERENCES `contracts`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_cattle_date` (`cattle_id`, `transaction_date`),
|
||||
INDEX `idx_seller` (`seller_id`),
|
||||
INDEX `idx_buyer` (`buyer_id`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易记录表';
|
||||
|
||||
-- ======================================
|
||||
-- 5. 商城管理相关表
|
||||
-- ======================================
|
||||
|
||||
-- 商品分类表
|
||||
CREATE TABLE IF NOT EXISTS `product_categories` (
|
||||
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '分类ID',
|
||||
`name` VARCHAR(50) NOT NULL COMMENT '分类名称',
|
||||
`parent_id` INT UNSIGNED DEFAULT 0 COMMENT '父分类ID',
|
||||
`level` TINYINT DEFAULT 1 COMMENT '层级',
|
||||
`sort_order` INT DEFAULT 0 COMMENT '排序',
|
||||
`image_url` VARCHAR(255) COMMENT '图片URL',
|
||||
`status` TINYINT DEFAULT 1 COMMENT '状态: 1-正常, 0-禁用',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX `idx_parent` (`parent_id`),
|
||||
INDEX `idx_level` (`level`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表';
|
||||
|
||||
-- 商品表
|
||||
CREATE TABLE IF NOT EXISTS `products` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '商品ID',
|
||||
`name` VARCHAR(100) NOT NULL COMMENT '商品名称',
|
||||
`description` TEXT COMMENT '商品描述',
|
||||
`category_id` INT UNSIGNED COMMENT '分类ID',
|
||||
`sku` VARCHAR(50) UNIQUE COMMENT 'SKU',
|
||||
`price` DECIMAL(10,2) NOT NULL COMMENT '价格',
|
||||
`original_price` DECIMAL(10,2) COMMENT '原价',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`stock_quantity` INT DEFAULT 0 COMMENT '库存数量',
|
||||
`min_stock` INT DEFAULT 0 COMMENT '最低库存',
|
||||
`unit` VARCHAR(20) COMMENT '单位',
|
||||
`weight` DECIMAL(8,3) COMMENT '重量(kg)',
|
||||
`origin` VARCHAR(100) COMMENT '产地',
|
||||
`production_date` DATE COMMENT '生产日期',
|
||||
`expiration_date` DATE COMMENT '保质期',
|
||||
`cattle_id` BIGINT UNSIGNED COMMENT '关联牛只ID',
|
||||
`status` ENUM('active', 'inactive', 'discontinued') DEFAULT 'active' COMMENT '状态',
|
||||
`image_urls` JSON COMMENT '图片URL列表',
|
||||
`tags` JSON COMMENT '标签',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`cattle_id`) REFERENCES `cattle`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_name` (`name`),
|
||||
INDEX `idx_category` (`category_id`),
|
||||
INDEX `idx_sku` (`sku`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
|
||||
|
||||
-- 订单表
|
||||
CREATE TABLE IF NOT EXISTS `orders` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
|
||||
`order_number` VARCHAR(50) NOT NULL UNIQUE COMMENT '订单编号',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`total_amount` DECIMAL(12,2) NOT NULL COMMENT '订单总额',
|
||||
`currency` VARCHAR(10) DEFAULT 'CNY' COMMENT '货币',
|
||||
`order_status` ENUM('pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded') DEFAULT 'pending' COMMENT '订单状态',
|
||||
`payment_status` ENUM('unpaid', 'partial', 'paid') DEFAULT 'unpaid' COMMENT '付款状态',
|
||||
`shipping_status` ENUM('unshipped', 'shipped', 'delivered') DEFAULT 'unshipped' COMMENT '发货状态',
|
||||
`receiver_name` VARCHAR(50) COMMENT '收货人姓名',
|
||||
`receiver_phone` VARCHAR(20) COMMENT '收货人电话',
|
||||
`receiver_address` TEXT COMMENT '收货地址',
|
||||
`shipping_method` VARCHAR(50) COMMENT '配送方式',
|
||||
`shipping_fee` DECIMAL(10,2) DEFAULT 0.00 COMMENT '运费',
|
||||
`notes` TEXT COMMENT '备注',
|
||||
`payment_method` VARCHAR(50) COMMENT '付款方式',
|
||||
`paid_at` TIMESTAMP NULL COMMENT '付款时间',
|
||||
`shipped_at` TIMESTAMP NULL COMMENT '发货时间',
|
||||
`delivered_at` TIMESTAMP NULL COMMENT '送达时间',
|
||||
`cancelled_at` TIMESTAMP NULL COMMENT '取消时间',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
INDEX `idx_order_number` (`order_number`),
|
||||
INDEX `idx_user` (`user_id`),
|
||||
INDEX `idx_status` (`order_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
|
||||
|
||||
-- 订单项表
|
||||
CREATE TABLE IF NOT EXISTS `order_items` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '订单项ID',
|
||||
`order_id` BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
|
||||
`product_id` BIGINT UNSIGNED NOT NULL COMMENT '商品ID',
|
||||
`quantity` INT NOT NULL COMMENT '数量',
|
||||
`unit_price` DECIMAL(10,2) NOT NULL COMMENT '单价',
|
||||
`total_price` DECIMAL(12,2) NOT NULL COMMENT '总价',
|
||||
`cattle_id` BIGINT UNSIGNED COMMENT '关联牛只ID',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`cattle_id`) REFERENCES `cattle`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_order` (`order_id`),
|
||||
INDEX `idx_product` (`product_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单项表';
|
||||
|
||||
-- 物流跟踪表
|
||||
CREATE TABLE IF NOT EXISTS `logistics_tracking` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '物流ID',
|
||||
`order_id` BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
|
||||
`tracking_number` VARCHAR(100) UNIQUE COMMENT '物流单号',
|
||||
`carrier` VARCHAR(50) COMMENT '承运商',
|
||||
`status` ENUM('pending', 'in_transit', 'delivered', 'exception') DEFAULT 'pending' COMMENT '物流状态',
|
||||
`origin` VARCHAR(255) COMMENT '起始地',
|
||||
`destination` VARCHAR(255) COMMENT '目的地',
|
||||
`estimated_delivery_date` DATE COMMENT '预计送达日期',
|
||||
`actual_delivery_date` DATE COMMENT '实际送达日期',
|
||||
`current_location` VARCHAR(255) COMMENT '当前位置',
|
||||
`tracking_info` JSON COMMENT '物流跟踪信息',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE CASCADE,
|
||||
INDEX `idx_tracking_number` (`tracking_number`),
|
||||
INDEX `idx_order` (`order_id`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流跟踪表';
|
||||
|
||||
-- ======================================
|
||||
-- 6. 政府监管相关表
|
||||
-- ======================================
|
||||
|
||||
-- 政府监管报告表
|
||||
CREATE TABLE IF NOT EXISTS `government_reports` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '报告ID',
|
||||
`report_type` ENUM('production', 'sales', 'disease', 'environment', 'finance') NOT NULL COMMENT '报告类型',
|
||||
`reporter_id` BIGINT UNSIGNED NOT NULL COMMENT '报告人ID',
|
||||
`reporting_period_start` DATE NOT NULL COMMENT '报告期开始日期',
|
||||
`reporting_period_end` DATE NOT NULL COMMENT '报告期结束日期',
|
||||
`data_content` JSON COMMENT '报告数据内容',
|
||||
`summary` TEXT COMMENT '摘要',
|
||||
`status` ENUM('draft', 'submitted', 'approved', 'rejected') DEFAULT 'draft' COMMENT '状态',
|
||||
`approver_id` BIGINT UNSIGNED COMMENT '审批人ID',
|
||||
`approval_notes` TEXT COMMENT '审批备注',
|
||||
`submitted_at` TIMESTAMP NULL COMMENT '提交时间',
|
||||
`approved_at` TIMESTAMP NULL COMMENT '审批时间',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
FOREIGN KEY (`reporter_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`approver_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
|
||||
INDEX `idx_reporter` (`reporter_id`),
|
||||
INDEX `idx_type` (`report_type`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政府监管报告表';
|
||||
|
||||
-- 新闻资讯表
|
||||
CREATE TABLE IF NOT EXISTS `news_articles` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '新闻ID',
|
||||
`title` VARCHAR(150) NOT NULL COMMENT '标题',
|
||||
`subtitle` VARCHAR(200) COMMENT '副标题',
|
||||
`content` TEXT NOT NULL COMMENT '内容',
|
||||
`author` VARCHAR(50) COMMENT '作者',
|
||||
`source` VARCHAR(100) COMMENT '来源',
|
||||
`cover_image` VARCHAR(255) COMMENT '封面图片URL',
|
||||
`is_featured` BOOLEAN DEFAULT FALSE COMMENT '是否推荐',
|
||||
`status` ENUM('draft', 'published', 'archived') DEFAULT 'draft' COMMENT '状态',
|
||||
`publish_date` TIMESTAMP NULL COMMENT '发布时间',
|
||||
`category` VARCHAR(50) COMMENT '分类',
|
||||
`views` INT UNSIGNED DEFAULT 0 COMMENT '浏览量',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_category` (`category`),
|
||||
INDEX `idx_publish_date` (`publish_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='新闻资讯表';
|
||||
|
||||
-- 政策公告表
|
||||
CREATE TABLE IF NOT EXISTS `policy_announcements` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '公告ID',
|
||||
`title` VARCHAR(150) NOT NULL COMMENT '标题',
|
||||
`content` TEXT NOT NULL COMMENT '内容',
|
||||
`issuer` VARCHAR(100) NOT NULL COMMENT '发布机构',
|
||||
`issue_date` DATE NOT NULL COMMENT '发布日期',
|
||||
`effective_date` DATE COMMENT '生效日期',
|
||||
`document_number` VARCHAR(50) COMMENT '文号',
|
||||
`attachment_url` VARCHAR(255) COMMENT '附件URL',
|
||||
`is_important` BOOLEAN DEFAULT FALSE COMMENT '是否重要公告',
|
||||
`status` ENUM('draft', 'published', 'expired') DEFAULT 'draft' COMMENT '状态',
|
||||
`views` INT UNSIGNED DEFAULT 0 COMMENT '浏览量',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX `idx_issue_date` (`issue_date`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_issuer` (`issuer`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政策公告表';
|
||||
|
||||
-- 环境监测表
|
||||
CREATE TABLE IF NOT EXISTS `environment_monitoring` (
|
||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '记录ID',
|
||||
`location` VARCHAR(255) NOT NULL COMMENT '监测位置',
|
||||
`temperature` DECIMAL(5,2) COMMENT '温度(℃)',
|
||||
`humidity` DECIMAL(5,2) COMMENT '湿度(%)',
|
||||
`air_quality` VARCHAR(50) COMMENT '空气质量',
|
||||
`ammonia_concentration` DECIMAL(6,3) COMMENT '氨气浓度(ppm)',
|
||||
`carbon_dioxide` DECIMAL(6,2) COMMENT '二氧化碳浓度(ppm)',
|
||||
`noise_level` DECIMAL(5,2) COMMENT '噪音(dB)',
|
||||
`light_intensity` DECIMAL(7,2) COMMENT '光照强度(lux)',
|
||||
`monitoring_date` DATETIME NOT NULL COMMENT '监测时间',
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX `idx_location_date` (`location`, `monitoring_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='环境监测表';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- ======================================
|
||||
-- 插入测试数据
|
||||
-- ======================================
|
||||
|
||||
-- 插入商品分类
|
||||
INSERT IGNORE INTO `product_categories` (`name`, `parent_id`, `level`, `sort_order`) VALUES
|
||||
('牛肉制品', 0, 1, 1),
|
||||
('新鲜牛肉', 1, 2, 1),
|
||||
('牛肉干', 1, 2, 2),
|
||||
('牛肉罐头', 1, 2, 3);
|
||||
|
||||
-- 插入测试牛只数据
|
||||
INSERT IGNORE INTO `cattle` (`ear_tag`, `name`, `breed`, `gender`, `birth_date`, `color`, `weight`, `farm_location`, `owner_id`) VALUES
|
||||
('XL001', '小花', '西门塔尔牛', 'female', '2022-03-15', '黄白花', 450.50, '锡林浩特市第一牧场', 1),
|
||||
('XL002', '壮壮', '安格斯牛', 'male', '2021-08-20', '黑色', 580.75, '锡林浩特市第一牧场', 1),
|
||||
('XL003', '美美', '夏洛莱牛', 'female', '2022-05-10', '白色', 420.30, '东乌旗牧场A', 1);
|
||||
|
||||
SELECT '数据库扩展表结构创建完成!' AS message;
|
||||
160
backend/database/package-lock.json
generated
Normal file
160
backend/database/package-lock.json
generated
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"name": "database",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "database",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"dotenv": "^17.2.2",
|
||||
"mysql2": "^3.14.4"
|
||||
}
|
||||
},
|
||||
"node_modules/aws-ssl-profiles": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
|
||||
"integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/denque": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz",
|
||||
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "17.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-17.2.2.tgz",
|
||||
"integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/generate-function": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz",
|
||||
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-property": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.0.tgz",
|
||||
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/is-property": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "7.18.3",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz",
|
||||
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/lru.min": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/lru.min/-/lru.min-1.1.2.tgz",
|
||||
"integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"bun": ">=1.0.0",
|
||||
"deno": ">=1.30.0",
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wellwelwel"
|
||||
}
|
||||
},
|
||||
"node_modules/mysql2": {
|
||||
"version": "3.14.4",
|
||||
"resolved": "https://registry.npmmirror.com/mysql2/-/mysql2-3.14.4.tgz",
|
||||
"integrity": "sha512-Cs/jx3WZPNrYHVz+Iunp9ziahaG5uFMvD2R8Zlmc194AqXNxt9HBNu7ZsPYrUtmJsF0egETCWIdMIYAwOGjL1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"aws-ssl-profiles": "^1.1.1",
|
||||
"denque": "^2.1.0",
|
||||
"generate-function": "^2.3.1",
|
||||
"iconv-lite": "^0.7.0",
|
||||
"long": "^5.2.1",
|
||||
"lru.min": "^1.0.0",
|
||||
"named-placeholders": "^1.1.3",
|
||||
"seq-queue": "^0.0.5",
|
||||
"sqlstring": "^2.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/named-placeholders": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/named-placeholders/-/named-placeholders-1.1.3.tgz",
|
||||
"integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lru-cache": "^7.14.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/seq-queue": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/seq-queue/-/seq-queue-0.0.5.tgz",
|
||||
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
|
||||
},
|
||||
"node_modules/sqlstring": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||
"integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
backend/database/package.json
Normal file
16
backend/database/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "database",
|
||||
"version": "1.0.0",
|
||||
"description": "## 概述",
|
||||
"main": "setup-database.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"dotenv": "^17.2.2",
|
||||
"mysql2": "^3.14.4"
|
||||
}
|
||||
}
|
||||
205
backend/database/setup-database.js
Normal file
205
backend/database/setup-database.js
Normal file
@@ -0,0 +1,205 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config();
|
||||
|
||||
class DatabaseSetup {
|
||||
constructor() {
|
||||
this.config = {
|
||||
host: process.env.DB_HOST,
|
||||
port: parseInt(process.env.DB_PORT),
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
multipleStatements: true
|
||||
};
|
||||
}
|
||||
|
||||
async checkConnection() {
|
||||
console.log('🔍 检查数据库连接...');
|
||||
console.log(`📍 服务器: ${this.config.host}:${this.config.port}`);
|
||||
console.log(`👤 用户: ${this.config.user}`);
|
||||
console.log(`🗄️ 数据库: ${this.config.database}`);
|
||||
|
||||
try {
|
||||
const connection = await mysql.createConnection(this.config);
|
||||
console.log('✅ 数据库连接成功!');
|
||||
|
||||
// 获取数据库版本信息
|
||||
const [version] = await connection.execute('SELECT VERSION() as version');
|
||||
console.log(`📋 MySQL版本: ${version[0].version}`);
|
||||
|
||||
await connection.end();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ 数据库连接失败:', error.message);
|
||||
|
||||
if (error.code === 'ER_ACCESS_DENIED_ERROR') {
|
||||
console.log('\n💡 可能的解决方案:');
|
||||
console.log('1. 检查用户名和密码是否正确');
|
||||
console.log('2. 确认用户有访问该数据库的权限');
|
||||
console.log('3. 检查IP白名单是否包含当前服务器IP');
|
||||
console.log(` 当前尝试连接的IP需要添加到腾讯云数据库白名单中`);
|
||||
} else if (error.code === 'ENOTFOUND') {
|
||||
console.log('\n💡 域名解析失败,请检查:');
|
||||
console.log('1. 数据库服务器地址是否正确');
|
||||
console.log('2. 网络连接是否正常');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async executeSQL(sqlFile) {
|
||||
console.log(`\n📄 执行SQL文件: ${sqlFile}`);
|
||||
|
||||
try {
|
||||
const sqlPath = path.join(__dirname, sqlFile);
|
||||
const sql = fs.readFileSync(sqlPath, 'utf8');
|
||||
|
||||
const connection = await mysql.createConnection(this.config);
|
||||
|
||||
// 分割SQL语句并逐个执行
|
||||
const statements = sql.split(';').filter(stmt => stmt.trim().length > 0);
|
||||
let successCount = 0;
|
||||
|
||||
for (const statement of statements) {
|
||||
const trimmedStmt = statement.trim();
|
||||
if (trimmedStmt) {
|
||||
try {
|
||||
await connection.execute(trimmedStmt);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
if (!error.message.includes('already exists')) {
|
||||
console.warn(`⚠️ 执行语句时警告: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ 成功执行 ${successCount} 条SQL语句`);
|
||||
await connection.end();
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`❌ 执行SQL文件失败: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async checkTables() {
|
||||
console.log('\n📋 检查数据库表结构...');
|
||||
|
||||
try {
|
||||
const connection = await mysql.createConnection(this.config);
|
||||
|
||||
// 获取所有表
|
||||
const [tables] = await connection.execute(
|
||||
'SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?',
|
||||
[this.config.database]
|
||||
);
|
||||
|
||||
console.log(`📊 数据库 ${this.config.database} 中共有 ${tables.length} 张表:`);
|
||||
|
||||
tables.forEach((table, index) => {
|
||||
console.log(` ${index + 1}. ${table.TABLE_NAME} - ${table.TABLE_COMMENT || '无注释'}`);
|
||||
});
|
||||
|
||||
// 检查重要表是否存在
|
||||
const requiredTables = ['users', 'cattle', 'loan_applications', 'insurance_applications', 'contracts', 'products', 'orders'];
|
||||
const existingTables = tables.map(t => t.TABLE_NAME);
|
||||
const missingTables = requiredTables.filter(table => !existingTables.includes(table));
|
||||
|
||||
if (missingTables.length === 0) {
|
||||
console.log('✅ 所有核心表已创建');
|
||||
} else {
|
||||
console.log(`⚠️ 缺少核心表: ${missingTables.join(', ')}`);
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
return { tables: existingTables, missing: missingTables };
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 检查表结构失败:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getMyIPAddress() {
|
||||
try {
|
||||
const https = require('https');
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get('https://api.ipify.org', (resp) => {
|
||||
let data = '';
|
||||
resp.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
resp.on('end', () => {
|
||||
resolve(data);
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
return '无法获取';
|
||||
}
|
||||
}
|
||||
|
||||
async setup() {
|
||||
console.log('🚀 开始数据库初始化流程...\n');
|
||||
|
||||
// 获取当前IP地址
|
||||
const myIP = await this.getMyIPAddress();
|
||||
console.log(`🌐 当前公网IP地址: ${myIP}`);
|
||||
console.log('📝 请确保此IP已添加到腾讯云数据库白名单中\n');
|
||||
|
||||
// 检查连接
|
||||
const connected = await this.checkConnection();
|
||||
if (!connected) {
|
||||
console.log('\n❌ 数据库连接失败,请先解决连接问题');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行基础表创建
|
||||
console.log('\n🔨 创建基础表结构...');
|
||||
const basicResult = await this.executeSQL('init_tables.sql');
|
||||
if (!basicResult) {
|
||||
console.log('❌ 基础表创建失败');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行扩展表创建
|
||||
console.log('\n🔧 创建扩展表结构...');
|
||||
const extendedResult = await this.executeSQL('init_tables_extended.sql');
|
||||
if (!extendedResult) {
|
||||
console.log('❌ 扩展表创建失败');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证表结构
|
||||
await this.checkTables();
|
||||
|
||||
console.log('\n🎉 数据库初始化完成!');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
const setup = new DatabaseSetup();
|
||||
setup.setup().then((success) => {
|
||||
if (success) {
|
||||
console.log('\n✅ 数据库设置成功完成');
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log('\n❌ 数据库设置失败');
|
||||
process.exit(1);
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error('💥 发生错误:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = DatabaseSetup;
|
||||
Reference in New Issue
Block a user