备货单 添加预览 跟进列表分页 审批记录显示问题处理
This commit is contained in:
@@ -638,10 +638,25 @@
|
||||
if (c.type === 'initiator_leader') {
|
||||
group.users = []
|
||||
} else if (c.value) {
|
||||
group.users = String(c.value)
|
||||
// group.users = String(c.value)
|
||||
// .split(',')
|
||||
// .map((v) => Number((v || '').trim()))
|
||||
// .filter((n) => !Number.isNaN(n))
|
||||
const values = String(c.value)
|
||||
.split(',')
|
||||
.map((v) => Number((v || '').trim()))
|
||||
.filter((n) => !Number.isNaN(n))
|
||||
.map((v) => (v || '').trim())
|
||||
.filter(Boolean)
|
||||
// 判断是否为纯数字ID
|
||||
const isNumericIds = values.every(
|
||||
(v) => !Number.isNaN(Number(v)) && Number.isInteger(Number(v))
|
||||
)
|
||||
if (isNumericIds) {
|
||||
// 如果是数字ID,转换为数字数组
|
||||
group.users = values.map((v) => Number(v))
|
||||
} else {
|
||||
// 如果是字符串名称,保持为字符串数组
|
||||
group.users = values
|
||||
}
|
||||
}
|
||||
node.ccGroups.push(group)
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
|
||||
@@ -937,6 +937,8 @@
|
||||
pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted',
|
||||
comment: h?.comment || h?.remark || ''
|
||||
}))
|
||||
} else {
|
||||
approvalRecords.value = []
|
||||
}
|
||||
timelineDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
@@ -499,6 +499,8 @@
|
||||
pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted',
|
||||
comment: h?.comment || h?.remark || ''
|
||||
}))
|
||||
} else {
|
||||
approvalRecords.value = []
|
||||
}
|
||||
timelineDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
@@ -499,6 +499,8 @@
|
||||
pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted',
|
||||
comment: h?.comment || h?.remark || ''
|
||||
}))
|
||||
} else {
|
||||
approvalRecords.value = []
|
||||
}
|
||||
timelineDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<el-table-column prop="name" label="名字" align="center" />
|
||||
<el-table-column prop="phone" label="电话" align="center" />
|
||||
<el-table-column prop="email" label="邮箱" align="center" />
|
||||
<el-table-column prop="report_to_name" label="直属上级" align="center" />
|
||||
<el-table-column prop="corp_name" label="所属公司" align="center" />
|
||||
<el-table-column prop="follow" label="状态" align="center">
|
||||
<template #default="scope">
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<span>{{ account.name }}</span>
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
</ElFormItem>
|
||||
<ElFormItem prop="company" label="系统">
|
||||
<ElSelect v-model="formData.systems" class="account-select" @change="changesystems">
|
||||
<ElOption
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
|
||||
@@ -875,7 +875,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.contract = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.contract = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<!-- 上传PI -->
|
||||
@@ -890,7 +896,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.pi_doc = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.pi_doc = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<!-- 上传水单 -->
|
||||
@@ -905,7 +917,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.transaction_slip = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.transaction_slip = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-card">
|
||||
@@ -1039,9 +1057,21 @@
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { CrmService } from '@/api/crmApi'
|
||||
import { useStockingForm } from '@/composables/useStockingForm'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import { onMounted, ref, computed, toRaw, watch, onBeforeUnmount } from 'vue'
|
||||
import MultiFileUpload from '@/components/core/forms/MultiFileUpload.vue'
|
||||
import contractIcon from '@/assets/img/crm/contract.png'
|
||||
|
||||
// 本地草稿缓存(用于切换页面回显,关闭页面时清空)
|
||||
const STORAGE_VERSION = 'v1'
|
||||
const userStoreForDraft = useUserStore()
|
||||
const storageUserId = userStoreForDraft?.info?.userId || 'anonymous'
|
||||
const draftKeyBase = `stocking:add:draft:${STORAGE_VERSION}:${storageUserId}`
|
||||
const routeForDraft = useRoute()
|
||||
const draftKey = computed(() => {
|
||||
// 若存在复制/编辑 id,区分不同草稿;否则使用路径
|
||||
const id = routeForDraft.query?.id
|
||||
return id ? `${draftKeyBase}:${id}` : `${draftKeyBase}:${routeForDraft.fullPath}`
|
||||
})
|
||||
|
||||
defineOptions({ name: 'CrmStockingAdd' }) // 定义组件名称,用于 KeepAlive 缓存控制
|
||||
|
||||
@@ -1173,6 +1203,69 @@
|
||||
handleVehicleCurrentChange,
|
||||
chooseVehicle
|
||||
} = useStockingForm(false) // isFinal = false
|
||||
|
||||
// ---------- 草稿缓存:保存/恢复/清理 ----------
|
||||
const DRAFT_DEBOUNCE_MS = 500
|
||||
let draftTimer: number | any = null
|
||||
|
||||
const pickDraftPayload = () => ({
|
||||
baseForm: toRaw(baseForm),
|
||||
items: toRaw(items.value),
|
||||
paymentItems: toRaw(paymentItems.value),
|
||||
contractFiles: toRaw(contractFiles.value),
|
||||
piFiles: toRaw(piFiles.value),
|
||||
waterBillFiles: toRaw(waterBillFiles.value)
|
||||
})
|
||||
|
||||
const saveDraft = () => {
|
||||
try {
|
||||
const payload = pickDraftPayload()
|
||||
localStorage.setItem(draftKey.value, JSON.stringify(payload))
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const scheduleSaveDraft = () => {
|
||||
if (draftTimer) clearTimeout(draftTimer)
|
||||
draftTimer = setTimeout(() => {
|
||||
saveDraft()
|
||||
}, DRAFT_DEBOUNCE_MS)
|
||||
}
|
||||
|
||||
const loadDraft = () => {
|
||||
try {
|
||||
const raw = localStorage.getItem(draftKey.value)
|
||||
if (!raw) return
|
||||
const parsed = JSON.parse(raw)
|
||||
// 合并到现有表单数据
|
||||
if (parsed?.baseForm && typeof parsed.baseForm === 'object') {
|
||||
Object.assign(baseForm, parsed.baseForm)
|
||||
}
|
||||
if (Array.isArray(parsed?.items)) {
|
||||
items.value = parsed.items
|
||||
}
|
||||
if (Array.isArray(parsed?.paymentItems)) {
|
||||
paymentItems.value = parsed.paymentItems
|
||||
}
|
||||
if (Array.isArray(parsed?.contractFiles)) {
|
||||
contractFiles.value = parsed.contractFiles
|
||||
baseForm.contract = (contractFiles.value || []).map((f: any) => f.file_name)
|
||||
}
|
||||
if (Array.isArray(parsed?.piFiles)) {
|
||||
piFiles.value = parsed.piFiles
|
||||
baseForm.pi_doc = (piFiles.value || []).map((f: any) => f.file_name)
|
||||
}
|
||||
if (Array.isArray(parsed?.waterBillFiles)) {
|
||||
waterBillFiles.value = parsed.waterBillFiles
|
||||
baseForm.transaction_slip = (waterBillFiles.value || []).map((f: any) => f.file_name)
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const clearDraft = () => {
|
||||
try {
|
||||
localStorage.removeItem(draftKey.value)
|
||||
} catch {}
|
||||
}
|
||||
// 获取详情数据
|
||||
const getdetilfn = async () => {
|
||||
const res = await CrmService.getStockDetail({ id: stocking_id })
|
||||
@@ -1197,6 +1290,8 @@
|
||||
}
|
||||
// 如果校验通过,调用原始的handleSubmit方法
|
||||
await handleSubmit(isFinal)
|
||||
// 提交成功后清理草稿
|
||||
clearDraft()
|
||||
} catch (error) {
|
||||
console.log('表单校验失败:', error)
|
||||
}
|
||||
@@ -1209,6 +1304,27 @@
|
||||
if (stocking_id) {
|
||||
await getdetilfn()
|
||||
}
|
||||
// 尝试从草稿恢复
|
||||
loadDraft()
|
||||
// 监听表单变化,自动保存草稿
|
||||
watch(
|
||||
() => [baseForm, items.value, paymentItems.value],
|
||||
() => scheduleSaveDraft(),
|
||||
{ deep: true }
|
||||
)
|
||||
watch(contractFiles, scheduleSaveDraft, { deep: true })
|
||||
watch(piFiles, scheduleSaveDraft, { deep: true })
|
||||
watch(waterBillFiles, scheduleSaveDraft, { deep: true })
|
||||
// 浏览器标签关闭时清理草稿
|
||||
const beforeUnload = () => {
|
||||
clearDraft()
|
||||
}
|
||||
window.addEventListener('beforeunload', beforeUnload)
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('beforeunload', beforeUnload)
|
||||
// 当页面真正被卸载(如关闭当前路由标签)时清理草稿
|
||||
clearDraft()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -866,10 +866,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.contract = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.contract = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传PI -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -882,10 +887,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.pi_doc = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.pi_doc = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传水单 -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -898,7 +908,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.transaction_slip = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.transaction_slip = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-card">
|
||||
|
||||
@@ -1005,10 +1005,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.contract = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.contract = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传PI -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -1021,10 +1026,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.pi_doc = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.pi_doc = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传水单 -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -1037,7 +1047,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.transaction_slip = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.transaction_slip = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-card">
|
||||
|
||||
@@ -228,6 +228,8 @@
|
||||
pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted',
|
||||
comment: h?.comment || h?.remark || ''
|
||||
}))
|
||||
} else {
|
||||
approvalRecords.value = []
|
||||
}
|
||||
timelineDialogVisible.value = true
|
||||
}
|
||||
@@ -312,7 +314,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
|
||||
@@ -869,10 +869,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.contract = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.contract = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传PI -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -885,10 +890,15 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.pi_doc = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.pi_doc = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 上传水单 -->
|
||||
<div class="boxshadow">
|
||||
<div class="form-title">
|
||||
@@ -901,7 +911,13 @@
|
||||
hint-text="支持多文件上传"
|
||||
:icon-src="contractIcon"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.txt"
|
||||
@change="(files) => (baseForm.transaction_slip = files.map((f) => f.file_name))"
|
||||
@change="
|
||||
(files) =>
|
||||
(baseForm.transaction_slip = files.map((f) => ({
|
||||
url: f.file_name,
|
||||
original_name: f.name
|
||||
})))
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-card">
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<i class="iconfont-sys"></i> 作废
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="scope.row.approval_status == 3 || scope.row.approval_status == 4"
|
||||
v-if="scope.row.approval_status != 1 && scope.row.approval_status != 2"
|
||||
type="danger"
|
||||
underline="never"
|
||||
@click="stockdeletefn(scope.row)"
|
||||
@@ -293,6 +293,8 @@
|
||||
pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted',
|
||||
comment: h?.comment || h?.remark || ''
|
||||
}))
|
||||
} else {
|
||||
approvalRecords.value = []
|
||||
}
|
||||
timelineDialogVisible.value = true
|
||||
}
|
||||
@@ -389,7 +391,7 @@
|
||||
const processFiles = (files: any[], type: string) => {
|
||||
if (!files || !Array.isArray(files)) return []
|
||||
return files.map((file: any) => ({
|
||||
name: `${type}文件`,
|
||||
name: file.original_name,
|
||||
url: file.file_full_url || file.file_url,
|
||||
file_name: file.file_url
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user