纺织行业采购计划管理系统
一款专为纺织行业设计的全流程协作管理平台,连接采购商(布行)、纺织厂、水洗厂三方,实现从计划制定到成品交付的数字化管理。
核心功能
多角色协作
- 采购商/布行:创建生产计划、管理坯布库存、跟踪生产进度、处理结款
- 纺织厂:接收生产计划、管理生产流程、坯布入库、纱线库存管理
- 水洗厂:接收水洗订单、管理水洗流程
计划管理
- 自动生成唯一计划编号和坯布识别码
- 纱线配比配置与用量自动计算
- 生产流程节点跟踪(确认计划 → 采纱 → 染纱 → 上机 → 坯布入库)
- 实时进度可视化,支持97%完成度自动提醒
库存管理
- 产品信息:按坯布码分组管理,入库记录追溯
- 产品管理:支持按名称、克重、颜色多级分组展示
- 出入库历史:查看每个产品的完整库存变动记录
- 价格历史:追踪采购价格变动
- 产品唯一性:产品码全局唯一,色号在"成品名称-克重-颜色"组合中唯一
- 原料纱仓库:库存预警、最低库存提醒
- 实时库存数据同步,入库自动更新
结款管理
- 按完成米数自动计算结款金额
- 待结款汇总统计
- 一键确认结款,记录结款时间
分享与导入
- 加密分享链接,保护敏感信息
- 支持剪贴板自动识别导入
- 扫码或链接快速关联计划
技术特性
前端技术栈
- React 18 + TypeScript - 类型安全的函数组件开发
- TailwindCSS - 原子化CSS,快速构建响应式界面
- Framer Motion - 流畅的页面过渡和交互动画
- Lucide React - 现代化图标库
移动端优化
- 响应式布局,适配手机、平板、桌面端
- 触控优化:44px最小触控区域、防双击缩放
- 输入优化:数字键盘自动唤起、输入模式适配
- 动画优化:硬件加速、自然动画曲线
后端服务
- Meoo Cloud (Supabase) - 云数据库 + 认证 + 实时订阅
- PostgreSQL - 关系型数据库,支持复杂查询
- Row Level Security - 行级安全策略,基于公司 ID 的数据隔离
- Realtime - 实时数据同步,入库记录即时更新
数据安全
- RLS 策略 - 所有表启用行级安全,严格的数据访问控制
- 公司隔离 - 基于 company_id 的数据隔离,确保数据安全
- 子账号支持 - 主账号/子账号权限继承,统一公司数据访问
- 分享加密 - 分享链接使用 Base64 + 盐值混淆加密,保护敏感信息
快速开始
环境要求
- Node.js 18+
- pnpm 8+
安装依赖
pnpm install
开发模式
pnpm run dev
服务启动在 http://localhost:3015
构建生产版本
pnpm run build
数据库迁移
# 查看云服务状态
meoo-cli cloud status
# 执行数据库迁移
meoo-cli cloud migrate --sql "..." --name "migration_name" --changes "变更说明"
项目结构
src/
├── components/ # 公共组件
│ ├── ProcessFlow.tsx # 生产流程节点
│ ├── PlanCard.tsx # 计划卡片
│ ├── StatusBadge.tsx # 状态标签
│ ├── InventoryRecordsModal.tsx # 入库记录弹窗
│ ├── OnboardingGuide.tsx # 新用户引导
│ ├── DemoDisclaimerModal.tsx # Demo免责声明
│ └── ComingSoonModal.tsx # 功能开发中提示
├── pages/ # 页面组件
│ ├── purchaser/ # 采购商页面
│ │ ├── Dashboard.tsx
│ │ ├── PlanOverview.tsx
│ │ ├── NewPlan.tsx
│ │ ├── WarehouseManage.tsx
│ │ └── FactoryManage.tsx
│ ├── textile/ # 纺织厂页面
│ │ ├── Dashboard.tsx
│ │ ├── PlanOverview.tsx
│ │ ├── YarnWarehouse.tsx
│ │ ├── FabricWarehouse.tsx
│ │ └── PaymentPending.tsx
│ ├── washing/ # 水洗厂页面
│ │ └── Dashboard.tsx
│ ├── LoginPage.tsx
│ ├── RegisterPage.tsx
│ ├── RoleSelectPage.tsx
│ ├── MemberManage.tsx
│ └── ImportPlanPage.tsx
├── hooks/ # 自定义Hooks
│ ├── useResponsive.ts # 响应式检测
│ └── useTheme.ts # 主题管理
├── contexts/ # React上下文
│ └── AuthContext.tsx # 认证上下文
├── styles/ # 全局样式
│ └── index.css
├── supabase/ # Supabase客户端
│ ├── client.ts
│ └── types.ts
└── utils/ # 工具函数
├── crypto.ts
└── shareCrypto.ts
组件说明
InventoryRecordsModal 入库记录弹窗
统一风格的入库记录详情弹窗,支持采购商和纺织厂页面复用。
特性:
- 统计摘要:显示总匹数和总米数
- 记录列表:按时间倒序显示所有入库记录
- 详细信息:日期时间、计划编号、工厂名称、批号、匹数、米数
- 动画效果:Framer Motion 平滑动画
使用示例:
import { InventoryRecordsModal } from '../../components/InventoryRecordsModal';
<InventoryRecordsModal
isOpen={recordsModalOpen}
onClose={() => setRecordsModalOpen(false)}
records={selectedRecords}
title="产品名称 - 入库记录"
/>
OnboardingGuide 新用户引导
首次进入系统时展示的功能引导动画,支持采购商和纺织厂角色。
特性:
- 分步骤功能介绍
- 支持跳转到对应功能区
- 进度条和步骤指示器
- 可跳过引导
DemoDisclaimerModal Demo免责声明
访问网站时显示的Demo阶段免责声明弹窗。
ComingSoonModal 功能开发中
点击未开发功能时显示的提示弹窗。
使用指南
采购商操作流程
- 注册/登录账号,选择"采购商"角色
- 创建新计划,填写产品信息、纱线配比
- 通过分享链接将计划发送给纺织厂
- 实时查看生产进度,管理坯布库存
- 生产完成后确认结款
纺织厂操作流程
- 注册/登录账号,选择"纺织厂"角色
- 通过分享链接或剪贴板导入计划
- 按流程节点确认生产进度
- 坯布入库时填写入库数量和匹数
- 查看待结款,确认收款
子账号管理
- 主账号可创建子账号,分配不同权限
- 子账号可独立操作,数据归属主账号公司
- 用户名全局唯一:子账号用户名不可与其他主账号或子账号重复
数据安全
- 分享链接采用加密传输,不包含敏感信息
- 导入页面隐藏成品名称、颜色、色号等敏感字段
- RLS策略确保数据隔离,仅授权用户可访问
- 虚拟邮箱格式
{username}@meoo.local保护隐私
浏览器支持
- Chrome 90+
- Safari 14+
- Firefox 88+
- Edge 90+
更新日志
2025-05-28 (v1.0.31)
- 动画性能优化
- 创建
usePerformanceHook,自动检测设备性能级别 - 支持三种性能模式:高性能/中等性能/低性能
- 自动检测系统减少动画偏好设置
- 简化页面过渡动画,仅使用 opacity 变化
- 优化 Dashboard 页面,使用 CSS transition 替代复杂动画
- 添加 CSS 硬件加速优化(GPU加速、内容可见性)
- 支持低配置电脑流畅运行
- 创建
2025-05-28 (v1.0.3)
- 原料纱仓库出入库记录功能
- 创建
yarn_stock_records表,记录原料纱出入库历史 - 采纱环节自动记录出库,关联到对应生产计划
- 原料纱入库时自动记录入库
- 原料纱仓库页面新增"出入库记录"标签页
- 显示出入库类型、数量、关联计划、时间等信息
- 创建
- 采纱环节优化
- 添加自动/手动分配模式切换
- 自动匹配失败时提示切换到手动分配
- 手动模式支持输入实际使用纱线名称和重量
- 确认时显示实际消耗统计(各纱线用量+总计)
- 库存不足时强制阻止确认,必须先补充库存
- Bug 修复
- 修复纱线占比显示为10000%的问题
2025-05-27 (v1.0.2)
- 账号管理页面帮助系统集成
- 新增"帮助与支持"卡片区域,集成用户手册、用户反馈、关于窗口
- 用户手册:详细使用指南,支持搜索功能
- 用户反馈:支持提交问题或建议到数据库
- 关于窗口:显示版本号 v1.0.2、版权信息、技术支持联系方式
- 帮助系统组件完善
- 内置帮助中心(F1快捷键):功能介绍、常见操作步骤、快捷键列表
- 新手指引:首次登录自动弹窗,引导完成关键设置
- 工具提示:所有按钮悬停显示功能说明
- 版本更新检查:自动检测新版本,仅弹窗一次
- 崩溃报告系统:全局错误监听,自动收集错误日志
- 通知中心主题色适配
- 采购商工作台:琥珀色主题(bg-amber-100/text-amber-700)
- 纺织厂工作台:翠绿色主题(bg-emerald-100/text-emerald-700)
- 水洗厂工作台:紫色主题(bg-purple-100/text-purple-700)
- 计划拒绝功能优化
- 使用 localStorage 持久化拒绝状态,跨页面保持同步
- 被拒绝的计划显示灰色卡片和"已拒绝"标签
- 被拒绝的计划自动从 Dashboard "最近计划"中移除
- 每个被拒绝的计划弹窗仅显示一次
2025-05-26
- 计划详情字段完善
- 采购商和纺织厂计划总览页面统一显示所有技术字段
- 新增显示字段:克重、经线克重、纬线克重、总克重、生产采购价、产品图片、纱线配比、每米纱用量
- 新增时间字段:创建时间、计划开始时间
- 新增备注字段显示
- 纺织厂页面隐藏敏感信息(成品名称、颜色、色号)以保护采购商数据
- 移动端 UI 优化
- 计划卡片移动端适配:缩小图片尺寸(64x64)、字体调整为 text-xs
- 字段标签简化(如"计划编号:"→"编号:")
- 网格布局优化,避免内容溢出
- 所有工作台退出按钮在移动端变为图标形式(LogOut图标)
- 拒绝计划功能增强
- 纺织厂拒绝计划后立即显示灰色卡片和"已拒绝"标签
- 被拒绝的计划自动折叠
- 被拒绝的计划从 Dashboard "最近计划"中消失
- 使用 localStorage 持久化拒绝状态,跨页面保持同步
2025-05-25
- 产品图片上传功能
- 为采购商产品信息管理添加图片上传功能
- 支持在产品创建和编辑时上传产品图片(JPG、PNG格式,最大5MB)
- 产品列表展示40x40px缩略图,无图片时显示默认占位图标
- 产品表单支持图片预览、重新上传和删除功能
- 使用 Supabase Storage
product_images存储桶存储图片 - 数据库
products表新增image_url字段
- UI 优化
- 纺织厂工作台"原坯布仓库"更名为"已生产坯布"(页面标题和首页快捷操作)
2025-05-24
- 新增出入库历史功能
- 采购商产品信息列表新增"出入库历史"按钮
- 支持查看每个产品的完整库存变动记录(批号、匹数、米数、时间)
- 桌面端和移动端均支持
- 类型系统优化
- 修复
ProductInRecord类型定义,与数据库表结构保持一致 - 区分数据库必需字段和前端展示扩展字段
- 修复
- 新增组件
OutboundForm.tsx- 出库表单组件PlanEditModal.tsx- 计划编辑弹窗NotificationCenter.tsx- 通知中心NetworkStatusBar.tsx- 网络状态栏VirtualList.tsx- 虚拟列表组件ErrorBoundary.tsx- 错误边界组件
2025-05-23
- 优化纺织厂工作台UI动画流畅度
- 全面适配移动端,优化触控体验
- 添加实时数据订阅,入库记录自动更新
- 优化坯布入库输入框布局
- 修复采购商仓库管理数据同步问题
- 创建统一的入库记录弹窗组件
InventoryRecordsModal
2025-05-22
- 项目初始化
- 完成基础架构搭建
- 实现用户认证系统
- 完成数据库设计和迁移
测试
类型检查
pnpm run typecheck
代码规范
pnpm run lint
构建验证
pnpm run build
CI/CD 配置
项目使用 GitHub Actions 进行持续集成和部署:
工作流配置
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'
- run: pnpm install
- run: pnpm run typecheck
- run: pnpm run lint
- run: pnpm run build
环境变量配置
项目使用以下环境变量:
开发环境 (.env.local)
# Supabase 配置
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
# 应用配置
VITE_APP_NAME=昱森(Demo版)
VITE_APP_VERSION=1.0.2
生产环境
生产环境变量通过 CI/CD 流水线注入,请勿在代码中硬编码敏感信息。
API 文档
Supabase 数据库 Schema
核心表结构
companies - 公司表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID | 主键 |
| name | TEXT | 公司名称 |
| role | app_role | 角色:purchaser/textile/washing |
| address | TEXT | 地址 |
| contact_phone | TEXT | 联系电话 |
production_plans - 生产计划表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID | 主键 |
| plan_code | TEXT | 计划编号 |
| product_name | TEXT | 产品名称 |
| color | TEXT | 颜色 |
| fabric_code | TEXT | 坯布码 |
| color_code | TEXT | 色号 |
| purchaser_id | UUID | 采购商ID |
| target_quantity | INTEGER | 计划产量 |
| completed_quantity | INTEGER | 已完成产量 |
| status | plan_status | 状态 |
plan_factories - 计划工厂关联表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID | 主键 |
| plan_id | UUID | 计划ID |
| factory_id | UUID | 工厂ID |
| factory_type | factory_type | 工厂类型 |
inventory_records - 入库记录表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID | 主键 |
| plan_id | UUID | 计划ID |
| warehouse_id | UUID | 仓库ID |
| quantity | DECIMAL | 入库数量 |
| rolls | INTEGER | 入库匹数 |
| operator_id | UUID | 操作人ID |
product_inventory_records - 产品出入库记录表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID | 主键 |
| product_id | UUID | 产品ID |
| company_id | UUID | 公司ID |
| batch_no | TEXT | 批号 |
| rolls | INTEGER | 匹数 |
| meters | DECIMAL | 米数 |
| notes | TEXT | 备注 |
| operator_id | UUID | 操作人ID |
| created_at | TIMESTAMPTZ | 创建时间 |
枚举类型
-- 应用角色
app_role: purchaser | textile | washing
-- 计划状态
plan_status: pending | producing | completed
-- 工厂类型
factory_type: textile | washing
-- 仓库类型
warehouse_type: raw_fabric | fabric | finished | yarn
-- 结款状态
payment_status: pending | completed
RLS 策略
所有表启用 Row Level Security,基于 company_id 进行数据隔离:
-- 示例:production_plans 表 RLS 策略
CREATE POLICY company_select_plans ON production_plans
FOR SELECT USING (purchaser_id = get_user_master_company_id());
CREATE POLICY company_insert_plans ON production_plans
FOR INSERT WITH CHECK (purchaser_id = get_user_master_company_id());
API 调用示例
查询计划列表
const { data } = await supabase
.from('production_plans')
.select('*')
.eq('purchaser_id', companyId)
.order('created_at', { ascending: false });
创建入库记录
await supabase.from('inventory_records').insert({
plan_id: planId,
warehouse_id: warehouseId,
quantity: quantity,
rolls: rolls,
operator_id: userId
});
实时订阅库存更新
supabase
.channel('inventory_changes')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'inventory_records'
}, callback)
.subscribe();
许可证
MIT License
技术支持
如有问题或建议,请联系开发团队。
常见问题与解决方案
Q1: 页面白屏/无法加载
可能原因:
- Webpack 热更新失败
- 类型检查错误阻止构建
- 环境变量配置错误
解决方案:
# 1. 清除缓存重新构建
rm -rf node_modules dist
pnpm install
pnpm run dev
# 2. 检查类型错误
pnpm run typecheck
# 3. 检查环境变量
cat .env.local
Q2: 数据无法保存/读取
可能原因:
- RLS 策略限制
- 网络连接问题
- 权限不足
解决方案:
# 1. 检查云服务状态
meoo-cli cloud status
# 2. 检查 RLS 策略
meoo-cli cloud query --sql "\dt"
meoo-cli cloud query --sql "SELECT * FROM pg_policies WHERE tablename = 'your_table'"
# 3. 检查用户权限
meoo-cli cloud query --sql "SELECT * FROM profiles WHERE id = 'your-user-id'"
Q3: 移动端样式错乱
可能原因:
- Tailwind 配置问题
- 响应式断点使用错误
- CSS 未正确加载
解决方案:
# 1. 检查 Tailwind 配置
cat tailwind.config.js
# 2. 检查 PostCSS 配置
cat postcss.config.js
# 3. 重新构建样式
pnpm run build
Q4: 实时数据不更新
可能原因:
- Realtime 未启用
- 订阅配置错误
- 网络问题
解决方案:
// 检查订阅是否正确设置
const channel = supabase
.channel('table_changes')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'your_table'
}, (payload) => {
console.log('Change received:', payload);
})
.subscribe((status) => {
console.log('Subscription status:', status);
});
Q5: 开发服务器预览加载失败(沙箱环境)
现象:
pnpm run dev启动正常,端口 3015 在监听- 但浏览器预览无法加载,curl 请求超时
根本原因:
- 沙箱环境网络限制:
net.ipv4.conf.all.forwarding = 0 - Webpack devServer 配置不当:
host: '127.0.0.1'无法在沙箱访问
解决方案:
// webpack.config.js - 正确配置
devServer: {
port: 3015,
host: '0.0.0.0', // 必须使用 0.0.0.0
allowedHosts: 'all',
hot: true,
historyApiFallback: true,
// 不要配置 static 和 devMiddleware
}
验证方法:
# 1. 类型检查
pnpm run typecheck
# 2. 构建验证(关键)
pnpm run build
# 3. 检查产物
ls -la dist/
# 4. 启动服务器(沙箱中预览可能受限,但构建成功即可部署)
pnpm run dev
注意:沙箱环境中 curl 可能仍超时,这不影响实际部署。只要 pnpm run build 成功,应用即可正常发布。
性能优化建议
1. 图片优化
- 使用 WebP 格式
- 实现懒加载
- 使用 CDN 加速
2. 代码分割
// 使用 React.lazy 进行代码分割
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
);
}
3. 数据缓存
// 使用 SWR 或 React Query 进行数据缓存
import useSWR from 'swr';
const { data, error } = useSWR('/api/data', fetcher, {
revalidateOnFocus: false,
dedupingInterval: 5000
});
4. 虚拟列表
对于大数据列表,使用虚拟列表组件避免渲染过多 DOM 节点。
安全最佳实践
1. 输入验证
// 始终验证用户输入
const validateInput = (input: string): boolean => {
// 防止 XSS
const xssPattern = /<script|javascript:|onerror=/i;
if (xssPattern.test(input)) return false;
// 防止 SQL 注入(虽然 Supabase 已防护)
const sqlPattern = /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE)\b)/i;
if (sqlPattern.test(input)) return false;
return true;
};
2. 敏感数据处理
// 不要在客户端暴露敏感信息
// ❌ 错误
const apiKey = 'sk-live-xxx';
// ✅ 正确 - 使用环境变量
const apiKey = process.env.VITE_API_KEY;
3. 认证检查
// 每个需要认证的页面都添加检查
useEffect(() => {
const checkAuth = async () => {
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
navigate('/login');
}
};
checkAuth();
}, []);
贡献指南
提交代码
- Fork 项目
- 创建功能分支 (
git checkout -b feature/xxx) - 提交更改 (
git commit -m 'Add xxx') - 推送到分支 (
git push origin feature/xxx) - 创建 Pull Request
代码规范
- 使用 TypeScript 严格模式
- 遵循 ESLint 规则
- 编写单元测试
- 更新相关文档
提交信息规范
feat: 新增功能
fix: 修复 bug
docs: 文档更新
style: 代码格式调整
refactor: 重构代码
test: 测试相关
chore: 构建/工具相关
Description
Languages
TypeScript
92.6%
Python
2.9%
PLpgSQL
2.8%
CSS
1%
JavaScript
0.3%
Other
0.3%