Commit 6cf093b5 by yuzhenWang

优化6

parent 0f248261
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
/> />
<!-- Select (支持 dictType / api / options) --> <!-- Select (支持 dictType / api / options) -->
<el-select <!-- <el-select
v-else-if="item.type === 'select'" v-else-if="item.type === 'select'"
v-model="localModel[item.prop]" v-model="localModel[item.prop]"
:multiple="!!item.multiple" :multiple="!!item.multiple"
...@@ -63,6 +63,32 @@ ...@@ -63,6 +63,32 @@
:label="opt.label" :label="opt.label"
:value="opt.value" :value="opt.value"
/> />
</el-select> -->
<!-- @focus="() => loadRemoteOptions(item, '')" -->
<el-select
v-else-if="item.type === 'select'"
:ref="
el => {
if (el) selectRefs[item.prop] = el
}
"
v-model="localModel[item.prop]"
:multiple="!!item.multiple"
:placeholder="item.placeholder || `请选择${item.label}`"
:clearable="true"
filterable
:remote="!!item.api"
:remote-method="query => handleRemoteSearch(query, item)"
:loading="remoteLoading[item.prop] || false"
:disabled="item.disabled"
@change="val => handleModelChange(val, item)"
>
<el-option
v-for="opt in getSelectOptions(item)"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select> </el-select>
<!-- Date --> <!-- Date -->
<el-date-picker <el-date-picker
...@@ -293,6 +319,21 @@ import dayjs from 'dayjs' ...@@ -293,6 +319,21 @@ import dayjs from 'dayjs'
import * as PDFJS from 'pdfjs-dist' import * as PDFJS from 'pdfjs-dist'
PDFJS.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.mjs' PDFJS.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.mjs'
// ==================== select ====================
const selectRefs = ref({})
// 新增远程搜索入口(带防抖)
let remoteSearchTimer = null
function handleRemoteSearch(query, item) {
if (!item.api) return
// 🔥 关键修改:如果 query 为空且当前已有选项数据,则不重新加载
if (query === '' && remoteOptions.value[item.prop] && remoteOptions.value[item.prop].length > 0) {
return
}
clearTimeout(remoteSearchTimer)
remoteSearchTimer = setTimeout(async () => {
await loadRemoteOptions(item, query)
}, item.debounceWait || 300)
}
// ==================== 文件预览弹窗 ==================== // ==================== 文件预览弹窗 ====================
const filePreviewRef = ref(null) const filePreviewRef = ref(null)
const previewDialogVisible = ref(false) const previewDialogVisible = ref(false)
...@@ -307,7 +348,6 @@ function previewFile(file, item) { ...@@ -307,7 +348,6 @@ function previewFile(file, item) {
}) })
} }
// 删除文件(复用原有删除逻辑) // 删除文件(复用原有删除逻辑)
function removeFile(file, item) { function removeFile(file, item) {
const fileList = localModel.value[item.prop] || [] const fileList = localModel.value[item.prop] || []
...@@ -659,6 +699,19 @@ function handleModelChange(value, item) { ...@@ -659,6 +699,19 @@ function handleModelChange(value, item) {
} }
} }
localModel.value = newModel localModel.value = newModel
// 🔥 新增:多选远程 select,选中后清空搜索关键词
if (item.type === 'select' && item.multiple && item.api && selectRefs.value[item.prop]) {
const selectInstance = selectRefs.value[item.prop]
// 获取 el-select 内部的 input 元素
const inputElement = selectInstance.$el?.querySelector('input')
if (inputElement && inputElement.value) {
inputElement.value = ''
// 触发 input 事件,让组件内部同步状态
inputElement.dispatchEvent(new Event('input', { bubbles: true }))
loadRemoteOptions(item, '')
}
}
nextTick(() => { nextTick(() => {
if (!isEqualShallow(props.modelValue, newModel)) { if (!isEqualShallow(props.modelValue, newModel)) {
emit('update:modelValue', newModel) emit('update:modelValue', newModel)
...@@ -766,40 +819,80 @@ async function loadRemoteOptionsForInit(item) { ...@@ -766,40 +819,80 @@ async function loadRemoteOptionsForInit(item) {
} }
// 加载远程 API 选项(focus 时调用,无搜索词) // 加载远程 API 选项(focus 时调用,无搜索词)
async function loadRemoteOptions(item) { // async function loadRemoteOptions(item) {
const { prop, api, requestParams } = item // const { prop, api, requestParams } = item
// if (!api) return
// // 如果已经有选项且不是强制刷新,可跳过;但为了保证初次加载,remoteOptions[prop] 为空时才加载
// if (remoteOptions.value[prop] && remoteOptions.value[prop].length > 0) return
// try {
// remoteLoading.value[prop] = true
// const payload = {
// ...(typeof requestParams === 'function' ? requestParams() : requestParams || {})
// }
// const res = await request({
// url: api,
// method: 'post',
// data: payload
// })
// const list =
// typeof item.transform === 'function'
// ? item.transform(res)
// : res.data?.records || res.data || []
// const newOptions = list.map(i => ({
// value: String(i[item.valueKey || 'value']),
// label: i[item.labelKey || 'label'],
// raw: i
// }))
// remoteOptions.value[prop] = newOptions
// markDictLoaded(prop)
// // 同步 extra 字段
// const currentVal = localModel.value[prop]
// if (currentVal !== undefined && currentVal !== null && currentVal !== '') {
// syncExtraFieldsForProp(prop, currentVal)
// }
// } catch (err) {
// ElMessage.error(`加载 ${item.label} 失败`)
// remoteOptions.value[prop] = []
// } finally {
// remoteLoading.value[prop] = false
// }
// }
// 修改原有的 loadRemoteOptions,使其支持关键词参数
async function loadRemoteOptions(item, keyword = '') {
const { prop, api, requestParams, keywordField = 'keyword' } = item
if (!api) return if (!api) return
// 如果已经有选项且不是强制刷新,可跳过;但为了保证初次加载,remoteOptions[prop] 为空时才加载
if (remoteOptions.value[prop] && remoteOptions.value[prop].length > 0) return
try { try {
remoteLoading.value[prop] = true remoteLoading.value[prop] = true
const payload = { let params = typeof requestParams === 'function' ? requestParams() : requestParams || {}
...(typeof requestParams === 'function' ? requestParams() : requestParams || {}) if (keyword) {
params = { ...params, [keywordField]: keyword }
} else {
// 可选:重置分页参数为第一页
params = { ...params, pageNo: 1 }
} }
const res = await request({ const res = await request({ url: api, method: 'post', data: params })
url: api,
method: 'post',
data: payload
})
const list = const list =
typeof item.transform === 'function' typeof item.transform === 'function'
? item.transform(res) ? item.transform(res)
: res.data?.records || res.data || [] : res.data?.records || res.data || []
const newOptions = list.map(i => ({ remoteOptions.value[prop] = list.map(i => ({
value: String(i[item.valueKey || 'value']), value: String(i[item.valueKey || 'value']),
label: i[item.labelKey || 'label'], label: i[item.labelKey || 'label'],
raw: i raw: i
})) }))
remoteOptions.value[prop] = newOptions
markDictLoaded(prop) markDictLoaded(prop)
// 同步 extra 字段
const currentVal = localModel.value[prop] const currentVal = localModel.value[prop]
if (currentVal !== undefined && currentVal !== null && currentVal !== '') { if (currentVal !== undefined && currentVal !== null && currentVal !== '') {
syncExtraFieldsForProp(prop, currentVal) syncExtraFieldsForProp(prop, currentVal)
...@@ -811,7 +904,6 @@ async function loadRemoteOptions(item) { ...@@ -811,7 +904,6 @@ async function loadRemoteOptions(item) {
remoteLoading.value[prop] = false remoteLoading.value[prop] = false
} }
} }
// 远程搜索(带关键词,防抖) // 远程搜索(带关键词,防抖)
let searchTimeout = null let searchTimeout = null
function handleFilterChange(keyword, item) { function handleFilterChange(keyword, item) {
...@@ -938,7 +1030,7 @@ onMounted(async () => { ...@@ -938,7 +1030,7 @@ onMounted(async () => {
}) })
) )
} else if (item.type === 'select' && item.api) { } else if (item.type === 'select' && item.api) {
apiPromises.push(loadRemoteOptionsForInit(item)) apiPromises.push(loadRemoteOptions(item, ''))
} else if (item.type === 'select' && item.options) { } else if (item.type === 'select' && item.options) {
remoteOptions.value[key] = [...item.options] remoteOptions.value[key] = [...item.options]
markDictLoaded(key) markDictLoaded(key)
...@@ -991,26 +1083,31 @@ defineExpose({ ...@@ -991,26 +1083,31 @@ defineExpose({
localModel.value = { ...resetData } localModel.value = { ...resetData }
nextTick(() => formRef.value?.clearValidate()) nextTick(() => formRef.value?.clearValidate())
}, },
// async refreshRemoteOptions(targetProp) {
// const item = internalConfig.value.find(i => i.prop === targetProp)
// if (!item) {
// console.warn(`[SearchForm] 未找到 prop 为 ${targetProp} 的配置项`)
// return
// }
// if (item.type !== 'select' || !item.api) {
// console.warn(`[SearchForm] 字段 ${targetProp} 不是远程 Select 或没有 API`)
// return
// }
// remoteOptions.value[targetProp] = []
// remoteLoading.value[targetProp] = true
// try {
// await loadRemoteOptions(item)
// } catch (error) {
// console.error(`[SearchForm] ${targetProp} 加载失败`, error)
// throw error
// } finally {
// remoteLoading.value[targetProp] = false
// }
// }
async refreshRemoteOptions(targetProp) { async refreshRemoteOptions(targetProp) {
const item = internalConfig.value.find(i => i.prop === targetProp) const item = internalConfig.value.find(i => i.prop === targetProp)
if (!item) { if (!item || item.type !== 'select' || !item.api) return
console.warn(`[SearchForm] 未找到 prop 为 ${targetProp} 的配置项`) await loadRemoteOptions(item, '')
return
}
if (item.type !== 'select' || !item.api) {
console.warn(`[SearchForm] 字段 ${targetProp} 不是远程 Select 或没有 API`)
return
}
remoteOptions.value[targetProp] = []
remoteLoading.value[targetProp] = true
try {
await loadRemoteOptions(item)
} catch (error) {
console.error(`[SearchForm] ${targetProp} 加载失败`, error)
throw error
} finally {
remoteLoading.value[targetProp] = false
}
} }
}) })
</script> </script>
......
...@@ -1051,12 +1051,12 @@ const addCheckRecordFormModel = ref({}) ...@@ -1051,12 +1051,12 @@ const addCheckRecordFormModel = ref({})
const addCheckRecordFormRef = ref(null) const addCheckRecordFormRef = ref(null)
const addCheckRecordFormDialogFlag = ref(false) const addCheckRecordFormDialogFlag = ref(false)
const addCheckRecordConfig = [ const addCheckRecordConfig = [
{ // {
type: 'month', // type: 'month',
prop: 'reconciliationYearMonth', // prop: 'reconciliationYearMonth',
label: '检核年月', // label: '检核年月',
placeholder: '检核年月' // placeholder: '检核年月'
}, // },
{ {
type: 'select', type: 'select',
prop: 'fortuneBizType', prop: 'fortuneBizType',
......
...@@ -456,11 +456,11 @@ const payableReportListTableColumns = ref([ ...@@ -456,11 +456,11 @@ const payableReportListTableColumns = ref([
formatter: row => getDictLabel('csf_expected_fortune_status', row.status) || '-' formatter: row => getDictLabel('csf_expected_fortune_status', row.status) || '-'
}, },
{ {
prop: 'currencyName', prop: 'payoutCurrency',
label: '出账币种', label: '出账币种',
sortable: true, sortable: true,
width: '100', width: '100',
formatter: row => row.currencyName || '-' formatter: row => row.payoutCurrency || '-'
}, },
{ {
prop: 'fortunePeriod', prop: 'fortunePeriod',
......
...@@ -157,8 +157,7 @@ ...@@ -157,8 +157,7 @@
/> />
<el-table-column fixed="right" label="操作" min-width="120"> <el-table-column fixed="right" label="操作" min-width="120">
<template #default="scope"> <template #default="scope">
<div style="display: flex; gap: 8px;"> <div style="display: flex; gap: 8px">
<!-- 👇 新增:查看按钮 --> <!-- 👇 新增:查看按钮 -->
<!-- <el-button <!-- <el-button
link link
...@@ -183,7 +182,6 @@ ...@@ -183,7 +182,6 @@
</el-button> </el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -239,7 +237,7 @@ import CommonDialog from '@/components/commonDialog' ...@@ -239,7 +237,7 @@ import CommonDialog from '@/components/commonDialog'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue' import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue'
import { getPolicyfollow, getProductList } from '@/api/sign/underwritingMain' import { getPolicyfollow, getProductList } from '@/api/sign/underwritingMain'
import { uploadOssFileList,delUploadFile } from '@/api/common' import { uploadOssFileList, delUploadFile } from '@/api/common'
import { getProcessDetail } from '@/api/sign/fna' import { getProcessDetail } from '@/api/sign/fna'
import { premiumReconciliationList } from '@/api/sign/policy' import { premiumReconciliationList } from '@/api/sign/policy'
import { loadDicts, getDictLabel } from '@/utils/useDict' import { loadDicts, getDictLabel } from '@/utils/useDict'
...@@ -247,7 +245,7 @@ import { getNowTime, formatToDate, formatToDateTime } from '@/utils/date' ...@@ -247,7 +245,7 @@ import { getNowTime, formatToDate, formatToDateTime } from '@/utils/date'
import EditableTable from '@/components/csf-common/EditableTable.vue' import EditableTable from '@/components/csf-common/EditableTable.vue'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import FileUploader from '@/components/LargeFileUploader/index.vue'; import FileUploader from '@/components/LargeFileUploader/index.vue'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
proxy.useDictLists([ proxy.useDictLists([
...@@ -289,17 +287,17 @@ const props = defineProps({ ...@@ -289,17 +287,17 @@ const props = defineProps({
default: '' default: ''
} }
}) })
const uploaderRef = ref(null); const uploaderRef = ref(null)
// 【关键】当弹窗关闭时,强制清空上传组件列表 // 【关键】当弹窗关闭时,强制清空上传组件列表
const handleDialogClose = () => { const handleDialogClose = () => {
if (uploaderRef.value) { if (uploaderRef.value) {
// 调用子组件暴露的清空方法 // 调用子组件暴露的清空方法
// 你需要在子组件中使用 defineExpose 暴露 clearList 方法 // 你需要在子组件中使用 defineExpose 暴露 clearList 方法
uploaderRef.value.clearList(); uploaderRef.value.clearList()
fileUploadDialogFlag.value = false fileUploadDialogFlag.value = false
getAttachmentListDetail(props.policyBizId) getAttachmentListDetail(props.policyBizId)
} }
}; }
const emit = defineEmits(['update:modelValue', 'submit', 'cancel', 'saveRow']) const emit = defineEmits(['update:modelValue', 'submit', 'cancel', 'saveRow'])
const introducerTableData = ref([]) const introducerTableData = ref([])
...@@ -319,7 +317,7 @@ const introducerConfig = [ ...@@ -319,7 +317,7 @@ const introducerConfig = [
internalCode: 'internalNumber', internalCode: 'internalNumber',
team: 'deptName', team: 'deptName',
phone: 'phone', phone: 'phone',
teamBizId:'deptBizId' teamBizId: 'deptBizId'
}, },
transform: res => { transform: res => {
return (res?.data.records || []).map(item => ({ return (res?.data.records || []).map(item => ({
...@@ -541,7 +539,7 @@ const policyInfoFormConfig = ref([ ...@@ -541,7 +539,7 @@ const policyInfoFormConfig = ref([
type: 'select', type: 'select',
prop: 'professionalInvestor', prop: 'professionalInvestor',
label: '专业投资者', label: '专业投资者',
defaultValue :'No', defaultValue: 'No',
options: [ options: [
{ label: '是', value: 'Yes' }, { label: '是', value: 'Yes' },
{ label: '否', value: 'No' } { label: '否', value: 'No' }
...@@ -692,7 +690,8 @@ const basicPlanFormConfig = ref([ ...@@ -692,7 +690,8 @@ const basicPlanFormConfig = ref([
categoryCodeList: [basicPlanFormData.value.insuranceCategoryCode || ''], categoryCodeList: [basicPlanFormData.value.insuranceCategoryCode || ''],
insuranceCompanyBizIdList: [basicPlanFormData.value.insuranceCompanyBizId || ''], insuranceCompanyBizIdList: [basicPlanFormData.value.insuranceCompanyBizId || ''],
pageNo: 1, pageNo: 1,
pageSize: 20 pageSize: 20,
productName: 'productName'
}), }),
placeholder: '请选择产品名称', placeholder: '请选择产品名称',
debounceWait: 500, debounceWait: 500,
...@@ -1042,7 +1041,9 @@ const activeTab = ref('basic') ...@@ -1042,7 +1041,9 @@ const activeTab = ref('basic')
const handleBeforeLeave = async (newTabName, oldTabName) => { const handleBeforeLeave = async (newTabName, oldTabName) => {
// console.log('切换前确认-----------------------', newTabName, oldTabName) // console.log('切换前确认-----------------------', newTabName, oldTabName)
// console.log(tabDirty.value) // console.log(tabDirty.value)
if(props.mode === 'viewDetail'){return;} if (props.mode === 'viewDetail') {
return
}
if (tabDirty.value[oldTabName]) { if (tabDirty.value[oldTabName]) {
try { try {
await ElMessageBox.confirm(`“${getTabLabel(oldTabName)}” 未提交,确定要切换吗?`, '提示', { await ElMessageBox.confirm(`“${getTabLabel(oldTabName)}” 未提交,确定要切换吗?`, '提示', {
...@@ -1127,7 +1128,7 @@ const handleSubmit = () => { ...@@ -1127,7 +1128,7 @@ const handleSubmit = () => {
activeTab: activeTab.value, activeTab: activeTab.value,
...localData.additionalPlans ...localData.additionalPlans
}) })
}else if (activeTab.value === 'attachment'){ } else if (activeTab.value === 'attachment') {
tabDirty.value.attachment = false tabDirty.value.attachment = false
emit('submit', { emit('submit', {
activeTab: activeTab.value activeTab: activeTab.value
...@@ -1141,17 +1142,16 @@ const handleCancel = () => { ...@@ -1141,17 +1142,16 @@ const handleCancel = () => {
emit('cancel') emit('cancel')
} }
// 删除附件 // 删除附件
const deleteFile = (row)=>{ const deleteFile = row => {
console.log(row) console.log(row)
const fileBizId = row.fileBizId || ''; const fileBizId = row.fileBizId || ''
delUploadFile(fileBizId,userStore.projectInfo.projectBizId).then(res=>{ delUploadFile(fileBizId, userStore.projectInfo.projectBizId).then(res => {
console.log(res) console.log(res)
if(res.code===200){ if (res.code === 200) {
getAttachmentListDetail(props.policyBizId) getAttachmentListDetail(props.policyBizId)
}else{ } else {
ElMessage.error('删除文件失败') ElMessage.error('删除文件失败')
} }
}) })
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment