feat: 初始化多个小程序和前端项目

- 新建多个小程序的 app.js、app.json 和 app.wxss 文件
- 新建多个前端项目的 App.vue 文件
- 添加 .gitignore 文件和后端 API 的 .env.example 文件
This commit is contained in:
ylweng
2025-08-18 23:48:54 +08:00
commit 1dbfbebd05
81 changed files with 5791 additions and 0 deletions

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

10
.idea/UniappTool.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="cn.fjdmy.uniapp.UniappProjectDataService">
<option name="generalBasePath" value="$PROJECT_DIR$" />
<option name="manifestPath" value="$PROJECT_DIR$/manifest.json" />
<option name="pagesPath" value="$PROJECT_DIR$/pages.json" />
<option name="scanNum" value="1" />
<option name="type" value="store" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/xlxumu.iml" filepath="$PROJECT_DIR$/.idea/xlxumu.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

9
.idea/xlxumu.iml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

310
ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,310 @@
# 系统架构文档
## 1. 概述
本项目是一个综合性的畜牧业数字化管理平台,主要面向锡林郭勒盟地区的安格斯牛养殖产业,包含官网展示、后台管理、移动端小程序等多个子系统。平台集成了养殖管理、银行监管、保险监管、牛只交易、运输管理、牛肉商城等功能模块,旨在通过数字化手段提升整个产业链的管理效率和透明度。
## 2. 技术栈
### 2.1 前端技术栈
- **官网首页**: HTML5 + CSS3 + JavaScript
- **后台管理系统**: Vue.js 3 + TypeScript + Ant Design Vue + Pinia
- **微信小程序矩阵**: 微信小程序原生开发 + uni-app
### 2.2 后端技术栈
- **API服务**: Node.js + Express.js + TypeScript
- **数据库**: MySQL
- **文件存储**: 腾讯云存储
### 2.3 安全架构
- **身份认证**: JWT (JSON Web Tokens)
- **权限管理**: 基于角色的访问控制 (RBAC)
- **数据传输**: HTTPS 加密传输
- **API防护**: 接口限流、参数校验、防SQL注入等
### 2.4 数据架构
- **实时数据采集**: IoT设备数据接入
- **大数据分析**: 数据分析引擎
- **智能预警**: 基于规则的预警系统
- **可视化展示**: 图表化数据展示平台
## 3. 系统架构图
```
┌─────────────────────────────────────────────────────────────────────┐
│ 用户端接入层 │
├─────────────────┬───────────────────────────────────────────────────┤
│ 官网首页 │ 专业管理系统 │
│ (HTML5展示) ├───────────────────────────────────────────────────┤
│ │ - 养殖管理系统 (Vue.js 3 + Ant) │
│ │ - 银行监管系统 (Vue.js 3 + Ant) │
│ │ - 保险监管系统 (Vue.js 3 + Ant) │
│ │ - 政府监管平台 (Vue.js 3 + Ant) │
│ │ - 活牛交易系统 (Vue.js 3 + Ant) │
│ │ - 商城管理系统 (Vue.js 3 + Ant) │
├─────────────────┼───────────────────────────────────────────────────┤
│ 微信小程序矩阵 │
│ - 牛肉商城小程序 │
│ - 养殖管理小程序 │
│ - 银行监管小程序 │
│ - 保险监管小程序 │
│ - 活牛交易小程序 │
├─────────────────┴───────────────────────────────────────────────────┤
│ API服务层 (Node.js) │
├─────────────────────────────────────────────────────────────────────┤
│ 数据层 │
├─────────────────────────────────────────────────────────────────────┤
│ 关系数据库(MySQL) │ 文件存储(腾讯云) │ 缓存系统(Redis) │
├─────────────────────────────────────────────────────────────────────┤
│ 数据分析层 │
├─────────────────────────────────────────────────────────────────────┤
│ 大数据分析引擎 │ 智能预警系统 │ 可视化平台 │
└─────────────────────────────────────────────────────────────────────┘
```
## 4. 前端系统架构
### 4.1 官网首页系统
- 纯HTML5、CSS3、JavaScript实现
- 响应式设计,适配多种设备
- 突出锡林郭勒盟地域元素和蒙古族文化特色
- 绿色草原主题风格
### 4.2 专业管理系统
#### 4.2.1 养殖管理系统
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 牛只档案管理
2. 饲养记录管理
3. 繁殖管理
4. 环境监测数据展示
5. 生产计划制定和执行跟踪
#### 4.2.2 银行监管系统
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 贷款申请和审批流程管理
2. 质押物(牛只)状态监控
3. 还款计划跟踪
4. 风险评估数据展示
5. 财务报表生成
#### 4.2.3 保险监管系统
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 保险投保管理
2. 理赔申请和处理流程
3. 风险评估和预警
4. 保险记录查询
5. 数据统计分析
#### 4.2.4 政府监管平台
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 产业数据总览
2. 各类监管数据汇总
3. 政策发布和通知
4. 合规性检查
5. 统计报表生成
#### 4.2.5 活牛交易系统
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 牛只信息发布和展示
2. 在线交易撮合
3. 合同管理
4. 支付流程管理
5. 交易记录查询
#### 4.2.6 商城管理系统
- 基于Vue.js 3 Composition API
- 使用Ant Design Vue组件库
- 状态管理采用Pinia
- TypeScript增强代码可维护性
##### 功能模块
1. 商品信息管理
2. 库存管理
3. 订单处理
4. 物流跟踪
5. 售后服务管理
### 4.3 微信小程序矩阵
- 使用微信小程序原生开发框架
- 跨平台支持采用uni-app
- 包含5个专门的小程序应用
#### 4.3.1 牛肉商城小程序(消费者端)
- 商品浏览和搜索
- 在线下单和支付
- 订单查询和跟踪
- 售后服务申请
- **认养功能**:用户可以认养特定牛只,跟踪其成长过程
#### 4.3.2 养殖管理小程序(牧民端)
- 移动端牛只档案查看
- 饲养记录录入
- 健康状况上报
- 通知消息接收
- 数据统计查看
#### 4.3.3 银行监管小程序(银行端)
- 移动端贷款审批
- 质押物状态查看
- 风险数据监控
- 移动办公支持
#### 4.3.4 保险监管小程序(保险端)
- 移动端保险处理
- 理赔流程管理
- 风险评估查看
- 移动查勘支持
#### 4.3.5 活牛交易小程序(交易员端)
- 活牛信息发布
- 在线交易撮合
- 合同查看和管理
- 交易记录查询
- 支付状态跟踪
## 5. 后端系统架构
### 5.1 API服务层
- 基于Node.js和Express.js构建
- 使用TypeScript增强代码健壮性
- RESTful API设计风格
- JWT身份认证机制
### 5.2 数据存储层
- 主数据库MySQL关系型数据库
- 文件存储:腾讯云对象存储服务
- 缓存系统Redis可选
### 5.3 安全架构
- 基于JWT的无状态认证
- RBAC角色权限管理系统
- HTTPS加密传输
- API接口安全防护限流、防注入等
### 5.4 数据分析层
- 实时数据采集系统
- 大数据分析引擎
- 智能预警系统
- 数据可视化展示平台
## 6. 项目结构
```
.
├── frontend/ # 前端项目
│ ├── website/ # 官网首页
│ ├── farming-management/ # 养殖管理系统
│ ├── bank-supervision/ # 银行监管系统
│ ├── insurance-supervision/ # 保险监管系统
│ ├── government-platform/ # 政府监管平台
│ ├── cattle-trading/ # 活牛交易系统
│ ├── mall-management/ # 商城管理系统
│ ├── dashboard/ # 大屏可视化系统
│ └── mini-programs/ # 微信小程序矩阵
│ ├── beef-mall/ # 牛肉商城小程序
│ ├── farming-manager/ # 养殖管理小程序
│ ├── bank-supervision/ # 银行监管小程序
│ ├── insurance-supervision/ # 保险监管小程序
│ └── cattle-trading/ # 活牛交易小程序
├── backend/ # 后端项目
│ ├── api/ # API服务
│ ├── database/ # 数据库脚本
│ └── utils/ # 工具函数
├── docs/ # 文档
└── deployment/ # 部署相关配置
```
## 7. 大屏可视化系统
### 7.1 系统概述
大屏可视化系统是本项目的重要组成部分,主要用于展示锡林郭勒盟安格斯牛养殖产业的整体数据、实时监控信息和分析结果。通过直观的图表和数据可视化方式,为管理者提供全面的产业洞察。
### 7.2 技术实现
- **前端框架**: Vue.js 3 + ECharts/DataV
- **可视化库**: Apache ECharts + D3.js
- **响应式设计**: 支持多种大屏比例(16:9, 4:3等)
- **实时数据**: WebSocket实时数据推送
### 7.3 功能模块
1. **产业概览**: 展示整体产业规模、产值、增长率等关键指标
2. **养殖监控**: 实时展示各牧场的养殖情况、环境数据
3. **交易统计**: 牛只交易量、价格趋势、区域分布等数据
4. **运输跟踪**: 牛只运输实时状态和路径展示
5. **风险预警**: 风险事件展示和预警信息推送
6. **生态指标**: 环保数据、可持续发展指标展示
### 7.4 设计特色
- 融入锡林郭勒盟草原绿色主题
- 采用蒙古族文化元素的UI设计
- 突出安格斯牛品牌形象
- 支持多维度数据钻取和交互
## 8. 设计特色
### 8.1 地域文化特色
- 锡林郭勒盟草原绿色主题设计
- 融入蒙古族文化元素
- 体现当地畜牧业特色
### 8.2 品牌专业化
- 突出安格斯牛品牌特色
- 专门的安格斯牛管理和交易模块
- 品牌化展示和推广
### 8.3 生态理念
- 绿色发展理念贯穿整个系统
- 可持续畜牧业理念体现
- 环保数据监控和展示
## 9. 性能优化策略
### 9.1 前端优化
- 代码分割和按需加载
- 图片懒加载和压缩
- CDN加速静态资源
- 浏览器缓存策略
### 9.2 后端优化
- 数据库索引优化
- API响应缓存
- 数据库连接池
- 负载均衡部署
## 10. 部署架构
### 10.1 开发环境
- 本地开发服务器
- 热重载功能
- 代理配置解决跨域问题
### 10.2 生产环境
- Nginx反向代理服务器
- 负载均衡配置
- SSL证书配置
- 日志收集和监控系统

