Files
my-mom-system/prd/采购管理-前端开发规范.md
panchengyong c28ada5050 commit content
2026-03-06 02:02:59 +08:00

594 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 采购管理模块 - 前端开发规范
> 本文档为采购管理模块的前端开发技术规范包含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
<el-table
:data="tableData"
border
stripe
style="width: 100%"
:header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
@row-click="handleRowClick"
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="code" label="单据编码" min-width="120" />
<el-table-column prop="status" label="状态" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="handleView(scope.row)">查看</el-button>
<el-button type="text" @click="handleEdit(scope.row)">修改</el-button>
<el-button type="text" class="danger-text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
```
### 3.2 查询表单
```vue
<el-form :inline="true" :model="queryParams" class="query-form">
<el-form-item label="供应商名称">
<el-input v-model="queryParams.supplierName" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="单据日期">
<el-date-picker
v-model="queryParams.dateRange"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
</el-form-item>
</el-form>
```
### 3.3 弹窗组件
```vue
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
width="800px"
:close-on-click-modal="false"
@close="handleClose"
>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<!-- 表单内容 -->
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</span>
</el-dialog>
```
### 3.4 分页组件
```vue
<el-pagination
background
:current-page="queryParams.pageNum"
:page-size="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
```
---
## 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: '采购发票明细表' }
}
]
}
```