Commit 3b104bbf by yuzhenWang

Merge branch 'test' into 'dev'

Test

See merge request !109
parents 75ee40be 83d3cb8c
......@@ -33,6 +33,7 @@
"js-cookie": "3.0.5",
"jsencrypt": "3.3.2",
"jszip": "^3.10.1",
"lodash": "^4.18.1",
"nprogress": "0.2.0",
"p-limit": "^7.3.0",
"pinia": "3.0.2",
......
......@@ -9,7 +9,6 @@ export function getPolicyCommissionList(data) {
})
}
// 生成可出账记录
export function generateCommissionRecord(data) {
return request({
......@@ -55,7 +54,7 @@ export function downloadPolicyFortuneAccount(data) {
return request({
url: '/csf/api/fortune/download/account',
method: 'post',
data: data,
data: data
})
}
......@@ -257,7 +256,6 @@ export function commissionEntryEditRecords(data) {
})
}
// 获取保单发佣列表
export function policyNoCommissionPayRecord(data) {
return request({
......@@ -303,8 +301,8 @@ export function updateCommissionExpected(data) {
}
// 修改出账状态
export function updataPayrollStatus(data){
return request({
export function updataPayrollStatus(data) {
return request({
url: '/csf/api/fortune/update/status',
method: 'post',
data: data
......@@ -312,8 +310,8 @@ export function updataPayrollStatus(data){
}
// 批量新增检核记录
export function addPayrollCheckRecord(data){
return request({
export function addPayrollCheckRecord(data) {
return request({
url: '/csf/api/commission/addBatch',
method: 'post',
data: data
......@@ -321,8 +319,8 @@ export function addPayrollCheckRecord(data){
}
// 新增应收款
export function addReceivedFortune(data){
return request({
export function addReceivedFortune(data) {
return request({
url: '/csf/api/CommissionExpected/add',
method: 'post',
data: data
......@@ -330,23 +328,23 @@ export function addReceivedFortune(data){
}
// 新增出账记录
export function addPayRecord(data){
return request({
export function addPayRecord(data) {
return request({
url: '/csf/api/expectedFortune/add',
method: 'post',
data: data
})
}
// 获取销售员详情
export function userSaleExpandDetail(data){
return request({
export function userSaleExpandDetail(data) {
return request({
url: '/insurance/base/api/userSaleExpand/detail?userSaleBizId=' + data,
method: 'get',
method: 'get'
})
}
// 更新比对状态
export function updateCompareStatus(data){
return request({
export function updateCompareStatus(data) {
return request({
url: '/csf/api/commission/updateCompareStatus',
method: 'post',
data: data
......@@ -354,8 +352,8 @@ export function updateCompareStatus(data){
}
// 更新数据
export function updateCommissionRecord(data){
return request({
export function updateCommissionRecord(data) {
return request({
url: '/csf/api/commission/update',
method: 'post',
data: data
......@@ -363,8 +361,8 @@ export function updateCommissionRecord(data){
}
// 新增出账检核记录
export function addCheckRecordaddBatch(data){
return request({
export function addCheckRecordaddBatch(data) {
return request({
url: '/csf/api/fortune/addBatch',
method: 'post',
data: data
......@@ -372,8 +370,8 @@ export function addCheckRecordaddBatch(data){
}
// 设置本期出账金额
export function updatePayoutAmount(data){
return request({
export function updatePayoutAmount(data) {
return request({
url: '/csf/api/fortune/update',
method: 'post',
data: data
......@@ -381,16 +379,16 @@ export function updatePayoutAmount(data){
}
// 同步预计来佣
export function syncExpectedCommission(data){
return request({
export function syncExpectedCommission(data) {
return request({
url: '/csf/api/commission/addToExpected',
method: 'post',
data: data
})
}
// 更新出账记录
export function updatePayRecord(data){
return request({
export function updatePayRecord(data) {
return request({
url: '/csf/api/expectedFortune/update',
method: 'post',
data: data
......@@ -406,10 +404,10 @@ export function exportPayRecord(data) {
})
}
// 入账检核重新比对
export function compareCommissionEntry(data){
return request({
export function compareCommissionEntry(data) {
return request({
url: '/csf/api/commission/compare?commissionBizId=' + data,
method: 'get',
method: 'get'
})
}
......@@ -418,7 +416,7 @@ export function payableReport(data) {
return request({
url: '/csf/api/expectedFortune/payable_report',
method: 'post',
data: data,
data: data
})
}
......@@ -429,4 +427,75 @@ export function receivableReport(data) {
method: 'post',
data: data
})
}
\ No newline at end of file
}
// 薪资拆分应发信息汇总列表
export function salarySummary(data) {
return request({
url: 'csf/api/salarySplit/summary/page',
method: 'post',
data: data
})
}
// 薪资拆分应发信息汇总列表下载---待提供
export function exportPayRoll(data) {
return request({
url: 'csf/api/salarySplit/export/summary/list',
method: 'post',
data: data
})
}
// 拆分出账列表
export function salarySplitList(data) {
return request({
url: 'csf/api/salarySplit/page',
method: 'post',
data: data
})
}
// 拆分出账查询-原币种剩余总金额和原币种
export function billSplitRemaining(data) {
return request({
url: 'csf/api/salarySplit/query/remaining',
method: 'post',
data: data
})
}
// 获取转介人详情
export function borkerDetail(data) {
return request({
url: '/insurance/base/api/userSaleExpand/detail?clientUserBizId=' + data,
method: 'get'
})
}
// 拆分出账查询-原币种和原币种金额——>目标币种即时汇率和目标币种金额
export function billSplitRate(data) {
return request({
url: 'csf/api/salarySplit/query/rate',
method: 'post',
data: data
})
}
// 拆分出账查询-批量保存-薪资拆分应发信息列表
export function billBatchSave(data) {
return request({
url: 'csf/api/salarySplit/batch/save',
method: 'post',
data: data
})
}
// 拆分出账查询-计算目标金额
export function billCalculateToAmount(data) {
return request({
url: 'csf/api/salarySplit/calculate/toAmount',
method: 'post',
data: data
})
}
......@@ -82,14 +82,28 @@
v-model="localModel[item.prop]"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="item.startPlaceholder || '开始日期'"
:end-placeholder="item.endPlaceholder || '结束日期'"
:value-format="item.valueFormat || 'YYYY-MM-DD'"
:disabled="item.disabled"
:disabled-date="getDisabledDateFn(item)"
style="width: 100%"
@change="val => handleModelChange(val, item)"
/>
<!-- Monthrange (新增) -->
<el-date-picker
v-else-if="item.type === 'monthrange'"
v-model="localModel[item.prop]"
type="monthrange"
range-separator="至"
:start-placeholder="item.startPlaceholder || '开始月份'"
:end-placeholder="item.endPlaceholder || '结束月份'"
:value-format="item.valueFormat || 'YYYY-MM'"
:disabled="item.disabled"
:disabled-date="getDisabledDateFn(item)"
style="width: 100%"
@change="val => handleModelChange(val, item)"
/>
<!-- Checkbox Group -->
<el-checkbox-group
......@@ -359,7 +373,7 @@ watch(
// 优先用父传值,否则用默认值
if (props.modelValue?.[key] !== undefined) {
initialModel[key] = props.modelValue[key]
} else if (item.multiple || ['checkbox-group', 'daterange'].includes(item.type)) {
} else if (item.multiple || ['checkbox-group', 'daterange','monthrange'].includes(item.type)) {
initialModel[key] = item.defaultValue ?? []
} else {
initialModel[key] = item.defaultValue ?? ''
......@@ -396,7 +410,7 @@ function syncModelFromProps(newModelValue, newConfig) {
const key = item.prop
if (newModelValue.hasOwnProperty(key)) {
synced[key] = newModelValue[key]
} else if (item.multiple || ['checkbox-group', 'daterange'].includes(item.type)) {
} else if (item.multiple || ['checkbox-group', 'daterange','monthrange'].includes(item.type)) {
synced[key] = item.defaultValue ?? []
} else {
synced[key] = item.defaultValue ?? ''
......@@ -571,7 +585,7 @@ onMounted(async () => {
if (localModel.value[key] == null) {
if (item.multiple) {
initialData[key] = item.defaultValue ?? []
} else if (['checkbox-group', 'daterange'].includes(item.type)) {
} else if (['checkbox-group', 'daterange','monthrange'].includes(item.type)) {
initialData[key] = item.defaultValue ?? []
} else {
initialData[key] = item.defaultValue ?? ''
......@@ -885,7 +899,7 @@ defineExpose({
const resetData = {}
internalConfig.value.forEach(item => {
const key = item.prop
if (['checkbox-group', 'daterange'].includes(item.type) || item.multiple) {
if (['checkbox-group', 'daterange','monthrange'].includes(item.type) || item.multiple) {
resetData[key] = item.defaultValue ?? []
} else if (item.type === 'upload') {
resetData[key] = item.defaultValue ?? [] // upload 也是数组
......
......@@ -75,3 +75,7 @@ export function processUserName(users) {
}
})
}
export function generateId() {
return `${Date.now()}_${Math.random().toString(36).substr(2, 8)}`
}
// 格式化金额为货币格式
export function formatCurrency(value, currency = '',fixedDigits = 2) {
export function formatCurrency(value, currency = '', fixedDigits = 2) {
if (value === undefined || value === null) return currency + '0.00'
return currency + value.toFixed(fixedDigits).replace(/\d(?=(\d{3})+\.)/g, '$&,')
}
......@@ -198,9 +198,19 @@ export function formatThousandsSimple(value) {
return result
}
export function inputThousands(value) {
if (value === undefined || value === null || value === '') {
return ''
}
const parts = String(value).split('.')
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
return parts.join('.')
}
export default {
formatCurrency,
numberFormat,
formatThousands,
formatThousandsSimple
formatThousandsSimple,
inputThousands
}
......@@ -16,7 +16,7 @@ const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时
timeout: 10000
timeout: 30000
})
// request拦截器
......
import { ref } from 'vue'
export function usePositiveDecimal(defaultPlaces = 2) {
// 实时过滤(返回过滤后的字符串)
const filterInput = (value, decimalPlaces = defaultPlaces) => {
if (value === undefined || value === null) return ''
let str = String(value)
// 1. 只保留数字和小数点
str = str.replace(/[^\d.]/g, '')
// 2. 限制只有一个小数点
const parts = str.split('.')
if (parts.length > 2) {
str = parts[0] + '.' + parts.slice(1).join('')
}
// 3. 限制小数位数
if (parts.length === 2 && parts[1].length > decimalPlaces) {
str = parts[0] + '.' + parts[1].slice(0, decimalPlaces)
}
return str
}
// 失焦时格式化(补零 / 截断)
const formatBlur = (value, decimalPlaces = defaultPlaces) => {
if (value === '' || value === null || value === undefined) {
return ''
}
let num = parseFloat(value)
if (isNaN(num) || num < 0) {
return ''
}
return num.toFixed(decimalPlaces)
}
return { filterInput, formatBlur }
}
......@@ -203,7 +203,7 @@ import {
getPolicyFortuneList,
addCheckRecordaddBatch,
updatePayoutAmount,
downloadPolicyFortuneAccount
downloadPolicyFortuneAccount,
} from '@/api/financial/commission'
import useUserStore from '@/store/modules/user'
......@@ -378,11 +378,13 @@ const addCheckRecordConfig = [
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入转介人名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'userSaleBizId',
valueKey: 'clientUserBizId',
labelKey: 'realName',
onChangeExtraFields: {
broker: 'realName', // 自动同步 raw.name 到 reconciliationCompany
reconciliationCompanyCode: 'code'
reconciliationCompanyCode: 'code',
team:'deptName',
teamBizId:'deptBizId',
},
transform: res => {
return res?.data.records || []
......
......@@ -122,7 +122,7 @@
<script setup name="Payables">
import CommonPage from '@/components/commonPage'
import { ref, reactive } from 'vue'
import { ref, reactive,nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { formatCurrency } from '@/utils/number'
import { expectedFortuneList, payRecordList, addPayRecord, updatePayRecord, exportPayRecord, payableReport } from '@/api/financial/commission'
......@@ -161,7 +161,7 @@ const payableReportListTableColumns = ref([
{ prop: 'broker', label: '转介人', sortable: true, width: '120', formatter: (row) => row.broker || '-' },
{ prop: 'fortuneName', label: '出账项目', sortable: true, width: '120', formatter: (row) => row.fortuneName || '-' },
{ prop: 'status', label: '出账状态', sortable: true, width: '120', formatter: (row) => getDictLabel('csf_expected_fortune_status', row.status) || '-' },
{ prop: 'currency', label: '出账币种', sortable: true, width: '100', formatter: (row) => row.currency || '-' },
{ prop: 'currencyName', label: '出账币种', sortable: true, width: '100', formatter: (row) => row.currencyName || '-' },
{ prop: 'fortunePeriod', label: '出账期数', sortable: true, width: '100', formatter: (row) => row.fortunePeriod || '-' },
{ prop: 'fortuneTotalPeriod', label: '出账总期数', sortable: true, width: '100', formatter: (row) => row.fortuneTotalPeriod || '-' },
{ prop: 'payoutDate', label: '出账日(估)', sortable: true, width: '120', formatter: (row) => row.payoutDate || '-' },
......@@ -387,7 +387,7 @@ const addPayRecordFormConfig = [
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入转介人名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'userSaleBizId',
valueKey: 'clientUserBizId',
labelKey: 'realName',
onChangeExtraFields: {
broker: 'realName',// 自动同步 raw.name 到 reconciliationCompany
......@@ -480,12 +480,13 @@ const handleSelect = async (e, row) => {
} else if (e === 'updateData') {
editStatus.value = 'edit'
addPayRecordDialogVisible.value = true
if (addPayRecordFormRef.value) {
addPayRecordFormModel.value = {
...selectedRow.value
}
}
// 2. 使用 nextTick 等待 DOM 更新
nextTick(() => {
// 3. 此时 addRecordRef.value 一定存在了
if (addPayRecordFormRef.value && selectedRow.value) {
addPayRecordFormModel.value = { ...selectedRow.value };
}
});
console.log(addPayRecordFormModel.value)
}
......
<template>
<div class='app-container'>
<CommonPage :operationBtnList='operationBtnList' :visibleDefaultButtons='visibleDefaultButtons'
:showSearchForm='true' :show-pagination='true' :total='pageTotal' :current-page='currentPage'
:page-size='pageSize' @size-change='handleSizeChange' @current-change='handleCurrentChange'>
<!-- 搜索区域 -->
<template #searchForm>
<SearchForm ref="searchFormRef" :config="searchConfig" />
</template>
<!-- 列表区域 -->
<template #table>
<el-table :data="tableData" v-loading="loading" ref="tableRef"
row-key="salarySplitNo" :reserve-selection="true" :border="true">
<el-table-column v-for="(column, index) in tableColumns" :key="index" :fixed="column.fixed"
:prop="column.prop" :label="column.label" :width="column.width" :sortable="column.sortable"
:formatter="column.formatter" />
</el-table>
</template>
</CommonPage>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import CommonPage from '@/components/commonPage'
import {salarySummary,exportPayRoll} from '@/api/financial/commission'
import { ElMessageBox, ElMessage } from 'element-plus'
import SearchForm from '@/components/SearchForm/SearchForm.vue'
const searchFormRef = ref(null)
const searchParams = ref({})
const searchConfig = ref([
{
type: 'select',
prop: 'brokerBizIdList',
label: '转介人',
api: '/insurance/base/api/userSaleExpand/page',
keywordField: 'realName',
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入转介人名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'clientUserBizId',
labelKey: 'realName',
multiple: true,
transform: (res) => {
return res?.data.records || []
}
},
{
type: 'monthrange',
prop: 'payoutMonth',
label: '出账年月(实)',
startPlaceholder: '开始年月',
endPlaceholder: '结束年月'
},
{
type: 'input',
prop: 'billOrg',
label: '出账机构',
}
])
const tableColumns = ref([
{ prop: 'salarySplitNo', label: '发放编号', sortable: true, width: '150',fixed:'left'},
{ prop: 'brokerName', label: '转介人', sortable: true, width: '150',fixed:'left'},
{ prop: 'internalNumber', label: '内部编号', sortable: true, width: '150'},
{ prop: 'team', label: '所属团队', sortable: true, width: '150'},
{ prop: 'fromAmount', label: '原币种金额', sortable: true, width: '150'},
{ prop: 'currency', label: '原币种', sortable: true, width: '150'},
{ prop: 'exchangeRate', label: '汇率(原币种->目标币种)', sortable: true, width: '150'},
{ prop: 'toAmount', label: '目标金额', sortable: true, width: '150'},
{ prop: 'toCurrency', label: '目标币种', sortable: true, width: '150'},
{ prop: 'fortuneAccountMonth', label: '出账月(实)', sortable: true, width: '150'},
{ prop: 'billOrg', label: '出账机构', sortable: true, width: '150'},
{ prop: 'hkdAmount', label: '本期总出账金额(原币种)', sortable: true, width: '150'},
{ prop: 'fortuneAccountBizId', label: '出账记录业务id', sortable: true, width: '150'},
])
// 添加表格引用
const tableRef = ref()
// 表格数据
const tableData = ref([])
const loading = ref(false)
// 分页相关
const currentPage = ref(1)
const pageSize = ref(10)
const pageTotal = ref(0)
// 分页事件
const handleSizeChange = (val) => {
pageSize.value = val
getList()
}
const handleCurrentChange = (val) => {
currentPage.value = val
getList()
}
// 获取数据列表
const getList = async (searchParams = {}) => {
loading.value = true
try {
const params = {
...searchParams,
startMonth:searchParams.payoutMonth ? searchParams.payoutMonth[0] : '',
endMonth:searchParams.payoutMonth ? searchParams.payoutMonth[1] :'',
payoutMonth:undefined,
pageNo: currentPage.value,
pageSize: pageSize.value
}
const response = await salarySummary(params)
if (response.data.page) {
tableData.value = response.data.page.records
pageTotal.value = response.data.page.total
loading.value = false
}
} catch (error) {
loading.value = false
// ElMessage.error('获取数据失败')
}
}
getList()
// 查询
const handleQuery = () => {
const params = searchFormRef.value.getFormData()
console.log('父组件发起查询:', params)
getList(params)
}
// 重置查询
const handleReset = () => {
// 重置搜索表单
searchFormRef.value.resetForm()
searchParams.value = {}
console.log('表单已重置')
getList(searchParams.value)
}
const handleExport = async () => {
// 获取搜索参数
let params = searchFormRef.value?.getFormData()
params = {
...params,
startMonth:params.payoutMonth ? params.payoutMonth[0] : '',
endMonth:params.payoutMonth ? params.payoutMonth[1] :'',
payoutMonth:undefined,
}
const response = await exportPayRoll(params)
if(response.data && response.data.url){
window.open(response.data.url)
}else{
ElMessage.error('导出失败')
}
}
const visibleDefaultButtons = ref(['export','reset', 'query'])
// 按钮配置
const operationBtnList = ref([
{
key: 'reset',
direction: 'right',
click: handleReset
},
{
key: 'query',
direction: 'right',
click: handleQuery
},
{
key: 'export',
direction: 'right',
click: handleExport
}
])
</script>
<style scoped></style>
\ No newline at end of file
......@@ -196,7 +196,7 @@
<script setup name="Receivables">
import CommonPage from '@/components/commonPage'
import CommonDialog from '@/components/commonDialog'
import { ref, reactive, onMounted, computed } from 'vue'
import { ref, reactive, onMounted, computed,nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue'
import {
......@@ -696,11 +696,14 @@ const handleSelect = async (e, row) => {
} else if (e === 'updateData') {
editStatus.value = 'update'
addReceivablesDialogVisible.value = true
if (addRecordRef.value) {
addReceivablesFormModel.value = {
...selectedRow.value
// 2. 使用 nextTick 等待 DOM 更新
nextTick(() => {
// 3. 此时 addRecordRef.value 一定存在了
if (addRecordRef.value && selectedRow.value) {
addReceivablesFormModel.value = { ...selectedRow.value };
console.log('赋值成功:', addReceivablesFormModel.value);
}
}
});
console.log('更新数据', selectedRow.value)
}
}
......
......@@ -582,9 +582,11 @@ const confirmAffirm = async () => {
currentRow.value = {}
}
} catch (error) {
console.log('error', error)
settingAffirmLoading.value = false
console.error('加载数据失败:', error)
ElMessage.error('必填项不能为空' || '认定失败')
if (error.message && error.message.includes('Validation')) {
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