288
DEVELOPMENT_PLAN.md Normal file
View File

@@ -0,0 +1,288 @@
# 开发计划
## 1. 项目概述
本项目是面向锡林郭勒盟地区安格斯牛养殖产业的综合性数字化管理平台,包含官网展示、多个专业管理系统(养殖管理、银行监管、保险监管、政府监管、活牛交易、商城管理)、大屏可视化系统、移动端小程序等多个子系统。平台旨在通过数字化手段提升整个产业链的管理效率和透明度。
## 2. 技术选型
### 2.1 前端技术栈
- **官网首页**: HTML5 + CSS3 + JavaScript
- **专业管理系统**: Vue.js 3 + TypeScript + Ant Design Vue + Pinia
- **大屏可视化系统**: Vue.js 3 + ECharts/DataV
- **微信小程序矩阵**: 微信小程序原生开发 + uni-app
### 2.2 后端技术栈
- **API服务**: Node.js + Express.js + TypeScript
- **数据库**: MySQL
- **API文档**: Swagger
- **安全**: JWT认证
- **文件存储**: 腾讯云存储
### 2.3 开发工具
- VS Code (推荐IDE)
- Git (版本控制)
- ESLint + Prettier (代码规范)
- Jest/Vitest (单元测试)
## 3. 开发阶段规划
### 阶段一:项目初始化与基础架构搭建 (2周)
#### 3.1 环境配置 (2天)
- 搭建开发环境
- 配置代码编辑器
- 初始化Git仓库
- 配置ESLint和Prettier
#### 3.2 项目脚手架搭建 (3天)
- 官网首页静态页面搭建
- 6个专业管理系统Vue项目初始化养殖管理、银行监管、保险监管、政府监管、活牛交易、商城管理
- 大屏可视化系统初始化
- 微信小程序项目初始化5个小程序
- 后端API服务搭建
#### 3.3 基础设施集成 (3天)
- 数据库设计和初始化
- 腾讯云存储服务集成
- JWT身份认证实现
- 基础权限管理框架
#### 3.4 开发规范制定 (2天)
- 制定代码规范
- 确定目录结构
- 编写开发文档
### 阶段二:核心功能开发 (8周)
#### 3.5 用户认证和权限系统 (1周)
- 用户注册/登录功能
- JWT Token管理
- 角色权限管理
- RBAC权限控制实现
#### 3.6 官网首页和基础框架 (1周)
- 官网首页设计和实现
- 6个专业管理系统基础布局
- 导航菜单实现
- 响应式设计适配
#### 3.7 养殖管理系统 (2周)
- 牛只档案管理
- 饲养记录管理
- 繁殖管理功能
- 环境监测数据展示
#### 3.8 银行监管系统 (1周)
- 贷款申请和审批流程管理
- 质押物(牛只)状态监控
- 还款计划跟踪
#### 3.9 保险监管系统 (1周)
- 保险投保管理
- 理赔申请和处理流程
- 风险评估和预警
#### 3.10 政府监管平台 (1周)
- 产业数据总览
- 各类监管数据汇总
- 政策发布和通知
#### 3.11 活牛交易系统 (1周)
- 牛只信息发布和展示
- 在线交易撮合
- 合同管理
### 阶段三:商城和小程序开发 (4周)
#### 3.12 商城管理系统 (1周)
- 商品信息管理
- 库存管理
- 订单处理
- 物流跟踪
#### 3.13 牛肉商城小程序(含认养功能) (1周)
- 商品浏览和搜索
- 在线下单和支付
- 订单查询和跟踪
- 认养功能实现
#### 3.14 养殖管理小程序 (1周)
- 移动端牛只档案查看
- 饲养记录录入
- 健康状况上报
#### 3.15 银行和保险监管小程序 (1周)
- 银行监管小程序功能开发
- 保险监管小程序功能开发
#### 3.16 活牛交易小程序 (1周)
- 活牛信息发布
- 在线交易撮合
- 合同查看和管理
### 阶段四:数据系统和特色功能 (3周)
#### 3.17 数据分析系统 (1周)
- 实时数据采集
- 大数据分析引擎
- 智能预警系统
#### 3.18 大屏可视化系统 (1周)
- 数据图表展示
- 仪表盘设计
- 报表生成和导出
#### 3.19 特色功能实现 (1周)
- 锡林郭勒盟地域元素融入
- 蒙古族文化特色设计
- 安格斯牛品牌突出展示
### 阶段五:测试与部署 (2周)
#### 3.20 测试用例编写 (3天)
- 单元测试编写
- 集成测试实现
- E2E测试配置
#### 3.21 Bug修复与优化 (3天)
- 功能测试与Bug修复
- 性能调优
- 用户体验优化
#### 3.22 部署准备 (3天)
- 生产环境配置
- 构建脚本优化
- 部署文档编写
- Docker配置
#### 3.23 项目验收与交付 (1天)
- 用户验收测试
- 项目文档完善
- 代码交接
- 项目总结
## 4. 团队分工
### 4.1 前端开发团队
- 前端架构师(1名):负责前端架构设计和技术选型
- 官网首页开发工程师(1名):负责官网首页开发
- 专业管理系统开发工程师(4名)负责6个专业管理系统开发
- 大屏可视化开发工程师(1名):负责大屏可视化系统开发
- 小程序开发工程师(3名)负责5个微信小程序开发
- UI设计师(1名):负责界面设计和用户体验优化
### 4.2 后端开发团队
- 后端架构师(1名):负责后端架构设计和技术选型
- API开发工程师(3名)负责后端API服务开发
- 数据库工程师(1名):负责数据库设计和优化
- 运维工程师(1名):负责部署和运维工作
### 4.3 数据分析团队
- 数据分析师(1名):负责数据分析和可视化
- 算法工程师(1名):负责智能预警系统开发
### 4.4 测试团队
- 测试工程师(2名):负责测试用例编写和执行
### 4.5 项目管理
- 项目经理(1名):负责进度管理和协调沟通
- 产品经理(1名):负责需求分析和产品设计
## 5. 风险评估与应对措施
### 5.1 技术风险
- **风险**:新技术学习成本高,可能影响开发进度
- **应对措施**:提前进行技术预研,安排技术培训
### 5.2 人员风险
- **风险**:关键人员流失可能影响项目进度
- **应对措施**:建立知识共享机制,确保文档完整
### 5.3 需求变更风险
- **风险**:需求频繁变更导致返工
- **应对措施**:建立需求变更控制流程,定期评审需求
### 5.4 进度风险
- **风险**:某个模块开发延期影响整体进度
- **应对措施**:设置里程碑检查点,及时调整资源分配
### 5.5 第三方服务风险
- **风险**:腾讯云服务异常或变更可能影响文件存储功能
- **应对措施**:设计抽象层,便于切换云服务提供商
## 6. 质量保证措施
### 6.1 代码质量控制
- 代码审查制度
- ESLint静态检查
- 单元测试覆盖率要求(>80%)
- TypeScript类型检查
### 6.2 文档管理
- 实时更新技术文档
- 维护API文档
- 编写用户手册
- 完善部署文档
### 6.3 版本管理
- Git分支管理策略
- 版本发布流程
- 回滚机制
- 变更日志记录
## 7. 交付物清单
### 7.1 源代码
- 官网首页源代码
- 6个专业管理系统源代码养殖管理、银行监管、保险监管、政府监管、活牛交易、商城管理
- 大屏可视化系统源代码
- 5个微信小程序源代码
- 后端API服务源代码
- 数据库脚本
### 7.2 文档
- 系统架构文档
- API接口文档
- 部署文档
- 用户手册
- 开发规范文档
- 测试报告
### 7.3 配置和脚本
- 构建脚本
- 部署脚本
- Docker配置文件
- 环境配置文件
## 8. 时间安排总览
| 阶段 | 时间 | 任务 |
|------|------|------|
| 阶段一 | 第1-2周 | 项目初始化与基础架构搭建 |
| 阶段二 | 第3-10周 | 核心功能开发 |
| 阶段三 | 第11-14周 | 商城和小程序开发 |
| 阶段四 | 第15-17周 | 数据系统和特色功能 |
| 阶段五 | 第18-19周 | 测试与部署 |
## 9. 里程碑计划
### 9.1 第一里程碑 (第2周末)
- 完成项目基础架构搭建
- 实现基础的用户认证和权限系统
### 9.2 第二里程碑 (第10周末)
- 完成所有专业管理系统核心功能开发
- 实现养殖管理、银行监管、保险监管、政府监管、活牛交易等核心功能
### 9.3 第三里程碑 (第14周末)
- 完成商城管理系统和所有小程序开发
- 实现牛肉商城(含认养功能)、养殖管理、银行监管、保险监管、活牛交易小程序
### 9.4 第四里程碑 (第17周末)
- 完成数据分析系统和大屏可视化系统
- 实现数据可视化和地域文化特色
### 9.5 第五里程碑 (第19周末)
- 完成测试和部署
- 项目正式交付

