Commit eb0cc621 by Sweet Zhang

searchform xiugai

parent 621b7859
...@@ -143,3 +143,12 @@ export function getInsuranceCompany(data) { ...@@ -143,3 +143,12 @@ export function getInsuranceCompany(data) {
method: 'post' method: 'post'
}) })
} }
// 通用excel导入
export function importExcel(data) {
return request({
url: '/oss/api/excel/import',
method: 'post',
data: data
})
}
...@@ -273,14 +273,6 @@ export function commissionEntryEditRecords(data) { ...@@ -273,14 +273,6 @@ export function commissionEntryEditRecords(data) {
}) })
} }
// 出账记录查询
export function payRecordList(data) {
return request({
url: '/csf/api/fortune/list/page/fortuneAccount',
method: 'post',
data: data
})
}
// 获取保单发佣列表 // 获取保单发佣列表
export function policyNoCommissionPayRecord(data) { export function policyNoCommissionPayRecord(data) {
...@@ -309,3 +301,62 @@ export function commissionExpectedRecord(data) { ...@@ -309,3 +301,62 @@ export function commissionExpectedRecord(data) {
data: data data: data
}) })
} }
// 出账记录查询
export function payRecordList(data) {
return request({
url: '/csf/api/fortune/pageByExpectedFortuneBizId',
method: 'post',
data: data
})
}
// 更新入账信息
export function updateCommissionExpected(data) {
return request({
url: '/csf/api/CommissionExpected/update',
method: 'post',
data: data
})
}
// 修改出账状态
export function updataPayrollStatus(data){
return request({
url: '/csf/api/fortune/update/status',
method: 'post',
data: data
})
}
// 批量新增检核记录
export function addPayrollCheckRecord(data){
return request({
url: '/csf/api/commission/addBatch',
method: 'post',
data: data
})
}
// 新增应收款
export function addReceivedFortune(data){
return request({
url: '/csf/api/CommissionExpected/add',
method: 'post',
data: data
})
}
// 新增出账记录
export function addPayRecord(data){
return request({
url: '/csf/api/expectedFortune/add',
method: 'post',
data: data
})
}
// 获取销售员详情
export function userSaleExpandDetail(data){
return request({
url: '/insurance/base/api/userSaleExpand/detail?userSaleBizId=' + data,
method: 'get',
})
}
<!-- components/SearchForm.vue -->
<template> <template>
<el-form :model="formModel" label-width="100px" size="default" label-position="top"> <el-form ref="formRef" :model="localModel" :rules="formRules" label-width="auto" v-bind="$attrs">
<el-row :gutter="20"> <el-row :gutter="20">
<template v-for="item in config" :key="item.prop"> <el-col v-for="item in visibleConfig" :key="item.prop" :span="item.span || 8">
<el-form-item :label="item.label" :prop="item.prop" :class="{ 'search-form-item': isSearch }">
<!-- Input --> <!-- Input -->
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-if="item.type === 'input'"> <el-input v-if="item.type === 'input'" v-model="localModel[item.prop]"
<el-form-item :label="item.label" :prop="item.prop" :rules="item.rules"> :placeholder="item.placeholder || `请输入${item.label}`" :clearable="true"
<el-input :model-value="formModel[item.prop]" @input="(val) => handleNumberInput(val, item)" @input="(val) => handleNumberInput(val, item)" />
:placeholder="item.placeholder || `请输入${item.label}`" clearable style="width: 100%" />
</el-form-item>
</el-col>
<!-- Remote Select (带 api 的 select) --> <!-- Select (支持 dictType / api / options) -->
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-else-if="item.type === 'select' && item.api"> <el-select v-else-if="item.type === 'select'" v-model="localModel[item.prop]"
<el-form-item :label="item.label" :prop="item.prop" :rules="item.rules"> :multiple="!!item.multiple" :placeholder="item.placeholder || `请选择${item.label}`"
<el-select ref="selectRefs[item.prop]" v-model="formModel[item.prop]" :clearable="true" filterable :loading="remoteLoading[item.prop] || false" @change="() => { }"
:placeholder="item.placeholder || `请选择${item.label}`" clearable filterable @focus="() => loadRemoteOptions(item)"
:multiple="item.multiple" :loading="item.loading" @filter-change="(keyword) => handleFilterChange(keyword, item)">
:no-match-text="item.noMatchText || '无匹配数据'" @filter="handleSelectFilter(item)" <el-option v-for="opt in getSelectOptions(item)" :key="opt.value" :label="opt.label"
@visible-change="handleVisibleChange(item)" @change="(val) => handleChange(item, val)" :value="opt.value" />
style="width: 100%">
<el-option v-for="opt in item._allOptions" :key="opt[item.valueKey || 'value']"
:label="opt[item.labelKey || 'label']" :value="opt[item.valueKey || 'value']" />
</el-select> </el-select>
</el-form-item>
</el-col>
<!-- Static Select / Dict Select --> <!-- Date -->
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-else-if="item.type === 'select'"> <el-date-picker v-else-if="item.type === 'date'" v-model="localModel[item.prop]" type="date"
<el-form-item :label="item.label" :prop="item.prop" :rules="item.rules"> :placeholder="`选择${item.label}`" value-format="YYYY-MM-DD" style="width: 100%"
<el-select v-model="formModel[item.prop]" :placeholder="item.placeholder || `请选择${item.label}`" :disabled-date="getDisabledDateFn(item)" @change="() => { }" />
clearable :filterable="item.filterable !== false" :multiple="item.multiple"
:no-match-text="item.noMatchText || '无匹配数据'"> <!-- Daterange -->
<el-option v-for="opt in item.options" :key="opt[item.valueKey || 'value']" <el-date-picker v-else-if="item.type === 'daterange'" v-model="localModel[item.prop]"
:label="opt[item.labelKey || 'label']" :value="opt[item.valueKey || 'value']" /> type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
</el-select> value-format="YYYY-MM-DD" :disabled-date="getDisabledDateFn(item)" style="width: 100%"
</el-form-item> @change="() => { }" />
</el-col>
<!-- Checkbox Group --> <!-- Checkbox Group -->
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-else-if="item.type === 'checkbox-group'"> <el-checkbox-group v-else-if="item.type === 'checkbox-group'" v-model="localModel[item.prop]"
<el-form-item :label="item.label" :prop="item.prop"> @change="() => { }">
<el-checkbox-group v-model="formModel[item.prop]"> <el-checkbox v-for="opt in getSelectOptions(item)" :key="opt.value" :label="opt.value">
<el-checkbox v-for="opt in item.options" :key="opt[item.valueKey || 'value']" {{ opt.label }}
:label="opt[item.valueKey || 'value']">
{{ opt[item.labelKey || 'label'] }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item>
</el-col>
<!-- Date -->
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-else-if="item.type === 'date'">
<el-form-item :label="item.label" :prop="item.prop">
<el-date-picker v-model="formModel[item.prop]" type="date"
:placeholder="item.placeholder || `请选择${item.label}`" :format="item.format || 'YYYY-MM-DD'"
:value-format="item.valueFormat || 'YYYY-MM-DD'" style="width: 100%" clearable />
</el-form-item>
</el-col>
<!-- Date Range --> <span v-else>Unsupported type: {{ item.type }}</span>
<el-col :xs="24" :sm="12" :md="6" :lg="6" v-else-if="item.type === 'daterange'">
<el-form-item :label="item.label" :prop="item.prop">
<el-date-picker v-model="formModel[item.prop]" type="daterange"
:range-separator="item.rangeSeparator || '至'"
:start-placeholder="item.startPlaceholder || '开始日期'"
:end-placeholder="item.endPlaceholder || '结束日期'" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
</template>
</el-row> </el-row>
</el-form> </el-form>
</template> </template>
<script setup> <script setup>
import { reactive, onMounted, onUnmounted } from 'vue' import { ref, watch, onMounted, nextTick, computed } from 'vue'
import { ElMessage } from 'element-plus'
// 🔑 引入你的字典方法
import useDictStore from '@/store/modules/dict'
import { getDicts } from '@/api/system/dict/data'
import request from '@/utils/request' import request from '@/utils/request'
import { loadDicts, getDictOptions } from '@/utils/useDict' import dayjs from 'dayjs'
// ==================== 工具函数:深拷贝配置(保留函数) ====================
function deepCloneConfig(obj) {
if (obj === null || typeof obj !== 'object') return obj
if (Array.isArray(obj)) return obj.map(deepCloneConfig)
const cloned = {}
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const val = obj[key]
cloned[key] = typeof val === 'function' ? val : deepCloneConfig(val)
}
}
return cloned
}
function parseToDate(str) {
if (!str) return null
if (str === 'today') {
return dayjs().startOf('day')
}
if (typeof str === 'string') {
const d = dayjs(str)
return d.isValid() ? d.startOf('day') : null
}
if (str instanceof Date) {
return dayjs(str).startOf('day')
}
return null
}
// ==================== 生成 disabledDate 函数 ====================
function getDisabledDateFn(item) {
const { minDate, maxDate } = item
const selectRefs = reactive({}) // 如果都没有限制,返回 null(不禁用任何日期)
if (minDate == null && maxDate == null) {
return () => false
}
// 新增 handleChange return (date) => {
function handleChange(item, value) { const currentDate = dayjs(date).startOf('day')
// 如果是多选,value 是数组;单选是值 let minD = null
// 这里不需要处理值,因为 v-model 已绑定 let maxD = null
// 清空 filter 输入框 // 解析最小日期
nextTick(() => { if (minDate != null) {
const ref = selectRefs[item.prop] if (typeof minDate === 'function') {
if (ref && typeof ref.inputValue === 'string') { const val = minDate(localModel.value)
ref.inputValue = '' minD = parseToDate(val)
} else {
minD = parseToDate(minDate)
}
}
// 解析最大日期
if (maxDate != null) {
if (typeof maxDate === 'function') {
const val = maxDate(localModel.value)
maxD = parseToDate(val)
} else {
maxD = parseToDate(maxDate)
}
}
// 判断是否被禁用
if (minD && currentDate.isBefore(minD)) {
return true
}
if (maxD && currentDate.isAfter(maxD)) {
return true
}
return false
} }
})
} }
// ======================== // ==================== Props & Emits ====================
// 工具函数
// ========================
const formModel = reactive({})
const props = defineProps({ const props = defineProps({
config: { type: Array, required: true } modelValue: { type: Object, default: () => ({}) },
config: { type: Array, default: () => [] },
isSearch: { type: Boolean, default: false }
}) })
// 防抖定时器 Map const emit = defineEmits(['update:modelValue'])
const debounceMap = new Map()
// 搜索缓存 Map: key = `${prop}:${keyword}`, value = option list
const searchCache = new Map()
// ======================== // ==================== Refs ====================
// 数字输入处理 const formRef = ref(null)
// ======================== const localModel = ref({})
function handleNumberInput(value, item) { const internalConfig = ref([])
const { inputType = 'text', decimalDigits = 2 } = item const remoteOptions = ref({}) // { prop: [options] }
if (inputType === 'text') { const remoteLoading = ref({}) // { prop: boolean }
formModel[item.prop] = value
return // ==================== 条件显隐 & 规则 ====================
const visibleConfig = computed(() => {
return internalConfig.value.filter(item => {
if (typeof item.visible === 'function') {
return item.visible(localModel.value)
} }
return true
})
})
let result = String(value) const formRules = computed(() => {
if (inputType === 'integer') { const rules = {}
result = result.replace(/[^\d]/g, '') visibleConfig.value.forEach(item => {
} else if (inputType === 'decimal') { if (item.rules) rules[item.prop] = item.rules
result = result.replace(/[^\d.]/g, '').replace(/^\./, '') })
const parts = result.split('.') return rules
if (parts.length > 2) result = parts[0] + '.' + parts.slice(1).join('') })
} else if (inputType === 'signed-decimal') {
result = result.replace(/[^\d.-]/g, '') // ==================== 双向绑定 ====================
if (result.startsWith('--')) result = '-' + result.slice(2) watch(() => props.modelValue, (newVal) => {
if (result.includes('-') && !result.startsWith('-')) result = result.replace(/-/g, '') if (newVal && typeof newVal === 'object') {
result = result.replace(/^\./, '') localModel.value = { ...newVal }
const parts = result.split('.')
if (parts.length > 2) result = parts[0] + '.' + parts.slice(1).join('')
} }
}, { immediate: true, deep: true })
if ((inputType === 'decimal' || inputType === 'signed-decimal') && decimalDigits >= 0) { watch(localModel, (newVal) => {
const dotIndex = result.indexOf('.') if (props.modelValue !== undefined) {
if (dotIndex !== -1) { emit('update:modelValue', { ...newVal })
const integerPart = result.slice(0, dotIndex)
let decimalPart = result.slice(dotIndex + 1).slice(0, decimalDigits)
result = integerPart + (decimalPart ? '.' + decimalPart : '')
} }
}, { deep: true })
// ==================== 加载字典选项 ====================
async function loadDictOptions(dictType) {
const dictStore = useDictStore()
let options = dictStore.getDict(dictType)
if (options && options.length > 0) {
return options
} }
formModel[item.prop] = result try {
const resp = await getDicts(dictType)
options = resp.data.map(p => ({
label: p.itemLabel,
value: p.itemValue
}))
dictStore.setDict(dictType, options)
return options
} catch (err) {
console.error(`加载字典 ${dictType} 失败`, err)
ElMessage.error(`字典 ${dictType} 加载失败`)
return []
}
} }
// ======================== // ==================== 初始化 ====================
// 远程选项请求 onMounted(async () => {
// ======================== internalConfig.value = deepCloneConfig(props.config)
async function fetchOptions(item, keyword = '') {
const payload = { const initialData = {}
...(item.requestParams || {}), const dictTypePromises = []
pageNo: item.pageNo || 1,
pageSize: item.pageSize || 20 for (const item of internalConfig.value) {
const key = item.prop
if (localModel.value[key] == null) {
if (item.multiple) {
initialData[key] = item.defaultValue ?? []
} else if (['checkbox-group', 'daterange'].includes(item.type)) {
initialData[key] = item.defaultValue ?? []
} else {
initialData[key] = item.defaultValue ?? ''
} }
if (keyword) {
const keyField = item.keywordField || 'keyword'
payload[keyField] = keyword.trim()
} }
const res = await request({ // 预加载 dictType
url: item.api, if (item.type === 'select' && item.dictType) {
method: item.method || 'POST', dictTypePromises.push(
data: payload loadDictOptions(item.dictType).then(opts => {
remoteOptions.value[key] = opts
}) })
)
} else if (item.type === 'select' && item.options) {
remoteOptions.value[key] = [...item.options]
}
// api 类型:延迟加载(focus 时)
}
let list = [] if (Object.keys(initialData).length > 0) {
if (typeof item.transform === 'function') { localModel.value = { ...localModel.value, ...initialData }
list = item.transform(res)
} else if (res?.data?.records) {
list = res.data.records
} else if (res?.data?.list) {
list = res.data.list
} else if (Array.isArray(res?.data)) {
list = res.data
} else if (res?.data?.data && Array.isArray(res.data.data)) {
list = res.data.data
}
return list
}
// ========================
// 远程搜索逻辑
// ========================
function handleSelectFilter(item, query) {
// 清除旧防抖
if (debounceMap.has(item.prop)) {
clearTimeout(debounceMap.get(item.prop))
} }
const timer = setTimeout(() => { // 等待所有字典加载完成
doRemoteSearch(item, query) await Promise.allSettled(dictTypePromises)
}, item.debounceWait ?? 300) })
debounceMap.set(item.prop, timer) // ==================== 获取 select 选项 ====================
function getSelectOptions(item) {
return remoteOptions.value[item.prop] || []
} }
async function doRemoteSearch(item, keyword) { // ==================== 加载远程 API 选项(首次 focus 时加载,无搜索词) ====================
const cacheKey = `${item.prop}:${keyword}` async function loadRemoteOptions(item) {
if (searchCache.has(cacheKey)) { const { prop, api, requestParams = {}, keywordField, debounceWait, ...rest } = item
item._allOptions = searchCache.get(cacheKey) if (!api || remoteOptions.value[prop]?.length > 0) return
return
}
item.loading = true
try { try {
let list = [] remoteLoading.value[prop] = true
if (!keyword.trim()) {
list = item._fullOptions || [] // 构造请求体:合并 requestParams + 分页(默认第一页)
} else { const payload = {
list = await fetchOptions(item, keyword) ...(requestParams || {})
} // 注意:此时无 keyword,所以不加 keywordField
item._allOptions = list
searchCache.set(cacheKey, list)
} catch (e) {
console.error(`${item.label} 搜索失败`, e)
item._allOptions = item._fullOptions || []
} finally {
item.loading = false
} }
}
// ======================== const res = await request({
// 下拉展开时懒加载全量 url: api,
// ======================== method: 'post', // ← 改为 POST
function handleVisibleChange(item, visible) { data: payload // ← 参数放 body
if (visible && !item._hasLoadedFull) {
item.loading = true
fetchOptions(item, '')
.then(list => {
item._allOptions = list
item._fullOptions = list
item._hasLoadedFull = true
searchCache.set(`${item.prop}:`, list) // 缓存空关键词
})
.catch(e => {
console.error('加载默认选项失败', e)
item._allOptions = []
})
.finally(() => {
item.loading = false
}) })
const list = typeof item.transform === 'function'
? item.transform(res)
: res.data?.records || res.data || []
remoteOptions.value[prop] = list.map(i => ({
value: i[item.valueKey || 'value'],
label: i[item.labelKey || 'label']
}))
} catch (err) {
ElMessage.error(`加载 ${item.label} 失败`)
remoteOptions.value[prop] = []
} finally {
remoteLoading.value[prop] = false
} }
} }
// ======================== // ==================== 远程搜索(带关键词,防抖) ====================
// 初始化 let searchTimeout = null
// ======================== function handleFilterChange(keyword, item) {
onMounted(async () => { const { prop, api, requestParams = {}, keywordField = 'keyword', debounceWait = 300 } = item
const dictTypes = [] if (!api) return
const dictItems = []
for (const item of props.config) { clearTimeout(searchTimeout)
// 初始化表单值 searchTimeout = setTimeout(async () => {
if (['checkbox-group', 'daterange'].includes(item.type)) {
formModel[item.prop] = item.defaultValue ?? []
} else {
formModel[item.prop] = item.defaultValue ?? ''
}
if (item.type === 'select' && item.api) {
item._allOptions = []
item._fullOptions = []
item.loading = true
try { try {
const list = await fetchOptions(item, '') // 无关键词,加载默认列表 remoteLoading.value[prop] = true
item._allOptions = list
item._fullOptions = list
item._hasLoadedFull = true
searchCache.set(`${item.prop}:`, list) // 缓存空关键词结果
} catch (e) {
console.error(`预加载 ${item.label} 默认选项失败`, e)
item._allOptions = []
} finally {
item.loading = false
}
}
// 处理数字输入
if (item.type === 'input' && item.inputType && item.inputType !== 'text') {
handleNumberInput(formModel[item.prop], item)
}
// 收集字典项 // 构造请求体:requestParams + 分页 + 动态关键词字段
if (item.type === 'select' && item.dictType) { const payload = {
dictTypes.push(item.dictType) ...(requestParams || {}),
dictItems.push(item) [keywordField]: keyword // ← 动态字段名,如 name / companyName
} }
const res = await request({
url: api,
method: 'post', // ← POST 请求
data: payload // ← body 传参
})
const list = typeof item.transform === 'function'
? item.transform(res)
: res.data?.records || res.data || []
remoteOptions.value[prop] = list.map(i => ({
value: i[item.valueKey || 'value'],
label: i[item.labelKey || 'label']
}))
} catch (err) {
ElMessage.error(`搜索 ${item.label} 失败`)
} finally {
remoteLoading.value[prop] = false
} }
}, debounceWait)
}
// 加载字典 // ==================== 数字输入处理 ====================
if (dictTypes.length > 0) { function handleNumberInput(value, item) {
await loadDicts(dictTypes) const { inputType = 'text', decimalDigits = 2, prop } = item
for (const item of dictItems) { if (!prop) return
item.options = getDictOptions(item.dictType)
let result = String(value ?? '').trim()
if (inputType === 'integer') {
result = result.replace(/[^\d]/g, '')
} else if (inputType === 'decimal') {
result = result.replace(/[^\d.]/g, '').replace(/^\./, '')
const parts = result.split('.')
if (parts.length > 2) {
result = parts[0] + '.' + parts.slice(1).join('')
}
if (result.includes('.')) {
const [intPart, decPart] = result.split('.')
const trimmedDec = decPart.slice(0, decimalDigits)
result = intPart + (trimmedDec ? '.' + trimmedDec : '')
if (result.endsWith('.')) result = result.slice(0, -1)
} }
} }
})
// ======================== localModel.value = { ...localModel.value, [prop]: result }
// 清理 }
// ========================
onUnmounted(() => {
debounceMap.forEach(timer => clearTimeout(timer))
debounceMap.clear()
searchCache.clear()
})
// ======================== // ==================== 暴露方法 ====================
// 暴露方法
// ========================
defineExpose({ defineExpose({
async validate() {
// 如果你有 el-form ref,可加校验;否则直接返回
return formModel
},
getSearchParams() { getSearchParams() {
const params = {} return { ...localModel.value }
for (const key in formModel) { },
const val = formModel[key] getFormData() {
if (val === '' || val === null || val === undefined) continue return { ...localModel.value }
if (Array.isArray(val) && val.length === 0) continue },
params[key] = val async validate() {
} return new Promise((resolve, reject) => {
return params formRef.value?.validate((valid) => {
if (valid) resolve(localModel.value)
else reject(new Error('Validation failed'))
})
})
}, },
resetForm() { resetForm() {
props.config.forEach(item => { const resetData = {}
internalConfig.value.forEach(item => {
const key = item.prop
if (['checkbox-group', 'daterange'].includes(item.type)) { if (['checkbox-group', 'daterange'].includes(item.type)) {
formModel[item.prop] = [] resetData[key] = item.defaultValue ?? []
} else { } else {
formModel[item.prop] = '' resetData[key] = item.defaultValue ?? ''
} }
}) })
}, localModel.value = { ...resetData }
getRawForm() { nextTick(() => formRef.value?.clearValidate())
return { ...formModel }
} }
}) })
</script> </script>
<style scoped>
.search-form-item {
margin-bottom: 20px;
}
</style>
\ No newline at end of file
...@@ -101,8 +101,8 @@ ...@@ -101,8 +101,8 @@
</el-table> </el-table>
</template> </template>
</CommonPage> </CommonPage>
<!-- 弹窗--> <!-- 新增出账检核页面-->
<CommonDialog dialogTitle='弹窗' dialogWidth='80%' :openDialog=dialogFlag :showAction='false' :showClose='true' <CommonDialog dialogTitle='新增出账检核' dialogWidth='80%' :openDialog=dialogFlag :showAction='false' :showClose='true'
@close='dialogFlag = false'> @close='dialogFlag = false'>
</CommonDialog> </CommonDialog>
...@@ -118,7 +118,9 @@ import { ElMessage } from 'element-plus' ...@@ -118,7 +118,9 @@ import { ElMessage } from 'element-plus'
import { formatCurrency } from '@/utils/number' import { formatCurrency } from '@/utils/number'
// 接口 // 接口
import { getPolicyFortuneList } from '@/api/financial/commission' import { getPolicyFortuneList } from '@/api/financial/commission'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
// 分页相关 // 分页相关
const currentPage = ref(1) const currentPage = ref(1)
const pageSize = ref(10) const pageSize = ref(10)
...@@ -134,10 +136,10 @@ const searchConfig = ref([ ...@@ -134,10 +136,10 @@ const searchConfig = ref([
}, { }, {
type: 'select', type: 'select',
prop: 'status', prop: 'status',
label: '账状态', label: '账状态',
multiple: true, multiple: true,
dictType: 'csf_expected_commission_status' dictType: 'csf_fortune_status'
}, { },{
type: 'select', type: 'select',
prop: 'insuranceCompanyBizIdList', prop: 'insuranceCompanyBizIdList',
label: '保险公司', label: '保险公司',
...@@ -158,7 +160,10 @@ const searchConfig = ref([ ...@@ -158,7 +160,10 @@ const searchConfig = ref([
label: '产品计划', label: '产品计划',
api: '/product/api/relProjectProductLaunch/parameter/page', api: '/product/api/relProjectProductLaunch/parameter/page',
keywordField: 'productName', keywordField: 'productName',
requestParams: { fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20 }, requestParams: {
tenantBizId: userStore.projectInfo.tenantBizId || '',
projectBizId: userStore.projectInfo.projectBizId || '', fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20
},
placeholder: '输入产品计划名称搜索', placeholder: '输入产品计划名称搜索',
debounceWait: 500, // 自定义防抖时间 debounceWait: 500, // 自定义防抖时间
valueKey: 'productLaunchBizId', valueKey: 'productLaunchBizId',
...@@ -172,13 +177,14 @@ const searchConfig = ref([ ...@@ -172,13 +177,14 @@ const searchConfig = ref([
label: '出账日(估)', label: '出账日(估)',
startPlaceholder: '开始时间', startPlaceholder: '开始时间',
endPlaceholder: '结束时间' endPlaceholder: '结束时间'
}, {
type: 'select',
prop: 'status',
label: '出账状态',
multiple: true,
dictType: 'csf_fortune_status'
}, },
// {
// type: 'select',
// prop: 'status',
// label: '入账状态',
// multiple: true,
// dictType: 'csf_expected_commission_status'
// },
]) ])
// 表格操作菜单 // 表格操作菜单
const dropdownItems = [ const dropdownItems = [
...@@ -209,7 +215,7 @@ const handleReset = () => { ...@@ -209,7 +215,7 @@ const handleReset = () => {
console.log('表单已重置') console.log('表单已重置')
} }
const handleQuery = async () => { const handleQuery = async () => {
const params = searchFormRef.value.getSearchParams() const params = searchFormRef.value.getFormData()
console.log('父组件发起查询:', params) console.log('父组件发起查询:', params)
loadTableData(params) loadTableData(params)
} }
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
<el-table-column prop="policyNo" label="保单号" width="120" sortable /> <el-table-column prop="policyNo" label="保单号" width="120" sortable />
<el-table-column prop="reconciliationCompany" label="对账公司" width="120" sortable /> <el-table-column prop="reconciliationCompany" label="对账公司" width="120" sortable />
<el-table-column prop="commissionDate" label="入账日" width="120" sortable /> <el-table-column prop="commissionDate" label="入账日" width="120" sortable />
<el-table-column prop="status" label="比对状态" width="120" sortable /> <el-table-column prop="status" label="入账状态" width="120" sortable :formatter="formatStatus" />
<el-table-column prop="currentCommissionRatio" label="本次入账比例" width="130" sortable /> <el-table-column prop="currentCommissionRatio" label="本次入账比例" width="130" sortable />
<el-table-column prop="periodPaidRatio" label="累积入账比例" width="130" sortable /> <el-table-column prop="periodPaidRatio" label="累积入账比例" width="130" sortable />
<el-table-column prop="periodPendingRatio" label="待入账比例" width="120" sortable /> <el-table-column prop="periodPendingRatio" label="待入账比例" width="120" sortable />
...@@ -125,12 +125,13 @@ ...@@ -125,12 +125,13 @@
</el-table> </el-table>
<!-- 表格操作菜单 --> <!-- 表格操作菜单 -->
<div class="tableOptionContainer"> <div class="tableOptionContainer">
<el-button type="primary" :icon="Select">生成可出账记录</el-button> <el-button type="primary" :icon="Select" :disabled="updatePayRollStatusDisable"
@click="generateCommissionRecordapi">生成可出账记录</el-button>
</div> </div>
</template> </template>
</CommonPage> </CommonPage>
<!-- 开始检核弹窗--> <!-- 开始检核弹窗-->
<CommonDialog dialogTitle='开始检核' dialogWidth='80%' :openDialog=dialogFlag :showAction='true' :showClose='true' <CommonDialog dialogTitle='开始检核' dialogWidth='80%' :openDialog=dialogFlag :showAction='false' :showClose='true'
@close='dialogFlag = false'> @close='dialogFlag = false'>
<el-row> <el-row>
<el-col :xs="24" :sm="24" :md="24" :lg="24"> <el-col :xs="24" :sm="24" :md="24" :lg="24">
...@@ -139,12 +140,12 @@ ...@@ -139,12 +140,12 @@
</el-row> </el-row>
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="3" :lg="3"> <el-col :xs="24" :sm="12" :md="3" :lg="3">
<el-button type="primary" :icon="Plus" :disabled="!checkFormRef?.getSearchParams().reconciliationYearMonth" <el-button type="primary" :icon="Plus" :disabled="!checkFormRef?.getFormData().reconciliationYearMonth"
@click="addCheckRecordDialogFlag = true">新增</el-button> @click="addCheckRecordDialogFlag = true; searchParams = checkFormRef.getFormData()">新增</el-button>
</el-col> </el-col>
<el-col :xs="24" :sm="24" :md="3" :lg="3"> <el-col :xs="24" :sm="24" :md="3" :lg="3">
<el-button type="primary" :icon="Upload" :disabled="!checkFormRef?.getSearchParams().reconciliationYearMonth" <el-button type="primary" :icon="Upload" :disabled="!checkFormRef?.getFormData().reconciliationYearMonth"
@click="fileUploadDialogFlag = true">导入</el-button> @click="fileUploadDialogFlag = true; searchParams = checkFormRef.getFormData()">导入</el-button>
</el-col> </el-col>
<el-col :xs="24" :sm="24" :md="3" :lg="3"> <el-col :xs="24" :sm="24" :md="3" :lg="3">
<el-button link type="primary">下载导入模板 </el-button> <el-button link type="primary">下载导入模板 </el-button>
...@@ -153,18 +154,18 @@ ...@@ -153,18 +154,18 @@
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :xs="24" :sm="24" :md="24" :lg="24"> <el-col :xs="24" :sm="24" :md="24" :lg="24">
<el-table :data="checkRecordTableData" style="width: 100%"> <el-table :data="checkRecordTableData" style="width: 100%">
<el-table-column prop="name" label="应收款类型" width="120" /> <el-table-column prop="commissionBizType" label="应收款类型" width="120" />
<el-table-column prop="state" label="应收款编号" width="120" /> <el-table-column prop="receivableNo" label="应收款编号" width="120" />
<el-table-column prop="city" label="关联保单号" width="120" /> <el-table-column prop="policyNo" label="关联保单号" width="120" />
<el-table-column prop="address" label="佣金期数" width="120" /> <el-table-column prop="status" label="比对状态" width="120" />
<el-table-column prop="zip" label="总期数" width="120" /> <el-table-column prop="commissionPeriod" label="佣金期数" width="120" />
<el-table-column prop="zip" label="入账日(估)" width="120" /> <el-table-column prop="totalPeriod" label="总期数" width="120" />
<el-table-column prop="zip" label="入账日(实)" width="120" /> <el-table-column prop="commissionDate" label="入账日(实)" width="120" />
<el-table-column prop="zip" label="入账金额" width="120" /> <el-table-column prop="amount" label="入账金额" width="120" />
<el-table-column prop="zip" label="入账币种" width="120" /> <el-table-column prop="currency" label="入账币种" width="120" />
<el-table-column prop="zip" label="入账项目" width="120" /> <el-table-column prop="commissionName" label="入账项目" width="120" />
<el-table-column prop="zip" label="对账公司" width="120" /> <el-table-column prop="reconciliationCompany" label="对账公司" width="120" />
<el-table-column prop="zip" label="入账状态" width="120" /> <!-- <el-table-column prop="zip" label="入账状态" width="120" /> -->
<el-table-column fixed="right" label="操作" min-width="120"> <el-table-column fixed="right" label="操作" min-width="120">
<template #default> <template #default>
<el-button link type="primary" size="small" @click="checkRecordEdit(row)"> <el-button link type="primary" size="small" @click="checkRecordEdit(row)">
...@@ -178,21 +179,10 @@ ...@@ -178,21 +179,10 @@
</el-row> </el-row>
</CommonDialog> </CommonDialog>
<!-- 新增检核记录弹窗 --> <!-- 新增检核记录弹窗 -->
<CommonDialog dialogTitle='新增检核记录' dialogWidth='80%' :openDialog=addCheckRecordDialogFlag :showAction='true' <CommonDialog dialogTitle='新增检核记录' dialogWidth='80%' :openDialog=addCheckRecordDialogFlag :showAction='true'
:showClose='true' @close='addCheckRecordDialogFlag = false'> :showClose='true' @close='addCheckRecordDialogFlag = false' @confirm='handleAddCheckRecord()'>
<el-row> <el-row>
<el-col :xs="24" :sm="24" :md="24" :lg="24"> <el-col :xs="24" :sm="24" :md="24" :lg="24">
<SearchForm ref="addCheckRecordFormRef" :config="addCheckRecordConfig" /> <SearchForm ref="addCheckRecordFormRef" :config="addCheckRecordConfig" />
...@@ -201,28 +191,46 @@ ...@@ -201,28 +191,46 @@
</CommonDialog> </CommonDialog>
<CommonDialog dialogTitle='文件导入' dialogWidth='80%' :openDialog=fileUploadDialogFlag :showAction='true' <CommonDialog dialogTitle='文件导入' dialogWidth='80%' :openDialog=fileUploadDialogFlag :showAction='true'
:showClose='true' @close='fileUploadDialogFlag = false'> :showClose='true' @close='fileUploadDialogFlag = false; files = ""'>
<FileUpload <FileUpload v-model="files" :data="{ headerRow: 0 }" :file-type="['xlsx', 'xls']" :action="'/oss/api/excel/import'"
v-model="files" :limit="1" :fileSize="15" />
:data="{ reconciliationYearMonth: checkFormRef?.getSearchParams().reconciliationYearMonth }" :file-type="['xlsx','xls']"
:action="'/csf/api/commission/upload/excel'" :limit="1"
/>
</CommonDialog> </CommonDialog>
<!-- 设置比对状态 -->
<CommonDialog dialogTitle='设置比对状态' dialogWidth='80%' :openDialog=setCompareStatusDialogFlag :showAction='true'
:showClose='true' @close='setCompareStatusDialogFlag = false;'>
<SearchForm ref="setCompareStatusFormRef" :config="setCompareStatusConfig" />
</CommonDialog>
<!-- 更新数据 -->
<CommonDialog dialogTitle='更新数据' dialogWidth='80%' :openDialog=updateDataDialogFlag :showAction='true'
:showClose='true' @close='updateDataDialogFlag = false;'>
</CommonDialog>
<!-- 查看记录 -->
<CommonDialog dialogTitle='查看记录' dialogWidth='80%' :openDialog=viewRecordDialogFlag :showAction='true'
:showClose='true' @close='viewRecordDialogFlag = false;'>
</CommonDialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive } from 'vue' import { ref, reactive, onMounted } from 'vue'
import CommonPage from '@/components/commonPage' import CommonPage from '@/components/commonPage'
import CommonDialog from '@/components/commonDialog' import CommonDialog from '@/components/commonDialog'
import SearchForm from '@/components/SearchForm/SearchForm.vue' import SearchForm from '@/components/SearchForm/SearchForm.vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { formatCurrency } from '@/utils/number' import { formatCurrency } from '@/utils/number'
// 接口 // 接口
import { getPolicyCommissionList } from '@/api/financial/commission' import { getPolicyCommissionList, generateCommissionRecord, addPayrollCheckRecord, commissionExpectedRecord } from '@/api/financial/commission'
import { Plus, Upload } from '@element-plus/icons-vue' import { Plus, Upload, Select } from '@element-plus/icons-vue'
import FileUpload from '@/components/FileUpload/index.vue' import FileUpload from '@/components/FileUpload/index.vue'
import { loadDicts, getDictLabel } from '@/utils/useDict'
const files = ref('')
// 分页相关 // 分页相关
const currentPage = ref(1) const currentPage = ref(1)
const pageSize = ref(10) const pageSize = ref(10)
...@@ -270,13 +278,14 @@ const searchConfig = ref([ ...@@ -270,13 +278,14 @@ const searchConfig = ref([
endPlaceholder: '结束时间' endPlaceholder: '结束时间'
}, { }, {
type: 'select', type: 'select',
prop: 'insurerBizId', prop: 'insuranceCompanyBizIdList',
label: '保险公司', label: '保险公司',
api: '/insurance/base/api/insuranceCompany/page', api: '/insurance/base/api/insuranceCompany/page',
keywordField: 'queryContent', keywordField: 'queryContent',
requestParams: { pageNo: 1, pageSize: 20 }, requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入保险公司名称搜索', placeholder: '输入保险公司名称搜索',
debounceWait: 500, // 自定义防抖时间 debounceWait: 500, // 自定义防抖时间
multiple: true,
valueKey: 'insuranceCompanyBizId', valueKey: 'insuranceCompanyBizId',
labelKey: 'abbreviation', labelKey: 'abbreviation',
transform: (res) => { transform: (res) => {
...@@ -293,6 +302,24 @@ const searchConfig = ref([ ...@@ -293,6 +302,24 @@ const searchConfig = ref([
} }
]) ])
// 设置比对状态
const setCompareStatusDialogFlag = ref(false)
const setCompareStatusConfig = ref([
{
type: 'select',
prop: 'status',
label: '比对状态',
dictType: 'csf_commission_status'
}
])
const setCompareStatusFormRef = ref(null)
// 更新数据
const updateDataDialogFlag = ref(false)
// 查看记录
const viewRecordDialogFlag = ref(false)
const fileUploadDialogFlag = ref(false) const fileUploadDialogFlag = ref(false)
const checkRecordTableData = ref([]) const checkRecordTableData = ref([])
...@@ -314,6 +341,22 @@ const checkRecordEdit = (row) => { ...@@ -314,6 +341,22 @@ const checkRecordEdit = (row) => {
console.log(row) console.log(row)
} }
// 生成可出账记录按钮
const updatePayRollStatusDisable = ref(true)
// 获取入账状态,字典值转化方法
onMounted(async () => {
try {
await loadDicts(['csf_expected_commission_status'])
} catch (error) {
console.error('字典加载失败', error)
} finally {
loading.value = false
}
})
// 格式化函数(每次渲染都会调用,所以能拿到最新字典)
const formatStatus = (row, column) => {
return getDictLabel('csf_expected_commission_status', row.status) // 实时查缓存
}
// 应收单类型 // 应收单类型
const commissionBizTypeOptions = [ const commissionBizTypeOptions = [
{ value: 'R', label: '关联保单应收单' }, { value: 'R', label: '关联保单应收单' },
...@@ -330,7 +373,7 @@ const addCheckRecordFormRef = ref(null) ...@@ -330,7 +373,7 @@ const addCheckRecordFormRef = ref(null)
const addCheckRecordConfig = ref([ const addCheckRecordConfig = ref([
{ {
type: 'select', type: 'select',
prop: 'reconciliationYearMonth', prop: 'commissionBizType',
label: '应收单类型', label: '应收单类型',
placeholder: '应收单类型', placeholder: '应收单类型',
options: commissionBizTypeOptions options: commissionBizTypeOptions
...@@ -342,7 +385,7 @@ const addCheckRecordConfig = ref([ ...@@ -342,7 +385,7 @@ const addCheckRecordConfig = ref([
}, },
{ {
type: 'input', type: 'input',
prop: 'fortunePeriod', prop: 'commissionPeriod',
label: '佣金期数', label: '佣金期数',
inputType: 'decimal', inputType: 'decimal',
rules: [ rules: [
...@@ -350,7 +393,7 @@ const addCheckRecordConfig = ref([ ...@@ -350,7 +393,7 @@ const addCheckRecordConfig = ref([
] ]
}, { }, {
type: 'input', type: 'input',
prop: 'fortunePeriod', prop: 'totalPeriod',
label: '总期数', label: '总期数',
inputType: 'decimal', inputType: 'decimal',
rules: [ rules: [
...@@ -358,17 +401,12 @@ const addCheckRecordConfig = ref([ ...@@ -358,17 +401,12 @@ const addCheckRecordConfig = ref([
] ]
}, { }, {
type: 'date', type: 'date',
prop: 'expectedDate', prop: 'commissionDate',
label: '入账日(估)',
placeholder: '请选择'
}, {
type: 'date',
prop: 'expectedDate',
label: '入账日(实)', label: '入账日(实)',
placeholder: '请选择' placeholder: '请选择'
}, { }, {
type: 'input', type: 'input',
prop: 'fortunePeriod', prop: 'amount',
label: '入账金额', label: '入账金额',
inputType: 'decimal', inputType: 'decimal',
rules: [ rules: [
...@@ -376,13 +414,12 @@ const addCheckRecordConfig = ref([ ...@@ -376,13 +414,12 @@ const addCheckRecordConfig = ref([
] ]
}, { }, {
type: 'select', type: 'select',
prop: 'statusList', prop: 'currency',
label: '入账币种', label: '入账币种',
multiple: true, dictType: 'bx_currency_type'
dictType: 'csf_expected_fortune_status'
}, { }, {
type: 'select', type: 'select',
prop: 'fortuneName', prop: 'commissionName',
label: '入账项目', label: '入账项目',
dictType: 'csf_commission_type' dictType: 'csf_commission_type'
}, { }, {
...@@ -401,46 +438,61 @@ const addCheckRecordConfig = ref([ ...@@ -401,46 +438,61 @@ const addCheckRecordConfig = ref([
console.log(res) console.log(res)
return res?.data.records || [] return res?.data.records || []
} }
}, { }
type: 'select',
prop: 'statusList',
label: '入账状态',
multiple: true,
dictType: 'csf_expected_commission_status'
},
]) ])
const addCheckRecordDialogFlag = ref(false) const addCheckRecordDialogFlag = ref(false)
const handleAddCheckRecord = async () => {
try {
const addCheckSearchParams = addCheckRecordFormRef.value.getFormData()
const params = {
...addCheckSearchParams,
reconciliationYearMonth: searchParams.value.reconciliationYearMonth
}
await addPayrollCheckRecord([params])
ElMessage.success('新增检核记录成功')
addCheckRecordDialogFlag.value = false
checkRecordTableData.value = []
checkRecordQuery()
} catch (error) {
console.error('新增检核记录失败', error)
ElMessage.error('新增检核记录失败')
}
}
// 生成可出账记录
const generateCommissionRecordapi = async () => {
try {
const res = await generateCommissionRecord({
commissionBizIdList: multipleSelection.value.map(item => item.commissionBizId)
})
if (res.code === 200) {
ElMessage.success('生成可出账记录成功')
} else {
ElMessage.error(res.msg || '生成可出账记录失败')
}
} catch (error) {
console.error('生成可出账记录失败', error)
ElMessage.error('生成可出账记录失败')
}
}
// 表格操作菜单 // 表格操作菜单
const dropdownItems = [ const dropdownItems = [
{ label: '设置比对状态', value: 'setStatus' }, { label: '设置比对状态', value: 'setStatus' },
{ label: '更新', value: 'editRecord' }, { label: '更新数据', value: 'editRecord' },
{ label: '查看记录', value: 'viewRecord' }, { label: '查看记录', value: 'viewRecord' }
{ label: '更新数据', value: 'updateData' },
] ]
// 统计信息 // 统计信息
const statisticsData = ref({ const statisticsData = ref({})
paidAmountRatio: 0,
pendingPaidAmount: 0,
totalAmount: 0,
totalPaidAmount: 0,
totalPolicyCount: 0
})
// 弹窗相关 // 弹窗相关
const dialogFlag = ref(false) const dialogFlag = ref(false)
// 按钮事件处理 // 按钮事件处理
const handleAdd = () => { const handleAdd = () => {
// ElMessage.info('点击新增按钮') // 开始检核
dialogFlag.value = true dialogFlag.value = true
} }
const handleImport = () => {
ElMessage.info('点击导入按钮')
}
const handleExport = () => { const handleExport = () => {
ElMessage.info('点击导出按钮') ElMessage.info('点击导出按钮')
} }
...@@ -451,17 +503,34 @@ const handleReset = () => { ...@@ -451,17 +503,34 @@ const handleReset = () => {
console.log('表单已重置') console.log('表单已重置')
} }
const handleQuery = async () => { const handleQuery = async () => {
const params = searchFormRef.value.getSearchParams() const params = searchFormRef.value.getFormData()
console.log('父组件发起查询:', params) console.log('父组件发起查询:', params)
loadTableData(params) loadTableData(params)
} }
// 查询检核记录
const checkRecordQuery = async () => {
try {
const params = {
reconciliationYearMonth: searchParams.value.reconciliationYearMonth
}
const res = await commissionExpectedRecord(params)
checkRecordTableData.value = res.data.records || []
} catch (error) {
console.error('查询检核记录失败', error)
ElMessage.error('查询检核记录失败')
}
}
const multipleSelection = ref([]) const multipleSelection = ref([])
const handleSelectionChange = (val) => { const handleSelectionChange = (val) => {
multipleSelection.value = val multipleSelection.value = val
console.log('全选:', val) console.log('全选:', val)
// 生成可出账记录按钮是否禁用
updatePayRollStatusDisable.value = val.length === 0
} }
const visibleDefaultButtons = ref(['add', 'export', 'reset', 'query']) const visibleDefaultButtons = ref(['add', 'reset', 'query'])
// 按钮配置 // 按钮配置
const operationBtnList = ref([ const operationBtnList = ref([
{ {
...@@ -470,11 +539,11 @@ const operationBtnList = ref([ ...@@ -470,11 +539,11 @@ const operationBtnList = ref([
label: '开始检核', label: '开始检核',
click: handleAdd click: handleAdd
}, },
{ // {
key: 'export', // key: 'export',
direction: 'right', // direction: 'right',
click: handleExport // click: handleExport
}, // },
{ {
key: 'reset', key: 'reset',
direction: 'right', direction: 'right',
...@@ -496,7 +565,8 @@ const loadTableData = async (searchParams = {}) => { ...@@ -496,7 +565,8 @@ const loadTableData = async (searchParams = {}) => {
pageSize: pageSize.value, pageSize: pageSize.value,
...searchParams, ...searchParams,
commissionDateStart: searchParams.commissionDate?.[0] || undefined, commissionDateStart: searchParams.commissionDate?.[0] || undefined,
commissionDateEnd: searchParams.commissionDate?.[1] || undefined commissionDateEnd: searchParams.commissionDate?.[1] || undefined,
commissionDate:undefined
} }
const res = await getPolicyCommissionList(params) const res = await getPolicyCommissionList(params)
tableData.value = res.data.page.records || [] tableData.value = res.data.page.records || []
...@@ -524,8 +594,18 @@ const handleCurrentChange = (val) => { ...@@ -524,8 +594,18 @@ const handleCurrentChange = (val) => {
// 表格数据 // 表格数据
const tableData = ref([]) const tableData = ref([])
const handleSelect = (row) => { const handleSelect = (e, row) => {
console.log('选中行:', row) console.log('选中行:', e, row)
if (row === 'setStatus') {
setCompareStatusDialogFlag.value = true
return
} else if (row === 'editRecord') {
updateDataDialogFlag.value = true
return
} else if (row === 'viewRecord') {
viewRecordDialogFlag.value = true
return
}
} }
...@@ -538,7 +618,8 @@ const handleSelect = (row) => { ...@@ -538,7 +618,8 @@ const handleSelect = (row) => {
margin-top: 10px; margin-top: 10px;
} }
.el-row { .el-row,
margin-bottom: 10px; .el-col {
margin-bottom: 5px;
} }
</style> </style>
\ No newline at end of file
...@@ -82,10 +82,8 @@ import { ...@@ -82,10 +82,8 @@ import {
getReferrerFortuneList, getReferrerFortuneList,
salaryStatistics, salaryStatistics,
} from '@/api/financial/commission' } from '@/api/financial/commission'
// import { searchIntermediaries } from '@/api/search'
import { formatCurrency } from '@/utils/number' import { formatCurrency } from '@/utils/number'
import { debounce } from '@/utils/index'; import { ElMessageBox, ElMessage } from 'element-plus'
import { ElMessageBox } from 'element-plus'
import SearchForm from '@/components/SearchForm/SearchForm.vue' import SearchForm from '@/components/SearchForm/SearchForm.vue'
const searchFormRef = ref(null) const searchFormRef = ref(null)
const searchParams = ref({}) const searchParams = ref({})
...@@ -115,9 +113,10 @@ const searchConfig = ref([ ...@@ -115,9 +113,10 @@ const searchConfig = ref([
}, },
{ {
type: 'select', type: 'select',
prop: 'status', prop: 'statusList',
label: '出账状态', label: '出账状态',
dictType: 'csf_fortune_account_status' dictType: 'csf_fortune_account_status',
multiple: true,
} }
]) ])
// 添加表格引用 // 添加表格引用
...@@ -264,7 +263,7 @@ const getStatusType = status => { ...@@ -264,7 +263,7 @@ const getStatusType = status => {
// 查询 // 查询
const handleQuery = () => { const handleQuery = () => {
const params = searchFormRef.value.getSearchParams() const params = searchFormRef.value.getFormData()
console.log('父组件发起查询:', params) console.log('父组件发起查询:', params)
clearAllSelection() clearAllSelection()
getList(params) getList(params)
...@@ -373,29 +372,7 @@ const fetchCompletePolicyFortune = async row => { ...@@ -373,29 +372,7 @@ const fetchCompletePolicyFortune = async row => {
} catch (error) { } } catch (error) { }
} }
const searchLoading = ref(false)
const brokerOptions = ref([])
// 获取转介人列表
const loadBrokers = async (query = '') => {
searchLoading.value = true
const params = {
realName: query,
pageNo: 1,
pageSize: 1000,
}
try {
// const res = await searchIntermediaries(params)
// if (res.code === 200) {
// brokerOptions.value = res.data.records || []
// searchLoading.value = false
// } else {
// brokerOptions.value = []
// searchLoading.value = false
// }
} catch (error) { }
}
debounce(loadBrokers, 500, false)
const visibleDefaultButtons = ref(['reset', 'query']) const visibleDefaultButtons = ref(['reset', 'query'])
// 按钮配置 // 按钮配置
const operationBtnList = ref([ const operationBtnList = ref([
......
...@@ -69,8 +69,9 @@ ...@@ -69,8 +69,9 @@
{{ getFortuneBizTypeLabel(row.fortuneBizType) }} {{ getFortuneBizTypeLabel(row.fortuneBizType) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="payableNo" label="应付款编号" width="120" sortable/> <el-table-column prop="payableNo" label="应付款编号" width="120" sortable />
<el-table-column prop="policyNo" label="保单号" width="120" sortable/> <el-table-column prop="policyNo" label="保单号" width="120" sortable />
<el-table-column prop="broker" label="转介人" width="120" sortable />
<el-table-column prop="status" label="出账状态" width="120" sortable> <el-table-column prop="status" label="出账状态" width="120" sortable>
<template #default="{ row }"> <template #default="{ row }">
{{ getDictLabel('csf_expected_fortune_status', row.status) }} {{ getDictLabel('csf_expected_fortune_status', row.status) }}
...@@ -112,6 +113,7 @@ ...@@ -112,6 +113,7 @@
{{ formatCurrency(row.unpaidAmount) }} {{ formatCurrency(row.unpaidAmount) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="broker_ratio" label="持有比例" width="120" sortable />
<el-table-column prop="insurerBizId" label="保险公司" width="120" sortable /> <el-table-column prop="insurerBizId" label="保险公司" width="120" sortable />
<el-table-column prop="productLaunchBizId" label="产品计划" width="120" sortable /> <el-table-column prop="productLaunchBizId" label="产品计划" width="120" sortable />
<el-table-column prop="premium" label="期交保费" width="120" sortable> <el-table-column prop="premium" label="期交保费" width="120" sortable>
...@@ -119,6 +121,7 @@ ...@@ -119,6 +121,7 @@
{{ formatCurrency(row.premium) }} {{ formatCurrency(row.premium) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="statusDesc" label="修改理由" width="150" />
<el-table-column prop="remark" label="备注" width="150" /> <el-table-column prop="remark" label="备注" width="150" />
<el-table-column fixed="right" label="操作" min-width="120"> <el-table-column fixed="right" label="操作" min-width="120">
<template #default="{ row }"> <template #default="{ row }">
...@@ -140,13 +143,25 @@ ...@@ -140,13 +143,25 @@
</template> </template>
</CommonPage> </CommonPage>
<!-- 出账记录表格弹窗--> <!-- 出账记录表格弹窗-->
<!-- <CommonDialog dialogTitle="出账记录" dialogWidth="80%" :openDialog="payRecordDialogTableVisible" :showAction="false" <CommonDialog dialogTitle="出账记录" dialogWidth="80%" :openDialog="payRecordDialogTableVisible" :showAction="true"
:showClose="true" @close="payRecordDialogTableVisible = false"> :showClose="true" @close="payRecordDialogTableVisible = false">
<el-table :data="payRecordDialogTableData" border style="width: 100%"> <el-table :data="payRecordDialogTableData" border style="width: 100%">
<el-table-column v-for="item in payRecordDialogTableColumns" :key="item.property" :property="item.property" <el-table-column v-for="item in payRecordDialogTableColumns" :key="item.property" :property="item.property"
:label="item.label" :width="item.width" /> :label="item.label" :width="item.width" />
</el-table> </el-table>
</CommonDialog> --> </CommonDialog>
<!-- 新增出账记录 -->
<CommonDialog dialogTitle="新增出账记录" dialogWidth="80%" :openDialog="addPayRecordDialogVisible" :showAction="true"
:showClose="true" @close="addPayRecordDialogVisible = false" @confirm="handleConfirmAddPayRecord">
<SearchForm ref="addPayRecordFormRef" :config="addPayRecordFormConfig" />
</CommonDialog>
<!-- 设置出账状态 -->
<CommonDialog dialogTitle="设置出账状态" dialogWidth="80%" :openDialog="setPayRecordStatusDialogVisible"
:showAction="false" :showClose="true" @close="setPayRecordStatusDialogVisible = false"
@confirm="handleConfirmSetPayRecordStatus">
<SearchForm ref="setPayRecordStatusFormRef" :config="setPayRecordStatusFormConfig" />
</CommonDialog>
</div> </div>
</template> </template>
...@@ -155,10 +170,29 @@ import CommonPage from '@/components/commonPage' ...@@ -155,10 +170,29 @@ import CommonPage from '@/components/commonPage'
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { formatCurrency } from '@/utils/number' import { formatCurrency } from '@/utils/number'
import { expectedFortuneList, payRecordList } from '@/api/financial/commission' import { expectedFortuneList, payRecordList, addPayRecord, userSaleExpandDetail } from '@/api/financial/commission'
import SearchForm from '@/components/SearchForm/SearchForm.vue' import SearchForm from '@/components/SearchForm/SearchForm.vue'
import CommonDialog from '@/components/commonDialog'
import { getDictLabel } from '@/utils/useDict';
import useUserStore from '@/store/modules/user'
// 设置出账状态
const setPayRecordStatusDialogVisible = ref(false)
const selectedRow = ref(null)
const setPayRecordStatusFormRef = ref(null)
const setPayRecordStatusFormConfig = ref([
{
type: 'select',
prop: 'status',
label: '出账状态',
dictType: 'csf_expected_fortune_status'
}, {
type: 'textarea',
prop: 'statusDesc',
label: '修改理由',
},
])
import {getDictLabel} from '@/utils/useDict'; const userStore = useUserStore()
// 应收单类型 // 应收单类型
const fortuneBizTypeOptions = [ const fortuneBizTypeOptions = [
{ value: 'R', label: '关联保单应付单' }, { value: 'R', label: '关联保单应付单' },
...@@ -227,7 +261,10 @@ const searchConfig = ref([ ...@@ -227,7 +261,10 @@ const searchConfig = ref([
label: '产品计划', label: '产品计划',
api: '/product/api/relProjectProductLaunch/parameter/page', api: '/product/api/relProjectProductLaunch/parameter/page',
keywordField: 'productName', keywordField: 'productName',
requestParams: { fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20 }, requestParams: {
tenantBizId: userStore.projectInfo.tenantBizId || '',
projectBizId: userStore.projectInfo.projectBizId || '', fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20
},
placeholder: '输入产品计划名称搜索', placeholder: '输入产品计划名称搜索',
debounceWait: 500, // 自定义防抖时间 debounceWait: 500, // 自定义防抖时间
valueKey: 'productLaunchBizId', valueKey: 'productLaunchBizId',
...@@ -259,6 +296,141 @@ const searchConfig = ref([ ...@@ -259,6 +296,141 @@ const searchConfig = ref([
} }
}, },
]) ])
const payRecordDialogTableVisible = ref(false)
// 新增出账记录
const addPayRecordDialogVisible = ref(false)
const addPayRecordFormRef = ref()
const addPayRecordFormConfig = ref([
{
type: 'select',
prop: 'fortuneBizType',
label: '应付单类型',
options: [
{ value: 'R', label: '关联保单应付单' },
{ value: 'U', label: '非关联保单应付单' }
]
}, {
type: 'input',
prop: 'policyNo',
label: '关联保单号'
}, {
type: 'input',
prop: 'fortunePeriod',
label: '佣金期数',
inputType: 'decimal',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
type: 'input',
prop: 'fortuneTotalPeriod',
label: '总期数',
inputType: 'decimal',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
type: 'date',
prop: 'payoutDate',
label: '出账日(估)',
placeholder: '请选择'
}, {
type: 'date',
prop: 'actualPayoutDate',
label: '出账日(实)',
placeholder: '请选择'
}, {
type: 'input',
prop: 'amount',
label: '出账金额',
inputType: 'decimal',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
type: 'select',
prop: 'currency',
label: '出账币种',
dictType: 'bx_currency_type'
}, {
type: 'select',
prop: 'fortuneType',
label: '出账项目',
dictType: 'csf_fortune_type'
}, {
type: 'select',
prop: 'brokerBizId',
label: '转介人',
api: '/insurance/base/api/userSaleExpand/page',
keywordField: 'realName',
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入转介人名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'userSaleBizId',
labelKey: 'realName',
transform: (res) => {
return res?.data.records || []
}
}, {
type: 'select',
prop: 'status',
label: '出账状态',
dictType: 'csf_expected_fortune_status'
}
])
const handleConfirmAddPayRecord = async () => {
const handleConfirmAddPayRecordparams = addPayRecordFormRef.value.getFormData()
try {
await addPayRecord([handleConfirmAddPayRecordparams])
ElMessage.success('新增出账记录成功')
addPayRecordDialogVisible.value = false
} catch (error) {
ElMessage.error(error.message)
}
}
// 出账记录
const payRecordDialogTableData = ref([])
const payRecordDialogTableColumns = ref([])
const handleSelect = async (e, row) => {
selectedRow.value = row
if (e === 'payRecord') {
payRecordDialogTableVisible.value = true
loadPayRecordTableData(selectedRow.value.expectedFortuneBizId);
payRecordDialogTableColumns.value = [
{ property: 'broker', label: '转介人', width: '100', },
{ property: 'fortuneName', label: '出账项目', width: '150' },
{ property: 'amount', label: '出账金额', width: '150' },
{ property: 'currency', label: '出账币种', width: '150' },
{ property: 'amount', label: '出账比例', width: '150' },
{ property: 'currentCommissionRatio', label: '待出账比例', width: '150' },
{ property: 'fortunePeriod', label: '佣金期数', width: '150' },
{ property: 'fortuneTotalPeriod', label: '总期数', width: '150' },
{ property: 'updaterId', label: '操作人', width: '150' },
{ property: 'updateTime', label: '操作时间', width: '150' }
]
} else if (e === 'setStatus') {
setPayRecordStatusDialogVisible.value = true
setPayRecordStatusFormConfig.value = [
{
type: 'select',
prop: 'status',
label: '出账状态',
dictType: 'csf_expected_fortune_status',
defaultValue: selectedRow.value.status || ''
}, {
type: 'textarea',
prop: 'statusDesc',
label: '修改理由',
defaultValue: selectedRow.value.statusDesc || ''
},
]
}
}
// 分页相关 // 分页相关
const currentPage = ref(1) const currentPage = ref(1)
...@@ -275,18 +447,12 @@ const dropdownItems = [ ...@@ -275,18 +447,12 @@ const dropdownItems = [
const tableData = ref([]) const tableData = ref([])
// 统计信息 // 统计信息
const statisticsData = ref({ const statisticsData = ref({})
totalExpectedAmount: 0,
totalPaidAmount: 0,
totalUnpaidAmount: 0,
paidAmountRatio: 0,
totalPolicyCount: 0,
totalPremiumAmount: 0
})
// 按钮事件处理 // 按钮事件处理
const handleAdd = () => { const handleAdd = () => {
ElMessage.info('点击新增按钮') // ElMessage.info('点击新增按钮')
addPayRecordDialogVisible.value = true
} }
const handleImport = () => { const handleImport = () => {
...@@ -307,9 +473,7 @@ const handleReset = () => { ...@@ -307,9 +473,7 @@ const handleReset = () => {
} }
const handleQuery = async () => { const handleQuery = async () => {
const params = searchFormRef.value.getSearchParams() loadTableData()
console.log('父组件发起查询:', params)
loadTableData(params)
} }
// 按钮配置 // 按钮配置
...@@ -353,8 +517,8 @@ const handleCurrentChange = (val) => { ...@@ -353,8 +517,8 @@ const handleCurrentChange = (val) => {
} }
// 加载表格数据 // 加载表格数据
const loadTableData = async (searchParams = {}) => { const loadTableData = async () => {
console.log(searchFormRef.value) const searchParams = searchFormRef.value.getFormData() || {}
loading.value = true loading.value = true
try { try {
const params = { const params = {
...@@ -389,16 +553,14 @@ const loadTableData = async (searchParams = {}) => { ...@@ -389,16 +553,14 @@ const loadTableData = async (searchParams = {}) => {
} }
// 出账记录查询 // 出账记录查询
const loadPayRecordTableData = async () => { const loadPayRecordTableData = async (expectedFortuneBizId) => {
loading.value = true loading.value = true
try { try {
const params = { const params = {
expectedFortuneBizId: expectedFortuneBizId
} }
const response = await payRecordList(params) const response = await payRecordList(params)
payRecordDialogTableData.value = response.data.records payRecordDialogTableData.value = response.data.records
pageTotal.value = response.data.total
pageSize.value = response.data.size
} catch (error) { } catch (error) {
console.error('加载数据失败:', error) console.error('加载数据失败:', error)
...@@ -408,9 +570,33 @@ const loadPayRecordTableData = async () => { ...@@ -408,9 +570,33 @@ const loadPayRecordTableData = async () => {
} }
} }
// 设置出账状态确认
const handleConfirmSetPayRecordStatus = async () => {
const formData = setPayRecordStatusFormRef.value.getFormData() || {}
if (!formData.status) {
ElMessage.error('请选择出账状态')
return
}
if (!formData.statusDesc) {
ElMessage.error('请输入修改理由')
return
}
try {
const params = {
...formData,
fortuneBizIdList: [selectedRow.value.expectedFortuneBizId]
}
await updataPayrollStatus(params)
ElMessage.success('设置出账状态成功')
setPayRecordStatusDialogVisible.value = false
loadTableData()
} catch (error) {
console.error('设置出账状态失败:', error)
ElMessage.error('设置出账状态失败')
}
}
loadTableData()
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</el-table-column> </el-table-column>
<el-table-column prop="commissionPeriod" label="入账期数" width="120" sortable /> <el-table-column prop="commissionPeriod" label="入账期数" width="120" sortable />
<el-table-column prop="totalPeriod" label="入账总期数" width="120" sortable /> <el-table-column prop="totalPeriod" label="入账总期数" width="120" sortable />
<el-table-column prop="commissionType" label="入账项目" width="120" sortable /> <el-table-column prop="commissionName" label="入账项目" width="120" sortable />
<el-table-column prop="commissionDate" label="入账日(估)" width="120" sortable /> <el-table-column prop="commissionDate" label="入账日(估)" width="120" sortable />
<el-table-column prop="commissionRatio" label="入账比例(估)" width="140" sortable> <el-table-column prop="commissionRatio" label="入账比例(估)" width="140" sortable>
<template #default="{ row }"> <template #default="{ row }">
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</el-table-column> </el-table-column>
<el-table-column prop="paidRatio" label="已入账比例" width="120" sortable> <el-table-column prop="paidRatio" label="已入账比例" width="120" sortable>
<template #default="{ row }"> <template #default="{ row }">
{{ (row.ratio || 0) + '%' }} {{ (row.paidRatio || 0) + '%' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="paidAmount" label="已入账金额" width="120" sortable> <el-table-column prop="paidAmount" label="已入账金额" width="120" sortable>
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
{{ numberWithCommas(row.premium) }} {{ numberWithCommas(row.premium) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="statusDesc" label="入账状态修改理由" width="150" />
<el-table-column prop="remark" label="备注" width="150" /> <el-table-column prop="remark" label="备注" width="150" />
<el-table-column fixed="right" label="操作" min-width="120"> <el-table-column fixed="right" label="操作" min-width="120">
<template #default="{ row }"> <template #default="{ row }">
...@@ -133,26 +134,14 @@ ...@@ -133,26 +134,14 @@
</CommonDialog> </CommonDialog>
<CommonDialog dialogTitle="设置入账状态" dialogWidth="80%" :openDialog="setStatusDialogTableVisible" <CommonDialog dialogTitle="设置入账状态" dialogWidth="80%" :openDialog="setStatusDialogTableVisible"
@close="setStatusDialogTableVisible = false" @confirm="setStatusDialogTableVisible = false"> @close="setStatusDialogTableVisible = false" @confirm="handleConfirmSetStatus">
<el-form :model="form"> <SearchForm ref="setCommissionRecordStatusFormRef" :config="setCommissionRecordStatusFormConfig" />
<el-form-item label="入账状态" label-width="120"> </CommonDialog>
<el-select v-model="form.status" placeholder="请选择入账状态">
<el-option label="待入账" value="0" /> <!-- 新增应收款管理 -->
<el-option label="完成入账" value="1" /> <CommonDialog dialogTitle="新增应收款" dialogWidth="80%" :openDialog="addReceivablesDialogVisible"
<el-option label="部分入账" value="2" /> @close="addReceivablesDialogVisible = false" @confirm="handleConfirmAddReceivables">
<el-option label="已失效" value="3" /> <SearchForm ref="addRecordRef" :config="addReceivablesFormConfig" v-model="addReceivablesFormModel" />
</el-select>
</el-form-item>
<el-form-item label="修改理由" :label-width="120">
<el-input v-model="form.desc" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="setStatusDialogTableVisible = false">取消</el-button>
<el-button type="primary" @click="handleConfirmSetStatus">确认</el-button>
</div>
</template>
</CommonDialog> </CommonDialog>
</div> </div>
</template> </template>
...@@ -160,20 +149,127 @@ ...@@ -160,20 +149,127 @@
<script setup name="Receivables"> <script setup name="Receivables">
import CommonPage from '@/components/commonPage' import CommonPage from '@/components/commonPage'
import CommonDialog from '@/components/commonDialog' import CommonDialog from '@/components/commonDialog'
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue' import { MoreFilled } from '@element-plus/icons-vue'
import { receivedFortuneList, commissionEntryRecord, commissionEntryEditRecords, exportReceivedFortune, commissionExpectedRecord } from '@/api/financial/commission' import { receivedFortuneList, updateCommissionExpected, commissionEntryEditRecords, exportReceivedFortune, commissionExpectedRecord, addReceivedFortune } from '@/api/financial/commission'
import { numberWithCommas } from '@/utils/index' import { numberWithCommas } from '@/utils/index'
import SearchForm from '@/components/SearchForm/SearchForm.vue' import SearchForm from '@/components/SearchForm/SearchForm.vue'
import { getDictLabel } from '@/utils/useDict'; import { getDictLabel } from '@/utils/useDict';
import { safeDownload } from '@/utils/safeDownload' import { safeDownload } from '@/utils/safeDownload'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
// 应收单类型 // 应收单类型
const commissionBizTypeOptions = [ const commissionBizTypeOptions = [
{ value: 'R', label: '关联保单应收单' }, { value: 'R', label: '关联保单应收单' },
{ value: 'U', label: '非关联保单应收单' } { value: 'U', label: '非关联保单应收单' }
] ]
// 新增应收款管理
const addReceivablesFormModel = reactive({
commissionBizType: 'U',
})
const addReceivablesDialogVisible = ref(false)
const addRecordRef = ref(null)
const addReceivablesFormConfig = [
{
type: 'select',
prop: 'commissionBizType',
label: '应收单类型',
placeholder: '应收单类型',
options: commissionBizTypeOptions
},
{
type: 'input',
prop: 'policyNo',
label: '保单号',
visible: (formData) => formData.commissionBizType == 'R'
}, {
type: 'input',
prop: 'commissionPeriod',
label: '佣金期数',
inputType: 'decimal',
visible: (formData) => formData.commissionBizType === 'R',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
},
{
type: 'input',
prop: 'totalPeriod',
label: '总期数',
inputType: 'decimal',
visible: (formData) => formData.commissionBizType === 'R',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
type: 'date',
prop: 'commissionDate',
label: '入账日(估)',
placeholder: '请选择'
}, {
type: 'date',
prop: 'actualCommissionDate',
label: '入账日(实)',
placeholder: '请选择',
maxDate: 'today'
}, {
type: 'input',
prop: 'amount',
label: '入账金额',
inputType: 'decimal',
decimalDigits: 2,
rules: [
{ required: true, message: '请输入金额', trigger: 'blur' },
{ pattern: /^\d+(\.\d{1,2})?$/, message: '最多两位小数', trigger: 'blur' }
]
}, {
type: 'select',
prop: 'currency',
label: '入账币种',
dictType: 'bx_currency_type'
}, {
type: 'select',
prop: 'commissionName',
label: '入账项目',
dictType: 'csf_commission_type'
}, {
type: 'select',
prop: 'reconciliationCompanyBizId',
label: '对账公司',
api: '/insurance/base/api/insuranceReconciliationCompany/page',
keywordField: 'name',
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入对账公司名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'reconciliationCompanyBizId',
labelKey: 'name',
transform: (res) => {
console.log('对账公司', res)
return res.data.records || []
}
}
]
const handleConfirmAddReceivables = async () => {
const p = addRecordRef.value.getFormData()
console.log('新增应收款', p)
try {
await addReceivedFortune({
commissionExpectedAddDtoList: [p]
})
ElMessage.success('新增应收款成功')
addReceivablesDialogVisible.value = false
handleSearch()
} catch (error) {
ElMessage.error(error.message)
}
}
const searchFormRef = ref(null) const searchFormRef = ref(null)
const searchParams = ref({}) const searchParams = ref({})
const searchConfig = ref([ const searchConfig = ref([
...@@ -249,7 +345,14 @@ const searchConfig = ref([ ...@@ -249,7 +345,14 @@ const searchConfig = ref([
label: '产品计划', label: '产品计划',
api: '/product/api/relProjectProductLaunch/parameter/page', api: '/product/api/relProjectProductLaunch/parameter/page',
keywordField: 'productName', keywordField: 'productName',
requestParams: { fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20 }, requestParams: {
tenantBizId: userStore.projectInfo.tenantBizId || '',
projectBizId: userStore.projectInfo.projectBizId || '',
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn',
pageNo: 1,
pageSize: 20
},
placeholder: '输入产品计划名称搜索', placeholder: '输入产品计划名称搜索',
debounceWait: 500, // 自定义防抖时间 debounceWait: 500, // 自定义防抖时间
valueKey: 'productLaunchBizId', valueKey: 'productLaunchBizId',
...@@ -310,11 +413,8 @@ const entryRecordDialogTableColumns = ref([]) ...@@ -310,11 +413,8 @@ const entryRecordDialogTableColumns = ref([])
const actionRecordsDialogTableColumns = ref([]) const actionRecordsDialogTableColumns = ref([])
// 设置入账状态表单 // 设置入账状态表单
const form = reactive({ const setCommissionRecordStatusFormRef = ref(null)
status: '', const setCommissionRecordStatusFormConfig = ref([])
desc: '',
})
const selectedRow = ref(null) const selectedRow = ref(null)
// 表格数据 // 表格数据
...@@ -330,11 +430,14 @@ const statisticsData = ref({ ...@@ -330,11 +430,14 @@ const statisticsData = ref({
}) })
// 按钮事件处理 // 按钮事件处理
const handleAdd = () => ElMessage.info('点击新增按钮') const handleAdd = () => {
addReceivablesDialogVisible.value = true
}
const handleImport = () => ElMessage.info('点击导入按钮') const handleImport = () => ElMessage.info('点击导入按钮')
const handleExport = async () => { const handleExport = async () => {
// 获取搜索参数 // 获取搜索参数
const params = searchFormRef.value?.getSearchParams() || {} const params = searchFormRef.value?.getFormData() || {}
const response = await exportReceivedFortune(params) const response = await exportReceivedFortune(params)
// 文件名设置为应收款导出_yyyy-MM-dd hh:mm:ss.xlsx,不需要-,用字符串 // 文件名设置为应收款导出_yyyy-MM-dd hh:mm:ss.xlsx,不需要-,用字符串
const fileName = `应收款导出_${new Date().toLocaleString().replace(/\//g, '').replace(/:/g, '').replace(/\s/g, '')}.xlsx` const fileName = `应收款导出_${new Date().toLocaleString().replace(/\//g, '').replace(/:/g, '').replace(/\s/g, '')}.xlsx`
...@@ -356,8 +459,7 @@ const handleReset = () => { ...@@ -356,8 +459,7 @@ const handleReset = () => {
} }
const handleQuery = () => { const handleQuery = () => {
const params = searchFormRef.value.getSearchParams() loadTableData()
loadTableData(params)
} }
// 按钮配置 // 按钮配置
...@@ -381,7 +483,8 @@ const handleCurrentChange = (val) => { ...@@ -381,7 +483,8 @@ const handleCurrentChange = (val) => {
} }
// 加载表格数据 // 加载表格数据
const loadTableData = async (searchParams = {}) => { const loadTableData = async () => {
const searchParams = searchFormRef.value.getFormData() || {}
loading.value = true loading.value = true
try { try {
const params = { const params = {
...@@ -465,13 +568,26 @@ const handleSelect = async (e, row) => { ...@@ -465,13 +568,26 @@ const handleSelect = async (e, row) => {
const records = await loadEntryRecordData(row.commissionExpectedBizId) const records = await loadEntryRecordData(row.commissionExpectedBizId)
entryRecordDialogTableData.value = records.length ? records : [] entryRecordDialogTableData.value = records.length ? records : []
} else if (e === 'setStatus') { } else if (e === 'setStatus') {
// 回显当前行状态 console.log(selectedRow.value.status)
form.status = row.status setCommissionRecordStatusFormConfig.value = [
form.desc = '' {
type: 'select',
prop: 'status',
label: '入账状态',
dictType: 'csf_expected_commission_status',
defaultValue: selectedRow.value.status || ''
}, {
type: 'textarea',
prop: 'statusDesc',
label: '修改理由',
defaultValue: selectedRow.value.statusDesc || ''
},
]
setStatusDialogTableVisible.value = true setStatusDialogTableVisible.value = true
} }
} }
// 查看比对记录 // 查看比对记录
const handleClick = async () => { const handleClick = async () => {
actionRecordsDialogVisible.value = true actionRecordsDialogVisible.value = true
...@@ -499,10 +615,11 @@ const handleClick = async () => { ...@@ -499,10 +615,11 @@ const handleClick = async () => {
// 新增:设置状态确认事件 // 新增:设置状态确认事件
const handleConfirmSetStatus = () => { const handleConfirmSetStatus = () => {
if (!form.status) { const formData = setCommissionRecordStatusFormRef.value.getFormData()
if (!formData.status) {
return ElMessage.warning('请选择入账状态') return ElMessage.warning('请选择入账状态')
} }
if (!form.desc) { if (!formData.statusDesc) {
return ElMessage.warning('请输入修改理由') return ElMessage.warning('请输入修改理由')
} }
// 调用接口修改状态(示例) // 调用接口修改状态(示例)
...@@ -511,17 +628,27 @@ const handleConfirmSetStatus = () => { ...@@ -511,17 +628,27 @@ const handleConfirmSetStatus = () => {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(async () => { }).then(async () => {
// 此处替换为真实接口调用 try {
const res = await updateCommissionExpected({
commissionExpectedBizId: selectedRow.value.commissionExpectedBizId,
...formData
})
if (res.code === 200) {
ElMessage.success('状态修改成功') ElMessage.success('状态修改成功')
setStatusDialogTableVisible.value = false setStatusDialogTableVisible.value = false
loadTableData() // 重新加载表格 loadTableData() // 重新加载表格
} else {
ElMessage.error(res.msg || '状态修改失败')
}
} catch (error) {
console.error('修改状态失败:', error)
ElMessage.error('修改状态失败')
}
}).catch(() => { }).catch(() => {
ElMessage.info('已取消修改') ElMessage.info('已取消修改')
}) })
} }
// 初始化加载数据
loadTableData()
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>
\ No newline at end of file
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