# 采购管理模块 - 前端开发规范 > 本文档为采购管理模块的前端开发技术规范,包含UI组件规范、字段验证、API接口等内容。 --- ## 1. 技术栈 | 技术 | 版本 | 说明 | |------|------|------| | Vue | 2.x | 前端框架 | | Element UI | 2.x | UI组件库 | | Axios | - | HTTP请求库 | | Vue Router | 3.x | 路由管理 | | Vuex | 3.x | 状态管理 | --- ## 2. 设计规范 ### 2.1 颜色规范 | 用途 | 色值 | 说明 | |------|------|------| | 主色 | #409EFF | 按钮、链接等 | | 成功色 | #67C23A | 成功状态 | | 警告色 | #E6A23C | 警告状态 | | 危险色 | #F56C6C | 错误、删除 | | 信息色 | #909399 | 次要信息 | | 背景色 | #F5F7FA | 页面背景 | | 边框色 | #DCDFE6 | 表格边框 | ### 2.2 状态标签颜色 | 状态 | 颜色类型 | Element Type | |------|----------|--------------| | 开立 | 信息 | info | | 审核 | 成功 | success | | 关闭 | 默认 | - | | 退回 | 警告 | warning | | 入账 | 成功 | success | ### 2.3 字体规范 | 用途 | 字号 | 字重 | |------|------|------| | 页面标题 | 20px | 500 | | 模块标题 | 16px | 500 | | 正文 | 14px | 400 | | 辅助文字 | 12px | 400 | | 表格文字 | 14px | 400 | ### 2.4 间距规范 | 用途 | 间距 | |------|------| | 页面边距 | 20px | | 模块间距 | 20px | | 表单行间距 | 22px | | 按钮间距 | 10px | | 表格单元格内边距 | 12px 0 | --- ## 3. 通用组件规范 ### 3.1 表格组件 ```vue ``` ### 3.2 查询表单 ```vue 搜索 ``` ### 3.3 弹窗组件 ```vue 取 消 确 定 ``` ### 3.4 分页组件 ```vue ``` --- ## 4. 数据字典 ### 4.1 单据状态(status) | 值 | 显示名称 | 说明 | |----|----------|------| | DRAFT | 开立 | 草稿状态 | | APPROVED | 审核 | 已审核 | | CLOSED | 关闭 | 已关闭 | | RETURNED | 退回 | 已退回 | ### 4.2 业务类型(businessType) | 值 | 显示名称 | |----|----------| | RAW_MATERIAL | 原材料 | | PARTS | 零部件 | | ASSEMBLY | 装配件 | | FINISHED | 成品 | | HARDWARE | 五金件 | | PACKAGING | 包装物 | ### 4.3 财务状态(financeStatus) | 值 | 显示名称 | |----|----------| | RECORDED | 录入 | | ENTERED | 入账 | ### 4.4 用料需求(materialNeed) | 值 | 显示名称 | |----|----------| | ORDER_USE | 订单用料 | | STOCK_USE | 备库用料 | ### 4.5 供应商状态(enableFlag) | 值 | 显示名称 | |----|----------| | Y | 正常 | | N | 停用 | ### 4.6 供应商等级(supplierLevel) | 值 | 显示名称 | |----|----------| | A | A级 | | B | B级 | | C | C级 | | D | D级 | --- ## 5. 表单字段规范 ### 5.1 原料供应商表单 | 字段名 | 字段key | 类型 | 必填 | 验证规则 | |--------|---------|------|------|----------| | 供应商名称 | supplierName | String | 是 | 最大100字符 | | 供应商别名 | supplierAlias | String | 否 | 最大100字符 | | 简称 | supplierNick | String | 否 | 最大50字符 | | 所属省/市 | provinceCity | Array | 否 | 级联选择 | | 供应料品 | supplyItems | Array | 否 | 多选 | | 供应商分类 | supplierType | String | 否 | 单选 | | 供应商等级 | supplierLevel | String | 否 | A/B/C/D | | 公司地址 | address | String | 否 | 最大200字符 | | 邮编 | zipCode | String | 否 | 6位数字 | | 电话 | tel | String | 否 | 电话格式 | | 备注 | remark | String | 否 | 最大500字符 | | 状态 | enableFlag | String | 否 | Y/N | | 开户行 | bankName | String | 否 | 最大100字符 | | 地址电话 | bankAddress | String | 否 | 最大200字符 | | 账号 | bankAccount | String | 否 | 最大30字符 | | 税号 | taxNo | String | 否 | 最大30字符 | | 业务联系人 | contact1 | String | 否 | 最大50字符 | | 业务手机 | contact1Tel | String | 否 | 手机格式 | | 财务联系人 | contact2 | String | 否 | 最大50字符 | | 财务手机 | contact2Tel | String | 否 | 手机格式 | ### 5.2 采购订单表单 | 字段名 | 字段key | 类型 | 必填 | 验证规则 | |--------|---------|------|------|----------| | 单据编码 | orderCode | String | 自动 | 系统生成 | | 单据日期 | orderDate | Date | 是 | 日期格式 | | 业务类型 | businessType | String | 是 | 必选 | | 单据类型 | orderType | String | 是 | 固定值 | | 采购部门 | deptId | Integer | 否 | 部门选择 | | 采购人员 | userId | Integer | 否 | 人员选择 | | 用料需求 | materialNeed | String | 是 | 必选 | | 供方 | supplierId | Integer | 否 | 供应商选择 | | 到货日期 | deliveryDate | Date | 否 | 日期格式 | | 合同号 | contractNo | String | 否 | 最大50字符 | | 备注信息 | remark | String | 否 | 最大500字符 | ### 5.3 采购订单明细 | 字段名 | 字段key | 类型 | 必填 | 验证规则 | |--------|---------|------|------|----------| | 物料编码 | itemCode | String | 是 | 物料选择 | | 物料名称 | itemName | String | - | 自动带出 | | 型号规格 | specification | String | - | 自动带出 | | 主计量 | unitName | String | - | 自动带出 | | 需求日期 | needDate | Date | 否 | 日期格式 | | 数量 | quantity | Decimal | 是 | >0 | | 单价 | unitPrice | Decimal | 否 | >=0 | | 金额 | amount | Decimal | - | 自动计算 | | 采购说明 | remark | String | 否 | 最大200字符 | --- ## 6. API 接口规范 > Base URL: `https://demo.rsun.vip/prod-api` ### 6.1 接口基础规范 #### 请求格式 ```javascript // Content-Type: application/json // 字符编码: UTF-8 // GET 请求 - 查询列表 axios.get('/po/supplier', { params: queryParams }) // GET 请求 - 获取详情 axios.get('/po/supplier/' + supplierId) // POST 请求 - 新增 axios.post('/po/supplier', formData) // PUT 请求 - 更新 axios.put('/po/supplier', formData) // DELETE 请求 - 删除(支持批量,逗号分隔) axios.delete('/po/supplier/' + supplierIds) ``` #### 响应格式 ```javascript // 通用响应 (AjaxResult) { "code": 200, // 状态码:200成功 "msg": "操作成功", // 提示信息 "data": { ... } // 返回数据 } // 分页响应 (TableDataInfo) { "total": 100, // 总条数 "rows": [ ... ], // 数据列表 "code": 200, "msg": "查询成功" } ``` ### 6.2 供应商接口 (/po/supplier) | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 分页列表 | GET | /po/supplier/list | 查询供应商列表 | | 详情 | GET | /po/supplier/{supplierId} | 获取供应商详情 | | 新增 | POST | /po/supplier | 新增供应商 | | 更新 | PUT | /po/supplier | 更新供应商 | | 删除 | DELETE | /po/supplier/{supplierIds} | 批量删除 | | 导出 | POST | /po/supplier/export | 导出Excel | #### 查询参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | supplierName | String | 否 | 供应商名称 | | contact1 | String | 否 | 业务联系人 | | supplyItem | String | 否 | 供应料品 | | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 | ### 6.3 采购订单接口 (/po/order) | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 分页列表 | GET | /po/order/list | 查询订单列表 | | 详情 | GET | /po/order/{orderId} | 获取订单详情 | | 新增 | POST | /po/order | 新增订单 | | 更新 | PUT | /po/order | 更新订单 | | 删除 | DELETE | /po/order/{orderIds} | 批量删除 | | 审核 | PUT | /po/order/approve | 审核订单 | | 反审核 | PUT | /po/order/unapprove | 反审核订单 | | 导出 | POST | /po/order/export | 导出Excel | #### 查询参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | trackCode | String | 否 | 跟单编号 | | orderCode | String | 否 | 单据编码 | | supplierName | String | 否 | 供应商名称 | | itemCode | String | 否 | 物料编码 | | itemName | String | 否 | 物料名称 | | beginDate | String | 否 | 开始日期 | | endDate | String | 否 | 结束日期 | | pageNum | Integer | 否 | 页码 | | pageSize | Integer | 否 | 每页条数 | ### 6.4 采购到货单接口 (/po/checkin) | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 分页列表 | GET | /po/checkin/list | 查询到货单列表 | | 详情 | GET | /po/checkin/{checkinId} | 获取到货单详情 | | 新增 | POST | /po/checkin | 新增到货单 | | 更新 | PUT | /po/checkin | 更新到货单 | | 删除 | DELETE | /po/checkin/{checkinIds} | 批量删除 | | 审核 | PUT | /po/checkin/approve | 审核 | | 导出 | POST | /po/checkin/export | 导出Excel | ### 6.5 采购发票接口 (/po/invoice) | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 分页列表 | GET | /po/invoice/list | 查询发票列表 | | 详情 | GET | /po/invoice/{invoiceId} | 获取发票详情 | | 新增 | POST | /po/invoice | 新增发票 | | 更新 | PUT | /po/invoice | 更新发票 | | 删除 | DELETE | /po/invoice/{invoiceIds} | 批量删除 | | 审核 | PUT | /po/invoice/approve | 审核 | | 入账 | PUT | /po/invoice/enter | 入账 | | 导出 | POST | /po/invoice/export | 导出Excel | ### 6.6 采购退货单接口 (/po/reject) | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 分页列表 | GET | /po/reject/list | 查询退货单列表 | | 详情 | GET | /po/reject/{rejectId} | 获取退货单详情 | | 新增 | POST | /po/reject | 新增退货单 | | 更新 | PUT | /po/reject | 更新退货单 | | 删除 | DELETE | /po/reject/{rejectIds} | 批量删除 | | 审核 | PUT | /po/reject/approve | 审核 | | 导出 | POST | /po/reject/export | 导出Excel | --- ## 7. 业务逻辑 ### 7.1 金额计算 ```javascript // 采购订单明细金额计算 function calculateAmount(quantity, unitPrice) { if (!quantity || !unitPrice) return 0; return (parseFloat(quantity) * parseFloat(unitPrice)).toFixed(2); } // 发票税额计算 function calculateTax(amount, taxRate) { if (!amount || !taxRate) return 0; return (parseFloat(amount) * parseFloat(taxRate) / 100).toFixed(2); } // 价税合计 function calculateTotal(amount, tax) { return (parseFloat(amount || 0) + parseFloat(tax || 0)).toFixed(2); } ``` ### 7.2 按钮权限控制 ```javascript // 按钮显示逻辑 const buttonPermissions = { // 审核按钮:开立状态可见 approve: (status) => status === 'DRAFT', // 反审核按钮:审核状态可见 unapprove: (status) => status === 'APPROVED', // 编辑按钮:开立状态可见 edit: (status) => status === 'DRAFT', // 删除按钮:开立状态可见 delete: (status) => status === 'DRAFT', // 入账按钮:审核状态可见(发票) enter: (status) => status === 'APPROVED' }; ``` ### 7.3 字段联动 ```javascript // 采购部门 -> 采购人员联动 watch: { 'form.deptId': function(newVal) { if (newVal) { this.getUsersByDept(newVal); } else { this.userOptions = []; this.form.userId = null; } } } // 物料选择后自动带出信息 function onItemSelect(item) { this.form.itemCode = item.itemCode; this.form.itemName = item.itemName; this.form.specification = item.specification; this.form.unitName = item.unitName; this.form.unitPrice = item.purchasePrice || 0; } ``` --- ## 8. 文件目录结构 ``` src/ ├── views/ │ └── po/ # 采购管理模块 │ ├── supplier/ # 供应商管理 │ │ └── index.vue │ ├── order/ # 采购订单 │ │ ├── index.vue # 列表页 │ │ └── form.vue # 新增/编辑页 │ ├── checkin/ # 采购到货 │ │ ├── index.vue │ │ └── form.vue │ ├── invoice/ # 采购发票 │ │ ├── index.vue │ │ └── form.vue │ ├── reject/ # 采购退货 │ │ ├── index.vue │ │ └── form.vue │ └── report/ # 报表 │ ├── detail.vue # 执行明细表 │ ├── total.vue # 执行汇总表 │ ├── line.vue # 到货明细表 │ └── fapiaoreport.vue # 发票明细表 ├── api/ │ └── po/ │ ├── supplier.js # 供应商接口 │ ├── order.js # 采购订单接口 │ ├── checkin.js # 到货单接口 │ ├── invoice.js # 发票接口 │ └── reject.js # 退货单接口 └── components/ └── po/ ├── SupplierSelect.vue # 供应商选择组件 ├── ItemSelect.vue # 物料选择组件 └── PlanImport.vue # 计划引入组件 ``` --- ## 9. 路由配置 ```javascript { path: '/po', component: Layout, redirect: '/po/supplier', name: 'Po', meta: { title: '采购管理', icon: 'shopping' }, children: [ { path: 'supplier', component: () => import('@/views/po/supplier/index'), name: 'PoSupplier', meta: { title: '原料供应商' } }, { path: 'order', component: () => import('@/views/po/order/index'), name: 'PoOrder', meta: { title: '采购订单' } }, { path: 'order/add', component: () => import('@/views/po/order/form'), name: 'PoOrderAdd', meta: { title: '新增采购订单', activeMenu: '/po/order' }, hidden: true }, { path: 'order/edit/:id', component: () => import('@/views/po/order/form'), name: 'PoOrderEdit', meta: { title: '编辑采购订单', activeMenu: '/po/order' }, hidden: true }, { path: 'checkin', component: () => import('@/views/po/checkin/index'), name: 'PoCheckin', meta: { title: '采购到货单' } }, { path: 'invoice', component: () => import('@/views/po/invoice/index'), name: 'PoInvoice', meta: { title: '采购发票' } }, { path: 'reject', component: () => import('@/views/po/reject/index'), name: 'PoReject', meta: { title: '采购退货单' } }, { path: 'report/detail', component: () => import('@/views/po/report/detail'), name: 'PoReportDetail', meta: { title: '采购执行明细表' } }, { path: 'report/total', component: () => import('@/views/po/report/total'), name: 'PoReportTotal', meta: { title: '采购执行汇总表' } }, { path: 'report/line', component: () => import('@/views/po/report/line'), name: 'PoReportLine', meta: { title: '采购到货明细表' } }, { path: 'report/fapiao', component: () => import('@/views/po/report/fapiaoreport'), name: 'PoReportFapiao', meta: { title: '采购发票明细表' } } ] } ```