BomManage: saveDraftData 简化为全局唯一草稿静默覆盖模式
This commit is contained in:
@ -542,34 +542,16 @@ const getOrGenerateTempBomNo = (): string => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleCreate = async () => {
|
const handleCreate = async () => {
|
||||||
|
// 1. 全局拦截
|
||||||
|
const isIntercepted = await checkAndInterceptGlobalDraft()
|
||||||
|
if (isIntercepted) return
|
||||||
|
|
||||||
|
// 2. 正常的纯新建逻辑
|
||||||
|
resetForm()
|
||||||
const tempBomNo = getOrGenerateTempBomNo()
|
const tempBomNo = getOrGenerateTempBomNo()
|
||||||
pendingDraftBomNo = tempBomNo
|
form.bom_no = tempBomNo
|
||||||
pendingDraftVersion = 'V1.0'
|
originalDraftHash.value = getDraftHash()
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await getDraftDetail({ bom_no: pendingDraftBomNo, version: pendingDraftVersion })
|
|
||||||
if (res.code === 200 && res.data) {
|
|
||||||
const confirm = await ElMessageBox.confirm(
|
|
||||||
'检测到未发布的草稿,是否恢复继续编辑?',
|
|
||||||
'草稿恢复',
|
|
||||||
{ confirmButtonText: '恢复草稿', cancelButtonText: '放弃草稿', type: 'info' }
|
|
||||||
).catch(() => null)
|
|
||||||
|
|
||||||
if (confirm) {
|
|
||||||
restoreDraftToForm(res.data)
|
|
||||||
dialogTitle.value = '新建 BOM'
|
|
||||||
isEditMode.value = false
|
|
||||||
isSaveAsMode.value = false
|
|
||||||
isReadOnlyMode.value = false
|
|
||||||
dialogVisible.value = true
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
resetForm()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
resetForm()
|
|
||||||
dialogTitle.value = '新建 BOM'
|
dialogTitle.value = '新建 BOM'
|
||||||
isEditMode.value = false
|
isEditMode.value = false
|
||||||
isSaveAsMode.value = false
|
isSaveAsMode.value = false
|
||||||
@ -578,45 +560,16 @@ const handleCreate = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const saveDraftData = async () => {
|
const saveDraftData = async () => {
|
||||||
|
// 获取当前正在编辑的单号
|
||||||
const draftBomNo = form.bom_no || getOrGenerateTempBomNo()
|
const draftBomNo = form.bom_no || getOrGenerateTempBomNo()
|
||||||
const currentHash = getDraftHash()
|
const currentHash = getDraftHash()
|
||||||
|
|
||||||
// 场景 A:之前已经存过/恢复过草稿,且没有任何改动
|
// 场景 A:防呆拦截。如果数据没有任何改动,直接提示并阻断多余的网络请求
|
||||||
if (originalDraftHash.value && currentHash === originalDraftHash.value) {
|
if (originalDraftHash.value && currentHash === originalDraftHash.value) {
|
||||||
return ElMessage.warning('草稿数据无变动,无需重复暂存')
|
return ElMessage.warning('草稿数据无变动,无需重复暂存')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 场景 B:已经存过草稿,且发生了改动 -> 询问覆盖还是新建
|
// 场景 B:执行保存。在"全局唯一草稿"架构下,不再询问,直接实时同步最新状态到数据库
|
||||||
if (originalDraftHash.value && currentHash !== originalDraftHash.value) {
|
|
||||||
try {
|
|
||||||
const action = await ElMessageBox.confirm(
|
|
||||||
'检测到草稿内容已发生变动,请选择保存方式:',
|
|
||||||
'草稿变动提示',
|
|
||||||
{
|
|
||||||
confirmButtonText: '直接覆盖',
|
|
||||||
cancelButtonText: '另存为新草稿',
|
|
||||||
distinguishCancelAndClose: true,
|
|
||||||
type: 'warning'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if (action === 'confirm') {
|
|
||||||
// 选择覆盖原草稿
|
|
||||||
await executeSaveDraftRequest(draftBomNo)
|
|
||||||
}
|
|
||||||
} catch (action) {
|
|
||||||
if (action === 'cancel') {
|
|
||||||
// 选择另存为新草稿:生成新单号并保存
|
|
||||||
const ts = new Date().toISOString().replace(/[-T:.Z]/g, '').slice(0, 14)
|
|
||||||
const uid = Math.random().toString(36).slice(2, 6)
|
|
||||||
const newTempNo = `DRAFT-TEMP-${ts}-${uid}`
|
|
||||||
form.bom_no = newTempNo
|
|
||||||
await executeSaveDraftRequest(newTempNo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 场景 C:第一次暂存
|
|
||||||
await executeSaveDraftRequest(draftBomNo)
|
await executeSaveDraftRequest(draftBomNo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,6 +595,7 @@ const executeSaveDraftRequest = async (targetBomNo: string) => {
|
|||||||
ElMessage.success('草稿暂存成功')
|
ElMessage.success('草稿暂存成功')
|
||||||
form.bom_no = targetBomNo
|
form.bom_no = targetBomNo
|
||||||
localStorage.setItem('pending_bom_draft_no', targetBomNo)
|
localStorage.setItem('pending_bom_draft_no', targetBomNo)
|
||||||
|
localStorage.setItem('pending_bom_draft_version', draftVersion)
|
||||||
originalDraftHash.value = getDraftHash()
|
originalDraftHash.value = getDraftHash()
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(res.msg || '暂存失败')
|
ElMessage.error(res.msg || '暂存失败')
|
||||||
@ -677,6 +631,71 @@ const restoreDraftToForm = (draftData: any) => {
|
|||||||
originalDraftHash.value = getDraftHash()
|
originalDraftHash.value = getDraftHash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkUserDraft = async (bomNo: string, version: string) => {
|
||||||
|
try {
|
||||||
|
const res = await getDraftDetail({ bom_no: bomNo, version: version })
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const confirm = await ElMessageBox.confirm(
|
||||||
|
`检测到未发布的草稿数据,是否恢复继续编辑?`,
|
||||||
|
'草稿恢复',
|
||||||
|
{ confirmButtonText: '恢复草稿', cancelButtonText: '放弃草稿', type: 'info' }
|
||||||
|
).catch(() => 'cancel')
|
||||||
|
|
||||||
|
if (confirm === 'confirm') {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 网络异常或查不到均视为无草稿
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkAndInterceptGlobalDraft = async (): Promise<boolean> => {
|
||||||
|
const pendingNo = localStorage.getItem('pending_bom_draft_no')
|
||||||
|
const pendingVer = localStorage.getItem('pending_bom_draft_version') || 'V1.0'
|
||||||
|
|
||||||
|
if (pendingNo) {
|
||||||
|
try {
|
||||||
|
const res = await getDraftDetail({ bom_no: pendingNo, version: pendingVer })
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const action = await ElMessageBox.confirm(
|
||||||
|
`系统检测到您有一个未发布的草稿 [${pendingNo}]。\n\n为防止数据混乱,同一时间只允许保留一份草稿。\n• 点击【恢复草稿】继续编辑\n• 点击【放弃旧草稿】彻底销毁它并开启新任务`,
|
||||||
|
'全局草稿拦截',
|
||||||
|
{
|
||||||
|
confirmButtonText: '恢复草稿',
|
||||||
|
cancelButtonText: '放弃旧草稿',
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).catch(action => action)
|
||||||
|
|
||||||
|
if (action === 'confirm') {
|
||||||
|
resetForm()
|
||||||
|
restoreDraftToForm(res.data)
|
||||||
|
originalDraftHash.value = getDraftHash()
|
||||||
|
dialogTitle.value = '继续编辑草稿'
|
||||||
|
isEditMode.value = false
|
||||||
|
isSaveAsMode.value = false
|
||||||
|
isReadOnlyMode.value = false
|
||||||
|
dialogVisible.value = true
|
||||||
|
return true
|
||||||
|
} else if (action === 'cancel') {
|
||||||
|
localStorage.removeItem('pending_bom_draft_no')
|
||||||
|
localStorage.removeItem('pending_bom_draft_version')
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
localStorage.removeItem('pending_bom_draft_no')
|
||||||
|
localStorage.removeItem('pending_bom_draft_version')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const handleView = async (row: BomItem) => {
|
const handleView = async (row: BomItem) => {
|
||||||
await loadDetail(row.bom_no, row.version)
|
await loadDetail(row.bom_no, row.version)
|
||||||
dialogTitle.value = '查看 BOM'
|
dialogTitle.value = '查看 BOM'
|
||||||
@ -686,16 +705,17 @@ const handleView = async (row: BomItem) => {
|
|||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSaveAs = async (row: BomItem) => {
|
const handleSaveAs = async (row: any) => {
|
||||||
// 1. 重置 form 基础状态
|
// 1. 全局拦截
|
||||||
resetForm()
|
const isIntercepted = await checkAndInterceptGlobalDraft()
|
||||||
|
if (isIntercepted) return
|
||||||
|
|
||||||
// 2. 获取源 BOM 详情(不通过 loadDetail,显式走"深拷贝+清 ID"路径)
|
// 2. 正常的纯另存为逻辑
|
||||||
|
resetForm()
|
||||||
const res = await getBomDetail(row.bom_no, row.version)
|
const res = await getBomDetail(row.bom_no, row.version)
|
||||||
if (res.code !== 200) return
|
if (res.code !== 200) return
|
||||||
const raw = JSON.parse(JSON.stringify(res.data))
|
const raw = JSON.parse(JSON.stringify(res.data))
|
||||||
|
|
||||||
// 3. ★ 核心:显式深拷贝 + 清除所有主键 ID(防止后端误判为更新操作)
|
|
||||||
if ('id' in raw) delete raw.id
|
if ('id' in raw) delete raw.id
|
||||||
if ('bom_id' in raw) delete raw.bom_id
|
if ('bom_id' in raw) delete raw.bom_id
|
||||||
if (Array.isArray(raw.children)) {
|
if (Array.isArray(raw.children)) {
|
||||||
@ -705,7 +725,6 @@ const handleSaveAs = async (row: BomItem) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 把"已清除 ID 的纯净数据"写入 form
|
|
||||||
form.children = raw.children.map((child: any, idx: number) => ({
|
form.children = raw.children.map((child: any, idx: number) => ({
|
||||||
rowKey: idx,
|
rowKey: idx,
|
||||||
child_id: child.child_id,
|
child_id: child.child_id,
|
||||||
@ -718,18 +737,18 @@ const handleSaveAs = async (row: BomItem) => {
|
|||||||
form.parent_id = raw.parent_id
|
form.parent_id = raw.parent_id
|
||||||
parentNameInput.value = raw.parent_name || '未知产品'
|
parentNameInput.value = raw.parent_name || '未知产品'
|
||||||
}
|
}
|
||||||
|
|
||||||
form.bom_no = (raw.parent_spec || row.bom_no).split('/')[0].trim()
|
form.bom_no = (raw.parent_spec || row.bom_no).split('/')[0].trim()
|
||||||
form.remark = raw.remark || ''
|
form.remark = raw.remark || ''
|
||||||
|
form.versionUpgradeType = 'minor'
|
||||||
|
form.version = versionOptions.value?.minor || 'V1.1'
|
||||||
|
|
||||||
// 5. 设置"另存为"模式特有状态(版本升级单选 + 子件变更检测)
|
|
||||||
originalVersion = raw.version || ''
|
originalVersion = raw.version || ''
|
||||||
currentBomNo = row.bom_no
|
currentBomNo = row.bom_no
|
||||||
originalChildren = JSON.parse(JSON.stringify(form.children))
|
originalChildren = JSON.parse(JSON.stringify(form.children))
|
||||||
form.versionUpgradeType = 'minor'
|
originalDraftHash.value = getDraftHash()
|
||||||
form.version = versionOptions.value.minor
|
|
||||||
|
|
||||||
// 6. 弹窗状态机:标题"新增 BOM",父件可改,启用版本升级单选
|
dialogTitle.value = '新增 BOM (版本升级)'
|
||||||
dialogTitle.value = '新增 BOM'
|
|
||||||
isEditMode.value = false
|
isEditMode.value = false
|
||||||
isSaveAsMode.value = true
|
isSaveAsMode.value = true
|
||||||
isReadOnlyMode.value = false
|
isReadOnlyMode.value = false
|
||||||
@ -844,6 +863,7 @@ const submitForm = async () => {
|
|||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
ElMessage.success('发布成功')
|
ElMessage.success('发布成功')
|
||||||
localStorage.removeItem('pending_bom_draft_no')
|
localStorage.removeItem('pending_bom_draft_no')
|
||||||
|
localStorage.removeItem('pending_bom_draft_version')
|
||||||
originalDraftHash.value = ''
|
originalDraftHash.value = ''
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
fetchBomList()
|
fetchBomList()
|
||||||
|
|||||||
Reference in New Issue
Block a user