279
REQUIREMENTS.md Normal file
View File

@@ -0,0 +1,279 @@
# 详细需求文档
## 1. 项目概述
### 1.1 项目名称
xlxumu - 锡林郭勒盟安格斯牛数字化管理平台
### 1.2 项目背景
本项目是面向锡林郭勒盟地区安格斯牛养殖产业的综合性数字化管理平台。通过整合物联网、大数据分析等现代信息技术,构建覆盖养殖、监管、交易、运输、销售全链条的数字化管理体系,提升畜牧业管理效率和透明度。
### 1.3 项目目标
- 构建完整的畜牧业数字化管理生态系统
- 实现养殖过程可视化、监管实时化、交易透明化
- 提升产业链协同效率
- 促进锡林郭勒盟安格斯牛品牌建设
## 2. 功能需求
### 2.1 前端系统
#### 2.1.1 官网首页系统
- 响应式设计适配PC、平板、手机等多种设备
- 突出锡林郭勒盟草原绿色主题和蒙古族文化特色
- 展示安格斯牛品牌信息和产业优势
- 提供平台功能导航入口
#### 2.1.2 专业管理系统Vue.js 3 + Ant Design Vue
##### 养殖管理系统
- 牛只档案管理(品种、年龄、健康状况等)
- 饲养记录管理(饲料、疫苗、治疗等)
- 繁殖管理(配种、产犊等记录)
- 环境监测数据展示(温湿度、空气质量等)
- 生产计划制定和执行跟踪
##### 银行监管系统
- 贷款申请和审批流程管理
- 质押物(牛只)状态监控
- 还款计划跟踪
- 风险评估数据展示
- 财务报表生成
##### 保险监管系统
- 保险投保管理
- 理赔申请和处理流程
- 风险评估和预警
- 保险记录查询
- 数据统计分析
##### 政府监管平台
- 产业数据总览
- 各类监管数据汇总
- 政策发布和通知
- 合规性检查
- 统计报表生成
##### 活牛交易系统
- 牛只信息发布和展示
- 在线交易撮合
- 合同管理
- 支付流程管理
- 交易记录查询
##### 商城管理系统
- 商品信息管理
- 库存管理
- 订单处理
- 物流跟踪
- 售后服务管理
#### 2.1.3 微信小程序矩阵
##### 牛肉商城小程序(消费者端)
- 商品浏览和搜索
- 在线下单和支付
- 订单查询和跟踪
- 售后服务申请
- 评价和反馈
- **认养功能**:用户可以认养特定牛只,跟踪其成长过程
##### 养殖管理小程序(牧民端)
- 移动端牛只档案查看
- 饲养记录录入
- 健康状况上报
- 通知消息接收
- 数据统计查看
##### 银行监管小程序(银行端)
- 移动端贷款审批
- 质押物状态查看
- 风险数据监控
- 移动办公支持
##### 保险监管小程序(保险端)
- 移动端保险处理
- 理赔流程管理
- 风险评估查看
- 移动查勘支持
##### 活牛交易小程序(交易员端)
- 活牛信息发布
- 在线交易撮合
- 合同查看和管理
- 交易记录查询
- 支付状态跟踪
### 2.2 后端系统
#### 2.2.1 API服务
- 用户认证和权限管理接口
- 各业务模块数据接口
- 文件上传和下载接口
- 实时数据推送接口
- 第三方服务集成接口
#### 2.2.2 数据库设计
- 用户和权限管理数据表
- 牛只档案和饲养记录表
- 交易和合同管理表
- 运输和物流跟踪表
- 商城和订单管理表
#### 2.2.3 文件存储
- 牛只图片和视频存储
- 文档和合同文件存储
- 用户上传文件管理
- 腾讯云存储集成
### 2.3 数据分析系统
#### 2.3.1 实时数据采集
- IoT设备数据接入
- 用户行为数据采集
- 业务操作日志收集
#### 2.3.2 大数据分析引擎
- 数据清洗和预处理
- 统计分析模型
- 预测分析算法
#### 2.3.3 智能预警系统
- 异常数据检测
- 风险预警机制
- 预警消息推送
#### 2.3.4 可视化展示平台
- 数据图表展示
- 仪表盘设计
- 报表生成和导出
## 3. 非功能需求
### 3.1 性能需求
- 首页加载时间不超过2秒
- 后台管理系统页面切换响应时间不超过1秒
- 支持1000+并发用户访问
- 实时数据更新延迟不超过5秒
### 3.2 兼容性需求
- 官网首页兼容所有主流浏览器
- 后台管理系统支持Chrome、Firefox、Safari、Edge最新版本
- 微信小程序符合微信平台规范
- 移动端适配iOS和Android系统
### 3.3 安全需求
- 用户密码加密存储BCrypt等
- JWT Token安全传输
- 敏感数据传输加密HTTPS
- 防止SQL注入和XSS攻击
- CSRF防护机制
- API接口限流和防护
- 数据备份和恢复机制
### 3.4 可用性需求
- 系统全年可用性达到99.9%
- 提供友好的错误提示信息
- 实现异常处理和恢复机制
- 支持多端数据同步
### 3.5 可维护性需求
- 微服务架构设计,降低模块间耦合
- 完善的日志记录和监控
- 支持灰度发布和热更新
- 容器化部署支持
## 4. 用户界面需求
### 4.1 设计风格
- 突出锡林郭勒盟草原绿色主题
- 融入蒙古族文化元素
- 简洁、现代的设计风格
- 统一的色彩搭配方案
### 4.2 响应式设计
- 支持PC端大屏显示
- 适配平板设备
- 支持手机端浏览
- 自适应不同分辨率
### 4.3 交互体验
- 提供操作反馈(加载状态、成功/失败提示)
- 实现页面过渡动画
- 支持键盘快捷操作
- 提供搜索和筛选功能
## 5. 数据需求
### 5.1 数据完整性
- 实现数据校验机制
- 提供数据备份和恢复功能
- 确保多端数据一致性
### 5.2 数据安全性
- 敏感数据加密存储
- 实现数据访问权限控制
- 提供数据审计功能
- 符合相关法规要求
## 6. 部署需求
### 6.1 部署环境
- 支持Docker容器化部署
- 支持云平台部署(腾讯云)
- 支持负载均衡部署
- 提供部署文档和脚本
### 6.2 监控需求
- 实现系统运行状态监控
- 提供性能监控指标
- 支持异常告警功能
- 日志收集和分析
## 7. 特色需求
### 7.1 地域文化特色
- 界面设计融入蒙古族文化元素
- 突出锡林郭勒盟草原特色
- 体现当地畜牧业传统和现代结合
### 7.2 品牌专业化
- 突出安格斯牛品牌特色
- 专门的安格斯牛管理和交易模块
- 品牌化展示和推广
### 7.3 生态理念
- 绿色发展理念贯穿整个系统
- 可持续畜牧业理念体现
- 环保数据监控和展示
## 8. 测试需求
### 8.1 单元测试
- 核心功能模块单元测试覆盖率不低于80%
- 提供自动化测试脚本
### 8.2 集成测试
- 实现主要业务流程的集成测试
- 提供测试用例文档
### 8.3 用户验收测试
- 提供用户验收测试计划
- 收集用户反馈并优化
## 9. 运维需求
### 9.1 日志管理
- 记录系统运行日志
- 提供日志查询和分析功能
- 实现日志轮转和清理
### 9.2 性能监控
- 监控系统资源使用情况
- 提供性能分析报告
- 实现性能瓶颈预警
### 9.3 故障处理
- 提供故障诊断工具
- 实现自动故障恢复机制
- 提供故障处理文档

25
backend/api/.env.example Normal file
View File

@@ -0,0 +1,25 @@
# 服务器配置
PORT=8000
# 数据库配置
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=password
DB_NAME=xlxumu
DB_PORT=3306
# JWT配置
JWT_SECRET=your_jwt_secret_key_here
JWT_EXPIRES_IN=24h
# 腾讯云存储配置
TENCENT_CLOUD_SECRET_ID=your_secret_id
TENCENT_CLOUD_SECRET_KEY=your_secret_key
TENCENT_CLOUD_BUCKET=your_bucket_name
TENCENT_CLOUD_REGION=your_region
# 日志配置
LOG_LEVEL=info
# 其他配置
NODE_ENV=development

30
backend/api/package.json Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "xlxumu-api",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛数字化管理平台API服务",
"author": "xlxumu team",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.0",
"cors": "^2.8.5",
"helmet": "^6.0.0",
"dotenv": "^16.0.0",
"jsonwebtoken": "^9.0.0",
"bcryptjs": "^2.4.3",
"mysql2": "^3.0.0",
"sequelize": "^6.0.0",
"joi": "^17.0.0",
"winston": "^3.8.0",
"express-rate-limit": "^6.7.0"
},
"devDependencies": {
"nodemon": "^2.0.0",
"jest": "^29.0.0",
"supertest": "^6.3.0"
}
}

