提交
This commit is contained in:
1 parent
dd1acdc787
commit
4222eaa593
47 files changed
+1054350
-9663
No files matched your search
@@ -102,6 +102,27 @@
|
||||
:selected-ids="selectedRows.map((r) => r.id)"
|
||||
filename="计划归档.xlsx"
|
||||
/>
|
||||
<el-dropdown trigger="click" @command="handleBatchErpCommand">
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length === 0"
|
||||
:loading="erpBatchLoading"
|
||||
>
|
||||
<el-icon><DocumentChecked /></el-icon>
|
||||
ERP录入
|
||||
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="entered" :disabled="erpBatchLoading">
|
||||
已录入ERP
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="not_entered" :disabled="erpBatchLoading">
|
||||
未录入ERP
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
<ListToolbarEndActions
|
||||
:loading="loading"
|
||||
@@ -229,10 +250,8 @@
|
||||
<template #default="{ row }">
|
||||
<div class="pl-plan-archive-erp-cell" @click.stop @mousedown.stop>
|
||||
<el-checkbox
|
||||
class="pl-plan-archive-erp-checkbox"
|
||||
:model-value="Number(row.erpEntered) === 1"
|
||||
:disabled="row.followStatus === 'cancelled' || erpUpdatingId === row.id"
|
||||
@click.stop
|
||||
@change="(checked) => handleErpEnteredChange(row, Boolean(checked))"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -431,6 +450,8 @@ import ListColumnStatsRow from '@/components/business/list-column-stats-row/inde
|
||||
import type { StatsRowColumn } from '@/utils/list-column-stats'
|
||||
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
|
||||
import {
|
||||
ArrowDown,
|
||||
DocumentChecked,
|
||||
FolderChecked,
|
||||
RefreshLeft,
|
||||
Search
|
||||
@@ -472,7 +493,7 @@ const viewPlanId = ref('')
|
||||
const viewDialogRef = ref<InstanceType<typeof PlPlanViewDialog>>()
|
||||
const archiveDialogVisible = ref(false)
|
||||
const archivePlanId = ref('')
|
||||
const erpUpdatingId = ref('')
|
||||
const erpBatchLoading = ref(false)
|
||||
const planList = ref<Plan[]>([])
|
||||
|
||||
const listColumnDefs = [
|
||||
@@ -765,25 +786,49 @@ function handleToolbarArchive() {
|
||||
handleArchive(selectedRows.value[0])
|
||||
}
|
||||
|
||||
async function handleErpEnteredChange(row: Plan, entered: boolean) {
|
||||
if (row.followStatus === 'cancelled') return
|
||||
const previous = Number(row.erpEntered) === 1
|
||||
if (previous === entered) return
|
||||
async function handleBatchErpCommand(command: 'entered' | 'not_entered') {
|
||||
const entered = command === 'entered'
|
||||
const eligibleRows = selectedRows.value.filter((row) => row.followStatus !== 'cancelled')
|
||||
if (eligibleRows.length === 0) {
|
||||
ElMessage.warning('请选择未作废的计划')
|
||||
return
|
||||
}
|
||||
|
||||
erpUpdatingId.value = row.id
|
||||
row.erpEntered = entered ? 1 : 0
|
||||
const targets = eligibleRows.filter((row) => (Number(row.erpEntered) === 1) !== entered)
|
||||
if (targets.length === 0) {
|
||||
ElMessage.info(entered ? '所选计划均已录入 ERP' : '所选计划均未录入 ERP')
|
||||
return
|
||||
}
|
||||
|
||||
erpBatchLoading.value = true
|
||||
try {
|
||||
const res = await planApi.setErpEntered(row.id, entered)
|
||||
const data = pickBxData<Plan>(res)
|
||||
if (data?.id) {
|
||||
row.erpEntered = data.erpEntered ?? (entered ? 1 : 0)
|
||||
const results = await Promise.allSettled(
|
||||
targets.map((row) => planApi.setErpEntered(row.id, entered))
|
||||
)
|
||||
let successCount = 0
|
||||
results.forEach((result, index) => {
|
||||
const row = targets[index]
|
||||
if (result.status === 'fulfilled') {
|
||||
const data = pickBxData<Plan>(result.value)
|
||||
row.erpEntered = data?.erpEntered ?? (entered ? 1 : 0)
|
||||
successCount += 1
|
||||
return
|
||||
}
|
||||
const message =
|
||||
result.reason instanceof Error ? result.reason.message : '更新 ERP 状态失败'
|
||||
ElMessage.error(
|
||||
`${row.planNo || row.id}:${message.includes('失败') ? message : `更新 ERP 状态失败:${message}`}`
|
||||
)
|
||||
})
|
||||
|
||||
if (successCount > 0) {
|
||||
ElMessage.success(
|
||||
entered ? `已将 ${successCount} 条计划标记为已录入 ERP` : `已将 ${successCount} 条计划标记为未录入 ERP`
|
||||
)
|
||||
await refreshViewIfOpen()
|
||||
}
|
||||
} catch (error) {
|
||||
row.erpEntered = previous ? 1 : 0
|
||||
const message = error instanceof Error ? error.message : '更新 ERP 状态失败'
|
||||
ElMessage.error(message.includes('失败') ? message : `更新 ERP 状态失败:${message}`)
|
||||
} finally {
|
||||
erpUpdatingId.value = ''
|
||||
erpBatchLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,4 +867,9 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pl-plan-archive-erp-checkbox {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
</style>
|
||||
@@ -173,15 +173,6 @@
|
||||
>
|
||||
<el-icon><DocumentCopy /></el-icon>三方人车快速创建
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="canForceFollowStatus"
|
||||
class="btn-ghost"
|
||||
:disabled="!selectedPlan"
|
||||
@click="openForceFollowStatusDialog"
|
||||
>
|
||||
<el-icon><EditPen /></el-icon>强制改状态
|
||||
</el-button>
|
||||
|
||||
<ListExportDropdown
|
||||
:export-fn="planApi.export"
|
||||
:get-filter-params="getPlanExportFilterParams"
|
||||
@@ -571,6 +562,13 @@
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
v-if="canForceFollowStatus"
|
||||
class="btn-ghost"
|
||||
@click="openForceFollowStatusDialog"
|
||||
>
|
||||
<el-icon><EditPen /></el-icon>强制改状态
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="canVoidPlan(viewingPlan)"
|
||||
class="btn-ghost"
|
||||
@@ -614,27 +612,27 @@
|
||||
>
|
||||
<el-form label-position="top" class="form-grid-2">
|
||||
<el-form-item label="计划编号" style="margin-bottom: 0">
|
||||
<span>{{ selectedPlan?.planNo || '—' }}</span>
|
||||
<span>{{ viewingPlan?.planNo || '—' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="单据类型" style="margin-bottom: 0">
|
||||
<span>{{ getPlanTypeLabel(selectedPlan?.planType) }}</span>
|
||||
<span>{{ getPlanTypeLabel(viewingPlan?.planType) }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="供方" style="margin-bottom: 0">
|
||||
<span>{{ selectedPlan?.supplierName || '—' }}</span>
|
||||
<span>{{ viewingPlan?.supplierName || '—' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="需方" style="margin-bottom: 0">
|
||||
<span>{{ selectedPlan?.customerName || '—' }}</span>
|
||||
<span>{{ viewingPlan?.customerName || '—' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品信息" class="form-col-span-2" style="margin-bottom: 0">
|
||||
<PlPlanListProductCell :products="selectedPlan?.products || []" />
|
||||
<PlPlanListProductCell :products="viewingPlan?.products || []" />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前跟进状态" style="margin-bottom: 0">
|
||||
<el-tag
|
||||
v-if="selectedPlan"
|
||||
:type="getPlPlanFollowStatusTagType(selectedPlan.followStatus)"
|
||||
v-if="viewingPlan"
|
||||
:type="getPlPlanFollowStatusTagType(viewingPlan.followStatus)"
|
||||
size="small"
|
||||
>
|
||||
{{ getPlPlanFollowStatusLabel(selectedPlan.followStatus) }}
|
||||
{{ getPlPlanFollowStatusLabel(viewingPlan.followStatus) }}
|
||||
</el-tag>
|
||||
<span v-else>—</span>
|
||||
</el-form-item>
|
||||
@@ -1284,8 +1282,8 @@ function handleToolbarVoid() {
|
||||
}
|
||||
|
||||
function openForceFollowStatusDialog() {
|
||||
if (!selectedPlan.value) return
|
||||
forceFollowStatusValue.value = selectedPlan.value.followStatus || ''
|
||||
if (!viewingPlan.value) return
|
||||
forceFollowStatusValue.value = viewingPlan.value.followStatus || ''
|
||||
forceFollowDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -1294,22 +1292,24 @@ function resetForceFollowDialog() {
|
||||
}
|
||||
|
||||
async function submitForceFollowStatus() {
|
||||
if (!selectedPlan.value) return
|
||||
if (!viewingPlan.value) return
|
||||
const next = (forceFollowStatusValue.value || '').trim()
|
||||
if (!next) {
|
||||
ElMessage.warning('请选择目标跟进状态')
|
||||
return
|
||||
}
|
||||
if (next === selectedPlan.value.followStatus) {
|
||||
if (next === viewingPlan.value.followStatus) {
|
||||
ElMessage.warning('目标状态与当前状态相同')
|
||||
return
|
||||
}
|
||||
forceFollowLoading.value = true
|
||||
try {
|
||||
await planApi.forceFollowStatus(selectedPlan.value.id, next)
|
||||
await planApi.forceFollowStatus(viewingPlan.value.id, next)
|
||||
ElMessage.success('跟进状态已更新')
|
||||
forceFollowDialogVisible.value = false
|
||||
fetchData()
|
||||
syncViewingPlan({ ...viewingPlan.value, followStatus: next })
|
||||
await fetchData()
|
||||
await refreshViewIfOpen()
|
||||
} catch (e) {
|
||||
const message = e instanceof Error ? e.message : '修改失败'
|
||||
ElMessage.error(message)
|
||||
|
||||
Reference in new issue
Block a user