新增 ERP 采购申请功能,实现从需求部门发起采购需求到生成采购订单的完整流程管理。
重要说明:采购申请审批需要集成 BPM 工作流,必须先在 BPM 模块创建 purchase_request_approve 分类和对应的审批流程。
采购申请审批需要 BPM 流程支持,必须先完成以下配置:
purchase_request_approve 分类erp-purchase-request-auditpurchase_request_approve 分类执行 SQL:sql -- 创建 BPM 采购申请审批分类 INSERT INTO bpm_category (id, name, code, description, status, sort, creator, create_time, updater, update_time, deleted) VALUES (101, '采购申请审批', 'purchase_request_approve', '采购申请审批流程分类', 0, 11, '1', NOW(), '1', NOW(), 0);
校验逻辑:
- 提交采购申请时,系统会校验 BPM 采购申请审批分类是否存在
- 如果分类不存在,会抛出异常:采购申请审批分类不存在,请先在BPM模块创建采购申请审批流程分类
- 如果流程标识为 erp-purchase-request-audit 的流程未发布或未激活,会抛出异常:采购申请审批流程未发布或未激活,请先创建流程标识为[erp-purchase-request-audit]的流程模型并发布
/erp/purchase/request/index - 采购申请列表/erp/purchase/request/form - 采购申请表单(新增/编辑)/erp/purchase/request/detail - 采购申请详情| 序号 | 功能 | 说明 |
|---|---|---|
| 1 | 新增采购申请 | 创建草稿状态的采购申请 |
| 2 | 编辑采购申请 | 修改草稿状态的采购申请 |
| 3 | 删除采购申请 | 删除草稿状态的采购申请 |
| 4 | 提交审批 | 提交 BPM 流程审批 |
| 5 | 生成采购订单 | 审批通过后生成采购订单 |
| 6 | 导出 Excel | 导出采购申请列表 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /erp/purchase-request/create | 创建采购申请 |
| PUT | /erp/purchase-request/update | 更新采购申请 |
| PUT | /erp/purchase-request/submit | 提交采购申请审批 |
| DELETE | /erp/purchase-request/delete | 删除采购申请 |
| GET | /erp/purchase-request/get | 获得采购申请详情 |
| GET | /erp/purchase-request/page | 获得采购申请分页 |
| GET | /erp/purchase-request/export-excel | 导出采购申请 Excel |
| POST | /erp/purchase-request/generate-order | 生成采购订单 |
| GET | /erp/purchase-request/approve-process-list | 获取审批流程列表 |
文件上传:使用通用接口
POST /infra/file/upload,参数file+directory=purchase-request,返回文件 URL。详见docs/file_upload_guide.md。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| requestTime | DateTime | 是 | 申请时间 |
| requestReason | String | 否 | 申请理由 |
| supplierId | Long | 否 | 供应商编号(可选) |
| discountPercent | BigDecimal | 否 | 优惠率,百分比 |
| fileUrl | String | 否 | 附件地址 |
| remark | String | 否 | 备注 |
| items | List | 是 | 申请明细列表 |
items 明细参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| productId | Long | 是 | 产品编号 |
| productUnitId | Long | 是 | 产品单位编号 |
| productPrice | BigDecimal | 否 | 产品单价(参考价) |
| count | BigDecimal | 是 | 数量 |
| taxPercent | BigDecimal | 否 | 税率,百分比 |
| demandTime | Date | 否 | 需求日期 |
| remark | String | 否 | 备注 |
响应: { "code": 0, "data": 1001, "msg": "操作成功" }
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 采购申请编号 |
| processDefinitionKey | String | 是 | 流程定义 Key(用户从流程列表中选择) |
响应: { "code": 0, "msg": "操作成功" }
流程选择:提交审批前,需先调用
/erp/purchase-request/approve-process-list获取可选流程列表,让用户选择后传入processDefinitionKey。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 采购申请编号 |
| supplierId | Long | 是 | 供应商编号 |
响应: { "code": 0, "data": 2001, "msg": "操作成功" }(返回采购订单编号)
{
"code": 0,
"data": {
"list": [
{
"id": 1,
"no": "CGSQ20260701000001",
"status": 20,
"requestUserId": 1,
"requestUserName": "张三",
"requestDeptId": 100,
"requestDeptName": "生产部",
"requestTime": "2026-07-01 10:00:00",
"requestReason": "生产需要",
"supplierId": 1,
"supplierName": "供应商A",
"totalCount": 100.00,
"totalPrice": 10000.00,
"productNames": "产品A,产品B",
"orderId": 2001,
"orderNo": "CGDD20260701000001",
"createTime": "2026-07-01 10:00:00"
}
],
"total": 1
},
"msg": "操作成功"
}
| 状态值 | 状态名 | 说明 |
|---|---|---|
| 0 | 未提交 | 草稿状态,可编辑、可删除 |
| 10 | 审批中 | 已提交审批,不可修改 |
| 20 | 审核通过 | 审批通过,可生成采购订单 |
| 30 | 审核不通过 | 审批被拒绝,可重新提交 |
| 40 | 已取消 | 流程被取消 |
状态流转图: 草稿(0) -> 提交 -> 审批中(10) -> 审批通过(20) -> 生成采购订单 | +-> 审批不通过(30) -> 重新提交 -> 审批中(10) | +-> 已取消(40)
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true">
<el-form-item label="申请单号" prop="no">
<el-input v-model="queryParams.no" placeholder="请输入申请单号" clearable />
</el-form-item>
<el-form-item label="申请人" prop="requestUserId">
<el-select v-model="queryParams.requestUserId" placeholder="请选择申请人" clearable>
<!-- 用户列表 -->
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
<el-option label="未提交" :value="0" />
<el-option label="审批中" :value="10" />
<el-option label="审核通过" :value="20" />
<el-option label="审核不通过" :value="30" />
<el-option label="已取消" :value="40" />
</el-select>
</el-form-item>
<el-form-item label="申请时间" prop="requestTime">
<el-date-picker v-model="queryParams.requestTime" type="daterange" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" @click="handleAdd" v-hasPermi="['erp:purchase-request:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" @click="handleExport" v-hasPermi="['erp:purchase-request:export']">导出</el-button>
</el-col>
</el-row>
<!-- 表格操作列 -->
<el-table-column label="操作" align="center" width="200">
<template #default="scope">
<el-button link type="primary" @click="handleDetail(scope.row)">详情</el-button>
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-if="scope.row.status === 0" v-hasPermi="['erp:purchase-request:update']">编辑</el-button>
<el-button link type="primary" @click="handleSubmit(scope.row)"
v-if="scope.row.status === 0" v-hasPermi="['erp:purchase-request:submit']">提交</el-button>
<el-button link type="primary" @click="handleGenerateOrder(scope.row)"
v-if="scope.row.status === 20 && !scope.row.orderId" v-hasPermi="['erp:purchase-request:generate-order']">生成订单</el-button>
<el-button link type="danger" @click="handleDelete(scope.row)"
v-if="scope.row.status === 0" v-hasPermi="['erp:purchase-request:delete']">删除</el-button>
</template>
</el-table-column>
data() {
return {
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
no: undefined,
requestUserId: undefined,
requestDeptId: undefined,
requestTime: [],
status: undefined,
productId: undefined,
},
// 状态字典
statusOptions: [
{ value: 0, label: '未提交' },
{ value: 10, label: '审批中' },
{ value: 20, label: '审核通过' },
{ value: 30, label: '审核不通过' },
{ value: 40, label: '已取消' },
],
}
}
methods: {
// 提交审批
async handleSubmit(row) {
try {
await this.$modal.confirm('确认提交该采购申请进行审批?')
await submitPurchaseRequest(row.id)
this.$modal.msgSuccess('提交成功')
this.getList()
} catch {}
},
// 生成采购订单
async handleGenerateOrder(row) {
try {
// 弹窗选择供应商
const { value: supplierId } = await this.$prompt('请选择供应商', '生成采购订单', {
inputType: 'select',
inputOptions: this.supplierOptions,
inputValidator: (value) => {
if (!value) return '请选择供应商'
return true
}
})
const orderId = await generatePurchaseOrder(row.id, supplierId)
this.$modal.msgSuccess(`生成采购订单成功,订单编号:${orderId}`)
this.getList()
} catch {}
},
}
使用通用文件上传接口
POST /infra/file/upload,详见docs/file_upload_guide.md。
<!-- 表单中的附件上传 -->
<el-form-item label="附件" prop="fileUrl">
<el-upload
:action="uploadUrl"
:headers="headers"
:data="{ directory: 'purchase-request' }"
:on-success="handleUploadSuccess"
:before-upload="beforeUpload"
:file-list="fileList"
:limit="1"
>
<el-button type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">支持 pdf、doc、docx、xls、xlsx 格式,最大 10MB</div>
</template>
</el-upload>
</el-form-item>
data() {
return {
// 文件上传配置(使用通用接口)
uploadUrl: process.env.VUE_APP_BASE_API + '/infra/file/upload',
headers: { Authorization: 'Bearer ' + getToken() },
fileList: [],
}
},
methods: {
handleUploadSuccess(response) {
if (response.code === 0) {
this.form.fileUrl = response.data
this.$modal.msgSuccess('上传成功')
} else {
this.$modal.msgError(response.msg || '上传失败')
}
},
beforeUpload(file) {
const allowedTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
const isAllowed = allowedTypes.includes(file.type) || file.name.endsWith('.pdf') || file.name.endsWith('.doc') || file.name.endsWith('.docx')
|| file.name.endsWith('.xls') || file.name.endsWith('.xlsx')
if (!isAllowed) {
this.$message.error('只支持 pdf、doc、docx、xls、xlsx 格式!')
return false
}
const isLt10M = file.size / 1024 / 1024 < 10
if (!isLt10M) {
this.$message.error('文件大小不能超过 10MB!')
return false
}
return true
},
}
| 权限标识 | 说明 |
|---|---|
| erp:purchase-request:query | 查询采购申请 |
| erp:purchase-request:create | 新增采购申请 |
| erp:purchase-request:update | 修改采购申请 |
| erp:purchase-request:delete | 删除采购申请 |
| erp:purchase-request:submit | 提交审批 |
| erp:purchase-request:export | 导出采购申请 |
| erp:purchase-request:generate-order | 生成采购订单 |