提交
This commit is contained in:
@@ -5,6 +5,7 @@ import { ArrowLeft, Plus, Trash2 } from '@lucide/vue'
|
||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||
import { useAuthStore } from '@/modules/auth/public'
|
||||
import { useUnsavedWorkRegistration } from '@/navigation/workspace-tabs/unsavedWork'
|
||||
import { createIdempotencyKey } from '@/utils/idempotencyKey'
|
||||
import { createDeliveryOrder, type DeliveryOrderFee, type DeliveryTransferPayload } from '../api/deliveryOrders'
|
||||
|
||||
type DeliveryCreateForm = Omit<DeliveryTransferPayload, 'idempotencyKey'>
|
||||
@@ -112,7 +113,7 @@ async function submit() {
|
||||
submitError.value = ''
|
||||
const valid = await formRef.value?.validate().catch(() => false)
|
||||
if (!valid || !validateFees()) return
|
||||
if (!pendingIdempotencyKey) pendingIdempotencyKey = crypto.randomUUID()
|
||||
if (!pendingIdempotencyKey) pendingIdempotencyKey = createIdempotencyKey()
|
||||
submitting.value = true
|
||||
try {
|
||||
const created = await createDeliveryOrder(requestPayload())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { overseasApiRequest, overseasBlobRequest } from '@/api/overseasHttp'
|
||||
import { createIdempotencyKey } from '@/utils/idempotencyKey'
|
||||
|
||||
export type RelabelDeliveryMethod = 'TRUCK' | 'EXPRESS' | 'TRUCK_PICKUP' | 'EXPRESS_PICKUP'
|
||||
|
||||
@@ -78,7 +79,7 @@ export function getRelabel(relabelNo: string) {
|
||||
return overseasApiRequest<RelabelDetail>({ method: 'GET', url: `/merchant/v1/last-leg/relabel-applications/${encodeURIComponent(relabelNo)}` })
|
||||
}
|
||||
export function confirmTransferMeasurement(transferNo: string, remark?: string) {
|
||||
return overseasApiRequest<Record<string, unknown>>({ method: 'POST', url: `/merchant/v1/last-leg/warehouse-transfers/${encodeURIComponent(transferNo)}/confirm-measurement`, data: { idempotencyKey: crypto.randomUUID(), remark } })
|
||||
return overseasApiRequest<Record<string, unknown>>({ method: 'POST', url: `/merchant/v1/last-leg/warehouse-transfers/${encodeURIComponent(transferNo)}/confirm-measurement`, data: { idempotencyKey: createIdempotencyKey(), remark } })
|
||||
}
|
||||
export interface TransferCartonLabel { transferNo: string; cartons: Array<{ cartonMark: string; customerCartonMark?: string; cartonIndex: number; totalCartons: number; status: string }>; printableHtml: string }
|
||||
export function getTransferCartonLabel(transferNo: string) {
|
||||
@@ -109,7 +110,7 @@ export function uploadRelabelFile(relabelNo: string, scope: 'CARTON_TOTAL' | 'SK
|
||||
return overseasApiRequest<RelabelDetail>({ method: 'POST', url: `/merchant/v1/last-leg/relabel-applications/${encodeURIComponent(relabelNo)}/files`, params: { scope, itemId }, data, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
}
|
||||
export function confirmRelabelCompletion(relabelNo: string, remark?: string) {
|
||||
return overseasApiRequest<RelabelDetail>({ method: 'POST', url: `/merchant/v1/last-leg/relabel-applications/${encodeURIComponent(relabelNo)}/confirm-completion`, data: { idempotencyKey: crypto.randomUUID(), remark } })
|
||||
return overseasApiRequest<RelabelDetail>({ method: 'POST', url: `/merchant/v1/last-leg/relabel-applications/${encodeURIComponent(relabelNo)}/confirm-completion`, data: { idempotencyKey: createIdempotencyKey(), remark } })
|
||||
}
|
||||
export function downloadRelabelCompletionPhoto(relabelNo: string, fileId: string) {
|
||||
return overseasBlobRequest({ method: 'GET', url: `/merchant/v1/last-leg/relabel-applications/${encodeURIComponent(relabelNo)}/completion-photos/${encodeURIComponent(fileId)}/download` })
|
||||
|
||||
@@ -8,6 +8,7 @@ import DataTable, { type DataTableColumn } from '@/components/common/DataTable.v
|
||||
import type { TableAction } from '@/components/common/tableActions'
|
||||
import { useAuthStore } from '@/modules/auth/public'
|
||||
import { getMerchantWarehouses, type MerchantWarehouse } from '@/modules/first-leg/public'
|
||||
import { createIdempotencyKey } from '@/utils/idempotencyKey'
|
||||
import { createReturnOrder, downloadReturnPhoto, getReturnOrder, listReturnOrders, updateReturnOrder, type ReturnOrderDetail, type ReturnOrderSummary, type ReturnReceipt } from '../api/returnOrders'
|
||||
|
||||
const props = withDefaults(defineProps<{ createPage?: boolean; detailPage?: boolean; returnNo?: string }>(), { createPage: false, detailPage: false, returnNo: '' })
|
||||
@@ -185,7 +186,7 @@ async function submit() {
|
||||
if (duplicateSkuIds.value.size) { ElMessage.warning('同一退货单不能重复填写相同 SKU'); return }
|
||||
creating.value = true
|
||||
try {
|
||||
const payload = { overseasWarehouseId: form.overseasWarehouseId, warehouseContactName: form.warehouseContactName.trim(), warehouseContactPhone: form.warehouseContactPhone.trim(), customerReferenceNo: form.customerReferenceNo || undefined, remark: form.remark || undefined, needRelabel: form.needRelabel, idempotencyKey: crypto.randomUUID(), items: items.map(item => ({ ...item, productNameZh: item.productNameZh || undefined })) }
|
||||
const payload = { overseasWarehouseId: form.overseasWarehouseId, warehouseContactName: form.warehouseContactName.trim(), warehouseContactPhone: form.warehouseContactPhone.trim(), customerReferenceNo: form.customerReferenceNo || undefined, remark: form.remark || undefined, needRelabel: form.needRelabel, idempotencyKey: createIdempotencyKey(), items: items.map(item => ({ ...item, productNameZh: item.productNameZh || undefined })) }
|
||||
const detail = editingReturnNo.value ? await updateReturnOrder(editingReturnNo.value, payload) : await createReturnOrder(payload)
|
||||
ElMessage.success(editingReturnNo.value ? '退货预报已更新' : '退货预报已创建'); showCreate.value = false; editingReturnNo.value = ''; resetForm(); await router.push({ name: 'overseas-return-relabel-detail', params: { returnNo: detail.order.returnNo } })
|
||||
} finally { creating.value = false }
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
type MerchantWarehouseDetail,
|
||||
} from '@/modules/first-leg/api/firstLeg'
|
||||
import { loadAllWarehouseRecords } from '@/modules/first-leg/utils/warehousePagination'
|
||||
import { createIdempotencyKey } from '@/utils/idempotencyKey'
|
||||
import { createReturnRelabel, uploadReturnRelabelFile } from '../api/returnOrders'
|
||||
|
||||
type ServiceType = 'labeling' | 'transfer' | 'disposal' | 'relabel'
|
||||
@@ -914,7 +915,7 @@ async function submitReturnRelabel() {
|
||||
destinationFbaWarehouseId: String(destination.id),
|
||||
destinationFbaWarehouseCode: destination.warehouseCode,
|
||||
cartonRemark: form.remark.trim() || undefined,
|
||||
idempotencyKey: crypto.randomUUID(),
|
||||
idempotencyKey: createIdempotencyKey(),
|
||||
})
|
||||
await uploadReturnRelabelFile(created.relabelNo, fileScope, selectedFile)
|
||||
ElMessage.success(`贴标申请 ${created.relabelNo} 已提交,等待审核`)
|
||||
@@ -1002,7 +1003,7 @@ async function submit(action: 'draft' | 'submit' = 'submit') {
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
const idempotencyKey = crypto.randomUUID()
|
||||
const idempotencyKey = createIdempotencyKey()
|
||||
if (props.service === 'labeling') {
|
||||
const sourceInboundOrders = [...new Set(cargoRows.value.map((item) => item.sourceInboundOrderNo || item.sourceInboundCode).filter((value): value is string => Boolean(value)))].join('、').slice(0, 128)
|
||||
const items = labelingMode.value === 'carton'
|
||||
@@ -1260,7 +1261,7 @@ async function resubmitRejectedRelabel() {
|
||||
selectedRelabelDetail.value = await resubmitRelabel(application.relabelNo, {
|
||||
labelDeadline: application.labelDeadline || '', contactName: application.contactName || '',
|
||||
contactPhone: application.contactPhone || '', remark: value?.trim() || undefined,
|
||||
idempotencyKey: crypto.randomUUID(),
|
||||
idempotencyKey: createIdempotencyKey(),
|
||||
})
|
||||
ElMessage.success('贴标单已重新提交审核')
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export function createIdempotencyKey(prefix = 'client') {
|
||||
const nativeUuid = globalThis.crypto?.randomUUID
|
||||
if (typeof nativeUuid === 'function') return nativeUuid.call(globalThis.crypto)
|
||||
|
||||
const bytes = new Uint8Array(16)
|
||||
if (typeof globalThis.crypto?.getRandomValues === 'function') {
|
||||
globalThis.crypto.getRandomValues(bytes)
|
||||
} else {
|
||||
for (let index = 0; index < bytes.length; index += 1) {
|
||||
bytes[index] = Math.floor(Math.random() * 256)
|
||||
}
|
||||
}
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80
|
||||
const hex = Array.from(bytes, value => value.toString(16).padStart(2, '0')).join('')
|
||||
const uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`
|
||||
return prefix ? `${prefix}-${uuid}` : uuid
|
||||
}
|
||||
Reference in New Issue
Block a user