更新项目文件结构,统一文档风格

This commit is contained in:
ylweng
2025-09-04 01:39:31 +08:00
parent 216cf80eab
commit 3ae7b4db8c
45 changed files with 17218 additions and 642 deletions

37
backend/database/.env Normal file
View 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

View 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. **容灾**: 配置主从复制和故障转移

View 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);
});

View 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;

View 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 '头像URLOSS存储路径',
`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;

View 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
View 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"
}
}
}
}

View 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"
}
}

View 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;