48
backend/api/server.js Normal file
View File

@@ -0,0 +1,48 @@
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const dotenv = require('dotenv');
const rateLimit = require('express-rate-limit');
// 加载环境变量
dotenv.config();
// 创建Express应用
const app = express();
const PORT = process.env.PORT || 8000;
// 中间件
app.use(helmet()); // 安全头部
app.use(cors()); // 跨域支持
app.use(express.json({ limit: '10mb' })); // JSON解析
app.use(express.urlencoded({ extended: true, limit: '10mb' })); // URL编码解析
// 速率限制
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 限制每个IP 15分钟内最多100个请求
message: '请求过于频繁,请稍后再试'
});
app.use(limiter);
// 基础路由
app.get('/', (req, res) => {
res.json({
message: '欢迎使用锡林郭勒盟安格斯牛数字化管理平台API服务',
version: '1.0.0'
});
});
app.get('/health', (req, res) => {
res.json({
status: 'OK',
timestamp: new Date().toISOString()
});
});
// 启动服务器
app.listen(PORT, () => {
console.log(`API服务器正在端口 ${PORT} 上运行`);
});
module.exports = app;

900
backend/database/DESIGN.md Normal file
View File

@@ -0,0 +1,900 @@
# 数据库详细设计
## 概述
本项目使用MySQL作为主要的关系型数据库存储用户信息、牛只档案、交易记录、监管数据等核心业务数据。
## 数据库设计规范
1. 使用InnoDB存储引擎
2. 字符集使用utf8mb4
3. 所有表都有创建时间和更新时间字段
4. 主键使用自增ID
5. 外键约束用于保证数据一致性
6. 表名使用复数形式,以下划线分隔单词
7. 字段名使用下划线分隔单词
8. 所有表都包含`created_at``updated_at`时间戳字段
## 核心数据表设计
### 1. 用户表 (users)
存储系统用户信息,包括牧民、银行职员、保险员、政府监管人员等。
```sql
CREATE TABLE 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 '密码哈希值',
real_name VARCHAR(50) COMMENT '真实姓名',
avatar_url VARCHAR(255) COMMENT '头像URL',
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='用户表';
```
### 2. 角色表 (roles)
存储系统角色信息,如管理员、牧民、银行职员等。
```sql
CREATE TABLE 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='角色表';
```
### 3. 用户角色关联表 (user_roles)
存储用户和角色的多对多关系。
```sql
CREATE TABLE 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='用户角色关联表';
```
### 4. 权限表 (permissions)
存储系统权限信息。
```sql
CREATE TABLE 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='权限表';
```
### 5. 角色权限关联表 (role_permissions)
存储角色和权限的多对多关系。
```sql
CREATE TABLE 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='角色权限关联表';
```
### 6. 牛只档案表 (cattle)
存储牛只基本信息,包括品种、年龄、健康状况等。
```sql
CREATE TABLE 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='牛只档案表';
```
### 7. 饲养记录表 (feeding_records)
存储牛只饲养记录,包括饲料、疫苗、治疗等信息。
```sql
CREATE TABLE 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='饲养记录表';
```
### 8. 繁殖记录表 (breeding_records)
存储牛只繁殖相关信息。
```sql
CREATE TABLE 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='繁殖记录表';
```
### 9. 环境监测表 (environment_monitoring)
存储牧场环境监测数据。
```sql
CREATE TABLE 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='环境监测表';
```
### 10. 交易记录表 (transactions)
存储活牛交易记录。
```sql
CREATE TABLE 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='交易记录表';
```
### 11. 合同表 (contracts)
存储交易合同信息。
```sql
CREATE TABLE 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='合同表';
```
### 12. 商品表 (products)
存储牛肉商城商品信息。
```sql
CREATE TABLE 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='商品表';
```
### 13. 商品分类表 (product_categories)
存储商品分类信息。
```sql
CREATE TABLE 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='商品分类表';
```
### 14. 订单表 (orders)
存储用户订单信息。
```sql
CREATE TABLE 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='订单表';
```
### 15. 订单项表 (order_items)
存储订单详情信息。
```sql
CREATE TABLE 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='订单项表';
```
### 16. 物流跟踪表 (logistics_tracking)
存储物流跟踪信息。
```sql
CREATE TABLE 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='物流跟踪表';
```
### 17. 贷款申请表 (loan_applications)
存储银行贷款申请信息。
```sql
CREATE TABLE 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='贷款申请表';
```
### 18. 保险申请表 (insurance_applications)
存储保险申请信息。
```sql
CREATE TABLE 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='保险申请表';
```
### 19. 理赔申请表 (claims)
存储保险理赔信息。
```sql
CREATE TABLE 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='理赔申请表';
```
### 20. 政府监管报告表 (government_reports)
存储政府监管报告信息。
```sql
CREATE TABLE 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='政府监管报告表';
```
## 数据库关系图
```mermaid
erDiagram
users ||--o{ user_roles : has
roles ||--o{ user_roles : includes
roles ||--o{ role_permissions : has
permissions ||--o{ role_permissions : includes
users ||--o{ cattle : owns
cattle ||--o{ feeding_records : has
cattle ||--o{ breeding_records : has
cattle ||--o{ transactions : involved_in
users ||--o{ transactions : involved_in
contracts ||--o{ transactions : related_to
cattle ||--o{ products : related_to
product_categories ||--o{ products : belongs_to
users ||--o{ orders : places
orders ||--o{ order_items : contains
products ||--o{ order_items : contains
cattle ||--o{ order_items : related_to
orders ||--o{ logistics_tracking : has
users ||--o{ loan_applications : applies
users ||--o{ loan_applications : reviews
cattle ||--o{ loan_applications : pledged
users ||--o{ insurance_applications : applies
users ||--o{ insurance_applications : underwrites
cattle ||--o{ insurance_applications : insured
insurance_applications ||--o{ claims : has
users ||--o{ claims : applies
users ||--o{ claims : reviews
users ||--o{ government_reports : submits
users ||--o{ government_reports : approves
users {
BIGINT id PK
VARCHAR username
VARCHAR email
VARCHAR phone
VARCHAR password_hash
VARCHAR real_name
VARCHAR avatar_url
ENUM user_type
TINYINT status
TIMESTAMP last_login
TIMESTAMP created_at
TIMESTAMP updated_at
}
roles {
INT id PK
VARCHAR name
TEXT description
TIMESTAMP created_at
TIMESTAMP updated_at
}
user_roles {
BIGINT id PK
BIGINT user_id FK
INT role_id FK
TIMESTAMP created_at
}
permissions {
INT id PK
VARCHAR name
TEXT description
VARCHAR module
TIMESTAMP created_at
TIMESTAMP updated_at
}
role_permissions {
BIGINT id PK
INT role_id FK
INT permission_id FK
TIMESTAMP created_at
}
cattle {
BIGINT id PK
VARCHAR ear_tag
VARCHAR name
VARCHAR breed
ENUM gender
DATE birth_date
VARCHAR color
DECIMAL weight
ENUM health_status
BIGINT owner_id FK
VARCHAR farm_location
ENUM status
VARCHAR image_url
VARCHAR qr_code_url
TIMESTAMP created_at
TIMESTAMP updated_at
}
feeding_records {
BIGINT id PK
BIGINT cattle_id FK
ENUM record_type
VARCHAR feed_type
DECIMAL feed_amount
VARCHAR vaccine_name
TEXT treatment_desc
VARCHAR medicine_name
VARCHAR dosage
VARCHAR veterinarian
DECIMAL cost
DATE record_date
TEXT notes
BIGINT operator_id FK
TIMESTAMP created_at
TIMESTAMP updated_at
}
breeding_records {
BIGINT id PK
BIGINT cattle_id FK
ENUM breeding_method
DATE breeding_date
BIGINT breeding_male_id FK
VARCHAR semen_code
DATE expected_delivery_date
DATE actual_delivery_date
TINYINT calf_count
JSON calf_ids
ENUM breeding_result
TEXT notes
BIGINT operator_id FK
TIMESTAMP created_at
TIMESTAMP updated_at
}
environment_monitoring {
BIGINT id PK
VARCHAR location
DECIMAL temperature
DECIMAL humidity
VARCHAR air_quality
DECIMAL ammonia_concentration
DECIMAL carbon_dioxide
DECIMAL noise_level
DECIMAL light_intensity
DATETIME monitoring_date
TIMESTAMP created_at
TIMESTAMP updated_at
}
transactions {
BIGINT id PK
BIGINT cattle_id FK
BIGINT seller_id FK
BIGINT buyer_id FK
ENUM transaction_type
DECIMAL price
VARCHAR currency
DATETIME transaction_date
BIGINT contract_id FK
ENUM status
ENUM payment_status
ENUM delivery_status
TEXT notes
TIMESTAMP created_at
TIMESTAMP updated_at
}
contracts {
BIGINT id PK
VARCHAR contract_number
BIGINT seller_id FK
BIGINT buyer_id FK
JSON cattle_details
DECIMAL total_price
VARCHAR currency
DATE contract_date
DATE effective_date
DATE expiry_date
TEXT payment_terms
TEXT delivery_terms
ENUM contract_status
VARCHAR contract_file_url
TEXT notes
TIMESTAMP created_at
TIMESTAMP updated_at
}
products {
BIGINT id PK
VARCHAR name
TEXT description
INT category_id FK
VARCHAR sku
DECIMAL price
DECIMAL original_price
VARCHAR currency
INT stock_quantity
INT min_stock
VARCHAR unit
DECIMAL weight
VARCHAR origin
DATE production_date
DATE expiration_date
BIGINT cattle_id FK
ENUM status
JSON image_urls
JSON tags
TIMESTAMP created_at
TIMESTAMP updated_at
}
product_categories {
INT id PK
VARCHAR name
INT parent_id
TINYINT level
INT sort_order
VARCHAR image_url
TINYINT status
TIMESTAMP created_at
TIMESTAMP updated_at
}
orders {
BIGINT id PK
VARCHAR order_number
BIGINT user_id FK
DECIMAL total_amount
VARCHAR currency
ENUM order_status
ENUM payment_status
ENUM shipping_status
VARCHAR receiver_name
VARCHAR receiver_phone
TEXT receiver_address
VARCHAR shipping_method
DECIMAL shipping_fee
TEXT notes
VARCHAR payment_method
TIMESTAMP paid_at
TIMESTAMP shipped_at
TIMESTAMP delivered_at
TIMESTAMP cancelled_at
TIMESTAMP created_at
TIMESTAMP updated_at
}
order_items {
BIGINT id PK
BIGINT order_id FK
BIGINT product_id FK
INT quantity
DECIMAL unit_price
DECIMAL total_price
BIGINT cattle_id FK
TIMESTAMP created_at
TIMESTAMP updated_at
}
logistics_tracking {
BIGINT id PK
BIGINT order_id FK
VARCHAR tracking_number
VARCHAR carrier
ENUM status
VARCHAR origin
VARCHAR destination
DATE estimated_delivery_date
DATE actual_delivery_date
VARCHAR current_location
JSON tracking_info
TIMESTAMP created_at
TIMESTAMP updated_at
}
loan_applications {
BIGINT id PK
BIGINT applicant_id FK
ENUM loan_type
JSON cattle_ids
DECIMAL loan_amount
VARCHAR currency
DECIMAL interest_rate
INT term_months
TEXT purpose
ENUM repayment_method
ENUM guarantee_type
ENUM status
BIGINT reviewer_id FK
TEXT review_notes
DECIMAL approved_amount
TIMESTAMP approved_date
TIMESTAMP disbursement_date
JSON repayment_schedule
TIMESTAMP created_at
TIMESTAMP updated_at
}
insurance_applications {
BIGINT id PK
BIGINT applicant_id FK
ENUM insurance_type
JSON cattle_ids
VARCHAR policy_number
DECIMAL insured_amount
DECIMAL premium
VARCHAR currency
DATE start_date
DATE end_date
ENUM status
BIGINT underwriter_id FK
TEXT underwriting_notes
VARCHAR policy_file_url
TIMESTAMP created_at
TIMESTAMP updated_at
}
claims {
BIGINT id PK
BIGINT insurance_id FK
BIGINT applicant_id FK
DECIMAL claim_amount
VARCHAR currency
DATE incident_date
ENUM incident_type
TEXT description
JSON evidence_files
ENUM status
BIGINT reviewer_id FK
TEXT review_notes
DECIMAL approved_amount
DECIMAL paid_amount
TIMESTAMP submitted_at
TIMESTAMP reviewed_at
TIMESTAMP approved_at
TIMESTAMP paid_at
TIMESTAMP created_at
TIMESTAMP updated_at
}
government_reports {
BIGINT id PK
ENUM report_type
BIGINT reporter_id FK
DATE reporting_period_start
DATE reporting_period_end
JSON data_content
TEXT summary
ENUM status
BIGINT approver_id FK
TEXT approval_notes
TIMESTAMP submitted_at
TIMESTAMP approved_at
TIMESTAMP created_at
TIMESTAMP updated_at
}
```

