单独修改状态接口

This commit is contained in:
2025-07-19 10:49:29 +08:00
parent c2b6e54a09
commit 0ad3f3f3c8
6 changed files with 217 additions and 20 deletions

View File

@@ -42,3 +42,42 @@ export function delStockIo(stockIoId) {
method: 'delete'
})
}
// 审核出入库单
export function auditStockIo(stockIoId) {
return request({
url: '/wms/stockIo/audit/' + stockIoId,
method: 'post'
})
}
// 撤销出入库单
export function cancelStockIo(stockIoId) {
return request({
url: '/wms/stockIo/cancel/' + stockIoId,
method: 'post'
})
}
// 根据类型和ID查询明细
export function detailByTypeAndId(ioType, stockIoId) {
return request({
url: '/wms/stockIo/detailByTypeAndId',
method: 'get',
params: {
ioType,
stockIoId
}
})
}
// 更新出入库单状态
export function updateStockIoStatus(stockIoId, status) {
return request({
url: '/wms/stockIo/updateStatus/' + stockIoId,
method: 'post',
params: {
status
}
})
}

View File

@@ -191,7 +191,10 @@
append-to-body
@close="onDetailClosed"
>
<StockIoDetailPanel :stockIo="detailStockIo" />
<StockIoDetailPanel
:stockIo="detailStockIo"
@status-changed="onStatusChanged"
/>
</el-dialog>
</div>
</template>
@@ -390,6 +393,15 @@ export default {
},
onDetailClosed() {
this.getList();
},
onStatusChanged(updatedStockIo) {
// 更新主表中的对应记录状态
const index = this.stockIoList.findIndex(item => item.stockIoId === updatedStockIo.stockIoId);
if (index !== -1) {
this.$set(this.stockIoList, index, updatedStockIo);
}
// 刷新列表
this.getList();
}
}
};

View File

