feat: edit collaboration remarks across order loading
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
approvePlatformUnifiedOrder,
|
||||
batchApprovePlatformUnifiedOrders,
|
||||
getPlatformUnifiedOrderBatchApprovalPreview,
|
||||
addPlatformUnifiedOrderNote,
|
||||
updatePlatformUnifiedOrderRemarks,
|
||||
getPlatformUnifiedOrder,
|
||||
downloadPlatformProductImage,
|
||||
listPlatformUnifiedOrders,
|
||||
@@ -172,10 +172,11 @@ describe('unified orders API contract', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('writes platform internal notes through the unified order boundary', async () => {
|
||||
vi.mocked(http.post).mockResolvedValue({ data: '91001' })
|
||||
await expect(addPlatformUnifiedOrderNote('208', '90001', '已确认船期')).resolves.toBe('91001')
|
||||
expect(http.post).toHaveBeenCalledWith('/platform/v1/orders/90001/internal-notes', { content: '已确认船期' }, { params: { tenantId: '208' } })
|
||||
it('updates the three editable remarks while keeping customer remark outside the request', async () => {
|
||||
const request = { expectedVersion: 7, internalRemark: '内部', warehouseRemark: '仓库', customerServiceRemark: '客服' }
|
||||
vi.mocked(http.put).mockResolvedValue({ data: { ...request, version: 8, customerRemark: '客户只读' } })
|
||||
await expect(updatePlatformUnifiedOrderRemarks('208', '90001', request)).resolves.toMatchObject({ version: 8 })
|
||||
expect(http.put).toHaveBeenCalledWith('/platform/v1/orders/90001/remarks', request, { params: { tenantId: '208' } })
|
||||
})
|
||||
|
||||
it('updates customer declaration fields through the versioned tenant-scoped contract', async () => {
|
||||
|
||||
@@ -160,6 +160,8 @@ export interface UnifiedOrderResource {
|
||||
customerRemark?: string | null
|
||||
latestInternalNote?: string | null
|
||||
internalRemark?: string | null
|
||||
warehouseRemark?: string | null
|
||||
customerServiceRemark?: string | null
|
||||
createdBy?: string | null
|
||||
}
|
||||
|
||||
@@ -599,10 +601,25 @@ export function batchApprovePlatformUnifiedOrders(tenantId: string, items: Unifi
|
||||
).then(unwrapApiResponse)
|
||||
}
|
||||
|
||||
export function addPlatformUnifiedOrderNote(tenantId: string, orderId: string, content: string) {
|
||||
return http.post<ApiEnvelope<number | string>, ApiEnvelope<number | string>>(
|
||||
`${unifiedOrdersApiPath}/${orderId}/internal-notes`,
|
||||
{ content },
|
||||
export interface UnifiedOrderRemarksUpdateRequest {
|
||||
expectedVersion: number
|
||||
internalRemark: string | null
|
||||
warehouseRemark: string | null
|
||||
customerServiceRemark: string | null
|
||||
}
|
||||
|
||||
export interface UnifiedOrderRemarksUpdateResponse {
|
||||
version: number
|
||||
customerRemark: string | null
|
||||
internalRemark: string | null
|
||||
warehouseRemark: string | null
|
||||
customerServiceRemark: string | null
|
||||
}
|
||||
|
||||
export function updatePlatformUnifiedOrderRemarks(tenantId: string, orderId: string, request: UnifiedOrderRemarksUpdateRequest) {
|
||||
return http.put<ApiEnvelope<UnifiedOrderRemarksUpdateResponse>, ApiEnvelope<UnifiedOrderRemarksUpdateResponse>>(
|
||||
`${unifiedOrdersApiPath}/${orderId}/remarks`,
|
||||
request,
|
||||
{ params: { tenantId } },
|
||||
).then(unwrapApiResponse)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ vi.mock('@/modules/warehouses', () => ({ listAllPlatformWarehouses: vi.fn().mock
|
||||
vi.mock('@/modules/inbounds', () => ({ downloadWeightImage: vi.fn(), getInboundMeasurement: vi.fn() }))
|
||||
vi.mock('@/modules/unified-orders/workflows', () => ({ UnifiedOrderWorkflowPanel: { template: '<div />' } }))
|
||||
vi.mock('@/modules/unified-orders/api/unifiedOrders', () => ({
|
||||
addPlatformUnifiedOrderNote: vi.fn(), approvePlatformUnifiedOrder: vi.fn(), batchApprovePlatformUnifiedOrders: vi.fn(),
|
||||
updatePlatformUnifiedOrderRemarks: vi.fn(), approvePlatformUnifiedOrder: vi.fn(), batchApprovePlatformUnifiedOrders: vi.fn(),
|
||||
getPlatformUnifiedOrder: vi.fn(), listPlatformUnifiedOrderFeeDetails: vi.fn(), listPlatformUnifiedOrders: vi.fn(),
|
||||
unifiedOrderStatusOptions: [{ value: 'WAIT_SPLIT', label: '待分柜' }],
|
||||
}))
|
||||
|
||||
@@ -26,7 +26,7 @@ vi.mock('@/shared/api/inboundCodeRelations', () => ({
|
||||
getLoadingAssociationSummary: vi.fn(), getOverseasInboundCodeRelationship: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/modules/unified-orders/api/unifiedOrders', () => ({
|
||||
addPlatformUnifiedOrderNote: vi.fn(), approvePlatformUnifiedOrder: vi.fn(), batchApprovePlatformUnifiedOrders: vi.fn(),
|
||||
updatePlatformUnifiedOrderRemarks: vi.fn(), approvePlatformUnifiedOrder: vi.fn(), batchApprovePlatformUnifiedOrders: vi.fn(),
|
||||
downloadPlatformProductImage: vi.fn(),
|
||||
getPlatformUnifiedOrder: vi.fn(), listPlatformUnifiedOrderFeeDetails: vi.fn(), listPlatformUnifiedOrders: vi.fn(),
|
||||
unifiedOrderStatusOptions: [],
|
||||
|
||||
@@ -24,7 +24,7 @@ vi.mock('@/modules/unified-orders/api/coLoadGroups', () => ({
|
||||
getPlatformCoLoadGroupByInboundCode: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/modules/unified-orders/api/unifiedOrders', () => ({
|
||||
addPlatformUnifiedOrderNote: vi.fn(),
|
||||
updatePlatformUnifiedOrderRemarks: vi.fn(),
|
||||
approvePlatformUnifiedOrder: vi.fn(),
|
||||
getPlatformUnifiedOrder: vi.fn(),
|
||||
listPlatformUnifiedOrderFeeDetails: vi.fn(),
|
||||
|
||||
@@ -375,6 +375,16 @@ describe('UnifiedOrdersView contract', () => {
|
||||
expect(source).not.toContain("value.replaceAll('_', ' ')")
|
||||
})
|
||||
|
||||
it('keeps customer remarks read-only and edits the three collaboration remarks together', () => {
|
||||
expect(source).toContain('title="编辑订单备注"')
|
||||
expect(source).toContain('label="客户备注(只读)"')
|
||||
expect(source).toContain(':model-value="noteOrder?.customerRemark')
|
||||
expect(source).toContain('v-model="noteForm.internalRemark"')
|
||||
expect(source).toContain('v-model="noteForm.warehouseRemark"')
|
||||
expect(source).toContain('v-model="noteForm.customerServiceRemark"')
|
||||
expect(source).toContain('await updatePlatformUnifiedOrderRemarks')
|
||||
})
|
||||
|
||||
it('keeps the customer order package count independent from measured inbound totals', () => {
|
||||
expect(source).toContain("{ source: '客户下单数据', count: customerTotals.count")
|
||||
expect(source).not.toContain("{ source: '客户下单数据', count: summary?.totalPackageCount")
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
approvePlatformUnifiedOrder,
|
||||
batchApprovePlatformUnifiedOrders,
|
||||
getPlatformUnifiedOrderBatchApprovalPreview,
|
||||
addPlatformUnifiedOrderNote,
|
||||
updatePlatformUnifiedOrderRemarks,
|
||||
listPlatformUnifiedOrders,
|
||||
updatePlatformUnifiedOrderPlanning,
|
||||
unifiedOrderStatusOptions,
|
||||
@@ -179,7 +179,7 @@ const coLoadError = ref<ApiErrorDetails | null>(null)
|
||||
const approvalOrder = ref<UnifiedOrderResource | null>(null)
|
||||
const noteOpen = ref(false)
|
||||
const noteSaving = ref(false)
|
||||
const noteContent = ref('')
|
||||
const noteForm = reactive({ internalRemark: '', warehouseRemark: '', customerServiceRemark: '' })
|
||||
const noteOrder = ref<UnifiedOrderResource | null>(null)
|
||||
const holdDetail = ref<InboundHoldDetail | null>(null)
|
||||
const holdLoading = ref(false)
|
||||
@@ -1360,27 +1360,30 @@ function openNoteDialog(order?: UnifiedOrderResource) {
|
||||
const target = order || detail.value?.summary || null
|
||||
if (!target) return
|
||||
noteOrder.value = target
|
||||
noteContent.value = ''
|
||||
noteForm.internalRemark = target.latestInternalNote || target.internalRemark || ''
|
||||
noteForm.warehouseRemark = target.warehouseRemark || ''
|
||||
noteForm.customerServiceRemark = target.customerServiceRemark || ''
|
||||
noteOpen.value = true
|
||||
}
|
||||
|
||||
async function saveNote() {
|
||||
const content = noteContent.value.trim()
|
||||
if (!noteOrder.value || !content) {
|
||||
ElMessage.warning('请填写内部备注')
|
||||
return
|
||||
}
|
||||
if (!noteOrder.value) return
|
||||
noteSaving.value = true
|
||||
try {
|
||||
const target = noteOrder.value
|
||||
await addPlatformUnifiedOrderNote(String(target.tenantId), String(target.orderId), content)
|
||||
await updatePlatformUnifiedOrderRemarks(String(target.tenantId), String(target.orderId), {
|
||||
expectedVersion: Number(target.orderVersion || 0),
|
||||
internalRemark: noteForm.internalRemark.trim() || null,
|
||||
warehouseRemark: noteForm.warehouseRemark.trim() || null,
|
||||
customerServiceRemark: noteForm.customerServiceRemark.trim() || null,
|
||||
})
|
||||
noteOpen.value = false
|
||||
await loadOrders()
|
||||
if (detail.value?.summary.orderId === target.orderId) await loadDetail(true)
|
||||
noteOrder.value = null
|
||||
ElMessage.success('内部备注已保存')
|
||||
ElMessage.success('订单备注已保存')
|
||||
} catch (error) {
|
||||
ElMessage.error(getApiErrorDetails(error, '内部备注保存失败,请稍后重试').message)
|
||||
ElMessage.error(getApiErrorDetails(error, '订单备注保存失败,请稍后重试').message)
|
||||
} finally {
|
||||
noteSaving.value = false
|
||||
}
|
||||
@@ -2725,8 +2728,13 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
</AppDrawer>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="noteOpen" title="添加内部备注" confirm-text="保存备注" :confirm-loading="noteSaving" @confirm="saveNote">
|
||||
<el-input v-model="noteContent" type="textarea" :rows="5" maxlength="2000" show-word-limit placeholder="请输入仅平台内部可见的备注" aria-label="内部备注内容" />
|
||||
<AppDialog class="admin-density-dialog" v-model="noteOpen" title="编辑订单备注" width="min(680px, calc(100vw - 28px))" confirm-text="保存备注" :confirm-loading="noteSaving" @confirm="saveNote">
|
||||
<el-form label-position="top" class="order-remarks-form">
|
||||
<el-form-item label="客户备注(只读)"><el-input :model-value="noteOrder?.customerRemark || '—'" disabled /></el-form-item>
|
||||
<el-form-item label="内部备注"><el-input v-model="noteForm.internalRemark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="可填写、修改或清空内部备注" /></el-form-item>
|
||||
<el-form-item label="仓库备注"><el-input v-model="noteForm.warehouseRemark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="可填写、修改或清空仓库备注" /></el-form-item>
|
||||
<el-form-item label="客服备注"><el-input v-model="noteForm.customerServiceRemark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="可填写、修改或清空客服备注" /></el-form-item>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="holdDialogOpen" :title="holdAction === 'HOLD' ? '确认扣货' : '确认解除扣货'" :confirm-text="holdAction === 'HOLD' ? '确认扣货' : '确认解除'" :confirm-type="holdAction === 'HOLD' ? 'danger' : 'primary'" :confirm-loading="holdSaving" :confirm-disabled="!holdReason.trim() || holdReason.trim().length > 1000" width="min(600px, calc(100vw - 28px))" destroy-on-close @confirm="submitHoldAction">
|
||||
|
||||
Reference in New Issue
Block a user