refactor(AdminIndex): 统一字段命名并优化数据映射逻辑
重构表单字段命名以保持前后端一致性,优化数据映射逻辑确保正确回显。 移除未使用的导入并简化状态管理,提升代码可维护性。
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
<n-space align="center">
|
||||
<span class="table-title">数据列表</span>
|
||||
<n-text depth="3" style="font-size: 12px; font-weight: normal;">共找到 {{ pagination.itemCount
|
||||
}}
|
||||
}}
|
||||
条记录</n-text>
|
||||
</n-space>
|
||||
</template>
|
||||
@@ -104,10 +104,10 @@
|
||||
</n-icon> 执行分配</div>
|
||||
<n-form label-placement="left" label-width="100">
|
||||
<n-form-item label="分配指导师">
|
||||
<n-input v-model:value="editingRow.guideName" placeholder="输入指导师姓名" />
|
||||
<n-input v-model:value="editingRow.assignee_name" placeholder="输入指导师姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="联系电话">
|
||||
<n-input v-model:value="editingRow.guidePhone" placeholder="输入指导师手机号" />
|
||||
<n-input v-model:value="editingRow.assignee_phone" placeholder="输入指导师手机号" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</div>
|
||||
@@ -119,23 +119,24 @@
|
||||
</n-icon> 客户及成交信息</div>
|
||||
<n-descriptions label-placement="left" :column="2" bordered size="small"
|
||||
class="custom-desc">
|
||||
<n-descriptions-item label="分析师主管">{{ editingRow.analystSupervisor
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="分析师部门">{{ editingRow.analystDepartment
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="分析师姓名">{{ editingRow.analystName
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="家长姓名">{{ editingRow.parentName }}</n-descriptions-item>
|
||||
<n-descriptions-item label="家长电话">{{ editingRow.parentPhone }}</n-descriptions-item>
|
||||
<n-descriptions-item label="身份证号">{{ editingRow.parentIdCard
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="成交日期">{{ editingRow.transactionDate
|
||||
<n-descriptions-item label="分析师主管">{{ editingRow.analyst_supervisor
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="分析师部门">{{ editingRow.analyst_department
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="分析师姓名">{{ editingRow.analyst_name
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="家长姓名">{{ editingRow.parent_name }}</n-descriptions-item>
|
||||
<n-descriptions-item label="家长电话">{{ editingRow.parent_phone
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="身份证号">{{ editingRow.parent_id_card
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="成交日期">{{ editingRow.transaction_date
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="成交金额"><span class="price-text">¥{{
|
||||
editingRow.transactionAmount
|
||||
editingRow.transaction_amount
|
||||
}}</span></n-descriptions-item>
|
||||
<n-descriptions-item label="指导周期" :span="2">{{ editingRow.guidancePeriod
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="指导周期" :span="2">{{ editingRow.guidance_period
|
||||
}}</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</div>
|
||||
|
||||
@@ -143,7 +144,7 @@
|
||||
<div class="group-title"><n-icon>
|
||||
<FileTrayOutline />
|
||||
</n-icon> 附件文档</div>
|
||||
<div class="file-box" v-if="editingRow.files?.length && editingRow.files[0]">
|
||||
<div class="file-box" v-if="editingRow.attachment_file_url">
|
||||
<n-button block secondary type="primary" @click="downloadFile">下载附件文档</n-button>
|
||||
</div>
|
||||
<n-empty v-else description="未上传附件" size="small" />
|
||||
@@ -155,7 +156,7 @@
|
||||
</n-icon> 付款截图</div>
|
||||
<n-image-group>
|
||||
<n-space>
|
||||
<n-image v-for="(img, i) in editingRow.paymentImages" :key="i" width="120"
|
||||
<n-image v-for="(img, i) in editingRow.payment_image_urls" :key="i" width="120"
|
||||
height="120" fit="cover" class="preview-img" :src="img" />
|
||||
</n-space>
|
||||
</n-image-group>
|
||||
@@ -166,7 +167,8 @@
|
||||
<BrushOutline />
|
||||
</n-icon> 电子签名</div>
|
||||
<div class="signature-wrapper">
|
||||
<n-image v-if="editingRow.signature" width="240" :src="editingRow.signature" />
|
||||
<n-image v-if="editingRow.signature_image_url" width="240"
|
||||
:src="editingRow.signature_image_url" />
|
||||
<n-text v-else depth="3">暂无签名数据</n-text>
|
||||
</div>
|
||||
</div>
|
||||
@@ -196,7 +198,7 @@ import {
|
||||
|
||||
import {
|
||||
SearchOutline, LogOutOutline, DownloadOutline, PersonOutline, FileTrayOutline,
|
||||
ImagesOutline, BrushOutline, ReaderOutline, EyeOutline, CheckmarkCircleOutline
|
||||
ImagesOutline, BrushOutline, ReaderOutline, EyeOutline
|
||||
} from '@vicons/ionicons5'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -204,7 +206,6 @@ const message = useMessage()
|
||||
const loading = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
|
||||
// 搜索参数
|
||||
const searchParams = reactive({
|
||||
wecom_id: '',
|
||||
parentInfo: '',
|
||||
@@ -219,7 +220,6 @@ const statusOptions = [
|
||||
|
||||
const displayData = ref([])
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
@@ -237,7 +237,7 @@ const pagination = reactive({
|
||||
}
|
||||
})
|
||||
|
||||
// 1. 获取列表数据
|
||||
// 1. 获取列表数据并映射回显
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -256,24 +256,35 @@ const fetchData = async () => {
|
||||
|
||||
if (res.success) {
|
||||
displayData.value = res.data.map(item => ({
|
||||
id: item.wecom_id,
|
||||
analystSupervisor: item.analyst_supervisor,
|
||||
analystDepartment: item.analyst_department,
|
||||
analystName: item.analyst_name,
|
||||
parentName: item.parent_name,
|
||||
parentPhone: item.parent_phone,
|
||||
parentIdCard: item.parent_id_card,
|
||||
transactionDate: item.transaction_date,
|
||||
transactionAmount: item.transaction_amount || '0',
|
||||
guidancePeriod: item.guidance_period,
|
||||
submissionTime: item.submission_time,
|
||||
// 基础信息
|
||||
wecom_id: item.wecom_id,
|
||||
analyst_supervisor: item.analyst_supervisor,
|
||||
analyst_department: item.analyst_department,
|
||||
analyst_name: item.analyst_name,
|
||||
parent_name: item.parent_name,
|
||||
parent_phone: item.parent_phone,
|
||||
parent_id_card: item.parent_id_card || '',
|
||||
transaction_date: item.transaction_date,
|
||||
transaction_amount: item.transaction_amount || '0',
|
||||
guidance_period: item.guidance_period || '',
|
||||
submission_time: item.submission_time,
|
||||
status: item.status,
|
||||
paymentImages: item.payment_image_url ? [item.payment_image_url] : [],
|
||||
signature: item.signature_image_url,
|
||||
files: item.attachment_file_url ? [item.attachment_file_url] : [],
|
||||
// 交互字段
|
||||
guideName: '',
|
||||
guidePhone: '',
|
||||
|
||||
// --- 修复关键:直接映射分配人信息以实现回显 ---
|
||||
assignee_name: item.assignee_name || '',
|
||||
assignee_phone: item.assignee_phone || '',
|
||||
|
||||
// 存储原始 Object Names (用于提交接口)
|
||||
payment_object_names: Array.isArray(item.payment_object_names) ? item.payment_object_names : [],
|
||||
signature_object_name: item.signature_object_name || '',
|
||||
attachment_object_name: item.attachment_object_name || '',
|
||||
|
||||
// 带有签名的展示 URL
|
||||
payment_image_urls: item.payment_image_url || [],
|
||||
signature_image_url: item.signature_image_url,
|
||||
attachment_file_url: item.attachment_file_url,
|
||||
|
||||
// 交互状态
|
||||
isSubmitting: false
|
||||
}))
|
||||
pagination.itemCount = res.pagination.total
|
||||
@@ -287,36 +298,32 @@ const fetchData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 提交分配请求函数
|
||||
// 2. 提交分配请求
|
||||
const submitAssignment = async (row) => {
|
||||
if (!row.guideName || !row.guidePhone) {
|
||||
message.warning('请填写完整的指导师信息')
|
||||
return
|
||||
if (!row.assignee_name || !row.assignee_phone) {
|
||||
message.warning('请填写指导师姓名和电话')
|
||||
return false
|
||||
}
|
||||
|
||||
row.isSubmitting = true
|
||||
try {
|
||||
// --- 修改开始 ---
|
||||
// 构建与 curl 命令匹配的 payload
|
||||
const payload = {
|
||||
wecom_id: row.id,
|
||||
// payment_object_names 需要是一个数组
|
||||
payment_object_names: row.paymentImages || [],
|
||||
signature_object_name: row.signature || "",
|
||||
attachment_object_name: row.files?.[0] || "",
|
||||
analyst_supervisor: row.analystSupervisor,
|
||||
analyst_department: row.analystDepartment,
|
||||
analyst_name: row.analystName,
|
||||
parent_name: row.parentName,
|
||||
parent_phone: row.parentPhone,
|
||||
parent_id_card: row.parentIdCard,
|
||||
transaction_date: row.transactionDate,
|
||||
transaction_amount: String(row.transactionAmount),
|
||||
guidance_period: row.guidancePeriod,
|
||||
assignee_name: row.guideName,
|
||||
assignee_phone: row.guidePhone
|
||||
wecom_id: String(row.wecom_id),
|
||||
payment_object_names: row.payment_object_names,
|
||||
signature_object_name: row.signature_object_name,
|
||||
attachment_object_name: row.attachment_object_name,
|
||||
analyst_supervisor: row.analyst_supervisor,
|
||||
analyst_department: row.analyst_department,
|
||||
analyst_name: row.analyst_name,
|
||||
parent_name: row.parent_name,
|
||||
parent_phone: row.parent_phone,
|
||||
parent_id_card: row.parent_id_card,
|
||||
transaction_date: row.transaction_date,
|
||||
transaction_amount: String(row.transaction_amount),
|
||||
guidance_period: row.guidance_period,
|
||||
assignee_name: row.assignee_name,
|
||||
assignee_phone: row.assignee_phone
|
||||
}
|
||||
// --- 修改结束 ---
|
||||
|
||||
const response = await fetch('http://192.168.15.115:5636/api/v1/material/submit', {
|
||||
method: 'POST',
|
||||
@@ -328,27 +335,35 @@ const submitAssignment = async (row) => {
|
||||
})
|
||||
|
||||
const res = await response.json()
|
||||
if (res.success || res.code === 200) {
|
||||
message.success('分配成功')
|
||||
row.status = 'processed' // 本地更新状态
|
||||
|
||||
if (response.ok && (res.success || res.code === 200)) {
|
||||
message.success('分配并提报成功')
|
||||
row.status = 'processed'
|
||||
return true
|
||||
} else {
|
||||
message.error(res.message || '提交失败')
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('提交请求失败,请检查网络')
|
||||
message.error('网络请求异常')
|
||||
return false
|
||||
} finally {
|
||||
row.isSubmitting = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleDrawerSubmit = async () => {
|
||||
submitLoading.value = true
|
||||
const success = await submitAssignment(editingRow.value)
|
||||
submitLoading.value = false
|
||||
if (success) showDrawer.value = false
|
||||
}
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{ title: '分析师', key: 'analystName', width: 90, fixed: 'left' },
|
||||
{ title: '家长姓名', key: 'parentName', width: 90 },
|
||||
{ title: '家长电话', key: 'parentPhone', width: 120 },
|
||||
{ title: '分析师', key: 'analyst_name', width: 90, fixed: 'left' },
|
||||
{ title: '家长姓名', key: 'parent_name', width: 90 },
|
||||
{ title: '家长电话', key: 'parent_phone', width: 120 },
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
@@ -358,27 +373,27 @@ const columns = [
|
||||
round: true, size: 'small'
|
||||
}, { default: () => row.status === 'pending' ? '待处理' : '已处理' })
|
||||
},
|
||||
{ title: '成交金额', key: 'transactionAmount', width: 100, render: (row) => h('span', { class: 'price-text' }, `¥${row.transactionAmount}`) },
|
||||
{ title: '成交金额', key: 'transaction_amount', width: 100, render: (row) => h('span', { class: 'price-text' }, `¥${row.transaction_amount}`) },
|
||||
{
|
||||
title: '分配指导师姓名',
|
||||
key: 'guideName',
|
||||
key: 'assignee_name',
|
||||
width: 130,
|
||||
render: (row) => h(NInput, {
|
||||
value: row.guideName,
|
||||
value: row.assignee_name,
|
||||
size: 'small',
|
||||
placeholder: '输入姓名',
|
||||
onUpdateValue: (v) => { row.guideName = v }
|
||||
onUpdateValue: (v) => { row.assignee_name = v }
|
||||
})
|
||||
},
|
||||
{
|
||||
title: '指导师电话',
|
||||
key: 'guidePhone',
|
||||
key: 'assignee_phone',
|
||||
width: 160,
|
||||
render: (row) => h(NInput, {
|
||||
value: row.guidePhone,
|
||||
value: row.assignee_phone,
|
||||
size: 'small',
|
||||
placeholder: '输入手机号',
|
||||
onUpdateValue: (v) => { row.guidePhone = v }
|
||||
onUpdateValue: (v) => { row.assignee_phone = v }
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -405,22 +420,13 @@ const columns = [
|
||||
}
|
||||
]
|
||||
|
||||
// 抽屉逻辑
|
||||
const showDrawer = ref(false)
|
||||
const editingRow = ref({})
|
||||
const openDetails = (row) => {
|
||||
editingRow.value = row // 这里使用引用,方便同步修改
|
||||
editingRow.value = row
|
||||
showDrawer.value = true
|
||||
}
|
||||
|
||||
const handleDrawerSubmit = async () => {
|
||||
submitLoading.value = true
|
||||
const success = await submitAssignment(editingRow.value)
|
||||
submitLoading.value = false
|
||||
if (success) showDrawer.value = false
|
||||
}
|
||||
|
||||
// 搜索逻辑
|
||||
const handleSearch = () => { pagination.page = 1; fetchData() }
|
||||
const resetSearch = () => {
|
||||
Object.assign(searchParams, { wecom_id: '', parentInfo: '', dateRange: null, status: null })
|
||||
@@ -431,7 +437,7 @@ const resetSearch = () => {
|
||||
onMounted(() => fetchData())
|
||||
|
||||
const logout = () => { localStorage.clear(); router.push('/login') }
|
||||
const downloadFile = () => { if (editingRow.value.files?.[0]) window.open(editingRow.value.files[0]) }
|
||||
const downloadFile = () => { if (editingRow.value.attachment_file_url) window.open(editingRow.value.attachment_file_url) }
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user