@@ -63,7 +63,12 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="明细ID" align="center" prop="detailId"/>
<el-table-column label="库区/库位ID" align="center" prop="warehouseId" />
<el-table-column label="源库区/库位ID" align="center" prop="fromWarehouseId" />
<el-table-column
v-if="stockIo.ioType === 'transfer'"
label="源库区/库位ID"
align="center"
prop="fromWarehouseId"
/>
<el-table-column label="物品类型" align="center" prop="itemType" />
<el-table-column label="物品ID" align="center" prop="itemId" />
<el-table-column label="数量" align="center" prop="quantity" />
@@ -96,29 +101,45 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 审核按钮 -->
<!-- 操作按钮 -->
<div style="margin-top: 20px; text-align: right;">
<!-- 状态修改按钮 -->
<el-button
v-if="stockIo.status !== 2"
v-if="stockIo.status === 0"
type="warning"
:loading="statusLoading"
@click="handleUpdateStatus"
>{{ getStatusButtonText() }}</el-button>
<!-- 审核按钮 -->
<el-button
v-if="stockIo.status === 1"
type="primary"
:loading="auditLoading"
@click="handleAudit"
>确认入库/审核</el-button>
>审核</el-button>
</div>
<!-- 明细编辑弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="出入库单ID" prop="stockIoId">
<el-input v-model="form.stockIoId" placeholder="请输入出入库单ID" :disabled="true" />
</el-form-item>
<el-form-item label="库区/库位ID" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入库区/库位ID" />
<el-form-item label="库区/库位" prop="warehouseId">
<warehouse-select v-model="form.warehouseId" placeholder="请选择库区/库位" />
</el-form-item>
<el-form-item label="源库区/库位ID" prop="fromWarehouseId">
<el-input v-model="form.fromWarehouseId" placeholder="请输入源库区/库位ID" />
<el-form-item
v-if="stockIo.ioType === 'transfer'"
label="源库区/库位"
prop="fromWarehouseId"
>
<warehouse-select v-model="form.fromWarehouseId" placeholder="请选择源库区/库位" />
</el-form-item>
<el-form-item label="物品类型" prop="itemType">
<el-input v-model="form.itemType" placeholder="请输入物品类型" />
<el-select v-model="form.itemType" placeholder="请选择物品类型" style="width: 100%">
<el-option label="原材料" value="raw_material"></el-option>
<el-option label="产品" value="product"></el-option>
</el-select>
</el-form-item>
<el-form-item label="物品ID" prop="itemId">
<el-input v-model="form.itemId" placeholder="请输入物品ID" />
@@ -150,9 +171,14 @@
<script>
import { listStockIoDetail, getStockIoDetail, delStockIoDetail, addStockIoDetail, updateStockIoDetail } from "@/api/wms/stockIoDetail";
import { auditStockIo } from "@/api/wms/stockIo";
import { auditStockIo, updateStockIoStatus } from "@/api/wms/stockIo";
import WarehouseSelect from '@/components/WarehouseSelect';
export default {
name: "StockIoDetailPanel",
components: {
WarehouseSelect
},
props: {
stockIo: {
type: Object,
@@ -176,7 +202,7 @@ export default {
buttonLoading: false,
rules: {
warehouseId: [
{ required: true, message: "库区/库位ID不能为空", trigger: "blur" }
{ required: true, message: "库区/库位不能为空", trigger: "blur" }
],
itemType: [
{ required: true, message: "物品类型不能为空", trigger: "blur" }
@@ -193,7 +219,8 @@ export default {
},
ids: [],
single: true,
multiple: true
multiple: true,
statusLoading: false // 新增状态修改按钮加载状态
};
},
watch: {
@@ -225,12 +252,31 @@ export default {
});
},
handleAudit() {
this.auditLoading = true;
auditStockIo(this.stockIo.stockIoId).then(() => {
this.$modal.msgSuccess('审核成功');
this.$set(this.stockIo, 'status', 2);
}).finally(() => {
this.auditLoading = false;
// 检查是否有明细数据
if (!this.stockIoDetailList || this.stockIoDetailList.length === 0) {
this.$modal.msgError('请先添加明细数据');
return;
}
// 确认审核
this.$modal.confirm('确认要审核此出入库单吗?审核后将影响库存数据。').then(() => {
this.auditLoading = true;
auditStockIo(this.stockIo.stockIoId).then(response => {
this.$modal.msgSuccess('审核成功');
// 更新主表状态
this.$set(this.stockIo, 'status', 2);
// 刷新明细列表
this.getList();
// 通知父组件状态已更新
this.$emit('status-changed', this.stockIo);
}).catch(error => {
console.error('审核失败:', error);
this.$modal.msgError('审核失败:' + (error.message || '未知错误'));
}).finally(() => {
this.auditLoading = false;
});
}).catch(() => {
// 用户取消审核
});
},
handleSelectionChange(selection) {
@@ -256,6 +302,15 @@ export default {
});
},
submitForm() {
// 动态添加源库位验证规则
if (this.stockIo.ioType === 'transfer') {
this.$set(this.rules, 'fromWarehouseId', [
{ required: true, message: "源库区/库位不能为空", trigger: "blur" }
]);
} else {
this.$delete(this.rules, 'fromWarehouseId');
}
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
@@ -316,6 +371,53 @@ export default {
this.download('klp/stockIoDetail/export', {
...this.queryParams
}, `stockIoDetail_${new Date().getTime()}.xlsx`)
},
getAuditButtonText() {
if (this.stockIo.ioType === 'in') {
return '确认入库/审核';
} else if (this.stockIo.ioType === 'out') {
return '确认出库/审核';
} else if (this.stockIo.ioType === 'transfer') {
return '确认移库/审核';
} else {
return '审核';
}
},
getStatusButtonText() {
if (this.stockIo.ioType === 'in') {
return '确认入库';
} else if (this.stockIo.ioType === 'out') {
return '确认出库';
} else if (this.stockIo.ioType === 'transfer') {
return '确认移库';
} else {
return '修改状态';
}
},
handleUpdateStatus() {
// 检查是否有明细数据
if (!this.stockIoDetailList || this.stockIoDetailList.length === 0) {
this.$modal.msgError('请先添加明细数据');
return;
}
this.$modal.confirm('确认要提交此出入库单吗?提交后将无法修改明细。').then(() => {
this.statusLoading = true;
updateStockIoStatus(this.stockIo.stockIoId, 1).then(response => {
this.$modal.msgSuccess('状态更新成功');
// 更新主表状态
this.$set(this.stockIo, 'status', 1);
// 通知父组件状态已更新
this.$emit('status-changed', this.stockIo);
}).catch(error => {
console.error('状态更新失败:', error);
this.$modal.msgError('状态更新失败:' + (error.message || '未知错误'));
}).finally(() => {
this.statusLoading = false;
});
}).catch(() => {
// 用户取消状态更新
});
}
}
}

View File

@@ -126,4 +126,14 @@ public class WmsStockIoController extends BaseController {
public R<List<WmsStockIoDetailVo>> detailByTypeAndId(@RequestParam String ioType, @RequestParam Long stockIoId) {
return R.ok(iWmsStockIoService.detailByTypeAndId(ioType, stockIoId));
}
/**
* 更新出入库单状态
*/
@Log(title = "出入库单主", businessType = BusinessType.UPDATE)
@PostMapping("/updateStatus/{stockIoId}")
public R<Void> updateStatus(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId,
@RequestParam Integer status) {
return toAjax(iWmsStockIoService.updateStatus(stockIoId, status));
}
}

View File

@@ -62,4 +62,9 @@ public interface IWmsStockIoService {
* 根据ioType和stockIoId联查明细
*/
java.util.List<WmsStockIoDetailVo> detailByTypeAndId(String ioType, Long stockIoId);
/**
* 更新出入库单状态
*/
Boolean updateStatus(Long stockIoId, Integer status);
}

View File

@@ -238,6 +238,35 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService {
return voList;
}
/**
* 更新出入库单状态
*/
@Override
public Boolean updateStatus(Long stockIoId, Integer status) {
WmsStockIo stockIo = baseMapper.selectById(stockIoId);
if (stockIo == null) {
throw new ServiceException("单据不存在");
}
// 状态流转验证
if (stockIo.getStatus() == 0 && status == 1) {
// 草稿 -> 已提交:需要检查是否有明细
List<WmsStockIoDetail> details = stockIoDetailMapper.selectList(
Wrappers.<WmsStockIoDetail>lambdaQuery().eq(WmsStockIoDetail::getStockIoId, stockIoId)
);
if (details == null || details.isEmpty()) {
throw new ServiceException("单据明细不能为空,无法提交");
}
} else if (stockIo.getStatus() == 1 && status == 0) {
// 已提交 -> 草稿:允许回退
} else {
throw new ServiceException("状态流转不允许");
}
stockIo.setStatus(status);
return baseMapper.updateById(stockIo) > 0;
}
/**
* 库存增减isAdd=true为增加false为减少减少时校验库存是否足够
*/