This commit is contained in:
2026-03-17 22:50:09 +08:00
parent dac6aca240
commit 2a5821805c
2 changed files with 66 additions and 30 deletions
+1 -1
View File
@@ -18,6 +18,6 @@
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-router@4/dist/vue-router.global.prod.js"></script>
<script src="/static/vue-app.js?v=20260317-01"></script>
<script src="/static/vue-app.js?v=20260317-02"></script>
</body>
</html>
+65 -29
View File
@@ -1488,6 +1488,7 @@ const InventoryView = {
supplierProductStatement: [],
products: [],
materials: [],
finishedProducts: [],
purchaseOrders: [],
purchaseWarehouseId: null,
purchaseReceiveItems: [],
@@ -1545,17 +1546,22 @@ const InventoryView = {
}
};
const loadProducts = async () => {
const loadFinishedProducts = async () => {
state.loading = true;
try {
state.products = await apiRequest('/api/products?limit=100');
state.finishedProducts = await apiRequest('/api/products?item_type=finished&limit=100');
} catch (e) {
handleApiError(e, '加载产品');
handleApiError(e, '加载成品');
} finally {
state.loading = false;
}
};
const loadProducts = async () => {
// Compatibility wrapper if needed, or just load finished products
await loadFinishedProducts();
};
const loadMaterials = async () => {
state.loading = true;
try {
@@ -1736,14 +1742,15 @@ const InventoryView = {
state.activeTab = tab;
switch (tab) {
case 'dashboard': loadDashboard(); break;
case 'products': loadProducts(); break;
case 'suppliers': loadSuppliers(); break;
case 'customers': loadCustomers(); break;
case 'inventory': loadInventory(); break;
case 'movements': loadMovements(); break;
case 'sales_orders': loadProductionOrders(); break;
case 'products': loadFinishedProducts(); break;
case 'materials': loadMaterials(); break;
case 'purchases': loadPurchaseOrders(); break;
case 'production': loadProductionOrders(); break;
case 'inventory': loadInventory(); break;
case 'customers': loadCustomers(); break;
case 'suppliers': loadSuppliers(); break;
case 'finance': loadFinance(); break;
case 'movements': loadMovements(); break;
}
};
@@ -2304,14 +2311,15 @@ const InventoryView = {
<div class="tabs">
<button :class="['tab', { active: state.activeTab === 'dashboard' }]" @click="switchTab('dashboard')">仪表盘</button>
<button :class="['tab', { active: state.activeTab === 'products' }]" @click="switchTab('products')">产品</button>
<button :class="['tab', { active: state.activeTab === 'inventory' }]" @click="switchTab('inventory')">库存</button>
<button :class="['tab', { active: state.activeTab === 'purchases' }]" @click="switchTab('purchases')">采购</button>
<button :class="['tab', { active: state.activeTab === 'suppliers' }]" @click="switchTab('suppliers')">供应商</button>
<button :class="['tab', { active: state.activeTab === 'sales_orders' }]" @click="switchTab('sales_orders')">销售订单</button>
<button :class="['tab', { active: state.activeTab === 'products' }]" @click="switchTab('products')">成品管理</button>
<button :class="['tab', { active: state.activeTab === 'materials' }]" @click="switchTab('materials')">物料管理</button>
<button :class="['tab', { active: state.activeTab === 'purchases' }]" @click="switchTab('purchases')">采购订单</button>
<button :class="['tab', { active: state.activeTab === 'inventory' }]" @click="switchTab('inventory')">库存管理</button>
<button :class="['tab', { active: state.activeTab === 'customers' }]" @click="switchTab('customers')">客户</button>
<button :class="['tab', { active: state.activeTab === 'movements' }]" @click="switchTab('movements')">变动记录</button>
<button :class="['tab', { active: state.activeTab === 'production' }]" @click="switchTab('production')">按单生产</button>
<button :class="['tab', { active: state.activeTab === 'suppliers' }]" @click="switchTab('suppliers')">供应商</button>
<button :class="['tab', { active: state.activeTab === 'finance' }]" @click="switchTab('finance')">财务</button>
<button :class="['tab', { active: state.activeTab === 'movements' }]" @click="switchTab('movements')">变动记录</button>
</div>
<div v-if="state.loading" class="loading-state">
@@ -2366,21 +2374,13 @@ const InventoryView = {
</div>
<div v-else-if="state.activeTab === 'products'">
<div class="table-container" style="margin-bottom: 12px;">
<div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
<button :class="['btn', state.productCategory === 'finished' ? 'btn-primary' : 'btn-secondary']" @click="switchProductCategory('finished')">成品</button>
<button :class="['btn', state.productCategory === 'material' ? 'btn-primary' : 'btn-secondary']" @click="switchProductCategory('material')">物料</button>
</div>
</div>
<div class="table-header">
<button v-if="state.productCategory === 'finished'" class="btn btn-primary" @click="openCreateProduct('finished')">+ 新增成品</button>
<button v-else class="btn btn-primary" @click="openCreateProduct('material')">+ 新增物料</button>
<button class="btn btn-primary" @click="openCreateProduct('finished')">+ 新增成品</button>
</div>
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th>类型</th>
<th>SKU</th>
<th>名称</th>
<th>分类</th>
@@ -2392,18 +2392,54 @@ const InventoryView = {
</tr>
</thead>
<tbody>
<tr v-for="product in state.products.filter(p => p.item_type === state.productCategory)" :key="product.id">
<td>{{ product.item_type === 'material' ? '物料' : '成品' }}</td>
<tr v-for="product in state.finishedProducts" :key="product.id">
<td>{{ product.sku }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category || '-' }}</td>
<td>{{ product.unit }}</td>
<td>{{ formatCurrency(product.cost_price) }}</td>
<td>{{ formatCurrency(product.sale_price) }}</td>
<td>{{ product.item_type === 'finished' ? formatCurrency(product.material_cost || 0) : '-' }}</td>
<td>{{ formatCurrency(product.material_cost || 0) }}</td>
<td>
<div class="action-btns">
<button class="btn btn-sm btn-secondary" @click="editProductBom(product)">BOM</button>
<button class="btn btn-sm btn-secondary" @click="openModal('product', product)">编辑</button>
<button class="btn btn-sm btn-danger" @click="deleteProduct(product.id)">删除</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-else-if="state.activeTab === 'materials'">
<div class="table-header">
<button class="btn btn-primary" @click="openCreateProduct('material')">+ 新增物料</button>
</div>
<div class="table-container">
<table class="data-table">
<thead>
<tr>
<th>SKU</th>
<th>名称</th>
<th>分类</th>
<th>单位</th>
<th>成本价</th>
<th>最低库存</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="product in state.materials" :key="product.id">
<td>{{ product.sku }}</td>
<td>{{ product.name }}</td>
<td>{{ product.category || '-' }}</td>
<td>{{ product.unit }}</td>
<td>{{ formatCurrency(product.cost_price) }}</td>
<td>{{ product.min_stock || '-' }}</td>
<td>
<div class="action-btns">
<button v-if="product.item_type === 'finished'" class="btn btn-sm btn-secondary" @click="editProductBom(product)">BOM</button>
<button class="btn btn-sm btn-secondary" @click="openModal('product', product)">编辑</button>
<button class="btn btn-sm btn-danger" @click="deleteProduct(product.id)">删除</button>
</div>
@@ -2566,7 +2602,7 @@ const InventoryView = {
</div>
</div>
<div v-else-if="state.activeTab === 'production'">
<div v-else-if="state.activeTab === 'sales_orders'">
<div class="table-header" style="margin-bottom: 12px;">
<button class="btn btn-primary" @click="openModal('salesOrder')">+ 新增销售订单</button>
</div>