From ffc7eef984c30179fdcb5eed540634e5872455db Mon Sep 17 00:00:00 2001 From: yi <100551693+yi1108@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:35:56 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=94=9F=E6=88=90=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=B9=B6=E4=BC=98=E5=8C=96=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 生成完整的 README.md 项目文档 - 统一图片路径为相对引用 - 完善 .gitignore 配置,添加常见忽略项 - 清理未使用的临时文件和图片资源 - 删除废弃的脚本文件 --- .gitignore | 3 + README.md | 108 +++++++++++++----- backend/Dockerfile | 2 +- .../migrations/001_create_category_tree.sql | 16 +-- .../002_create_purchase_inventory.sql | 6 +- ...03_create_procurement_logistics_tables.sql | 14 +-- ...005_create_subcontractor_payment_infos.sql | 6 +- backend/migrations/999_init_sample_data.sql | 0 docker-compose.full.yml | 59 ++++++++++ docker-compose.yml | 56 ++------- frontend/Dockerfile | 4 +- frontend/index.html | 6 +- frontend/public/manifest.json | 6 +- .../src/components/common/CompanyLogo.tsx | 12 +- frontend/src/components/layout/MainLayout.tsx | 13 +++ frontend/src/locales/zh-CN.ts | 8 +- frontend/src/pages/admin/AboutPage.tsx | 47 ++++++-- frontend/src/pages/auth/LoginPage.tsx | 81 +++++++------ scripts/init_sample_data.sql | 58 ++++++++++ 19 files changed, 343 insertions(+), 162 deletions(-) create mode 100644 backend/migrations/999_init_sample_data.sql create mode 100644 docker-compose.full.yml create mode 100644 scripts/init_sample_data.sql diff --git a/.gitignore b/.gitignore index 0e9e700..90d3192 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ backups/ # Cache .cache/ *.cache + +# Workflow +.work/ diff --git a/README.md b/README.md index c3dcd59..24fafbc 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,87 @@ -# 轻远电力老挝ERP系统 +# 云海财务系统 -## 系统访问 -- **前端地址**: http://43.161.248.209:3001/ -- **后端API**: http://43.161.248.209:3000/ +## 1. 项目简介 -## 测试账号 -| 用户名 | 密码 | 角色 | -|--------|------|------| -| admin | 123456 | 系统管理员 | -| finance1 | 123456 | 财务专员 | -| shejianjun | 123456 | 管理员 | +- **项目概述**:云海财务系统是一款高效、智能、专业的企业财务与项目管理平台,能够全方位提升企业的项目监控与资金流转效率。 +- **项目定位**:主要面向中大型企业、工程建设及跨国分公司,提供财务报销、项目预算与进度管理服务。 +- **核心价值**:实现项目与财务数据的无缝对接,简化审批流,实时监控预算使用情况,确保企业资金健康与合规。 -## 功能模块 -1. **仪表板** - 数据概览和统计 -2. **项目管理** - 项目创建、查看、编辑 -3. **财务管理** - 预支申请、报销申请 -4. **报表中心** - 财务报表查看 +## 2. 整体架构与技术栈 -## 技术栈 -- 前端:React + TypeScript + Ant Design + Vite -- 后端:Node.js + Express -- 数据库:PostgreSQL +本系统采用前后端分离的现代化架构,通过 Docker 容器化部署以确保高可用性。 -## 服务管理 -```bash -# 查看服务状态 -netstat -tlnp | grep -E ':3000|:3001' +### 技术栈展示: +- **后端技术**:Node.js + Express +- **前端技术**:React 18 + TypeScript + Ant Design 5 + Vite +- **数据库**:PostgreSQL 15 +- **部署技术**:Docker / Docker Compose -# 重启后端 -cd /opt/qingyuan-erp/backend -node api-complete.js & +### 系统架构图 +*(暂无架构图,系统分为前端应用容器、后端 API 容器及独立的 PostgreSQL 数据库容器)* -# 重启前端 -cd /opt/qingyuan-erp/frontend -npm run dev -- --host 0.0.0.0 & +## 3. 项目目录概览 + +```text +├── backend/ # 后端服务源码 +│ ├── routes/ # API路由 +│ ├── services/ # 业务逻辑 +│ ├── migrations/ # 数据库迁移脚本 +│ └── app.js # 后端主程序 +├── frontend/ # 前端服务源码 +│ ├── src/ # React源码及组件 +│ └── vite.config.ts # Vite配置 +├── scripts/ # 初始化脚本 (如 init_sample_data.sql) +└── docker-compose.full.yml # Docker本地部署配置 ``` + +## 4. 核心业务功能 + +- **项目管理**:支持项目的创建、进度跟踪、合同与里程碑管理。 +- **财务管理**:包括财务报销、预支款申请、付款申请与核销流程。 +- **采购与供应链**:商品管理、采购申请、订单管理与入库记录。 +- **伙伴管理**:集中管理供应商、分包商与客户信息。 +- **数据分析与仪表盘**:直观展示核心财务数据及项目状态。 + +## 5. 实际应用场景示例 + +- **跨国分公司财务管控**:海外分公司提交预支与报销申请,总部可在线审核,统一汇率转换及预算扣减。 +- **工程类项目核算**:将施工日志与项目付款节点绑定,确保按进度结算分包商款项。 +- **企业日常运营**:员工出差报销、办公采购,全流程数字化审批与记录。 + +## 6. 帮助解决的核心问题 + +- **财务数据孤岛**:项目信息与财务开销割裂,难以追踪真实成本。 +- **审批效率低下**:传统纸质或邮件审批慢、易遗漏。 +- **预算超支风险**:缺乏实时的数据监控及超支预警机制。 + +## 7. 快速开始 + +### 环境要求 +- Docker 及 Docker Compose +- Node.js (如需本地独立运行) + +### 安装与运行步骤 (基于 Docker) + +本系统内置了 `docker-compose.full.yml` 文件及示例数据初始化脚本,可一键启动全套服务。 + +1. **一键构建与启动**: + ```bash + docker-compose -f docker-compose.full.yml up -d --build + ``` +2. **检查服务状态**: + ```bash + docker-compose -f docker-compose.full.yml ps + ``` + +### 访问地址与默认账号 +- **前端访问地址**:`http://localhost:10050` +- **后端 API 地址**:`http://localhost:10051` +- **默认管理员账号**:`admin` / `X123c321@` (具体密码请参考登录页提示) + +### 常见问题 +- **数据库未初始化**:如果首次启动未完成数据装载,可执行 `docker-compose down -v` 删除未初始化的数据卷后重新启动。 +- **端口冲突**:如果 `10050` 或 `10051` 端口已被占用,请修改 `docker-compose.full.yml` 中的端口映射。 + +## 8. 运行示例截图 + +*(截图预留位置)* diff --git a/backend/Dockerfile b/backend/Dockerfile index 35022cd..892b056 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -3,7 +3,7 @@ FROM node:18-alpine WORKDIR /app COPY package*.json ./ -RUN npm ci --production +RUN npm install --production COPY . . diff --git a/backend/migrations/001_create_category_tree.sql b/backend/migrations/001_create_category_tree.sql index f741cfd..1f93022 100644 --- a/backend/migrations/001_create_category_tree.sql +++ b/backend/migrations/001_create_category_tree.sql @@ -5,7 +5,7 @@ -- 1. 创建新的分类表(树状结构) CREATE TABLE IF NOT EXISTS category_tree ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, name TEXT NOT NULL, -- 分类名称 parent_id INTEGER DEFAULT NULL, -- 父分类ID(NULL表示一级分类) level INTEGER DEFAULT 1, -- 层级(1=一级,2=二级) @@ -26,7 +26,7 @@ ALTER TABLE products RENAME TO products_backup; -- 创建新的商品表 CREATE TABLE products ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, name TEXT NOT NULL, -- 商品名称 model TEXT, -- 型号 category_id INTEGER, -- 二级分类ID(关联category_tree) @@ -206,17 +206,9 @@ FROM category_tree WHERE name = '其他材料' AND level = 1; -- ============================================ -- 创建触发器:自动更新updated_at -- ============================================ -CREATE TRIGGER IF NOT EXISTS update_category_tree_timestamp -AFTER UPDATE ON category_tree -BEGIN - UPDATE category_tree SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id; -END; -CREATE TRIGGER IF NOT EXISTS update_products_timestamp -AFTER UPDATE ON products -BEGIN - UPDATE products SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id; -END; + + -- ============================================ -- 迁移完成 diff --git a/backend/migrations/002_create_purchase_inventory.sql b/backend/migrations/002_create_purchase_inventory.sql index 09c2456..97dc0d1 100644 --- a/backend/migrations/002_create_purchase_inventory.sql +++ b/backend/migrations/002_create_purchase_inventory.sql @@ -5,7 +5,7 @@ -- 表1:采购申请表 (purchase_requests) -- ============================================ CREATE TABLE IF NOT EXISTS purchase_requests ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, request_code TEXT UNIQUE NOT NULL, project_id INTEGER NOT NULL, applicant TEXT NOT NULL, @@ -28,7 +28,7 @@ CREATE TABLE IF NOT EXISTS purchase_requests ( -- 表2:采购明细表 (purchase_request_items) -- ============================================ CREATE TABLE IF NOT EXISTS purchase_request_items ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, purchase_request_id INTEGER NOT NULL, product_id INTEGER, product_name TEXT NOT NULL, @@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS purchase_request_items ( -- 表3:库存记录表 (inventory_records) -- ============================================ CREATE TABLE IF NOT EXISTS inventory_records ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, record_type TEXT NOT NULL, project_id INTEGER, purchase_request_id INTEGER, diff --git a/backend/migrations/003_create_procurement_logistics_tables.sql b/backend/migrations/003_create_procurement_logistics_tables.sql index ca06469..a431066 100644 --- a/backend/migrations/003_create_procurement_logistics_tables.sql +++ b/backend/migrations/003_create_procurement_logistics_tables.sql @@ -12,7 +12,7 @@ -- 表1:跨境物流公司表 (logistics_companies) -- 设计方案章节:9.9 跨境物流公司表 CREATE TABLE IF NOT EXISTS logistics_companies ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, name TEXT NOT NULL, address TEXT, @@ -31,7 +31,7 @@ CREATE INDEX IF NOT EXISTS idx_logistics_companies_status ON logistics_companies -- 表2:物流公司收款信息表 (logistics_company_payment_infos) -- 设计方案章节:9.10 物流公司收款信息表 CREATE TABLE IF NOT EXISTS logistics_company_payment_infos ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, logistics_company_id INTEGER NOT NULL, account_name TEXT, account_number TEXT, @@ -48,7 +48,7 @@ CREATE INDEX IF NOT EXISTS idx_lc_payment_infos_company ON logistics_company_pay -- 表3:物流单表 (logistics_records) -- 设计方案章节:9.4 物流单表 CREATE TABLE IF NOT EXISTS logistics_records ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, purchase_order_id INTEGER NOT NULL, @@ -102,7 +102,7 @@ CREATE INDEX IF NOT EXISTS idx_logistics_records_company ON logistics_records(lo -- 表4:验收单表 (verification_records) -- 设计方案章节:9.5 验收单表 CREATE TABLE IF NOT EXISTS verification_records ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, purchase_order_id INTEGER NOT NULL, logistics_record_id INTEGER, @@ -137,7 +137,7 @@ CREATE INDEX IF NOT EXISTS idx_verification_records_status ON verification_recor -- 表5:退库单表 (return_records) -- 设计方案章节:9.6 退库单表 CREATE TABLE IF NOT EXISTS return_records ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, project_id INTEGER NOT NULL, @@ -167,7 +167,7 @@ CREATE INDEX IF NOT EXISTS idx_return_records_status ON return_records(status); -- 表6:材料价格历史表 (material_price_history) -- 设计方案章节:9.7 材料价格历史表 CREATE TABLE IF NOT EXISTS material_price_history ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, product_id INTEGER NOT NULL, purchase_order_id INTEGER, supplier_id INTEGER, @@ -191,7 +191,7 @@ CREATE INDEX IF NOT EXISTS idx_material_price_history_date ON material_price_his -- 表7:项目材料库存表 (project_material_inventory) -- 设计方案章节:9.8 项目材料库存表 CREATE TABLE IF NOT EXISTS project_material_inventory ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, project_id INTEGER NOT NULL, product_id INTEGER NOT NULL, product_name TEXT, diff --git a/backend/migrations/005_create_subcontractor_payment_infos.sql b/backend/migrations/005_create_subcontractor_payment_infos.sql index a0ab321..a03d084 100644 --- a/backend/migrations/005_create_subcontractor_payment_infos.sql +++ b/backend/migrations/005_create_subcontractor_payment_infos.sql @@ -1,14 +1,14 @@ -- 创建分包商收款信息表 CREATE TABLE IF NOT EXISTS subcontractor_payment_infos ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id SERIAL PRIMARY KEY, subcontractor_id INTEGER NOT NULL, account_name TEXT NOT NULL, bank_account TEXT NOT NULL, bank_name TEXT NOT NULL, qr_code TEXT, is_primary INTEGER DEFAULT 0, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (subcontractor_id) REFERENCES subcontractors(id) ON DELETE CASCADE ); diff --git a/backend/migrations/999_init_sample_data.sql b/backend/migrations/999_init_sample_data.sql new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.full.yml b/docker-compose.full.yml new file mode 100644 index 0000000..96f47fe --- /dev/null +++ b/docker-compose.full.yml @@ -0,0 +1,59 @@ +version: '3.8' + +services: + postgres: + image: postgres:15-alpine + container_name: yunhaifinance-postgres + ports: + - "10052:5432" + volumes: + - yunhaifinance-postgres-data:/var/lib/postgresql/data + - ./scripts/init_sample_data.sql:/docker-entrypoint-initdb.d/999_init_sample_data.sql:ro + environment: + POSTGRES_USER: ${DB_USER:-postgres} + POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme} + POSTGRES_DB: ${DB_NAME:-company_finance} + POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=zh_CN.UTF-8" + + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: yunhaifinance-backend + ports: + - "10051:3000" + environment: + NODE_ENV: production + PORT: 3000 + DB_HOST: postgres + DB_PORT: 5432 + DB_NAME: ${DB_NAME:-company_finance} + DB_USER: ${DB_USER:-postgres} + DB_PASSWORD: ${DB_PASSWORD:-changeme} + JWT_SECRET: ${JWT_SECRET:-please-change-this-secret} + CORS_ORIGIN: ${CORS_ORIGIN:-} + depends_on: + - postgres + volumes: + - yunhaifinance-upload-data:/app/uploads + networks: + - yunhaifinance-network + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + container_name: yunhaifinance-frontend + ports: + - "10050:80" + depends_on: + - backend + networks: + - yunhaifinance-network + +volumes: + yunhaifinance-postgres-data: + yunhaifinance-upload-data: + +networks: + yunhaifinance-network: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 4cd4f8c..e01bcf8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,59 +3,21 @@ version: '3.8' services: postgres: image: postgres:15-alpine - restart: unless-stopped + container_name: yunhaifinance-postgres environment: POSTGRES_USER: ${DB_USER:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme} POSTGRES_DB: ${DB_NAME:-company_finance} ports: - - "5432:5432" + - "10052:5432" volumes: - - postgres_data:/var/lib/postgresql/data + - yunhaifinance-postgres-data:/var/lib/postgresql/data - ./backend/migrations:/docker-entrypoint-initdb.d - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres}"] - interval: 10s - timeout: 5s - retries: 5 - - backend: - build: - context: ./backend - dockerfile: Dockerfile - restart: unless-stopped - ports: - - "${BACKEND_PORT:-3000}:3000" - environment: - NODE_ENV: production - PORT: 3000 - DB_HOST: postgres - DB_PORT: 5432 - DB_NAME: ${DB_NAME:-company_finance} - DB_USER: ${DB_USER:-postgres} - DB_PASSWORD: ${DB_PASSWORD:-changeme} - JWT_SECRET: ${JWT_SECRET:-please-change-this-secret} - CORS_ORIGIN: ${CORS_ORIGIN:-} - TENCENT_SECRET_ID: ${TENCENT_SECRET_ID:-} - TENCENT_SECRET_KEY: ${TENCENT_SECRET_KEY:-} - COS_BUCKET: ${COS_BUCKET:-} - COS_REGION: ${COS_REGION:-} - depends_on: - postgres: - condition: service_healthy - volumes: - - upload_data:/app/uploads - - frontend: - build: - context: ./frontend - dockerfile: Dockerfile - restart: unless-stopped - ports: - - "${FRONTEND_PORT:-80}:80" - depends_on: - - backend + networks: + - yunhaifinance-network volumes: - postgres_data: - upload_data: + yunhaifinance-postgres-data: + +networks: + yunhaifinance-network: \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index cfe242c..5e43581 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -3,12 +3,12 @@ FROM node:18-alpine AS build WORKDIR /app COPY package*.json ./ -RUN npm ci +RUN npm install COPY . . RUN npm run build -FROM nginx:alpine +FROM nginx:1.26-alpine COPY --from=build /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf diff --git a/frontend/index.html b/frontend/index.html index 95d823a..5f60a8c 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -7,11 +7,11 @@ - - + + -