This commit is contained in:
2026-03-15 22:30:41 +08:00
parent a86fb9803a
commit 4e9f66ccd6
2 changed files with 81 additions and 12 deletions
+68 -8
View File
@@ -1498,6 +1498,49 @@ const InventoryView = {
form: {}
});
const inboundMovementOptions = [
{ value: 'purchase_in', label: '采购入库' },
{ value: 'return_from_production', label: '生产退料入库' },
{ value: 'outsource_return', label: '外协回库' },
{ value: 'finish_in', label: '完工入库' },
{ value: 'in', label: '其他入库' }
];
const outboundMovementOptions = [
{ value: 'issue_to_production', label: '生产领料出库' },
{ value: 'outsource_send', label: '外协发料出库' },
{ value: 'shipment_out', label: '销售出库' },
{ value: 'scrap_out', label: '报废出库' },
{ value: 'out', label: '其他出库' }
];
const getMovementTypeLabel = (movementType) => {
const movementLabelMap = {
in: '其他入库',
out: '其他出库',
adjust: '库存调整',
purchase_in: '采购入库',
return_from_production: '生产退料入库',
outsource_return: '外协回库',
finish_in: '完工入库',
issue_to_production: '生产领料出库',
outsource_send: '外协发料出库',
shipment_out: '销售出库',
scrap_out: '报废出库'
};
return movementLabelMap[movementType] || movementType;
};
const getMovementBadgeClass = (movementType) => {
if (['purchase_in', 'return_from_production', 'outsource_return', 'finish_in', 'in'].includes(movementType)) {
return 'badge-success';
}
if (['issue_to_production', 'outsource_send', 'shipment_out', 'scrap_out', 'out'].includes(movementType)) {
return 'badge-error';
}
return 'badge-warning';
};
const loadDashboard = async () => {
state.loading = true;
try {
@@ -1672,7 +1715,8 @@ const InventoryView = {
state.form = {
product_id: state.products[0]?.id || null,
warehouse_id: state.warehouses.find(w => w.is_default)?.id || state.warehouses[0]?.id || null,
quantity: 1
quantity: 1,
movement_type: type === 'stockIn' ? 'purchase_in' : 'issue_to_production'
};
}
}
@@ -1789,7 +1833,7 @@ const InventoryView = {
try {
await apiRequest('/api/stock-movements', {
method: 'POST',
body: JSON.stringify({ ...state.form, movement_type: 'in' })
body: JSON.stringify({ ...state.form, movement_type: state.form.movement_type || 'purchase_in' })
});
addNotification('入库成功', 'success');
closeModal();
@@ -1804,7 +1848,7 @@ const InventoryView = {
try {
await apiRequest('/api/stock-movements', {
method: 'POST',
body: JSON.stringify({ ...state.form, movement_type: 'out' })
body: JSON.stringify({ ...state.form, movement_type: state.form.movement_type || 'issue_to_production' })
});
addNotification('出库成功', 'success');
closeModal();
@@ -1839,7 +1883,11 @@ const InventoryView = {
deleteCustomer,
stockIn,
stockOut,
refreshFinanceByPeriod
refreshFinanceByPeriod,
inboundMovementOptions,
outboundMovementOptions,
getMovementTypeLabel,
getMovementBadgeClass
};
},
template: `
@@ -1949,8 +1997,8 @@ const InventoryView = {
<div v-else-if="state.activeTab === 'inventory'">
<div class="table-header">
<button class="btn btn-primary" @click="openModal('stockIn')">📥 入库</button>
<button class="btn btn-secondary" @click="openModal('stockOut')" style="margin-left: 8px;">📤 出库</button>
<button class="btn btn-primary" @click="openModal('stockIn')">📥 采购/完工入库</button>
<button class="btn btn-secondary" @click="openModal('stockOut')" style="margin-left: 8px;">📤 领料/销售出库</button>
</div>
<div class="table-container">
<table class="data-table">
@@ -2258,8 +2306,8 @@ const InventoryView = {
<tr v-for="movement in state.movements" :key="movement.id">
<td>{{ movement.product_name }}{{ movement.product_sku ? ' (' + movement.product_sku + ')' : '' }}</td>
<td>
<span :class="['badge', movement.movement_type === 'in' ? 'badge-success' : movement.movement_type === 'out' ? 'badge-error' : 'badge-warning']">
{{ movement.movement_type === 'in' ? '入库' : movement.movement_type === 'out' ? '出库' : '调整' }}
<span :class="['badge', getMovementBadgeClass(movement.movement_type)]">
{{ getMovementTypeLabel(movement.movement_type) }}
</span>
</td>
<td>{{ movement.quantity }}</td>
@@ -2392,6 +2440,12 @@ const InventoryView = {
</option>
</select>
</div>
<div class="form-group">
<label class="form-label">业务类型 *</label>
<select v-model="state.form.movement_type" class="form-input" required>
<option v-for="item in inboundMovementOptions" :key="'stockin-type-' + item.value" :value="item.value">{{ item.label }}</option>
</select>
</div>
<div class="form-group">
<label class="form-label">数量 *</label>
<input v-model.number="state.form.quantity" type="number" class="form-input" required placeholder="入库数量" />
@@ -2430,6 +2484,12 @@ const InventoryView = {
</option>
</select>
</div>
<div class="form-group">
<label class="form-label">业务类型 *</label>
<select v-model="state.form.movement_type" class="form-input" required>
<option v-for="item in outboundMovementOptions" :key="'stockout-type-' + item.value" :value="item.value">{{ item.label }}</option>
</select>
</div>
<div class="form-group">
<label class="form-label">数量 *</label>
<input v-model.number="state.form.quantity" type="number" class="form-input" required placeholder="出库数量" />