|
|
|
@ -68,7 +68,7 @@ |
|
|
|
<van-radio :name="true"> |
|
|
|
<template #icon="{ checked }"> |
|
|
|
<div class="custom-radio-icon" :class="{ checked }"> |
|
|
|
<van-icon v-if="checked" name="success" size="16" color="#fff" /> |
|
|
|
<van-icon v-if="checked" name="success" size="14" color="#fff" /> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
<span class="radio-text">同意</span> |
|
|
|
@ -76,7 +76,7 @@ |
|
|
|
<van-radio :name="false"> |
|
|
|
<template #icon="{ checked }"> |
|
|
|
<div class="custom-radio-icon" :class="{ checked }"> |
|
|
|
<van-icon v-if="checked" name="success" size="16" color="#fff" /> |
|
|
|
<van-icon v-if="checked" name="success" size="14" color="#fff" /> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
<span class="radio-text">不同意</span> |
|
|
|
@ -94,7 +94,8 @@ |
|
|
|
|
|
|
|
<!-- 投诉事项选择弹窗 --> |
|
|
|
<ComplaintItemPicker v-model:show="showComplaintItemPicker" :list="complaintItemList" |
|
|
|
@select="onComplaintItemSelect" /> |
|
|
|
:loading="complaintLoading" :finished="complaintFinished" |
|
|
|
@select="onComplaintItemSelect" @loadMore="loadComplaintItemList" @search="onComplaintItemSearch" /> |
|
|
|
|
|
|
|
<!-- 地址级联选择弹窗 --> |
|
|
|
<van-popup v-model:show="showAddressPicker" position="bottom" :style="{ width: '100%', height: '60%' }"> |
|
|
|
@ -113,8 +114,9 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup name="complaintSuggestion"> |
|
|
|
import { showToast } from 'vant'; |
|
|
|
import { showToast, showConfirmDialog } from 'vant'; |
|
|
|
import 'vant/es/toast/style'; |
|
|
|
import 'vant/es/dialog/style'; |
|
|
|
import { queryDict, getDeptList, getComplaintItemList, addComplaint } from '@/api/enterprise'; |
|
|
|
import { uploadFile } from '@/util/fileUpload'; |
|
|
|
import BureauPicker from '@/components/complaint/BureauPicker.vue'; |
|
|
|
@ -203,6 +205,15 @@ const onComplaintTypeConfirm = ({ text, value }) => { |
|
|
|
// ========== 投诉事项弹窗数据 ========== |
|
|
|
const showComplaintItemPicker = ref(false); |
|
|
|
const complaintItemList = ref([]); |
|
|
|
const complaintPageNum = ref(1); |
|
|
|
const complaintPageSize = ref(10); |
|
|
|
const complaintLoading = ref(false); |
|
|
|
const complaintFinished = ref(false); |
|
|
|
const complaintSearchParams = ref({ |
|
|
|
beginTime: '', |
|
|
|
endTime: '', |
|
|
|
searchValue: '' |
|
|
|
}); |
|
|
|
|
|
|
|
// 将接口返回的一行数据适配为弹窗渲染结构 |
|
|
|
// 接口 /app-ent/complaint/listNotComplaint 返回字段: |
|
|
|
@ -211,34 +222,77 @@ const complaintItemList = ref([]); |
|
|
|
const mapComplaintItem = (item) => { |
|
|
|
return { |
|
|
|
id: item.id || item.relId || '', |
|
|
|
relId: item.relId || '', |
|
|
|
code: item.complaintItemCodes || item.complaintItemCode || item.code || '', |
|
|
|
title: item.complaintItemNames || item.complaintItemName || item.title || '', |
|
|
|
time: item.enforcementTime || item.enforceTime || item.createTime || '', |
|
|
|
unit: item.complaintDepartments || item.bureauName || item.deptName || '', |
|
|
|
unitId: item.complaintDepartmentIds || '', |
|
|
|
subName: item.enterpriseName || item.subName || '', |
|
|
|
userId: item.userId || '', |
|
|
|
title: item.title || '', |
|
|
|
enforcementTime: item.enforcementTime || '', |
|
|
|
bureauDeptName: item.bureauDeptName || '', |
|
|
|
lawEnforcer: item.lawEnforcer || '', |
|
|
|
lawEnforcerId: item.lawEnforcerId || '', |
|
|
|
lawEnforcerOther: item.lawEnforcerOther || '', |
|
|
|
lawEnforcerOtherId: item.lawEnforcerOtherId || '', |
|
|
|
lawEnforcementType: item.lawEnforcementType || '', |
|
|
|
raw: item |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
// 加载投诉事项列表(不缓存,每次点击都重新拉取) |
|
|
|
const loadComplaintItemList = () => { |
|
|
|
getComplaintItemList({}, (res) => { |
|
|
|
// 加载投诉事项列表(支持动态分页和搜索) |
|
|
|
const loadComplaintItemList = (isRefresh = false, searchParams = null) => { |
|
|
|
// 非刷新模式下,检查是否正在加载或已加载完成 |
|
|
|
if (!isRefresh && (complaintFinished.value || complaintLoading.value)) return; |
|
|
|
|
|
|
|
if (isRefresh) { |
|
|
|
complaintPageNum.value = 1; |
|
|
|
complaintFinished.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
// 合并搜索参数 |
|
|
|
const params = { |
|
|
|
pageNum: complaintPageNum.value, |
|
|
|
pageSize: complaintPageSize.value, |
|
|
|
...complaintSearchParams.value, |
|
|
|
...(searchParams || {}) |
|
|
|
}; |
|
|
|
|
|
|
|
complaintLoading.value = true; |
|
|
|
getComplaintItemList(params, (res) => { |
|
|
|
let rows = []; |
|
|
|
if (Array.isArray(res)) rows = res; |
|
|
|
else if (res && Array.isArray(res.rows)) rows = res.rows; |
|
|
|
else if (res && Array.isArray(res.data)) rows = res.data; |
|
|
|
else if (res && res.data && Array.isArray(res.data.rows)) rows = res.data.rows; |
|
|
|
complaintItemList.value = rows.map(mapComplaintItem); |
|
|
|
|
|
|
|
const total = res?.total ?? res?.data?.total ?? 0; |
|
|
|
|
|
|
|
if (isRefresh) { |
|
|
|
complaintItemList.value = rows.map(mapComplaintItem); |
|
|
|
} else { |
|
|
|
complaintItemList.value = [...complaintItemList.value, ...rows.map(mapComplaintItem)]; |
|
|
|
} |
|
|
|
|
|
|
|
if (rows.length === 0 || complaintItemList.value.length >= total) { |
|
|
|
complaintFinished.value = true; |
|
|
|
} else { |
|
|
|
complaintPageNum.value++; |
|
|
|
} |
|
|
|
complaintLoading.value = false; |
|
|
|
}, () => { |
|
|
|
showToast('投诉事项加载失败'); |
|
|
|
complaintLoading.value = false; |
|
|
|
complaintFinished.value = true; |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 投诉事项弹窗搜索处理 |
|
|
|
const onComplaintItemSearch = (searchParams) => { |
|
|
|
complaintSearchParams.value = { ...searchParams }; |
|
|
|
loadComplaintItemList(true); |
|
|
|
}; |
|
|
|
|
|
|
|
const onComplaintItemSelect = (item) => { |
|
|
|
form.value.complaintItem = item.title; |
|
|
|
form.value.complaintItemCode = item.code || ''; |
|
|
|
form.value.complaintItemId = item.id || ''; |
|
|
|
showComplaintItemPicker.value = false; |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 地址级联选择数据 ========== |
|
|
|
@ -335,7 +389,7 @@ const showPicker = (field) => { |
|
|
|
} else if (field === 'complaintItem') { |
|
|
|
showComplaintItemPicker.value = true; |
|
|
|
// 投诉事项不缓存,每次打开都刷新 |
|
|
|
loadComplaintItemList(); |
|
|
|
loadComplaintItemList(true); |
|
|
|
} else if (field === 'address') { |
|
|
|
showAddressPicker.value = true; |
|
|
|
// 未加载时触发区级字典请求(已有缓存不重复调用) |
|
|
|
@ -368,22 +422,27 @@ const onAfterReadImage = (file) => { |
|
|
|
const files = Array.isArray(file) ? file : [file]; |
|
|
|
files.forEach(f => { |
|
|
|
uploadFile(f, (res) => { |
|
|
|
// 直接取返回的 data 字段(字符串路径) |
|
|
|
const data = res && res.data ? res.data : res; |
|
|
|
// 兼容后端返回结构 |
|
|
|
f.url = (data && (data.url || data.fileUrl || data.path)) || f.url; |
|
|
|
f.fileName = (data && (data.fileName || data.name || data.originalFilename)) || (f.file && f.file.name) || ''; |
|
|
|
const filePath = typeof data === 'string' ? data : (data && (data.url || data.fileUrl || data.path)) || ''; |
|
|
|
if (filePath) { |
|
|
|
// 设置文件对象的 url 属性,保持预览显示 |
|
|
|
f.url = filePath; |
|
|
|
f.status = 'done'; |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 将 form.images 转换为提交用的 fileList |
|
|
|
// 将 form.images 转换为提交用的 fileList(纯字符串数组) |
|
|
|
const buildFileList = () => { |
|
|
|
return (form.value.images || []) |
|
|
|
.filter(img => img && (img.url || img.content)) |
|
|
|
.map(img => ({ |
|
|
|
url: img.url || '', |
|
|
|
fileName: img.fileName || (img.file && img.file.name) || '' |
|
|
|
})); |
|
|
|
.map(img => { |
|
|
|
// 转换为纯字符串路径 |
|
|
|
return img.url || ''; |
|
|
|
}) |
|
|
|
.filter(Boolean); |
|
|
|
}; |
|
|
|
|
|
|
|
// ========== 提交表单 ========== |
|
|
|
@ -395,34 +454,44 @@ const onSubmit = () => { |
|
|
|
showToast('附件上传中,请稍后'); |
|
|
|
return; |
|
|
|
} |
|
|
|
// const enterpriseAddress = ['深圳市', form.value.addressArea, form.value.addressDetail] |
|
|
|
// .filter(Boolean) |
|
|
|
// .join(' '); |
|
|
|
const payload = { |
|
|
|
enforceType: form.value.complaintTypeCode, |
|
|
|
linkman: form.value.contactName, |
|
|
|
linkmanTel: form.value.contactPhone, |
|
|
|
problemDescription: form.value.content, |
|
|
|
authorization: form.value.authorized ? 1 : 0, |
|
|
|
addressArea: '深圳市' + form.value.addressArea, |
|
|
|
addressDetail: form.value.addressDetail, |
|
|
|
fileList: buildFileList(), |
|
|
|
complaintItemCodes: form.value.complaintItemCode || '', |
|
|
|
complaintItemNames: form.value.complaintItem || '', |
|
|
|
complaintDepartments: form.value.bureauDept || '', |
|
|
|
complaintDepartmentIds: form.value.bureauDeptId || '' |
|
|
|
}; |
|
|
|
submitting.value = true; |
|
|
|
addComplaint(payload, () => { |
|
|
|
submitting.value = false; |
|
|
|
showToast('提交成功,我们将尽快处理'); |
|
|
|
setTimeout(() => { |
|
|
|
// 提交成功后直接回到我的页面,用 replace 清掉中间的投诉相关页面 |
|
|
|
router.replace({ name: 'myPage' }); |
|
|
|
}, 1200); |
|
|
|
}, (err) => { |
|
|
|
submitting.value = false; |
|
|
|
showToast((err && err.msg) || '提交失败,请稍后重试'); |
|
|
|
|
|
|
|
// 弹出确认对话框 |
|
|
|
showConfirmDialog({ |
|
|
|
title: '确认提交', |
|
|
|
message: '确认提交本次投诉建议吗?提交后将无法修改。', |
|
|
|
}).then(() => { |
|
|
|
// 确认提交 |
|
|
|
// const enterpriseAddress = ['深圳市', form.value.addressArea, form.value.addressDetail] |
|
|
|
// .filter(Boolean) |
|
|
|
// .join(' '); |
|
|
|
const payload = { |
|
|
|
enforceType: form.value.complaintTypeCode, |
|
|
|
linkman: form.value.contactName, |
|
|
|
linkmanTel: form.value.contactPhone, |
|
|
|
problemDescription: form.value.content, |
|
|
|
authorization: form.value.authorized ? 1 : 0, |
|
|
|
enterpriseAddress: '深圳市' + form.value.addressArea, |
|
|
|
detailedAddress: form.value.addressDetail, |
|
|
|
fileList: buildFileList(), |
|
|
|
complaintItemCodes: form.value.complaintItemCode || '', |
|
|
|
complaintItemNames: form.value.complaintItem || '', |
|
|
|
complaintDepartments: form.value.bureauDept || '', |
|
|
|
complaintDepartmentIds: form.value.bureauDeptId || '' |
|
|
|
}; |
|
|
|
submitting.value = true; |
|
|
|
addComplaint(payload, () => { |
|
|
|
submitting.value = false; |
|
|
|
showToast('提交成功,我们将尽快处理'); |
|
|
|
setTimeout(() => { |
|
|
|
// 提交成功后直接回到我的页面,用 replace 清掉中间的投诉相关页面 |
|
|
|
router.replace({ name: 'complaintList' }); |
|
|
|
}, 500); |
|
|
|
}, (err) => { |
|
|
|
submitting.value = false; |
|
|
|
showToast((err && err.msg) || '提交失败,请稍后重试'); |
|
|
|
}); |
|
|
|
}).catch(() => { |
|
|
|
// 取消提交 |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
@ -605,13 +674,13 @@ const onFailed = (errorInfo) => { |
|
|
|
.address-field { |
|
|
|
padding: 0.15rem 0.3rem 0.3rem; |
|
|
|
background: transparent; |
|
|
|
margin-left: 70px; |
|
|
|
margin-left: 86px; |
|
|
|
box-sizing: border-box; |
|
|
|
width: 80%; |
|
|
|
|
|
|
|
:deep(.van-field__control) { |
|
|
|
font-size: 0.32rem; |
|
|
|
color: #999; |
|
|
|
color: #333; |
|
|
|
text-align: left; |
|
|
|
} |
|
|
|
|
|
|
|
|