PSI进销存系统移动端App开发
移动端需求分析
移动端是进销存系统的重要组成部分,需要满足以下核心场景:
| 场景 | 功能需求 | 技术要点 |
|---|---|---|
| 扫码出入库 | 扫描条码/二维码,快速完成出入库 | 相机扫码、离线缓存 |
| 库存查询 | 实时查询库存、库存预警 | 数据同步、缓存策略 |
| 订单管理 | 创建订单、订单审批、状态跟踪 | 表单验证、离线提交 |
| 数据报表 | 销售报表、库存报表查看 | 图表展示、数据导出 |
| 消息通知 | 订单提醒、库存预警、审批通知 | 推送通知、实时通讯 |
技术选型
移动端开发的技术方案对比:
- 原生开发:性能最优,但开发成本高,需要维护iOS和Android两套代码
- 跨平台框架:React Native、Flutter,一套代码多端运行
- 混合开发:Cordova、Capacitor,使用Web技术开发
- 小程序:微信/支付宝小程序,用户无需安装
App架构设计
PSI移动端采用模块化架构:
// App模块结构
const appModules = {
// 核心模块
core: {
auth: '认证模块',
network: '网络请求',
storage: '本地存储',
cache: '缓存管理'
},
// 业务模块
business: {
warehouse: '仓储管理',
purchase: '采购管理',
sales: '销售管理',
inventory: '库存管理',
report: '报表中心'
},
// 公共模块
common: {
scanner: '扫码功能',
camera: '相机拍照',
location: '定位服务',
push: '消息推送'
}
};
// 页面路由配置
const routes = {
'/': 'HomePage',
'/login': 'LoginPage',
'/dashboard': 'DashboardPage',
'/warehouse/in': 'WarehouseInPage',
'/warehouse/out': 'WarehouseOutPage',
'/warehouse/scan': 'ScannerPage',
'/order/create': 'OrderCreatePage',
'/order/list': 'OrderListPage',
'/inventory/check': 'InventoryCheckPage',
'/report/sales': 'SalesReportPage'
};
扫码功能实现
扫码是进销存系统的核心功能:
// 扫码功能实现
class ScannerService {
constructor() {
this.scanner = null;
}
// 初始化扫码器
async init() {
if (this.scanner) return;
const { BarcodeScanner } = require('@capacitor-community/barcode-scanner');
this.scanner = BarcodeScanner;
}
// 检查相机权限
async checkPermission() {
const permission = await this.scanner.checkPermission();
return permission.granted;
}
// 请求相机权限
async requestPermission() {
const permission = await this.scanner.requestPermission();
return permission.granted;
}
// 启动扫码
async startScan(options = {}) {
const hasPermission = await this.checkPermission();
if (!hasPermission) {
const granted = await this.requestPermission();
if (!granted) throw new Error('相机权限被拒绝');
}
return new Promise((resolve, reject) => {
this.scanner.startScan({
targetedFormats: ['QR_CODE', 'CODE_128', 'EAN_13'],
...options
}).then(result => {
if (result.hasContent) {
resolve(result.content);
} else {
reject(new Error('未扫描到内容'));
}
}).catch(reject);
});
}
// 停止扫码
async stopScan() {
await this.scanner.stopScan();
}
// 解析条码内容
parseBarcode(content) {
// 判断条码类型
if (content.startsWith('P:')) {
// 产品条码
return { type: 'product', code: content.substring(2) };
} else if (content.startsWith('O:')) {
// 订单条码
return { type: 'order', code: content.substring(2) };
} else if (content.startsWith('L:')) {
// 库位条码
return { type: 'location', code: content.substring(2) };
} else {
// 通用条码
return { type: 'unknown', code: content };
}
}
}
// 扫码出入库页面逻辑
class WarehouseInPage {
constructor() {
this.scanner = new ScannerService();
this.items = [];
}
async handleScan() {
try {
const content = await this.scanner.startScan();
const parsed = this.scanner.parseBarcode(content);
if (parsed.type === 'product') {
// 查询产品信息
const product = await this.queryProduct(parsed.code);
this.addItem(product);
} else {
this.showError('无效的产品条码');
}
} catch (error) {
this.showError(error.message);
}
}
async addItem(product) {
// 检查是否已存在
const existing = this.items.find(item => item.productId === product.id);
if (existing) {
existing.quantity++;
} else {
this.items.push({
productId: product.id,
productCode: product.code,
productName: product.name,
quantity: 1,
location: ''
});
}
this.render();
}
}
离线数据同步
移动端需要支持离线操作:
// 离线数据管理
class OfflineManager {
constructor() {
this.pendingOps = []; // 待同步操作
this.db = null; // 本地数据库
}
// 初始化本地数据库
async init() {
const { SQLite } = require('@capacitor-community/sqlite');
this.db = await SQLite.createDatabase({ name: 'psi.db' });
await this.createTables();
}
// 创建离线表
async createTables() {
await this.db.execute(`
CREATE TABLE IF NOT EXISTS offline_operations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL,
table_name TEXT NOT NULL,
data TEXT NOT NULL,
created_at INTEGER NOT NULL,
synced INTEGER DEFAULT 0
)
`);
}
// 保存离线操作
async saveOperation(type, tableName, data) {
const operation = {
type,
tableName,
data: JSON.stringify(data),
createdAt: Date.now(),
synced: 0
};
await this.db.execute(
'INSERT INTO offline_operations (type, table_name, data, created_at, synced) VALUES (?, ?, ?, ?, ?)',
[operation.type, operation.tableName, operation.data, operation.createdAt, operation.synced]
);
// 尝试立即同步
this.syncNow();
}
// 同步到服务器
async syncNow() {
const operations = await this.db.execute(
'SELECT * FROM offline_operations WHERE synced = 0 ORDER BY created_at'
);
for (const op of operations.values) {
try {
await this.syncOperation(op);
await this.db.execute(
'UPDATE offline_operations SET synced = 1 WHERE id = ?',
[op.id]
);
} catch (error) {
console.error('同步失败:', error);
// 重试逻辑
}
}
}
// 同步单个操作
async syncOperation(operation) {
const url = `/api/${operation.table_name}`;
const method = operation.type === 'create' ? 'POST'
: operation.type === 'update' ? 'PUT'
: 'DELETE';
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: operation.data
});
if (!response.ok) {
throw new Error('Sync failed');
}
}
// 定期同步
startPeriodicSync(interval = 60000) {
setInterval(() => this.syncNow(), interval);
}
}
消息推送集成
实现消息推送功能:
// 消息推送服务
class PushService {
constructor() {
this.token = null;
this.listeners = [];
}
// 初始化推送
async init() {
const { PushNotifications } = require('@capacitor/push-notifications');
// 请求权限
const result = await PushNotifications.requestPermission();
if (result.granted) {
// 注册设备
await PushNotifications.register();
}
// 监听token
PushNotifications.addListener('registration', (token) => {
this.token = token.value;
this.saveToken(token.value);
});
// 监听消息
PushNotifications.addListener('pushNotificationReceived', (notification) => {
this.handleNotification(notification);
});
// 监听点击
PushNotifications.addListener('pushNotificationActionPerformed', (notification) => {
this.handleAction(notification);
});
}
// 处理通知
handleNotification(notification) {
const { title, body, data } = notification;
// 根据通知类型处理
switch (data.type) {
case 'order_approve':
// 跳转审批页面
router.navigate('/order/approve');
break;
case 'inventory_alert':
// 跳转库存预警
router.navigate('/inventory/alert');
break;
case 'stock_out':
// 跳转缺货提醒
router.navigate('/inventory/out');
break;
}
// 通知监听器
this.listeners.forEach(listener => listener(notification));
}
// 添加监听器
addListener(callback) {
this.listeners.push(callback);
}
// 保存token到服务器
async saveToken(token) {
await api.post('/device/token', { token, platform: 'android' });
}
}
性能优化
移动端性能优化策略:
- 图片优化:使用WebP格式、按需加载、懒加载
- 列表优化:使用虚拟列表、长列表分页加载
- 缓存策略:合理使用本地缓存,减少网络请求
- 代码分割:按模块加载,减少首屏加载时间
总结
PSI移动端App开发采用跨平台方案,实现了一套代码同时支持iOS和Android。通过扫码、离线同步、消息推送等核心功能,满足了仓储、物流等场景的移动办公需求。