潘的第一次 commit
This commit is contained in:
156
erp-frontend-vue/src/api/__tests__/customer.test.ts
Normal file
156
erp-frontend-vue/src/api/__tests__/customer.test.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import {
|
||||
getCustomerList,
|
||||
getCustomerDetail,
|
||||
createCustomer,
|
||||
updateCustomer,
|
||||
deleteCustomer,
|
||||
updateCustomerStatus,
|
||||
type Customer,
|
||||
type CustomerQuery
|
||||
} from '../customer'
|
||||
|
||||
const mockGet = vi.fn()
|
||||
const mockPost = vi.fn()
|
||||
const mockPut = vi.fn()
|
||||
const mockDelete = vi.fn()
|
||||
|
||||
vi.mock('../request', () => ({
|
||||
default: {
|
||||
get: (...args: unknown[]) => mockGet(...args),
|
||||
post: (...args: unknown[]) => mockPost(...args),
|
||||
put: (...args: unknown[]) => mockPut(...args),
|
||||
delete: (...args: unknown[]) => mockDelete(...args)
|
||||
}
|
||||
}))
|
||||
|
||||
describe('customer API', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('getCustomerList', () => {
|
||||
it('requests list and maps rows with compat fields', async () => {
|
||||
mockGet.mockResolvedValue({
|
||||
rows: [
|
||||
{
|
||||
clientId: 1,
|
||||
clientCode: 'C001',
|
||||
clientName: '客户A',
|
||||
clientNick: 'A',
|
||||
contact1: '张三',
|
||||
contact1Tel: '13800001111',
|
||||
address: '深圳市',
|
||||
enableFlag: 'Y',
|
||||
createTime: '2026-01-25 10:00:00'
|
||||
}
|
||||
],
|
||||
total: 1
|
||||
})
|
||||
|
||||
const res = await getCustomerList({
|
||||
clientCode: 'C001',
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
expect(mockGet).toHaveBeenCalledWith('/erp/sl/client/list', {
|
||||
params: expect.objectContaining({ clientCode: 'C001', pageNum: 1, pageSize: 10 })
|
||||
})
|
||||
expect(res.list).toHaveLength(1)
|
||||
expect(res.total).toBe(1)
|
||||
expect(res.list[0]).toMatchObject({
|
||||
clientId: 1,
|
||||
clientCode: 'C001',
|
||||
clientName: '客户A',
|
||||
id: 1,
|
||||
code: 'C001',
|
||||
name: '客户A',
|
||||
contact: '张三',
|
||||
phone: '13800001111'
|
||||
})
|
||||
})
|
||||
|
||||
it('maps name param to clientName', async () => {
|
||||
mockGet.mockResolvedValue({ rows: [], total: 0 })
|
||||
await getCustomerList({ name: '测试' } as CustomerQuery)
|
||||
expect(mockGet).toHaveBeenCalledWith('/erp/sl/client/list', {
|
||||
params: expect.objectContaining({ clientName: '测试' })
|
||||
})
|
||||
})
|
||||
|
||||
it('handles res.list or res.data.rows', async () => {
|
||||
mockGet.mockResolvedValue({ list: [{ clientId: 2, clientCode: 'C002', clientName: 'B' }], total: 1 })
|
||||
const res = await getCustomerList({})
|
||||
expect(res.list).toHaveLength(1)
|
||||
expect(res.list[0]?.clientCode).toBe('C002')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getCustomerDetail', () => {
|
||||
it('fetches detail and maps compat fields', async () => {
|
||||
mockGet.mockResolvedValue({
|
||||
data: {
|
||||
clientId: 1,
|
||||
clientCode: 'C001',
|
||||
clientName: '客户A',
|
||||
contact1: '李四',
|
||||
contact1Tel: '13900002222'
|
||||
}
|
||||
})
|
||||
|
||||
const res = await getCustomerDetail(1)
|
||||
expect(mockGet).toHaveBeenCalledWith('/erp/sl/client/1')
|
||||
expect(res.clientId).toBe(1)
|
||||
expect(res.id).toBe(1)
|
||||
expect(res.code).toBe('C001')
|
||||
expect(res.name).toBe('客户A')
|
||||
expect(res.contact).toBe('李四')
|
||||
expect(res.phone).toBe('13900002222')
|
||||
})
|
||||
})
|
||||
|
||||
describe('createCustomer', () => {
|
||||
it('POSTs payload', async () => {
|
||||
mockPost.mockResolvedValue(undefined)
|
||||
const data: Partial<Customer> = {
|
||||
clientCode: 'C003',
|
||||
clientName: '客户C',
|
||||
enableFlag: 'Y'
|
||||
}
|
||||
await createCustomer(data)
|
||||
expect(mockPost).toHaveBeenCalledWith('/erp/sl/client', data)
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateCustomer', () => {
|
||||
it('PUTs payload', async () => {
|
||||
mockPut.mockResolvedValue(undefined)
|
||||
const data: Partial<Customer> = { clientId: 1, clientName: '更新名' }
|
||||
await updateCustomer(data)
|
||||
expect(mockPut).toHaveBeenCalledWith('/erp/sl/client', data)
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteCustomer', () => {
|
||||
it('DELETEs single id', async () => {
|
||||
mockDelete.mockResolvedValue(undefined)
|
||||
await deleteCustomer(1)
|
||||
expect(mockDelete).toHaveBeenCalledWith('/erp/sl/client/1')
|
||||
})
|
||||
|
||||
it('DELETEs comma-separated ids', async () => {
|
||||
mockDelete.mockResolvedValue(undefined)
|
||||
await deleteCustomer([1, 2, 3])
|
||||
expect(mockDelete).toHaveBeenCalledWith('/erp/sl/client/1,2,3')
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateCustomerStatus', () => {
|
||||
it('PUTs clientId and enableFlag', async () => {
|
||||
mockPut.mockResolvedValue(undefined)
|
||||
await updateCustomerStatus(1, 'N')
|
||||
expect(mockPut).toHaveBeenCalledWith('/erp/sl/client', { clientId: 1, enableFlag: 'N' })
|
||||
})
|
||||
})
|
||||
})
|
||||
58
erp-frontend-vue/src/api/auth.ts
Normal file
58
erp-frontend-vue/src/api/auth.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import axios from 'axios'
|
||||
|
||||
// 创建一个专门用于登录相关的 axios 实例(不带 /erp 前缀)
|
||||
const authRequest = axios.create({
|
||||
baseURL: '',
|
||||
timeout: 30000
|
||||
})
|
||||
|
||||
// 登录方法
|
||||
export function login(username: string, password: string, code: string, uuid: string) {
|
||||
return authRequest({
|
||||
url: '/login',
|
||||
method: 'post',
|
||||
data: { username, password, code, uuid }
|
||||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// 注册方法
|
||||
export function register(data: { username: string; password: string; confirmPassword: string }) {
|
||||
return authRequest({
|
||||
url: '/register',
|
||||
method: 'post',
|
||||
data
|
||||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
const token = localStorage.getItem('Admin-Token')
|
||||
return authRequest({
|
||||
url: '/getInfo',
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: token ? `Bearer ${token}` : ''
|
||||
}
|
||||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// 退出方法
|
||||
export function logout() {
|
||||
const token = localStorage.getItem('Admin-Token')
|
||||
return authRequest({
|
||||
url: '/logout',
|
||||
method: 'post',
|
||||
headers: {
|
||||
Authorization: token ? `Bearer ${token}` : ''
|
||||
}
|
||||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() {
|
||||
return authRequest({
|
||||
url: '/captchaImage',
|
||||
method: 'get',
|
||||
timeout: 20000
|
||||
}).then(res => res.data)
|
||||
}
|
||||
96
erp-frontend-vue/src/api/checkin.ts
Normal file
96
erp-frontend-vue/src/api/checkin.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import request from './request'
|
||||
|
||||
export interface CheckinLine {
|
||||
lineId: number
|
||||
checkinId: number
|
||||
checkinCode: string
|
||||
lineNo: number
|
||||
orderLineId?: number
|
||||
trackCode?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
orderQuantity?: number
|
||||
quantity: number
|
||||
stockedQuantity?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface Checkin {
|
||||
checkinId: number
|
||||
checkinCode: string
|
||||
checkinDate: string
|
||||
status: string
|
||||
businessType: string
|
||||
orderId?: number
|
||||
orderCode?: string
|
||||
supplierId?: number
|
||||
supplierName?: string
|
||||
warehouseId?: number
|
||||
warehouseName?: string
|
||||
totalQuantity?: number
|
||||
stockedQuantity?: number
|
||||
remark?: string
|
||||
operatorName?: string
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
lines: CheckinLine[]
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface CheckinQuery {
|
||||
trackCode?: string
|
||||
checkinCode?: string
|
||||
supplierName?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface CheckinListResponse {
|
||||
rows: Checkin[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取采购到货单列表
|
||||
export function getCheckinList(params: CheckinQuery): Promise<CheckinListResponse> {
|
||||
return request.get('/erp/po/checkin/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取采购到货单详情
|
||||
export function getCheckinDetail(checkinId: number): Promise<Checkin> {
|
||||
return request.get(`/erp/po/checkin/${checkinId}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增采购到货单
|
||||
export function createCheckin(data: Partial<Checkin>): Promise<void> {
|
||||
return request.post('/erp/po/checkin', data)
|
||||
}
|
||||
|
||||
// 更新采购到货单
|
||||
export function updateCheckin(data: Partial<Checkin>): Promise<void> {
|
||||
return request.put('/erp/po/checkin', data)
|
||||
}
|
||||
|
||||
// 删除采购到货单
|
||||
export function deleteCheckin(checkinIds: string): Promise<void> {
|
||||
return request.delete(`/erp/po/checkin/${checkinIds}`)
|
||||
}
|
||||
|
||||
// 注意:采购到货单审核接口后端暂未实现
|
||||
// export function approveCheckin(checkinId: number): Promise<void> {
|
||||
// return request.post(`/erp/po/checkin/audit/${checkinId}`)
|
||||
// }
|
||||
63
erp-frontend-vue/src/api/contract.ts
Normal file
63
erp-frontend-vue/src/api/contract.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import request from './request'
|
||||
|
||||
export interface Contract {
|
||||
contractId?: number
|
||||
contractCode?: string
|
||||
contractName?: string
|
||||
clientId?: number
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
contractDate?: string
|
||||
startDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
totalAmount?: number
|
||||
remark?: string
|
||||
createTime?: string
|
||||
tenantId?: string
|
||||
}
|
||||
|
||||
export interface ContractQuery {
|
||||
contractCode?: string
|
||||
clientName?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface ContractListResponse {
|
||||
list: Contract[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取销售合同列表
|
||||
export function getContractList(params: ContractQuery): Promise<ContractListResponse> {
|
||||
return request.get('/sl/contract/list', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取销售合同详情
|
||||
export function getContractDetail(id: number): Promise<Contract> {
|
||||
return request.get(`/sl/contract/${id}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增销售合同
|
||||
export function createContract(data: Partial<Contract>): Promise<void> {
|
||||
return request.post('/sl/contract', data)
|
||||
}
|
||||
|
||||
// 更新销售合同
|
||||
export function updateContract(id: number, data: Partial<Contract>): Promise<void> {
|
||||
return request.put('/sl/contract', { ...data, contractId: id })
|
||||
}
|
||||
|
||||
// 删除销售合同
|
||||
export function deleteContract(id: number): Promise<void> {
|
||||
return request.delete(`/sl/contract/${id}`)
|
||||
}
|
||||
111
erp-frontend-vue/src/api/customer.ts
Normal file
111
erp-frontend-vue/src/api/customer.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import request from './request'
|
||||
|
||||
/** 客户档案 - 与 ERP 数据模型 SlClient 对齐 */
|
||||
export interface Customer {
|
||||
clientId?: number
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
clientNick?: string
|
||||
/** 兼容表单选择:id = clientId */
|
||||
id?: number
|
||||
/** 兼容表单选择:code = clientCode */
|
||||
code?: string
|
||||
/** 兼容表单选择:name = clientName */
|
||||
name?: string
|
||||
/** 兼容表单选择:contact = contact1 */
|
||||
contact?: string
|
||||
/** 兼容表单选择:phone = contact1Tel */
|
||||
phone?: string
|
||||
clientEn?: string
|
||||
clientDes?: string
|
||||
clientLogo?: string
|
||||
clientType?: string
|
||||
clientLevel?: string
|
||||
clientSource?: string
|
||||
clientIndustry?: string
|
||||
address?: string
|
||||
website?: string
|
||||
email?: string
|
||||
tel?: string
|
||||
contact1?: string
|
||||
contact1Tel?: string
|
||||
contact2?: string
|
||||
contact2Tel?: string
|
||||
creditCode?: string
|
||||
bankName?: string
|
||||
bankAccount?: string
|
||||
taxNo?: string
|
||||
invoiceAddress?: string
|
||||
enableFlag?: 'Y' | 'N'
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
export interface CustomerQuery {
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
clientNick?: string
|
||||
/** 兼容:映射为 clientName */
|
||||
name?: string
|
||||
enableFlag?: 'Y' | 'N'
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface CustomerListResponse {
|
||||
list: Customer[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/erp/sl/client'
|
||||
|
||||
function mapRow(r: any): Customer {
|
||||
return {
|
||||
...r,
|
||||
id: r.clientId ?? r.id,
|
||||
code: r.clientCode ?? r.code,
|
||||
name: r.clientName ?? r.name,
|
||||
contact: r.contact1 ?? r.contact,
|
||||
phone: r.contact1Tel ?? r.phone
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取客户列表(分页) */
|
||||
export function getCustomerList(params: CustomerQuery): Promise<CustomerListResponse> {
|
||||
const { name, ...rest } = params
|
||||
const req = { ...rest, clientName: rest.clientName ?? name } as Record<string, unknown>
|
||||
return request.get(`${BASE}/list`, { params: req }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? res.list ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { list: rows.map(mapRow), total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取客户详情 */
|
||||
export function getCustomerDetail(clientId: number): Promise<Customer> {
|
||||
return request.get(`${BASE}/${clientId}`).then((res: any) => mapRow(res.data ?? res))
|
||||
}
|
||||
|
||||
/** 新增客户 */
|
||||
export function createCustomer(data: Partial<Customer>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 更新客户 */
|
||||
export function updateCustomer(data: Partial<Customer>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除客户(支持单个或批量,逗号分隔 ID) */
|
||||
export function deleteCustomer(clientIds: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(clientIds) ? clientIds.join(',') : String(clientIds)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 更新客户启用状态 */
|
||||
export function updateCustomerStatus(clientId: number, enableFlag: 'Y' | 'N'): Promise<void> {
|
||||
return request.put(BASE, { clientId, enableFlag })
|
||||
}
|
||||
108
erp-frontend-vue/src/api/deliver.ts
Normal file
108
erp-frontend-vue/src/api/deliver.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import request from './request'
|
||||
|
||||
export interface DeliverLine {
|
||||
lineId?: number
|
||||
id?: number
|
||||
deliverId?: number
|
||||
deliverCode?: string
|
||||
orderLineId?: number
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
materialCode?: string
|
||||
itemName?: string
|
||||
materialName?: string
|
||||
specification?: string
|
||||
spec?: string
|
||||
unitOfMeasure?: string
|
||||
unit?: string
|
||||
orderQty?: number
|
||||
deliverQty: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface Deliver {
|
||||
deliverId?: number
|
||||
id?: number
|
||||
deliverCode?: string
|
||||
code?: string
|
||||
clientId?: number
|
||||
customerId?: number
|
||||
clientCode?: string
|
||||
customerCode?: string
|
||||
clientName?: string
|
||||
customerName?: string
|
||||
deliverDate: string
|
||||
status: string
|
||||
totalQty?: number
|
||||
deliveryAddress?: string
|
||||
contact?: string
|
||||
phone?: string
|
||||
remark?: string
|
||||
lines?: DeliverLine[]
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface DeliverQuery {
|
||||
code?: string
|
||||
customerName?: string
|
||||
status?: string
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface DeliverListResponse {
|
||||
list: Deliver[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取发货单列表
|
||||
export function getDeliverList(params: DeliverQuery): Promise<DeliverListResponse> {
|
||||
return request.get('/erp/sl/deliver/list', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取发货单详情
|
||||
export function getDeliverDetail(id: number): Promise<Deliver> {
|
||||
return request.get(`/erp/sl/deliver/${id}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增发货单
|
||||
export function createDeliver(data: Partial<Deliver>): Promise<void> {
|
||||
return request.post('/erp/sl/deliver', data)
|
||||
}
|
||||
|
||||
// 更新发货单
|
||||
export function updateDeliver(id: number, data: Partial<Deliver>): Promise<void> {
|
||||
return request.put('/erp/sl/deliver', { ...data, deliverId: id })
|
||||
}
|
||||
|
||||
// 删除发货单
|
||||
export function deleteDeliver(id: number): Promise<void> {
|
||||
return request.delete(`/erp/sl/deliver/${id}`)
|
||||
}
|
||||
|
||||
// 审核发货单
|
||||
export function auditDeliver(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/deliver/audit/${id}`)
|
||||
}
|
||||
|
||||
// 反审核发货单
|
||||
export function unauditDeliver(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/deliver/unaudit/${id}`)
|
||||
}
|
||||
|
||||
// 引入销售订单
|
||||
export function getIntroduceOrderList(params: any): Promise<DeliverListResponse> {
|
||||
return request.get('/erp/sl/deliver/introduce', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
77
erp-frontend-vue/src/api/invoice.ts
Normal file
77
erp-frontend-vue/src/api/invoice.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import request from './request'
|
||||
|
||||
export interface Invoice {
|
||||
invoiceId?: number
|
||||
id?: number
|
||||
invoiceCode?: string
|
||||
code?: string
|
||||
clientId?: number
|
||||
customerId?: number
|
||||
clientCode?: string
|
||||
customerCode?: string
|
||||
clientName?: string
|
||||
customerName?: string
|
||||
invoiceDate: string
|
||||
invoiceType?: string
|
||||
status: string
|
||||
totalAmount?: number
|
||||
taxAmount?: number
|
||||
invoiceNo?: string
|
||||
remark?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface InvoiceQuery {
|
||||
code?: string
|
||||
customerName?: string
|
||||
status?: string
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface InvoiceListResponse {
|
||||
list: Invoice[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取销售发票列表
|
||||
export function getInvoiceList(params: InvoiceQuery): Promise<InvoiceListResponse> {
|
||||
return request.get('/erp/sl/invoice/list', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取销售发票详情
|
||||
export function getInvoiceDetail(id: number): Promise<Invoice> {
|
||||
return request.get(`/erp/sl/invoice/${id}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增销售发票
|
||||
export function createInvoice(data: Partial<Invoice>): Promise<void> {
|
||||
return request.post('/erp/sl/invoice', data)
|
||||
}
|
||||
|
||||
// 更新销售发票
|
||||
export function updateInvoice(id: number, data: Partial<Invoice>): Promise<void> {
|
||||
return request.put('/erp/sl/invoice', { ...data, invoiceId: id })
|
||||
}
|
||||
|
||||
// 删除销售发票
|
||||
export function deleteInvoice(id: number): Promise<void> {
|
||||
return request.delete(`/erp/sl/invoice/${id}`)
|
||||
}
|
||||
|
||||
// 审核销售发票
|
||||
export function auditInvoice(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/invoice/audit/${id}`)
|
||||
}
|
||||
|
||||
// 反审核销售发票
|
||||
export function unauditInvoice(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/invoice/unaudit/${id}`)
|
||||
}
|
||||
201
erp-frontend-vue/src/api/masterdata/bom.ts
Normal file
201
erp-frontend-vue/src/api/masterdata/bom.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import request from '../request'
|
||||
|
||||
/** BOM 表头(md_bom) */
|
||||
export interface BomHeader {
|
||||
bomId?: number
|
||||
bomCode?: string
|
||||
bomName?: string
|
||||
version?: string
|
||||
versionDesc?: string
|
||||
status?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemSpec?: string
|
||||
unitName?: string
|
||||
baseQty?: number
|
||||
enableFlag?: string
|
||||
bomItemId?: number
|
||||
bomItemCode?: string
|
||||
bomItemName?: string
|
||||
bomItemSpec?: string
|
||||
unitOfMeasure?: string
|
||||
itemOrProduct?: string
|
||||
quantity?: number
|
||||
lineNo?: number
|
||||
lossRate?: number
|
||||
supplyType?: string
|
||||
tenantId?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
/** BOM 明细(md_product_bom) */
|
||||
export interface BomLine {
|
||||
bomId?: number // 明细行ID(现有表主键)
|
||||
bomCode?: string
|
||||
bomName?: string
|
||||
version?: string
|
||||
versionDesc?: string
|
||||
status?: string
|
||||
itemId?: number // 母件物料ID
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemSpec?: string
|
||||
bomItemId?: number
|
||||
bomItemCode?: string
|
||||
bomItemName?: string
|
||||
bomItemSpec?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
itemOrProduct?: string
|
||||
quantity?: number
|
||||
baseQty?: number
|
||||
lineNo?: number
|
||||
lossRate?: number
|
||||
supplyType?: string
|
||||
enableFlag?: string
|
||||
tenantId?: string
|
||||
delFlag?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
/** 扩展字段(后端可忽略/不落库,页面需要透传) */
|
||||
attr1?: string
|
||||
attr2?: string
|
||||
// 详情页表格里用到的前端临时字段(后端可忽略)
|
||||
planRoute?: string
|
||||
usageType?: string
|
||||
drawingNo?: string
|
||||
}
|
||||
|
||||
/** BOM 表头查询参数 */
|
||||
export interface BomHeaderQuery {
|
||||
bomCode?: string
|
||||
bomName?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemOrProduct?: string
|
||||
itemTypeId?: number
|
||||
status?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** BOM 表头列表响应 */
|
||||
export interface BomHeaderListResponse {
|
||||
rows: BomHeader[]
|
||||
total: number
|
||||
}
|
||||
|
||||
/** BOM 明细查询参数 */
|
||||
export interface BomLineQuery {
|
||||
bomCode?: string
|
||||
itemId?: number
|
||||
bomItemCode?: string
|
||||
bomItemName?: string
|
||||
status?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** BOM 明细列表响应 */
|
||||
export interface BomLineListResponse {
|
||||
rows: BomLine[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BOM_HEADER_BASE = '/mes/md/bom'
|
||||
const BOM_LINE_BASE = '/mes/md/bom/line'
|
||||
|
||||
/** 查询BOM表头列表 */
|
||||
export function listBomHeader(query?: BomHeaderQuery): Promise<BomHeaderListResponse> {
|
||||
return request.get(`${BOM_HEADER_BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询BOM表头详情 */
|
||||
export function getBomHeader(bomId: number): Promise<{ data: BomHeader }> {
|
||||
return request.get(`${BOM_HEADER_BASE}/${bomId}`)
|
||||
}
|
||||
|
||||
/** 新增BOM表头 */
|
||||
export function addBomHeader(data: Partial<BomHeader>): Promise<{ data: BomHeader }> {
|
||||
return request.post(BOM_HEADER_BASE, data)
|
||||
}
|
||||
|
||||
/** 修改BOM表头 */
|
||||
export function updateBomHeader(data: Partial<BomHeader>): Promise<{ data: BomHeader }> {
|
||||
return request.put(BOM_HEADER_BASE, data)
|
||||
}
|
||||
|
||||
/** 删除BOM表头 */
|
||||
export function delBomHeader(bomId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(bomId) ? bomId.join(',') : String(bomId)
|
||||
return request.delete(`${BOM_HEADER_BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 查询BOM明细列表 */
|
||||
export function listBomLine(query?: BomLineQuery): Promise<BomLineListResponse> {
|
||||
return request.get(`${BOM_LINE_BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询BOM明细详情 */
|
||||
export function getBomLine(lineId: number): Promise<{ data: BomLine }> {
|
||||
return request.get(`${BOM_LINE_BASE}/${lineId}`)
|
||||
}
|
||||
|
||||
/** 新增BOM明细 */
|
||||
export function addBomLine(data: Partial<BomLine>): Promise<{ data: BomLine }> {
|
||||
return request.post(BOM_LINE_BASE, data)
|
||||
}
|
||||
|
||||
/** 修改BOM明细 */
|
||||
export function updateBomLine(data: Partial<BomLine>): Promise<{ data: BomLine }> {
|
||||
return request.put(BOM_LINE_BASE, data)
|
||||
}
|
||||
|
||||
/** 删除BOM明细 */
|
||||
export function delBomLine(lineId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(lineId) ? lineId.join(',') : String(lineId)
|
||||
return request.delete(`${BOM_LINE_BASE}/${ids}`)
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 兼容旧命名(当前BOM页面仍在使用)
|
||||
// -----------------------------
|
||||
export type ProductBom = BomHeader
|
||||
export type ProductBomQuery = BomHeaderQuery
|
||||
export type ProductBomListResponse = BomHeaderListResponse
|
||||
export const listProductBom = listBomHeader
|
||||
export const getProductBom = getBomHeader
|
||||
export const addProductBom = addBomHeader
|
||||
export const updateProductBom = updateBomHeader
|
||||
export const delProductBom = delBomHeader
|
||||
|
||||
/** BOM状态选项 */
|
||||
export const bomStatusOptions = [
|
||||
{ value: 'DRAFT', label: '草稿' },
|
||||
{ value: 'APPROVED', label: '已审核' },
|
||||
{ value: 'OBSOLETE', label: '已废弃' }
|
||||
]
|
||||
|
||||
/** 供应方式选项 */
|
||||
export const supplyTypeOptions = [
|
||||
{ value: 'PURCHASE', label: '采购' },
|
||||
{ value: 'PRODUCE', label: '自制' },
|
||||
{ value: 'OUTSOURCE', label: '委外' }
|
||||
]
|
||||
70
erp-frontend-vue/src/api/masterdata/item.ts
Normal file
70
erp-frontend-vue/src/api/masterdata/item.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface MdItem {
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
itemTypeId?: number
|
||||
itemTypeName?: string
|
||||
itemOrProduct?: string
|
||||
enableFlag?: string
|
||||
safeStockFlag?: string
|
||||
minStock?: number
|
||||
maxStock?: number
|
||||
batchFlag?: string
|
||||
highValue?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
export interface MdItemQuery {
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemTypeId?: number
|
||||
itemOrProduct?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface MdItemListResponse {
|
||||
rows: MdItem[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/mes/md/mditem'
|
||||
|
||||
/** 查询物料列表 */
|
||||
export function listMdItem(query?: MdItemQuery): Promise<MdItemListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询物料详细 */
|
||||
export function getMdItem(itemId: number): Promise<{ data: MdItem }> {
|
||||
return request.get(`${BASE}/${itemId}`)
|
||||
}
|
||||
|
||||
/** 新增物料 */
|
||||
export function addMdItem(data: Partial<MdItem>): Promise<{ data: MdItem }> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改物料 */
|
||||
export function updateMdItem(data: Partial<MdItem>): Promise<{ data: MdItem }> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除物料 */
|
||||
export function delMdItem(itemId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(itemId) ? itemId.join(',') : String(itemId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
79
erp-frontend-vue/src/api/masterdata/itemtype.ts
Normal file
79
erp-frontend-vue/src/api/masterdata/itemtype.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface ItemType {
|
||||
itemTypeId?: number
|
||||
parentTypeId?: number
|
||||
itemTypeCode?: string
|
||||
itemTypeName?: string
|
||||
orderNum?: number
|
||||
enableFlag?: string
|
||||
itemOrProduct?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
children?: ItemType[]
|
||||
}
|
||||
|
||||
export interface ItemTypeQuery {
|
||||
itemTypeCode?: string
|
||||
itemTypeName?: string
|
||||
enableFlag?: string
|
||||
}
|
||||
|
||||
const BASE = '/mes/md/itemtype'
|
||||
|
||||
/** 查询物料分类列表 */
|
||||
export function listItemType(query?: ItemTypeQuery): Promise<{ data: ItemType[] }> {
|
||||
return request.get(`${BASE}/list`, { params: query })
|
||||
}
|
||||
|
||||
/** 查询物料分类下拉树结构 */
|
||||
export function getItemTypeTreeselect(): Promise<{ data: any[] }> {
|
||||
return request.get(`${BASE}/treeselect`)
|
||||
}
|
||||
|
||||
/** 查询物料分类详细 */
|
||||
export function getItemType(itemTypeId: number): Promise<{ data: ItemType }> {
|
||||
return request.get(`${BASE}/${itemTypeId}`)
|
||||
}
|
||||
|
||||
/** 新增物料分类 */
|
||||
export function addItemType(data: Partial<ItemType>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改物料分类 */
|
||||
export function updateItemType(data: Partial<ItemType>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除物料分类 */
|
||||
export function delItemType(itemTypeId: number): Promise<void> {
|
||||
return request.delete(`${BASE}/${itemTypeId}`)
|
||||
}
|
||||
|
||||
/** 构建分类树 */
|
||||
export function handleTree(data: ItemType[], idField = 'itemTypeId', parentField = 'parentTypeId'): ItemType[] {
|
||||
const map = new Map<number, ItemType>()
|
||||
const result: ItemType[] = []
|
||||
|
||||
data.forEach(item => {
|
||||
map.set(item[idField as keyof ItemType] as number, { ...item, children: [] })
|
||||
})
|
||||
|
||||
data.forEach(item => {
|
||||
const current = map.get(item[idField as keyof ItemType] as number)!
|
||||
const parentId = item[parentField as keyof ItemType] as number
|
||||
if (parentId && map.has(parentId)) {
|
||||
const parent = map.get(parentId)!
|
||||
parent.children = parent.children || []
|
||||
parent.children.push(current)
|
||||
} else {
|
||||
result.push(current)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
65
erp-frontend-vue/src/api/masterdata/unit.ts
Normal file
65
erp-frontend-vue/src/api/masterdata/unit.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface UnitMeasure {
|
||||
measureId?: number
|
||||
measureCode?: string
|
||||
measureName?: string
|
||||
primaryFlag?: string
|
||||
primaryId?: number
|
||||
changeRate?: number
|
||||
enableFlag?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
export interface UnitMeasureQuery {
|
||||
measureCode?: string
|
||||
measureName?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface UnitMeasureListResponse {
|
||||
rows: UnitMeasure[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/mes/md/unitmeasure'
|
||||
|
||||
/** 查询计量单位列表 */
|
||||
export function listUnitMeasure(query?: UnitMeasureQuery): Promise<UnitMeasureListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询所有计量单位(不分页) */
|
||||
export function listAllUnitMeasure(): Promise<{ data: UnitMeasure[] }> {
|
||||
return request.get(`${BASE}/selectall`)
|
||||
}
|
||||
|
||||
/** 查询计量单位详细 */
|
||||
export function getUnitMeasure(measureId: number): Promise<{ data: UnitMeasure }> {
|
||||
return request.get(`${BASE}/${measureId}`)
|
||||
}
|
||||
|
||||
/** 新增计量单位 */
|
||||
export function addUnitMeasure(data: Partial<UnitMeasure>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改计量单位 */
|
||||
export function updateUnitMeasure(data: Partial<UnitMeasure>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除计量单位 */
|
||||
export function delUnitMeasure(measureId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(measureId) ? measureId.join(',') : String(measureId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
64
erp-frontend-vue/src/api/masterdata/workshop.ts
Normal file
64
erp-frontend-vue/src/api/masterdata/workshop.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface Workshop {
|
||||
workshopId?: number
|
||||
workshopCode?: string
|
||||
workshopName?: string
|
||||
area?: string
|
||||
charge?: string
|
||||
enableFlag?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
export interface WorkshopQuery {
|
||||
workshopCode?: string
|
||||
workshopName?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface WorkshopListResponse {
|
||||
rows: Workshop[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/mes/md/workshop'
|
||||
|
||||
/** 查询车间列表 */
|
||||
export function listWorkshop(query?: WorkshopQuery): Promise<WorkshopListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询所有车间(不分页) */
|
||||
export function listAllWorkshop(): Promise<{ data: Workshop[] }> {
|
||||
return request.get(`${BASE}/listAll`)
|
||||
}
|
||||
|
||||
/** 查询车间详细 */
|
||||
export function getWorkshop(workshopId: number): Promise<{ data: Workshop }> {
|
||||
return request.get(`${BASE}/${workshopId}`)
|
||||
}
|
||||
|
||||
/** 新增车间 */
|
||||
export function addWorkshop(data: Partial<Workshop>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改车间 */
|
||||
export function updateWorkshop(data: Partial<Workshop>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除车间 */
|
||||
export function delWorkshop(workshopId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(workshopId) ? workshopId.join(',') : String(workshopId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
68
erp-frontend-vue/src/api/masterdata/workstation.ts
Normal file
68
erp-frontend-vue/src/api/masterdata/workstation.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface Workstation {
|
||||
workstationId?: number
|
||||
workstationCode?: string
|
||||
workstationName?: string
|
||||
workstationAddress?: string
|
||||
workshopId?: number
|
||||
workshopName?: string
|
||||
processId?: number
|
||||
processName?: string
|
||||
enableFlag?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
export interface WorkstationQuery {
|
||||
workstationCode?: string
|
||||
workstationName?: string
|
||||
workshopId?: number
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface WorkstationListResponse {
|
||||
rows: Workstation[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/mes/md/workstation'
|
||||
|
||||
/** 查询工作站列表 */
|
||||
export function listWorkstation(query?: WorkstationQuery): Promise<WorkstationListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询所有工作站(不分页) */
|
||||
export function listAllWorkstation(): Promise<{ data: Workstation[] }> {
|
||||
return request.get(`${BASE}/listAll`)
|
||||
}
|
||||
|
||||
/** 查询工作站详细 */
|
||||
export function getWorkstation(workstationId: number): Promise<{ data: Workstation }> {
|
||||
return request.get(`${BASE}/${workstationId}`)
|
||||
}
|
||||
|
||||
/** 新增工作站 */
|
||||
export function addWorkstation(data: Partial<Workstation>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改工作站 */
|
||||
export function updateWorkstation(data: Partial<Workstation>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除工作站 */
|
||||
export function delWorkstation(workstationId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(workstationId) ? workstationId.join(',') : String(workstationId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
78
erp-frontend-vue/src/api/material.ts
Normal file
78
erp-frontend-vue/src/api/material.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { listMdItem, getMdItem, type MdItem } from './masterdata/item'
|
||||
|
||||
export interface Material {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
spec?: string
|
||||
unit: string
|
||||
category?: string
|
||||
price?: number
|
||||
status: number
|
||||
}
|
||||
|
||||
export interface MaterialQuery {
|
||||
code?: string
|
||||
name?: string
|
||||
category?: string
|
||||
itemOrProduct?: string
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface MaterialListResponse {
|
||||
list: Material[]
|
||||
total: number
|
||||
}
|
||||
|
||||
/** 将后端MdItem转换为前端Material */
|
||||
function convertMdItemToMaterial(item: MdItem): Material {
|
||||
return {
|
||||
id: item.itemId || 0,
|
||||
code: item.itemCode || '',
|
||||
name: item.itemName || '',
|
||||
spec: item.specification,
|
||||
unit: item.unitOfMeasure || item.unitName || '',
|
||||
category: item.itemTypeName,
|
||||
price: 0, // 物料主数据中没有价格,价格在订单中设置
|
||||
status: item.enableFlag === 'Y' ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取物料列表 */
|
||||
export async function getMaterialList(params: MaterialQuery): Promise<MaterialListResponse> {
|
||||
try {
|
||||
const query: any = {
|
||||
itemCode: params.code,
|
||||
itemName: params.name,
|
||||
pageNum: params.page || 1,
|
||||
pageSize: params.pageSize || 100
|
||||
}
|
||||
if (params.itemOrProduct) {
|
||||
query.itemOrProduct = params.itemOrProduct
|
||||
}
|
||||
|
||||
const res = await listMdItem(query)
|
||||
// 返回所有物料,让用户自行选择
|
||||
const list = res.rows.map(convertMdItemToMaterial)
|
||||
|
||||
return {
|
||||
list,
|
||||
total: res.total
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取物料列表失败:', error)
|
||||
return { list: [], total: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取物料详情 */
|
||||
export async function getMaterialDetail(id: number): Promise<Material> {
|
||||
try {
|
||||
const res = await getMdItem(id)
|
||||
return convertMdItemToMaterial(res.data)
|
||||
} catch (error) {
|
||||
console.error('获取物料详情失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
142
erp-frontend-vue/src/api/mbom.ts
Normal file
142
erp-frontend-vue/src/api/mbom.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import request from './request'
|
||||
|
||||
export interface Mbom {
|
||||
mbomId: number
|
||||
mbomCode: string
|
||||
mbomDate: string
|
||||
status: string
|
||||
businessType: string
|
||||
issueStatus?: string
|
||||
planId: number
|
||||
planCode: string
|
||||
salesOrderId?: number
|
||||
salesOrderCode?: string
|
||||
deliveryDate?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
unitName?: string
|
||||
supplyType?: string
|
||||
quantity: number
|
||||
workshopId?: number
|
||||
workshopName?: string
|
||||
issueDate?: string
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
remark?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
/** 物料清单明细行 */
|
||||
export interface MbomLine {
|
||||
lineId: number
|
||||
mbomId: number
|
||||
mbomCode?: string
|
||||
lineNo?: number
|
||||
bomLevel?: number
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
baseQty?: number
|
||||
quantity: number
|
||||
lossRate?: number
|
||||
supplyType?: string
|
||||
pickType?: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
/** 物料清单详情(表头 + 明细行) */
|
||||
export interface MbomDetail extends Mbom {
|
||||
lines?: MbomLine[]
|
||||
}
|
||||
|
||||
export interface MbomQuery {
|
||||
salesOrderCode?: string
|
||||
mbomCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
supplyType?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface MbomListResponse {
|
||||
rows: Mbom[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取物料清单列表
|
||||
export function getMbomList(params: MbomQuery): Promise<MbomListResponse> {
|
||||
return request.get('/erp/mp/mbom/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取物料清单详情(含明细行)
|
||||
export function getMbomDetail(mbomId: number): Promise<MbomDetail> {
|
||||
return request.get(`/erp/mp/mbom/${mbomId}`).then((res: any) => {
|
||||
const data = res.data ?? res
|
||||
return data as MbomDetail
|
||||
})
|
||||
}
|
||||
|
||||
// 获取物料清单明细列表
|
||||
export function getMbomLines(mbomId: number): Promise<MbomLine[]> {
|
||||
return request.get(`/erp/mp/mbomline/mbom/${mbomId}`).then((res: any) => {
|
||||
const rows = res.rows ?? res.data ?? []
|
||||
return rows as MbomLine[]
|
||||
})
|
||||
}
|
||||
|
||||
// 更新物料清单明细行
|
||||
export function updateMbomLine(data: Partial<MbomLine>): Promise<void> {
|
||||
return request.put('/erp/mp/mbomline', data)
|
||||
}
|
||||
|
||||
// 新增物料清单
|
||||
export function createMbom(data: Partial<Mbom>): Promise<void> {
|
||||
return request.post('/erp/mp/mbom', data)
|
||||
}
|
||||
|
||||
// 更新物料清单
|
||||
export function updateMbom(data: Partial<Mbom>): Promise<void> {
|
||||
return request.put('/erp/mp/mbom', data)
|
||||
}
|
||||
|
||||
// 删除物料清单
|
||||
export function deleteMbom(mbomIds: string): Promise<void> {
|
||||
return request.delete(`/erp/mp/mbom/${mbomIds}`)
|
||||
}
|
||||
|
||||
// 审核物料清单
|
||||
export function approveMbom(mbomId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/mbom/approve/${mbomId}`)
|
||||
}
|
||||
|
||||
// 反审核物料清单
|
||||
export function unapproveMbom(mbomId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/mbom/unapprove/${mbomId}`)
|
||||
}
|
||||
|
||||
// 下发车间
|
||||
export function issueToWorkshop(mbomId: number, workshopId: number, workshopName: string): Promise<void> {
|
||||
return request.put(`/erp/mp/mbom/issue/${mbomId}/${workshopId}/${workshopName}`)
|
||||
}
|
||||
|
||||
// 撤销下发车间
|
||||
export function revokeIssue(mbomId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/mbom/revoke-issue/${mbomId}`)
|
||||
}
|
||||
|
||||
// BOM运算(从生产计划)
|
||||
export function calcBom(planId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/plan/bom-calculate/${planId}`)
|
||||
}
|
||||
72
erp-frontend-vue/src/api/parts.ts
Normal file
72
erp-frontend-vue/src/api/parts.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import request from './request'
|
||||
|
||||
export interface PartsOrder {
|
||||
partsId: number
|
||||
partsCode: string
|
||||
partsDate: string
|
||||
status: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
drawingNo?: string
|
||||
unitName?: string
|
||||
quantity: number
|
||||
planQty?: number
|
||||
completedQty?: number
|
||||
remark?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface PartsQuery {
|
||||
partsCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface PartsListResponse {
|
||||
rows: PartsOrder[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取零部件订单列表
|
||||
export function getPartsOrderList(params: PartsQuery): Promise<PartsListResponse> {
|
||||
return request.get('/erp/mp/parts/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取零部件订单详情
|
||||
export function getPartsOrderDetail(partsId: number): Promise<PartsOrder> {
|
||||
return request.get(`/erp/mp/parts/${partsId}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增零部件订单
|
||||
export function createPartsOrder(data: Partial<PartsOrder>): Promise<void> {
|
||||
return request.post('/erp/mp/parts', data)
|
||||
}
|
||||
|
||||
// 更新零部件订单
|
||||
export function updatePartsOrder(data: Partial<PartsOrder>): Promise<void> {
|
||||
return request.put('/erp/mp/parts', data)
|
||||
}
|
||||
|
||||
// 删除零部件订单
|
||||
export function deletePartsOrder(partsIds: string): Promise<void> {
|
||||
return request.delete(`/erp/mp/parts/${partsIds}`)
|
||||
}
|
||||
|
||||
// 审核零部件订单
|
||||
export function approvePartsOrder(partsId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/parts/approve/${partsId}`)
|
||||
}
|
||||
357
erp-frontend-vue/src/api/productionPlan.ts
Normal file
357
erp-frontend-vue/src/api/productionPlan.ts
Normal file
@@ -0,0 +1,357 @@
|
||||
import request from './request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 生产计划明细行 */
|
||||
export interface PlanLine {
|
||||
lineId?: number
|
||||
planId?: number
|
||||
planCode?: string
|
||||
lineNo?: number
|
||||
salesLineId?: number
|
||||
trackCode?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitId?: number
|
||||
unitName?: string
|
||||
quantity?: number
|
||||
qualityReq?: string
|
||||
remark?: string
|
||||
delFlag?: string
|
||||
}
|
||||
|
||||
/** 生产计划单主表 */
|
||||
export interface ProductionPlan {
|
||||
planId?: number
|
||||
planCode?: string
|
||||
planDate?: string
|
||||
status?: string
|
||||
businessStatus?: string
|
||||
businessType?: string
|
||||
workType?: number
|
||||
salesOrderId?: number
|
||||
salesOrderCode?: string
|
||||
salesUserId?: number
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
bomId?: number
|
||||
/** EBOM单号(选择BOM后显示在表头订单BOM) */
|
||||
bomCode?: string
|
||||
bomVersion?: string
|
||||
bomDesc?: string
|
||||
totalQuantity?: number
|
||||
remark?: string
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
approverId?: number
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
lines?: PlanLine[]
|
||||
slaveList?: PlanLine[]
|
||||
/** 部门名称(单据视图) */
|
||||
deptName?: string
|
||||
/** 操作员/业务人员(单据视图表头) */
|
||||
operatorName?: string
|
||||
/** 审核日期 */
|
||||
approveDate?: string
|
||||
/** 物料清单(BOM运算结果,详情页只读) */
|
||||
mbomList?: MbomLine[]
|
||||
/** 补料清单(详情页只读) */
|
||||
supplementList?: SupplementLine[]
|
||||
}
|
||||
|
||||
/** 明细视图数据(展开物料维度) */
|
||||
export interface PlanDetailView {
|
||||
lineId: number
|
||||
planId: number
|
||||
planCode: string
|
||||
planDate: string
|
||||
status: string
|
||||
workType: number
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
trackCode?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
quantity: number
|
||||
/** 物料清单状态:BOM运算 / BOM运算,BOM补料 / 空 */
|
||||
mbomStatus?: string
|
||||
}
|
||||
|
||||
/** 物料清单行(BOM运算结果) */
|
||||
export interface MbomLine {
|
||||
mbomId?: number
|
||||
mbomCode?: string
|
||||
mbomStatus?: string
|
||||
businessType?: string
|
||||
issueStatus?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
unitName?: string
|
||||
supplyType?: string
|
||||
productionQty?: number
|
||||
workshopId?: number
|
||||
workshopName?: string
|
||||
issueDate?: string
|
||||
}
|
||||
|
||||
/** 补料清单行 */
|
||||
export interface SupplementLine {
|
||||
supCode?: string
|
||||
supStatus?: string
|
||||
businessType?: string
|
||||
issueStatus?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
unitName?: string
|
||||
supplyType?: string
|
||||
productionQty?: number
|
||||
supReason?: string
|
||||
supDate?: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface PlanQuery {
|
||||
salesOrderCode?: string
|
||||
planCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
workType?: number
|
||||
status?: string
|
||||
businessStatus?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 分页响应 */
|
||||
export interface PlanListResponse {
|
||||
rows: ProductionPlan[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface PlanDetailListResponse {
|
||||
rows: PlanDetailView[]
|
||||
total: number
|
||||
}
|
||||
|
||||
/** 引入订单数据类型 */
|
||||
export interface ImportOrder {
|
||||
orderId: number
|
||||
orderCode: string
|
||||
orderDate: string
|
||||
userId?: number
|
||||
userName?: string
|
||||
salesmanName?: string
|
||||
clientName?: string
|
||||
deliveryDate?: string
|
||||
deliveryStatus?: string
|
||||
businessType?: string
|
||||
remark?: string
|
||||
lines?: ImportOrderLine[]
|
||||
}
|
||||
|
||||
/** 引入订单明细 */
|
||||
export interface ImportOrderLine {
|
||||
lineId: number
|
||||
orderId: number
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitOfMeasure?: string
|
||||
quantity: number
|
||||
qualityReq?: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
// ============ 状态映射 ============
|
||||
|
||||
export const PLAN_STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
'PREPARE': { label: '开立', type: 'info' },
|
||||
'DRAFT': { label: '开立', type: 'info' },
|
||||
'开立': { label: '开立', type: 'info' },
|
||||
'APPROVED': { label: '审核', type: 'success' },
|
||||
'审核': { label: '审核', type: 'success' },
|
||||
'CLOSED': { label: '关闭', type: 'info' }
|
||||
}
|
||||
|
||||
export const BUSINESS_STATUS_OPTIONS = [
|
||||
{ value: 'NORMAL', label: '正常' },
|
||||
{ value: 'PAUSE', label: '暂停' },
|
||||
{ value: 'CANCEL', label: '取消' }
|
||||
]
|
||||
|
||||
export const WORK_TYPE_OPTIONS = [
|
||||
{ value: 0, label: '生产计划单' },
|
||||
{ value: 1, label: '零部件计划单' },
|
||||
{ value: 2, label: '零部件订单' }
|
||||
]
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/erp/mp/plan'
|
||||
|
||||
/** 获取生产计划单列表(单据视图) */
|
||||
export function getProductionPlanList(params: PlanQuery): Promise<PlanListResponse> {
|
||||
return request.get(`${BASE}/list`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取生产计划单明细列表(明细视图,展开物料维度) */
|
||||
export function getProductionPlanDetailList(params: PlanQuery): Promise<PlanDetailListResponse> {
|
||||
return request.get(`${BASE}/lineList`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取生产计划单详情(含明细行) */
|
||||
export function getProductionPlanDetail(planId: number): Promise<ProductionPlan> {
|
||||
return request.get(`${BASE}/${planId}`).then((res: any) => {
|
||||
const data = res.data ?? res
|
||||
// 统一明细字段名
|
||||
if (data.slaveList && !data.lines) {
|
||||
data.lines = data.slaveList
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
/** 新增生产计划单 */
|
||||
export function createProductionPlan(data: Partial<ProductionPlan>): Promise<{ planId: number }> {
|
||||
const payload = { ...data }
|
||||
if (payload.lines) {
|
||||
payload.slaveList = payload.lines
|
||||
delete payload.lines
|
||||
}
|
||||
return request.post(BASE, payload).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 更新生产计划单 */
|
||||
export function updateProductionPlan(data: Partial<ProductionPlan>): Promise<void> {
|
||||
const payload = { ...data }
|
||||
if (payload.lines) {
|
||||
payload.slaveList = payload.lines
|
||||
delete payload.lines
|
||||
}
|
||||
return request.put(BASE, payload)
|
||||
}
|
||||
|
||||
/** 删除生产计划单(支持批量) */
|
||||
export function deleteProductionPlan(planIds: number | number[] | string): Promise<void> {
|
||||
const ids = Array.isArray(planIds) ? planIds.join(',') : String(planIds)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 审核生产计划单(支持批量) */
|
||||
export function approveProductionPlan(planIds: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(planIds) ? planIds.join(',') : String(planIds)
|
||||
return request.put(`${BASE}/approve/${ids}`)
|
||||
}
|
||||
|
||||
/** 反审核生产计划单(支持批量) */
|
||||
export function unapproveProductionPlan(planIds: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(planIds) ? planIds.join(',') : String(planIds)
|
||||
return request.put(`${BASE}/reject/${ids}`)
|
||||
}
|
||||
|
||||
/** 导出生产计划单 */
|
||||
export function exportProductionPlan(params: PlanQuery): Promise<Blob> {
|
||||
return request.get(`${BASE}/export`, {
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/** BOM运算 */
|
||||
export function bomCalculate(planId: number): Promise<void> {
|
||||
return request.post(`/erp/mp/mbom/calc`, { planId })
|
||||
}
|
||||
|
||||
// ============ 引入订单相关 ============
|
||||
|
||||
/** 获取可引入的销售订单列表(已审核的订单) */
|
||||
export function getImportOrderList(params?: {
|
||||
orderCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
}): Promise<ImportOrder[]> {
|
||||
return request.get('/erp/sl/order/list', {
|
||||
params: {
|
||||
...params,
|
||||
orderStatus: '审核',
|
||||
pageNum: 1,
|
||||
pageSize: 100
|
||||
}
|
||||
}).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
// 转换字段名
|
||||
return rows.map((row: any) => ({
|
||||
orderId: row.orderId,
|
||||
orderCode: row.orderCode,
|
||||
orderDate: row.orderDate,
|
||||
userId: row.salesmanId,
|
||||
userName: row.salesmanName,
|
||||
salesmanName: row.salesmanName,
|
||||
clientName: row.clientName,
|
||||
deliveryDate: row.deliveryDate,
|
||||
deliveryStatus: row.deliveryDate && new Date(row.deliveryDate) < new Date() ? '超期' : '预计',
|
||||
businessType: '销售订单',
|
||||
remark: row.remark
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取销售订单详情(用于引入订单明细) */
|
||||
export function getImportOrderDetail(orderId: number): Promise<ImportOrder> {
|
||||
return request.get(`/erp/sl/order/${orderId}`).then((res: any) => {
|
||||
const data = res.data ?? res
|
||||
const lines = data.lines ?? data.slaveList ?? []
|
||||
const salesPersonName = data.salesmanName ?? data.salesUserName ?? ''
|
||||
return {
|
||||
orderId: data.orderId,
|
||||
orderCode: data.orderCode,
|
||||
orderDate: data.orderDate,
|
||||
userId: data.salesmanId ?? data.salesUserId,
|
||||
userName: salesPersonName,
|
||||
salesmanName: salesPersonName,
|
||||
clientName: data.clientName,
|
||||
deliveryDate: data.deliveryDate,
|
||||
deliveryStatus: data.deliveryDate && new Date(data.deliveryDate) < new Date() ? '超期' : '预计',
|
||||
businessType: '销售订单',
|
||||
remark: data.remark,
|
||||
lines: lines.map((line: any) => ({
|
||||
lineId: line.lineId,
|
||||
orderId: line.orderId,
|
||||
itemId: line.itemId,
|
||||
itemCode: line.itemCode,
|
||||
itemName: line.itemName,
|
||||
specification: line.specification,
|
||||
unitOfMeasure: line.unitOfMeasure,
|
||||
quantity: line.quantity,
|
||||
qualityReq: line.qualityReq,
|
||||
remark: line.remark
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
70
erp-frontend-vue/src/api/purchaseInvoice.ts
Normal file
70
erp-frontend-vue/src/api/purchaseInvoice.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import request from './request'
|
||||
|
||||
export interface PurchaseInvoice {
|
||||
invoiceId: number
|
||||
invoiceCode: string
|
||||
invoiceDate: string
|
||||
status: string
|
||||
financeStatus: string
|
||||
businessType: string
|
||||
supplierId: number
|
||||
supplierName: string
|
||||
invoiceNo?: string
|
||||
invoiceAmount: number
|
||||
taxRate?: number
|
||||
taxAmount?: number
|
||||
totalAmount?: number
|
||||
remark?: string
|
||||
operatorName?: string
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface PurchaseInvoiceQuery {
|
||||
invoiceCode?: string
|
||||
supplierName?: string
|
||||
invoiceNo?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface PurchaseInvoiceListResponse {
|
||||
rows: PurchaseInvoice[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取采购发票列表
|
||||
export function getPurchaseInvoiceList(params: PurchaseInvoiceQuery): Promise<PurchaseInvoiceListResponse> {
|
||||
return request.get('/erp/po/invoice/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取采购发票详情
|
||||
export function getPurchaseInvoiceDetail(invoiceId: number): Promise<PurchaseInvoice> {
|
||||
return request.get(`/erp/po/invoice/${invoiceId}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增采购发票
|
||||
export function createPurchaseInvoice(data: Partial<PurchaseInvoice>): Promise<void> {
|
||||
return request.post('/erp/po/invoice', data)
|
||||
}
|
||||
|
||||
// 更新采购发票
|
||||
export function updatePurchaseInvoice(data: Partial<PurchaseInvoice>): Promise<void> {
|
||||
return request.put('/erp/po/invoice', data)
|
||||
}
|
||||
|
||||
// 删除采购发票
|
||||
export function deletePurchaseInvoice(invoiceIds: string): Promise<void> {
|
||||
return request.delete(`/erp/po/invoice/${invoiceIds}`)
|
||||
}
|
||||
60
erp-frontend-vue/src/api/purchaseNeed.ts
Normal file
60
erp-frontend-vue/src/api/purchaseNeed.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import request from './request'
|
||||
|
||||
export interface PurchaseNeedRow {
|
||||
purchaseId: number
|
||||
salesOrderCode: string
|
||||
planCode: string
|
||||
purchaseCode: string
|
||||
itemCode: string
|
||||
itemName: string
|
||||
demandQty: number
|
||||
availableQty: number
|
||||
purchaseQty: number
|
||||
orderedQty: number
|
||||
unorderedQty: number // = purchaseQty - orderedQty (backend returns in totalQuantity)
|
||||
purchaseDate: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface PurchaseNeedQuery {
|
||||
salesOrderCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
businessType?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface PurchaseNeedListResponse {
|
||||
rows: PurchaseNeedRow[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface PurchaseNeedSummary {
|
||||
totalPurchaseQty: number
|
||||
totalOrderedQty: number
|
||||
totalUnorderedQty: number
|
||||
}
|
||||
|
||||
// 查询采购计划需求列表
|
||||
export function getPurchaseNeedList(params: PurchaseNeedQuery): Promise<PurchaseNeedListResponse> {
|
||||
return request.get('/erp/mp/purchase/need/list', { params }).then((res: any) => {
|
||||
const rows = (res.rows || []).map((r: any) => ({
|
||||
...r,
|
||||
unorderedQty: r.totalQuantity // backend puts unordered qty in totalQuantity field
|
||||
}))
|
||||
return { rows, total: res.total || 0 }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询采购计划需求汇总
|
||||
export function getPurchaseNeedSummary(params: PurchaseNeedQuery): Promise<PurchaseNeedSummary> {
|
||||
return request.get('/erp/mp/purchase/need/summary', { params }).then((res: any) => res.data || {})
|
||||
}
|
||||
|
||||
// 导出采购计划需求表
|
||||
export function exportPurchaseNeed(params: PurchaseNeedQuery): Promise<Blob> {
|
||||
return request.post('/erp/mp/purchase/need/export', params, { responseType: 'blob' })
|
||||
}
|
||||
237
erp-frontend-vue/src/api/purchaseOrder.ts
Normal file
237
erp-frontend-vue/src/api/purchaseOrder.ts
Normal file
@@ -0,0 +1,237 @@
|
||||
import request from './request'
|
||||
|
||||
export interface PurchaseOrderLine {
|
||||
lineId: number
|
||||
orderId: number
|
||||
orderCode: string
|
||||
lineNo: number
|
||||
trackCode?: string
|
||||
planCode?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
needDate?: string
|
||||
quantity: number
|
||||
unitPrice?: number
|
||||
amount?: number
|
||||
arrivedQuantity?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface PurchaseOrder {
|
||||
orderId: number
|
||||
orderCode: string
|
||||
orderDate: string
|
||||
status: string
|
||||
businessStatus?: string
|
||||
businessType: string
|
||||
orderType: string
|
||||
materialNeed: string
|
||||
supplierId?: number
|
||||
supplierCode?: string
|
||||
supplierName?: string
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
userId?: number
|
||||
userName?: string
|
||||
deliveryDate?: string
|
||||
contractNo?: string
|
||||
contractFile?: string
|
||||
totalQuantity?: number
|
||||
totalAmount?: number
|
||||
arrivedQuantity?: number
|
||||
remark?: string
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
approverId?: number
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
lines: PurchaseOrderLine[]
|
||||
createTime?: string
|
||||
// Detail-view join fields
|
||||
trackCode?: string
|
||||
planCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
needDate?: string
|
||||
quantity?: number
|
||||
lineArrivedQuantity?: number
|
||||
}
|
||||
|
||||
/** 供应商(采购订单用,数据来源:md_vendor) */
|
||||
export interface PoSupplier {
|
||||
supplierId: number
|
||||
supplierCode?: string
|
||||
supplierName: string
|
||||
supplierNick?: string
|
||||
tel?: string
|
||||
contact1?: string
|
||||
contact1Tel?: string
|
||||
enableFlag?: string
|
||||
}
|
||||
|
||||
/** 引入弹窗行(采购计划明细) */
|
||||
export interface LeadInRow {
|
||||
purchaseId: number
|
||||
purchaseCode: string
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
demandDate?: string
|
||||
purchaseQty: number
|
||||
orderedQty: number
|
||||
unpurchasedQty?: number
|
||||
}
|
||||
|
||||
export interface PurchaseOrderQuery {
|
||||
trackCode?: string
|
||||
orderCode?: string
|
||||
supplierName?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface PurchaseOrderListResponse {
|
||||
rows: PurchaseOrder[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取采购订单列表
|
||||
export function getPurchaseOrderList(params: PurchaseOrderQuery): Promise<PurchaseOrderListResponse> {
|
||||
return request.get('/erp/po/order/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取采购订单详情
|
||||
export function getPurchaseOrderDetail(orderId: number): Promise<PurchaseOrder> {
|
||||
return request.get(`/erp/po/order/${orderId}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增采购订单
|
||||
export function createPurchaseOrder(data: Partial<PurchaseOrder>): Promise<void> {
|
||||
return request.post('/erp/po/order', data)
|
||||
}
|
||||
|
||||
// 更新采购订单
|
||||
export function updatePurchaseOrder(data: Partial<PurchaseOrder>): Promise<void> {
|
||||
return request.put('/erp/po/order', data)
|
||||
}
|
||||
|
||||
// 删除采购订单
|
||||
export function deletePurchaseOrder(orderIds: string): Promise<void> {
|
||||
return request.delete(`/erp/po/order/${orderIds}`)
|
||||
}
|
||||
|
||||
// 获取采购订单单据视图列表
|
||||
export function getPurchaseOrderDocList(params: PurchaseOrderQuery): Promise<PurchaseOrderListResponse> {
|
||||
return request.get('/erp/po/order/docList', { params }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
// 获取采购订单汇总
|
||||
export function getPurchaseOrderSummary(params: PurchaseOrderQuery): Promise<{ totalOrderQty: number; totalArrivedQty: number }> {
|
||||
return request.get('/erp/po/order/summary', { params }).then((res: any) => res.data || {})
|
||||
}
|
||||
|
||||
// 生成采购订单编码(后端返回的编码在 data 中,msg 为「操作成功」)
|
||||
export function genPurchaseOrderCode(): Promise<string> {
|
||||
return request.get('/erp/po/order/genCode').then((res: any) => res.data ?? res.msg ?? '')
|
||||
}
|
||||
|
||||
// 审核采购订单
|
||||
export function approvePurchaseOrder(orderIds: string): Promise<void> {
|
||||
return request.put(`/erp/po/order/approve/${orderIds}`)
|
||||
}
|
||||
|
||||
// 反审核采购订单
|
||||
export function unapprovePurchaseOrder(orderIds: string): Promise<void> {
|
||||
return request.put(`/erp/po/order/unapprove/${orderIds}`)
|
||||
}
|
||||
|
||||
// 导出采购订单
|
||||
export function exportPurchaseOrder(params: PurchaseOrderQuery): Promise<Blob> {
|
||||
return request.post('/erp/po/order/export', params, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
// ============ 供应商 API(使用 MOM md_vendor,表 erp_po_supplier 在 my_mes 中未建) ============
|
||||
|
||||
export function getPoSupplierList(params?: { supplierName?: string; contact1?: string; pageNum?: number; pageSize?: number }): Promise<{ rows: PoSupplier[]; total: number }> {
|
||||
const { supplierName, contact1, pageNum = 1, pageSize = 200, ...rest } = params ?? {}
|
||||
return request.get('/mes/md/vendor/list', {
|
||||
params: { enableFlag: 'Y', pageNum, pageSize, vendorName: supplierName, contact1, ...rest }
|
||||
}).then((res: any) => {
|
||||
const rows = (res.rows ?? []).map((v: any) => ({
|
||||
supplierId: v.vendorId,
|
||||
supplierCode: v.vendorCode,
|
||||
supplierName: v.vendorName ?? '',
|
||||
supplierNick: v.vendorNick,
|
||||
tel: v.tel,
|
||||
contact1: v.contact1,
|
||||
contact1Tel: v.contact1Tel,
|
||||
enableFlag: v.enableFlag
|
||||
}))
|
||||
return { rows, total: res.total ?? 0 }
|
||||
})
|
||||
}
|
||||
|
||||
// ============ 引入采购计划单明细 API ============
|
||||
|
||||
export function getLeadInList(params?: { salesOrderCode?: string; itemCode?: string; itemName?: string; businessType?: string; pageNum?: number; pageSize?: number }): Promise<{ rows: LeadInRow[]; total: number }> {
|
||||
return request.get('/erp/po/order/leadIn', { params: { pageNum: 1, pageSize: 200, ...params } }).then((res: any) => {
|
||||
const rows = (res.rows ?? []).map((r: any) => ({
|
||||
...r,
|
||||
unpurchasedQty: (r.purchaseQty ?? 0) - (r.orderedQty ?? 0)
|
||||
}))
|
||||
return { rows, total: res.total ?? 0 }
|
||||
})
|
||||
}
|
||||
|
||||
// ============ 状态映射 ============
|
||||
|
||||
export const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
PREPARE: { label: '开立', type: 'info' },
|
||||
DRAFT: { label: '开立', type: 'info' },
|
||||
APPROVED: { label: '审核', type: 'success' },
|
||||
CLOSED: { label: '关闭', type: '' },
|
||||
REJECTED: { label: '退回', type: 'warning' }
|
||||
}
|
||||
|
||||
export const BUSINESS_STATUS_MAP: Record<string, string> = {
|
||||
NORMAL: '正常', COMPLETED: '完成', PAUSE: '暂停', CANCEL: '取消'
|
||||
}
|
||||
|
||||
export const BUSINESS_TYPE_OPTIONS = [
|
||||
{ value: '原材料', label: '原材料' },
|
||||
{ value: '零部件', label: '零部件' },
|
||||
{ value: '装配件', label: '装配件' },
|
||||
{ value: '成品', label: '成品' },
|
||||
{ value: '五金件', label: '五金件' },
|
||||
{ value: '包装物', label: '包装物' }
|
||||
]
|
||||
|
||||
export const BUSINESS_STATUS_OPTIONS = [
|
||||
{ value: 'NORMAL', label: '正常' },
|
||||
{ value: 'COMPLETED', label: '完成' },
|
||||
{ value: 'PAUSE', label: '暂停' },
|
||||
{ value: 'CANCEL', label: '取消' }
|
||||
]
|
||||
344
erp-frontend-vue/src/api/purchasePlan.ts
Normal file
344
erp-frontend-vue/src/api/purchasePlan.ts
Normal file
@@ -0,0 +1,344 @@
|
||||
import request from './request'
|
||||
|
||||
// ============ Type Definitions ============
|
||||
|
||||
/** Purchase plan line item */
|
||||
export interface PurchasePlanLine {
|
||||
purchaseId?: number
|
||||
purchaseCode?: string
|
||||
lineNo?: number
|
||||
itemId?: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
demandDate?: string
|
||||
demandQty?: number
|
||||
availableQty?: number
|
||||
purchaseQty: number
|
||||
orderedQty?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
/** Purchase plan flat row (detail view) */
|
||||
export interface PurchasePlan {
|
||||
purchaseId: number
|
||||
purchaseCode: string
|
||||
purchaseDate: string
|
||||
status: string
|
||||
needType: number
|
||||
businessType?: string
|
||||
businessStatus?: string
|
||||
planId?: number
|
||||
planCode?: string
|
||||
salesOrderId?: number
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
totalQuantity?: number
|
||||
demandQty?: number
|
||||
availableQty?: number
|
||||
purchaseQty: number
|
||||
orderedQty?: number
|
||||
remark?: string
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
operatorName2?: string
|
||||
approverId?: number
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
/** Purchase plan detail (header + lines from /detail/{id} endpoint) */
|
||||
export interface PurchasePlanDetail {
|
||||
purchaseId?: number
|
||||
purchaseCode: string
|
||||
purchaseDate: string
|
||||
status: string
|
||||
businessType?: string
|
||||
businessStatus?: string
|
||||
needType: number
|
||||
planId?: number
|
||||
planCode?: string
|
||||
salesOrderId?: number
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
headerItemCode?: string
|
||||
headerItemName?: string
|
||||
unitName?: string
|
||||
totalQuantity?: number
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
operatorName2?: string
|
||||
approverId?: number
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
remark?: string
|
||||
lines: PurchasePlanLine[]
|
||||
}
|
||||
|
||||
/** List query params */
|
||||
export interface PurchasePlanQuery {
|
||||
salesOrderCode?: string
|
||||
purchaseCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
needType?: number
|
||||
status?: string
|
||||
businessStatus?: string
|
||||
'params[beginDate]'?: string
|
||||
'params[endDate]'?: string
|
||||
'params[itemTypeId]'?: number | string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** Summary response */
|
||||
export interface PurchasePlanSummary {
|
||||
totalPurchaseQty: number
|
||||
totalOrderedQty: number
|
||||
}
|
||||
|
||||
/** Import dialog - production plan parent row */
|
||||
export interface ImportPlanRow {
|
||||
planId: number
|
||||
planCode: string
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
unitName?: string
|
||||
quantity?: number
|
||||
children?: ImportPlanMaterial[]
|
||||
}
|
||||
|
||||
/** Import dialog - material detail child row */
|
||||
export interface ImportPlanMaterial {
|
||||
mbomId?: number
|
||||
/** Stable unique key for table row-key (mbomId or composite fallback) */
|
||||
materialKey?: string
|
||||
planId?: number
|
||||
planCode?: string
|
||||
salesOrderCode?: string
|
||||
salesUserName?: string
|
||||
deliveryDate?: string
|
||||
itemId?: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
demandQty: number
|
||||
availableQty?: number
|
||||
purchasedQty?: number
|
||||
unpurchasedQty?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
// ============ Status Maps ============
|
||||
|
||||
export const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
'PREPARE': { label: '开立', type: 'info' },
|
||||
'DRAFT': { label: '开立', type: 'info' },
|
||||
'APPROVED': { label: '审核', type: 'success' },
|
||||
'REJECTED': { label: '退回', type: 'warning' }
|
||||
}
|
||||
|
||||
export const STATUS_OPTIONS = [
|
||||
{ value: 'PREPARE', label: '开立' },
|
||||
{ value: 'APPROVED', label: '审核' },
|
||||
{ value: 'REJECTED', label: '退回' }
|
||||
]
|
||||
|
||||
export const BUSINESS_STATUS_OPTIONS = [
|
||||
{ value: 'NORMAL', label: '正常' },
|
||||
{ value: 'PAUSE', label: '暂停' },
|
||||
{ value: 'CANCEL', label: '取消' },
|
||||
{ value: 'COMPLETED', label: '完成' }
|
||||
]
|
||||
|
||||
export const BUSINESS_STATUS_MAP: Record<string, string> = {
|
||||
'NORMAL': '正常',
|
||||
'PAUSE': '暂停',
|
||||
'CANCEL': '取消',
|
||||
'COMPLETED': '完成'
|
||||
}
|
||||
|
||||
export const BUSINESS_TYPE_OPTIONS = [
|
||||
{ value: '原材料', label: '原材料' },
|
||||
{ value: '零部件', label: '零部件' },
|
||||
{ value: '装配件', label: '装配件' },
|
||||
{ value: '成品', label: '成品' },
|
||||
{ value: '五金件', label: '五金件' },
|
||||
{ value: '包装物', label: '包装物' }
|
||||
]
|
||||
|
||||
export const NEED_TYPE_OPTIONS = [
|
||||
{ value: 0, label: '订单用料' },
|
||||
{ value: 1, label: '库存备料' }
|
||||
]
|
||||
|
||||
export function isEditableStatus(status: string): boolean {
|
||||
return status === 'PREPARE' || status === 'DRAFT' || status === 'REJECTED'
|
||||
}
|
||||
|
||||
export function isApprovedStatus(status: string): boolean {
|
||||
return status === 'APPROVED'
|
||||
}
|
||||
|
||||
// ============ API Functions ============
|
||||
|
||||
const BASE = '/erp/mp/purchase'
|
||||
|
||||
export function getPurchasePlanList(params: PurchasePlanQuery) {
|
||||
return request.get<any>(`${BASE}/list`, { params }).then((res: any) => ({
|
||||
rows: (res.rows ?? []) as PurchasePlan[],
|
||||
total: (res.total ?? 0) as number
|
||||
}))
|
||||
}
|
||||
|
||||
export function getPurchasePlanDocList(params: PurchasePlanQuery) {
|
||||
return request.get<any>(`${BASE}/docList`, { params }).then((res: any) => ({
|
||||
rows: (res.rows ?? []) as PurchasePlan[],
|
||||
total: (res.total ?? 0) as number
|
||||
}))
|
||||
}
|
||||
|
||||
export function getPurchasePlanSummary(params: PurchasePlanQuery) {
|
||||
return request.get<any>(`${BASE}/summary`, { params }).then((res: any) => {
|
||||
const d = res.data ?? res
|
||||
return { totalPurchaseQty: d.totalPurchaseQty ?? 0, totalOrderedQty: d.totalOrderedQty ?? 0 } as PurchasePlanSummary
|
||||
})
|
||||
}
|
||||
|
||||
export function getPurchasePlanDetail(idOrCode: number | string) {
|
||||
return request.get<any>(`${BASE}/detail/${idOrCode}`).then((res: any) => {
|
||||
const d = res.data ?? res
|
||||
if (!d.lines) d.lines = d.slaveList ?? d.details ?? []
|
||||
return d as PurchasePlanDetail
|
||||
})
|
||||
}
|
||||
|
||||
export function getPurchasePlanById(purchaseId: number) {
|
||||
return request.get<any>(`${BASE}/${purchaseId}`).then((res: any) => (res.data ?? res) as PurchasePlan)
|
||||
}
|
||||
|
||||
export function createPurchasePlan(data: Partial<PurchasePlanDetail>) {
|
||||
return request.post<any>(BASE, data).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
export function updatePurchasePlan(data: Partial<PurchasePlanDetail>) {
|
||||
return request.put<any>(BASE, data)
|
||||
}
|
||||
|
||||
export function deletePurchasePlan(purchaseIds: string) {
|
||||
return request.delete<any>(`${BASE}/${purchaseIds}`)
|
||||
}
|
||||
|
||||
export function deletePurchasePlanByCode(purchaseCode: string) {
|
||||
return request.delete<any>(`${BASE}/byCode/${purchaseCode}`)
|
||||
}
|
||||
|
||||
export function approvePurchasePlan(purchaseIds: string | number) {
|
||||
return request.put<any>(`${BASE}/approve/${purchaseIds}`)
|
||||
}
|
||||
|
||||
export function unapprovePurchasePlan(purchaseIds: string | number) {
|
||||
return request.put<any>(`${BASE}/unapprove/${purchaseIds}`)
|
||||
}
|
||||
|
||||
export function genPurchaseCode() {
|
||||
return request.get<any>(`${BASE}/genCode`).then((res: any) => (res.data ?? res.msg ?? '') as string)
|
||||
}
|
||||
|
||||
export function exportPurchasePlan(params: PurchasePlanQuery) {
|
||||
return request.post<any>(`${BASE}/export`, params, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
export function generateFromMbom(mbomId: number) {
|
||||
return request.post<any>(`${BASE}/generate/${mbomId}`)
|
||||
}
|
||||
|
||||
// ============ Import Dialog APIs ============
|
||||
|
||||
export function getImportPlanList(params?: {
|
||||
salesOrderCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
}) {
|
||||
const q: any = { status: 'APPROVED', pageNum: 1, pageSize: 200 }
|
||||
if (params?.salesOrderCode) q.salesOrderCode = params.salesOrderCode
|
||||
if (params?.itemCode) q.itemCode = params.itemCode
|
||||
if (params?.itemName) q.itemName = params.itemName
|
||||
if (params?.beginDate) q['params[beginDate]'] = params.beginDate
|
||||
if (params?.endDate) q['params[endDate]'] = params.endDate
|
||||
|
||||
return request.get<any>('/erp/mp/plan/list', { params: q }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
return rows.map((row: any) => ({
|
||||
planId: row.planId,
|
||||
planCode: row.planCode,
|
||||
salesOrderCode: row.salesOrderCode,
|
||||
salesUserName: row.salesUserName,
|
||||
deliveryDate: row.deliveryDate,
|
||||
itemCode: row.itemCode,
|
||||
itemName: row.itemName,
|
||||
unitName: row.unitName,
|
||||
quantity: row.totalQuantity ?? row.quantity,
|
||||
children: []
|
||||
})) as ImportPlanRow[]
|
||||
})
|
||||
}
|
||||
|
||||
export function getImportPlanMaterials(planId: number) {
|
||||
// 查询该生产计划下的MBOM明细行(子件物料),不再过滤supplyType以展示所有物料
|
||||
return request.get<any>(`/erp/mp/mbomline/plan/${planId}`).then((res: any) => {
|
||||
const rows = res.data ?? res.rows ?? []
|
||||
return rows.map((row: any, index: number) => {
|
||||
const lineId = row.lineId ?? row.mbomId
|
||||
const materialKey =
|
||||
lineId != null ? String(lineId) : `plan_${planId}_${row.itemId ?? row.itemCode ?? index}_${index}`
|
||||
const demandQty = row.quantity ?? 0
|
||||
const purchasedQty = row.purchasedQty ?? row.orderedQty ?? 0
|
||||
return {
|
||||
mbomId: lineId,
|
||||
materialKey,
|
||||
planId,
|
||||
planCode: row.planCode ?? row.mbomCode,
|
||||
itemId: row.itemId,
|
||||
itemCode: row.itemCode,
|
||||
itemName: row.itemName,
|
||||
specification: row.specification,
|
||||
unitName: row.unitName,
|
||||
demandQty,
|
||||
availableQty: row.availableQty ?? row.stockQty ?? 0,
|
||||
purchasedQty,
|
||||
unpurchasedQty: row.unpurchasedQty ?? (demandQty - purchasedQty),
|
||||
remark: row.remark ?? ''
|
||||
}
|
||||
}) as ImportPlanMaterial[]
|
||||
})
|
||||
}
|
||||
|
||||
export function getItemTypeList() {
|
||||
return request.get<any>('/mes/md/itemtype/list', { params: { pageNum: 1, pageSize: 100 } }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? (Array.isArray(res.data) ? res.data : [])
|
||||
return rows.map((row: any) => ({
|
||||
itemTypeId: row.itemTypeId,
|
||||
itemTypeName: row.itemTypeName
|
||||
})) as Array<{ itemTypeId: number; itemTypeName: string }>
|
||||
})
|
||||
}
|
||||
227
erp-frontend-vue/src/api/rd/ebom.ts
Normal file
227
erp-frontend-vue/src/api/rd/ebom.ts
Normal file
@@ -0,0 +1,227 @@
|
||||
import request from '../request'
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
|
||||
/** EBOM 表头 */
|
||||
export interface EbomHeader {
|
||||
bomId?: number
|
||||
bomCode?: string
|
||||
bomName?: string
|
||||
bomDate?: string
|
||||
version?: string
|
||||
versionDesc?: string
|
||||
status?: string
|
||||
businessType?: string
|
||||
businessStatus?: string
|
||||
drawingNo?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemSpec?: string
|
||||
unitName?: string
|
||||
baseQty?: number
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
approverId?: number
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
enableFlag?: string
|
||||
remark?: string
|
||||
tenantId?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
/** 明细行 (表单提交时携带) */
|
||||
lines?: EbomLine[]
|
||||
}
|
||||
|
||||
/** EBOM 明细行 */
|
||||
export interface EbomLine {
|
||||
lineId?: number
|
||||
bomId?: number
|
||||
bomCode?: string
|
||||
lineNo?: number
|
||||
bomItemId?: number
|
||||
bomItemCode?: string
|
||||
bomItemName?: string
|
||||
bomItemSpec?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
itemOrProduct?: string
|
||||
quantity?: number
|
||||
numerator?: number
|
||||
denominator?: number
|
||||
lossRate?: number
|
||||
supplyType?: string
|
||||
pickType?: string
|
||||
usageType?: string
|
||||
routeId?: number
|
||||
routeName?: string
|
||||
drawingNo?: string
|
||||
remark?: string
|
||||
tenantId?: string
|
||||
delFlag?: string
|
||||
/** 前端临时字段 */
|
||||
_isNew?: boolean
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface EbomQuery {
|
||||
bomCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemTypeId?: number
|
||||
status?: string
|
||||
businessStatus?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
workType?: number
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 列表响应 */
|
||||
export interface EbomListResponse {
|
||||
rows: EbomHeader[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// ==================== 常量定义 ====================
|
||||
|
||||
/** 单据状态映射 */
|
||||
export const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
DRAFT: { label: '开立', type: 'info' },
|
||||
APPROVED: { label: '审核', type: 'success' },
|
||||
REJECTED: { label: '退回', type: 'warning' }
|
||||
}
|
||||
|
||||
/** 单据状态选项 */
|
||||
export const STATUS_OPTIONS = [
|
||||
{ value: 'DRAFT', label: '开立' },
|
||||
{ value: 'APPROVED', label: '审核' },
|
||||
{ value: 'REJECTED', label: '退回' }
|
||||
]
|
||||
|
||||
/** 业务状态选项 */
|
||||
export const BIZ_STATUS_OPTIONS = [
|
||||
{ value: 'NORMAL', label: '正常' },
|
||||
{ value: 'PAUSE', label: '暂停' },
|
||||
{ value: 'CANCEL', label: '取消' }
|
||||
]
|
||||
|
||||
/** 业务类型选项 */
|
||||
export const BIZ_TYPE_OPTIONS = [
|
||||
{ value: 'MECHANICAL', label: '机械BOM' },
|
||||
{ value: 'ELECTRICAL', label: '电气BOM' },
|
||||
{ value: 'ASSEMBLY', label: '装配BOM' },
|
||||
{ value: 'GENERAL', label: '通用BOM' }
|
||||
]
|
||||
|
||||
/** 领料方式选项 */
|
||||
export const PICK_TYPE_OPTIONS = [
|
||||
{ value: 'ORDER', label: '按单领用' },
|
||||
{ value: 'DIRECT', label: '直接领用' }
|
||||
]
|
||||
|
||||
/** 用量方式选项 */
|
||||
export const USAGE_TYPE_OPTIONS = [
|
||||
{ value: 'RATIO', label: '按比例' },
|
||||
{ value: 'FIXED', label: '固定用量' }
|
||||
]
|
||||
|
||||
/** 供应方式选项 */
|
||||
export const SUPPLY_TYPE_OPTIONS = [
|
||||
{ value: 'PURCHASE', label: '采购' },
|
||||
{ value: 'PRODUCE', label: '生产' },
|
||||
{ value: 'OUTSOURCE', label: '委外' },
|
||||
{ value: 'ASSEMBLY', label: '装配' },
|
||||
{ value: 'PROCESS', label: '加工' }
|
||||
]
|
||||
|
||||
// ==================== API 函数 ====================
|
||||
|
||||
const BASE = '/mes/md/bom'
|
||||
const LINE_BASE = '/mes/md/bom/line'
|
||||
|
||||
/** 查询EBOM列表(单据视图) */
|
||||
export function listEbom(query?: EbomQuery): Promise<EbomListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询EBOM列表(明细视图 - 含物料信息的展开列表) */
|
||||
export function listEbomDetail(query?: EbomQuery): Promise<EbomListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 获取EBOM详情 */
|
||||
export function getEbom(bomId: number): Promise<{ data: EbomHeader }> {
|
||||
return request.get(`${BASE}/${bomId}`)
|
||||
}
|
||||
|
||||
/** 新增EBOM */
|
||||
export function addEbom(data: Partial<EbomHeader>): Promise<{ data: EbomHeader }> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改EBOM */
|
||||
export function updateEbom(data: Partial<EbomHeader>): Promise<{ data: EbomHeader }> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除EBOM */
|
||||
export function deleteEbom(ids: number | number[]): Promise<void> {
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : String(ids)
|
||||
return request.delete(`${BASE}/${idStr}`)
|
||||
}
|
||||
|
||||
/** 审核EBOM */
|
||||
export function approveEbom(bomId: number): Promise<void> {
|
||||
return request.put(`${BASE}/approve`, { bomId })
|
||||
}
|
||||
|
||||
/** 反审核EBOM */
|
||||
export function unapproveEbom(bomId: number): Promise<void> {
|
||||
return request.put(`${BASE}/reject`, { bomId })
|
||||
}
|
||||
|
||||
/** 查询BOM明细列表 */
|
||||
export function listEbomLines(query?: { bomCode?: string; pageNum?: number; pageSize?: number }): Promise<{ rows: EbomLine[]; total: number }> {
|
||||
return request.get(`${LINE_BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 新增BOM明细 */
|
||||
export function addEbomLine(data: Partial<EbomLine>): Promise<{ data: EbomLine }> {
|
||||
return request.post(LINE_BASE, data)
|
||||
}
|
||||
|
||||
/** 修改BOM明细 */
|
||||
export function updateEbomLine(data: Partial<EbomLine>): Promise<{ data: EbomLine }> {
|
||||
return request.put(LINE_BASE, data)
|
||||
}
|
||||
|
||||
/** 删除BOM明细 */
|
||||
export function deleteEbomLine(ids: number | number[]): Promise<void> {
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : String(ids)
|
||||
return request.delete(`${LINE_BASE}/${idStr}`)
|
||||
}
|
||||
|
||||
/** 导出EBOM列表(GET,后端与 POST /export 行为一致) */
|
||||
export function exportEbom(query?: EbomQuery): Promise<Blob> {
|
||||
return request.get(`${BASE}/export`, {
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
91
erp-frontend-vue/src/api/reject.ts
Normal file
91
erp-frontend-vue/src/api/reject.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import request from './request'
|
||||
|
||||
export interface RejectLine {
|
||||
lineId: number
|
||||
rejectId: number
|
||||
rejectCode: string
|
||||
lineNo: number
|
||||
checkinLineId?: number
|
||||
trackCode?: string
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
unitName?: string
|
||||
quantity: number
|
||||
outQuantity?: number
|
||||
returnQuantity?: number
|
||||
reason?: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface Reject {
|
||||
rejectId: number
|
||||
rejectCode: string
|
||||
rejectDate: string
|
||||
status: string
|
||||
businessType: string
|
||||
supplierId: number
|
||||
supplierName: string
|
||||
checkinId?: number
|
||||
checkinCode?: string
|
||||
totalQuantity?: number
|
||||
outQuantity?: number
|
||||
returnQuantity?: number
|
||||
reason?: string
|
||||
remark?: string
|
||||
operatorName?: string
|
||||
approverName?: string
|
||||
approveDate?: string
|
||||
lines: RejectLine[]
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface RejectQuery {
|
||||
trackCode?: string
|
||||
rejectCode?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
beginDate?: string
|
||||
endDate?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface RejectListResponse {
|
||||
rows: Reject[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取采购退货单列表
|
||||
export function getRejectList(params: RejectQuery): Promise<RejectListResponse> {
|
||||
return request.get('/erp/po/reject/list', { params }).then((res: any) => {
|
||||
return {
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取采购退货单详情
|
||||
export function getRejectDetail(rejectId: number): Promise<Reject> {
|
||||
return request.get(`/erp/po/reject/${rejectId}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增采购退货单
|
||||
export function createReject(data: Partial<Reject>): Promise<void> {
|
||||
return request.post('/erp/po/reject', data)
|
||||
}
|
||||
|
||||
// 更新采购退货单
|
||||
export function updateReject(data: Partial<Reject>): Promise<void> {
|
||||
return request.put('/erp/po/reject', data)
|
||||
}
|
||||
|
||||
// 删除采购退货单
|
||||
export function deleteReject(rejectIds: string): Promise<void> {
|
||||
return request.delete(`/erp/po/reject/${rejectIds}`)
|
||||
}
|
||||
105
erp-frontend-vue/src/api/request.ts
Normal file
105
erp-frontend-vue/src/api/request.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import axios from 'axios'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getToken, removeToken } from '@/utils/auth'
|
||||
import router from '@/router'
|
||||
|
||||
// 是否显示重新登录弹窗
|
||||
let isReloginShowing = false
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: '',
|
||||
timeout: 30000
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
// 根据URL前缀动态设置baseURL
|
||||
// 支持 /mes/*、/erp/* 和 /system/* 三种API地址
|
||||
if (config.url) {
|
||||
if (config.url.startsWith('/mes/')) {
|
||||
// /mes/* 接口直接使用,不添加额外前缀
|
||||
// 保持原样
|
||||
} else if (config.url.startsWith('/erp/')) {
|
||||
// /erp/* 接口直接使用,不添加额外前缀
|
||||
// 保持原样
|
||||
} else if (config.url.startsWith('/system/')) {
|
||||
// /system/* 接口直接使用,不添加额外前缀(组织架构模块)
|
||||
// 保持原样
|
||||
} else {
|
||||
// 其他接口默认添加 /erp 前缀
|
||||
config.url = '/erp' + config.url
|
||||
}
|
||||
}
|
||||
|
||||
// 添加 Token 到请求头
|
||||
const token = getToken()
|
||||
if (token) {
|
||||
config.headers = config.headers || {}
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
const res = response.data
|
||||
const code = res.code || 200
|
||||
|
||||
// 处理 401 未授权
|
||||
if (code === 401) {
|
||||
if (!isReloginShowing) {
|
||||
isReloginShowing = true
|
||||
ElMessageBox.confirm(
|
||||
'登录状态已过期,您可以继续留在该页面,或者重新登录',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
isReloginShowing = false
|
||||
removeToken()
|
||||
router.push('/login')
|
||||
}).catch(() => {
|
||||
isReloginShowing = false
|
||||
})
|
||||
}
|
||||
return Promise.reject(new Error('无效的会话,或者会话已过期,请重新登录。'))
|
||||
}
|
||||
|
||||
// 处理其他错误码
|
||||
if (code !== 200) {
|
||||
const msg = res.msg || res.message || '请求失败'
|
||||
ElMessage.error(msg)
|
||||
return Promise.reject(new Error(msg))
|
||||
}
|
||||
|
||||
return res
|
||||
},
|
||||
(error) => {
|
||||
console.error('Request error:', error)
|
||||
let message = error.message || '网络错误'
|
||||
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
const status = message.substring(message.length - 3)
|
||||
message = `系统接口 ${status} 异常`
|
||||
}
|
||||
|
||||
ElMessage.error(message)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default request
|
||||
105
erp-frontend-vue/src/api/saleback.ts
Normal file
105
erp-frontend-vue/src/api/saleback.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import request from './request'
|
||||
|
||||
export interface SalebackLine {
|
||||
lineId?: number
|
||||
id?: number
|
||||
salebackId?: number
|
||||
salebackCode?: string
|
||||
deliverLineId?: number
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
materialCode?: string
|
||||
itemName?: string
|
||||
materialName?: string
|
||||
specification?: string
|
||||
spec?: string
|
||||
unitOfMeasure?: string
|
||||
unit?: string
|
||||
returnQty: number
|
||||
reason?: string
|
||||
}
|
||||
|
||||
export interface Saleback {
|
||||
salebackId?: number
|
||||
id?: number
|
||||
salebackCode?: string
|
||||
code?: string
|
||||
clientId?: number
|
||||
customerId?: number
|
||||
clientCode?: string
|
||||
customerCode?: string
|
||||
clientName?: string
|
||||
customerName?: string
|
||||
returnDate: string
|
||||
status: string
|
||||
totalQty?: number
|
||||
reason?: string
|
||||
remark?: string
|
||||
lines?: SalebackLine[]
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
export interface SalebackQuery {
|
||||
code?: string
|
||||
customerName?: string
|
||||
status?: string
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface SalebackListResponse {
|
||||
list: Saleback[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// 获取退货单列表
|
||||
export function getSalebackList(params: SalebackQuery): Promise<SalebackListResponse> {
|
||||
return request.get('/erp/sl/saleback/list', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取退货单详情
|
||||
export function getSalebackDetail(id: number): Promise<Saleback> {
|
||||
return request.get(`/erp/sl/saleback/${id}`).then((res: any) => {
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增退货单
|
||||
export function createSaleback(data: Partial<Saleback>): Promise<void> {
|
||||
return request.post('/erp/sl/saleback', data)
|
||||
}
|
||||
|
||||
// 更新退货单
|
||||
export function updateSaleback(id: number, data: Partial<Saleback>): Promise<void> {
|
||||
return request.put('/erp/sl/saleback', { ...data, salebackId: id })
|
||||
}
|
||||
|
||||
// 删除退货单
|
||||
export function deleteSaleback(id: number): Promise<void> {
|
||||
return request.delete(`/erp/sl/saleback/${id}`)
|
||||
}
|
||||
|
||||
// 审核退货单
|
||||
export function auditSaleback(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/saleback/audit/${id}`)
|
||||
}
|
||||
|
||||
// 反审核退货单
|
||||
export function unauditSaleback(id: number): Promise<void> {
|
||||
return request.post(`/erp/sl/saleback/unaudit/${id}`)
|
||||
}
|
||||
|
||||
// 引入发货单
|
||||
export function getIntroduceDeliverList(params: any): Promise<SalebackListResponse> {
|
||||
return request.get('/erp/sl/saleback/introduce', { params }).then((res: any) => {
|
||||
return {
|
||||
list: res.rows || [],
|
||||
total: res.total || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
268
erp-frontend-vue/src/api/salesOrder.ts
Normal file
268
erp-frontend-vue/src/api/salesOrder.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
import request from './request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 订单明细行 */
|
||||
export interface SalesOrderLine {
|
||||
lineId?: number
|
||||
orderId?: number
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitOfMeasure?: string
|
||||
quantity?: number // 可选,新增时默认为空
|
||||
unitPrice?: number
|
||||
amount?: number
|
||||
deliveredQty?: number
|
||||
qualityReq?: string
|
||||
remark?: string
|
||||
delFlag?: string
|
||||
}
|
||||
|
||||
/** 销售订单主表 */
|
||||
export interface SalesOrder {
|
||||
orderId?: number
|
||||
orderCode?: string
|
||||
orderName?: string
|
||||
orderDate?: string
|
||||
orderStatus?: string
|
||||
// 客户信息
|
||||
clientId?: number
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
// 业务信息
|
||||
contractNo?: string
|
||||
bizType?: string
|
||||
bizStatus?: string
|
||||
salesType?: string
|
||||
supplyMode?: string
|
||||
deliveryStatus?: string
|
||||
// 部门/人员
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
salesmanId?: number
|
||||
salesmanName?: string
|
||||
operatorId?: number
|
||||
operatorName?: string
|
||||
auditorId?: number
|
||||
auditorName?: string
|
||||
auditDate?: string
|
||||
// 收货信息
|
||||
receiver?: string
|
||||
receiverPhone?: string
|
||||
receiverAddress?: string
|
||||
destCountry?: string
|
||||
paymentTerms?: string
|
||||
deliveryDate?: string
|
||||
// 金额
|
||||
totalAmount?: number
|
||||
currency?: string
|
||||
// 其他
|
||||
remark?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
// 明细行
|
||||
lines?: SalesOrderLine[]
|
||||
slaveList?: SalesOrderLine[]
|
||||
}
|
||||
|
||||
/** 明细视图数据(展开物料维度) */
|
||||
export interface SalesOrderDetailView {
|
||||
orderId: number
|
||||
orderCode: string
|
||||
orderDate: string
|
||||
orderStatus: string
|
||||
contractNo?: string
|
||||
clientId: number
|
||||
clientName: string
|
||||
salesmanName?: string
|
||||
salesType?: string
|
||||
// 物料信息
|
||||
lineId: number
|
||||
itemId: number
|
||||
itemCode: string
|
||||
itemName: string
|
||||
specification?: string
|
||||
quantity: number
|
||||
unitPrice?: number
|
||||
amount?: number
|
||||
deliveredQty?: number
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface SalesOrderQuery {
|
||||
orderCode?: string
|
||||
contractNo?: string
|
||||
clientName?: string
|
||||
salesmanName?: string
|
||||
salesType?: string
|
||||
itemName?: string
|
||||
orderStatus?: string
|
||||
beginOrderDate?: string
|
||||
endOrderDate?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 分页响应 */
|
||||
export interface SalesOrderListResponse {
|
||||
list: SalesOrder[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface SalesOrderDetailListResponse {
|
||||
list: SalesOrderDetailView[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// ============ 状态映射 ============
|
||||
|
||||
export const ORDER_STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
'DRAFT': { label: '草稿', type: 'info' },
|
||||
'开立': { label: '开立', type: '' },
|
||||
'审核': { label: '审核', type: 'success' },
|
||||
'退回': { label: '退回', type: 'warning' },
|
||||
'关闭': { label: '关闭', type: 'danger' }
|
||||
}
|
||||
|
||||
export const SALES_TYPE_OPTIONS = [
|
||||
{ value: 'factory', label: '工厂订单' },
|
||||
{ value: 'stock', label: '库存供应' },
|
||||
{ value: 'purchase', label: '买进卖出' }
|
||||
]
|
||||
|
||||
export const SUPPLY_MODE_OPTIONS = [
|
||||
{ value: 'plan', label: '计划生产' },
|
||||
{ value: 'stock', label: '库存供应' }
|
||||
]
|
||||
|
||||
export const DELIVERY_STATUS_OPTIONS = [
|
||||
{ value: 'estimate', label: '预计' },
|
||||
{ value: 'confirm', label: '确认' }
|
||||
]
|
||||
|
||||
export const BIZ_TYPE_OPTIONS = [
|
||||
{ value: 'sales_order', label: '销售订单' }
|
||||
]
|
||||
|
||||
export const BIZ_STATUS_OPTIONS = [
|
||||
{ value: 'normal', label: '正常' },
|
||||
{ value: 'suspend', label: '挂起' }
|
||||
]
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/erp/sl/order'
|
||||
|
||||
/** 获取销售订单列表(单据视图) */
|
||||
export function getSalesOrderList(params: SalesOrderQuery): Promise<SalesOrderListResponse> {
|
||||
return request.get(`${BASE}/list`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { list: rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取销售订单明细列表(明细视图,展开物料维度) */
|
||||
export function getSalesOrderDetailList(params: SalesOrderQuery): Promise<SalesOrderDetailListResponse> {
|
||||
return request.get(`${BASE}/lineList`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { list: rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取销售订单详情(含明细行) */
|
||||
export function getSalesOrderDetail(orderId: number): Promise<SalesOrder> {
|
||||
return request.get(`${BASE}/${orderId}`).then((res: any) => {
|
||||
const data = res.data ?? res
|
||||
// 统一明细字段名
|
||||
if (data.slaveList && !data.lines) {
|
||||
data.lines = data.slaveList
|
||||
}
|
||||
// 后端返回 salesUserId/salesUserName,前端表单使用 salesmanId/salesmanName,便于下拉回显
|
||||
if (data.salesUserId !== undefined) data.salesmanId = data.salesUserId
|
||||
if (data.salesUserName !== undefined) data.salesmanName = data.salesUserName
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
/** 构建保存用 payload:明细转 slaveList,销售人员字段对齐后端 salesUserId/salesUserName */
|
||||
function buildOrderPayload(data: Partial<SalesOrder>): Record<string, unknown> {
|
||||
const payload: Record<string, unknown> = { ...data }
|
||||
if (payload.lines) {
|
||||
payload.slaveList = payload.lines
|
||||
delete payload.lines
|
||||
}
|
||||
// 后端实体为 salesUserId / salesUserName,前端表单为 salesmanId / salesmanName,此处统一发给后端
|
||||
if (payload.salesmanId !== undefined) payload.salesUserId = payload.salesmanId
|
||||
if (payload.salesmanName !== undefined) payload.salesUserName = payload.salesmanName
|
||||
return payload
|
||||
}
|
||||
|
||||
/** 新增销售订单 */
|
||||
export function createSalesOrder(data: Partial<SalesOrder>): Promise<{ orderId: number }> {
|
||||
return request.post(BASE, buildOrderPayload(data)).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 更新销售订单 */
|
||||
export function updateSalesOrder(data: Partial<SalesOrder>): Promise<void> {
|
||||
return request.put(BASE, buildOrderPayload(data))
|
||||
}
|
||||
|
||||
/** 删除销售订单(支持批量) */
|
||||
export function deleteSalesOrder(orderIds: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(orderIds) ? orderIds.join(',') : String(orderIds)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 审核销售订单(支持批量) */
|
||||
export function auditSalesOrder(orderIds: number | number[]): Promise<void> {
|
||||
if (orderIds == null || (Array.isArray(orderIds) && orderIds.length === 0)) {
|
||||
return Promise.reject(new Error('订单ID不能为空'))
|
||||
}
|
||||
const ids = Array.isArray(orderIds) ? orderIds.join(',') : String(orderIds)
|
||||
return request.post(`${BASE}/audit/${ids}`)
|
||||
}
|
||||
|
||||
/** 反审核销售订单(支持批量) */
|
||||
export function unauditSalesOrder(orderIds: number | number[]): Promise<void> {
|
||||
if (orderIds == null || (Array.isArray(orderIds) && orderIds.length === 0)) {
|
||||
return Promise.reject(new Error('订单ID不能为空'))
|
||||
}
|
||||
const ids = Array.isArray(orderIds) ? orderIds.join(',') : String(orderIds)
|
||||
return request.post(`${BASE}/unaudit/${ids}`)
|
||||
}
|
||||
|
||||
/** 导出销售订单 */
|
||||
export function exportSalesOrder(params: SalesOrderQuery): Promise<Blob> {
|
||||
return request.get(`${BASE}/export`, {
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// ============ 辅助接口 ============
|
||||
|
||||
/** 从销售合同引入订单明细 */
|
||||
export function importFromContract(contractId: number): Promise<{ lines: SalesOrderLine[] }> {
|
||||
return request.get(`/erp/sl/contract/${contractId}/lines`).then((res: any) => {
|
||||
return { lines: res.data ?? res.rows ?? [] }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取可引入的合同列表 */
|
||||
export function getAvailableContracts(clientId?: number): Promise<any[]> {
|
||||
return request.get('/erp/sl/contract/available', { params: { clientId } }).then((res: any) => {
|
||||
return res.rows ?? res.data ?? []
|
||||
})
|
||||
}
|
||||
|
||||
/** 生成订单编码(可选,后端自动生成时不需要) */
|
||||
export function generateOrderCode(): Promise<string> {
|
||||
return request.get(`${BASE}/generateCode`).then((res: any) => res.data ?? res)
|
||||
}
|
||||
155
erp-frontend-vue/src/api/supplier.ts
Normal file
155
erp-frontend-vue/src/api/supplier.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import request from './request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 供应商主数据 */
|
||||
export interface Supplier {
|
||||
vendorId?: number
|
||||
vendorCode?: string
|
||||
vendorName?: string
|
||||
vendorNick?: string
|
||||
vendorEn?: string
|
||||
vendorDes?: string
|
||||
vendorType?: string
|
||||
vendorLevel?: string
|
||||
vendorScore?: number
|
||||
vendorLogo?: string
|
||||
address?: string
|
||||
province?: string
|
||||
city?: string
|
||||
zipCode?: string
|
||||
website?: string
|
||||
email?: string
|
||||
tel?: string
|
||||
fax?: string
|
||||
contact1?: string
|
||||
contact1Tel?: string
|
||||
contact1Email?: string
|
||||
contact2?: string
|
||||
contact2Tel?: string
|
||||
contact2Email?: string
|
||||
creditCode?: string
|
||||
bankName?: string
|
||||
bankAccount?: string
|
||||
bankAddress?: string
|
||||
taxNo?: string
|
||||
supplyItems?: string
|
||||
remark?: string
|
||||
enableFlag?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface SupplierQuery {
|
||||
vendorCode?: string
|
||||
vendorName?: string
|
||||
vendorNick?: string
|
||||
vendorEn?: string
|
||||
vendorType?: string
|
||||
vendorLevel?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 分页响应 */
|
||||
export interface SupplierListResponse {
|
||||
rows: Supplier[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// ============ 状态枚举 ============
|
||||
|
||||
/** 供应商等级选项 */
|
||||
export const VENDOR_LEVEL_OPTIONS = [
|
||||
{ value: 'A', label: 'A级' },
|
||||
{ value: 'B', label: 'B级' },
|
||||
{ value: 'C', label: 'C级' },
|
||||
{ value: 'D', label: 'D级' }
|
||||
]
|
||||
|
||||
/** 供应商类型选项 */
|
||||
export const VENDOR_TYPE_OPTIONS = [
|
||||
{ value: 'CORE', label: '核心供应商' },
|
||||
{ value: 'NORMAL', label: '普通供应商' },
|
||||
{ value: 'TEMP', label: '临时供应商' }
|
||||
]
|
||||
|
||||
/** 是否启用选项 */
|
||||
export const ENABLE_FLAG_OPTIONS = [
|
||||
{ value: 'Y', label: '启用' },
|
||||
{ value: 'N', label: '停用' }
|
||||
]
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/mes/md/vendor'
|
||||
|
||||
/** 获取供应商列表 */
|
||||
export function getSupplierList(params: SupplierQuery): Promise<SupplierListResponse> {
|
||||
return request.get(`${BASE}/list`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取供应商详情 */
|
||||
export function getSupplierDetail(vendorId: number): Promise<Supplier> {
|
||||
return request.get(`${BASE}/${vendorId}`).then((res: any) => {
|
||||
return res.data ?? res
|
||||
})
|
||||
}
|
||||
|
||||
/** 新增供应商 */
|
||||
export function createSupplier(data: Partial<Supplier>): Promise<{ vendorId: number }> {
|
||||
return request.post(BASE, data).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 更新供应商 */
|
||||
export function updateSupplier(data: Partial<Supplier>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除供应商(支持批量) */
|
||||
export function deleteSupplier(vendorIds: number | number[] | string): Promise<void> {
|
||||
const ids = Array.isArray(vendorIds) ? vendorIds.join(',') : String(vendorIds)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 导出供应商列表 */
|
||||
export function exportSupplier(params: SupplierQuery): Promise<Blob> {
|
||||
return request.get(`${BASE}/export`, {
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/** 下载导入模板 */
|
||||
export function downloadImportTemplate(): Promise<Blob> {
|
||||
return request.get(`${BASE}/importTemplate`, {
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/** 导入供应商数据 */
|
||||
export function importSupplier(file: File, updateSupport: boolean = false): Promise<any> {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return request.post(`${BASE}/importData?updateSupport=${updateSupport}`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取供应商选项列表(用于下拉选择) */
|
||||
export function getSupplierOptions(): Promise<Supplier[]> {
|
||||
return request.get(`${BASE}/list`, {
|
||||
params: { enableFlag: 'Y', pageNum: 1, pageSize: 1000 }
|
||||
}).then((res: any) => {
|
||||
return res.rows ?? res.data?.rows ?? []
|
||||
})
|
||||
}
|
||||
91
erp-frontend-vue/src/api/system/dept.ts
Normal file
91
erp-frontend-vue/src/api/system/dept.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface Dept {
|
||||
deptId?: number
|
||||
parentId?: number
|
||||
ancestors?: string
|
||||
deptCode?: string
|
||||
deptName?: string
|
||||
orderNum?: number
|
||||
leader?: string
|
||||
phone?: string
|
||||
email?: string
|
||||
status?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
children?: Dept[]
|
||||
}
|
||||
|
||||
export interface DeptQuery {
|
||||
deptName?: string
|
||||
status?: string
|
||||
}
|
||||
|
||||
const BASE = '/system/dept'
|
||||
|
||||
/** 查询部门列表 */
|
||||
export function listDept(query?: DeptQuery): Promise<{ data: Dept[] }> {
|
||||
return request.get(`${BASE}/list`, { params: query })
|
||||
}
|
||||
|
||||
/** 查询部门列表(排除节点) */
|
||||
export function listDeptExcludeChild(deptId: number): Promise<{ data: Dept[] }> {
|
||||
return request.get(`${BASE}/list/exclude/${deptId}`)
|
||||
}
|
||||
|
||||
/** 查询部门详细 */
|
||||
export function getDept(deptId: number): Promise<{ data: Dept }> {
|
||||
return request.get(`${BASE}/${deptId}`)
|
||||
}
|
||||
|
||||
/** 查询部门下拉树结构 */
|
||||
export function getDeptTreeselect(): Promise<{ data: any[] }> {
|
||||
return request.get(`${BASE}/treeselect`)
|
||||
}
|
||||
|
||||
/** 根据角色ID查询部门树结构 */
|
||||
export function getRoleDeptTreeselect(roleId: number): Promise<{ data: any }> {
|
||||
return request.get(`${BASE}/roleDeptTreeselect/${roleId}`)
|
||||
}
|
||||
|
||||
/** 新增部门 */
|
||||
export function addDept(data: Partial<Dept>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改部门 */
|
||||
export function updateDept(data: Partial<Dept>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除部门 */
|
||||
export function delDept(deptId: number): Promise<void> {
|
||||
return request.delete(`${BASE}/${deptId}`)
|
||||
}
|
||||
|
||||
/** 构建部门树 */
|
||||
export function handleTree(data: Dept[], idField = 'deptId', parentField = 'parentId'): Dept[] {
|
||||
const map = new Map<number, Dept>()
|
||||
const result: Dept[] = []
|
||||
|
||||
data.forEach(item => {
|
||||
map.set(item[idField as keyof Dept] as number, { ...item, children: [] })
|
||||
})
|
||||
|
||||
data.forEach(item => {
|
||||
const current = map.get(item[idField as keyof Dept] as number)!
|
||||
const parentId = item[parentField as keyof Dept] as number
|
||||
if (parentId && map.has(parentId)) {
|
||||
const parent = map.get(parentId)!
|
||||
parent.children = parent.children || []
|
||||
parent.children.push(current)
|
||||
} else {
|
||||
result.push(current)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
58
erp-frontend-vue/src/api/system/post.ts
Normal file
58
erp-frontend-vue/src/api/system/post.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface Post {
|
||||
postId?: number
|
||||
postCode?: string
|
||||
postName?: string
|
||||
postSort?: number
|
||||
status?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface PostQuery {
|
||||
postCode?: string
|
||||
postName?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface PostListResponse {
|
||||
rows: Post[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/system/post'
|
||||
|
||||
/** 查询岗位列表 */
|
||||
export function listPost(query?: PostQuery): Promise<PostListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询岗位详细 */
|
||||
export function getPost(postId: number): Promise<{ data: Post }> {
|
||||
return request.get(`${BASE}/${postId}`)
|
||||
}
|
||||
|
||||
/** 新增岗位 */
|
||||
export function addPost(data: Partial<Post>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改岗位 */
|
||||
export function updatePost(data: Partial<Post>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除岗位 */
|
||||
export function delPost(postId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(postId) ? postId.join(',') : String(postId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
99
erp-frontend-vue/src/api/system/role.ts
Normal file
99
erp-frontend-vue/src/api/system/role.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface Role {
|
||||
roleId?: number
|
||||
roleName?: string
|
||||
roleKey?: string
|
||||
roleSort?: number
|
||||
dataScope?: string
|
||||
menuCheckStrictly?: boolean
|
||||
deptCheckStrictly?: boolean
|
||||
status?: string
|
||||
delFlag?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
remark?: string
|
||||
menuIds?: number[]
|
||||
deptIds?: number[]
|
||||
}
|
||||
|
||||
export interface RoleQuery {
|
||||
roleName?: string
|
||||
roleKey?: string
|
||||
status?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface RoleListResponse {
|
||||
rows: Role[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/system/role'
|
||||
|
||||
/** 查询角色列表 */
|
||||
export function listRole(query?: RoleQuery): Promise<RoleListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询角色详细 */
|
||||
export function getRole(roleId: number): Promise<{ data: Role }> {
|
||||
return request.get(`${BASE}/${roleId}`)
|
||||
}
|
||||
|
||||
/** 新增角色 */
|
||||
export function addRole(data: Partial<Role>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改角色 */
|
||||
export function updateRole(data: Partial<Role>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 角色数据权限 */
|
||||
export function dataScope(data: Partial<Role>): Promise<void> {
|
||||
return request.put(`${BASE}/dataScope`, data)
|
||||
}
|
||||
|
||||
/** 角色状态修改 */
|
||||
export function changeRoleStatus(roleId: number, status: string): Promise<void> {
|
||||
return request.put(`${BASE}/changeStatus`, { roleId, status })
|
||||
}
|
||||
|
||||
/** 删除角色 */
|
||||
export function delRole(roleId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(roleId) ? roleId.join(',') : String(roleId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 查询角色已授权用户列表 */
|
||||
export function allocatedUserList(query: any): Promise<any> {
|
||||
return request.get(`${BASE}/authUser/allocatedList`, { params: query })
|
||||
}
|
||||
|
||||
/** 查询角色未授权用户列表 */
|
||||
export function unallocatedUserList(query: any): Promise<any> {
|
||||
return request.get(`${BASE}/authUser/unallocatedList`, { params: query })
|
||||
}
|
||||
|
||||
/** 取消用户授权角色 */
|
||||
export function authUserCancel(data: any): Promise<void> {
|
||||
return request.put(`${BASE}/authUser/cancel`, data)
|
||||
}
|
||||
|
||||
/** 批量取消用户授权角色 */
|
||||
export function authUserCancelAll(data: any): Promise<void> {
|
||||
return request.put(`${BASE}/authUser/cancelAll`, data)
|
||||
}
|
||||
|
||||
/** 授权用户选择 */
|
||||
export function authUserSelectAll(data: any): Promise<void> {
|
||||
return request.put(`${BASE}/authUser/selectAll`, data)
|
||||
}
|
||||
123
erp-frontend-vue/src/api/system/user.ts
Normal file
123
erp-frontend-vue/src/api/system/user.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import request from '../request'
|
||||
|
||||
export interface User {
|
||||
userId?: number
|
||||
deptId?: number
|
||||
userName?: string
|
||||
nickName?: string
|
||||
userType?: string
|
||||
email?: string
|
||||
phonenumber?: string
|
||||
sex?: string
|
||||
avatar?: string
|
||||
password?: string
|
||||
status?: string
|
||||
delFlag?: string
|
||||
loginIp?: string
|
||||
loginDate?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
remark?: string
|
||||
dept?: {
|
||||
deptId?: number
|
||||
deptName?: string
|
||||
}
|
||||
roles?: any[]
|
||||
roleIds?: number[]
|
||||
postIds?: number[]
|
||||
}
|
||||
|
||||
export interface UserQuery {
|
||||
userName?: string
|
||||
phonenumber?: string
|
||||
status?: string
|
||||
deptId?: number
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
beginTime?: string
|
||||
endTime?: string
|
||||
}
|
||||
|
||||
export interface UserListResponse {
|
||||
rows: User[]
|
||||
total: number
|
||||
}
|
||||
|
||||
const BASE = '/system/user'
|
||||
|
||||
/** 查询用户列表 */
|
||||
export function listUser(query?: UserQuery): Promise<UserListResponse> {
|
||||
return request.get(`${BASE}/list`, { params: query }).then((res: any) => ({
|
||||
rows: res.rows || [],
|
||||
total: res.total || 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 查询用户详细 */
|
||||
export function getUser(userId?: number): Promise<{
|
||||
data: User
|
||||
roles: any[]
|
||||
posts: any[]
|
||||
postIds: number[]
|
||||
roleIds: number[]
|
||||
}> {
|
||||
return request.get(userId ? `${BASE}/${userId}` : BASE)
|
||||
}
|
||||
|
||||
/** 新增用户 */
|
||||
export function addUser(data: Partial<User>): Promise<void> {
|
||||
return request.post(BASE, data)
|
||||
}
|
||||
|
||||
/** 修改用户 */
|
||||
export function updateUser(data: Partial<User>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除用户 */
|
||||
export function delUser(userId: number | number[]): Promise<void> {
|
||||
const ids = Array.isArray(userId) ? userId.join(',') : String(userId)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 用户密码重置 */
|
||||
export function resetUserPwd(userId: number, password: string): Promise<void> {
|
||||
return request.put(BASE + '/resetPwd', { userId, password })
|
||||
}
|
||||
|
||||
/** 用户状态修改 */
|
||||
export function changeUserStatus(userId: number, status: string): Promise<void> {
|
||||
return request.put(BASE + '/changeStatus', { userId, status })
|
||||
}
|
||||
|
||||
/** 查询用户个人信息 */
|
||||
export function getUserProfile(): Promise<{ data: User }> {
|
||||
return request.get(`${BASE}/profile`)
|
||||
}
|
||||
|
||||
/** 修改用户个人信息 */
|
||||
export function updateUserProfile(data: Partial<User>): Promise<void> {
|
||||
return request.put(`${BASE}/profile`, data)
|
||||
}
|
||||
|
||||
/** 用户密码重置 */
|
||||
export function updateUserPwd(oldPassword: string, newPassword: string): Promise<void> {
|
||||
return request.put(`${BASE}/profile/updatePwd`, { oldPassword, newPassword })
|
||||
}
|
||||
|
||||
/** 用户头像上传 */
|
||||
export function uploadAvatar(data: FormData): Promise<{ imgUrl: string }> {
|
||||
return request.post(`${BASE}/profile/avatar`, data)
|
||||
}
|
||||
|
||||
/** 查询授权角色 */
|
||||
export function getAuthRole(userId: number): Promise<{ user: User; roles: any[] }> {
|
||||
return request.get(`${BASE}/authRole/${userId}`)
|
||||
}
|
||||
|
||||
/** 保存授权角色 */
|
||||
export function updateAuthRole(data: { userId: number; roleIds: string }): Promise<void> {
|
||||
return request.put(`${BASE}/authRole`, data)
|
||||
}
|
||||
222
erp-frontend-vue/src/api/warehouse/issue.ts
Normal file
222
erp-frontend-vue/src/api/warehouse/issue.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
import request from '../request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 生产领料单头 */
|
||||
export interface IssueHeader {
|
||||
issueId?: number
|
||||
issueCode?: string
|
||||
issueName?: string
|
||||
workstationId?: number
|
||||
workstationCode?: string
|
||||
workstationName?: string
|
||||
workorderId?: number
|
||||
workorderCode?: string
|
||||
taskId?: number
|
||||
taskCode?: string
|
||||
clientId?: number
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
clientNick?: string
|
||||
requiredTime?: string
|
||||
issueDate?: string
|
||||
status?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface IssueHeaderQuery {
|
||||
issueCode?: string
|
||||
issueName?: string
|
||||
workorderCode?: string
|
||||
workstationName?: string
|
||||
status?: string
|
||||
beginIssueDate?: string
|
||||
endIssueDate?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 分页响应 */
|
||||
export interface IssueHeaderListResponse {
|
||||
rows: IssueHeader[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// ============ 状态映射 ============
|
||||
|
||||
export const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
'PREPARE': { label: '草稿', type: 'info' },
|
||||
'CONFIRMED': { label: '已确认', type: '' },
|
||||
'APPROVED': { label: '已审核', type: 'success' },
|
||||
'FINISHED': { label: '已完成', type: 'success' }
|
||||
}
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/mes/wm/issueheader'
|
||||
|
||||
/** 查询领料单列表 */
|
||||
export function getIssueHeaderList(params: IssueHeaderQuery): Promise<IssueHeaderListResponse> {
|
||||
return request.get(`${BASE}/list`, { params }).then((res: any) => {
|
||||
const rows = res.rows ?? res.data?.rows ?? []
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取领料单详情 */
|
||||
export function getIssueHeaderDetail(issueId: number): Promise<IssueHeader> {
|
||||
return request.get(`${BASE}/${issueId}`).then((res: any) => {
|
||||
return res.data ?? res
|
||||
})
|
||||
}
|
||||
|
||||
/** 将日期字段规范为 yyyy-MM-dd HH:mm:ss(后端 JsonFormat 要求) */
|
||||
function normalizeDateFields(data: Partial<IssueHeader>): Partial<IssueHeader> {
|
||||
const out = { ...data }
|
||||
if (typeof out.issueDate === 'string' && out.issueDate.length === 10) {
|
||||
out.issueDate = out.issueDate + ' 00:00:00'
|
||||
}
|
||||
if (typeof out.requiredTime === 'string' && out.requiredTime.length === 10) {
|
||||
out.requiredTime = out.requiredTime + ' 00:00:00'
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
/** 新增领料单,返回服务端生成的领料单对象(含 issueId、issueCode) */
|
||||
export function createIssueHeader(data: Partial<IssueHeader>): Promise<IssueHeader> {
|
||||
return request.post(BASE, normalizeDateFields(data)).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 修改领料单 */
|
||||
export function updateIssueHeader(data: Partial<IssueHeader>): Promise<void> {
|
||||
return request.put(BASE, normalizeDateFields(data))
|
||||
}
|
||||
|
||||
/** 删除领料单(支持批量) */
|
||||
export function deleteIssueHeader(ids: number | number[] | string): Promise<void> {
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : String(ids)
|
||||
return request.delete(`${BASE}/${idStr}`)
|
||||
}
|
||||
|
||||
/** 执行出库 */
|
||||
export function executeIssue(issueId: number): Promise<void> {
|
||||
return request.put(`${BASE}/${issueId}`)
|
||||
}
|
||||
|
||||
/** 校验领料数量与明细数量匹配 */
|
||||
export function checkQuantity(issueId: number): Promise<boolean> {
|
||||
return request.get(`${BASE}/checkQuantity/${issueId}`).then((res: any) => {
|
||||
return res.data ?? res
|
||||
})
|
||||
}
|
||||
|
||||
/** 导出领料单 */
|
||||
export function exportIssueHeader(params: IssueHeaderQuery): Promise<Blob> {
|
||||
return request.post(`${BASE}/export`, params, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
// ============ 辅助选择 API ============
|
||||
|
||||
/** 工单列表(选择弹窗) */
|
||||
export function getWorkorderSelectList(params?: {
|
||||
workorderCode?: string
|
||||
workorderName?: string
|
||||
productName?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/pro/workorder/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 物料列表(选择弹窗) */
|
||||
export function getItemSelectList(params?: {
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/md/mditem/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 客户列表(选择弹窗) */
|
||||
export function getClientSelectList(params?: {
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/md/client/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 工作站列表(选择弹窗) */
|
||||
export function getWorkstationSelectList(params?: {
|
||||
workstationCode?: string
|
||||
workstationName?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/md/workstation/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 仓库列表 */
|
||||
export function getWarehouseList(params?: {
|
||||
warehouseCode?: string
|
||||
warehouseName?: string
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/wm/warehouse/list', {
|
||||
params: { pageNum: 1, pageSize: 200, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 库区列表(按仓库筛选) */
|
||||
export function getLocationList(params?: {
|
||||
warehouseId?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/wm/location/list', {
|
||||
params: { pageNum: 1, pageSize: 200, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 库位列表(按库区筛选) */
|
||||
export function getAreaList(params?: {
|
||||
locationId?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/wm/area/list', {
|
||||
params: { pageNum: 1, pageSize: 200, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
69
erp-frontend-vue/src/api/warehouse/issueDetail.ts
Normal file
69
erp-frontend-vue/src/api/warehouse/issueDetail.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import request from '../request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 出库明细 */
|
||||
export interface IssueDetail {
|
||||
detailId?: number
|
||||
issueId?: number
|
||||
lineId?: number
|
||||
materialStockId?: string
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
quantity?: number
|
||||
batchId?: number
|
||||
batchCode?: string
|
||||
warehouseId?: number
|
||||
warehouseCode?: string
|
||||
warehouseName?: string
|
||||
locationId?: number
|
||||
locationCode?: string
|
||||
locationName?: string
|
||||
areaId?: number
|
||||
areaCode?: string
|
||||
areaName?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/mes/wm/issuedetail'
|
||||
|
||||
/** 查询出库明细列表 */
|
||||
export function getIssueDetailList(params: {
|
||||
issueId?: number
|
||||
lineId?: number
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: IssueDetail[]; total: number }> {
|
||||
return request.get(`${BASE}/list`, {
|
||||
params: { pageNum: 1, pageSize: 200, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? res.data?.rows ?? [],
|
||||
total: res.total ?? res.data?.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 新增出库明细 */
|
||||
export function createIssueDetail(data: Partial<IssueDetail>): Promise<number> {
|
||||
return request.post(BASE, data).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 修改出库明细 */
|
||||
export function updateIssueDetail(data: Partial<IssueDetail>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除出库明细(支持批量) */
|
||||
export function deleteIssueDetail(ids: number | number[] | string): Promise<void> {
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : String(ids)
|
||||
return request.delete(`${BASE}/${idStr}`)
|
||||
}
|
||||
59
erp-frontend-vue/src/api/warehouse/issueLine.ts
Normal file
59
erp-frontend-vue/src/api/warehouse/issueLine.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import request from '../request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 领料行 */
|
||||
export interface IssueLine {
|
||||
lineId?: number
|
||||
issueId?: number
|
||||
materialStockId?: number
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
specification?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
quantityIssued?: number
|
||||
quantity?: number
|
||||
batchId?: number
|
||||
batchCode?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/mes/wm/issueline'
|
||||
|
||||
/** 查询领料行列表 */
|
||||
export function getIssueLineList(params: {
|
||||
issueId?: number
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: IssueLine[]; total: number }> {
|
||||
return request.get(`${BASE}/list`, {
|
||||
params: { pageNum: 1, pageSize: 200, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? res.data?.rows ?? [],
|
||||
total: res.total ?? res.data?.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
/** 新增领料行 */
|
||||
export function createIssueLine(data: Partial<IssueLine>): Promise<number> {
|
||||
return request.post(BASE, data).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 修改领料行 */
|
||||
export function updateIssueLine(data: Partial<IssueLine>): Promise<void> {
|
||||
return request.put(BASE, data)
|
||||
}
|
||||
|
||||
/** 删除领料行(支持批量) */
|
||||
export function deleteIssueLine(ids: number | number[] | string): Promise<void> {
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : String(ids)
|
||||
return request.delete(`${BASE}/${idStr}`)
|
||||
}
|
||||
305
erp-frontend-vue/src/api/workOrder.ts
Normal file
305
erp-frontend-vue/src/api/workOrder.ts
Normal file
@@ -0,0 +1,305 @@
|
||||
import request from './request'
|
||||
|
||||
// ============ 类型定义 ============
|
||||
|
||||
/** 生产工单 BOM 物料行 */
|
||||
export interface WorkOrderBom {
|
||||
lineId?: number
|
||||
workorderId?: number
|
||||
itemId?: number
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
itemSpc?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
itemOrProduct?: string
|
||||
quantity?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
/** 生产工单主表 */
|
||||
export interface WorkOrder {
|
||||
workorderId?: number
|
||||
workorderCode?: string
|
||||
workorderName?: string
|
||||
workorderType?: string
|
||||
orderSource?: string
|
||||
sourceCode?: string
|
||||
productId?: number
|
||||
productCode?: string
|
||||
productName?: string
|
||||
productSpc?: string
|
||||
unitOfMeasure?: string
|
||||
unitName?: string
|
||||
routeId?: number
|
||||
routeCode?: string
|
||||
routeName?: string
|
||||
batchCode?: string
|
||||
quantity?: number
|
||||
quantityProduced?: number
|
||||
quantityChanged?: number
|
||||
quantityScheduled?: number
|
||||
clientId?: number
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
vendorId?: number
|
||||
vendorCode?: string
|
||||
vendorName?: string
|
||||
productionDate?: string // 前端字段名,映射到后端 requestDate
|
||||
requestDate?: string // 后端实际字段名(数据库列 request_date)
|
||||
finishDate?: string
|
||||
cancelDate?: string
|
||||
parentId?: number
|
||||
ancestors?: string
|
||||
status?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
// v3.1 新增字段
|
||||
orderDate?: string // 单据日期
|
||||
businessType?: string // 业务类型
|
||||
businessStatus?: string // 业务状态
|
||||
operatorName?: string // 操作员
|
||||
approverName?: string // 审核员
|
||||
approveDate?: string // 审核日期
|
||||
salesOrderCode?: string // 跟单编号(销售订单号)
|
||||
deliveryDate?: string // 订单交期
|
||||
drawingNo?: string // 图纸号
|
||||
productionLine?: string // 生产线
|
||||
processTime?: number // 加工时长(分钟)
|
||||
qualityReq?: string // 质量要求
|
||||
}
|
||||
|
||||
/** 查询参数 */
|
||||
export interface WorkOrderQuery {
|
||||
workorderCode?: string
|
||||
workorderName?: string
|
||||
workorderType?: string
|
||||
sourceCode?: string
|
||||
productCode?: string
|
||||
productName?: string
|
||||
status?: string
|
||||
beginProductionDate?: string // 前端用,映射到后端 beginRequestDate
|
||||
endProductionDate?: string // 前端用,映射到后端 endRequestDate
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
/** 分页响应 */
|
||||
export interface WorkOrderListResponse {
|
||||
rows: WorkOrder[]
|
||||
total: number
|
||||
}
|
||||
|
||||
// ============ 状态映射 ============
|
||||
|
||||
export const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
'PREPARE': { label: '草稿', type: 'info' },
|
||||
'CONFIRMED': { label: '已确认', type: '' },
|
||||
'APPROVED': { label: '已审核', type: 'success' },
|
||||
'FINISHED': { label: '已完成', type: 'success' },
|
||||
'CANCELED': { label: '已取消', type: 'danger' }
|
||||
}
|
||||
|
||||
export const WORKORDER_TYPE_OPTIONS = [
|
||||
{ value: 'SELF', label: '自产' },
|
||||
{ value: 'OUTSOURCE', label: '委外' },
|
||||
{ value: 'PROCESSING', label: '加工车间' }
|
||||
]
|
||||
|
||||
export const BUSINESS_STATUS_OPTIONS = [
|
||||
{ value: 'NORMAL', label: '正常' },
|
||||
{ value: 'PAUSE', label: '暂停' },
|
||||
{ value: 'CANCEL', label: '取消' }
|
||||
]
|
||||
|
||||
// ============ API 接口 ============
|
||||
|
||||
const BASE = '/mes/pro/workorder'
|
||||
|
||||
/** 查询生产工单列表 */
|
||||
export function getWorkOrderList(params: WorkOrderQuery): Promise<WorkOrderListResponse> {
|
||||
// 将前端日期查询参数映射为后端字段名
|
||||
const backendParams: Record<string, any> = { ...params }
|
||||
if (backendParams.beginProductionDate) {
|
||||
backendParams.beginRequestDate = backendParams.beginProductionDate
|
||||
delete backendParams.beginProductionDate
|
||||
}
|
||||
if (backendParams.endProductionDate) {
|
||||
backendParams.endRequestDate = backendParams.endProductionDate
|
||||
delete backendParams.endProductionDate
|
||||
}
|
||||
return request.get(`${BASE}/list`, { params: backendParams }).then((res: any) => {
|
||||
const rows = (res.rows ?? res.data?.rows ?? []).map((row: any) => {
|
||||
// 后端返回 requestDate,前端显示用 productionDate
|
||||
if (row.requestDate && !row.productionDate) {
|
||||
row.productionDate = row.requestDate
|
||||
}
|
||||
return row
|
||||
})
|
||||
const total = res.total ?? res.data?.total ?? 0
|
||||
return { rows, total }
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取生产工单详情 */
|
||||
export function getWorkOrderDetail(workorderId: number): Promise<WorkOrder> {
|
||||
return request.get(`${BASE}/${workorderId}`).then((res: any) => {
|
||||
const data = res.data ?? res
|
||||
// 后端返回 requestDate,前端用 productionDate
|
||||
if (data.requestDate && !data.productionDate) {
|
||||
data.productionDate = data.requestDate
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
/** 将前端字段名映射为后端字段名 */
|
||||
function toBackendPayload(data: Partial<WorkOrder>): Record<string, any> {
|
||||
const payload: Record<string, any> = { ...data }
|
||||
// 前端用 productionDate,后端用 requestDate
|
||||
if (payload.productionDate !== undefined) {
|
||||
payload.requestDate = payload.productionDate
|
||||
delete payload.productionDate
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
/** 新增生产工单 */
|
||||
export function createWorkOrder(data: Partial<WorkOrder>): Promise<number> {
|
||||
return request.post(BASE, toBackendPayload(data)).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 修改生产工单 */
|
||||
export function updateWorkOrder(data: Partial<WorkOrder>): Promise<void> {
|
||||
return request.put(BASE, toBackendPayload(data))
|
||||
}
|
||||
|
||||
/** 删除生产工单(支持批量) */
|
||||
export function deleteWorkOrder(workorderIds: number | number[] | string): Promise<void> {
|
||||
const ids = Array.isArray(workorderIds) ? workorderIds.join(',') : String(workorderIds)
|
||||
return request.delete(`${BASE}/${ids}`)
|
||||
}
|
||||
|
||||
/** 完工工单 */
|
||||
export function finishWorkOrder(workorderId: number): Promise<void> {
|
||||
return request.put(`${BASE}/finish/${workorderId}`)
|
||||
}
|
||||
|
||||
/** 取消工单 */
|
||||
export function cancelWorkOrder(workorderId: number): Promise<void> {
|
||||
return request.put(`${BASE}/cancel/${workorderId}`)
|
||||
}
|
||||
|
||||
/** 获取工单 BOM 组成列表(直接查 pro_workorder_bom 表,字段名直接对应) */
|
||||
export function getWorkOrderBomList(workorderId: number): Promise<WorkOrderBom[]> {
|
||||
return request.get('/mes/pro/workorderbom/list', {
|
||||
params: { workorderId, pageNum: 1, pageSize: 500 }
|
||||
}).then((res: any) => {
|
||||
return res.rows ?? res.data?.rows ?? []
|
||||
})
|
||||
}
|
||||
|
||||
/** 导出生产工单 */
|
||||
export function exportWorkOrder(params: WorkOrderQuery): Promise<Blob> {
|
||||
return request.post(`${BASE}/export`, params, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
/** 一键领料:根据工单 BOM 自动创建领料单,返回领料单 ID */
|
||||
export function quickIssue(workorderId: number): Promise<number> {
|
||||
return request.post(`${BASE}/quickIssue/${workorderId}`).then((res: any) => res.data ?? res)
|
||||
}
|
||||
|
||||
/** 审核工单(确认):PREPARE → CONFIRMED */
|
||||
export function confirmWorkOrder(workorderId: number): Promise<void> {
|
||||
return request.put(`${BASE}/confirm/${workorderId}`)
|
||||
}
|
||||
|
||||
/** 反审核工单:CONFIRMED → PREPARE */
|
||||
export function unconfirmWorkOrder(workorderId: number): Promise<void> {
|
||||
return request.put(`${BASE}/unconfirm/${workorderId}`)
|
||||
}
|
||||
|
||||
/** 查询工单关联的领料明细列表 */
|
||||
export function getIssueListByWorkorder(workorderId: number): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/wm/issueheader/list', {
|
||||
params: { workorderId, pageNum: 1, pageSize: 100 }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
// ============ 工序任务(ProTask)API ============
|
||||
|
||||
/** 工序任务 */
|
||||
export interface ProTask {
|
||||
taskId?: number
|
||||
taskCode?: string
|
||||
taskName?: string
|
||||
workorderId?: number
|
||||
workorderCode?: string
|
||||
processId?: number
|
||||
processCode?: string
|
||||
processName?: string
|
||||
quantity?: number
|
||||
quantityProduced?: number
|
||||
quantityQuanlified?: number
|
||||
quantityUnquanlified?: number
|
||||
startTime?: string
|
||||
duration?: number
|
||||
endTime?: string
|
||||
colorCode?: string
|
||||
status?: string
|
||||
remark?: string
|
||||
createBy?: string
|
||||
createTime?: string
|
||||
updateBy?: string
|
||||
updateTime?: string
|
||||
}
|
||||
|
||||
/** 根据工单 ID 获取工序任务列表 */
|
||||
export function getTaskListByWorkorder(workorderId: number): Promise<ProTask[]> {
|
||||
return request.get('/mes/pro/protask/list', {
|
||||
params: { workorderId, pageNum: 1, pageSize: 500 }
|
||||
}).then((res: any) => {
|
||||
return res.rows ?? res.data?.rows ?? []
|
||||
})
|
||||
}
|
||||
|
||||
// ============ 工艺路线选择 API ============
|
||||
|
||||
/** 工艺路线列表(选择弹窗,不默认过滤 enableFlag 以避免列表为空) */
|
||||
export function getRouteList(params?: {
|
||||
routeCode?: string
|
||||
routeName?: string
|
||||
enableFlag?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/pro/proroute/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
|
||||
// ============ 客户选择 API(备用) ============
|
||||
|
||||
/** 客户列表(选择弹窗) */
|
||||
export function getClientList(params?: {
|
||||
clientCode?: string
|
||||
clientName?: string
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
}): Promise<{ rows: any[]; total: number }> {
|
||||
return request.get('/mes/md/client/list', {
|
||||
params: { pageNum: 1, pageSize: 100, ...params }
|
||||
}).then((res: any) => ({
|
||||
rows: res.rows ?? [],
|
||||
total: res.total ?? 0
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user