View File

@@ -0,0 +1,49 @@
# 数据库设计
## 概述
本项目使用MySQL作为主要的关系型数据库存储用户信息、牛只档案、交易记录、监管数据等核心业务数据。
## 数据库设计规范
1. 使用InnoDB存储引擎
2. 字符集使用utf8mb4
3. 所有表都有创建时间和更新时间字段
4. 主键使用自增ID
5. 外键约束用于保证数据一致性
## 核心数据表
### 1. 用户表 (users)
存储系统用户信息,包括牧民、银行职员、保险员、政府监管人员等。
### 2. 角色表 (roles)
存储系统角色信息,如管理员、牧民、银行职员等。
### 3. 权限表 (permissions)
存储系统权限信息。
### 4. 牛只档案表 (cattle)
存储牛只基本信息,包括品种、年龄、健康状况等。
### 5. 饲养记录表 (feeding_records)
存储牛只饲养记录,包括饲料、疫苗、治疗等信息。
### 6. 繁殖记录表 (breeding_records)
存储牛只繁殖相关信息。
### 7. 交易记录表 (transactions)
存储活牛交易记录。
### 8. 合同表 (contracts)
存储交易合同信息。
### 9. 商品表 (products)
存储牛肉商城商品信息。
### 10. 订单表 (orders)
存储用户订单信息。
## 数据库脚本
数据库初始化脚本和迁移脚本将存放在此目录中。

42
backend/utils/README.md Normal file
View File

@@ -0,0 +1,42 @@
# 工具类
## 概述
本目录包含项目中使用的各种工具函数和辅助类。
## 工具分类
### 1. 认证工具 (auth.js)
- JWT令牌生成和验证
- 密码加密和验证
- 用户身份验证
### 2. 文件处理工具 (file.js)
- 腾讯云存储集成
- 文件上传和下载
- 图片处理
### 3. 数据验证工具 (validation.js)
- 请求参数验证
- 数据格式校验
### 4. 日志工具 (logger.js)
- 系统日志记录
- 错误日志处理
### 5. 邮件工具 (email.js)
- 邮件发送功能
- 邮件模板
### 6. 短信工具 (sms.js)
- 短信发送功能
- 验证码生成
### 7. 工具函数 (helpers.js)
- 通用工具函数
- 数据处理函数
- 时间处理函数
## 使用说明
所有工具函数都应该是无状态的纯函数,便于测试和复用。

215
deployment/README.md Normal file
View File

@@ -0,0 +1,215 @@
# 部署指南
## 概述
本文档描述了锡林郭勒盟安格斯牛数字化管理平台的部署流程和配置要求。
## 部署架构
```
┌─────────────────────────────────────────────────────────────────────┐
│ 负载均衡器 │
├─────────────────────────────────────────────────────────────────────┤
│ Web服务器 (Nginx) │
├─────────────────────────────────────────────────────────────────────┤
│ 前端静态文件 │ 后端API服务 (Node.js) │
├─────────────────────────────────────────────────────────────────────┤
│ MySQL数据库 │ 腾讯云对象存储 │
└─────────────────────────────────────────────────────────────────────┘
```
## 环境要求
### 服务器要求
- 操作系统: Linux (推荐Ubuntu 20.04+ 或 CentOS 8+)
- 内存: 8GB+
- 存储: 100GB+
- CPU: 4核+
### 软件依赖
- Node.js 16+
- MySQL 8.0+
- Nginx 1.20+
- Docker (可选,用于容器化部署)
- Git
## 部署步骤
### 1. 数据库部署
```bash
# 安装MySQL
sudo apt update
sudo apt install mysql-server
# 创建数据库
mysql -u root -p
CREATE DATABASE xlxumu CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 创建用户并授权
CREATE USER 'xlxumu'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON xlxumu.* TO 'xlxumu'@'localhost';
FLUSH PRIVILEGES;
```
### 2. 后端API服务部署
```bash
# 克隆代码
git clone [repository_url] /opt/xlxumu
cd /opt/xlxumu/backend/api
# 安装依赖
npm install
# 配置环境变量
cp .env.example .env
# 编辑.env文件配置数据库连接等信息
# 启动服务
npm start
```
### 3. 前端应用部署
```bash
# 构建各个前端应用
cd /opt/xlxumu/frontend/website
# 构建静态网站
cd /opt/xlxumu/frontend/farming-management
npm install
npm run build
# 为其他管理系统执行相同操作
```
### 4. Nginx配置
```nginx
server {
listen 80;
server_name your_domain.com;
# 静态网站
location / {
root /opt/xlxumu/frontend/website/dist;
index index.html;
try_files $uri $uri/ =404;
}
# API代理
location /api/ {
proxy_pass http://localhost:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 各个管理系统
location /farming-management/ {
alias /opt/xlxumu/frontend/farming-management/dist/;
try_files $uri $uri/ /farming-management/index.html;
}
# 为其他管理系统添加类似配置
}
```
## 容器化部署 (Docker)
### Docker Compose配置
```yaml
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: xlxumu
MYSQL_USER: xlxumu
MYSQL_PASSWORD: user_password
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
api:
build: ./backend/api
ports:
- "8000:8000"
environment:
- DB_HOST=mysql
- DB_USER=xlxumu
- DB_PASSWORD=user_password
- DB_NAME=xlxumu
depends_on:
- mysql
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./frontend:/usr/share/nginx/html
depends_on:
- api
volumes:
mysql_data:
```
## 监控和日志
### 日志管理
- 应用日志: `/var/log/xlxumu/`
- Nginx日志: `/var/log/nginx/`
- MySQL日志: `/var/log/mysql/`
### 监控指标
- API响应时间
- 数据库查询性能
- 服务器资源使用率
- 用户访问统计
## 安全配置
### SSL证书
推荐使用Let's Encrypt免费SSL证书:
```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your_domain.com
```
### 防火墙配置
```bash
# 开放必要端口
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
```
## 备份策略
### 数据库备份
```bash
# 定时备份脚本
mysqldump -u xlxumu -p xlxumu > /backup/xlxumu_$(date +%Y%m%d).sql
```
### 文件备份
- 静态资源文件备份
- 配置文件备份
- 日志文件轮转
## 故障处理
### 常见问题
1. 数据库连接失败
2. API服务无响应
3. 前端页面加载缓慢
4. 权限认证问题
### 恢复流程
1. 检查服务状态
2. 查看日志文件
3. 恢复备份数据
4. 重启相关服务

