325 lines
9.1 KiB
TypeScript
325 lines
9.1 KiB
TypeScript
/**
|
|
* 合同管理 API(门户 http + Java 对齐 GET/PUT/DELETE 语义)
|
|
*/
|
|
import request from '@/utils/http'
|
|
import type { ContractForm, ContractQuery, ContractVO } from './types'
|
|
|
|
const BASE = '/web/crm/contract'
|
|
|
|
function unwrapData(res: any) {
|
|
return res?.data ?? res ?? {}
|
|
}
|
|
|
|
function mapListQuery(query: ContractQuery = {}): Record<string, any> {
|
|
const params: Record<string, any> = {
|
|
pageNum: query.pageNum ?? 1,
|
|
pageSize: query.pageSize ?? 20
|
|
}
|
|
const fields: (keyof ContractQuery)[] = [
|
|
'contractNo',
|
|
'contractName',
|
|
'customerName',
|
|
'contractType',
|
|
'status',
|
|
'excludeStatus',
|
|
'approvalStatus',
|
|
'minAmount',
|
|
'maxAmount',
|
|
'signDateBegin',
|
|
'signDateEnd',
|
|
'beginTime',
|
|
'endTime'
|
|
]
|
|
fields.forEach((key) => {
|
|
const val = query[key]
|
|
if (val != null && val !== '') params[key] = val
|
|
})
|
|
;['customerId', 'opportunityId', 'quoteId', 'ownerUserId', 'approvedByUserId', 'pendingApprovalUserId'].forEach(
|
|
(key) => {
|
|
const val = (query as any)[key]
|
|
if (val != null && val !== '') params[key] = String(val)
|
|
}
|
|
)
|
|
return params
|
|
}
|
|
|
|
function stringifyIds(ids: number | number[] | string | string[]) {
|
|
return Array.isArray(ids) ? ids.map(String).join(',') : String(ids)
|
|
}
|
|
|
|
function stringifyBody(data: Record<string, any>) {
|
|
const body = { ...data }
|
|
;[
|
|
'id',
|
|
'customerId',
|
|
'opportunityId',
|
|
'quoteId',
|
|
'parentContractId',
|
|
'templateId',
|
|
'contactId',
|
|
'ownerUserId',
|
|
'supplierId',
|
|
'productId',
|
|
'contractId'
|
|
].forEach((key) => {
|
|
if (body[key] != null) body[key] = String(body[key])
|
|
})
|
|
if (body.ids) body.ids = (body.ids as any[]).map(String)
|
|
if (body.approverIds) body.approverIds = (body.approverIds as any[]).map(String)
|
|
if (body.products && Array.isArray(body.products)) {
|
|
body.products = body.products.map((p: Record<string, any>) => ({
|
|
...p,
|
|
id: p.id != null ? String(p.id) : undefined,
|
|
productId: p.productId != null ? String(p.productId) : undefined,
|
|
categoryId: p.categoryId != null ? String(p.categoryId) : undefined,
|
|
contractId: p.contractId != null ? String(p.contractId) : undefined
|
|
}))
|
|
}
|
|
return body
|
|
}
|
|
|
|
export async function listContract(query?: ContractQuery) {
|
|
const res = await request.get({ url: `${BASE}/list`, params: mapListQuery(query) })
|
|
const data = unwrapData(res)
|
|
return { rows: data.list || data.rows || [], total: data.total ?? 0 }
|
|
}
|
|
|
|
export async function getContract(id: number | string) {
|
|
const data = await request.get({ url: `${BASE}/${String(id)}` })
|
|
return { data: unwrapData(data) as ContractVO }
|
|
}
|
|
|
|
export function addContract(data: ContractForm) {
|
|
return request.post({ url: BASE, data: stringifyBody(data as Record<string, any>) })
|
|
}
|
|
|
|
export function updateContract(data: ContractForm) {
|
|
return request.put({ url: BASE, data: stringifyBody(data as Record<string, any>) })
|
|
}
|
|
|
|
export function delContract(ids: number | number[] | string | string[]) {
|
|
return request.del({ url: `${BASE}/${stringifyIds(ids)}` })
|
|
}
|
|
|
|
export function submitApproval(data: { id: number | string; approverIds: (number | string)[]; remark?: string }) {
|
|
return request.put({
|
|
url: `${BASE}/submitApproval`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function batchSubmitApproval(data: {
|
|
ids: (number | string)[]
|
|
approverIds: (number | string)[]
|
|
remark?: string
|
|
}) {
|
|
return request.put({
|
|
url: `${BASE}/batchSubmitApproval`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function saveTemplate(
|
|
id: number | string,
|
|
templateContent: string,
|
|
settlementClauseDrafts?: string
|
|
) {
|
|
return request.post({
|
|
url: `${BASE}/saveTemplate`,
|
|
data: { id: String(id), templateContent, settlementClauseDrafts }
|
|
})
|
|
}
|
|
|
|
export async function getTemplate(id: number | string) {
|
|
const data = await request.get({ url: `${BASE}/getTemplate/${String(id)}` })
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export function withdrawApproval(data: { id: number | string; remark?: string }) {
|
|
return request.put({
|
|
url: `${BASE}/withdrawApproval`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function startExecute(data: { id: number | string; remark?: string }) {
|
|
return request.put({
|
|
url: `${BASE}/startExecute`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function finishContract(data: { id: number | string; remark?: string }) {
|
|
return request.put({
|
|
url: `${BASE}/finish`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function invalidContract(data: { id: number | string; invalidReason: string; remark?: string }) {
|
|
return request.put({
|
|
url: `${BASE}/invalid`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function uploadFile(data: { id: number | string; fileUrl: string }) {
|
|
return request.post({
|
|
url: `${BASE}/uploadFile`,
|
|
data: { id: String(data.id), fileUrl: data.fileUrl }
|
|
})
|
|
}
|
|
|
|
export function uploadAttachments(data: {
|
|
id: number | string
|
|
attachments?: Array<{ ossId: string; category: string }>
|
|
ossIds?: string
|
|
}) {
|
|
return request.post({
|
|
url: `${BASE}/uploadAttachments`,
|
|
data: { ...data, id: String(data.id) }
|
|
})
|
|
}
|
|
|
|
export async function exportContract(query?: ContractQuery) {
|
|
return request.post({
|
|
url: `${BASE}/export`,
|
|
data: mapListQuery(query),
|
|
responseType: 'blob'
|
|
})
|
|
}
|
|
|
|
export async function getStatisticsOverview(params?: {
|
|
ownerUserId?: number | string
|
|
beginTime?: string
|
|
endTime?: string
|
|
}) {
|
|
const data = await request.get({
|
|
url: `${BASE}/statistics/overview`,
|
|
params: {
|
|
ownerUserId: params?.ownerUserId != null ? String(params.ownerUserId) : undefined,
|
|
beginTime: params?.beginTime,
|
|
endTime: params?.endTime
|
|
}
|
|
})
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export async function getStatisticsByStatus() {
|
|
const data = await request.get({ url: `${BASE}/statistics/status` })
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export async function getStatisticsByType() {
|
|
const data = await request.get({ url: `${BASE}/statistics/type` })
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export async function getStatisticsTrend(params?: { type?: string; beginTime?: string; endTime?: string }) {
|
|
const data = await request.get({
|
|
url: `${BASE}/statistics/trend`,
|
|
params: params || {}
|
|
})
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export async function getExpiringContracts(params?: { days?: number }) {
|
|
const data = await request.get({
|
|
url: `${BASE}/statistics/expiring`,
|
|
params: params || {}
|
|
})
|
|
return { data: unwrapData(data) }
|
|
}
|
|
|
|
export function renewContract(parentContractId: number | string, data: ContractForm) {
|
|
return request.post({
|
|
url: `${BASE}/renew/${String(parentContractId)}`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function createFromOpportunity(opportunityId: number | string, data: ContractForm) {
|
|
return request.post({
|
|
url: `${BASE}/createFromOpportunity/${String(opportunityId)}`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function createFromQuote(quoteId: number | string, data: ContractForm) {
|
|
return request.post({
|
|
url: `${BASE}/createFromQuote/${String(quoteId)}`,
|
|
data: stringifyBody(data as Record<string, any>)
|
|
})
|
|
}
|
|
|
|
export function submitContract(id: number | string, approverIds: (number | string)[], remark?: string) {
|
|
return submitApproval({ id, approverIds, remark })
|
|
}
|
|
|
|
export function batchSubmitContract(ids: (number | string)[], approverIds: (number | string)[], remark?: string) {
|
|
return batchSubmitApproval({ ids, approverIds, remark })
|
|
}
|
|
|
|
export function approveContract(id: number | string, comment: string) {
|
|
return request.post({
|
|
url: `${BASE}/approval`,
|
|
data: {
|
|
id: String(id),
|
|
approvalResult: 'approved',
|
|
approvalOpinion: comment,
|
|
remark: comment
|
|
}
|
|
})
|
|
}
|
|
|
|
export function rejectContract(id: number | string, comment: string) {
|
|
return request.post({
|
|
url: `${BASE}/approval`,
|
|
data: {
|
|
id: String(id),
|
|
approvalResult: 'rejected',
|
|
approvalOpinion: comment,
|
|
remark: comment
|
|
}
|
|
})
|
|
}
|
|
|
|
export function withdrawContract(id: number | string, reason: string) {
|
|
return withdrawApproval({ id, remark: reason })
|
|
}
|
|
|
|
export async function listContractApproval(contractId: number | string) {
|
|
const data = await request.get({ url: `${BASE}/approval/flow/${String(contractId)}` })
|
|
const unwrapped = unwrapData(data)
|
|
return { data: unwrapped.list || unwrapped.rows || unwrapped || [] }
|
|
}
|
|
|
|
export function executeContract(
|
|
id: number | string,
|
|
_executeStartDate: string,
|
|
_expectedEndDate?: string,
|
|
remark?: string
|
|
) {
|
|
return startExecute({ id, remark })
|
|
}
|
|
|
|
export function completeContract(
|
|
id: number | string,
|
|
_actualEndDate: string,
|
|
completeRemark: string,
|
|
_satisfaction?: number
|
|
) {
|
|
return finishContract({ id, remark: completeRemark })
|
|
}
|
|
|
|
export async function listContractOperLog(_contractId: number | string) {
|
|
const res = await request.post({
|
|
url: '/web/monitor/operlog/list',
|
|
data: { title: '合同管理', pageNum: 1, pageSize: 100 }
|
|
})
|
|
const data = unwrapData(res)
|
|
return { rows: data.list || data.rows || [], total: data.total ?? 0 }
|
|
}
|
|
|
|
export * from './types'
|