39
docs/README.md Normal file
View File

@@ -0,0 +1,39 @@
# 项目文档
## 概述
本文档目录包含了锡林郭勒盟安格斯牛数字化管理平台的所有相关文档。
## 文档列表
### 1. 架构文档
- [系统架构文档](../ARCHITECTURE.md) - 系统整体架构设计
- [详细需求文档](../REQUIREMENTS.md) - 功能和非功能需求说明
- [开发计划文档](../DEVELOPMENT_PLAN.md) - 项目开发计划和时间安排
### 2. 技术文档
- API接口文档 (待编写)
- 数据库设计文档 (位于[backend/database](file:///Users/ainongkeji/code/vue/xlxumu/backend/database)目录)
- 前端组件文档 (各前端项目中)
- 部署文档 ([deployment/README.md](file:///Users/ainongkeji/code/vue/xlxumu/deployment/README.md))
### 3. 用户文档
- 用户手册 (待编写)
- 管理员手册 (待编写)
- 操作指南 (待编写)
### 4. 其他文档
- 测试报告 (待编写)
- 项目总结报告 (待编写)
## 文档维护
所有文档应保持最新状态,与代码实现保持一致。当功能发生变化时,应及时更新相关文档。
## 贡献指南
如果您需要更新文档,请遵循以下步骤:
1. Fork项目仓库
2. 创建新的文档分支
3. 进行文档修改
4. 提交Pull Request

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3002,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3005,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3007,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3001,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3004,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3003,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>养殖管理系统 - 锡林郭勒盟安格斯牛数字化管理平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"name": "farming-management",
"version": "1.0.0",
"description": "锡林郭勒盟安格斯牛养殖管理系统",
"author": "xlxumu team",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.0",
"vue-router": "^4.0.0",
"ant-design-vue": "^3.0.0",
"pinia": "^2.0.0",
"echarts": "^5.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.0",
"vite": "^3.0.0",
"typescript": "^4.0.0",
"@types/node": "^18.0.0"
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
height: 100vh;
}
</style>

View File

@@ -0,0 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import App from './App.vue'
import router from './router'
import 'ant-design-vue/dist/antd.css'
import './styles/global.css'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')

View File

@@ -0,0 +1,97 @@
/* 全局样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 通用按钮样式 */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
.btn-secondary {
background-color: var(--accent-color);
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
/* 通用卡片样式 */
.card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin-bottom: 1.5rem;
}
/* 通用表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
}

View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 3006,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})

View File

@@ -0,0 +1,80 @@
App({
onLaunch() {
// 小程序初始化
console.log('牛肉商城小程序初始化');
// 检查登录状态
this.checkLoginStatus();
},
onShow() {
// 小程序显示
console.log('牛肉商城小程序显示');
},
onHide() {
// 小程序隐藏
console.log('牛肉商城小程序隐藏');
},
onError(msg) {
// 错误处理
console.log('小程序发生错误:', msg);
},
globalData: {
userInfo: null,
token: null,
baseUrl: 'http://localhost:8000/api'
},
// 检查登录状态
checkLoginStatus() {
try {
const token = wx.getStorageSync('token');
if (token) {
this.globalData.token = token;
// 验证token有效性
this.verifyToken(token);
}
} catch (e) {
console.error('检查登录状态失败:', e);
}
},
// 验证token
verifyToken(token) {
wx.request({
url: `${this.globalData.baseUrl}/auth/verify`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
},
success: (res) => {
if (res.data.valid) {
this.globalData.userInfo = res.data.user;
} else {
// token无效清除本地存储
wx.removeStorageSync('token');
this.globalData.token = null;
this.globalData.userInfo = null;
}
},
fail: (err) => {
console.error('验证token失败', err);
}
});
},
// 登录方法
login(userInfo) {
this.globalData.userInfo = userInfo;
},
// 登出方法
logout() {
this.globalData.userInfo = null;
this.globalData.token = null;
wx.removeStorageSync('token');
}
})

View File

@@ -0,0 +1,59 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/cart/cart",
"pages/profile/profile",
"pages/product/detail",
"pages/order/list",
"pages/order/detail",
"pages/adopt/list",
"pages/adopt/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4CAF50",
"navigationBarTitleText": "锡林郭勒盟安格斯牛",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#4CAF50",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "assets/icons/home.png",
"selectedIconPath": "assets/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "assets/icons/category.png",
"selectedIconPath": "assets/icons/category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "assets/icons/cart.png",
"selectedIconPath": "assets/icons/cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/profile/profile",
"iconPath": "assets/icons/profile.png",
"selectedIconPath": "assets/icons/profile-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"requiredPrivateInfos": []
}

View File

@@ -0,0 +1,174 @@
/* 全局样式 */
page {
background-color: #f5f5f5;
font-size: 28rpx;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
}
/* 通用样式类 */
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
.text-primary {
color: #4CAF50;
}
.text-secondary {
color: #388E3C;
}
.text-accent {
color: #FF9800;
}
.bg-white {
background-color: #ffffff;
}
.padding {
padding: 20rpx;
}
.padding-horizontal {
padding-left: 20rpx;
padding-right: 20rpx;
}
.padding-vertical {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.margin {
margin: 20rpx;
}
.margin-horizontal {
margin-left: 20rpx;
margin-right: 20rpx;
}
.margin-vertical {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
/* 按钮样式 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 30rpx;
border-radius: 10rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #388E3C;
}
.btn-secondary {
background-color: #FF9800;
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
.btn-block {
width: 100%;
}
/* 卡片样式 */
.card {
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
margin: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 表单样式 */
.form-group {
margin-bottom: 30rpx;
}
.form-group label {
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.form-group input,
.form-group picker,
.form-group textarea {
width: 100%;
padding: 20rpx;
border: 2rpx solid #ddd;
border-radius: 10rpx;
font-size: 28rpx;
}
/* 加载动画 */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx;
}
.spinner {
width: 50rpx;
height: 50rpx;
border: 5rpx solid #f3f3f3;
border-top: 5rpx solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,52 @@
{
"description": "牛肉商城小程序",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"bundle": false,
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
},
"compileType": "miniprogram",
"libVersion": "2.24.7",
"appid": "wxa123456789012345",
"projectname": "beef-mall",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -0,0 +1,80 @@
App({
onLaunch() {
// 小程序初始化
console.log('牛肉商城小程序初始化');
// 检查登录状态
this.checkLoginStatus();
},
onShow() {
// 小程序显示
console.log('牛肉商城小程序显示');
},
onHide() {
// 小程序隐藏
console.log('牛肉商城小程序隐藏');
},
onError(msg) {
// 错误处理
console.log('小程序发生错误:', msg);
},
globalData: {
userInfo: null,
token: null,
baseUrl: 'http://localhost:8000/api'
},
// 检查登录状态
checkLoginStatus() {
try {
const token = wx.getStorageSync('token');
if (token) {
this.globalData.token = token;
// 验证token有效性
this.verifyToken(token);
}
} catch (e) {
console.error('检查登录状态失败:', e);
}
},
// 验证token
verifyToken(token) {
wx.request({
url: `${this.globalData.baseUrl}/auth/verify`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
},
success: (res) => {
if (res.data.valid) {
this.globalData.userInfo = res.data.user;
} else {
// token无效清除本地存储
wx.removeStorageSync('token');
this.globalData.token = null;
this.globalData.userInfo = null;
}
},
fail: (err) => {
console.error('验证token失败', err);
}
});
},
// 登录方法
login(userInfo) {
this.globalData.userInfo = userInfo;
},
// 登出方法
logout() {
this.globalData.userInfo = null;
this.globalData.token = null;
wx.removeStorageSync('token');
}
})

View File

@@ -0,0 +1,59 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/cart/cart",
"pages/profile/profile",
"pages/product/detail",
"pages/order/list",
"pages/order/detail",
"pages/adopt/list",
"pages/adopt/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4CAF50",
"navigationBarTitleText": "锡林郭勒盟安格斯牛",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#4CAF50",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "assets/icons/home.png",
"selectedIconPath": "assets/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "assets/icons/category.png",
"selectedIconPath": "assets/icons/category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "assets/icons/cart.png",
"selectedIconPath": "assets/icons/cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/profile/profile",
"iconPath": "assets/icons/profile.png",
"selectedIconPath": "assets/icons/profile-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"requiredPrivateInfos": []
}

View File

@@ -0,0 +1,174 @@
/* 全局样式 */
page {
background-color: #f5f5f5;
font-size: 28rpx;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
}
/* 通用样式类 */
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
.text-primary {
color: #4CAF50;
}
.text-secondary {
color: #388E3C;
}
.text-accent {
color: #FF9800;
}
.bg-white {
background-color: #ffffff;
}
.padding {
padding: 20rpx;
}
.padding-horizontal {
padding-left: 20rpx;
padding-right: 20rpx;
}
.padding-vertical {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.margin {
margin: 20rpx;
}
.margin-horizontal {
margin-left: 20rpx;
margin-right: 20rpx;
}
.margin-vertical {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
/* 按钮样式 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 30rpx;
border-radius: 10rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #388E3C;
}
.btn-secondary {
background-color: #FF9800;
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
.btn-block {
width: 100%;
}
/* 卡片样式 */
.card {
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
margin: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 表单样式 */
.form-group {
margin-bottom: 30rpx;
}
.form-group label {
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.form-group input,
.form-group picker,
.form-group textarea {
width: 100%;
padding: 20rpx;
border: 2rpx solid #ddd;
border-radius: 10rpx;
font-size: 28rpx;
}
/* 加载动画 */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx;
}
.spinner {
width: 50rpx;
height: 50rpx;
border: 5rpx solid #f3f3f3;
border-top: 5rpx solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,52 @@
{
"description": "牛肉商城小程序",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"bundle": false,
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
},
"compileType": "miniprogram",
"libVersion": "2.24.7",
"appid": "wxa123456789012345",
"projectname": "beef-mall",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -0,0 +1,80 @@
App({
onLaunch() {
// 小程序初始化
console.log('牛肉商城小程序初始化');
// 检查登录状态
this.checkLoginStatus();
},
onShow() {
// 小程序显示
console.log('牛肉商城小程序显示');
},
onHide() {
// 小程序隐藏
console.log('牛肉商城小程序隐藏');
},
onError(msg) {
// 错误处理
console.log('小程序发生错误:', msg);
},
globalData: {
userInfo: null,
token: null,
baseUrl: 'http://localhost:8000/api'
},
// 检查登录状态
checkLoginStatus() {
try {
const token = wx.getStorageSync('token');
if (token) {
this.globalData.token = token;
// 验证token有效性
this.verifyToken(token);
}
} catch (e) {
console.error('检查登录状态失败:', e);
}
},
// 验证token
verifyToken(token) {
wx.request({
url: `${this.globalData.baseUrl}/auth/verify`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
},
success: (res) => {
if (res.data.valid) {
this.globalData.userInfo = res.data.user;
} else {
// token无效清除本地存储
wx.removeStorageSync('token');
this.globalData.token = null;
this.globalData.userInfo = null;
}
},
fail: (err) => {
console.error('验证token失败', err);
}
});
},
// 登录方法
login(userInfo) {
this.globalData.userInfo = userInfo;
},
// 登出方法
logout() {
this.globalData.userInfo = null;
this.globalData.token = null;
wx.removeStorageSync('token');
}
})

View File

@@ -0,0 +1,59 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/cart/cart",
"pages/profile/profile",
"pages/product/detail",
"pages/order/list",
"pages/order/detail",
"pages/adopt/list",
"pages/adopt/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4CAF50",
"navigationBarTitleText": "锡林郭勒盟安格斯牛",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#4CAF50",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "assets/icons/home.png",
"selectedIconPath": "assets/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "assets/icons/category.png",
"selectedIconPath": "assets/icons/category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "assets/icons/cart.png",
"selectedIconPath": "assets/icons/cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/profile/profile",
"iconPath": "assets/icons/profile.png",
"selectedIconPath": "assets/icons/profile-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"requiredPrivateInfos": []
}

View File

@@ -0,0 +1,174 @@
/* 全局样式 */
page {
background-color: #f5f5f5;
font-size: 28rpx;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
}
/* 通用样式类 */
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
.text-primary {
color: #4CAF50;
}
.text-secondary {
color: #388E3C;
}
.text-accent {
color: #FF9800;
}
.bg-white {
background-color: #ffffff;
}
.padding {
padding: 20rpx;
}
.padding-horizontal {
padding-left: 20rpx;
padding-right: 20rpx;
}
.padding-vertical {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.margin {
margin: 20rpx;
}
.margin-horizontal {
margin-left: 20rpx;
margin-right: 20rpx;
}
.margin-vertical {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
/* 按钮样式 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 30rpx;
border-radius: 10rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #388E3C;
}
.btn-secondary {
background-color: #FF9800;
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
.btn-block {
width: 100%;
}
/* 卡片样式 */
.card {
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
margin: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 表单样式 */
.form-group {
margin-bottom: 30rpx;
}
.form-group label {
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.form-group input,
.form-group picker,
.form-group textarea {
width: 100%;
padding: 20rpx;
border: 2rpx solid #ddd;
border-radius: 10rpx;
font-size: 28rpx;
}
/* 加载动画 */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx;
}
.spinner {
width: 50rpx;
height: 50rpx;
border: 5rpx solid #f3f3f3;
border-top: 5rpx solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,52 @@
{
"description": "牛肉商城小程序",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"bundle": false,
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
},
"compileType": "miniprogram",
"libVersion": "2.24.7",
"appid": "wxa123456789012345",
"projectname": "beef-mall",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -0,0 +1,80 @@
App({
onLaunch() {
// 小程序初始化
console.log('牛肉商城小程序初始化');
// 检查登录状态
this.checkLoginStatus();
},
onShow() {
// 小程序显示
console.log('牛肉商城小程序显示');
},
onHide() {
// 小程序隐藏
console.log('牛肉商城小程序隐藏');
},
onError(msg) {
// 错误处理
console.log('小程序发生错误:', msg);
},
globalData: {
userInfo: null,
token: null,
baseUrl: 'http://localhost:8000/api'
},
// 检查登录状态
checkLoginStatus() {
try {
const token = wx.getStorageSync('token');
if (token) {
this.globalData.token = token;
// 验证token有效性
this.verifyToken(token);
}
} catch (e) {
console.error('检查登录状态失败:', e);
}
},
// 验证token
verifyToken(token) {
wx.request({
url: `${this.globalData.baseUrl}/auth/verify`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
},
success: (res) => {
if (res.data.valid) {
this.globalData.userInfo = res.data.user;
} else {
// token无效清除本地存储
wx.removeStorageSync('token');
this.globalData.token = null;
this.globalData.userInfo = null;
}
},
fail: (err) => {
console.error('验证token失败', err);
}
});
},
// 登录方法
login(userInfo) {
this.globalData.userInfo = userInfo;
},
// 登出方法
logout() {
this.globalData.userInfo = null;
this.globalData.token = null;
wx.removeStorageSync('token');
}
})

View File

@@ -0,0 +1,59 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/cart/cart",
"pages/profile/profile",
"pages/product/detail",
"pages/order/list",
"pages/order/detail",
"pages/adopt/list",
"pages/adopt/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4CAF50",
"navigationBarTitleText": "锡林郭勒盟安格斯牛",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#4CAF50",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "assets/icons/home.png",
"selectedIconPath": "assets/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "assets/icons/category.png",
"selectedIconPath": "assets/icons/category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "assets/icons/cart.png",
"selectedIconPath": "assets/icons/cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/profile/profile",
"iconPath": "assets/icons/profile.png",
"selectedIconPath": "assets/icons/profile-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"requiredPrivateInfos": []
}

View File

@@ -0,0 +1,174 @@
/* 全局样式 */
page {
background-color: #f5f5f5;
font-size: 28rpx;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
}
/* 通用样式类 */
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
.text-primary {
color: #4CAF50;
}
.text-secondary {
color: #388E3C;
}
.text-accent {
color: #FF9800;
}
.bg-white {
background-color: #ffffff;
}
.padding {
padding: 20rpx;
}
.padding-horizontal {
padding-left: 20rpx;
padding-right: 20rpx;
}
.padding-vertical {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.margin {
margin: 20rpx;
}
.margin-horizontal {
margin-left: 20rpx;
margin-right: 20rpx;
}
.margin-vertical {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
/* 按钮样式 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 30rpx;
border-radius: 10rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #388E3C;
}
.btn-secondary {
background-color: #FF9800;
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
.btn-block {
width: 100%;
}
/* 卡片样式 */
.card {
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
margin: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 表单样式 */
.form-group {
margin-bottom: 30rpx;
}
.form-group label {
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.form-group input,
.form-group picker,
.form-group textarea {
width: 100%;
padding: 20rpx;
border: 2rpx solid #ddd;
border-radius: 10rpx;
font-size: 28rpx;
}
/* 加载动画 */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx;
}
.spinner {
width: 50rpx;
height: 50rpx;
border: 5rpx solid #f3f3f3;
border-top: 5rpx solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,52 @@
{
"description": "牛肉商城小程序",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"bundle": false,
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
},
"compileType": "miniprogram",
"libVersion": "2.24.7",
"appid": "wxa123456789012345",
"projectname": "beef-mall",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -0,0 +1,80 @@
App({
onLaunch() {
// 小程序初始化
console.log('牛肉商城小程序初始化');
// 检查登录状态
this.checkLoginStatus();
},
onShow() {
// 小程序显示
console.log('牛肉商城小程序显示');
},
onHide() {
// 小程序隐藏
console.log('牛肉商城小程序隐藏');
},
onError(msg) {
// 错误处理
console.log('小程序发生错误:', msg);
},
globalData: {
userInfo: null,
token: null,
baseUrl: 'http://localhost:8000/api'
},
// 检查登录状态
checkLoginStatus() {
try {
const token = wx.getStorageSync('token');
if (token) {
this.globalData.token = token;
// 验证token有效性
this.verifyToken(token);
}
} catch (e) {
console.error('检查登录状态失败:', e);
}
},
// 验证token
verifyToken(token) {
wx.request({
url: `${this.globalData.baseUrl}/auth/verify`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`
},
success: (res) => {
if (res.data.valid) {
this.globalData.userInfo = res.data.user;
} else {
// token无效清除本地存储
wx.removeStorageSync('token');
this.globalData.token = null;
this.globalData.userInfo = null;
}
},
fail: (err) => {
console.error('验证token失败', err);
}
});
},
// 登录方法
login(userInfo) {
this.globalData.userInfo = userInfo;
},
// 登出方法
logout() {
this.globalData.userInfo = null;
this.globalData.token = null;
wx.removeStorageSync('token');
}
})

View File

@@ -0,0 +1,59 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/cart/cart",
"pages/profile/profile",
"pages/product/detail",
"pages/order/list",
"pages/order/detail",
"pages/adopt/list",
"pages/adopt/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#4CAF50",
"navigationBarTitleText": "锡林郭勒盟安格斯牛",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#4CAF50",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "assets/icons/home.png",
"selectedIconPath": "assets/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "assets/icons/category.png",
"selectedIconPath": "assets/icons/category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "assets/icons/cart.png",
"selectedIconPath": "assets/icons/cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/profile/profile",
"iconPath": "assets/icons/profile.png",
"selectedIconPath": "assets/icons/profile-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"requiredPrivateInfos": []
}

View File

@@ -0,0 +1,174 @@
/* 全局样式 */
page {
background-color: #f5f5f5;
font-size: 28rpx;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
}
/* 通用样式类 */
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
.text-primary {
color: #4CAF50;
}
.text-secondary {
color: #388E3C;
}
.text-accent {
color: #FF9800;
}
.bg-white {
background-color: #ffffff;
}
.padding {
padding: 20rpx;
}
.padding-horizontal {
padding-left: 20rpx;
padding-right: 20rpx;
}
.padding-vertical {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.margin {
margin: 20rpx;
}
.margin-horizontal {
margin-left: 20rpx;
margin-right: 20rpx;
}
.margin-vertical {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
/* 按钮样式 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 30rpx;
border-radius: 10rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #388E3C;
}
.btn-secondary {
background-color: #FF9800;
color: white;
}
.btn-secondary:hover {
background-color: #F57C00;
}
.btn-block {
width: 100%;
}
/* 卡片样式 */
.card {
background-color: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
margin: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 表单样式 */
.form-group {
margin-bottom: 30rpx;
}
.form-group label {
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.form-group input,
.form-group picker,
.form-group textarea {
width: 100%;
padding: 20rpx;
border: 2rpx solid #ddd;
border-radius: 10rpx;
font-size: 28rpx;
}
/* 加载动画 */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx;
}
.spinner {
width: 50rpx;
height: 50rpx;
border: 5rpx solid #f3f3f3;
border-top: 5rpx solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,52 @@
{
"description": "牛肉商城小程序",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"bundle": false,
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
},
"compileType": "miniprogram",
"libVersion": "2.24.7",
"appid": "wxa123456789012345",
"projectname": "beef-mall",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -0,0 +1,200 @@
/* 锡林郭勒盟安格斯牛平台官网样式 */
:root {
--primary-color: #4CAF50;
--secondary-color: #388E3C;
--accent-color: #FF9800;
--light-color: #f5f5f5;
--dark-color: #333;
--text-color: #333;
--border-radius: 4px;
--box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: #fff;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 头部样式 */
header {
background-color: var(--primary-color);
color: white;
padding: 1rem 0;
box-shadow: var(--box-shadow);
}
header h1 {
font-size: 1.8rem;
margin-bottom: 0.5rem;
}
nav ul {
display: flex;
list-style: none;
}
nav ul li {
margin-right: 1.5rem;
}
nav ul li a {
color: white;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
nav ul li a:hover {
color: var(--light-color);
}
/* 主要内容区域 */
main {
min-height: calc(100vh - 140px);
}
/* 英雄区域 */
.hero {
background: linear-gradient(rgba(76, 175, 80, 0.8), rgba(56, 142, 60, 0.9)), url('../images/hero-bg.jpg') no-repeat center center/cover;
color: white;
text-align: center;
padding: 4rem 0;
}
.hero h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.hero p {
font-size: 1.2rem;
margin-bottom: 2rem;
}
.cta-buttons {
display: flex;
justify-content: center;
gap: 1rem;
}
.btn {
display: inline-block;
padding: 0.8rem 1.5rem;
border-radius: var(--border-radius);
text-decoration: none;
font-weight: 500;
transition: all 0.3s;
}
.btn.primary {
background-color: var(--accent-color);
color: white;
}
.btn.primary:hover {
background-color: #F57C00;
transform: translateY(-2px);
}
.btn.secondary {
background-color: transparent;
color: white;
border: 2px solid white;
}
.btn.secondary:hover {
background-color: white;
color: var(--primary-color);
transform: translateY(-2px);
}
/* 特色功能区域 */
.features {
padding: 4rem 0;
background-color: var(--light-color);
}
.features h2 {
text-align: center;
font-size: 2rem;
margin-bottom: 3rem;
color: var(--primary-color);
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
}
.feature-card {
background: white;
padding: 2rem;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
text-align: center;
transition: transform 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card h3 {
color: var(--primary-color);
margin-bottom: 1rem;
}
/* 页脚 */
footer {
background-color: var(--dark-color);
color: white;
text-align: center;
padding: 1.5rem 0;
}
/* 响应式设计 */
@media (max-width: 768px) {
header h1 {
font-size: 1.5rem;
}
nav ul {
flex-direction: column;
}
nav ul li {
margin: 0.5rem 0;
}
.hero h2 {
font-size: 2rem;
}
.hero p {
font-size: 1rem;
}
.cta-buttons {
flex-direction: column;
align-items: center;
}
.feature-grid {
grid-template-columns: 1fr;
}
}

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>锡林郭勒盟安格斯牛数字化管理平台</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<div class="container">
<h1>锡林郭勒盟安格斯牛数字化管理平台</h1>
<nav>
<ul>
<li><a href="#home">首页</a></li>
<li><a href="#about">关于我们</a></li>
<li><a href="#services">服务</a></li>
<li><a href="#contact">联系我们</a></li>
</ul>
</nav>
</div>
</header>
<main>
<section id="home" class="hero">
<div class="container">
<h2>推动畜牧业数字化转型</h2>
<p>打造锡林郭勒盟安格斯牛全产业链数字化管理平台</p>
<div class="cta-buttons">
<a href="#" class="btn primary">平台入口</a>
<a href="#" class="btn secondary">了解详情</a>
</div>
</div>
</section>
<section id="features" class="features">
<div class="container">
<h2>平台特色</h2>
<div class="feature-grid">
<div class="feature-card">
<h3>养殖管理</h3>
<p>全流程数字化养殖管理,提升养殖效率</p>
</div>
<div class="feature-card">
<h3>交易撮合</h3>
<p>安全可靠的活牛交易平台,保障交易双方权益</p>
</div>
<div class="feature-card">
<h3>金融监管</h3>
<p>银行与保险机构数字化监管,降低金融风险</p>
</div>
<div class="feature-card">
<h3>政府监管</h3>
<p>政府数字化监管平台,提升监管效率</p>
</div>
</div>
</div>
</section>
</main>
<footer>
<div class="container">
<p>&copy; 2025 锡林郭勒盟安格斯牛数字化管理平台. 保留所有权利.</p>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,64 @@
// 锡林郭勒盟安格斯牛平台官网JavaScript
document.addEventListener('DOMContentLoaded', function() {
// 平滑滚动效果
const links = document.querySelectorAll('a[href^="#"]');
links.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetElement = document.querySelector(targetId);
if (targetElement) {
window.scrollTo({
top: targetElement.offsetTop - 70,
behavior: 'smooth'
});
}
});
});
// 简单的移动端菜单切换
const mobileMenuButton = document.createElement('button');
mobileMenuButton.classList.add('mobile-menu-toggle');
mobileMenuButton.innerHTML = '☰';
mobileMenuButton.setAttribute('aria-label', '切换菜单');
const header = document.querySelector('header');
const nav = document.querySelector('nav');
if (header && nav) {
header.insertBefore(mobileMenuButton, nav);
mobileMenuButton.addEventListener('click', function() {
nav.classList.toggle('active');
});
}
// 添加一些简单的交互效果
const featureCards = document.querySelectorAll('.feature-card');
featureCards.forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.boxShadow = '0 5px 15px rgba(0, 0, 0, 0.2)';
});
card.addEventListener('mouseleave', function() {
this.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
});
});
});
// 简单的表单验证示例
function validateForm(form) {
// 这里可以添加表单验证逻辑
console.log('表单验证');
return true;
}
// 页面加载完成后的初始化
window.addEventListener('load', function() {
console.log('锡林郭勒盟安格斯牛平台官网加载完成');
});